diff --git a/.github/ISSUE_TEMPLATE/01-feature_request.yaml b/.github/ISSUE_TEMPLATE/01-feature_request.yaml index 763733c0958..eda44e63e18 100644 --- a/.github/ISSUE_TEMPLATE/01-feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/01-feature_request.yaml @@ -15,7 +15,7 @@ body: attributes: label: NetBox version description: What version of NetBox are you currently running? - placeholder: v4.4.0 + placeholder: v4.4.1 validations: required: true - type: dropdown diff --git a/.github/ISSUE_TEMPLATE/02-bug_report.yaml b/.github/ISSUE_TEMPLATE/02-bug_report.yaml index f25b70b1923..4e62aa84e13 100644 --- a/.github/ISSUE_TEMPLATE/02-bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/02-bug_report.yaml @@ -8,26 +8,26 @@ body: attributes: value: > **NOTE:** This form is only for reporting _reproducible bugs_ in a current NetBox - installation. If you're having trouble with installation or just looking for - assistance with using NetBox, please visit our + release. If you're having trouble with installation or just looking for assistance + using NetBox, please visit our [discussion forum](https://github.com/netbox-community/netbox/discussions) instead. - type: dropdown attributes: - label: Deployment Type + label: NetBox Edition description: > - How are you running NetBox? (For issues with the Docker image, please go to the - [netbox-docker](https://github.com/netbox-community/netbox-docker) repo.) + Users of [NetBox Cloud](https://netboxlabs.com/netbox-cloud/) or + [NetBox Enterprise](https://netboxlabs.com/netbox-enterprise/), please contact the + [NetBox Labs](https://netboxlabs.com/) support team for assistance to ensure your + request receives immediate attention. options: - - NetBox Cloud - - NetBox Enterprise - - Self-hosted + - NetBox Community validations: required: true - type: input attributes: label: NetBox Version description: What version of NetBox are you currently running? - placeholder: v4.4.0 + placeholder: v4.4.1 validations: required: true - type: dropdown diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 5b18f45252f..2bee327a73c 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -13,9 +13,6 @@ contact_links: - name: 🌎 Correct a Translation url: https://explore.transifex.com/netbox-community/netbox/ about: "Spot an incorrect translation? You can propose a fix on Transifex." - - name: 💡 Plugin Idea - url: https://plugin-ideas.netbox.dev - about: "Have an idea for a plugin? Head over to the ideas board!" - name: 💬 Community Slack url: https://netdev.chat about: "Join #netbox on the NetDev Community Slack for assistance with installation issues and other problems." diff --git a/README.md b/README.md index 66560dd2a98..1fd8e2f5a5a 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,6 @@ NetBox automatically logs the creation, modification, and deletion of all manage * Join the conversation on [the discussion forum](https://github.com/netbox-community/netbox/discussions) and [Slack](https://netdev.chat/)! * Already a power user? You can [suggest a feature](https://github.com/netbox-community/netbox/issues/new?assignees=&labels=type%3A+feature&template=feature_request.yaml) or [report a bug](https://github.com/netbox-community/netbox/issues/new?assignees=&labels=type%3A+bug&template=bug_report.yaml) on GitHub. * Contributions from the community are encouraged and appreciated! Check out our [contributing guide](CONTRIBUTING.md) to get started. -* [Share your idea](https://plugin-ideas.netbox.dev/) for a new plugin, or [learn how to build one](https://github.com/netbox-community/netbox-plugin-tutorial) yourself! ## Screenshots diff --git a/SECURITY.md b/SECURITY.md index 58b73cbb780..c00fe610741 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -34,4 +34,4 @@ For any security concerns regarding the community-maintained Docker image for Ne ### Bug Bounties -As NetBox is provided as free open source software, we do not offer any monetary compensation for vulnerability or bug reports, however your contributions are greatly appreciated. +As NetBox is provided as free open source software, we do not offer any monetary compensation for vulnerability or bug reports; however, your contributions are greatly appreciated. diff --git a/base_requirements.txt b/base_requirements.txt index fd20eae0921..9bf8680a5e9 100644 --- a/base_requirements.txt +++ b/base_requirements.txt @@ -139,8 +139,7 @@ requests # rq # https://github.com/rq/rq/blob/master/CHANGES.md -# RQ v2.5 drops support for Redis < 5.0 -rq==2.4.1 +rq # Django app for social-auth-core # https://github.com/python-social-auth/social-app-django/blob/master/CHANGELOG.md diff --git a/contrib/generated_schema.json b/contrib/generated_schema.json index 9c115cf14ca..473e75cffa2 100644 --- a/contrib/generated_schema.json +++ b/contrib/generated_schema.json @@ -330,14 +330,87 @@ "100base-lfx", "100base-tx", "100base-t1", - "1000base-t", + "1000base-bx10-d", + "1000base-bx10-u", + "1000base-cx", + "1000base-cwdm", + "1000base-dwdm", + "1000base-ex", "1000base-sx", + "1000base-lsx", "1000base-lx", + "1000base-lx10", + "1000base-t", "1000base-tx", + "1000base-zx", "2.5gbase-t", "5gbase-t", - "10gbase-t", + "10gbase-br-d", + "10gbase-br-u", "10gbase-cx4", + "10gbase-er", + "10gbase-lr", + "10gbase-lrm", + "10gbase-lx4", + "10gbase-sr", + "10gbase-t", + "10gbase-zr", + "25gbase-cr", + "25gbase-er", + "25gbase-lr", + "25gbase-sr", + "25gbase-t", + "40gbase-cr4", + "40gbase-er4", + "40gbase-fr4", + "40gbase-lr4", + "40gbase-sr4", + "50gbase-cr", + "50gbase-er", + "50gbase-fr", + "50gbase-lr", + "50gbase-sr", + "100gbase-cr1", + "100gbase-cr2", + "100gbase-cr4", + "100gbase-cr10", + "100gbase-dr", + "100gbase-er4", + "100gbase-fr1", + "100gbase-lr1", + "100gbase-lr4", + "100gbase-sr1", + "100gbase-sr1.2", + "100gbase-sr2", + "100gbase-sr4", + "100gbase-sr10", + "100gbase-zr", + "200gbase-cr2", + "200gbase-cr4", + "200gbase-sr2", + "200gbase-sr4", + "200gbase-dr4", + "200gbase-er4", + "200gbase-fr4", + "200gbase-lr4", + "200gbase-vr2", + "400gbase-cr4", + "400gbase-dr4", + "400gbase-er8", + "400gbase-fr4", + "400gbase-fr8", + "400gbase-lr4", + "400gbase-lr8", + "400gbase-sr4", + "400gbase-sr4_2", + "400gbase-sr8", + "400gbase-sr16", + "400gbase-vr4", + "400gbase-zr", + "800gbase-cr8", + "800gbase-dr8", + "800gbase-sr8", + "800gbase-vr8", "100base-x-sfp", "1000base-x-gbic", "1000base-x-sfp", diff --git a/contrib/openapi.json b/contrib/openapi.json index 09733b4c209..ddbdff987e3 100644 --- a/contrib/openapi.json +++ b/contrib/openapi.json @@ -23531,7 +23531,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true } }, @@ -23552,7 +23552,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true } }, @@ -23566,7 +23566,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true } }, @@ -23580,7 +23580,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true } }, @@ -23594,7 +23594,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true } }, @@ -23608,7 +23608,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true } }, @@ -23622,7 +23622,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true } }, @@ -23636,7 +23636,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true } }, @@ -23650,7 +23650,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true } }, @@ -23664,7 +23664,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true } }, @@ -23678,7 +23678,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true } }, @@ -23692,7 +23692,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true } }, @@ -47839,7 +47839,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -47859,7 +47859,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -47872,7 +47872,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -47885,7 +47885,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -47898,7 +47898,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -47911,7 +47911,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -47924,7 +47924,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -47937,7 +47937,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -47950,7 +47950,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -47963,7 +47963,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -47976,7 +47976,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -47989,7 +47989,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -51766,7 +51766,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -51786,7 +51786,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -51799,7 +51799,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -51812,7 +51812,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -51825,7 +51825,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -51838,7 +51838,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -51851,7 +51851,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -51864,7 +51864,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -51877,7 +51877,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -51890,7 +51890,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -51903,7 +51903,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -51916,7 +51916,7 @@ "type": "array", "items": { "type": "string", - "x-spec-enum-id": "8c4c5e112f77a383" + "x-spec-enum-id": "efa24ff9c7a39c40" } }, "explode": true, @@ -112805,8 +112805,8 @@ "schema": { "type": "array", "items": { - "type": "integer", - "format": "int32" + "type": "number", + "format": "double" } }, "explode": true, @@ -112825,8 +112825,8 @@ "schema": { "type": "array", "items": { - "type": "integer", - "format": "int32" + "type": "number", + "format": "double" } }, "explode": true, @@ -112838,8 +112838,8 @@ "schema": { "type": "array", "items": { - "type": "integer", - "format": "int32" + "type": "number", + "format": "double" } }, "explode": true, @@ -112851,8 +112851,8 @@ "schema": { "type": "array", "items": { - "type": "integer", - "format": "int32" + "type": "number", + "format": "double" } }, "explode": true, @@ -112864,8 +112864,8 @@ "schema": { "type": "array", "items": { - "type": "integer", - "format": "int32" + "type": "number", + "format": "double" } }, "explode": true, @@ -112877,8 +112877,8 @@ "schema": { "type": "array", "items": { - "type": "integer", - "format": "int32" + "type": "number", + "format": "double" } }, "explode": true, @@ -112890,8 +112890,8 @@ "schema": { "type": "array", "items": { - "type": "integer", - "format": "int32" + "type": "number", + "format": "double" } }, "explode": true, @@ -112910,8 +112910,8 @@ "schema": { "type": "array", "items": { - "type": "integer", - "format": "int32" + "type": "number", + "format": "double" } }, "explode": true, @@ -112923,8 +112923,8 @@ "schema": { "type": "array", "items": { - "type": "integer", - "format": "int32" + "type": "number", + "format": "double" } }, "explode": true, @@ -112936,8 +112936,8 @@ "schema": { "type": "array", "items": { - "type": "integer", - "format": "int32" + "type": "number", + "format": "double" } }, "explode": true, @@ -112949,8 +112949,8 @@ "schema": { "type": "array", "items": { - "type": "integer", - "format": "int32" + "type": "number", + "format": "double" } }, "explode": true, @@ -112962,8 +112962,8 @@ "schema": { "type": "array", "items": { - "type": "integer", - "format": "int32" + "type": "number", + "format": "double" } }, "explode": true, @@ -204674,9 +204674,9 @@ "cat7", "cat7a", "cat8", + "mrj21-trunk", "dac-active", "dac-passive", - "mrj21-trunk", "coaxial", "mmf", "mmf-om1", @@ -204688,14 +204688,14 @@ "smf-os1", "smf-os2", "aoc", - "usb", "power", + "usb", "", null ], "type": "string", - "description": "* `cat3` - CAT3\n* `cat5` - CAT5\n* `cat5e` - CAT5e\n* `cat6` - CAT6\n* `cat6a` - CAT6a\n* `cat7` - CAT7\n* `cat7a` - CAT7a\n* `cat8` - CAT8\n* `dac-active` - Direct Attach Copper (Active)\n* `dac-passive` - Direct Attach Copper (Passive)\n* `mrj21-trunk` - MRJ21 Trunk\n* `coaxial` - Coaxial\n* `mmf` - Multimode Fiber\n* `mmf-om1` - Multimode Fiber (OM1)\n* `mmf-om2` - Multimode Fiber (OM2)\n* `mmf-om3` - Multimode Fiber (OM3)\n* `mmf-om4` - Multimode Fiber (OM4)\n* `mmf-om5` - Multimode Fiber (OM5)\n* `smf` - Singlemode Fiber\n* `smf-os1` - Singlemode Fiber (OS1)\n* `smf-os2` - Singlemode Fiber (OS2)\n* `aoc` - Active Optical Cabling (AOC)\n* `usb` - USB\n* `power` - Power", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "description": "* `cat3` - CAT3\n* `cat5` - CAT5\n* `cat5e` - CAT5e\n* `cat6` - CAT6\n* `cat6a` - CAT6a\n* `cat7` - CAT7\n* `cat7a` - CAT7a\n* `cat8` - CAT8\n* `mrj21-trunk` - MRJ21 Trunk\n* `dac-active` - Direct Attach Copper (Active)\n* `dac-passive` - Direct Attach Copper (Passive)\n* `coaxial` - Coaxial\n* `mmf` - Multimode Fiber\n* `mmf-om1` - Multimode Fiber (OM1)\n* `mmf-om2` - Multimode Fiber (OM2)\n* `mmf-om3` - Multimode Fiber (OM3)\n* `mmf-om4` - Multimode Fiber (OM4)\n* `mmf-om5` - Multimode Fiber (OM5)\n* `smf` - Single-mode Fiber\n* `smf-os1` - Single-mode Fiber (OS1)\n* `smf-os2` - Single-mode Fiber (OS2)\n* `aoc` - Active Optical Cabling (AOC)\n* `power` - Power\n* `usb` - USB", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true }, "a_terminations": { @@ -204844,9 +204844,9 @@ "cat7", "cat7a", "cat8", + "mrj21-trunk", "dac-active", "dac-passive", - "mrj21-trunk", "coaxial", "mmf", "mmf-om1", @@ -204858,14 +204858,14 @@ "smf-os1", "smf-os2", "aoc", - "usb", "power", + "usb", "", null ], "type": "string", - "description": "* `cat3` - CAT3\n* `cat5` - CAT5\n* `cat5e` - CAT5e\n* `cat6` - CAT6\n* `cat6a` - CAT6a\n* `cat7` - CAT7\n* `cat7a` - CAT7a\n* `cat8` - CAT8\n* `dac-active` - Direct Attach Copper (Active)\n* `dac-passive` - Direct Attach Copper (Passive)\n* `mrj21-trunk` - MRJ21 Trunk\n* `coaxial` - Coaxial\n* `mmf` - Multimode Fiber\n* `mmf-om1` - Multimode Fiber (OM1)\n* `mmf-om2` - Multimode Fiber (OM2)\n* `mmf-om3` - Multimode Fiber (OM3)\n* `mmf-om4` - Multimode Fiber (OM4)\n* `mmf-om5` - Multimode Fiber (OM5)\n* `smf` - Singlemode Fiber\n* `smf-os1` - Singlemode Fiber (OS1)\n* `smf-os2` - Singlemode Fiber (OS2)\n* `aoc` - Active Optical Cabling (AOC)\n* `usb` - USB\n* `power` - Power", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "description": "* `cat3` - CAT3\n* `cat5` - CAT5\n* `cat5e` - CAT5e\n* `cat6` - CAT6\n* `cat6a` - CAT6a\n* `cat7` - CAT7\n* `cat7a` - CAT7a\n* `cat8` - CAT8\n* `mrj21-trunk` - MRJ21 Trunk\n* `dac-active` - Direct Attach Copper (Active)\n* `dac-passive` - Direct Attach Copper (Passive)\n* `coaxial` - Coaxial\n* `mmf` - Multimode Fiber\n* `mmf-om1` - Multimode Fiber (OM1)\n* `mmf-om2` - Multimode Fiber (OM2)\n* `mmf-om3` - Multimode Fiber (OM3)\n* `mmf-om4` - Multimode Fiber (OM4)\n* `mmf-om5` - Multimode Fiber (OM5)\n* `smf` - Single-mode Fiber\n* `smf-os1` - Single-mode Fiber (OS1)\n* `smf-os2` - Single-mode Fiber (OS2)\n* `aoc` - Active Optical Cabling (AOC)\n* `power` - Power\n* `usb` - USB", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true }, "a_terminations": { @@ -209051,19 +209051,23 @@ "description": "Fields with higher weights appear lower in a form." }, "validation_minimum": { - "type": "integer", - "maximum": 9223372036854775807, - "minimum": -9223372036854775808, - "format": "int64", + "type": "number", + "format": "double", + "maximum": 1000000000000, + "minimum": -1000000000000, + "exclusiveMaximum": true, + "exclusiveMinimum": true, "nullable": true, "title": "Minimum value", "description": "Minimum allowed value (for numeric fields)" }, "validation_maximum": { - "type": "integer", - "maximum": 9223372036854775807, - "minimum": -9223372036854775808, - "format": "int64", + "type": "number", + "format": "double", + "maximum": 1000000000000, + "minimum": -1000000000000, + "exclusiveMaximum": true, + "exclusiveMinimum": true, "nullable": true, "title": "Maximum value", "description": "Maximum allowed value (for numeric fields)" @@ -209367,19 +209371,23 @@ "description": "Fields with higher weights appear lower in a form." }, "validation_minimum": { - "type": "integer", - "maximum": 9223372036854775807, - "minimum": -9223372036854775808, - "format": "int64", + "type": "number", + "format": "double", + "maximum": 1000000000000, + "minimum": -1000000000000, + "exclusiveMaximum": true, + "exclusiveMinimum": true, "nullable": true, "title": "Minimum value", "description": "Minimum allowed value (for numeric fields)" }, "validation_maximum": { - "type": "integer", - "maximum": 9223372036854775807, - "minimum": -9223372036854775808, - "format": "int64", + "type": "number", + "format": "double", + "maximum": 1000000000000, + "minimum": -1000000000000, + "exclusiveMaximum": true, + "exclusiveMinimum": true, "nullable": true, "title": "Maximum value", "description": "Maximum allowed value (for numeric fields)" @@ -215311,14 +215319,87 @@ "100base-lfx", "100base-tx", "100base-t1", - "1000base-t", + "1000base-bx10-d", + "1000base-bx10-u", + "1000base-cx", + "1000base-cwdm", + "1000base-dwdm", + "1000base-ex", "1000base-sx", + "1000base-lsx", "1000base-lx", + "1000base-lx10", + "1000base-t", "1000base-tx", + "1000base-zx", "2.5gbase-t", "5gbase-t", - "10gbase-t", + "10gbase-br-d", + "10gbase-br-u", "10gbase-cx4", + "10gbase-er", + "10gbase-lr", + "10gbase-lrm", + "10gbase-lx4", + "10gbase-sr", + "10gbase-t", + "10gbase-zr", + "25gbase-cr", + "25gbase-er", + "25gbase-lr", + "25gbase-sr", + "25gbase-t", + "40gbase-cr4", + "40gbase-er4", + "40gbase-fr4", + "40gbase-lr4", + "40gbase-sr4", + "50gbase-cr", + "50gbase-er", + "50gbase-fr", + "50gbase-lr", + "50gbase-sr", + "100gbase-cr1", + "100gbase-cr2", + "100gbase-cr4", + "100gbase-cr10", + "100gbase-dr", + "100gbase-er4", + "100gbase-fr1", + "100gbase-lr1", + "100gbase-lr4", + "100gbase-sr1", + "100gbase-sr1.2", + "100gbase-sr2", + "100gbase-sr4", + "100gbase-sr10", + "100gbase-zr", + "200gbase-cr2", + "200gbase-cr4", + "200gbase-sr2", + "200gbase-sr4", + "200gbase-dr4", + "200gbase-er4", + "200gbase-fr4", + "200gbase-lr4", + "200gbase-vr2", + "400gbase-cr4", + "400gbase-dr4", + "400gbase-er8", + "400gbase-fr4", + "400gbase-fr8", + "400gbase-lr4", + "400gbase-lr8", + "400gbase-sr4", + "400gbase-sr4_2", + "400gbase-sr8", + "400gbase-sr16", + "400gbase-vr4", + "400gbase-zr", + "800gbase-cr8", + "800gbase-dr8", + "800gbase-sr8", + "800gbase-vr8", "100base-x-sfp", "1000base-x-gbic", "1000base-x-sfp", @@ -215438,8 +215519,8 @@ "other" ], "type": "string", - "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME FIBER)\n* `100base-lfx` - 100BASE-LFX (10/100ME FIBER)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME Single Pair)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n\n* `ieee802.11ac` - IEEE 802.11ac\n* `ieee802.11ad` - IEEE 802.11ad\n* `ieee802.11ax` - IEEE 802.11ax\n* `ieee802.11ay` - IEEE 802.11ay\n* `ieee802.11be` - IEEE 802.11be\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", - "x-spec-enum-id": "8c4c5e112f77a383" + "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME)\n* `100base-lfx` - 100BASE-LFX (10/100ME)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME)\n* `1000base-bx10-d` - 1000BASE-BX10-D (1GE BiDi Down)\n* `1000base-bx10-u` - 1000BASE-BX10-U (1GE BiDi Up)\n* `1000base-cx` - 1000BASE-CX (1GE DAC)\n* `1000base-cwdm` - 1000BASE-CWDM (1GE)\n* `1000base-dwdm` - 1000BASE-DWDM (1GE)\n* `1000base-ex` - 1000BASE-EX (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lsx` - 1000BASE-LSX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-lx10` - 1000BASE-LX10/LH (1GE)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `1000base-zx` - 1000BASE-ZX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-br-d` - 10GBASE-DR-D (10GE BiDi Down)\n* `10gbase-br-u` - 10GBASE-DR-U (10GE BiDi Up)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE DAC)\n* `10gbase-er` - 10GBASE-ER (10GE)\n* `10gbase-lr` - 10GBASE-LR (10GE)\n* `10gbase-lrm` - 10GBASE-LRM (10GE)\n* `10gbase-lx4` - 10GBASE-LX4 (10GE)\n* `10gbase-sr` - 10GBASE-SR (10GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-zr` - 10GBASE-ZR (10GE)\n* `25gbase-cr` - 25GBASE-CR (25GE DAC)\n* `25gbase-er` - 25GBASE-ER (25GE)\n* `25gbase-lr` - 25GBASE-LR (25GE)\n* `25gbase-sr` - 25GBASE-SR (25GE)\n* `25gbase-t` - 25GBASE-T (25GE)\n* `40gbase-cr4` - 40GBASE-CR4 (40GE DAC)\n* `40gbase-er4` - 40GBASE-ER4 (40GE)\n* `40gbase-fr4` - 40GBASE-FR4 (40GE)\n* `40gbase-lr4` - 40GBASE-LR4 (40GE)\n* `40gbase-sr4` - 40GBASE-SR4 (40GE)\n* `50gbase-cr` - 50GBASE-CR (50GE DAC)\n* `50gbase-er` - 50GBASE-ER (50GE)\n* `50gbase-fr` - 50GBASE-FR (50GE)\n* `50gbase-lr` - 50GBASE-LR (50GE)\n* `50gbase-sr` - 50GBASE-SR (50GE)\n* `100gbase-cr1` - 100GBASE-CR1 (100GE DAC)\n* `100gbase-cr2` - 100GBASE-CR2 (100GE DAC)\n* `100gbase-cr4` - 100GBASE-CR4 (100GE DAC)\n* `100gbase-cr10` - 100GBASE-CR10 (100GE DAC)\n* `100gbase-dr` - 100GBASE-DR (100GE)\n* `100gbase-er4` - 100GBASE-ER4 (100GE)\n* `100gbase-fr1` - 100GBASE-FR1 (100GE)\n* `100gbase-lr1` - 100GBASE-LR1 (100GE)\n* `100gbase-lr4` - 100GBASE-LR4 (100GE)\n* `100gbase-sr1` - 100GBASE-SR1 (100GE)\n* `100gbase-sr1.2` - 100GBASE-SR1.2 (100GE BiDi)\n* `100gbase-sr2` - 100GBASE-SR2 (100GE)\n* `100gbase-sr4` - 100GBASE-SR4 (100GE)\n* `100gbase-sr10` - 100GBASE-SR10 (100GE)\n* `100gbase-zr` - 100GBASE-ZR (100GE)\n* `200gbase-cr2` - 200GBASE-CR2 (200GE)\n* `200gbase-cr4` - 200GBASE-CR4 (200GE)\n* `200gbase-sr2` - 200GBASE-SR2 (200GE)\n* `200gbase-sr4` - 200GBASE-SR4 (200GE)\n* `200gbase-dr4` - 200GBASE-DR4 (200GE)\n* `200gbase-er4` - 200GBASE-ER4 (200GE)\n* `200gbase-fr4` - 200GBASE-FR4 (200GE)\n* `200gbase-lr4` - 200GBASE-LR4 (200GE)\n* `200gbase-vr2` - 200GBASE-VR2 (200GE)\n* `400gbase-cr4` - 400GBASE-CR4 (400GE)\n* `400gbase-dr4` - 400GBASE-DR4 (400GE)\n* `400gbase-er8` - 400GBASE-ER8 (400GE)\n* `400gbase-fr4` - 400GBASE-FR4 (400GE)\n* `400gbase-fr8` - 400GBASE-FR8 (400GE)\n* `400gbase-lr4` - 400GBASE-LR4 (400GE)\n* `400gbase-lr8` - 400GBASE-LR8 (400GE)\n* `400gbase-sr4` - 400GBASE-SR4 (400GE)\n* `400gbase-sr4_2` - 400GBASE-SR4.2 (400GE BiDi)\n* `400gbase-sr8` - 400GBASE-SR8 (400GE)\n* `400gbase-sr16` - 400GBASE-SR16 (400GE)\n* `400gbase-vr4` - 400GBASE-VR4 (400GE)\n* `400gbase-zr` - 400GBASE-ZR (400GE)\n* `800gbase-cr8` - 800GBASE-CR8 (800GE)\n* `800gbase-dr8` - 800GBASE-DR8 (800GE)\n* `800gbase-sr8` - 800GBASE-SR8 (800GE)\n* `800gbase-vr8` - 800GBASE-VR8 (800GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n (Wi-Fi 4)\n* `ieee802.11ac` - IEEE 802.11ac (Wi-Fi 5)\n* `ieee802.11ad` - IEEE 802.11ad (WiGig)\n* `ieee802.11ax` - IEEE 802.11ax (Wi-Fi 6)\n* `ieee802.11ay` - IEEE 802.11ay (WiGig)\n* `ieee802.11be` - IEEE 802.11be (Wi-Fi 7)\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", + "x-spec-enum-id": "efa24ff9c7a39c40" }, "label": { "type": "string", @@ -215447,18 +215528,91 @@ "Virtual", "Bridge", "Link Aggregation Group (LAG)", - "100BASE-FX (10/100ME FIBER)", - "100BASE-LFX (10/100ME FIBER)", + "100BASE-FX (10/100ME)", + "100BASE-LFX (10/100ME)", "100BASE-TX (10/100ME)", - "100BASE-T1 (10/100ME Single Pair)", - "1000BASE-T (1GE)", + "100BASE-T1 (10/100ME)", + "1000BASE-BX10-D (1GE BiDi Down)", + "1000BASE-BX10-U (1GE BiDi Up)", + "1000BASE-CX (1GE DAC)", + "1000BASE-CWDM (1GE)", + "1000BASE-DWDM (1GE)", + "1000BASE-EX (1GE)", "1000BASE-SX (1GE)", + "1000BASE-LSX (1GE)", "1000BASE-LX (1GE)", + "1000BASE-LX10/LH (1GE)", + "1000BASE-T (1GE)", "1000BASE-TX (1GE)", + "1000BASE-ZX (1GE)", "2.5GBASE-T (2.5GE)", "5GBASE-T (5GE)", + "10GBASE-DR-D (10GE BiDi Down)", + "10GBASE-DR-U (10GE BiDi Up)", + "10GBASE-CX4 (10GE DAC)", + "10GBASE-ER (10GE)", + "10GBASE-LR (10GE)", + "10GBASE-LRM (10GE)", + "10GBASE-LX4 (10GE)", + "10GBASE-SR (10GE)", "10GBASE-T (10GE)", - "10GBASE-CX4 (10GE)", + "10GBASE-ZR (10GE)", + "25GBASE-CR (25GE DAC)", + "25GBASE-ER (25GE)", + "25GBASE-LR (25GE)", + "25GBASE-SR (25GE)", + "25GBASE-T (25GE)", + "40GBASE-CR4 (40GE DAC)", + "40GBASE-ER4 (40GE)", + "40GBASE-FR4 (40GE)", + "40GBASE-LR4 (40GE)", + "40GBASE-SR4 (40GE)", + "50GBASE-CR (50GE DAC)", + "50GBASE-ER (50GE)", + "50GBASE-FR (50GE)", + "50GBASE-LR (50GE)", + "50GBASE-SR (50GE)", + "100GBASE-CR1 (100GE DAC)", + "100GBASE-CR2 (100GE DAC)", + "100GBASE-CR4 (100GE DAC)", + "100GBASE-CR10 (100GE DAC)", + "100GBASE-DR (100GE)", + "100GBASE-ER4 (100GE)", + "100GBASE-FR1 (100GE)", + "100GBASE-LR1 (100GE)", + "100GBASE-LR4 (100GE)", + "100GBASE-SR1 (100GE)", + "100GBASE-SR1.2 (100GE BiDi)", + "100GBASE-SR2 (100GE)", + "100GBASE-SR4 (100GE)", + "100GBASE-SR10 (100GE)", + "100GBASE-ZR (100GE)", + "200GBASE-CR2 (200GE)", + "200GBASE-CR4 (200GE)", + "200GBASE-SR2 (200GE)", + "200GBASE-SR4 (200GE)", + "200GBASE-DR4 (200GE)", + "200GBASE-ER4 (200GE)", + "200GBASE-FR4 (200GE)", + "200GBASE-LR4 (200GE)", + "200GBASE-VR2 (200GE)", + "400GBASE-CR4 (400GE)", + "400GBASE-DR4 (400GE)", + "400GBASE-ER8 (400GE)", + "400GBASE-FR4 (400GE)", + "400GBASE-FR8 (400GE)", + "400GBASE-LR4 (400GE)", + "400GBASE-LR8 (400GE)", + "400GBASE-SR4 (400GE)", + "400GBASE-SR4.2 (400GE BiDi)", + "400GBASE-SR8 (400GE)", + "400GBASE-SR16 (400GE)", + "400GBASE-VR4 (400GE)", + "400GBASE-ZR (400GE)", + "800GBASE-CR8 (800GE)", + "800GBASE-DR8 (800GE)", + "800GBASE-SR8 (800GE)", + "800GBASE-VR8 (800GE)", "SFP (100ME)", "GBIC (1GE)", "SFP (1GE)", @@ -215504,12 +215658,12 @@ "100GBASE-KR4 (100GE)", "IEEE 802.11a", "IEEE 802.11b/g", - "IEEE 802.11n", - "IEEE 802.11ac", - "IEEE 802.11ad", - "IEEE 802.11ax", - "IEEE 802.11ay", - "IEEE 802.11be", + "IEEE 802.11n (Wi-Fi 4)", + "IEEE 802.11ac (Wi-Fi 5)", + "IEEE 802.11ad (WiGig)", + "IEEE 802.11ax (Wi-Fi 6)", + "IEEE 802.11ay (WiGig)", + "IEEE 802.11be (Wi-Fi 7)", "IEEE 802.15.1 (Bluetooth)", "IEEE 802.15.4 (LR-WPAN)", "Other (Wireless)", @@ -216447,14 +216601,87 @@ "100base-lfx", "100base-tx", "100base-t1", - "1000base-t", + "1000base-bx10-d", + "1000base-bx10-u", + "1000base-cx", + "1000base-cwdm", + "1000base-dwdm", + "1000base-ex", "1000base-sx", + "1000base-lsx", "1000base-lx", + "1000base-lx10", + "1000base-t", "1000base-tx", + "1000base-zx", "2.5gbase-t", "5gbase-t", - "10gbase-t", + "10gbase-br-d", + "10gbase-br-u", "10gbase-cx4", + "10gbase-er", + "10gbase-lr", + "10gbase-lrm", + "10gbase-lx4", + "10gbase-sr", + "10gbase-t", + "10gbase-zr", + "25gbase-cr", + "25gbase-er", + "25gbase-lr", + "25gbase-sr", + "25gbase-t", + "40gbase-cr4", + "40gbase-er4", + "40gbase-fr4", + "40gbase-lr4", + "40gbase-sr4", + "50gbase-cr", + "50gbase-er", + "50gbase-fr", + "50gbase-lr", + "50gbase-sr", + "100gbase-cr1", + "100gbase-cr2", + "100gbase-cr4", + "100gbase-cr10", + "100gbase-dr", + "100gbase-er4", + "100gbase-fr1", + "100gbase-lr1", + "100gbase-lr4", + "100gbase-sr1", + "100gbase-sr1.2", + "100gbase-sr2", + "100gbase-sr4", + "100gbase-sr10", + "100gbase-zr", + "200gbase-cr2", + "200gbase-cr4", + "200gbase-sr2", + "200gbase-sr4", + "200gbase-dr4", + "200gbase-er4", + "200gbase-fr4", + "200gbase-lr4", + "200gbase-vr2", + "400gbase-cr4", + "400gbase-dr4", + "400gbase-er8", + "400gbase-fr4", + "400gbase-fr8", + "400gbase-lr4", + "400gbase-lr8", + "400gbase-sr4", + "400gbase-sr4_2", + "400gbase-sr8", + "400gbase-sr16", + "400gbase-vr4", + "400gbase-zr", + "800gbase-cr8", + "800gbase-dr8", + "800gbase-sr8", + "800gbase-vr8", "100base-x-sfp", "1000base-x-gbic", "1000base-x-sfp", @@ -216574,8 +216801,8 @@ "other" ], "type": "string", - "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME FIBER)\n* `100base-lfx` - 100BASE-LFX (10/100ME FIBER)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME Single Pair)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n\n* `ieee802.11ac` - IEEE 802.11ac\n* `ieee802.11ad` - IEEE 802.11ad\n* `ieee802.11ax` - IEEE 802.11ax\n* `ieee802.11ay` - IEEE 802.11ay\n* `ieee802.11be` - IEEE 802.11be\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", - "x-spec-enum-id": "8c4c5e112f77a383" + "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME)\n* `100base-lfx` - 100BASE-LFX (10/100ME)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME)\n* `1000base-bx10-d` - 1000BASE-BX10-D (1GE BiDi Down)\n* `1000base-bx10-u` - 1000BASE-BX10-U (1GE BiDi Up)\n* `1000base-cx` - 1000BASE-CX (1GE DAC)\n* `1000base-cwdm` - 1000BASE-CWDM (1GE)\n* `1000base-dwdm` - 1000BASE-DWDM (1GE)\n* `1000base-ex` - 1000BASE-EX (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lsx` - 1000BASE-LSX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-lx10` - 1000BASE-LX10/LH (1GE)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `1000base-zx` - 1000BASE-ZX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-br-d` - 10GBASE-DR-D (10GE BiDi Down)\n* `10gbase-br-u` - 10GBASE-DR-U (10GE BiDi Up)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE DAC)\n* `10gbase-er` - 10GBASE-ER (10GE)\n* `10gbase-lr` - 10GBASE-LR (10GE)\n* `10gbase-lrm` - 10GBASE-LRM (10GE)\n* `10gbase-lx4` - 10GBASE-LX4 (10GE)\n* `10gbase-sr` - 10GBASE-SR (10GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-zr` - 10GBASE-ZR (10GE)\n* `25gbase-cr` - 25GBASE-CR (25GE DAC)\n* `25gbase-er` - 25GBASE-ER (25GE)\n* `25gbase-lr` - 25GBASE-LR (25GE)\n* `25gbase-sr` - 25GBASE-SR (25GE)\n* `25gbase-t` - 25GBASE-T (25GE)\n* `40gbase-cr4` - 40GBASE-CR4 (40GE DAC)\n* `40gbase-er4` - 40GBASE-ER4 (40GE)\n* `40gbase-fr4` - 40GBASE-FR4 (40GE)\n* `40gbase-lr4` - 40GBASE-LR4 (40GE)\n* `40gbase-sr4` - 40GBASE-SR4 (40GE)\n* `50gbase-cr` - 50GBASE-CR (50GE DAC)\n* `50gbase-er` - 50GBASE-ER (50GE)\n* `50gbase-fr` - 50GBASE-FR (50GE)\n* `50gbase-lr` - 50GBASE-LR (50GE)\n* `50gbase-sr` - 50GBASE-SR (50GE)\n* `100gbase-cr1` - 100GBASE-CR1 (100GE DAC)\n* `100gbase-cr2` - 100GBASE-CR2 (100GE DAC)\n* `100gbase-cr4` - 100GBASE-CR4 (100GE DAC)\n* `100gbase-cr10` - 100GBASE-CR10 (100GE DAC)\n* `100gbase-dr` - 100GBASE-DR (100GE)\n* `100gbase-er4` - 100GBASE-ER4 (100GE)\n* `100gbase-fr1` - 100GBASE-FR1 (100GE)\n* `100gbase-lr1` - 100GBASE-LR1 (100GE)\n* `100gbase-lr4` - 100GBASE-LR4 (100GE)\n* `100gbase-sr1` - 100GBASE-SR1 (100GE)\n* `100gbase-sr1.2` - 100GBASE-SR1.2 (100GE BiDi)\n* `100gbase-sr2` - 100GBASE-SR2 (100GE)\n* `100gbase-sr4` - 100GBASE-SR4 (100GE)\n* `100gbase-sr10` - 100GBASE-SR10 (100GE)\n* `100gbase-zr` - 100GBASE-ZR (100GE)\n* `200gbase-cr2` - 200GBASE-CR2 (200GE)\n* `200gbase-cr4` - 200GBASE-CR4 (200GE)\n* `200gbase-sr2` - 200GBASE-SR2 (200GE)\n* `200gbase-sr4` - 200GBASE-SR4 (200GE)\n* `200gbase-dr4` - 200GBASE-DR4 (200GE)\n* `200gbase-er4` - 200GBASE-ER4 (200GE)\n* `200gbase-fr4` - 200GBASE-FR4 (200GE)\n* `200gbase-lr4` - 200GBASE-LR4 (200GE)\n* `200gbase-vr2` - 200GBASE-VR2 (200GE)\n* `400gbase-cr4` - 400GBASE-CR4 (400GE)\n* `400gbase-dr4` - 400GBASE-DR4 (400GE)\n* `400gbase-er8` - 400GBASE-ER8 (400GE)\n* `400gbase-fr4` - 400GBASE-FR4 (400GE)\n* `400gbase-fr8` - 400GBASE-FR8 (400GE)\n* `400gbase-lr4` - 400GBASE-LR4 (400GE)\n* `400gbase-lr8` - 400GBASE-LR8 (400GE)\n* `400gbase-sr4` - 400GBASE-SR4 (400GE)\n* `400gbase-sr4_2` - 400GBASE-SR4.2 (400GE BiDi)\n* `400gbase-sr8` - 400GBASE-SR8 (400GE)\n* `400gbase-sr16` - 400GBASE-SR16 (400GE)\n* `400gbase-vr4` - 400GBASE-VR4 (400GE)\n* `400gbase-zr` - 400GBASE-ZR (400GE)\n* `800gbase-cr8` - 800GBASE-CR8 (800GE)\n* `800gbase-dr8` - 800GBASE-DR8 (800GE)\n* `800gbase-sr8` - 800GBASE-SR8 (800GE)\n* `800gbase-vr8` - 800GBASE-VR8 (800GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n (Wi-Fi 4)\n* `ieee802.11ac` - IEEE 802.11ac (Wi-Fi 5)\n* `ieee802.11ad` - IEEE 802.11ad (WiGig)\n* `ieee802.11ax` - IEEE 802.11ax (Wi-Fi 6)\n* `ieee802.11ay` - IEEE 802.11ay (WiGig)\n* `ieee802.11be` - IEEE 802.11be (Wi-Fi 7)\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", + "x-spec-enum-id": "efa24ff9c7a39c40" }, "enabled": { "type": "boolean" @@ -217093,14 +217320,87 @@ "100base-lfx", "100base-tx", "100base-t1", - "1000base-t", + "1000base-bx10-d", + "1000base-bx10-u", + "1000base-cx", + "1000base-cwdm", + "1000base-dwdm", + "1000base-ex", "1000base-sx", + "1000base-lsx", "1000base-lx", + "1000base-lx10", + "1000base-t", "1000base-tx", + "1000base-zx", "2.5gbase-t", "5gbase-t", - "10gbase-t", + "10gbase-br-d", + "10gbase-br-u", "10gbase-cx4", + "10gbase-er", + "10gbase-lr", + "10gbase-lrm", + "10gbase-lx4", + "10gbase-sr", + "10gbase-t", + "10gbase-zr", + "25gbase-cr", + "25gbase-er", + "25gbase-lr", + "25gbase-sr", + "25gbase-t", + "40gbase-cr4", + "40gbase-er4", + "40gbase-fr4", + "40gbase-lr4", + "40gbase-sr4", + "50gbase-cr", + "50gbase-er", + "50gbase-fr", + "50gbase-lr", + "50gbase-sr", + "100gbase-cr1", + "100gbase-cr2", + "100gbase-cr4", + "100gbase-cr10", + "100gbase-dr", + "100gbase-er4", + "100gbase-fr1", + "100gbase-lr1", + "100gbase-lr4", + "100gbase-sr1", + "100gbase-sr1.2", + "100gbase-sr2", + "100gbase-sr4", + "100gbase-sr10", + "100gbase-zr", + "200gbase-cr2", + "200gbase-cr4", + "200gbase-sr2", + "200gbase-sr4", + "200gbase-dr4", + "200gbase-er4", + "200gbase-fr4", + "200gbase-lr4", + "200gbase-vr2", + "400gbase-cr4", + "400gbase-dr4", + "400gbase-er8", + "400gbase-fr4", + "400gbase-fr8", + "400gbase-lr4", + "400gbase-lr8", + "400gbase-sr4", + "400gbase-sr4_2", + "400gbase-sr8", + "400gbase-sr16", + "400gbase-vr4", + "400gbase-zr", + "800gbase-cr8", + "800gbase-dr8", + "800gbase-sr8", + "800gbase-vr8", "100base-x-sfp", "1000base-x-gbic", "1000base-x-sfp", @@ -217220,8 +217520,8 @@ "other" ], "type": "string", - "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME FIBER)\n* `100base-lfx` - 100BASE-LFX (10/100ME FIBER)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME Single Pair)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n\n* `ieee802.11ac` - IEEE 802.11ac\n* `ieee802.11ad` - IEEE 802.11ad\n* `ieee802.11ax` - IEEE 802.11ax\n* `ieee802.11ay` - IEEE 802.11ay\n* `ieee802.11be` - IEEE 802.11be\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", - "x-spec-enum-id": "8c4c5e112f77a383" + "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME)\n* `100base-lfx` - 100BASE-LFX (10/100ME)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME)\n* `1000base-bx10-d` - 1000BASE-BX10-D (1GE BiDi Down)\n* `1000base-bx10-u` - 1000BASE-BX10-U (1GE BiDi Up)\n* `1000base-cx` - 1000BASE-CX (1GE DAC)\n* `1000base-cwdm` - 1000BASE-CWDM (1GE)\n* `1000base-dwdm` - 1000BASE-DWDM (1GE)\n* `1000base-ex` - 1000BASE-EX (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lsx` - 1000BASE-LSX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-lx10` - 1000BASE-LX10/LH (1GE)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `1000base-zx` - 1000BASE-ZX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-br-d` - 10GBASE-DR-D (10GE BiDi Down)\n* `10gbase-br-u` - 10GBASE-DR-U (10GE BiDi Up)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE DAC)\n* `10gbase-er` - 10GBASE-ER (10GE)\n* `10gbase-lr` - 10GBASE-LR (10GE)\n* `10gbase-lrm` - 10GBASE-LRM (10GE)\n* `10gbase-lx4` - 10GBASE-LX4 (10GE)\n* `10gbase-sr` - 10GBASE-SR (10GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-zr` - 10GBASE-ZR (10GE)\n* `25gbase-cr` - 25GBASE-CR (25GE DAC)\n* `25gbase-er` - 25GBASE-ER (25GE)\n* `25gbase-lr` - 25GBASE-LR (25GE)\n* `25gbase-sr` - 25GBASE-SR (25GE)\n* `25gbase-t` - 25GBASE-T (25GE)\n* `40gbase-cr4` - 40GBASE-CR4 (40GE DAC)\n* `40gbase-er4` - 40GBASE-ER4 (40GE)\n* `40gbase-fr4` - 40GBASE-FR4 (40GE)\n* `40gbase-lr4` - 40GBASE-LR4 (40GE)\n* `40gbase-sr4` - 40GBASE-SR4 (40GE)\n* `50gbase-cr` - 50GBASE-CR (50GE DAC)\n* `50gbase-er` - 50GBASE-ER (50GE)\n* `50gbase-fr` - 50GBASE-FR (50GE)\n* `50gbase-lr` - 50GBASE-LR (50GE)\n* `50gbase-sr` - 50GBASE-SR (50GE)\n* `100gbase-cr1` - 100GBASE-CR1 (100GE DAC)\n* `100gbase-cr2` - 100GBASE-CR2 (100GE DAC)\n* `100gbase-cr4` - 100GBASE-CR4 (100GE DAC)\n* `100gbase-cr10` - 100GBASE-CR10 (100GE DAC)\n* `100gbase-dr` - 100GBASE-DR (100GE)\n* `100gbase-er4` - 100GBASE-ER4 (100GE)\n* `100gbase-fr1` - 100GBASE-FR1 (100GE)\n* `100gbase-lr1` - 100GBASE-LR1 (100GE)\n* `100gbase-lr4` - 100GBASE-LR4 (100GE)\n* `100gbase-sr1` - 100GBASE-SR1 (100GE)\n* `100gbase-sr1.2` - 100GBASE-SR1.2 (100GE BiDi)\n* `100gbase-sr2` - 100GBASE-SR2 (100GE)\n* `100gbase-sr4` - 100GBASE-SR4 (100GE)\n* `100gbase-sr10` - 100GBASE-SR10 (100GE)\n* `100gbase-zr` - 100GBASE-ZR (100GE)\n* `200gbase-cr2` - 200GBASE-CR2 (200GE)\n* `200gbase-cr4` - 200GBASE-CR4 (200GE)\n* `200gbase-sr2` - 200GBASE-SR2 (200GE)\n* `200gbase-sr4` - 200GBASE-SR4 (200GE)\n* `200gbase-dr4` - 200GBASE-DR4 (200GE)\n* `200gbase-er4` - 200GBASE-ER4 (200GE)\n* `200gbase-fr4` - 200GBASE-FR4 (200GE)\n* `200gbase-lr4` - 200GBASE-LR4 (200GE)\n* `200gbase-vr2` - 200GBASE-VR2 (200GE)\n* `400gbase-cr4` - 400GBASE-CR4 (400GE)\n* `400gbase-dr4` - 400GBASE-DR4 (400GE)\n* `400gbase-er8` - 400GBASE-ER8 (400GE)\n* `400gbase-fr4` - 400GBASE-FR4 (400GE)\n* `400gbase-fr8` - 400GBASE-FR8 (400GE)\n* `400gbase-lr4` - 400GBASE-LR4 (400GE)\n* `400gbase-lr8` - 400GBASE-LR8 (400GE)\n* `400gbase-sr4` - 400GBASE-SR4 (400GE)\n* `400gbase-sr4_2` - 400GBASE-SR4.2 (400GE BiDi)\n* `400gbase-sr8` - 400GBASE-SR8 (400GE)\n* `400gbase-sr16` - 400GBASE-SR16 (400GE)\n* `400gbase-vr4` - 400GBASE-VR4 (400GE)\n* `400gbase-zr` - 400GBASE-ZR (400GE)\n* `800gbase-cr8` - 800GBASE-CR8 (800GE)\n* `800gbase-dr8` - 800GBASE-DR8 (800GE)\n* `800gbase-sr8` - 800GBASE-SR8 (800GE)\n* `800gbase-vr8` - 800GBASE-VR8 (800GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n (Wi-Fi 4)\n* `ieee802.11ac` - IEEE 802.11ac (Wi-Fi 5)\n* `ieee802.11ad` - IEEE 802.11ad (WiGig)\n* `ieee802.11ax` - IEEE 802.11ax (Wi-Fi 6)\n* `ieee802.11ay` - IEEE 802.11ay (WiGig)\n* `ieee802.11be` - IEEE 802.11be (Wi-Fi 7)\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", + "x-spec-enum-id": "efa24ff9c7a39c40" }, "label": { "type": "string", @@ -217229,18 +217529,91 @@ "Virtual", "Bridge", "Link Aggregation Group (LAG)", - "100BASE-FX (10/100ME FIBER)", - "100BASE-LFX (10/100ME FIBER)", + "100BASE-FX (10/100ME)", + "100BASE-LFX (10/100ME)", "100BASE-TX (10/100ME)", - "100BASE-T1 (10/100ME Single Pair)", - "1000BASE-T (1GE)", + "100BASE-T1 (10/100ME)", + "1000BASE-BX10-D (1GE BiDi Down)", + "1000BASE-BX10-U (1GE BiDi Up)", + "1000BASE-CX (1GE DAC)", + "1000BASE-CWDM (1GE)", + "1000BASE-DWDM (1GE)", + "1000BASE-EX (1GE)", "1000BASE-SX (1GE)", + "1000BASE-LSX (1GE)", "1000BASE-LX (1GE)", + "1000BASE-LX10/LH (1GE)", + "1000BASE-T (1GE)", "1000BASE-TX (1GE)", + "1000BASE-ZX (1GE)", "2.5GBASE-T (2.5GE)", "5GBASE-T (5GE)", + "10GBASE-DR-D (10GE BiDi Down)", + "10GBASE-DR-U (10GE BiDi Up)", + "10GBASE-CX4 (10GE DAC)", + "10GBASE-ER (10GE)", + "10GBASE-LR (10GE)", + "10GBASE-LRM (10GE)", + "10GBASE-LX4 (10GE)", + "10GBASE-SR (10GE)", "10GBASE-T (10GE)", - "10GBASE-CX4 (10GE)", + "10GBASE-ZR (10GE)", + "25GBASE-CR (25GE DAC)", + "25GBASE-ER (25GE)", + "25GBASE-LR (25GE)", + "25GBASE-SR (25GE)", + "25GBASE-T (25GE)", + "40GBASE-CR4 (40GE DAC)", + "40GBASE-ER4 (40GE)", + "40GBASE-FR4 (40GE)", + "40GBASE-LR4 (40GE)", + "40GBASE-SR4 (40GE)", + "50GBASE-CR (50GE DAC)", + "50GBASE-ER (50GE)", + "50GBASE-FR (50GE)", + "50GBASE-LR (50GE)", + "50GBASE-SR (50GE)", + "100GBASE-CR1 (100GE DAC)", + "100GBASE-CR2 (100GE DAC)", + "100GBASE-CR4 (100GE DAC)", + "100GBASE-CR10 (100GE DAC)", + "100GBASE-DR (100GE)", + "100GBASE-ER4 (100GE)", + "100GBASE-FR1 (100GE)", + "100GBASE-LR1 (100GE)", + "100GBASE-LR4 (100GE)", + "100GBASE-SR1 (100GE)", + "100GBASE-SR1.2 (100GE BiDi)", + "100GBASE-SR2 (100GE)", + "100GBASE-SR4 (100GE)", + "100GBASE-SR10 (100GE)", + "100GBASE-ZR (100GE)", + "200GBASE-CR2 (200GE)", + "200GBASE-CR4 (200GE)", + "200GBASE-SR2 (200GE)", + "200GBASE-SR4 (200GE)", + "200GBASE-DR4 (200GE)", + "200GBASE-ER4 (200GE)", + "200GBASE-FR4 (200GE)", + "200GBASE-LR4 (200GE)", + "200GBASE-VR2 (200GE)", + "400GBASE-CR4 (400GE)", + "400GBASE-DR4 (400GE)", + "400GBASE-ER8 (400GE)", + "400GBASE-FR4 (400GE)", + "400GBASE-FR8 (400GE)", + "400GBASE-LR4 (400GE)", + "400GBASE-LR8 (400GE)", + "400GBASE-SR4 (400GE)", + "400GBASE-SR4.2 (400GE BiDi)", + "400GBASE-SR8 (400GE)", + "400GBASE-SR16 (400GE)", + "400GBASE-VR4 (400GE)", + "400GBASE-ZR (400GE)", + "800GBASE-CR8 (800GE)", + "800GBASE-DR8 (800GE)", + "800GBASE-SR8 (800GE)", + "800GBASE-VR8 (800GE)", "SFP (100ME)", "GBIC (1GE)", "SFP (1GE)", @@ -217286,12 +217659,12 @@ "100GBASE-KR4 (100GE)", "IEEE 802.11a", "IEEE 802.11b/g", - "IEEE 802.11n", - "IEEE 802.11ac", - "IEEE 802.11ad", - "IEEE 802.11ax", - "IEEE 802.11ay", - "IEEE 802.11be", + "IEEE 802.11n (Wi-Fi 4)", + "IEEE 802.11ac (Wi-Fi 5)", + "IEEE 802.11ad (WiGig)", + "IEEE 802.11ax (Wi-Fi 6)", + "IEEE 802.11ay (WiGig)", + "IEEE 802.11be (Wi-Fi 7)", "IEEE 802.15.1 (Bluetooth)", "IEEE 802.15.4 (LR-WPAN)", "Other (Wireless)", @@ -217544,14 +217917,87 @@ "100base-lfx", "100base-tx", "100base-t1", - "1000base-t", + "1000base-bx10-d", + "1000base-bx10-u", + "1000base-cx", + "1000base-cwdm", + "1000base-dwdm", + "1000base-ex", "1000base-sx", + "1000base-lsx", "1000base-lx", + "1000base-lx10", + "1000base-t", "1000base-tx", + "1000base-zx", "2.5gbase-t", "5gbase-t", - "10gbase-t", + "10gbase-br-d", + "10gbase-br-u", "10gbase-cx4", + "10gbase-er", + "10gbase-lr", + "10gbase-lrm", + "10gbase-lx4", + "10gbase-sr", + "10gbase-t", + "10gbase-zr", + "25gbase-cr", + "25gbase-er", + "25gbase-lr", + "25gbase-sr", + "25gbase-t", + "40gbase-cr4", + "40gbase-er4", + "40gbase-fr4", + "40gbase-lr4", + "40gbase-sr4", + "50gbase-cr", + "50gbase-er", + "50gbase-fr", + "50gbase-lr", + "50gbase-sr", + "100gbase-cr1", + "100gbase-cr2", + "100gbase-cr4", + "100gbase-cr10", + "100gbase-dr", + "100gbase-er4", + "100gbase-fr1", + "100gbase-lr1", + "100gbase-lr4", + "100gbase-sr1", + "100gbase-sr1.2", + "100gbase-sr2", + "100gbase-sr4", + "100gbase-sr10", + "100gbase-zr", + "200gbase-cr2", + "200gbase-cr4", + "200gbase-sr2", + "200gbase-sr4", + "200gbase-dr4", + "200gbase-er4", + "200gbase-fr4", + "200gbase-lr4", + "200gbase-vr2", + "400gbase-cr4", + "400gbase-dr4", + "400gbase-er8", + "400gbase-fr4", + "400gbase-fr8", + "400gbase-lr4", + "400gbase-lr8", + "400gbase-sr4", + "400gbase-sr4_2", + "400gbase-sr8", + "400gbase-sr16", + "400gbase-vr4", + "400gbase-zr", + "800gbase-cr8", + "800gbase-dr8", + "800gbase-sr8", + "800gbase-vr8", "100base-x-sfp", "1000base-x-gbic", "1000base-x-sfp", @@ -217671,8 +218117,8 @@ "other" ], "type": "string", - "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME FIBER)\n* `100base-lfx` - 100BASE-LFX (10/100ME FIBER)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME Single Pair)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n\n* `ieee802.11ac` - IEEE 802.11ac\n* `ieee802.11ad` - IEEE 802.11ad\n* `ieee802.11ax` - IEEE 802.11ax\n* `ieee802.11ay` - IEEE 802.11ay\n* `ieee802.11be` - IEEE 802.11be\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", - "x-spec-enum-id": "8c4c5e112f77a383" + "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME)\n* `100base-lfx` - 100BASE-LFX (10/100ME)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME)\n* `1000base-bx10-d` - 1000BASE-BX10-D (1GE BiDi Down)\n* `1000base-bx10-u` - 1000BASE-BX10-U (1GE BiDi Up)\n* `1000base-cx` - 1000BASE-CX (1GE DAC)\n* `1000base-cwdm` - 1000BASE-CWDM (1GE)\n* `1000base-dwdm` - 1000BASE-DWDM (1GE)\n* `1000base-ex` - 1000BASE-EX (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lsx` - 1000BASE-LSX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-lx10` - 1000BASE-LX10/LH (1GE)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `1000base-zx` - 1000BASE-ZX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-br-d` - 10GBASE-DR-D (10GE BiDi Down)\n* `10gbase-br-u` - 10GBASE-DR-U (10GE BiDi Up)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE DAC)\n* `10gbase-er` - 10GBASE-ER (10GE)\n* `10gbase-lr` - 10GBASE-LR (10GE)\n* `10gbase-lrm` - 10GBASE-LRM (10GE)\n* `10gbase-lx4` - 10GBASE-LX4 (10GE)\n* `10gbase-sr` - 10GBASE-SR (10GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-zr` - 10GBASE-ZR (10GE)\n* `25gbase-cr` - 25GBASE-CR (25GE DAC)\n* `25gbase-er` - 25GBASE-ER (25GE)\n* `25gbase-lr` - 25GBASE-LR (25GE)\n* `25gbase-sr` - 25GBASE-SR (25GE)\n* `25gbase-t` - 25GBASE-T (25GE)\n* `40gbase-cr4` - 40GBASE-CR4 (40GE DAC)\n* `40gbase-er4` - 40GBASE-ER4 (40GE)\n* `40gbase-fr4` - 40GBASE-FR4 (40GE)\n* `40gbase-lr4` - 40GBASE-LR4 (40GE)\n* `40gbase-sr4` - 40GBASE-SR4 (40GE)\n* `50gbase-cr` - 50GBASE-CR (50GE DAC)\n* `50gbase-er` - 50GBASE-ER (50GE)\n* `50gbase-fr` - 50GBASE-FR (50GE)\n* `50gbase-lr` - 50GBASE-LR (50GE)\n* `50gbase-sr` - 50GBASE-SR (50GE)\n* `100gbase-cr1` - 100GBASE-CR1 (100GE DAC)\n* `100gbase-cr2` - 100GBASE-CR2 (100GE DAC)\n* `100gbase-cr4` - 100GBASE-CR4 (100GE DAC)\n* `100gbase-cr10` - 100GBASE-CR10 (100GE DAC)\n* `100gbase-dr` - 100GBASE-DR (100GE)\n* `100gbase-er4` - 100GBASE-ER4 (100GE)\n* `100gbase-fr1` - 100GBASE-FR1 (100GE)\n* `100gbase-lr1` - 100GBASE-LR1 (100GE)\n* `100gbase-lr4` - 100GBASE-LR4 (100GE)\n* `100gbase-sr1` - 100GBASE-SR1 (100GE)\n* `100gbase-sr1.2` - 100GBASE-SR1.2 (100GE BiDi)\n* `100gbase-sr2` - 100GBASE-SR2 (100GE)\n* `100gbase-sr4` - 100GBASE-SR4 (100GE)\n* `100gbase-sr10` - 100GBASE-SR10 (100GE)\n* `100gbase-zr` - 100GBASE-ZR (100GE)\n* `200gbase-cr2` - 200GBASE-CR2 (200GE)\n* `200gbase-cr4` - 200GBASE-CR4 (200GE)\n* `200gbase-sr2` - 200GBASE-SR2 (200GE)\n* `200gbase-sr4` - 200GBASE-SR4 (200GE)\n* `200gbase-dr4` - 200GBASE-DR4 (200GE)\n* `200gbase-er4` - 200GBASE-ER4 (200GE)\n* `200gbase-fr4` - 200GBASE-FR4 (200GE)\n* `200gbase-lr4` - 200GBASE-LR4 (200GE)\n* `200gbase-vr2` - 200GBASE-VR2 (200GE)\n* `400gbase-cr4` - 400GBASE-CR4 (400GE)\n* `400gbase-dr4` - 400GBASE-DR4 (400GE)\n* `400gbase-er8` - 400GBASE-ER8 (400GE)\n* `400gbase-fr4` - 400GBASE-FR4 (400GE)\n* `400gbase-fr8` - 400GBASE-FR8 (400GE)\n* `400gbase-lr4` - 400GBASE-LR4 (400GE)\n* `400gbase-lr8` - 400GBASE-LR8 (400GE)\n* `400gbase-sr4` - 400GBASE-SR4 (400GE)\n* `400gbase-sr4_2` - 400GBASE-SR4.2 (400GE BiDi)\n* `400gbase-sr8` - 400GBASE-SR8 (400GE)\n* `400gbase-sr16` - 400GBASE-SR16 (400GE)\n* `400gbase-vr4` - 400GBASE-VR4 (400GE)\n* `400gbase-zr` - 400GBASE-ZR (400GE)\n* `800gbase-cr8` - 800GBASE-CR8 (800GE)\n* `800gbase-dr8` - 800GBASE-DR8 (800GE)\n* `800gbase-sr8` - 800GBASE-SR8 (800GE)\n* `800gbase-vr8` - 800GBASE-VR8 (800GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n (Wi-Fi 4)\n* `ieee802.11ac` - IEEE 802.11ac (Wi-Fi 5)\n* `ieee802.11ad` - IEEE 802.11ad (WiGig)\n* `ieee802.11ax` - IEEE 802.11ax (Wi-Fi 6)\n* `ieee802.11ay` - IEEE 802.11ay (WiGig)\n* `ieee802.11be` - IEEE 802.11be (Wi-Fi 7)\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", + "x-spec-enum-id": "efa24ff9c7a39c40" }, "enabled": { "type": "boolean" @@ -228705,9 +229151,9 @@ "cat7", "cat7a", "cat8", + "mrj21-trunk", "dac-active", "dac-passive", - "mrj21-trunk", "coaxial", "mmf", "mmf-om1", @@ -228719,14 +229165,14 @@ "smf-os1", "smf-os2", "aoc", - "usb", "power", + "usb", "", null ], "type": "string", - "description": "* `cat3` - CAT3\n* `cat5` - CAT5\n* `cat5e` - CAT5e\n* `cat6` - CAT6\n* `cat6a` - CAT6a\n* `cat7` - CAT7\n* `cat7a` - CAT7a\n* `cat8` - CAT8\n* `dac-active` - Direct Attach Copper (Active)\n* `dac-passive` - Direct Attach Copper (Passive)\n* `mrj21-trunk` - MRJ21 Trunk\n* `coaxial` - Coaxial\n* `mmf` - Multimode Fiber\n* `mmf-om1` - Multimode Fiber (OM1)\n* `mmf-om2` - Multimode Fiber (OM2)\n* `mmf-om3` - Multimode Fiber (OM3)\n* `mmf-om4` - Multimode Fiber (OM4)\n* `mmf-om5` - Multimode Fiber (OM5)\n* `smf` - Singlemode Fiber\n* `smf-os1` - Singlemode Fiber (OS1)\n* `smf-os2` - Singlemode Fiber (OS2)\n* `aoc` - Active Optical Cabling (AOC)\n* `usb` - USB\n* `power` - Power", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "description": "* `cat3` - CAT3\n* `cat5` - CAT5\n* `cat5e` - CAT5e\n* `cat6` - CAT6\n* `cat6a` - CAT6a\n* `cat7` - CAT7\n* `cat7a` - CAT7a\n* `cat8` - CAT8\n* `mrj21-trunk` - MRJ21 Trunk\n* `dac-active` - Direct Attach Copper (Active)\n* `dac-passive` - Direct Attach Copper (Passive)\n* `coaxial` - Coaxial\n* `mmf` - Multimode Fiber\n* `mmf-om1` - Multimode Fiber (OM1)\n* `mmf-om2` - Multimode Fiber (OM2)\n* `mmf-om3` - Multimode Fiber (OM3)\n* `mmf-om4` - Multimode Fiber (OM4)\n* `mmf-om5` - Multimode Fiber (OM5)\n* `smf` - Single-mode Fiber\n* `smf-os1` - Single-mode Fiber (OS1)\n* `smf-os2` - Single-mode Fiber (OS2)\n* `aoc` - Active Optical Cabling (AOC)\n* `power` - Power\n* `usb` - USB", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true }, "a_terminations": { @@ -229727,19 +230173,23 @@ "description": "Fields with higher weights appear lower in a form." }, "validation_minimum": { - "type": "integer", - "maximum": 9223372036854775807, - "minimum": -9223372036854775808, - "format": "int64", + "type": "number", + "format": "double", + "maximum": 1000000000000, + "minimum": -1000000000000, + "exclusiveMaximum": true, + "exclusiveMinimum": true, "nullable": true, "title": "Minimum value", "description": "Minimum allowed value (for numeric fields)" }, "validation_maximum": { - "type": "integer", - "maximum": 9223372036854775807, - "minimum": -9223372036854775808, - "format": "int64", + "type": "number", + "format": "double", + "maximum": 1000000000000, + "minimum": -1000000000000, + "exclusiveMaximum": true, + "exclusiveMinimum": true, "nullable": true, "title": "Maximum value", "description": "Maximum allowed value (for numeric fields)" @@ -231357,14 +231807,87 @@ "100base-lfx", "100base-tx", "100base-t1", - "1000base-t", + "1000base-bx10-d", + "1000base-bx10-u", + "1000base-cx", + "1000base-cwdm", + "1000base-dwdm", + "1000base-ex", "1000base-sx", + "1000base-lsx", "1000base-lx", + "1000base-lx10", + "1000base-t", "1000base-tx", + "1000base-zx", "2.5gbase-t", "5gbase-t", - "10gbase-t", + "10gbase-br-d", + "10gbase-br-u", "10gbase-cx4", + "10gbase-er", + "10gbase-lr", + "10gbase-lrm", + "10gbase-lx4", + "10gbase-sr", + "10gbase-t", + "10gbase-zr", + "25gbase-cr", + "25gbase-er", + "25gbase-lr", + "25gbase-sr", + "25gbase-t", + "40gbase-cr4", + "40gbase-er4", + "40gbase-fr4", + "40gbase-lr4", + "40gbase-sr4", + "50gbase-cr", + "50gbase-er", + "50gbase-fr", + "50gbase-lr", + "50gbase-sr", + "100gbase-cr1", + "100gbase-cr2", + "100gbase-cr4", + "100gbase-cr10", + "100gbase-dr", + "100gbase-er4", + "100gbase-fr1", + "100gbase-lr1", + "100gbase-lr4", + "100gbase-sr1", + "100gbase-sr1.2", + "100gbase-sr2", + "100gbase-sr4", + "100gbase-sr10", + "100gbase-zr", + "200gbase-cr2", + "200gbase-cr4", + "200gbase-sr2", + "200gbase-sr4", + "200gbase-dr4", + "200gbase-er4", + "200gbase-fr4", + "200gbase-lr4", + "200gbase-vr2", + "400gbase-cr4", + "400gbase-dr4", + "400gbase-er8", + "400gbase-fr4", + "400gbase-fr8", + "400gbase-lr4", + "400gbase-lr8", + "400gbase-sr4", + "400gbase-sr4_2", + "400gbase-sr8", + "400gbase-sr16", + "400gbase-vr4", + "400gbase-zr", + "800gbase-cr8", + "800gbase-dr8", + "800gbase-sr8", + "800gbase-vr8", "100base-x-sfp", "1000base-x-gbic", "1000base-x-sfp", @@ -231484,8 +232007,8 @@ "other" ], "type": "string", - "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME FIBER)\n* `100base-lfx` - 100BASE-LFX (10/100ME FIBER)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME Single Pair)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n\n* `ieee802.11ac` - IEEE 802.11ac\n* `ieee802.11ad` - IEEE 802.11ad\n* `ieee802.11ax` - IEEE 802.11ax\n* `ieee802.11ay` - IEEE 802.11ay\n* `ieee802.11be` - IEEE 802.11be\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", - "x-spec-enum-id": "8c4c5e112f77a383" + "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME)\n* `100base-lfx` - 100BASE-LFX (10/100ME)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME)\n* `1000base-bx10-d` - 1000BASE-BX10-D (1GE BiDi Down)\n* `1000base-bx10-u` - 1000BASE-BX10-U (1GE BiDi Up)\n* `1000base-cx` - 1000BASE-CX (1GE DAC)\n* `1000base-cwdm` - 1000BASE-CWDM (1GE)\n* `1000base-dwdm` - 1000BASE-DWDM (1GE)\n* `1000base-ex` - 1000BASE-EX (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lsx` - 1000BASE-LSX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-lx10` - 1000BASE-LX10/LH (1GE)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `1000base-zx` - 1000BASE-ZX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-br-d` - 10GBASE-DR-D (10GE BiDi Down)\n* `10gbase-br-u` - 10GBASE-DR-U (10GE BiDi Up)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE DAC)\n* `10gbase-er` - 10GBASE-ER (10GE)\n* `10gbase-lr` - 10GBASE-LR (10GE)\n* `10gbase-lrm` - 10GBASE-LRM (10GE)\n* `10gbase-lx4` - 10GBASE-LX4 (10GE)\n* `10gbase-sr` - 10GBASE-SR (10GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-zr` - 10GBASE-ZR (10GE)\n* `25gbase-cr` - 25GBASE-CR (25GE DAC)\n* `25gbase-er` - 25GBASE-ER (25GE)\n* `25gbase-lr` - 25GBASE-LR (25GE)\n* `25gbase-sr` - 25GBASE-SR (25GE)\n* `25gbase-t` - 25GBASE-T (25GE)\n* `40gbase-cr4` - 40GBASE-CR4 (40GE DAC)\n* `40gbase-er4` - 40GBASE-ER4 (40GE)\n* `40gbase-fr4` - 40GBASE-FR4 (40GE)\n* `40gbase-lr4` - 40GBASE-LR4 (40GE)\n* `40gbase-sr4` - 40GBASE-SR4 (40GE)\n* `50gbase-cr` - 50GBASE-CR (50GE DAC)\n* `50gbase-er` - 50GBASE-ER (50GE)\n* `50gbase-fr` - 50GBASE-FR (50GE)\n* `50gbase-lr` - 50GBASE-LR (50GE)\n* `50gbase-sr` - 50GBASE-SR (50GE)\n* `100gbase-cr1` - 100GBASE-CR1 (100GE DAC)\n* `100gbase-cr2` - 100GBASE-CR2 (100GE DAC)\n* `100gbase-cr4` - 100GBASE-CR4 (100GE DAC)\n* `100gbase-cr10` - 100GBASE-CR10 (100GE DAC)\n* `100gbase-dr` - 100GBASE-DR (100GE)\n* `100gbase-er4` - 100GBASE-ER4 (100GE)\n* `100gbase-fr1` - 100GBASE-FR1 (100GE)\n* `100gbase-lr1` - 100GBASE-LR1 (100GE)\n* `100gbase-lr4` - 100GBASE-LR4 (100GE)\n* `100gbase-sr1` - 100GBASE-SR1 (100GE)\n* `100gbase-sr1.2` - 100GBASE-SR1.2 (100GE BiDi)\n* `100gbase-sr2` - 100GBASE-SR2 (100GE)\n* `100gbase-sr4` - 100GBASE-SR4 (100GE)\n* `100gbase-sr10` - 100GBASE-SR10 (100GE)\n* `100gbase-zr` - 100GBASE-ZR (100GE)\n* `200gbase-cr2` - 200GBASE-CR2 (200GE)\n* `200gbase-cr4` - 200GBASE-CR4 (200GE)\n* `200gbase-sr2` - 200GBASE-SR2 (200GE)\n* `200gbase-sr4` - 200GBASE-SR4 (200GE)\n* `200gbase-dr4` - 200GBASE-DR4 (200GE)\n* `200gbase-er4` - 200GBASE-ER4 (200GE)\n* `200gbase-fr4` - 200GBASE-FR4 (200GE)\n* `200gbase-lr4` - 200GBASE-LR4 (200GE)\n* `200gbase-vr2` - 200GBASE-VR2 (200GE)\n* `400gbase-cr4` - 400GBASE-CR4 (400GE)\n* `400gbase-dr4` - 400GBASE-DR4 (400GE)\n* `400gbase-er8` - 400GBASE-ER8 (400GE)\n* `400gbase-fr4` - 400GBASE-FR4 (400GE)\n* `400gbase-fr8` - 400GBASE-FR8 (400GE)\n* `400gbase-lr4` - 400GBASE-LR4 (400GE)\n* `400gbase-lr8` - 400GBASE-LR8 (400GE)\n* `400gbase-sr4` - 400GBASE-SR4 (400GE)\n* `400gbase-sr4_2` - 400GBASE-SR4.2 (400GE BiDi)\n* `400gbase-sr8` - 400GBASE-SR8 (400GE)\n* `400gbase-sr16` - 400GBASE-SR16 (400GE)\n* `400gbase-vr4` - 400GBASE-VR4 (400GE)\n* `400gbase-zr` - 400GBASE-ZR (400GE)\n* `800gbase-cr8` - 800GBASE-CR8 (800GE)\n* `800gbase-dr8` - 800GBASE-DR8 (800GE)\n* `800gbase-sr8` - 800GBASE-SR8 (800GE)\n* `800gbase-vr8` - 800GBASE-VR8 (800GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n (Wi-Fi 4)\n* `ieee802.11ac` - IEEE 802.11ac (Wi-Fi 5)\n* `ieee802.11ad` - IEEE 802.11ad (WiGig)\n* `ieee802.11ax` - IEEE 802.11ax (Wi-Fi 6)\n* `ieee802.11ay` - IEEE 802.11ay (WiGig)\n* `ieee802.11be` - IEEE 802.11be (Wi-Fi 7)\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", + "x-spec-enum-id": "efa24ff9c7a39c40" }, "enabled": { "type": "boolean" @@ -232002,14 +232525,87 @@ "100base-lfx", "100base-tx", "100base-t1", - "1000base-t", + "1000base-bx10-d", + "1000base-bx10-u", + "1000base-cx", + "1000base-cwdm", + "1000base-dwdm", + "1000base-ex", "1000base-sx", + "1000base-lsx", "1000base-lx", + "1000base-lx10", + "1000base-t", "1000base-tx", + "1000base-zx", "2.5gbase-t", "5gbase-t", - "10gbase-t", + "10gbase-br-d", + "10gbase-br-u", "10gbase-cx4", + "10gbase-er", + "10gbase-lr", + "10gbase-lrm", + "10gbase-lx4", + "10gbase-sr", + "10gbase-t", + "10gbase-zr", + "25gbase-cr", + "25gbase-er", + "25gbase-lr", + "25gbase-sr", + "25gbase-t", + "40gbase-cr4", + "40gbase-er4", + "40gbase-fr4", + "40gbase-lr4", + "40gbase-sr4", + "50gbase-cr", + "50gbase-er", + "50gbase-fr", + "50gbase-lr", + "50gbase-sr", + "100gbase-cr1", + "100gbase-cr2", + "100gbase-cr4", + "100gbase-cr10", + "100gbase-dr", + "100gbase-er4", + "100gbase-fr1", + "100gbase-lr1", + "100gbase-lr4", + "100gbase-sr1", + "100gbase-sr1.2", + "100gbase-sr2", + "100gbase-sr4", + "100gbase-sr10", + "100gbase-zr", + "200gbase-cr2", + "200gbase-cr4", + "200gbase-sr2", + "200gbase-sr4", + "200gbase-dr4", + "200gbase-er4", + "200gbase-fr4", + "200gbase-lr4", + "200gbase-vr2", + "400gbase-cr4", + "400gbase-dr4", + "400gbase-er8", + "400gbase-fr4", + "400gbase-fr8", + "400gbase-lr4", + "400gbase-lr8", + "400gbase-sr4", + "400gbase-sr4_2", + "400gbase-sr8", + "400gbase-sr16", + "400gbase-vr4", + "400gbase-zr", + "800gbase-cr8", + "800gbase-dr8", + "800gbase-sr8", + "800gbase-vr8", "100base-x-sfp", "1000base-x-gbic", "1000base-x-sfp", @@ -232129,8 +232725,8 @@ "other" ], "type": "string", - "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME FIBER)\n* `100base-lfx` - 100BASE-LFX (10/100ME FIBER)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME Single Pair)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n\n* `ieee802.11ac` - IEEE 802.11ac\n* `ieee802.11ad` - IEEE 802.11ad\n* `ieee802.11ax` - IEEE 802.11ax\n* `ieee802.11ay` - IEEE 802.11ay\n* `ieee802.11be` - IEEE 802.11be\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", - "x-spec-enum-id": "8c4c5e112f77a383" + "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME)\n* `100base-lfx` - 100BASE-LFX (10/100ME)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME)\n* `1000base-bx10-d` - 1000BASE-BX10-D (1GE BiDi Down)\n* `1000base-bx10-u` - 1000BASE-BX10-U (1GE BiDi Up)\n* `1000base-cx` - 1000BASE-CX (1GE DAC)\n* `1000base-cwdm` - 1000BASE-CWDM (1GE)\n* `1000base-dwdm` - 1000BASE-DWDM (1GE)\n* `1000base-ex` - 1000BASE-EX (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lsx` - 1000BASE-LSX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-lx10` - 1000BASE-LX10/LH (1GE)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `1000base-zx` - 1000BASE-ZX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-br-d` - 10GBASE-DR-D (10GE BiDi Down)\n* `10gbase-br-u` - 10GBASE-DR-U (10GE BiDi Up)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE DAC)\n* `10gbase-er` - 10GBASE-ER (10GE)\n* `10gbase-lr` - 10GBASE-LR (10GE)\n* `10gbase-lrm` - 10GBASE-LRM (10GE)\n* `10gbase-lx4` - 10GBASE-LX4 (10GE)\n* `10gbase-sr` - 10GBASE-SR (10GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-zr` - 10GBASE-ZR (10GE)\n* `25gbase-cr` - 25GBASE-CR (25GE DAC)\n* `25gbase-er` - 25GBASE-ER (25GE)\n* `25gbase-lr` - 25GBASE-LR (25GE)\n* `25gbase-sr` - 25GBASE-SR (25GE)\n* `25gbase-t` - 25GBASE-T (25GE)\n* `40gbase-cr4` - 40GBASE-CR4 (40GE DAC)\n* `40gbase-er4` - 40GBASE-ER4 (40GE)\n* `40gbase-fr4` - 40GBASE-FR4 (40GE)\n* `40gbase-lr4` - 40GBASE-LR4 (40GE)\n* `40gbase-sr4` - 40GBASE-SR4 (40GE)\n* `50gbase-cr` - 50GBASE-CR (50GE DAC)\n* `50gbase-er` - 50GBASE-ER (50GE)\n* `50gbase-fr` - 50GBASE-FR (50GE)\n* `50gbase-lr` - 50GBASE-LR (50GE)\n* `50gbase-sr` - 50GBASE-SR (50GE)\n* `100gbase-cr1` - 100GBASE-CR1 (100GE DAC)\n* `100gbase-cr2` - 100GBASE-CR2 (100GE DAC)\n* `100gbase-cr4` - 100GBASE-CR4 (100GE DAC)\n* `100gbase-cr10` - 100GBASE-CR10 (100GE DAC)\n* `100gbase-dr` - 100GBASE-DR (100GE)\n* `100gbase-er4` - 100GBASE-ER4 (100GE)\n* `100gbase-fr1` - 100GBASE-FR1 (100GE)\n* `100gbase-lr1` - 100GBASE-LR1 (100GE)\n* `100gbase-lr4` - 100GBASE-LR4 (100GE)\n* `100gbase-sr1` - 100GBASE-SR1 (100GE)\n* `100gbase-sr1.2` - 100GBASE-SR1.2 (100GE BiDi)\n* `100gbase-sr2` - 100GBASE-SR2 (100GE)\n* `100gbase-sr4` - 100GBASE-SR4 (100GE)\n* `100gbase-sr10` - 100GBASE-SR10 (100GE)\n* `100gbase-zr` - 100GBASE-ZR (100GE)\n* `200gbase-cr2` - 200GBASE-CR2 (200GE)\n* `200gbase-cr4` - 200GBASE-CR4 (200GE)\n* `200gbase-sr2` - 200GBASE-SR2 (200GE)\n* `200gbase-sr4` - 200GBASE-SR4 (200GE)\n* `200gbase-dr4` - 200GBASE-DR4 (200GE)\n* `200gbase-er4` - 200GBASE-ER4 (200GE)\n* `200gbase-fr4` - 200GBASE-FR4 (200GE)\n* `200gbase-lr4` - 200GBASE-LR4 (200GE)\n* `200gbase-vr2` - 200GBASE-VR2 (200GE)\n* `400gbase-cr4` - 400GBASE-CR4 (400GE)\n* `400gbase-dr4` - 400GBASE-DR4 (400GE)\n* `400gbase-er8` - 400GBASE-ER8 (400GE)\n* `400gbase-fr4` - 400GBASE-FR4 (400GE)\n* `400gbase-fr8` - 400GBASE-FR8 (400GE)\n* `400gbase-lr4` - 400GBASE-LR4 (400GE)\n* `400gbase-lr8` - 400GBASE-LR8 (400GE)\n* `400gbase-sr4` - 400GBASE-SR4 (400GE)\n* `400gbase-sr4_2` - 400GBASE-SR4.2 (400GE BiDi)\n* `400gbase-sr8` - 400GBASE-SR8 (400GE)\n* `400gbase-sr16` - 400GBASE-SR16 (400GE)\n* `400gbase-vr4` - 400GBASE-VR4 (400GE)\n* `400gbase-zr` - 400GBASE-ZR (400GE)\n* `800gbase-cr8` - 800GBASE-CR8 (800GE)\n* `800gbase-dr8` - 800GBASE-DR8 (800GE)\n* `800gbase-sr8` - 800GBASE-SR8 (800GE)\n* `800gbase-vr8` - 800GBASE-VR8 (800GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n (Wi-Fi 4)\n* `ieee802.11ac` - IEEE 802.11ac (Wi-Fi 5)\n* `ieee802.11ad` - IEEE 802.11ad (WiGig)\n* `ieee802.11ax` - IEEE 802.11ax (Wi-Fi 6)\n* `ieee802.11ay` - IEEE 802.11ay (WiGig)\n* `ieee802.11be` - IEEE 802.11be (Wi-Fi 7)\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", + "x-spec-enum-id": "efa24ff9c7a39c40" }, "enabled": { "type": "boolean" @@ -248783,9 +249379,9 @@ "cat7", "cat7a", "cat8", + "mrj21-trunk", "dac-active", "dac-passive", - "mrj21-trunk", "coaxial", "mmf", "mmf-om1", @@ -248797,14 +249393,14 @@ "smf-os1", "smf-os2", "aoc", - "usb", "power", + "usb", "", null ], "type": "string", - "description": "* `cat3` - CAT3\n* `cat5` - CAT5\n* `cat5e` - CAT5e\n* `cat6` - CAT6\n* `cat6a` - CAT6a\n* `cat7` - CAT7\n* `cat7a` - CAT7a\n* `cat8` - CAT8\n* `dac-active` - Direct Attach Copper (Active)\n* `dac-passive` - Direct Attach Copper (Passive)\n* `mrj21-trunk` - MRJ21 Trunk\n* `coaxial` - Coaxial\n* `mmf` - Multimode Fiber\n* `mmf-om1` - Multimode Fiber (OM1)\n* `mmf-om2` - Multimode Fiber (OM2)\n* `mmf-om3` - Multimode Fiber (OM3)\n* `mmf-om4` - Multimode Fiber (OM4)\n* `mmf-om5` - Multimode Fiber (OM5)\n* `smf` - Singlemode Fiber\n* `smf-os1` - Singlemode Fiber (OS1)\n* `smf-os2` - Singlemode Fiber (OS2)\n* `aoc` - Active Optical Cabling (AOC)\n* `usb` - USB\n* `power` - Power", - "x-spec-enum-id": "7b11d524b2b1a7ef", + "description": "* `cat3` - CAT3\n* `cat5` - CAT5\n* `cat5e` - CAT5e\n* `cat6` - CAT6\n* `cat6a` - CAT6a\n* `cat7` - CAT7\n* `cat7a` - CAT7a\n* `cat8` - CAT8\n* `mrj21-trunk` - MRJ21 Trunk\n* `dac-active` - Direct Attach Copper (Active)\n* `dac-passive` - Direct Attach Copper (Passive)\n* `coaxial` - Coaxial\n* `mmf` - Multimode Fiber\n* `mmf-om1` - Multimode Fiber (OM1)\n* `mmf-om2` - Multimode Fiber (OM2)\n* `mmf-om3` - Multimode Fiber (OM3)\n* `mmf-om4` - Multimode Fiber (OM4)\n* `mmf-om5` - Multimode Fiber (OM5)\n* `smf` - Single-mode Fiber\n* `smf-os1` - Single-mode Fiber (OS1)\n* `smf-os2` - Single-mode Fiber (OS2)\n* `aoc` - Active Optical Cabling (AOC)\n* `power` - Power\n* `usb` - USB", + "x-spec-enum-id": "c731f2793fceac04", "nullable": true }, "a_terminations": { @@ -249846,19 +250442,23 @@ "description": "Fields with higher weights appear lower in a form." }, "validation_minimum": { - "type": "integer", - "maximum": 9223372036854775807, - "minimum": -9223372036854775808, - "format": "int64", + "type": "number", + "format": "double", + "maximum": 1000000000000, + "minimum": -1000000000000, + "exclusiveMaximum": true, + "exclusiveMinimum": true, "nullable": true, "title": "Minimum value", "description": "Minimum allowed value (for numeric fields)" }, "validation_maximum": { - "type": "integer", - "maximum": 9223372036854775807, - "minimum": -9223372036854775808, - "format": "int64", + "type": "number", + "format": "double", + "maximum": 1000000000000, + "minimum": -1000000000000, + "exclusiveMaximum": true, + "exclusiveMinimum": true, "nullable": true, "title": "Maximum value", "description": "Maximum allowed value (for numeric fields)" @@ -251544,14 +252144,87 @@ "100base-lfx", "100base-tx", "100base-t1", - "1000base-t", + "1000base-bx10-d", + "1000base-bx10-u", + "1000base-cx", + "1000base-cwdm", + "1000base-dwdm", + "1000base-ex", "1000base-sx", + "1000base-lsx", "1000base-lx", + "1000base-lx10", + "1000base-t", "1000base-tx", + "1000base-zx", "2.5gbase-t", "5gbase-t", - "10gbase-t", + "10gbase-br-d", + "10gbase-br-u", "10gbase-cx4", + "10gbase-er", + "10gbase-lr", + "10gbase-lrm", + "10gbase-lx4", + "10gbase-sr", + "10gbase-t", + "10gbase-zr", + "25gbase-cr", + "25gbase-er", + "25gbase-lr", + "25gbase-sr", + "25gbase-t", + "40gbase-cr4", + "40gbase-er4", + "40gbase-fr4", + "40gbase-lr4", + "40gbase-sr4", + "50gbase-cr", + "50gbase-er", + "50gbase-fr", + "50gbase-lr", + "50gbase-sr", + "100gbase-cr1", + "100gbase-cr2", + "100gbase-cr4", + "100gbase-cr10", + "100gbase-dr", + "100gbase-er4", + "100gbase-fr1", + "100gbase-lr1", + "100gbase-lr4", + "100gbase-sr1", + "100gbase-sr1.2", + "100gbase-sr2", + "100gbase-sr4", + "100gbase-sr10", + "100gbase-zr", + "200gbase-cr2", + "200gbase-cr4", + "200gbase-sr2", + "200gbase-sr4", + "200gbase-dr4", + "200gbase-er4", + "200gbase-fr4", + "200gbase-lr4", + "200gbase-vr2", + "400gbase-cr4", + "400gbase-dr4", + "400gbase-er8", + "400gbase-fr4", + "400gbase-fr8", + "400gbase-lr4", + "400gbase-lr8", + "400gbase-sr4", + "400gbase-sr4_2", + "400gbase-sr8", + "400gbase-sr16", + "400gbase-vr4", + "400gbase-zr", + "800gbase-cr8", + "800gbase-dr8", + "800gbase-sr8", + "800gbase-vr8", "100base-x-sfp", "1000base-x-gbic", "1000base-x-sfp", @@ -251671,8 +252344,8 @@ "other" ], "type": "string", - "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME FIBER)\n* `100base-lfx` - 100BASE-LFX (10/100ME FIBER)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME Single Pair)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n\n* `ieee802.11ac` - IEEE 802.11ac\n* `ieee802.11ad` - IEEE 802.11ad\n* `ieee802.11ax` - IEEE 802.11ax\n* `ieee802.11ay` - IEEE 802.11ay\n* `ieee802.11be` - IEEE 802.11be\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", - "x-spec-enum-id": "8c4c5e112f77a383" + "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME)\n* `100base-lfx` - 100BASE-LFX (10/100ME)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME)\n* `1000base-bx10-d` - 1000BASE-BX10-D (1GE BiDi Down)\n* `1000base-bx10-u` - 1000BASE-BX10-U (1GE BiDi Up)\n* `1000base-cx` - 1000BASE-CX (1GE DAC)\n* `1000base-cwdm` - 1000BASE-CWDM (1GE)\n* `1000base-dwdm` - 1000BASE-DWDM (1GE)\n* `1000base-ex` - 1000BASE-EX (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lsx` - 1000BASE-LSX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-lx10` - 1000BASE-LX10/LH (1GE)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `1000base-zx` - 1000BASE-ZX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-br-d` - 10GBASE-DR-D (10GE BiDi Down)\n* `10gbase-br-u` - 10GBASE-DR-U (10GE BiDi Up)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE DAC)\n* `10gbase-er` - 10GBASE-ER (10GE)\n* `10gbase-lr` - 10GBASE-LR (10GE)\n* `10gbase-lrm` - 10GBASE-LRM (10GE)\n* `10gbase-lx4` - 10GBASE-LX4 (10GE)\n* `10gbase-sr` - 10GBASE-SR (10GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-zr` - 10GBASE-ZR (10GE)\n* `25gbase-cr` - 25GBASE-CR (25GE DAC)\n* `25gbase-er` - 25GBASE-ER (25GE)\n* `25gbase-lr` - 25GBASE-LR (25GE)\n* `25gbase-sr` - 25GBASE-SR (25GE)\n* `25gbase-t` - 25GBASE-T (25GE)\n* `40gbase-cr4` - 40GBASE-CR4 (40GE DAC)\n* `40gbase-er4` - 40GBASE-ER4 (40GE)\n* `40gbase-fr4` - 40GBASE-FR4 (40GE)\n* `40gbase-lr4` - 40GBASE-LR4 (40GE)\n* `40gbase-sr4` - 40GBASE-SR4 (40GE)\n* `50gbase-cr` - 50GBASE-CR (50GE DAC)\n* `50gbase-er` - 50GBASE-ER (50GE)\n* `50gbase-fr` - 50GBASE-FR (50GE)\n* `50gbase-lr` - 50GBASE-LR (50GE)\n* `50gbase-sr` - 50GBASE-SR (50GE)\n* `100gbase-cr1` - 100GBASE-CR1 (100GE DAC)\n* `100gbase-cr2` - 100GBASE-CR2 (100GE DAC)\n* `100gbase-cr4` - 100GBASE-CR4 (100GE DAC)\n* `100gbase-cr10` - 100GBASE-CR10 (100GE DAC)\n* `100gbase-dr` - 100GBASE-DR (100GE)\n* `100gbase-er4` - 100GBASE-ER4 (100GE)\n* `100gbase-fr1` - 100GBASE-FR1 (100GE)\n* `100gbase-lr1` - 100GBASE-LR1 (100GE)\n* `100gbase-lr4` - 100GBASE-LR4 (100GE)\n* `100gbase-sr1` - 100GBASE-SR1 (100GE)\n* `100gbase-sr1.2` - 100GBASE-SR1.2 (100GE BiDi)\n* `100gbase-sr2` - 100GBASE-SR2 (100GE)\n* `100gbase-sr4` - 100GBASE-SR4 (100GE)\n* `100gbase-sr10` - 100GBASE-SR10 (100GE)\n* `100gbase-zr` - 100GBASE-ZR (100GE)\n* `200gbase-cr2` - 200GBASE-CR2 (200GE)\n* `200gbase-cr4` - 200GBASE-CR4 (200GE)\n* `200gbase-sr2` - 200GBASE-SR2 (200GE)\n* `200gbase-sr4` - 200GBASE-SR4 (200GE)\n* `200gbase-dr4` - 200GBASE-DR4 (200GE)\n* `200gbase-er4` - 200GBASE-ER4 (200GE)\n* `200gbase-fr4` - 200GBASE-FR4 (200GE)\n* `200gbase-lr4` - 200GBASE-LR4 (200GE)\n* `200gbase-vr2` - 200GBASE-VR2 (200GE)\n* `400gbase-cr4` - 400GBASE-CR4 (400GE)\n* `400gbase-dr4` - 400GBASE-DR4 (400GE)\n* `400gbase-er8` - 400GBASE-ER8 (400GE)\n* `400gbase-fr4` - 400GBASE-FR4 (400GE)\n* `400gbase-fr8` - 400GBASE-FR8 (400GE)\n* `400gbase-lr4` - 400GBASE-LR4 (400GE)\n* `400gbase-lr8` - 400GBASE-LR8 (400GE)\n* `400gbase-sr4` - 400GBASE-SR4 (400GE)\n* `400gbase-sr4_2` - 400GBASE-SR4.2 (400GE BiDi)\n* `400gbase-sr8` - 400GBASE-SR8 (400GE)\n* `400gbase-sr16` - 400GBASE-SR16 (400GE)\n* `400gbase-vr4` - 400GBASE-VR4 (400GE)\n* `400gbase-zr` - 400GBASE-ZR (400GE)\n* `800gbase-cr8` - 800GBASE-CR8 (800GE)\n* `800gbase-dr8` - 800GBASE-DR8 (800GE)\n* `800gbase-sr8` - 800GBASE-SR8 (800GE)\n* `800gbase-vr8` - 800GBASE-VR8 (800GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n (Wi-Fi 4)\n* `ieee802.11ac` - IEEE 802.11ac (Wi-Fi 5)\n* `ieee802.11ad` - IEEE 802.11ad (WiGig)\n* `ieee802.11ax` - IEEE 802.11ax (Wi-Fi 6)\n* `ieee802.11ay` - IEEE 802.11ay (WiGig)\n* `ieee802.11be` - IEEE 802.11be (Wi-Fi 7)\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", + "x-spec-enum-id": "efa24ff9c7a39c40" }, "enabled": { "type": "boolean" @@ -252194,14 +252867,87 @@ "100base-lfx", "100base-tx", "100base-t1", - "1000base-t", + "1000base-bx10-d", + "1000base-bx10-u", + "1000base-cx", + "1000base-cwdm", + "1000base-dwdm", + "1000base-ex", "1000base-sx", + "1000base-lsx", "1000base-lx", + "1000base-lx10", + "1000base-t", "1000base-tx", + "1000base-zx", "2.5gbase-t", "5gbase-t", - "10gbase-t", + "10gbase-br-d", + "10gbase-br-u", "10gbase-cx4", + "10gbase-er", + "10gbase-lr", + "10gbase-lrm", + "10gbase-lx4", + "10gbase-sr", + "10gbase-t", + "10gbase-zr", + "25gbase-cr", + "25gbase-er", + "25gbase-lr", + "25gbase-sr", + "25gbase-t", + "40gbase-cr4", + "40gbase-er4", + "40gbase-fr4", + "40gbase-lr4", + "40gbase-sr4", + "50gbase-cr", + "50gbase-er", + "50gbase-fr", + "50gbase-lr", + "50gbase-sr", + "100gbase-cr1", + "100gbase-cr2", + "100gbase-cr4", + "100gbase-cr10", + "100gbase-dr", + "100gbase-er4", + "100gbase-fr1", + "100gbase-lr1", + "100gbase-lr4", + "100gbase-sr1", + "100gbase-sr1.2", + "100gbase-sr2", + "100gbase-sr4", + "100gbase-sr10", + "100gbase-zr", + "200gbase-cr2", + "200gbase-cr4", + "200gbase-sr2", + "200gbase-sr4", + "200gbase-dr4", + "200gbase-er4", + "200gbase-fr4", + "200gbase-lr4", + "200gbase-vr2", + "400gbase-cr4", + "400gbase-dr4", + "400gbase-er8", + "400gbase-fr4", + "400gbase-fr8", + "400gbase-lr4", + "400gbase-lr8", + "400gbase-sr4", + "400gbase-sr4_2", + "400gbase-sr8", + "400gbase-sr16", + "400gbase-vr4", + "400gbase-zr", + "800gbase-cr8", + "800gbase-dr8", + "800gbase-sr8", + "800gbase-vr8", "100base-x-sfp", "1000base-x-gbic", "1000base-x-sfp", @@ -252321,8 +253067,8 @@ "other" ], "type": "string", - "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME FIBER)\n* `100base-lfx` - 100BASE-LFX (10/100ME FIBER)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME Single Pair)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n\n* `ieee802.11ac` - IEEE 802.11ac\n* `ieee802.11ad` - IEEE 802.11ad\n* `ieee802.11ax` - IEEE 802.11ax\n* `ieee802.11ay` - IEEE 802.11ay\n* `ieee802.11be` - IEEE 802.11be\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", - "x-spec-enum-id": "8c4c5e112f77a383" + "description": "* `virtual` - Virtual\n* `bridge` - Bridge\n* `lag` - Link Aggregation Group (LAG)\n* `100base-fx` - 100BASE-FX (10/100ME)\n* `100base-lfx` - 100BASE-LFX (10/100ME)\n* `100base-tx` - 100BASE-TX (10/100ME)\n* `100base-t1` - 100BASE-T1 (10/100ME)\n* `1000base-bx10-d` - 1000BASE-BX10-D (1GE BiDi Down)\n* `1000base-bx10-u` - 1000BASE-BX10-U (1GE BiDi Up)\n* `1000base-cx` - 1000BASE-CX (1GE DAC)\n* `1000base-cwdm` - 1000BASE-CWDM (1GE)\n* `1000base-dwdm` - 1000BASE-DWDM (1GE)\n* `1000base-ex` - 1000BASE-EX (1GE)\n* `1000base-sx` - 1000BASE-SX (1GE)\n* `1000base-lsx` - 1000BASE-LSX (1GE)\n* `1000base-lx` - 1000BASE-LX (1GE)\n* `1000base-lx10` - 1000BASE-LX10/LH (1GE)\n* `1000base-t` - 1000BASE-T (1GE)\n* `1000base-tx` - 1000BASE-TX (1GE)\n* `1000base-zx` - 1000BASE-ZX (1GE)\n* `2.5gbase-t` - 2.5GBASE-T (2.5GE)\n* `5gbase-t` - 5GBASE-T (5GE)\n* `10gbase-br-d` - 10GBASE-DR-D (10GE BiDi Down)\n* `10gbase-br-u` - 10GBASE-DR-U (10GE BiDi Up)\n* `10gbase-cx4` - 10GBASE-CX4 (10GE DAC)\n* `10gbase-er` - 10GBASE-ER (10GE)\n* `10gbase-lr` - 10GBASE-LR (10GE)\n* `10gbase-lrm` - 10GBASE-LRM (10GE)\n* `10gbase-lx4` - 10GBASE-LX4 (10GE)\n* `10gbase-sr` - 10GBASE-SR (10GE)\n* `10gbase-t` - 10GBASE-T (10GE)\n* `10gbase-zr` - 10GBASE-ZR (10GE)\n* `25gbase-cr` - 25GBASE-CR (25GE DAC)\n* `25gbase-er` - 25GBASE-ER (25GE)\n* `25gbase-lr` - 25GBASE-LR (25GE)\n* `25gbase-sr` - 25GBASE-SR (25GE)\n* `25gbase-t` - 25GBASE-T (25GE)\n* `40gbase-cr4` - 40GBASE-CR4 (40GE DAC)\n* `40gbase-er4` - 40GBASE-ER4 (40GE)\n* `40gbase-fr4` - 40GBASE-FR4 (40GE)\n* `40gbase-lr4` - 40GBASE-LR4 (40GE)\n* `40gbase-sr4` - 40GBASE-SR4 (40GE)\n* `50gbase-cr` - 50GBASE-CR (50GE DAC)\n* `50gbase-er` - 50GBASE-ER (50GE)\n* `50gbase-fr` - 50GBASE-FR (50GE)\n* `50gbase-lr` - 50GBASE-LR (50GE)\n* `50gbase-sr` - 50GBASE-SR (50GE)\n* `100gbase-cr1` - 100GBASE-CR1 (100GE DAC)\n* `100gbase-cr2` - 100GBASE-CR2 (100GE DAC)\n* `100gbase-cr4` - 100GBASE-CR4 (100GE DAC)\n* `100gbase-cr10` - 100GBASE-CR10 (100GE DAC)\n* `100gbase-dr` - 100GBASE-DR (100GE)\n* `100gbase-er4` - 100GBASE-ER4 (100GE)\n* `100gbase-fr1` - 100GBASE-FR1 (100GE)\n* `100gbase-lr1` - 100GBASE-LR1 (100GE)\n* `100gbase-lr4` - 100GBASE-LR4 (100GE)\n* `100gbase-sr1` - 100GBASE-SR1 (100GE)\n* `100gbase-sr1.2` - 100GBASE-SR1.2 (100GE BiDi)\n* `100gbase-sr2` - 100GBASE-SR2 (100GE)\n* `100gbase-sr4` - 100GBASE-SR4 (100GE)\n* `100gbase-sr10` - 100GBASE-SR10 (100GE)\n* `100gbase-zr` - 100GBASE-ZR (100GE)\n* `200gbase-cr2` - 200GBASE-CR2 (200GE)\n* `200gbase-cr4` - 200GBASE-CR4 (200GE)\n* `200gbase-sr2` - 200GBASE-SR2 (200GE)\n* `200gbase-sr4` - 200GBASE-SR4 (200GE)\n* `200gbase-dr4` - 200GBASE-DR4 (200GE)\n* `200gbase-er4` - 200GBASE-ER4 (200GE)\n* `200gbase-fr4` - 200GBASE-FR4 (200GE)\n* `200gbase-lr4` - 200GBASE-LR4 (200GE)\n* `200gbase-vr2` - 200GBASE-VR2 (200GE)\n* `400gbase-cr4` - 400GBASE-CR4 (400GE)\n* `400gbase-dr4` - 400GBASE-DR4 (400GE)\n* `400gbase-er8` - 400GBASE-ER8 (400GE)\n* `400gbase-fr4` - 400GBASE-FR4 (400GE)\n* `400gbase-fr8` - 400GBASE-FR8 (400GE)\n* `400gbase-lr4` - 400GBASE-LR4 (400GE)\n* `400gbase-lr8` - 400GBASE-LR8 (400GE)\n* `400gbase-sr4` - 400GBASE-SR4 (400GE)\n* `400gbase-sr4_2` - 400GBASE-SR4.2 (400GE BiDi)\n* `400gbase-sr8` - 400GBASE-SR8 (400GE)\n* `400gbase-sr16` - 400GBASE-SR16 (400GE)\n* `400gbase-vr4` - 400GBASE-VR4 (400GE)\n* `400gbase-zr` - 400GBASE-ZR (400GE)\n* `800gbase-cr8` - 800GBASE-CR8 (800GE)\n* `800gbase-dr8` - 800GBASE-DR8 (800GE)\n* `800gbase-sr8` - 800GBASE-SR8 (800GE)\n* `800gbase-vr8` - 800GBASE-VR8 (800GE)\n* `100base-x-sfp` - SFP (100ME)\n* `1000base-x-gbic` - GBIC (1GE)\n* `1000base-x-sfp` - SFP (1GE)\n* `10gbase-x-sfpp` - SFP+ (10GE)\n* `10gbase-x-xfp` - XFP (10GE)\n* `10gbase-x-xenpak` - XENPAK (10GE)\n* `10gbase-x-x2` - X2 (10GE)\n* `25gbase-x-sfp28` - SFP28 (25GE)\n* `50gbase-x-sfp56` - SFP56 (50GE)\n* `40gbase-x-qsfpp` - QSFP+ (40GE)\n* `50gbase-x-sfp28` - QSFP28 (50GE)\n* `100gbase-x-cfp` - CFP (100GE)\n* `100gbase-x-cfp2` - CFP2 (100GE)\n* `200gbase-x-cfp2` - CFP2 (200GE)\n* `400gbase-x-cfp2` - CFP2 (400GE)\n* `100gbase-x-cfp4` - CFP4 (100GE)\n* `100gbase-x-cxp` - CXP (100GE)\n* `100gbase-x-cpak` - Cisco CPAK (100GE)\n* `100gbase-x-dsfp` - DSFP (100GE)\n* `100gbase-x-sfpdd` - SFP-DD (100GE)\n* `100gbase-x-qsfp28` - QSFP28 (100GE)\n* `100gbase-x-qsfpdd` - QSFP-DD (100GE)\n* `200gbase-x-qsfp56` - QSFP56 (200GE)\n* `200gbase-x-qsfpdd` - QSFP-DD (200GE)\n* `400gbase-x-qsfp112` - QSFP112 (400GE)\n* `400gbase-x-qsfpdd` - QSFP-DD (400GE)\n* `400gbase-x-osfp` - OSFP (400GE)\n* `400gbase-x-osfp-rhs` - OSFP-RHS (400GE)\n* `400gbase-x-cdfp` - CDFP (400GE)\n* `400gbase-x-cfp8` - CPF8 (400GE)\n* `800gbase-x-qsfpdd` - QSFP-DD (800GE)\n* `800gbase-x-osfp` - OSFP (800GE)\n* `1000base-kx` - 1000BASE-KX (1GE)\n* `2.5gbase-kx` - 2.5GBASE-KX (2.5GE)\n* `5gbase-kr` - 5GBASE-KR (5GE)\n* `10gbase-kr` - 10GBASE-KR (10GE)\n* `10gbase-kx4` - 10GBASE-KX4 (10GE)\n* `25gbase-kr` - 25GBASE-KR (25GE)\n* `40gbase-kr4` - 40GBASE-KR4 (40GE)\n* `50gbase-kr` - 50GBASE-KR (50GE)\n* `100gbase-kp4` - 100GBASE-KP4 (100GE)\n* `100gbase-kr2` - 100GBASE-KR2 (100GE)\n* `100gbase-kr4` - 100GBASE-KR4 (100GE)\n* `ieee802.11a` - IEEE 802.11a\n* `ieee802.11g` - IEEE 802.11b/g\n* `ieee802.11n` - IEEE 802.11n (Wi-Fi 4)\n* `ieee802.11ac` - IEEE 802.11ac (Wi-Fi 5)\n* `ieee802.11ad` - IEEE 802.11ad (WiGig)\n* `ieee802.11ax` - IEEE 802.11ax (Wi-Fi 6)\n* `ieee802.11ay` - IEEE 802.11ay (WiGig)\n* `ieee802.11be` - IEEE 802.11be (Wi-Fi 7)\n* `ieee802.15.1` - IEEE 802.15.1 (Bluetooth)\n* `ieee802.15.4` - IEEE 802.15.4 (LR-WPAN)\n* `other-wireless` - Other (Wireless)\n* `gsm` - GSM\n* `cdma` - CDMA\n* `lte` - LTE\n* `4g` - 4G\n* `5g` - 5G\n* `sonet-oc3` - OC-3/STM-1\n* `sonet-oc12` - OC-12/STM-4\n* `sonet-oc48` - OC-48/STM-16\n* `sonet-oc192` - OC-192/STM-64\n* `sonet-oc768` - OC-768/STM-256\n* `sonet-oc1920` - OC-1920/STM-640\n* `sonet-oc3840` - OC-3840/STM-1234\n* `1gfc-sfp` - SFP (1GFC)\n* `2gfc-sfp` - SFP (2GFC)\n* `4gfc-sfp` - SFP (4GFC)\n* `8gfc-sfpp` - SFP+ (8GFC)\n* `16gfc-sfpp` - SFP+ (16GFC)\n* `32gfc-sfp28` - SFP28 (32GFC)\n* `32gfc-sfpp` - SFP+ (32GFC)\n* `64gfc-qsfpp` - QSFP+ (64GFC)\n* `64gfc-sfpdd` - SFP-DD (64GFC)\n* `64gfc-sfpp` - SFP+ (64GFC)\n* `128gfc-qsfp28` - QSFP28 (128GFC)\n* `infiniband-sdr` - SDR (2 Gbps)\n* `infiniband-ddr` - DDR (4 Gbps)\n* `infiniband-qdr` - QDR (8 Gbps)\n* `infiniband-fdr10` - FDR10 (10 Gbps)\n* `infiniband-fdr` - FDR (13.5 Gbps)\n* `infiniband-edr` - EDR (25 Gbps)\n* `infiniband-hdr` - HDR (50 Gbps)\n* `infiniband-ndr` - NDR (100 Gbps)\n* `infiniband-xdr` - XDR (250 Gbps)\n* `t1` - T1 (1.544 Mbps)\n* `e1` - E1 (2.048 Mbps)\n* `t3` - T3 (45 Mbps)\n* `e3` - E3 (34 Mbps)\n* `xdsl` - xDSL\n* `docsis` - DOCSIS\n* `moca` - MoCA\n* `bpon` - BPON (622 Mbps / 155 Mbps)\n* `epon` - EPON (1 Gbps)\n* `10g-epon` - 10G-EPON (10 Gbps)\n* `gpon` - GPON (2.5 Gbps / 1.25 Gbps)\n* `xg-pon` - XG-PON (10 Gbps / 2.5 Gbps)\n* `xgs-pon` - XGS-PON (10 Gbps)\n* `ng-pon2` - NG-PON2 (TWDM-PON) (4x10 Gbps)\n* `25g-pon` - 25G-PON (25 Gbps)\n* `50g-pon` - 50G-PON (50 Gbps)\n* `cisco-stackwise` - Cisco StackWise\n* `cisco-stackwise-plus` - Cisco StackWise Plus\n* `cisco-flexstack` - Cisco FlexStack\n* `cisco-flexstack-plus` - Cisco FlexStack Plus\n* `cisco-stackwise-80` - Cisco StackWise-80\n* `cisco-stackwise-160` - Cisco StackWise-160\n* `cisco-stackwise-320` - Cisco StackWise-320\n* `cisco-stackwise-480` - Cisco StackWise-480\n* `cisco-stackwise-1t` - Cisco StackWise-1T\n* `juniper-vcp` - Juniper VCP\n* `extreme-summitstack` - Extreme SummitStack\n* `extreme-summitstack-128` - Extreme SummitStack-128\n* `extreme-summitstack-256` - Extreme SummitStack-256\n* `extreme-summitstack-512` - Extreme SummitStack-512\n* `other` - Other", + "x-spec-enum-id": "efa24ff9c7a39c40" }, "enabled": { "type": "boolean" diff --git a/docs/administration/authentication/microsoft-entra-id.md b/docs/administration/authentication/microsoft-entra-id.md index b44499fbe07..66794ae0c95 100644 --- a/docs/administration/authentication/microsoft-entra-id.md +++ b/docs/administration/authentication/microsoft-entra-id.md @@ -25,7 +25,7 @@ Once finished, make note of the application (client) ID; this will be used when ![Completed app registration](../../media/authentication/azure_ad_app_registration_created.png) !!! tip "Multitenant authentication" - NetBox also supports multitenant authentication via Azure AD, however it requires a different backend and an additional configuration parameter. Please see the [`python-social-auth` documentation](https://python-social-auth.readthedocs.io/en/latest/backends/azuread.html#tenant-support) for details concerning multitenant authentication. + NetBox also supports multitenant authentication via Azure AD; however, it requires a different backend and an additional configuration parameter. Please see the [`python-social-auth` documentation](https://python-social-auth.readthedocs.io/en/latest/backends/azuread.html#tenant-support) for details concerning multitenant authentication. ### 3. Create a secret diff --git a/docs/administration/netbox-shell.md b/docs/administration/netbox-shell.md index 21cef01b200..a74c5114ba5 100644 --- a/docs/administration/netbox-shell.md +++ b/docs/administration/netbox-shell.md @@ -106,7 +106,7 @@ This approach can span multiple levels of relations. For example, the following ``` !!! note - While the above query is functional, it's not very efficient. There are ways to optimize such requests, however they are out of scope for this document. For more information, see the [Django queryset method reference](https://docs.djangoproject.com/en/stable/ref/models/querysets/) documentation. + While the above query is functional, it's not very efficient. There are ways to optimize such requests; however, they are out of scope for this document. For more information, see the [Django queryset method reference](https://docs.djangoproject.com/en/stable/ref/models/querysets/) documentation. Reverse relationships can be traversed as well. For example, the following will find all devices with an interface named "em0": diff --git a/docs/configuration/data-validation.md b/docs/configuration/data-validation.md index 1b8263de355..9988f6e0b65 100644 --- a/docs/configuration/data-validation.md +++ b/docs/configuration/data-validation.md @@ -17,7 +17,7 @@ CUSTOM_VALIDATORS = { }, "my_plugin.validators.Validator1" ], - "dim.device": [ + "dcim.device": [ "my_plugin.validators.Validator1" ] } diff --git a/docs/configuration/system.md b/docs/configuration/system.md index 89e7d8d8eb5..8a73f629f7a 100644 --- a/docs/configuration/system.md +++ b/docs/configuration/system.md @@ -257,6 +257,46 @@ The specific configuration settings for each storage backend can be found in the !!! note Any keys defined in the `STORAGES` configuration parameter replace those in the default configuration. It is only necessary to define keys within the `STORAGES` for the specific backend(s) you wish to configure. +### Environment Variables and Third-Party Libraries + +NetBox uses an explicit Python configuration approach rather than automatic environment variable detection. While this provides clear configuration management and version control capabilities, it affects how some third-party libraries like `django-storages` function within NetBox's context. + +Many Django libraries (including `django-storages`) expect to automatically detect environment variables like `AWS_STORAGE_BUCKET_NAME` or `AWS_S3_ACCESS_KEY_ID`. However, NetBox's configuration processing prevents this automatic detection from working as documented in some of these libraries. + +When using third-party libraries that rely on environment variable detection, you may need to explicitly read environment variables in your NetBox `configuration.py`: + +```python +import os + +STORAGES = { + 'default': { + 'BACKEND': 'storages.backends.s3.S3Storage', + 'OPTIONS': { + 'bucket_name': os.environ.get('AWS_STORAGE_BUCKET_NAME'), + 'access_key': os.environ.get('AWS_S3_ACCESS_KEY_ID'), + 'secret_key': os.environ.get('AWS_S3_SECRET_ACCESS_KEY'), + 'endpoint_url': os.environ.get('AWS_S3_ENDPOINT_URL'), + 'location': 'media/', + } + }, + 'staticfiles': { + 'BACKEND': 'storages.backends.s3.S3Storage', + 'OPTIONS': { + 'bucket_name': os.environ.get('AWS_STORAGE_BUCKET_NAME'), + 'access_key': os.environ.get('AWS_S3_ACCESS_KEY_ID'), + 'secret_key': os.environ.get('AWS_S3_SECRET_ACCESS_KEY'), + 'endpoint_url': os.environ.get('AWS_S3_ENDPOINT_URL'), + 'location': 'static/', + } + }, +} +``` + +This approach works because the environment variables are resolved during NetBox's configuration processing, before the third-party library attempts its own environment variable detection. + +!!! warning "Configuration Behavior" + Simply setting environment variables like `AWS_STORAGE_BUCKET_NAME` without explicitly reading them in your configuration will not work. The variables must be read using `os.environ.get()` within your `configuration.py` file. + --- ## TIME_ZONE diff --git a/docs/getting-started/planning.md b/docs/getting-started/planning.md index 9641cd98bd4..7893db55b59 100644 --- a/docs/getting-started/planning.md +++ b/docs/getting-started/planning.md @@ -17,7 +17,7 @@ Dedicate some time to take stock of your own sources of truth for your infrastru * **Multiple conflicting sources** for a given domain. For example, there may be multiple versions of a spreadsheet circulating, each of which asserts a conflicting set of data. * **Sources with no domain defined.** You may encounter that different teams within your organization use different tools for the same purpose, with no normal definition of when either should be used. -* **Inaccessible data formatting.** Some tools are better suited for programmatic usage than others. For example, spreadsheets are generally very easy to parse and export, however free-form notes on wiki or similar application are much more difficult to consume. +* **Inaccessible data formatting.** Some tools are better suited for programmatic usage than others. For example, spreadsheets are generally very easy to parse and export; however, free-form notes on wiki or similar application are much more difficult to consume. * **There is no source of truth.** Sometimes you'll find that a source of truth simply doesn't exist for a domain. For example, when assigning IP addresses, operators may be just using any (presumed) available IP from a subnet without ever recording its usage. See if you can identify each domain of infrastructure data for your organization, and the source of truth for each. Once you have these compiled, you'll need to determine what belongs in NetBox. diff --git a/docs/plugins/development/index.md b/docs/plugins/development/index.md index 56bde5e41fa..0acf5f90ace 100644 --- a/docs/plugins/development/index.md +++ b/docs/plugins/development/index.md @@ -66,7 +66,7 @@ The top level is the project root, which can have any name that you like. Immedi * `README.md` - A brief introduction to your plugin, how to install and configure it, where to find help, and any other pertinent information. It is recommended to write `README` files using a markup language such as Markdown to enable human-friendly display. * The plugin source directory. This must be a valid Python package name, typically comprising only lowercase letters, numbers, and underscores. -The plugin source directory contains all the actual Python code and other resources used by your plugin. Its structure is left to the author's discretion, however it is recommended to follow best practices as outlined in the [Django documentation](https://docs.djangoproject.com/en/stable/intro/reusable-apps/). At a minimum, this directory **must** contain an `__init__.py` file containing an instance of NetBox's `PluginConfig` class, discussed below. +The plugin source directory contains all the actual Python code and other resources used by your plugin. Its structure is left to the author's discretion; however, it is recommended to follow best practices as outlined in the [Django documentation](https://docs.djangoproject.com/en/stable/intro/reusable-apps/). At a minimum, this directory **must** contain an `__init__.py` file containing an instance of NetBox's `PluginConfig` class, discussed below. **Note:** The [Cookiecutter NetBox Plugin](https://github.com/netbox-community/cookiecutter-netbox-plugin) can be used to auto-generate all the needed directories and files for a new plugin. @@ -186,7 +186,7 @@ Many of these are self-explanatory, but for more information, see the [pyproject ## Create a Virtual Environment -It is strongly recommended to create a Python [virtual environment](https://docs.python.org/3/tutorial/venv.html) for the development of your plugin, as opposed to using system-wide packages. This will afford you complete control over the installed versions of all dependencies and avoid conflict with system packages. This environment can live wherever you'd like, however it should be excluded from revision control. (A popular convention is to keep all virtual environments in the user's home directory, e.g. `~/.virtualenvs/`.) +It is strongly recommended to create a Python [virtual environment](https://docs.python.org/3/tutorial/venv.html) for the development of your plugin, as opposed to using system-wide packages. This will afford you complete control over the installed versions of all dependencies and avoid conflict with system packages. This environment can live wherever you'd like;however, it should be excluded from revision control. (A popular convention is to keep all virtual environments in the user's home directory, e.g. `~/.virtualenvs/`.) ```shell python3 -m venv ~/.virtualenvs/my_plugin diff --git a/docs/plugins/development/tables.md b/docs/plugins/development/tables.md index c5115884938..ea36b204de4 100644 --- a/docs/plugins/development/tables.md +++ b/docs/plugins/development/tables.md @@ -47,6 +47,11 @@ table.configure(request) This will automatically apply any user-specific preferences for the table. (If using a generic view provided by NetBox, table configuration is handled automatically.) + +### Bulk Edit and Delete Actions + +Bulk edit and delete buttons are automatically added to the table, if there is an appropriate view registered to the `${modelname}_bulk_edit` or `${modelname}_bulk_delete` path name. + ## Columns The table column classes listed below are supported for use in plugins. These classes can be imported from `netbox.tables.columns`. diff --git a/docs/release-notes/version-3.0.md b/docs/release-notes/version-3.0.md index a7003eedfe6..ae290b02ae6 100644 --- a/docs/release-notes/version-3.0.md +++ b/docs/release-notes/version-3.0.md @@ -357,7 +357,7 @@ And the response: ... ``` -All GraphQL requests are made at the `/graphql` URL (which also serves the GraphiQL UI). The API is currently read-only, however users who wish to disable it until needed can do so by setting the `GRAPHQL_ENABLED` configuration parameter to False. For more detail on NetBox's GraphQL implementation, see [the GraphQL API documentation](../integrations/graphql-api.md). +All GraphQL requests are made at the `/graphql` URL (which also serves the GraphiQL UI). The API is currently read-only; however, users who wish to disable it until needed can do so by setting the `GRAPHQL_ENABLED` configuration parameter to False. For more detail on NetBox's GraphQL implementation, see [the GraphQL API documentation](../integrations/graphql-api.md). #### IP Ranges ([#834](https://github.com/netbox-community/netbox/issues/834)) diff --git a/docs/release-notes/version-4.4.md b/docs/release-notes/version-4.4.md index 7138c277c48..0c95e9fcf1d 100644 --- a/docs/release-notes/version-4.4.md +++ b/docs/release-notes/version-4.4.md @@ -1,5 +1,47 @@ # NetBox v4.4 +## v4.4.1 (2025-09-16) + +### Enhancements + +* [#15492](https://github.com/netbox-community/netbox/issues/15492) - Enable cloning of permissions +* [#16381](https://github.com/netbox-community/netbox/issues/16381) - Display script result timestamps in system timezone +* [#19262](https://github.com/netbox-community/netbox/issues/19262) - No longer restrict FHRP group assignment by assigned IP address +* [#19408](https://github.com/netbox-community/netbox/issues/19408) - Support export templates for circuit terminations and virtual circuit terminations +* [#19428](https://github.com/netbox-community/netbox/issues/19428) - Add an optional U height field to the devices table +* [#19547](https://github.com/netbox-community/netbox/issues/19547) - Add individual "sync" buttons in data sources table +* [#19865](https://github.com/netbox-community/netbox/issues/19865) - Reorganize cable type groupings +* [#20222](https://github.com/netbox-community/netbox/issues/20222) - Enable the `HttpOnly` flag for CSRF cookie +* [#20237](https://github.com/netbox-community/netbox/issues/20237) - Include VPN tunnel groups in global search results +* [#20241](https://github.com/netbox-community/netbox/issues/20241) - Record A & B terminations in cable changelog data +* [#20277](https://github.com/netbox-community/netbox/issues/20277) - Add support for attribute assignment to `deserialize_object()` utility +* [#20321](https://github.com/netbox-community/netbox/issues/20321) - Add physical media types for transceiver interfaces +* [#20347](https://github.com/netbox-community/netbox/issues/20347) - Add Wi-Fi Alliance aliases to 802.11 interface types + +### Bug Fixes + +* [#19729](https://github.com/netbox-community/netbox/issues/19729) - Restore `kind` filter for interfaces in GraphQL API +* [#19744](https://github.com/netbox-community/netbox/issues/19744) - Plugins list should be orderable by "active" column +* [#19851](https://github.com/netbox-community/netbox/issues/19851) - Fix `ValueError` complaining of missing `scope` when bulk importing wireless LANs +* [#19896](https://github.com/netbox-community/netbox/issues/19896) - Min/max values for decimal custom fields should accept decimal values +* [#20197](https://github.com/netbox-community/netbox/issues/20197) - Correct validation for virtual chassis parent interface +* [#20215](https://github.com/netbox-community/netbox/issues/20215) - All GraphQL filters for config contexts should be optional +* [#20217](https://github.com/netbox-community/netbox/issues/20217) - Remove "0 VLANs available" row at end of VLAN range table +* [#20221](https://github.com/netbox-community/netbox/issues/20221) - JSON fields should not coerce empty dictionaries to null +* [#20227](https://github.com/netbox-community/netbox/issues/20227) - Ensure consistent padding of Markdown content +* [#20234](https://github.com/netbox-community/netbox/issues/20234) - Fix "add" button link for prerequisite object warning in UI +* [#20236](https://github.com/netbox-community/netbox/issues/20236) - Strip invalid characters from uploaded image file names +* [#20238](https://github.com/netbox-community/netbox/issues/20238) - Fix support for outside IP assignment during bulk import of tunnel terminations +* [#20242](https://github.com/netbox-community/netbox/issues/20242) - Avoid `AttributeError` exception on background jobs with no request ID +* [#20252](https://github.com/netbox-community/netbox/issues/20252) - Remove generic AddObject from ObjectChildrenView to prevent duplicate "add" buttons +* [#20264](https://github.com/netbox-community/netbox/issues/20264) - Fix rendering of default icon in plugins list +* [#20272](https://github.com/netbox-community/netbox/issues/20272) - ConfigContexts assigned to ancestor locations should apply to device/VM +* [#20282](https://github.com/netbox-community/netbox/issues/20282) - Fix styling of prerequisite objects warning +* [#20298](https://github.com/netbox-community/netbox/issues/20298) - Display a placeholder when an image thumbnail fails to load +* [#20327](https://github.com/netbox-community/netbox/issues/20327) - Avoid calling `distinct()` on device/VM queryset when fetching config context data + +--- + ## v4.4.0 (2025-09-02) ### New Features diff --git a/netbox/core/tables/data.py b/netbox/core/tables/data.py index 5c6ccebcf05..226a480810f 100644 --- a/netbox/core/tables/data.py +++ b/netbox/core/tables/data.py @@ -4,6 +4,7 @@ import django_tables2 as tables from core.models import * from netbox.tables import NetBoxTable, columns from .columns import BackendTypeColumn +from .template_code import DATA_SOURCE_SYNC_BUTTON __all__ = ( 'DataFileTable', @@ -37,6 +38,9 @@ class DataSourceTable(NetBoxTable): tags = columns.TagColumn( url_name='core:datasource_list', ) + actions = columns.ActionsColumn( + extra_buttons=DATA_SOURCE_SYNC_BUTTON, + ) class Meta(NetBoxTable.Meta): model = DataSource diff --git a/netbox/core/tables/plugins.py b/netbox/core/tables/plugins.py index e1b80af4233..d3f459cf3b7 100644 --- a/netbox/core/tables/plugins.py +++ b/netbox/core/tables/plugins.py @@ -1,10 +1,8 @@ import django_tables2 as tables -from django.urls import reverse -from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ from netbox.tables import BaseTable, columns -from .template_code import PLUGIN_IS_INSTALLED +from .template_code import PLUGIN_IS_INSTALLED, PLUGIN_NAME_TEMPLATE __all__ = ( 'CatalogPluginTable', @@ -12,12 +10,6 @@ __all__ = ( ) -PLUGIN_NAME_TEMPLATE = """ - -{{ record.title_long }} -""" - - class PluginVersionTable(BaseTable): version = tables.Column( verbose_name=_('Version') @@ -61,6 +53,7 @@ class CatalogPluginTable(BaseTable): verbose_name=_('Local') ) is_installed = columns.TemplateColumn( + accessor=tables.A('is_loaded'), verbose_name=_('Active'), template_code=PLUGIN_IS_INSTALLED ) @@ -93,10 +86,4 @@ class CatalogPluginTable(BaseTable): ) # List installed plugins first, then certified plugins, then # everything else (with each tranche ordered alphabetically) - order_by = ('-is_installed', '-is_certified', 'name') - - def render_title_long(self, value, record): - if record.static: - return value - url = reverse('core:plugin', args=[record.config_name]) - return mark_safe(f"{value}") + order_by = ('-is_installed', '-is_certified', 'title_long') diff --git a/netbox/core/tables/template_code.py b/netbox/core/tables/template_code.py index 9fc652c4c58..dc604876f8b 100644 --- a/netbox/core/tables/template_code.py +++ b/netbox/core/tables/template_code.py @@ -26,3 +26,29 @@ PLUGIN_IS_INSTALLED = """ {% endif %} """ + +PLUGIN_NAME_TEMPLATE = """ +{% load static %} +{% if record.icon_url %} + +{% else %} + +{% endif %} +{{ record.title_long }} +""" + +DATA_SOURCE_SYNC_BUTTON = """ +{% load helpers %} +{% load i18n %} +{% if perms.core.sync_datasource %} + {% if record.ready_for_sync %} + + {% else %} + + {% endif %} +{% endif %} +""" diff --git a/netbox/core/views.py b/netbox/core/views.py index b1893730825..0959e1c12a0 100644 --- a/netbox/core/views.py +++ b/netbox/core/views.py @@ -33,7 +33,13 @@ from utilities.forms import ConfirmationForm from utilities.htmx import htmx_partial from utilities.json import ConfigJSONEncoder from utilities.query import count_related -from utilities.views import ContentTypePermissionRequiredMixin, GetRelatedModelsMixin, ViewTab, register_model_view +from utilities.views import ( + ContentTypePermissionRequiredMixin, + GetRelatedModelsMixin, + GetReturnURLMixin, + ViewTab, + register_model_view, +) from . import filtersets, forms, tables from .jobs import SyncDataSourceJob from .models import * @@ -66,7 +72,7 @@ class DataSourceView(GetRelatedModelsMixin, generic.ObjectView): @register_model_view(DataSource, 'sync') -class DataSourceSyncView(BaseObjectView): +class DataSourceSyncView(GetReturnURLMixin, BaseObjectView): queryset = DataSource.objects.all() def get_required_permission(self): @@ -85,7 +91,7 @@ class DataSourceSyncView(BaseObjectView): request, _("Queued job #{id} to sync {datasource}").format(id=job.pk, datasource=datasource) ) - return redirect(datasource.get_absolute_url()) + return redirect(self.get_return_url(request, datasource)) @register_model_view(DataSource, 'add', detail=False) diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index d44048d58f8..328b09a6cf7 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -889,22 +889,118 @@ class InterfaceTypeChoices(ChoiceSet): TYPE_BRIDGE = 'bridge' TYPE_LAG = 'lag' - # Ethernet + # FastEthernet TYPE_100ME_FX = '100base-fx' TYPE_100ME_LFX = '100base-lfx' - TYPE_100ME_FIXED = '100base-tx' + TYPE_100ME_FIXED = '100base-tx' # TODO: Rename to _TX TYPE_100ME_T1 = '100base-t1' + + # GigabitEthernet + TYPE_1GE_BX10_D = '1000base-bx10-d' + TYPE_1GE_BX10_U = '1000base-bx10-u' + TYPE_1GE_CWDM = '1000base-cwdm' + TYPE_1GE_CX = '1000base-cx' + TYPE_1GE_DWDM = '1000base-dwdm' + TYPE_1GE_EX = '1000base-ex' + TYPE_1GE_SX_FIXED = '1000base-sx' # TODO: Drop _FIXED suffix + TYPE_1GE_LSX = '1000base-lsx' + TYPE_1GE_LX_FIXED = '1000base-lx' # TODO: Drop _FIXED suffix + TYPE_1GE_LX10 = '1000base-lx10' + TYPE_1GE_FIXED = '1000base-t' # TODO: Rename to _T + TYPE_1GE_TX_FIXED = '1000base-tx' # TODO: Drop _FIXED suffix + TYPE_1GE_ZX = '1000base-zx' + + # 2.5/5 Gbps Ethernet + TYPE_2GE_FIXED = '2.5gbase-t' # TODO: Rename to _T + TYPE_5GE_FIXED = '5gbase-t' # TODO: Rename to _T + + # 10 Gbps Ethernet + TYPE_10GE_BR_D = '10gbase-br-d' + TYPE_10GE_BR_U = '10gbase-br-u' + TYPE_10GE_CX4 = '10gbase-cx4' + TYPE_10GE_ER = '10gbase-er' + TYPE_10GE_LR = '10gbase-lr' + TYPE_10GE_LRM = '10gbase-lrm' + TYPE_10GE_LX4 = '10gbase-lx4' + TYPE_10GE_SR = '10gbase-sr' + TYPE_10GE_FIXED = '10gbase-t' + TYPE_10GE_ZR = '10gbase-zr' + + # 25 Gbps Ethernet + TYPE_25GE_CR = '25gbase-cr' + TYPE_25GE_ER = '25gbase-er' + TYPE_25GE_LR = '25gbase-lr' + TYPE_25GE_SR = '25gbase-sr' + TYPE_25GE_T = '25gbase-t' + + # 40 Gbps Ethernet + TYPE_40GE_CR4 = '40gbase-cr4' + TYPE_40GE_ER4 = '40gbase-er4' + TYPE_40GE_FR4 = '40gbase-fr4' + TYPE_40GE_LR4 = '40gbase-lr4' + TYPE_40GE_SR4 = '40gbase-sr4' + + # 50 Gbps Ethernet + TYPE_50GE_CR = '50gbase-cr' + TYPE_50GE_ER = '50gbase-er' + TYPE_50GE_FR = '50gbase-fr' + TYPE_50GE_LR = '50gbase-lr' + TYPE_50GE_SR = '50gbase-sr' + + # 100 Gbps Ethernet + TYPE_100GE_CR1 = '100gbase-cr1' + TYPE_100GE_CR2 = '100gbase-cr2' + TYPE_100GE_CR4 = '100gbase-cr4' + TYPE_100GE_CR10 = '100gbase-cr10' + TYPE_100GE_CWDM4 = '100gbase-cwdm4' + TYPE_100GE_DR = '100gbase-dr' + TYPE_100GE_FR1 = '100gbase-fr1' + TYPE_100GE_ER4 = '100gbase-er4' + TYPE_100GE_LR1 = '100gbase-lr1' + TYPE_100GE_LR4 = '100gbase-lr4' + TYPE_100GE_SR1 = '100gbase-sr1' + TYPE_100GE_SR1_2 = '100gbase-sr1.2' + TYPE_100GE_SR2 = '100gbase-sr2' + TYPE_100GE_SR4 = '100gbase-sr4' + TYPE_100GE_SR10 = '100gbase-sr10' + TYPE_100GE_ZR = '100gbase-zr' + + # 200 Gbps Ethernet + TYPE_200GE_CR2 = '200gbase-cr2' + TYPE_200GE_CR4 = '200gbase-cr4' + TYPE_200GE_SR2 = '200gbase-sr2' + TYPE_200GE_SR4 = '200gbase-sr4' + TYPE_200GE_DR4 = '200gbase-dr4' + TYPE_200GE_FR4 = '200gbase-fr4' + TYPE_200GE_LR4 = '200gbase-lr4' + TYPE_200GE_ER4 = '200gbase-er4' + TYPE_200GE_VR2 = '200gbase-vr2' + + # 400 Gbps Ethernet + TYPE_400GE_CR4 = '400gbase-cr4' + TYPE_400GE_DR4 = '400gbase-dr4' + TYPE_400GE_ER8 = '400gbase-er8' + TYPE_400GE_FR4 = '400gbase-fr4' + TYPE_400GE_FR8 = '400gbase-fr8' + TYPE_400GE_LR4 = '400gbase-lr4' + TYPE_400GE_LR8 = '400gbase-lr8' + TYPE_400GE_SR4 = '400gbase-sr4' + TYPE_400GE_SR4_2 = '400gbase-sr4_2' + TYPE_400GE_SR8 = '400gbase-sr8' + TYPE_400GE_SR16 = '400gbase-sr16' + TYPE_400GE_VR4 = '400gbase-vr4' + TYPE_400GE_ZR = '400gbase-zr' + + # 800 Gbps Ethernet + TYPE_800GE_CR8 = '800gbase-cr8' + TYPE_800GE_DR8 = '800gbase-dr8' + TYPE_800GE_SR8 = '800gbase-sr8' + TYPE_800GE_VR8 = '800gbase-vr8' + + # Ethernet (modular) TYPE_100ME_SFP = '100base-x-sfp' - TYPE_1GE_FIXED = '1000base-t' - TYPE_1GE_SX_FIXED = '1000base-sx' - TYPE_1GE_LX_FIXED = '1000base-lx' - TYPE_1GE_TX_FIXED = '1000base-tx' TYPE_1GE_GBIC = '1000base-x-gbic' TYPE_1GE_SFP = '1000base-x-sfp' - TYPE_2GE_FIXED = '2.5gbase-t' - TYPE_5GE_FIXED = '5gbase-t' - TYPE_10GE_FIXED = '10gbase-t' - TYPE_10GE_CX4 = '10gbase-cx4' TYPE_10GE_SFP_PLUS = '10gbase-x-sfpp' TYPE_10GE_XFP = '10gbase-x-xfp' TYPE_10GE_XENPAK = '10gbase-x-xenpak' @@ -935,7 +1031,7 @@ class InterfaceTypeChoices(ChoiceSet): TYPE_800GE_QSFP_DD = '800gbase-x-qsfpdd' TYPE_800GE_OSFP = '800gbase-x-osfp' - # Ethernet Backplane + # Backplane Ethernet TYPE_1GE_KX = '1000base-kx' TYPE_2GE_KX = '2.5gbase-kx' TYPE_5GE_KR = '5gbase-kr' @@ -1054,24 +1150,147 @@ class InterfaceTypeChoices(ChoiceSet): ), ), ( - _('Ethernet (fixed)'), + _('FastEthernet (100 Mbps)'), ( - (TYPE_100ME_FX, '100BASE-FX (10/100ME FIBER)'), - (TYPE_100ME_LFX, '100BASE-LFX (10/100ME FIBER)'), + (TYPE_100ME_FX, '100BASE-FX (10/100ME)'), + (TYPE_100ME_LFX, '100BASE-LFX (10/100ME)'), (TYPE_100ME_FIXED, '100BASE-TX (10/100ME)'), - (TYPE_100ME_T1, '100BASE-T1 (10/100ME Single Pair)'), - (TYPE_1GE_FIXED, '1000BASE-T (1GE)'), + (TYPE_100ME_T1, '100BASE-T1 (10/100ME)'), + ), + ), + ( + _('GigabitEthernet (1 Gbps)'), + ( + (TYPE_1GE_BX10_D, '1000BASE-BX10-D (1GE BiDi Down)'), + (TYPE_1GE_BX10_U, '1000BASE-BX10-U (1GE BiDi Up)'), + (TYPE_1GE_CX, '1000BASE-CX (1GE DAC)'), + (TYPE_1GE_CWDM, '1000BASE-CWDM (1GE)'), + (TYPE_1GE_DWDM, '1000BASE-DWDM (1GE)'), + (TYPE_1GE_EX, '1000BASE-EX (1GE)'), (TYPE_1GE_SX_FIXED, '1000BASE-SX (1GE)'), + (TYPE_1GE_LSX, '1000BASE-LSX (1GE)'), (TYPE_1GE_LX_FIXED, '1000BASE-LX (1GE)'), + (TYPE_1GE_LX10, '1000BASE-LX10/LH (1GE)'), + (TYPE_1GE_FIXED, '1000BASE-T (1GE)'), (TYPE_1GE_TX_FIXED, '1000BASE-TX (1GE)'), + (TYPE_1GE_ZX, '1000BASE-ZX (1GE)'), + ), + ), + ( + _('2.5/5 Gbps Ethernet'), + ( (TYPE_2GE_FIXED, '2.5GBASE-T (2.5GE)'), (TYPE_5GE_FIXED, '5GBASE-T (5GE)'), + ), + ), + ( + _('10 Gbps Ethernet'), + ( + (TYPE_10GE_BR_D, '10GBASE-DR-D (10GE BiDi Down)'), + (TYPE_10GE_BR_U, '10GBASE-DR-U (10GE BiDi Up)'), + (TYPE_10GE_CX4, '10GBASE-CX4 (10GE DAC)'), + (TYPE_10GE_ER, '10GBASE-ER (10GE)'), + (TYPE_10GE_LR, '10GBASE-LR (10GE)'), + (TYPE_10GE_LRM, '10GBASE-LRM (10GE)'), + (TYPE_10GE_LX4, '10GBASE-LX4 (10GE)'), + (TYPE_10GE_SR, '10GBASE-SR (10GE)'), (TYPE_10GE_FIXED, '10GBASE-T (10GE)'), - (TYPE_10GE_CX4, '10GBASE-CX4 (10GE)'), + (TYPE_10GE_ZR, '10GBASE-ZR (10GE)'), ) ), ( - _('Ethernet (modular)'), + _('25 Gbps Ethernet'), + ( + (TYPE_25GE_CR, '25GBASE-CR (25GE DAC)'), + (TYPE_25GE_ER, '25GBASE-ER (25GE)'), + (TYPE_25GE_LR, '25GBASE-LR (25GE)'), + (TYPE_25GE_SR, '25GBASE-SR (25GE)'), + (TYPE_25GE_T, '25GBASE-T (25GE)'), + ) + ), + ( + _('40 Gbps Ethernet'), + ( + (TYPE_40GE_CR4, '40GBASE-CR4 (40GE DAC)'), + (TYPE_40GE_ER4, '40GBASE-ER4 (40GE)'), + (TYPE_40GE_FR4, '40GBASE-FR4 (40GE)'), + (TYPE_40GE_LR4, '40GBASE-LR4 (40GE)'), + (TYPE_40GE_SR4, '40GBASE-SR4 (40GE)'), + ) + ), + ( + _('50 Gbps Ethernet'), + ( + (TYPE_50GE_CR, '50GBASE-CR (50GE DAC)'), + (TYPE_50GE_ER, '50GBASE-ER (50GE)'), + (TYPE_50GE_FR, '50GBASE-FR (50GE)'), + (TYPE_50GE_LR, '50GBASE-LR (50GE)'), + (TYPE_50GE_SR, '50GBASE-SR (50GE)'), + ) + ), + ( + _('100 Gbps Ethernet'), + ( + (TYPE_100GE_CR1, '100GBASE-CR1 (100GE DAC)'), + (TYPE_100GE_CR2, '100GBASE-CR2 (100GE DAC)'), + (TYPE_100GE_CR4, '100GBASE-CR4 (100GE DAC)'), + (TYPE_100GE_CR10, '100GBASE-CR10 (100GE DAC)'), + (TYPE_100GE_DR, '100GBASE-DR (100GE)'), + (TYPE_100GE_ER4, '100GBASE-ER4 (100GE)'), + (TYPE_100GE_FR1, '100GBASE-FR1 (100GE)'), + (TYPE_100GE_LR1, '100GBASE-LR1 (100GE)'), + (TYPE_100GE_LR4, '100GBASE-LR4 (100GE)'), + (TYPE_100GE_SR1, '100GBASE-SR1 (100GE)'), + (TYPE_100GE_SR1_2, '100GBASE-SR1.2 (100GE BiDi)'), + (TYPE_100GE_SR2, '100GBASE-SR2 (100GE)'), + (TYPE_100GE_SR4, '100GBASE-SR4 (100GE)'), + (TYPE_100GE_SR10, '100GBASE-SR10 (100GE)'), + (TYPE_100GE_ZR, '100GBASE-ZR (100GE)'), + ) + ), + ( + _('200 Gbps Ethernet'), + ( + (TYPE_200GE_CR2, '200GBASE-CR2 (200GE)'), + (TYPE_200GE_CR4, '200GBASE-CR4 (200GE)'), + (TYPE_200GE_SR2, '200GBASE-SR2 (200GE)'), + (TYPE_200GE_SR4, '200GBASE-SR4 (200GE)'), + (TYPE_200GE_DR4, '200GBASE-DR4 (200GE)'), + (TYPE_200GE_ER4, '200GBASE-ER4 (200GE)'), + (TYPE_200GE_FR4, '200GBASE-FR4 (200GE)'), + (TYPE_200GE_LR4, '200GBASE-LR4 (200GE)'), + (TYPE_200GE_VR2, '200GBASE-VR2 (200GE)'), + ) + ), + ( + _('400 Gbps Ethernet'), + ( + (TYPE_400GE_CR4, '400GBASE-CR4 (400GE)'), + (TYPE_400GE_DR4, '400GBASE-DR4 (400GE)'), + (TYPE_400GE_ER8, '400GBASE-ER8 (400GE)'), + (TYPE_400GE_FR4, '400GBASE-FR4 (400GE)'), + (TYPE_400GE_FR8, '400GBASE-FR8 (400GE)'), + (TYPE_400GE_LR4, '400GBASE-LR4 (400GE)'), + (TYPE_400GE_LR8, '400GBASE-LR8 (400GE)'), + (TYPE_400GE_SR4, '400GBASE-SR4 (400GE)'), + (TYPE_400GE_SR4_2, '400GBASE-SR4.2 (400GE BiDi)'), + (TYPE_400GE_SR8, '400GBASE-SR8 (400GE)'), + (TYPE_400GE_SR16, '400GBASE-SR16 (400GE)'), + (TYPE_400GE_VR4, '400GBASE-VR4 (400GE)'), + (TYPE_400GE_ZR, '400GBASE-ZR (400GE)'), + ) + ), + ( + _('800 Gbps Ethernet'), + ( + (TYPE_800GE_CR8, '800GBASE-CR8 (800GE)'), + (TYPE_800GE_DR8, '800GBASE-DR8 (800GE)'), + (TYPE_800GE_SR8, '800GBASE-SR8 (800GE)'), + (TYPE_800GE_VR8, '800GBASE-VR8 (800GE)'), + ) + ), + ( + _('Pluggable transceivers'), ( (TYPE_100ME_SFP, 'SFP (100ME)'), (TYPE_1GE_GBIC, 'GBIC (1GE)'), @@ -1108,7 +1327,7 @@ class InterfaceTypeChoices(ChoiceSet): ) ), ( - _('Ethernet (backplane)'), + _('Backplane Ethernet'), ( (TYPE_1GE_KX, '1000BASE-KX (1GE)'), (TYPE_2GE_KX, '2.5GBASE-KX (2.5GE)'), @@ -1128,12 +1347,12 @@ class InterfaceTypeChoices(ChoiceSet): ( (TYPE_80211A, 'IEEE 802.11a'), (TYPE_80211G, 'IEEE 802.11b/g'), - (TYPE_80211N, 'IEEE 802.11n'), - (TYPE_80211AC, 'IEEE 802.11ac'), - (TYPE_80211AD, 'IEEE 802.11ad'), - (TYPE_80211AX, 'IEEE 802.11ax'), - (TYPE_80211AY, 'IEEE 802.11ay'), - (TYPE_80211BE, 'IEEE 802.11be'), + (TYPE_80211N, 'IEEE 802.11n (Wi-Fi 4)'), + (TYPE_80211AC, 'IEEE 802.11ac (Wi-Fi 5)'), + (TYPE_80211AD, 'IEEE 802.11ad (WiGig)'), + (TYPE_80211AX, 'IEEE 802.11ax (Wi-Fi 6)'), + (TYPE_80211AY, 'IEEE 802.11ay (WiGig)'), + (TYPE_80211BE, 'IEEE 802.11be (Wi-Fi 7)'), (TYPE_802151, 'IEEE 802.15.1 (Bluetooth)'), (TYPE_802154, 'IEEE 802.15.4 (LR-WPAN)'), (TYPE_OTHER_WIRELESS, 'Other (Wireless)'), @@ -1497,8 +1716,9 @@ class PortTypeChoices(ChoiceSet): # Cables/links # -class CableTypeChoices(ChoiceSet): +class CableTypeChoices(ChoiceSet): + # Copper - Twisted Pair (UTP/STP) TYPE_CAT3 = 'cat3' TYPE_CAT5 = 'cat5' TYPE_CAT5E = 'cat5e' @@ -1507,26 +1727,41 @@ class CableTypeChoices(ChoiceSet): TYPE_CAT7 = 'cat7' TYPE_CAT7A = 'cat7a' TYPE_CAT8 = 'cat8' + TYPE_MRJ21_TRUNK = 'mrj21-trunk' + + # Copper - Twinax (DAC) TYPE_DAC_ACTIVE = 'dac-active' TYPE_DAC_PASSIVE = 'dac-passive' - TYPE_MRJ21_TRUNK = 'mrj21-trunk' + + # Copper - Coaxial TYPE_COAXIAL = 'coaxial' + + # Fiber Optic - Multimode TYPE_MMF = 'mmf' TYPE_MMF_OM1 = 'mmf-om1' TYPE_MMF_OM2 = 'mmf-om2' TYPE_MMF_OM3 = 'mmf-om3' TYPE_MMF_OM4 = 'mmf-om4' TYPE_MMF_OM5 = 'mmf-om5' + + # Fiber Optic - Single-mode TYPE_SMF = 'smf' TYPE_SMF_OS1 = 'smf-os1' TYPE_SMF_OS2 = 'smf-os2' + + # Fiber Optic - Other TYPE_AOC = 'aoc' + + # Power TYPE_POWER = 'power' + + # USB TYPE_USB = 'usb' CHOICES = ( ( - _('Copper'), ( + _('Copper - Twisted Pair (UTP/STP)'), + ( (TYPE_CAT3, 'CAT3'), (TYPE_CAT5, 'CAT5'), (TYPE_CAT5E, 'CAT5e'), @@ -1535,28 +1770,57 @@ class CableTypeChoices(ChoiceSet): (TYPE_CAT7, 'CAT7'), (TYPE_CAT7A, 'CAT7a'), (TYPE_CAT8, 'CAT8'), + (TYPE_MRJ21_TRUNK, 'MRJ21 Trunk'), + ), + ), + ( + _('Copper - Twinax (DAC)'), + ( (TYPE_DAC_ACTIVE, 'Direct Attach Copper (Active)'), (TYPE_DAC_PASSIVE, 'Direct Attach Copper (Passive)'), - (TYPE_MRJ21_TRUNK, 'MRJ21 Trunk'), + ), + ), + ( + _('Copper - Coaxial'), + ( (TYPE_COAXIAL, 'Coaxial'), ), ), ( - _('Fiber'), ( + _('Fiber - Multimode'), + ( (TYPE_MMF, 'Multimode Fiber'), (TYPE_MMF_OM1, 'Multimode Fiber (OM1)'), (TYPE_MMF_OM2, 'Multimode Fiber (OM2)'), (TYPE_MMF_OM3, 'Multimode Fiber (OM3)'), (TYPE_MMF_OM4, 'Multimode Fiber (OM4)'), (TYPE_MMF_OM5, 'Multimode Fiber (OM5)'), - (TYPE_SMF, 'Singlemode Fiber'), - (TYPE_SMF_OS1, 'Singlemode Fiber (OS1)'), - (TYPE_SMF_OS2, 'Singlemode Fiber (OS2)'), - (TYPE_AOC, 'Active Optical Cabling (AOC)'), ), ), - (TYPE_USB, _('USB')), - (TYPE_POWER, _('Power')), + ( + _('Fiber - Single-mode'), + ( + (TYPE_SMF, 'Single-mode Fiber'), + (TYPE_SMF_OS1, 'Single-mode Fiber (OS1)'), + (TYPE_SMF_OS2, 'Single-mode Fiber (OS2)'), + ), + ), + ( + _('Fiber - Other'), + ((TYPE_AOC, 'Active Optical Cabling (AOC)'),), + ), + ( + _('Power'), + ( + (TYPE_POWER, 'Power'), + ), + ), + ( + _('USB'), + ( + (TYPE_USB, 'USB'), + ), + ), ) diff --git a/netbox/dcim/graphql/enums.py b/netbox/dcim/graphql/enums.py index 5f888cfb51a..62a666b4544 100644 --- a/netbox/dcim/graphql/enums.py +++ b/netbox/dcim/graphql/enums.py @@ -12,6 +12,7 @@ __all__ = ( 'DeviceFaceEnum', 'DeviceStatusEnum', 'InterfaceDuplexEnum', + 'InterfaceKindEnum', 'InterfaceModeEnum', 'InterfacePoEModeEnum', 'InterfacePoETypeEnum', @@ -48,6 +49,7 @@ DeviceAirflowEnum = strawberry.enum(DeviceAirflowChoices.as_enum(prefix='airflow DeviceFaceEnum = strawberry.enum(DeviceFaceChoices.as_enum(prefix='face')) DeviceStatusEnum = strawberry.enum(DeviceStatusChoices.as_enum(prefix='status')) InterfaceDuplexEnum = strawberry.enum(InterfaceDuplexChoices.as_enum(prefix='duplex')) +InterfaceKindEnum = strawberry.enum(InterfaceKindChoices.as_enum(prefix='kind')) InterfaceModeEnum = strawberry.enum(InterfaceModeChoices.as_enum(prefix='mode')) InterfacePoEModeEnum = strawberry.enum(InterfacePoEModeChoices.as_enum(prefix='mode')) InterfacePoETypeEnum = strawberry.enum(InterfacePoETypeChoices.as_enum()) diff --git a/netbox/dcim/graphql/filters.py b/netbox/dcim/graphql/filters.py index a8a6c2a5e03..af2922e1362 100644 --- a/netbox/dcim/graphql/filters.py +++ b/netbox/dcim/graphql/filters.py @@ -1,5 +1,6 @@ from typing import Annotated, TYPE_CHECKING +from django.db.models import Q import strawberry import strawberry_django from strawberry.scalars import ID @@ -7,6 +8,8 @@ from strawberry_django import FilterLookup from core.graphql.filter_mixins import ChangeLogFilterMixin from dcim import models +from dcim.constants import * +from dcim.graphql.enums import InterfaceKindEnum from extras.graphql.filter_mixins import ConfigContextFilterMixin from netbox.graphql.filter_mixins import ( PrimaryModelFilterMixin, @@ -485,6 +488,27 @@ class InterfaceFilter(ModularComponentModelFilterMixin, InterfaceBaseFilterMixin strawberry_django.filter_field() ) + @strawberry_django.filter_field + def connected(self, queryset, value: bool, prefix: str): + if value is True: + return queryset, Q(**{f"{prefix}_path__is_active": True}) + else: + return queryset, Q(**{f"{prefix}_path__isnull": True}) | Q(**{f"{prefix}_path__is_active": False}) + + @strawberry_django.filter_field + def kind( + self, + queryset, + value: Annotated['InterfaceKindEnum', strawberry.lazy('dcim.graphql.enums')], + prefix: str + ): + if value == InterfaceKindEnum.KIND_PHYSICAL: + return queryset, ~Q(**{f"{prefix}type__in": NONCONNECTABLE_IFACE_TYPES}) + elif value == InterfaceKindEnum.KIND_VIRTUAL: + return queryset, Q(**{f"{prefix}type__in": VIRTUAL_IFACE_TYPES}) + elif value == InterfaceKindEnum.KIND_WIRELESS: + return queryset, Q(**{f"{prefix}type__in": WIRELESS_IFACE_TYPES}) + @strawberry_django.filter_type(models.InterfaceTemplate, lookups=True) class InterfaceTemplateFilter(ModularComponentTemplateFilterMixin): diff --git a/netbox/dcim/models/cables.py b/netbox/dcim/models/cables.py index 69e07ed9432..89c9a99b419 100644 --- a/netbox/dcim/models/cables.py +++ b/netbox/dcim/models/cables.py @@ -18,6 +18,7 @@ from utilities.conversion import to_meters from utilities.exceptions import AbortRequest from utilities.fields import ColorField, GenericArrayForeignKey from utilities.querysets import RestrictedQuerySet +from utilities.serialization import deserialize_object, serialize_object from wireless.models import WirelessLink from .device_components import FrontPort, RearPort, PathEndpoint @@ -119,43 +120,61 @@ class Cable(PrimaryModel): pk = self.pk or self._pk return self.label or f'#{pk}' - @property - def a_terminations(self): - if hasattr(self, '_a_terminations'): - return self._a_terminations + def get_status_color(self): + return LinkStatusChoices.colors.get(self.status) + def _get_x_terminations(self, side): + """ + Return the terminating objects for the given cable end (A or B). + """ + if side not in (CableEndChoices.SIDE_A, CableEndChoices.SIDE_B): + raise ValueError(f"Unknown cable side: {side}") + attr = f'_{side.lower()}_terminations' + + if hasattr(self, attr): + return getattr(self, attr) if not self.pk: return [] - - # Query self.terminations.all() to leverage cached results return [ - ct.termination for ct in self.terminations.all() if ct.cable_end == CableEndChoices.SIDE_A + # Query self.terminations.all() to leverage cached results + ct.termination for ct in self.terminations.all() if ct.cable_end == side ] + def _set_x_terminations(self, side, value): + """ + Set the terminating objects for the given cable end (A or B). + """ + if side not in (CableEndChoices.SIDE_A, CableEndChoices.SIDE_B): + raise ValueError(f"Unknown cable side: {side}") + _attr = f'_{side.lower()}_terminations' + + # If the provided value is a list of CableTermination IDs, resolve them + # to their corresponding termination objects. + if all(isinstance(item, int) for item in value): + value = [ + ct.termination for ct in CableTermination.objects.filter(pk__in=value).prefetch_related('termination') + ] + + if not self.pk or getattr(self, _attr, []) != list(value): + self._terminations_modified = True + + setattr(self, _attr, value) + + @property + def a_terminations(self): + return self._get_x_terminations(CableEndChoices.SIDE_A) + @a_terminations.setter def a_terminations(self, value): - if not self.pk or self.a_terminations != list(value): - self._terminations_modified = True - self._a_terminations = value + self._set_x_terminations(CableEndChoices.SIDE_A, value) @property def b_terminations(self): - if hasattr(self, '_b_terminations'): - return self._b_terminations - - if not self.pk: - return [] - - # Query self.terminations.all() to leverage cached results - return [ - ct.termination for ct in self.terminations.all() if ct.cable_end == CableEndChoices.SIDE_B - ] + return self._get_x_terminations(CableEndChoices.SIDE_B) @b_terminations.setter def b_terminations(self, value): - if not self.pk or self.b_terminations != list(value): - self._terminations_modified = True - self._b_terminations = value + self._set_x_terminations(CableEndChoices.SIDE_B, value) @property def color_name(self): @@ -208,7 +227,7 @@ class Cable(PrimaryModel): for termination in self.b_terminations: CableTermination(cable=self, cable_end='B', termination=termination).clean() - def save(self, *args, **kwargs): + def save(self, *args, force_insert=False, force_update=False, using=None, update_fields=None): _created = self.pk is None # Store the given length (if any) in meters for use in database ordering @@ -221,39 +240,87 @@ class Cable(PrimaryModel): if self.length is None: self.length_unit = None - super().save(*args, **kwargs) + # If this is a new Cable, save it before attempting to create its CableTerminations + if self._state.adding: + super().save(*args, force_insert=True, using=using, update_fields=update_fields) + # Update the private PK used in __str__() + self._pk = self.pk - # Update the private pk used in __str__ in case this is a new object (i.e. just got its pk) - self._pk = self.pk - - # Retrieve existing A/B terminations for the Cable - a_terminations = {ct.termination: ct for ct in self.terminations.filter(cable_end='A')} - b_terminations = {ct.termination: ct for ct in self.terminations.filter(cable_end='B')} - - # Delete stale CableTerminations if self._terminations_modified: - for termination, ct in a_terminations.items(): - if termination.pk and termination not in self.a_terminations: - ct.delete() - for termination, ct in b_terminations.items(): - if termination.pk and termination not in self.b_terminations: - ct.delete() + self.update_terminations() + + super().save(*args, force_update=True, using=using, update_fields=update_fields) - # Save new CableTerminations (if any) - if self._terminations_modified: - for termination in self.a_terminations: - if not termination.pk or termination not in a_terminations: - CableTermination(cable=self, cable_end='A', termination=termination).save() - for termination in self.b_terminations: - if not termination.pk or termination not in b_terminations: - CableTermination(cable=self, cable_end='B', termination=termination).save() try: trace_paths.send(Cable, instance=self, created=_created) except UnsupportedCablePath as e: raise AbortRequest(e) - def get_status_color(self): - return LinkStatusChoices.colors.get(self.status) + def serialize_object(self, exclude=None): + data = serialize_object(self, exclude=exclude or []) + + # Add A & B terminations to the serialized data + a_terminations, b_terminations = self.get_terminations() + data['a_terminations'] = sorted([ct.pk for ct in a_terminations.values()]) + data['b_terminations'] = sorted([ct.pk for ct in b_terminations.values()]) + + return data + + @classmethod + def deserialize_object(cls, data, pk=None): + a_terminations = data.pop('a_terminations', []) + b_terminations = data.pop('b_terminations', []) + + instance = deserialize_object(cls, data, pk=pk) + + # Assign A & B termination objects to the Cable instance + queryset = CableTermination.objects.prefetch_related('termination') + instance.a_terminations = [ + ct.termination for ct in queryset.filter(pk__in=a_terminations) + ] + instance.b_terminations = [ + ct.termination for ct in queryset.filter(pk__in=b_terminations) + ] + + return instance + + def get_terminations(self): + """ + Return two dictionaries mapping A & B side terminating objects to their corresponding CableTerminations + for this Cable. + """ + a_terminations = {} + b_terminations = {} + + for ct in CableTermination.objects.filter(cable=self).prefetch_related('termination'): + if ct.cable_end == CableEndChoices.SIDE_A: + a_terminations[ct.termination] = ct + else: + b_terminations[ct.termination] = ct + + return a_terminations, b_terminations + + def update_terminations(self): + """ + Create/delete CableTerminations for this Cable to reflect its current state. + """ + a_terminations, b_terminations = self.get_terminations() + + # Delete any stale CableTerminations + for termination, ct in a_terminations.items(): + if termination.pk and termination not in self.a_terminations: + ct.delete() + for termination, ct in b_terminations.items(): + if termination.pk and termination not in self.b_terminations: + ct.delete() + + # Save any new CableTerminations + for termination in self.a_terminations: + if not termination.pk or termination not in a_terminations: + CableTermination(cable=self, cable_end='A', termination=termination).save() + for termination in self.b_terminations: + if not termination.pk or termination not in b_terminations: + CableTermination(cable=self, cable_end='B', termination=termination).save() class CableTermination(ChangeLoggedModel): diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py index f1e460d779f..9e1d7b61e9b 100644 --- a/netbox/dcim/models/device_components.py +++ b/netbox/dcim/models/device_components.py @@ -872,14 +872,14 @@ class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEnd "The selected parent interface ({interface}) belongs to a different device ({device})" ).format(interface=self.parent, device=self.parent.device) }) - elif self.parent.device.virtual_chassis != self.parent.virtual_chassis: + elif self.parent.device.virtual_chassis != self.device.virtual_chassis: raise ValidationError({ 'parent': _( "The selected parent interface ({interface}) belongs to {device}, which is not part of " "virtual chassis {virtual_chassis}." ).format( interface=self.parent, - device=self.parent_device, + device=self.parent.device, virtual_chassis=self.device.virtual_chassis ) }) @@ -890,7 +890,7 @@ class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEnd if self.pk and self.bridge_id == self.pk: raise ValidationError({'bridge': _("An interface cannot be bridged to itself.")}) - # A bridged interface belong to the same device or virtual chassis + # A bridged interface belongs to the same device or virtual chassis if self.bridge and self.bridge.device != self.device: if self.device.virtual_chassis is None: raise ValidationError({ diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index 8287e36669d..fe07bb57faa 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -195,6 +195,11 @@ class DeviceTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable): linkify=True, verbose_name=_('Type') ) + u_height = columns.TemplateColumn( + accessor=tables.A('device_type.u_height'), + verbose_name=_('U Height'), + template_code='{{ value|floatformat }}' + ) platform = tables.Column( linkify=True, verbose_name=_('Platform') diff --git a/netbox/dcim/tests/test_views.py b/netbox/dcim/tests/test_views.py index b23f7e16d79..2e6d5ebc58c 100644 --- a/netbox/dcim/tests/test_views.py +++ b/netbox/dcim/tests/test_views.py @@ -1078,14 +1078,14 @@ class ModuleTypeTestCase(ViewTestCases.PrimaryObjectViewTestCase): 'dcim.add_modulebaytemplate', ) + def verify_module_type_profile(scenario_name): + # TODO: remove extra regression asserts once parent test supports testing all import fields + fan_module_type = ModuleType.objects.get(part_number='generic-fan') + fan_module_type_profile = ModuleTypeProfile.objects.get(name='Fan') + assert fan_module_type.profile == fan_module_type_profile + # run base test - super().test_bulk_import_objects_with_permission() - - # TODO: remove extra regression asserts once parent test supports testing all import fields - fan_module_type = ModuleType.objects.get(part_number='generic-fan') - fan_module_type_profile = ModuleTypeProfile.objects.get(name='Fan') - - assert fan_module_type.profile == fan_module_type_profile + super().test_bulk_import_objects_with_permission(post_import_callback=verify_module_type_profile) @override_settings(EXEMPT_VIEW_PERMISSIONS=['*'], EXEMPT_EXCLUDE_MODELS=[]) def test_bulk_import_objects_with_constrained_permission(self): @@ -3290,8 +3290,10 @@ class CableTestCase( Device(name='Device 1', site=sites[0], device_type=devicetype, role=role), Device(name='Device 2', site=sites[0], device_type=devicetype, role=role), Device(name='Device 3', site=sites[0], device_type=devicetype, role=role), + Device(name='Device 4', site=sites[0], device_type=devicetype, role=role), # Create 'Device 1' assigned to 'Site 2' (allowed since the site is different) Device(name='Device 1', site=sites[1], device_type=devicetype, role=role), + Device(name='Device 5', site=sites[1], device_type=devicetype, role=role), ) Device.objects.bulk_create(devices) @@ -3300,22 +3302,36 @@ class CableTestCase( vc.save() interfaces = ( + # Device 1, Site 1 Interface(device=devices[0], name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED), Interface(device=devices[0], name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED), Interface(device=devices[0], name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED), + # Device 2, Site 1 Interface(device=devices[1], name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED), Interface(device=devices[1], name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED), Interface(device=devices[1], name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED), + # Device 3, Site 1 Interface(device=devices[2], name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED), Interface(device=devices[2], name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED), Interface(device=devices[2], name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED), + # Device 3, Site 1 Interface(device=devices[3], name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED), Interface(device=devices[3], name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED), Interface(device=devices[3], name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED), + # Device 1, Site 2 + Interface(device=devices[4], name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED), + Interface(device=devices[4], name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED), + Interface(device=devices[4], name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED), + + # Device 1, Site 2 + Interface(device=devices[5], name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED), + Interface(device=devices[5], name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED), + Interface(device=devices[5], name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED), + Interface(device=devices[1], name='Device 2 Interface', type=InterfaceTypeChoices.TYPE_1GE_FIXED), Interface(device=devices[2], name='Device 3 Interface', type=InterfaceTypeChoices.TYPE_1GE_FIXED), - Interface(device=devices[3], name='Interface 4', type=InterfaceTypeChoices.TYPE_1GE_FIXED), - Interface(device=devices[3], name='Interface 5', type=InterfaceTypeChoices.TYPE_1GE_FIXED), + Interface(device=devices[4], name='Interface 4', type=InterfaceTypeChoices.TYPE_1GE_FIXED), + Interface(device=devices[4], name='Interface 5', type=InterfaceTypeChoices.TYPE_1GE_FIXED), ) Interface.objects.bulk_create(interfaces) @@ -3342,16 +3358,29 @@ class CableTestCase( 'tags': [t.pk for t in tags], } - # Ensure that CSV bulk import supports assigning terminations from parent devices that share - # the same device name, provided those devices belong to different sites. - cls.csv_data = ( - "side_a_site,side_a_device,side_a_type,side_a_name,side_b_site,side_b_device,side_b_type,side_b_name", - "Site 1,Device 3,dcim.interface,Interface 1,Site 2,Device 1,dcim.interface,Interface 1", - "Site 1,Device 3,dcim.interface,Interface 2,Site 2,Device 1,dcim.interface,Interface 2", - "Site 1,Device 3,dcim.interface,Interface 3,Site 2,Device 1,dcim.interface,Interface 3", - "Site 1,Device 1,dcim.interface,Device 2 Interface,Site 2,Device 1,dcim.interface,Interface 4", - "Site 1,Device 1,dcim.interface,Device 3 Interface,Site 2,Device 1,dcim.interface,Interface 5", - ) + cls.csv_data = { + 'default': ( + "side_a_device,side_a_type,side_a_name,side_b_device,side_b_type,side_b_name", + "Device 4,dcim.interface,Interface 1,Device 5,dcim.interface,Interface 1", + "Device 3,dcim.interface,Interface 2,Device 4,dcim.interface,Interface 2", + "Device 3,dcim.interface,Interface 3,Device 4,dcim.interface,Interface 3", + + # The following is no longer possible in this scenario, because there are multiple + # devices named "Device 1" across multiple sites. See the "site-filtering" scenario + # below for how to specify a site for non-unique device names. + # "Device 1,dcim.interface,Device 3 Interface,Device 4,dcim.interface,Interface 5", + ), + 'site-filtering': ( + # Ensure that CSV bulk import supports assigning terminations from parent devices + # that share the same device name, provided those devices belong to different sites. + "side_a_site,side_a_device,side_a_type,side_a_name,side_b_site,side_b_device,side_b_type,side_b_name", + "Site 1,Device 3,dcim.interface,Interface 1,Site 2,Device 1,dcim.interface,Interface 1", + "Site 1,Device 3,dcim.interface,Interface 2,Site 2,Device 1,dcim.interface,Interface 2", + "Site 1,Device 3,dcim.interface,Interface 3,Site 2,Device 1,dcim.interface,Interface 3", + "Site 1,Device 1,dcim.interface,Device 2 Interface,Site 2,Device 1,dcim.interface,Interface 4", + "Site 1,Device 1,dcim.interface,Device 3 Interface,Site 2,Device 1,dcim.interface,Interface 5", + ) + } cls.csv_update_data = ( "id,label,color", diff --git a/netbox/extras/graphql/filters.py b/netbox/extras/graphql/filters.py index e7d5ef573d4..13221982c92 100644 --- a/netbox/extras/graphql/filters.py +++ b/netbox/extras/graphql/filters.py @@ -43,12 +43,12 @@ __all__ = ( @strawberry_django.filter_type(models.ConfigContext, lookups=True) class ConfigContextFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLogFilterMixin): - name: FilterLookup[str] = strawberry_django.filter_field() + name: FilterLookup[str] | None = strawberry_django.filter_field() weight: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) - description: FilterLookup[str] = strawberry_django.filter_field() - is_active: FilterLookup[bool] = strawberry_django.filter_field() + description: FilterLookup[str] | None = strawberry_django.filter_field() + is_active: FilterLookup[bool] | None = strawberry_django.filter_field() regions: Annotated['RegionFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/extras/jobs.py b/netbox/extras/jobs.py index 8a039c7c8a5..c270833b1e5 100644 --- a/netbox/extras/jobs.py +++ b/netbox/extras/jobs.py @@ -106,7 +106,7 @@ class ScriptJob(JobRunner): # Add the current request as a property of the script script.request = request - self.logger.debug(f"Request ID: {request.id}") + self.logger.debug(f"Request ID: {request.id if request else None}") # Execute the script. If commit is True, wrap it with the event_tracking context manager to ensure we process # change logging, event rules, etc. diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index be4c44d63af..7361d087dec 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -1,6 +1,6 @@ import json -import os import urllib.parse +from pathlib import Path from django.conf import settings from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation @@ -728,7 +728,9 @@ class ImageAttachment(ChangeLoggedModel): @property def filename(self): - return os.path.basename(self.image.name).split('_', 2)[2] + base_name = Path(self.image.name).name + prefix = f"{self.object_type.model}_{self.object_id}_" + return base_name.removeprefix(prefix) @property def html_tag(self): diff --git a/netbox/extras/querysets.py b/netbox/extras/querysets.py index 8d6628a834f..ee2afed4c9f 100644 --- a/netbox/extras/querysets.py +++ b/netbox/extras/querysets.py @@ -22,9 +22,10 @@ class ConfigContextQuerySet(RestrictedQuerySet): aggregate_data: If True, use the JSONBAgg aggregate function to return only the list of JSON data objects """ - # Device type and location assignment is relevant only for Devices + # Device type and location assignment are relevant only for Devices device_type = getattr(obj, 'device_type', None) location = getattr(obj, 'location', None) + locations = location.get_ancestors(include_self=True) if location else [] # Get assigned cluster, group, and type (if any) cluster = getattr(obj, 'cluster', None) @@ -49,7 +50,7 @@ class ConfigContextQuerySet(RestrictedQuerySet): Q(regions__in=regions) | Q(regions=None), Q(site_groups__in=sitegroups) | Q(site_groups=None), Q(sites=obj.site) | Q(sites=None), - Q(locations=location) | Q(locations=None), + Q(locations__in=locations) | Q(locations=None), Q(device_types=device_type) | Q(device_types=None), Q(roles__in=device_roles) | Q(roles=None), Q(platforms=obj.platform) | Q(platforms=None), @@ -92,7 +93,7 @@ class ConfigContextModelQuerySet(RestrictedQuerySet): _data=EmptyGroupByJSONBAgg('data', ordering=['weight', 'name']) ).values("_data").order_by() ) - ).distinct() + ) def _get_config_context_filters(self): # Construct the set of Q objects for the specific object types @@ -116,7 +117,7 @@ class ConfigContextModelQuerySet(RestrictedQuerySet): ).values_list( 'tag_id', flat=True - ) + ).distinct() ) ) | Q(tags=None), is_active=True, @@ -124,7 +125,15 @@ class ConfigContextModelQuerySet(RestrictedQuerySet): # Apply Location & DeviceType filters only for VirtualMachines if self.model._meta.model_name == 'device': - base_query.add((Q(locations=OuterRef('location')) | Q(locations=None)), Q.AND) + base_query.add( + (Q( + locations__tree_id=OuterRef('location__tree_id'), + locations__level__lte=OuterRef('location__level'), + locations__lft__lte=OuterRef('location__lft'), + locations__rght__gte=OuterRef('location__rght'), + ) | Q(locations=None)), + Q.AND + ) base_query.add((Q(device_types=OuterRef('device_type')) | Q(device_types=None)), Q.AND) elif self.model._meta.model_name == 'virtualmachine': base_query.add(Q(locations=None), Q.AND) diff --git a/netbox/extras/tables/tables.py b/netbox/extras/tables/tables.py index 5c1a63d265e..e89d06c4041 100644 --- a/netbox/extras/tables/tables.py +++ b/netbox/extras/tables/tables.py @@ -725,8 +725,9 @@ class ScriptResultsTable(BaseTable): index = tables.Column( verbose_name=_('Line') ) - time = tables.Column( - verbose_name=_('Time') + time = columns.DateTimeColumn( + verbose_name=_('Time'), + timespec='seconds' ) status = tables.TemplateColumn( template_code="""{% load log_levels %}{% log_level record.status %}""", diff --git a/netbox/extras/tests/test_models.py b/netbox/extras/tests/test_models.py index 341920a81a3..7b2e58646af 100644 --- a/netbox/extras/tests/test_models.py +++ b/netbox/extras/tests/test_models.py @@ -1,17 +1,95 @@ import tempfile from pathlib import Path +from django.contrib.contenttypes.models import ContentType +from django.core.files.uploadedfile import SimpleUploadedFile from django.forms import ValidationError from django.test import tag, TestCase from core.models import DataSource, ObjectType from dcim.models import Device, DeviceRole, DeviceType, Location, Manufacturer, Platform, Region, Site, SiteGroup -from extras.models import ConfigContext, ConfigContextProfile, ConfigTemplate, Tag +from extras.models import ConfigContext, ConfigContextProfile, ConfigTemplate, ImageAttachment, Tag, TaggedItem from tenancy.models import Tenant, TenantGroup from utilities.exceptions import AbortRequest from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine +class ImageAttachmentTests(TestCase): + @classmethod + def setUpTestData(cls): + cls.ct_rack = ContentType.objects.get(app_label='dcim', model='rack') + cls.image_content = b'' + + def _stub_image_attachment(self, object_id, image_filename, name=None): + """ + Creates an instance of ImageAttachment with the provided object_id and image_name. + + This method prepares a stubbed image attachment to test functionalities that + require an ImageAttachment object. + The function initializes the attachment with a specified file name and + pre-defined image content. + """ + ia = ImageAttachment( + object_type=self.ct_rack, + object_id=object_id, + name=name, + image=SimpleUploadedFile( + name=image_filename, + content=self.image_content, + content_type='image/jpeg', + ), + ) + return ia + + def test_filename_strips_expected_prefix(self): + """ + Tests that the filename of the image attachment is stripped of the expected + prefix. + """ + ia = self._stub_image_attachment(12, 'image-attachments/rack_12_My_File.png') + self.assertEqual(ia.filename, 'My_File.png') + + def test_filename_legacy_nested_path_returns_basename(self): + """ + Tests if the filename of a legacy-nested path correctly returns only the basename. + """ + # e.g. "image-attachments/rack_12_5/31/23.jpg" -> "23.jpg" + ia = self._stub_image_attachment(12, 'image-attachments/rack_12_5/31/23.jpg') + self.assertEqual(ia.filename, '23.jpg') + + def test_filename_no_prefix_returns_basename(self): + """ + Tests that the filename property correctly returns the basename for an image + attachment that has no leading prefix in its path. + """ + ia = self._stub_image_attachment(42, 'image-attachments/just_name.webp') + self.assertEqual(ia.filename, 'just_name.webp') + + def test_mismatched_prefix_is_not_stripped(self): + """ + Tests that a mismatched prefix in the filename is not stripped. + """ + # Prefix does not match object_id -> leave as-is (basename only) + ia = self._stub_image_attachment(12, 'image-attachments/rack_13_other.png') + self.assertEqual('rack_13_other.png', ia.filename) + + def test_str_uses_name_when_present(self): + """ + Tests that the `str` representation of the object uses the + `name` attribute when provided. + """ + ia = self._stub_image_attachment(12, 'image-attachments/rack_12_file.png', name='Human title') + self.assertEqual('Human title', str(ia)) + + def test_str_falls_back_to_filename(self): + """ + Tests that the `str` representation of the object falls back to + the filename if the name attribute is not set. + """ + ia = self._stub_image_attachment(12, 'image-attachments/rack_12_file.png', name='') + self.assertEqual('file.png', str(ia)) + + class TagTest(TestCase): def test_default_ordering_weight_then_name_is_set(self): @@ -445,7 +523,7 @@ class ConfigContextTest(TestCase): vm1 = VirtualMachine.objects.create(name="VM 1", site=site, role=vm_role) vm2 = VirtualMachine.objects.create(name="VM 2", cluster=cluster, role=vm_role) - # Check that their individually-rendered config contexts are identical + # Check that their individually rendered config contexts are identical self.assertEqual( vm1.get_config_context(), vm2.get_config_context() @@ -458,11 +536,39 @@ class ConfigContextTest(TestCase): vms[1].get_config_context() ) + def test_valid_local_context_data(self): + device = Device.objects.first() + device.local_context_data = None + device.clean() + + device.local_context_data = {"foo": "bar"} + device.clean() + + def test_invalid_local_context_data(self): + device = Device.objects.first() + + device.local_context_data = "" + with self.assertRaises(ValidationError): + device.clean() + + device.local_context_data = 0 + with self.assertRaises(ValidationError): + device.clean() + + device.local_context_data = False + with self.assertRaises(ValidationError): + device.clean() + + device.local_context_data = 'foo' + with self.assertRaises(ValidationError): + device.clean() + + @tag('regression') def test_multiple_tags_return_distinct_objects(self): """ Tagged items use a generic relationship, which results in duplicate rows being returned when queried. This is combated by appending distinct() to the config context querysets. This test creates a config - context assigned to two tags and ensures objects related by those same two tags result in only a single + context assigned to two tags and ensures objects related to those same two tags result in only a single config context record being returned. See https://github.com/netbox-community/netbox/issues/5314 @@ -495,14 +601,15 @@ class ConfigContextTest(TestCase): self.assertEqual(ConfigContext.objects.get_for_object(device).count(), 1) self.assertEqual(device.get_config_context(), annotated_queryset[0].get_config_context()) - def test_multiple_tags_return_distinct_objects_with_seperate_config_contexts(self): + @tag('regression') + def test_multiple_tags_return_distinct_objects_with_separate_config_contexts(self): """ Tagged items use a generic relationship, which results in duplicate rows being returned when queried. - This is combatted by by appending distinct() to the config context querysets. This test creates a config - context assigned to two tags and ensures objects related by those same two tags result in only a single + This is combated by appending distinct() to the config context querysets. This test creates a config + context assigned to two tags and ensures objects related to those same two tags result in only a single config context record being returned. - This test case is seperate from the above in that it deals with multiple config context objects in play. + This test case is separate from the above in that it deals with multiple config context objects in play. See https://github.com/netbox-community/netbox/issues/5387 """ @@ -543,32 +650,47 @@ class ConfigContextTest(TestCase): self.assertEqual(ConfigContext.objects.get_for_object(device).count(), 2) self.assertEqual(device.get_config_context(), annotated_queryset[0].get_config_context()) - def test_valid_local_context_data(self): + @tag('performance', 'regression') + def test_config_context_annotation_query_optimization(self): + """ + Regression test for issue #20327: Ensure config context annotation + doesn't use expensive DISTINCT on main query. + + Verifies that DISTINCT is only used in tag subquery where needed, + not on the main device query which is expensive for large datasets. + """ device = Device.objects.first() - device.local_context_data = None - device.clean() + queryset = Device.objects.filter(pk=device.pk).annotate_config_context_data() - device.local_context_data = {"foo": "bar"} - device.clean() + # Main device query should NOT use DISTINCT + self.assertFalse(queryset.query.distinct) - def test_invalid_local_context_data(self): - device = Device.objects.first() + # Check that tag subqueries DO use DISTINCT by inspecting the annotation + config_annotation = queryset.query.annotations.get('config_context_data') + self.assertIsNotNone(config_annotation) - device.local_context_data = "" - with self.assertRaises(ValidationError): - device.clean() + def find_tag_subqueries(where_node): + """Find subqueries in WHERE clause that relate to tag filtering""" + subqueries = [] - device.local_context_data = 0 - with self.assertRaises(ValidationError): - device.clean() + def traverse(node): + if hasattr(node, 'children'): + for child in node.children: + try: + if child.rhs.query.model is TaggedItem: + subqueries.append(child.rhs.query) + except AttributeError: + traverse(child) + traverse(where_node) + return subqueries - device.local_context_data = False - with self.assertRaises(ValidationError): - device.clean() + # Find subqueries in the WHERE clause that should have DISTINCT + tag_subqueries = find_tag_subqueries(config_annotation.query.where) + distinct_subqueries = [sq for sq in tag_subqueries if sq.distinct] - device.local_context_data = 'foo' - with self.assertRaises(ValidationError): - device.clean() + # Verify we found at least one DISTINCT subquery for tags + self.assertEqual(len(distinct_subqueries), 1) + self.assertTrue(distinct_subqueries[0].distinct) class ConfigTemplateTest(TestCase): diff --git a/netbox/extras/tests/test_utils.py b/netbox/extras/tests/test_utils.py index b851acab83f..ec0102887af 100644 --- a/netbox/extras/tests/test_utils.py +++ b/netbox/extras/tests/test_utils.py @@ -1,7 +1,10 @@ +from types import SimpleNamespace + +from django.contrib.contenttypes.models import ContentType from django.test import TestCase from extras.models import ExportTemplate -from extras.utils import filename_from_model +from extras.utils import filename_from_model, image_upload from tenancy.models import ContactGroup, TenantGroup from wireless.models import WirelessLANGroup @@ -17,3 +20,141 @@ class FilenameFromModelTests(TestCase): for model, expected in cases: self.assertEqual(filename_from_model(model), expected) + + +class ImageUploadTests(TestCase): + @classmethod + def setUpTestData(cls): + # We only need a ContentType with model="rack" for the prefix; + # this doesn't require creating a Rack object. + cls.ct_rack = ContentType.objects.get(app_label='dcim', model='rack') + + def _stub_instance(self, object_id=12, name=None): + """ + Creates a minimal stub for use with the `image_upload()` function. + + This method generates an instance of `SimpleNamespace` containing a set + of attributes required to simulate the expected input for the + `image_upload()` method. + It is designed to simplify testing or processing by providing a + lightweight representation of an object. + """ + return SimpleNamespace(object_type=self.ct_rack, object_id=object_id, name=name) + + def _second_segment(self, path: str): + """ + Extracts and returns the portion of the input string after the + first '/' character. + """ + return path.split('/', 1)[1] + + def test_windows_fake_path_and_extension_lowercased(self): + """ + Tests handling of a Windows file path with a fake directory and extension. + """ + inst = self._stub_instance(name=None) + path = image_upload(inst, r'C:\fake_path\MyPhoto.JPG') + # Base directory and single-level path + seg2 = self._second_segment(path) + self.assertTrue(path.startswith('image-attachments/rack_12_')) + self.assertNotIn('/', seg2, 'should not create nested directories') + # Extension from the uploaded file, lowercased + self.assertTrue(seg2.endswith('.jpg')) + + def test_name_with_slashes_is_flattened_no_subdirectories(self): + """ + Tests that a name with slashes is flattened and does not + create subdirectories. + """ + inst = self._stub_instance(name='5/31/23') + path = image_upload(inst, 'image.png') + seg2 = self._second_segment(path) + self.assertTrue(seg2.startswith('rack_12_')) + self.assertNotIn('/', seg2) + self.assertNotIn('\\', seg2) + self.assertTrue(seg2.endswith('.png')) + + def test_name_with_backslashes_is_flattened_no_subdirectories(self): + """ + Tests that a name including backslashes is correctly flattened + into a single directory name without creating subdirectories. + """ + inst = self._stub_instance(name=r'5\31\23') + path = image_upload(inst, 'image_name.png') + + seg2 = self._second_segment(path) + self.assertTrue(seg2.startswith('rack_12_')) + self.assertNotIn('/', seg2) + self.assertNotIn('\\', seg2) + self.assertTrue(seg2.endswith('.png')) + + def test_prefix_format_is_as_expected(self): + """ + Tests the output path format generated by the `image_upload` function. + """ + inst = self._stub_instance(object_id=99, name='label') + path = image_upload(inst, 'a.webp') + # The second segment must begin with "rack_99_" + seg2 = self._second_segment(path) + self.assertTrue(seg2.startswith('rack_99_')) + self.assertTrue(seg2.endswith('.webp')) + + def test_unsupported_file_extension(self): + """ + Test that when the file extension is not allowed, the extension + is omitted. + """ + inst = self._stub_instance(name='test') + path = image_upload(inst, 'document.txt') + + seg2 = self._second_segment(path) + self.assertTrue(seg2.startswith('rack_12_test')) + self.assertFalse(seg2.endswith('.txt')) + # When not allowed, no extension should be appended + self.assertNotRegex(seg2, r'\.txt$') + + def test_instance_name_with_whitespace_and_special_chars(self): + """ + Test that an instance name with leading/trailing whitespace and + special characters is sanitized properly. + """ + # Suppose the instance name has surrounding whitespace and + # extra slashes. + inst = self._stub_instance(name=' my/complex\\name ') + path = image_upload(inst, 'irrelevant.png') + + # The output should be flattened and sanitized. + # We expect the name to be transformed into a valid filename without + # path separators. + seg2 = self._second_segment(path) + self.assertNotIn(' ', seg2) + self.assertNotIn('/', seg2) + self.assertNotIn('\\', seg2) + self.assertTrue(seg2.endswith('.png')) + + def test_separator_variants_with_subTest(self): + """ + Tests that both forward slash and backslash in file paths are + handled consistently by the `image_upload` function and + processed into a sanitized uniform format. + """ + for name in ['2025/09/12', r'2025\09\12']: + with self.subTest(name=name): + inst = self._stub_instance(name=name) + path = image_upload(inst, 'x.jpeg') + seg2 = self._second_segment(path) + self.assertTrue(seg2.startswith('rack_12_')) + self.assertNotIn('/', seg2) + self.assertNotIn('\\', seg2) + self.assertTrue(seg2.endswith('.jpeg') or seg2.endswith('.jpg')) + + def test_fallback_on_suspicious_file_operation(self): + """ + Test that when default_storage.get_valid_name() raises a + SuspiciousFileOperation, the fallback default is used. + """ + inst = self._stub_instance(name=' ') + path = image_upload(inst, 'sample.png') + # Expect the fallback name 'unnamed' to be used. + self.assertIn('unnamed', path) + self.assertTrue(path.startswith('image-attachments/rack_12_')) diff --git a/netbox/extras/utils.py b/netbox/extras/utils.py index c9f554d224b..761f4affb7d 100644 --- a/netbox/extras/utils.py +++ b/netbox/extras/utils.py @@ -1,15 +1,20 @@ import importlib +from pathlib import Path -from django.core.exceptions import ImproperlyConfigured +from django.core.exceptions import ImproperlyConfigured, SuspiciousFileOperation +from django.core.files.storage import default_storage +from django.core.files.utils import validate_file_name from django.db import models from django.db.models import Q from taggit.managers import _TaggableManager from netbox.context import current_request + from .validators import CustomValidator __all__ = ( 'SharedObjectViewMixin', + 'filename_from_model', 'image_upload', 'is_report', 'is_script', @@ -35,13 +40,13 @@ class SharedObjectViewMixin: def filename_from_model(model: models.Model) -> str: - """Standardises how we generate filenames from model class for exports""" + """Standardizes how we generate filenames from model class for exports""" base = model._meta.verbose_name_plural.lower().replace(' ', '_') return f'netbox_{base}' def filename_from_object(context: dict) -> str: - """Standardises how we generate filenames from model class for exports""" + """Standardizes how we generate filenames from model class for exports""" if 'device' in context: base = f"{context['device'].name or 'config'}" elif 'virtualmachine' in context: @@ -64,17 +69,42 @@ def is_taggable(obj): def image_upload(instance, filename): """ Return a path for uploading image attachments. + + - Normalizes browser paths (e.g., C:\\fake_path\\photo.jpg) + - Uses the instance.name if provided (sanitized to a *basename*, no ext) + - Prefixes with a machine-friendly identifier + + Note: Relies on Django's default_storage utility. """ - path = 'image-attachments/' + upload_dir = 'image-attachments' + default_filename = 'unnamed' + allowed_img_extensions = ('bmp', 'gif', 'jpeg', 'jpg', 'png', 'webp') - # Rename the file to the provided name, if any. Attempt to preserve the file extension. - extension = filename.rsplit('.')[-1].lower() - if instance.name and extension in ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'webp']: - filename = '.'.join([instance.name, extension]) - elif instance.name: - filename = instance.name + # Normalize Windows paths and create a Path object. + normalized_filename = str(filename).replace('\\', '/') + file_path = Path(normalized_filename) - return '{}{}_{}_{}'.format(path, instance.object_type.name, instance.object_id, filename) + # Extract the extension from the uploaded file. + ext = file_path.suffix.lower().lstrip('.') + + # Use the instance-provided name if available; otherwise use the file stem. + # Rely on Django's get_valid_filename to perform sanitization. + stem = (instance.name or file_path.stem).strip() + try: + safe_stem = default_storage.get_valid_name(stem) + except SuspiciousFileOperation: + safe_stem = default_filename + + # Append the uploaded extension only if it's an allowed image type + final_name = f"{safe_stem}.{ext}" if ext in allowed_img_extensions else safe_stem + + # Create a machine-friendly prefix from the instance + prefix = f"{instance.object_type.model}_{instance.object_id}" + name_with_path = f"{upload_dir}/{prefix}_{final_name}" + + # Validate the generated relative path (blocks absolute/traversal) + validate_file_name(name_with_path, allow_relative_path=True) + return name_with_path def is_script(obj): @@ -107,7 +137,7 @@ def run_validators(instance, validators): request = current_request.get() for validator in validators: - # Loading a validator class by dotted path + # Loading a validator class by a dotted path if type(validator) is str: module, cls = validator.rsplit('.', 1) validator = getattr(importlib.import_module(module), cls)() diff --git a/netbox/extras/views.py b/netbox/extras/views.py index c76afbd15fb..32d19674b86 100644 --- a/netbox/extras/views.py +++ b/netbox/extras/views.py @@ -1,3 +1,4 @@ +from datetime import datetime from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.contenttypes.models import ContentType @@ -1547,7 +1548,6 @@ class ScriptResultView(TableMixin, generic.ObjectView): except KeyError: log_threshold = LOG_LEVEL_RANK[LogLevelChoices.LOG_INFO] if job.data: - if 'log' in job.data: if 'tests' in job.data: tests = job.data['tests'] @@ -1558,7 +1558,7 @@ class ScriptResultView(TableMixin, generic.ObjectView): index += 1 result = { 'index': index, - 'time': log.get('time'), + 'time': datetime.fromisoformat(log.get('time')), 'status': log.get('status'), 'message': log.get('message'), 'object': log.get('obj'), diff --git a/netbox/ipam/filtersets.py b/netbox/ipam/filtersets.py index 7f8cd2f04fc..cf4f99d3276 100644 --- a/netbox/ipam/filtersets.py +++ b/netbox/ipam/filtersets.py @@ -804,6 +804,7 @@ class FHRPGroupFilterSet(NetBoxModelFilterSet): return queryset return queryset.filter( Q(description__icontains=value) | + Q(group_id__contains=value) | Q(name__icontains=value) ) diff --git a/netbox/ipam/forms/model_forms.py b/netbox/ipam/forms/model_forms.py index 1b4a3d596b5..399198c52b0 100644 --- a/netbox/ipam/forms/model_forms.py +++ b/netbox/ipam/forms/model_forms.py @@ -580,13 +580,6 @@ class FHRPGroupAssignmentForm(forms.ModelForm): model = FHRPGroupAssignment fields = ('group', 'priority') - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - ipaddresses = self.instance.interface.ip_addresses.all() - for ipaddress in ipaddresses: - self.fields['group'].widget.add_query_param('related_ip', ipaddress.pk) - def clean_group(self): group = self.cleaned_data['group'] diff --git a/netbox/ipam/utils.py b/netbox/ipam/utils.py index 8fe40592e30..790ac6503d0 100644 --- a/netbox/ipam/utils.py +++ b/netbox/ipam/utils.py @@ -164,7 +164,7 @@ def available_vlans_from_range(vlans, vlan_group, vid_range): prev_vid = vlan.vid # Annotate any remaining available VLANs - if prev_vid < max_vid: + if prev_vid < max_vid - 1: new_vlans.append({ 'vid': prev_vid + 1, 'vlan_group': vlan_group, diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js index 12c48b79e32..b6f1b04c32e 100644 --- a/netbox/project-static/dist/netbox.js +++ b/netbox/project-static/dist/netbox.js @@ -1,11 +1,11 @@ -"use strict";(()=>{var nu=Object.create;var Mi=Object.defineProperty,iu=Object.defineProperties,ru=Object.getOwnPropertyDescriptor,ou=Object.getOwnPropertyDescriptors,su=Object.getOwnPropertyNames,ps=Object.getOwnPropertySymbols,au=Object.getPrototypeOf,ms=Object.prototype.hasOwnProperty,lu=Object.prototype.propertyIsEnumerable;var qr=(n,e,t)=>e in n?Mi(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,O=(n,e)=>{for(var t in e||(e={}))ms.call(e,t)&&qr(n,t,e[t]);if(ps)for(var t of ps(e))lu.call(e,t)&&qr(n,t,e[t]);return n},ae=(n,e)=>iu(n,ou(e));var cu=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports),gs=(n,e)=>{for(var t in e)Mi(n,t,{get:e[t],enumerable:!0})},uu=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of su(e))!ms.call(n,r)&&r!==t&&Mi(n,r,{get:()=>e[r],enumerable:!(i=ru(e,r))||i.enumerable});return n};var du=(n,e,t)=>(t=n!=null?nu(au(n)):{},uu(e||!n||!n.__esModule?Mi(t,"default",{value:n,enumerable:!0}):t,n));var ee=(n,e,t)=>qr(n,typeof e!="symbol"?e+"":e,t);var at=(n,e,t)=>new Promise((i,r)=>{var o=l=>{try{a(t.next(l))}catch(c){r(c)}},s=l=>{try{a(t.throw(l))}catch(c){r(c)}},a=l=>l.done?i(l.value):Promise.resolve(l.value).then(o,s);a((t=t.apply(n,e)).next())});var gc=cu((vi,ts)=>{(function(e,t){typeof vi=="object"&&typeof ts=="object"?ts.exports=t():typeof define=="function"&&define.amd?define([],t):typeof vi=="object"?vi.ClipboardJS=t():e.ClipboardJS=t()})(vi,function(){return function(){var n={686:function(i,r,o){"use strict";o.d(r,{default:function(){return Re}});var s=o(279),a=o.n(s),l=o(370),c=o.n(l),u=o(817),d=o.n(u);function p(W){try{return document.execCommand(W)}catch(M){return!1}}var y=function(M){var D=d()(M);return p("cut"),D},m=y;function v(W){var M=document.documentElement.getAttribute("dir")==="rtl",D=document.createElement("textarea");D.style.fontSize="12pt",D.style.border="0",D.style.padding="0",D.style.margin="0",D.style.position="absolute",D.style[M?"right":"left"]="-9999px";var $=window.pageYOffset||document.documentElement.scrollTop;return D.style.top="".concat($,"px"),D.setAttribute("readonly",""),D.value=W,D}var w=function(M,D){var $=v(M);D.container.appendChild($);var V=d()($);return p("copy"),$.remove(),V},T=function(M){var D=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},$="";return typeof M=="string"?$=w(M,D):M instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(M==null?void 0:M.type)?$=w(M.value,D):($=d()(M),p("copy")),$},_=T;function S(W){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?S=function(D){return typeof D}:S=function(D){return D&&typeof Symbol=="function"&&D.constructor===Symbol&&D!==Symbol.prototype?"symbol":typeof D},S(W)}var A=function(){var M=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},D=M.action,$=D===void 0?"copy":D,V=M.container,q=M.target,U=M.text;if($!=="copy"&&$!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(q!==void 0)if(q&&S(q)==="object"&&q.nodeType===1){if($==="copy"&&q.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if($==="cut"&&(q.hasAttribute("readonly")||q.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(U)return _(U,{container:V});if(q)return $==="cut"?m(q):_(q,{container:V})},K=A;function z(W){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?z=function(D){return typeof D}:z=function(D){return D&&typeof Symbol=="function"&&D.constructor===Symbol&&D!==Symbol.prototype?"symbol":typeof D},z(W)}function L(W,M){if(!(W instanceof M))throw new TypeError("Cannot call a class as a function")}function H(W,M){for(var D=0;D0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof V.action=="function"?V.action:this.defaultAction,this.target=typeof V.target=="function"?V.target:this.defaultTarget,this.text=typeof V.text=="function"?V.text:this.defaultText,this.container=z(V.container)==="object"?V.container:document.body}},{key:"listenClick",value:function(V){var q=this;this.listener=c()(V,"click",function(U){return q.onClick(U)})}},{key:"onClick",value:function(V){var q=V.delegateTarget||V.currentTarget,U=this.action(q)||"copy",Z=K({action:U,container:this.container,target:this.target(q),text:this.text(q)});this.emit(Z?"success":"error",{action:U,text:Z,trigger:q,clearSelection:function(){q&&q.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(V){return ne("action",V)}},{key:"defaultTarget",value:function(V){var q=ne("target",V);if(q)return document.querySelector(q)}},{key:"defaultText",value:function(V){return ne("text",V)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(V){var q=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return _(V,q)}},{key:"cut",value:function(V){return m(V)}},{key:"isSupported",value:function(){var V=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],q=typeof V=="string"?[V]:V,U=!!document.queryCommandSupported;return q.forEach(function(Z){U=U&&!!document.queryCommandSupported(Z)}),U}}]),D}(a()),Re=qe},828:function(i){var r=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var o=Element.prototype;o.matches=o.matchesSelector||o.mozMatchesSelector||o.msMatchesSelector||o.oMatchesSelector||o.webkitMatchesSelector}function s(a,l){for(;a&&a.nodeType!==r;){if(typeof a.matches=="function"&&a.matches(l))return a;a=a.parentNode}}i.exports=s},438:function(i,r,o){var s=o(828);function a(u,d,p,y,m){var v=c.apply(this,arguments);return u.addEventListener(p,v,m),{destroy:function(){u.removeEventListener(p,v,m)}}}function l(u,d,p,y,m){return typeof u.addEventListener=="function"?a.apply(null,arguments):typeof p=="function"?a.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(v){return a(v,d,p,y,m)}))}function c(u,d,p,y){return function(m){m.delegateTarget=s(m.target,d),m.delegateTarget&&y.call(u,m)}}i.exports=l},879:function(i,r){r.node=function(o){return o!==void 0&&o instanceof HTMLElement&&o.nodeType===1},r.nodeList=function(o){var s=Object.prototype.toString.call(o);return o!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in o&&(o.length===0||r.node(o[0]))},r.string=function(o){return typeof o=="string"||o instanceof String},r.fn=function(o){var s=Object.prototype.toString.call(o);return s==="[object Function]"}},370:function(i,r,o){var s=o(879),a=o(438);function l(p,y,m){if(!p&&!y&&!m)throw new Error("Missing required arguments");if(!s.string(y))throw new TypeError("Second argument must be a String");if(!s.fn(m))throw new TypeError("Third argument must be a Function");if(s.node(p))return c(p,y,m);if(s.nodeList(p))return u(p,y,m);if(s.string(p))return d(p,y,m);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(p,y,m){return p.addEventListener(y,m),{destroy:function(){p.removeEventListener(y,m)}}}function u(p,y,m){return Array.prototype.forEach.call(p,function(v){v.addEventListener(y,m)}),{destroy:function(){Array.prototype.forEach.call(p,function(v){v.removeEventListener(y,m)})}}}function d(p,y,m){return a(document.body,p,y,m)}i.exports=l},817:function(i){function r(o){var s;if(o.nodeName==="SELECT")o.focus(),s=o.value;else if(o.nodeName==="INPUT"||o.nodeName==="TEXTAREA"){var a=o.hasAttribute("readonly");a||o.setAttribute("readonly",""),o.select(),o.setSelectionRange(0,o.value.length),a||o.removeAttribute("readonly"),s=o.value}else{o.hasAttribute("contenteditable")&&o.focus();var l=window.getSelection(),c=document.createRange();c.selectNodeContents(o),l.removeAllRanges(),l.addRange(c),s=l.toString()}return s}i.exports=r},279:function(i){function r(){}r.prototype={on:function(o,s,a){var l=this.e||(this.e={});return(l[o]||(l[o]=[])).push({fn:s,ctx:a}),this},once:function(o,s,a){var l=this;function c(){l.off(o,c),s.apply(a,arguments)}return c._=s,this.on(o,c,a)},emit:function(o){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[o]||[]).slice(),l=0,c=a.length;for(l;lws,afterRead:()=>Es,afterWrite:()=>Cs,applyStyles:()=>hn,arrow:()=>Ni,auto:()=>jn,basePlacements:()=>lt,beforeMain:()=>bs,beforeRead:()=>vs,beforeWrite:()=>xs,bottom:()=>ge,clippingParents:()=>Ur,computeStyles:()=>mn,createPopper:()=>Jn,createPopperBase:()=>Is,createPopperLite:()=>Rs,detectOverflow:()=>ke,end:()=>_t,eventListeners:()=>gn,flip:()=>Pi,hide:()=>Fi,left:()=>he,main:()=>_s,modifierPhases:()=>Gr,offset:()=>Bi,placements:()=>qn,popper:()=>$t,popperGenerator:()=>Gt,popperOffsets:()=>En,preventOverflow:()=>$i,read:()=>ys,reference:()=>Yr,right:()=>me,start:()=>rt,top:()=>de,variationPlacements:()=>ki,viewport:()=>Wn,write:()=>Ts});var de="top",ge="bottom",me="right",he="left",jn="auto",lt=[de,ge,me,he],rt="start",_t="end",Ur="clippingParents",Wn="viewport",$t="popper",Yr="reference",ki=lt.reduce(function(n,e){return n.concat([e+"-"+rt,e+"-"+_t])},[]),qn=[].concat(lt,[jn]).reduce(function(n,e){return n.concat([e,e+"-"+rt,e+"-"+_t])},[]),vs="beforeRead",ys="read",Es="afterRead",bs="beforeMain",_s="main",ws="afterMain",xs="beforeWrite",Ts="write",Cs="afterWrite",Gr=[vs,ys,Es,bs,_s,ws,xs,Ts,Cs];function we(n){return n?(n.nodeName||"").toLowerCase():null}function ce(n){if(n==null)return window;if(n.toString()!=="[object Window]"){var e=n.ownerDocument;return e&&e.defaultView||window}return n}function Ue(n){var e=ce(n).Element;return n instanceof e||n instanceof Element}function be(n){var e=ce(n).HTMLElement;return n instanceof e||n instanceof HTMLElement}function fn(n){if(typeof ShadowRoot=="undefined")return!1;var e=ce(n).ShadowRoot;return n instanceof e||n instanceof ShadowRoot}function fu(n){var e=n.state;Object.keys(e.elements).forEach(function(t){var i=e.styles[t]||{},r=e.attributes[t]||{},o=e.elements[t];!be(o)||!we(o)||(Object.assign(o.style,i),Object.keys(r).forEach(function(s){var a=r[s];a===!1?o.removeAttribute(s):o.setAttribute(s,a===!0?"":a)}))})}function hu(n){var e=n.state,t={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,t.popper),e.styles=t,e.elements.arrow&&Object.assign(e.elements.arrow.style,t.arrow),function(){Object.keys(e.elements).forEach(function(i){var r=e.elements[i],o=e.attributes[i]||{},s=Object.keys(e.styles.hasOwnProperty(i)?e.styles[i]:t[i]),a=s.reduce(function(l,c){return l[c]="",l},{});!be(r)||!we(r)||(Object.assign(r.style,a),Object.keys(o).forEach(function(l){r.removeAttribute(l)}))})}}var hn={name:"applyStyles",enabled:!0,phase:"write",fn:fu,effect:hu,requires:["computeStyles"]};function xe(n){return n.split("-")[0]}var Ze=Math.max,Vt=Math.min,ct=Math.round;function pn(){var n=navigator.userAgentData;return n!=null&&n.brands&&Array.isArray(n.brands)?n.brands.map(function(e){return e.brand+"/"+e.version}).join(" "):navigator.userAgent}function Un(){return!/^((?!chrome|android).)*safari/i.test(pn())}function Ye(n,e,t){e===void 0&&(e=!1),t===void 0&&(t=!1);var i=n.getBoundingClientRect(),r=1,o=1;e&&be(n)&&(r=n.offsetWidth>0&&ct(i.width)/n.offsetWidth||1,o=n.offsetHeight>0&&ct(i.height)/n.offsetHeight||1);var s=Ue(n)?ce(n):window,a=s.visualViewport,l=!Un()&&t,c=(i.left+(l&&a?a.offsetLeft:0))/r,u=(i.top+(l&&a?a.offsetTop:0))/o,d=i.width/r,p=i.height/o;return{width:d,height:p,top:u,right:c+d,bottom:u+p,left:c,x:c,y:u}}function zt(n){var e=Ye(n),t=n.offsetWidth,i=n.offsetHeight;return Math.abs(e.width-t)<=1&&(t=e.width),Math.abs(e.height-i)<=1&&(i=e.height),{x:n.offsetLeft,y:n.offsetTop,width:t,height:i}}function Yn(n,e){var t=e.getRootNode&&e.getRootNode();if(n.contains(e))return!0;if(t&&fn(t)){var i=e;do{if(i&&n.isSameNode(i))return!0;i=i.parentNode||i.host}while(i)}return!1}function Me(n){return ce(n).getComputedStyle(n)}function Kr(n){return["table","td","th"].indexOf(we(n))>=0}function Ae(n){return((Ue(n)?n.ownerDocument:n.document)||window.document).documentElement}function ut(n){return we(n)==="html"?n:n.assignedSlot||n.parentNode||(fn(n)?n.host:null)||Ae(n)}function As(n){return!be(n)||Me(n).position==="fixed"?null:n.offsetParent}function pu(n){var e=/firefox/i.test(pn()),t=/Trident/i.test(pn());if(t&&be(n)){var i=Me(n);if(i.position==="fixed")return null}var r=ut(n);for(fn(r)&&(r=r.host);be(r)&&["html","body"].indexOf(we(r))<0;){var o=Me(r);if(o.transform!=="none"||o.perspective!=="none"||o.contain==="paint"||["transform","perspective"].indexOf(o.willChange)!==-1||e&&o.willChange==="filter"||e&&o.filter&&o.filter!=="none")return r;r=r.parentNode}return null}function et(n){for(var e=ce(n),t=As(n);t&&Kr(t)&&Me(t).position==="static";)t=As(t);return t&&(we(t)==="html"||we(t)==="body"&&Me(t).position==="static")?e:t||pu(n)||e}function jt(n){return["top","bottom"].indexOf(n)>=0?"x":"y"}function Wt(n,e,t){return Ze(n,Vt(e,t))}function Ss(n,e,t){var i=Wt(n,e,t);return i>t?t:i}function Gn(){return{top:0,right:0,bottom:0,left:0}}function Kn(n){return Object.assign({},Gn(),n)}function Xn(n,e){return e.reduce(function(t,i){return t[i]=n,t},{})}var mu=function(e,t){return e=typeof e=="function"?e(Object.assign({},t.rects,{placement:t.placement})):e,Kn(typeof e!="number"?e:Xn(e,lt))};function gu(n){var e,t=n.state,i=n.name,r=n.options,o=t.elements.arrow,s=t.modifiersData.popperOffsets,a=xe(t.placement),l=jt(a),c=[he,me].indexOf(a)>=0,u=c?"height":"width";if(!(!o||!s)){var d=mu(r.padding,t),p=zt(o),y=l==="y"?de:he,m=l==="y"?ge:me,v=t.rects.reference[u]+t.rects.reference[l]-s[l]-t.rects.popper[u],w=s[l]-t.rects.reference[l],T=et(o),_=T?l==="y"?T.clientHeight||0:T.clientWidth||0:0,S=v/2-w/2,A=d[y],K=_-p[u]-d[m],z=_/2-p[u]/2+S,L=Wt(A,z,K),H=l;t.modifiersData[i]=(e={},e[H]=L,e.centerOffset=L-z,e)}}function vu(n){var e=n.state,t=n.options,i=t.element,r=i===void 0?"[data-popper-arrow]":i;r!=null&&(typeof r=="string"&&(r=e.elements.popper.querySelector(r),!r)||Yn(e.elements.popper,r)&&(e.elements.arrow=r))}var Ni={name:"arrow",enabled:!0,phase:"main",fn:gu,effect:vu,requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Ge(n){return n.split("-")[1]}var yu={top:"auto",right:"auto",bottom:"auto",left:"auto"};function Eu(n,e){var t=n.x,i=n.y,r=e.devicePixelRatio||1;return{x:ct(t*r)/r||0,y:ct(i*r)/r||0}}function Ds(n){var e,t=n.popper,i=n.popperRect,r=n.placement,o=n.variation,s=n.offsets,a=n.position,l=n.gpuAcceleration,c=n.adaptive,u=n.roundOffsets,d=n.isFixed,p=s.x,y=p===void 0?0:p,m=s.y,v=m===void 0?0:m,w=typeof u=="function"?u({x:y,y:v}):{x:y,y:v};y=w.x,v=w.y;var T=s.hasOwnProperty("x"),_=s.hasOwnProperty("y"),S=he,A=de,K=window;if(c){var z=et(t),L="clientHeight",H="clientWidth";if(z===ce(t)&&(z=Ae(t),Me(z).position!=="static"&&a==="absolute"&&(L="scrollHeight",H="scrollWidth")),z=z,r===de||(r===he||r===me)&&o===_t){A=ge;var N=d&&z===K&&K.visualViewport?K.visualViewport.height:z[L];v-=N-i.height,v*=l?1:-1}if(r===he||(r===de||r===ge)&&o===_t){S=me;var Y=d&&z===K&&K.visualViewport?K.visualViewport.width:z[H];y-=Y-i.width,y*=l?1:-1}}var B=Object.assign({position:a},c&&yu),ie=u===!0?Eu({x:y,y:v},ce(t)):{x:y,y:v};if(y=ie.x,v=ie.y,l){var J;return Object.assign({},B,(J={},J[A]=_?"0":"",J[S]=T?"0":"",J.transform=(K.devicePixelRatio||1)<=1?"translate("+y+"px, "+v+"px)":"translate3d("+y+"px, "+v+"px, 0)",J))}return Object.assign({},B,(e={},e[A]=_?v+"px":"",e[S]=T?y+"px":"",e.transform="",e))}function bu(n){var e=n.state,t=n.options,i=t.gpuAcceleration,r=i===void 0?!0:i,o=t.adaptive,s=o===void 0?!0:o,a=t.roundOffsets,l=a===void 0?!0:a,c={placement:xe(e.placement),variation:Ge(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:r,isFixed:e.options.strategy==="fixed"};e.modifiersData.popperOffsets!=null&&(e.styles.popper=Object.assign({},e.styles.popper,Ds(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:s,roundOffsets:l})))),e.modifiersData.arrow!=null&&(e.styles.arrow=Object.assign({},e.styles.arrow,Ds(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})}var mn={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:bu,data:{}};var Ii={passive:!0};function _u(n){var e=n.state,t=n.instance,i=n.options,r=i.scroll,o=r===void 0?!0:r,s=i.resize,a=s===void 0?!0:s,l=ce(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach(function(u){u.addEventListener("scroll",t.update,Ii)}),a&&l.addEventListener("resize",t.update,Ii),function(){o&&c.forEach(function(u){u.removeEventListener("scroll",t.update,Ii)}),a&&l.removeEventListener("resize",t.update,Ii)}}var gn={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:_u,data:{}};var wu={left:"right",right:"left",bottom:"top",top:"bottom"};function vn(n){return n.replace(/left|right|bottom|top/g,function(e){return wu[e]})}var xu={start:"end",end:"start"};function Ri(n){return n.replace(/start|end/g,function(e){return xu[e]})}function qt(n){var e=ce(n),t=e.pageXOffset,i=e.pageYOffset;return{scrollLeft:t,scrollTop:i}}function Ut(n){return Ye(Ae(n)).left+qt(n).scrollLeft}function Xr(n,e){var t=ce(n),i=Ae(n),r=t.visualViewport,o=i.clientWidth,s=i.clientHeight,a=0,l=0;if(r){o=r.width,s=r.height;var c=Un();(c||!c&&e==="fixed")&&(a=r.offsetLeft,l=r.offsetTop)}return{width:o,height:s,x:a+Ut(n),y:l}}function Qr(n){var e,t=Ae(n),i=qt(n),r=(e=n.ownerDocument)==null?void 0:e.body,o=Ze(t.scrollWidth,t.clientWidth,r?r.scrollWidth:0,r?r.clientWidth:0),s=Ze(t.scrollHeight,t.clientHeight,r?r.scrollHeight:0,r?r.clientHeight:0),a=-i.scrollLeft+Ut(n),l=-i.scrollTop;return Me(r||t).direction==="rtl"&&(a+=Ze(t.clientWidth,r?r.clientWidth:0)-o),{width:o,height:s,x:a,y:l}}function Yt(n){var e=Me(n),t=e.overflow,i=e.overflowX,r=e.overflowY;return/auto|scroll|overlay|hidden/.test(t+r+i)}function Hi(n){return["html","body","#document"].indexOf(we(n))>=0?n.ownerDocument.body:be(n)&&Yt(n)?n:Hi(ut(n))}function wt(n,e){var t;e===void 0&&(e=[]);var i=Hi(n),r=i===((t=n.ownerDocument)==null?void 0:t.body),o=ce(i),s=r?[o].concat(o.visualViewport||[],Yt(i)?i:[]):i,a=e.concat(s);return r?a:a.concat(wt(ut(s)))}function yn(n){return Object.assign({},n,{left:n.x,top:n.y,right:n.x+n.width,bottom:n.y+n.height})}function Tu(n,e){var t=Ye(n,!1,e==="fixed");return t.top=t.top+n.clientTop,t.left=t.left+n.clientLeft,t.bottom=t.top+n.clientHeight,t.right=t.left+n.clientWidth,t.width=n.clientWidth,t.height=n.clientHeight,t.x=t.left,t.y=t.top,t}function Os(n,e,t){return e===Wn?yn(Xr(n,t)):Ue(e)?Tu(e,t):yn(Qr(Ae(n)))}function Cu(n){var e=wt(ut(n)),t=["absolute","fixed"].indexOf(Me(n).position)>=0,i=t&&be(n)?et(n):n;return Ue(i)?e.filter(function(r){return Ue(r)&&Yn(r,i)&&we(r)!=="body"}):[]}function Jr(n,e,t,i){var r=e==="clippingParents"?Cu(n):[].concat(e),o=[].concat(r,[t]),s=o[0],a=o.reduce(function(l,c){var u=Os(n,c,i);return l.top=Ze(u.top,l.top),l.right=Vt(u.right,l.right),l.bottom=Vt(u.bottom,l.bottom),l.left=Ze(u.left,l.left),l},Os(n,s,i));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}function Qn(n){var e=n.reference,t=n.element,i=n.placement,r=i?xe(i):null,o=i?Ge(i):null,s=e.x+e.width/2-t.width/2,a=e.y+e.height/2-t.height/2,l;switch(r){case de:l={x:s,y:e.y-t.height};break;case ge:l={x:s,y:e.y+e.height};break;case me:l={x:e.x+e.width,y:a};break;case he:l={x:e.x-t.width,y:a};break;default:l={x:e.x,y:e.y}}var c=r?jt(r):null;if(c!=null){var u=c==="y"?"height":"width";switch(o){case rt:l[c]=l[c]-(e[u]/2-t[u]/2);break;case _t:l[c]=l[c]+(e[u]/2-t[u]/2);break;default:}}return l}function ke(n,e){e===void 0&&(e={});var t=e,i=t.placement,r=i===void 0?n.placement:i,o=t.strategy,s=o===void 0?n.strategy:o,a=t.boundary,l=a===void 0?Ur:a,c=t.rootBoundary,u=c===void 0?Wn:c,d=t.elementContext,p=d===void 0?$t:d,y=t.altBoundary,m=y===void 0?!1:y,v=t.padding,w=v===void 0?0:v,T=Kn(typeof w!="number"?w:Xn(w,lt)),_=p===$t?Yr:$t,S=n.rects.popper,A=n.elements[m?_:p],K=Jr(Ue(A)?A:A.contextElement||Ae(n.elements.popper),l,u,s),z=Ye(n.elements.reference),L=Qn({reference:z,element:S,strategy:"absolute",placement:r}),H=yn(Object.assign({},S,L)),N=p===$t?H:z,Y={top:K.top-N.top+T.top,bottom:N.bottom-K.bottom+T.bottom,left:K.left-N.left+T.left,right:N.right-K.right+T.right},B=n.modifiersData.offset;if(p===$t&&B){var ie=B[r];Object.keys(Y).forEach(function(J){var Te=[me,ge].indexOf(J)>=0?1:-1,Ce=[de,ge].indexOf(J)>=0?"y":"x";Y[J]+=ie[Ce]*Te})}return Y}function Zr(n,e){e===void 0&&(e={});var t=e,i=t.placement,r=t.boundary,o=t.rootBoundary,s=t.padding,a=t.flipVariations,l=t.allowedAutoPlacements,c=l===void 0?qn:l,u=Ge(i),d=u?a?ki:ki.filter(function(m){return Ge(m)===u}):lt,p=d.filter(function(m){return c.indexOf(m)>=0});p.length===0&&(p=d);var y=p.reduce(function(m,v){return m[v]=ke(n,{placement:v,boundary:r,rootBoundary:o,padding:s})[xe(v)],m},{});return Object.keys(y).sort(function(m,v){return y[m]-y[v]})}function Au(n){if(xe(n)===jn)return[];var e=vn(n);return[Ri(n),e,Ri(e)]}function Su(n){var e=n.state,t=n.options,i=n.name;if(!e.modifiersData[i]._skip){for(var r=t.mainAxis,o=r===void 0?!0:r,s=t.altAxis,a=s===void 0?!0:s,l=t.fallbackPlacements,c=t.padding,u=t.boundary,d=t.rootBoundary,p=t.altBoundary,y=t.flipVariations,m=y===void 0?!0:y,v=t.allowedAutoPlacements,w=e.options.placement,T=xe(w),_=T===w,S=l||(_||!m?[vn(w)]:Au(w)),A=[w].concat(S).reduce(function(V,q){return V.concat(xe(q)===jn?Zr(e,{placement:q,boundary:u,rootBoundary:d,padding:c,flipVariations:m,allowedAutoPlacements:v}):q)},[]),K=e.rects.reference,z=e.rects.popper,L=new Map,H=!0,N=A[0],Y=0;Y=0,Ce=Te?"width":"height",se=ke(e,{placement:B,boundary:u,rootBoundary:d,altBoundary:p,padding:c}),ne=Te?J?me:he:J?ge:de;K[Ce]>z[Ce]&&(ne=vn(ne));var qe=vn(ne),Re=[];if(o&&Re.push(se[ie]<=0),a&&Re.push(se[ne]<=0,se[qe]<=0),Re.every(function(V){return V})){N=B,H=!1;break}L.set(B,Re)}if(H)for(var W=m?3:1,M=function(q){var U=A.find(function(Z){var oe=L.get(Z);if(oe)return oe.slice(0,q).every(function(bt){return bt})});if(U)return N=U,"break"},D=W;D>0;D--){var $=M(D);if($==="break")break}e.placement!==N&&(e.modifiersData[i]._skip=!0,e.placement=N,e.reset=!0)}}var Pi={name:"flip",enabled:!0,phase:"main",fn:Su,requiresIfExists:["offset"],data:{_skip:!1}};function Ls(n,e,t){return t===void 0&&(t={x:0,y:0}),{top:n.top-e.height-t.y,right:n.right-e.width+t.x,bottom:n.bottom-e.height+t.y,left:n.left-e.width-t.x}}function Ms(n){return[de,me,ge,he].some(function(e){return n[e]>=0})}function Du(n){var e=n.state,t=n.name,i=e.rects.reference,r=e.rects.popper,o=e.modifiersData.preventOverflow,s=ke(e,{elementContext:"reference"}),a=ke(e,{altBoundary:!0}),l=Ls(s,i),c=Ls(a,r,o),u=Ms(l),d=Ms(c);e.modifiersData[t]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:u,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":u,"data-popper-escaped":d})}var Fi={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:Du};function Ou(n,e,t){var i=xe(n),r=[he,de].indexOf(i)>=0?-1:1,o=typeof t=="function"?t(Object.assign({},e,{placement:n})):t,s=o[0],a=o[1];return s=s||0,a=(a||0)*r,[he,me].indexOf(i)>=0?{x:a,y:s}:{x:s,y:a}}function Lu(n){var e=n.state,t=n.options,i=n.name,r=t.offset,o=r===void 0?[0,0]:r,s=qn.reduce(function(u,d){return u[d]=Ou(d,e.rects,o),u},{}),a=s[e.placement],l=a.x,c=a.y;e.modifiersData.popperOffsets!=null&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[i]=s}var Bi={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:Lu};function Mu(n){var e=n.state,t=n.name;e.modifiersData[t]=Qn({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})}var En={name:"popperOffsets",enabled:!0,phase:"read",fn:Mu,data:{}};function eo(n){return n==="x"?"y":"x"}function ku(n){var e=n.state,t=n.options,i=n.name,r=t.mainAxis,o=r===void 0?!0:r,s=t.altAxis,a=s===void 0?!1:s,l=t.boundary,c=t.rootBoundary,u=t.altBoundary,d=t.padding,p=t.tether,y=p===void 0?!0:p,m=t.tetherOffset,v=m===void 0?0:m,w=ke(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:u}),T=xe(e.placement),_=Ge(e.placement),S=!_,A=jt(T),K=eo(A),z=e.modifiersData.popperOffsets,L=e.rects.reference,H=e.rects.popper,N=typeof v=="function"?v(Object.assign({},e.rects,{placement:e.placement})):v,Y=typeof N=="number"?{mainAxis:N,altAxis:N}:Object.assign({mainAxis:0,altAxis:0},N),B=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,ie={x:0,y:0};if(z){if(o){var J,Te=A==="y"?de:he,Ce=A==="y"?ge:me,se=A==="y"?"height":"width",ne=z[A],qe=ne+w[Te],Re=ne-w[Ce],W=y?-H[se]/2:0,M=_===rt?L[se]:H[se],D=_===rt?-H[se]:-L[se],$=e.elements.arrow,V=y&&$?zt($):{width:0,height:0},q=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:Gn(),U=q[Te],Z=q[Ce],oe=Wt(0,L[se],V[se]),bt=S?L[se]/2-W-oe-U-Y.mainAxis:M-oe-U-Y.mainAxis,Br=S?-L[se]/2+W+oe+Z+Y.mainAxis:D+oe+Z+Y.mainAxis,on=e.elements.arrow&&et(e.elements.arrow),sn=on?A==="y"?on.clientTop||0:on.clientLeft||0:0,Ti=(J=B==null?void 0:B[A])!=null?J:0,$r=ne+bt-Ti-sn,Ci=ne+Br-Ti,Ai=Wt(y?Vt(qe,$r):qe,ne,y?Ze(Re,Ci):Re);z[A]=Ai,ie[A]=Ai-ne}if(a){var Bn,Si=A==="x"?de:he,an=A==="x"?ge:me,ot=z[K],ln=K==="y"?"height":"width",$n=ot+w[Si],cn=ot-w[an],un=[de,he].indexOf(T)!==-1,Bt=(Bn=B==null?void 0:B[K])!=null?Bn:0,Di=un?$n:ot-L[ln]-H[ln]-Bt+Y.altAxis,Vn=un?ot+L[ln]+H[ln]-Bt-Y.altAxis:cn,Oi=y&&un?Ss(Di,ot,Vn):Wt(y?Di:$n,ot,y?Vn:cn);z[K]=Oi,ie[K]=Oi-ot}e.modifiersData[i]=ie}}var $i={name:"preventOverflow",enabled:!0,phase:"main",fn:ku,requiresIfExists:["offset"]};function to(n){return{scrollLeft:n.scrollLeft,scrollTop:n.scrollTop}}function no(n){return n===ce(n)||!be(n)?qt(n):to(n)}function Nu(n){var e=n.getBoundingClientRect(),t=ct(e.width)/n.offsetWidth||1,i=ct(e.height)/n.offsetHeight||1;return t!==1||i!==1}function io(n,e,t){t===void 0&&(t=!1);var i=be(e),r=be(e)&&Nu(e),o=Ae(e),s=Ye(n,r,t),a={scrollLeft:0,scrollTop:0},l={x:0,y:0};return(i||!i&&!t)&&((we(e)!=="body"||Yt(o))&&(a=no(e)),be(e)?(l=Ye(e,!0),l.x+=e.clientLeft,l.y+=e.clientTop):o&&(l.x=Ut(o))),{x:s.left+a.scrollLeft-l.x,y:s.top+a.scrollTop-l.y,width:s.width,height:s.height}}function Iu(n){var e=new Map,t=new Set,i=[];n.forEach(function(o){e.set(o.name,o)});function r(o){t.add(o.name);var s=[].concat(o.requires||[],o.requiresIfExists||[]);s.forEach(function(a){if(!t.has(a)){var l=e.get(a);l&&r(l)}}),i.push(o)}return n.forEach(function(o){t.has(o.name)||r(o)}),i}function ro(n){var e=Iu(n);return Gr.reduce(function(t,i){return t.concat(e.filter(function(r){return r.phase===i}))},[])}function oo(n){var e;return function(){return e||(e=new Promise(function(t){Promise.resolve().then(function(){e=void 0,t(n())})})),e}}function so(n){var e=n.reduce(function(t,i){var r=t[i.name];return t[i.name]=r?Object.assign({},r,i,{options:Object.assign({},r.options,i.options),data:Object.assign({},r.data,i.data)}):i,t},{});return Object.keys(e).map(function(t){return e[t]})}var ks={placement:"bottom",modifiers:[],strategy:"absolute"};function Ns(){for(var n=arguments.length,e=new Array(n),t=0;t(n&&window.CSS&&window.CSS.escape&&(n=n.replace(/#([^\s"#']+)/g,(e,t)=>`#${CSS.escape(t)}`)),n),Bu=n=>n==null?`${n}`:Object.prototype.toString.call(n).match(/\s([a-z]+)/i)[1].toLowerCase(),$u=n=>{do n+=Math.floor(Math.random()*Pu);while(document.getElementById(n));return n},Vu=n=>{if(!n)return 0;let{transitionDuration:e,transitionDelay:t}=window.getComputedStyle(n),i=Number.parseFloat(e),r=Number.parseFloat(t);return!i&&!r?0:(e=e.split(",")[0],t=t.split(",")[0],(Number.parseFloat(e)+Number.parseFloat(t))*Fu)},da=n=>{n.dispatchEvent(new Event(To))},dt=n=>!n||typeof n!="object"?!1:(typeof n.jquery!="undefined"&&(n=n[0]),typeof n.nodeType!="undefined"),Tt=n=>dt(n)?n.jquery?n[0]:n:typeof n=="string"&&n.length>0?document.querySelector(ua(n)):null,An=n=>{if(!dt(n)||n.getClientRects().length===0)return!1;let e=getComputedStyle(n).getPropertyValue("visibility")==="visible",t=n.closest("details:not([open])");if(!t)return e;if(t!==n){let i=n.closest("summary");if(i&&i.parentNode!==t||i===null)return!1}return e},Ct=n=>!n||n.nodeType!==Node.ELEMENT_NODE||n.classList.contains("disabled")?!0:typeof n.disabled!="undefined"?n.disabled:n.hasAttribute("disabled")&&n.getAttribute("disabled")!=="false",fa=n=>{if(!document.documentElement.attachShadow)return null;if(typeof n.getRootNode=="function"){let e=n.getRootNode();return e instanceof ShadowRoot?e:null}return n instanceof ShadowRoot?n:n.parentNode?fa(n.parentNode):null},Xi=()=>{},ii=n=>{n.offsetHeight},ha=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,lo=[],zu=n=>{document.readyState==="loading"?(lo.length||document.addEventListener("DOMContentLoaded",()=>{for(let e of lo)e()}),lo.push(n)):n()},Ke=()=>document.documentElement.dir==="rtl",Qe=n=>{zu(()=>{let e=ha();if(e){let t=n.NAME,i=e.fn[t];e.fn[t]=n.jQueryInterface,e.fn[t].Constructor=n,e.fn[t].noConflict=()=>(e.fn[t]=i,n.jQueryInterface)}})},He=(n,e=[],t=n)=>typeof n=="function"?n.call(...e):t,pa=(n,e,t=!0)=>{if(!t){He(n);return}let r=Vu(e)+5,o=!1,s=({target:a})=>{a===e&&(o=!0,e.removeEventListener(To,s),He(n))};e.addEventListener(To,s),setTimeout(()=>{o||da(e)},r)},Do=(n,e,t,i)=>{let r=n.length,o=n.indexOf(e);return o===-1?!t&&i?n[r-1]:n[0]:(o+=t?1:-1,i&&(o=(o+r)%r),n[Math.max(0,Math.min(o,r-1))])},ju=/[^.]*(?=\..*)\.|.*/,Wu=/\..*/,qu=/::\d+$/,co={},Hs=1,ma={mouseenter:"mouseover",mouseleave:"mouseout"},Uu=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function ga(n,e){return e&&`${e}::${Hs++}`||n.uidEvent||Hs++}function va(n){let e=ga(n);return n.uidEvent=e,co[e]=co[e]||{},co[e]}function Yu(n,e){return function t(i){return Oo(i,{delegateTarget:n}),t.oneOff&&x.off(n,i.type,e),e.apply(n,[i])}}function Gu(n,e,t){return function i(r){let o=n.querySelectorAll(e);for(let{target:s}=r;s&&s!==this;s=s.parentNode)for(let a of o)if(a===s)return Oo(r,{delegateTarget:s}),i.oneOff&&x.off(n,r.type,e,t),t.apply(s,[r])}}function ya(n,e,t=null){return Object.values(n).find(i=>i.callable===e&&i.delegationSelector===t)}function Ea(n,e,t){let i=typeof e=="string",r=i?t:e||t,o=ba(n);return Uu.has(o)||(o=n),[i,r,o]}function Ps(n,e,t,i,r){if(typeof e!="string"||!n)return;let[o,s,a]=Ea(e,t,i);e in ma&&(s=(m=>function(v){if(!v.relatedTarget||v.relatedTarget!==v.delegateTarget&&!v.delegateTarget.contains(v.relatedTarget))return m.call(this,v)})(s));let l=va(n),c=l[a]||(l[a]={}),u=ya(c,s,o?t:null);if(u){u.oneOff=u.oneOff&&r;return}let d=ga(s,e.replace(ju,"")),p=o?Gu(n,t,s):Yu(n,s);p.delegationSelector=o?t:null,p.callable=s,p.oneOff=r,p.uidEvent=d,c[d]=p,n.addEventListener(a,p,o)}function Co(n,e,t,i,r){let o=ya(e[t],i,r);o&&(n.removeEventListener(t,o,!!r),delete e[t][o.uidEvent])}function Ku(n,e,t,i){let r=e[t]||{};for(let[o,s]of Object.entries(r))o.includes(i)&&Co(n,e,t,s.callable,s.delegationSelector)}function ba(n){return n=n.replace(Wu,""),ma[n]||n}var x={on(n,e,t,i){Ps(n,e,t,i,!1)},one(n,e,t,i){Ps(n,e,t,i,!0)},off(n,e,t,i){if(typeof e!="string"||!n)return;let[r,o,s]=Ea(e,t,i),a=s!==e,l=va(n),c=l[s]||{},u=e.startsWith(".");if(typeof o!="undefined"){if(!Object.keys(c).length)return;Co(n,l,s,o,r?t:null);return}if(u)for(let d of Object.keys(l))Ku(n,l,d,e.slice(1));for(let[d,p]of Object.entries(c)){let y=d.replace(qu,"");(!a||e.includes(y))&&Co(n,l,s,p.callable,p.delegationSelector)}},trigger(n,e,t){if(typeof e!="string"||!n)return null;let i=ha(),r=ba(e),o=e!==r,s=null,a=!0,l=!0,c=!1;o&&i&&(s=i.Event(e,t),i(n).trigger(s),a=!s.isPropagationStopped(),l=!s.isImmediatePropagationStopped(),c=s.isDefaultPrevented());let u=Oo(new Event(e,{bubbles:a,cancelable:!0}),t);return c&&u.preventDefault(),l&&n.dispatchEvent(u),u.defaultPrevented&&s&&s.preventDefault(),u}};function Oo(n,e={}){for(let[t,i]of Object.entries(e))try{n[t]=i}catch(r){Object.defineProperty(n,t,{configurable:!0,get(){return i}})}return n}function Fs(n){if(n==="true")return!0;if(n==="false")return!1;if(n===Number(n).toString())return Number(n);if(n===""||n==="null")return null;if(typeof n!="string")return n;try{return JSON.parse(decodeURIComponent(n))}catch(e){return n}}function uo(n){return n.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}var ft={setDataAttribute(n,e,t){n.setAttribute(`data-bs-${uo(e)}`,t)},removeDataAttribute(n,e){n.removeAttribute(`data-bs-${uo(e)}`)},getDataAttributes(n){if(!n)return{};let e={},t=Object.keys(n.dataset).filter(i=>i.startsWith("bs")&&!i.startsWith("bsConfig"));for(let i of t){let r=i.replace(/^bs/,"");r=r.charAt(0).toLowerCase()+r.slice(1),e[r]=Fs(n.dataset[i])}return e},getDataAttribute(n,e){return Fs(n.getAttribute(`data-bs-${uo(e)}`))}},Qt=class{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(e){return e=this._mergeConfigObj(e),e=this._configAfterMerge(e),this._typeCheckConfig(e),e}_configAfterMerge(e){return e}_mergeConfigObj(e,t){let i=dt(t)?ft.getDataAttribute(t,"config"):{};return O(O(O(O({},this.constructor.Default),typeof i=="object"?i:{}),dt(t)?ft.getDataAttributes(t):{}),typeof e=="object"?e:{})}_typeCheckConfig(e,t=this.constructor.DefaultType){for(let[i,r]of Object.entries(t)){let o=e[i],s=dt(o)?"element":Bu(o);if(!new RegExp(r).test(s))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${i}" provided type "${s}" but expected type "${r}".`)}}},Xu="5.3.8",je=class extends Qt{constructor(e,t){super(),e=Tt(e),e&&(this._element=e,this._config=this._getConfig(t),ao.set(this._element,this.constructor.DATA_KEY,this))}dispose(){ao.remove(this._element,this.constructor.DATA_KEY),x.off(this._element,this.constructor.EVENT_KEY);for(let e of Object.getOwnPropertyNames(this))this[e]=null}_queueCallback(e,t,i=!0){pa(e,t,i)}_getConfig(e){return e=this._mergeConfigObj(e,this._element),e=this._configAfterMerge(e),this._typeCheckConfig(e),e}static getInstance(e){return ao.get(Tt(e),this.DATA_KEY)}static getOrCreateInstance(e,t={}){return this.getInstance(e)||new this(e,typeof t=="object"?t:null)}static get VERSION(){return Xu}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(e){return`${e}${this.EVENT_KEY}`}},fo=n=>{let e=n.getAttribute("data-bs-target");if(!e||e==="#"){let t=n.getAttribute("href");if(!t||!t.includes("#")&&!t.startsWith("."))return null;t.includes("#")&&!t.startsWith("#")&&(t=`#${t.split("#")[1]}`),e=t&&t!=="#"?t.trim():null}return e?e.split(",").map(t=>ua(t)).join(","):null},j={find(n,e=document.documentElement){return[].concat(...Element.prototype.querySelectorAll.call(e,n))},findOne(n,e=document.documentElement){return Element.prototype.querySelector.call(e,n)},children(n,e){return[].concat(...n.children).filter(t=>t.matches(e))},parents(n,e){let t=[],i=n.parentNode.closest(e);for(;i;)t.push(i),i=i.parentNode.closest(e);return t},prev(n,e){let t=n.previousElementSibling;for(;t;){if(t.matches(e))return[t];t=t.previousElementSibling}return[]},next(n,e){let t=n.nextElementSibling;for(;t;){if(t.matches(e))return[t];t=t.nextElementSibling}return[]},focusableChildren(n){let e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map(t=>`${t}:not([tabindex^="-"])`).join(",");return this.find(e,n).filter(t=>!Ct(t)&&An(t))},getSelectorFromElement(n){let e=fo(n);return e&&j.findOne(e)?e:null},getElementFromSelector(n){let e=fo(n);return e?j.findOne(e):null},getMultipleElementsFromSelector(n){let e=fo(n);return e?j.find(e):[]}},rr=(n,e="hide")=>{let t=`click.dismiss${n.EVENT_KEY}`,i=n.NAME;x.on(document,t,`[data-bs-dismiss="${i}"]`,function(r){if(["A","AREA"].includes(this.tagName)&&r.preventDefault(),Ct(this))return;let o=j.getElementFromSelector(this)||this.closest(`.${i}`);n.getOrCreateInstance(o)[e]()})},Qu="alert",Ju="bs.alert",_a=`.${Ju}`,Zu=`close${_a}`,ed=`closed${_a}`,td="fade",nd="show",Qi=class n extends je{static get NAME(){return Qu}close(){if(x.trigger(this._element,Zu).defaultPrevented)return;this._element.classList.remove(nd);let t=this._element.classList.contains(td);this._queueCallback(()=>this._destroyElement(),this._element,t)}_destroyElement(){this._element.remove(),x.trigger(this._element,ed),this.dispose()}static jQueryInterface(e){return this.each(function(){let t=n.getOrCreateInstance(this);if(typeof e=="string"){if(t[e]===void 0||e.startsWith("_")||e==="constructor")throw new TypeError(`No method named "${e}"`);t[e](this)}})}};rr(Qi,"close");Qe(Qi);var id="button",rd="bs.button",od=`.${rd}`,sd=".data-api",ad="active",Bs='[data-bs-toggle="button"]',ld=`click${od}${sd}`,Ji=class n extends je{static get NAME(){return id}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle(ad))}static jQueryInterface(e){return this.each(function(){let t=n.getOrCreateInstance(this);e==="toggle"&&t[e]()})}};x.on(document,ld,Bs,n=>{n.preventDefault();let e=n.target.closest(Bs);Ji.getOrCreateInstance(e).toggle()});Qe(Ji);var cd="swipe",Sn=".bs.swipe",ud=`touchstart${Sn}`,dd=`touchmove${Sn}`,fd=`touchend${Sn}`,hd=`pointerdown${Sn}`,pd=`pointerup${Sn}`,md="touch",gd="pen",vd="pointer-event",yd=40,Ed={endCallback:null,leftCallback:null,rightCallback:null},bd={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"},Zi=class n extends Qt{constructor(e,t){super(),this._element=e,!(!e||!n.isSupported())&&(this._config=this._getConfig(t),this._deltaX=0,this._supportPointerEvents=!!window.PointerEvent,this._initEvents())}static get Default(){return Ed}static get DefaultType(){return bd}static get NAME(){return cd}dispose(){x.off(this._element,Sn)}_start(e){if(!this._supportPointerEvents){this._deltaX=e.touches[0].clientX;return}this._eventIsPointerPenTouch(e)&&(this._deltaX=e.clientX)}_end(e){this._eventIsPointerPenTouch(e)&&(this._deltaX=e.clientX-this._deltaX),this._handleSwipe(),He(this._config.endCallback)}_move(e){this._deltaX=e.touches&&e.touches.length>1?0:e.touches[0].clientX-this._deltaX}_handleSwipe(){let e=Math.abs(this._deltaX);if(e<=yd)return;let t=e/this._deltaX;this._deltaX=0,t&&He(t>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(x.on(this._element,hd,e=>this._start(e)),x.on(this._element,pd,e=>this._end(e)),this._element.classList.add(vd)):(x.on(this._element,ud,e=>this._start(e)),x.on(this._element,dd,e=>this._move(e)),x.on(this._element,fd,e=>this._end(e)))}_eventIsPointerPenTouch(e){return this._supportPointerEvents&&(e.pointerType===gd||e.pointerType===md)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}},_d="carousel",wd="bs.carousel",Ot=`.${wd}`,wa=".data-api",xd="ArrowLeft",Td="ArrowRight",Cd=500,Zn="next",bn="prev",wn="left",Gi="right",Ad=`slide${Ot}`,ho=`slid${Ot}`,Sd=`keydown${Ot}`,Dd=`mouseenter${Ot}`,Od=`mouseleave${Ot}`,Ld=`dragstart${Ot}`,Md=`load${Ot}${wa}`,kd=`click${Ot}${wa}`,xa="carousel",zi="active",Nd="slide",Id="carousel-item-end",Rd="carousel-item-start",Hd="carousel-item-next",Pd="carousel-item-prev",Ta=".active",Ca=".carousel-item",Fd=Ta+Ca,Bd=".carousel-item img",$d=".carousel-indicators",Vd="[data-bs-slide], [data-bs-slide-to]",zd='[data-bs-ride="carousel"]',jd={[xd]:Gi,[Td]:wn},Wd={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},qd={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"},ti=class n extends je{constructor(e,t){super(e,t),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=j.findOne($d,this._element),this._addEventListeners(),this._config.ride===xa&&this.cycle()}static get Default(){return Wd}static get DefaultType(){return qd}static get NAME(){return _d}next(){this._slide(Zn)}nextWhenVisible(){!document.hidden&&An(this._element)&&this.next()}prev(){this._slide(bn)}pause(){this._isSliding&&da(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval(()=>this.nextWhenVisible(),this._config.interval)}_maybeEnableCycle(){if(this._config.ride){if(this._isSliding){x.one(this._element,ho,()=>this.cycle());return}this.cycle()}}to(e){let t=this._getItems();if(e>t.length-1||e<0)return;if(this._isSliding){x.one(this._element,ho,()=>this.to(e));return}let i=this._getItemIndex(this._getActive());if(i===e)return;let r=e>i?Zn:bn;this._slide(r,t[e])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(e){return e.defaultInterval=e.interval,e}_addEventListeners(){this._config.keyboard&&x.on(this._element,Sd,e=>this._keydown(e)),this._config.pause==="hover"&&(x.on(this._element,Dd,()=>this.pause()),x.on(this._element,Od,()=>this._maybeEnableCycle())),this._config.touch&&Zi.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(let i of j.find(Bd,this._element))x.on(i,Ld,r=>r.preventDefault());let t={leftCallback:()=>this._slide(this._directionToOrder(wn)),rightCallback:()=>this._slide(this._directionToOrder(Gi)),endCallback:()=>{this._config.pause==="hover"&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout(()=>this._maybeEnableCycle(),Cd+this._config.interval))}};this._swipeHelper=new Zi(this._element,t)}_keydown(e){if(/input|textarea/i.test(e.target.tagName))return;let t=jd[e.key];t&&(e.preventDefault(),this._slide(this._directionToOrder(t)))}_getItemIndex(e){return this._getItems().indexOf(e)}_setActiveIndicatorElement(e){if(!this._indicatorsElement)return;let t=j.findOne(Ta,this._indicatorsElement);t.classList.remove(zi),t.removeAttribute("aria-current");let i=j.findOne(`[data-bs-slide-to="${e}"]`,this._indicatorsElement);i&&(i.classList.add(zi),i.setAttribute("aria-current","true"))}_updateInterval(){let e=this._activeElement||this._getActive();if(!e)return;let t=Number.parseInt(e.getAttribute("data-bs-interval"),10);this._config.interval=t||this._config.defaultInterval}_slide(e,t=null){if(this._isSliding)return;let i=this._getActive(),r=e===Zn,o=t||Do(this._getItems(),i,r,this._config.wrap);if(o===i)return;let s=this._getItemIndex(o),a=y=>x.trigger(this._element,y,{relatedTarget:o,direction:this._orderToDirection(e),from:this._getItemIndex(i),to:s});if(a(Ad).defaultPrevented||!i||!o)return;let c=!!this._interval;this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(s),this._activeElement=o;let u=r?Rd:Id,d=r?Hd:Pd;o.classList.add(d),ii(o),i.classList.add(u),o.classList.add(u);let p=()=>{o.classList.remove(u,d),o.classList.add(zi),i.classList.remove(zi,d,u),this._isSliding=!1,a(ho)};this._queueCallback(p,i,this._isAnimated()),c&&this.cycle()}_isAnimated(){return this._element.classList.contains(Nd)}_getActive(){return j.findOne(Fd,this._element)}_getItems(){return j.find(Ca,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(e){return Ke()?e===wn?bn:Zn:e===wn?Zn:bn}_orderToDirection(e){return Ke()?e===bn?wn:Gi:e===bn?Gi:wn}static jQueryInterface(e){return this.each(function(){let t=n.getOrCreateInstance(this,e);if(typeof e=="number"){t.to(e);return}if(typeof e=="string"){if(t[e]===void 0||e.startsWith("_")||e==="constructor")throw new TypeError(`No method named "${e}"`);t[e]()}})}};x.on(document,kd,Vd,function(n){let e=j.getElementFromSelector(this);if(!e||!e.classList.contains(xa))return;n.preventDefault();let t=ti.getOrCreateInstance(e),i=this.getAttribute("data-bs-slide-to");if(i){t.to(i),t._maybeEnableCycle();return}if(ft.getDataAttribute(this,"slide")==="next"){t.next(),t._maybeEnableCycle();return}t.prev(),t._maybeEnableCycle()});x.on(window,Md,()=>{let n=j.find(zd);for(let e of n)ti.getOrCreateInstance(e)});Qe(ti);var Ud="collapse",Yd="bs.collapse",ri=`.${Yd}`,Gd=".data-api",Kd=`show${ri}`,Xd=`shown${ri}`,Qd=`hide${ri}`,Jd=`hidden${ri}`,Zd=`click${ri}${Gd}`,po="show",Tn="collapse",ji="collapsing",ef="collapsed",tf=`:scope .${Tn} .${Tn}`,nf="collapse-horizontal",rf="width",of="height",sf=".collapse.show, .collapse.collapsing",Ao='[data-bs-toggle="collapse"]',af={parent:null,toggle:!0},lf={parent:"(null|element)",toggle:"boolean"},At=class n extends je{constructor(e,t){super(e,t),this._isTransitioning=!1,this._triggerArray=[];let i=j.find(Ao);for(let r of i){let o=j.getSelectorFromElement(r),s=j.find(o).filter(a=>a===this._element);o!==null&&s.length&&this._triggerArray.push(r)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return af}static get DefaultType(){return lf}static get NAME(){return Ud}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let e=[];if(this._config.parent&&(e=this._getFirstLevelChildren(sf).filter(a=>a!==this._element).map(a=>n.getOrCreateInstance(a,{toggle:!1}))),e.length&&e[0]._isTransitioning||x.trigger(this._element,Kd).defaultPrevented)return;for(let a of e)a.hide();let i=this._getDimension();this._element.classList.remove(Tn),this._element.classList.add(ji),this._element.style[i]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;let r=()=>{this._isTransitioning=!1,this._element.classList.remove(ji),this._element.classList.add(Tn,po),this._element.style[i]="",x.trigger(this._element,Xd)},s=`scroll${i[0].toUpperCase()+i.slice(1)}`;this._queueCallback(r,this._element,!0),this._element.style[i]=`${this._element[s]}px`}hide(){if(this._isTransitioning||!this._isShown()||x.trigger(this._element,Qd).defaultPrevented)return;let t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,ii(this._element),this._element.classList.add(ji),this._element.classList.remove(Tn,po);for(let r of this._triggerArray){let o=j.getElementFromSelector(r);o&&!this._isShown(o)&&this._addAriaAndCollapsedClass([r],!1)}this._isTransitioning=!0;let i=()=>{this._isTransitioning=!1,this._element.classList.remove(ji),this._element.classList.add(Tn),x.trigger(this._element,Jd)};this._element.style[t]="",this._queueCallback(i,this._element,!0)}_isShown(e=this._element){return e.classList.contains(po)}_configAfterMerge(e){return e.toggle=!!e.toggle,e.parent=Tt(e.parent),e}_getDimension(){return this._element.classList.contains(nf)?rf:of}_initializeChildren(){if(!this._config.parent)return;let e=this._getFirstLevelChildren(Ao);for(let t of e){let i=j.getElementFromSelector(t);i&&this._addAriaAndCollapsedClass([t],this._isShown(i))}}_getFirstLevelChildren(e){let t=j.find(tf,this._config.parent);return j.find(e,this._config.parent).filter(i=>!t.includes(i))}_addAriaAndCollapsedClass(e,t){if(e.length)for(let i of e)i.classList.toggle(ef,!t),i.setAttribute("aria-expanded",t)}static jQueryInterface(e){let t={};return typeof e=="string"&&/show|hide/.test(e)&&(t.toggle=!1),this.each(function(){let i=n.getOrCreateInstance(this,t);if(typeof e=="string"){if(typeof i[e]=="undefined")throw new TypeError(`No method named "${e}"`);i[e]()}})}};x.on(document,Zd,Ao,function(n){(n.target.tagName==="A"||n.delegateTarget&&n.delegateTarget.tagName==="A")&&n.preventDefault();for(let e of j.getMultipleElementsFromSelector(this))At.getOrCreateInstance(e,{toggle:!1}).toggle()});Qe(At);var $s="dropdown",cf="bs.dropdown",Zt=`.${cf}`,Lo=".data-api",uf="Escape",Vs="Tab",df="ArrowUp",zs="ArrowDown",ff=2,hf=`hide${Zt}`,pf=`hidden${Zt}`,mf=`show${Zt}`,gf=`shown${Zt}`,Aa=`click${Zt}${Lo}`,Sa=`keydown${Zt}${Lo}`,vf=`keyup${Zt}${Lo}`,xn="show",yf="dropup",Ef="dropend",bf="dropstart",_f="dropup-center",wf="dropdown-center",Kt='[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)',xf=`${Kt}.${xn}`,Ki=".dropdown-menu",Tf=".navbar",Cf=".navbar-nav",Af=".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",Sf=Ke()?"top-end":"top-start",Df=Ke()?"top-start":"top-end",Of=Ke()?"bottom-end":"bottom-start",Lf=Ke()?"bottom-start":"bottom-end",Mf=Ke()?"left-start":"right-start",kf=Ke()?"right-start":"left-start",Nf="top",If="bottom",Rf={autoClose:!0,boundary:"clippingParents",display:"dynamic",offset:[0,2],popperConfig:null,reference:"toggle"},Hf={autoClose:"(boolean|string)",boundary:"(string|element)",display:"string",offset:"(array|string|function)",popperConfig:"(null|object|function)",reference:"(string|element|object)"},St=class n extends je{constructor(e,t){super(e,t),this._popper=null,this._parent=this._element.parentNode,this._menu=j.next(this._element,Ki)[0]||j.prev(this._element,Ki)[0]||j.findOne(Ki,this._parent),this._inNavbar=this._detectNavbar()}static get Default(){return Rf}static get DefaultType(){return Hf}static get NAME(){return $s}toggle(){return this._isShown()?this.hide():this.show()}show(){if(Ct(this._element)||this._isShown())return;let e={relatedTarget:this._element};if(!x.trigger(this._element,mf,e).defaultPrevented){if(this._createPopper(),"ontouchstart"in document.documentElement&&!this._parent.closest(Cf))for(let i of[].concat(...document.body.children))x.on(i,"mouseover",Xi);this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(xn),this._element.classList.add(xn),x.trigger(this._element,gf,e)}}hide(){if(Ct(this._element)||!this._isShown())return;let e={relatedTarget:this._element};this._completeHide(e)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(e){if(!x.trigger(this._element,hf,e).defaultPrevented){if("ontouchstart"in document.documentElement)for(let i of[].concat(...document.body.children))x.off(i,"mouseover",Xi);this._popper&&this._popper.destroy(),this._menu.classList.remove(xn),this._element.classList.remove(xn),this._element.setAttribute("aria-expanded","false"),ft.removeDataAttribute(this._menu,"popper"),x.trigger(this._element,pf,e)}}_getConfig(e){if(e=super._getConfig(e),typeof e.reference=="object"&&!dt(e.reference)&&typeof e.reference.getBoundingClientRect!="function")throw new TypeError(`${$s.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return e}_createPopper(){if(typeof Vi=="undefined")throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org/docs/v2/)");let e=this._element;this._config.reference==="parent"?e=this._parent:dt(this._config.reference)?e=Tt(this._config.reference):typeof this._config.reference=="object"&&(e=this._config.reference);let t=this._getPopperConfig();this._popper=Jn(e,this._menu,t)}_isShown(){return this._menu.classList.contains(xn)}_getPlacement(){let e=this._parent;if(e.classList.contains(Ef))return Mf;if(e.classList.contains(bf))return kf;if(e.classList.contains(_f))return Nf;if(e.classList.contains(wf))return If;let t=getComputedStyle(this._menu).getPropertyValue("--bs-position").trim()==="end";return e.classList.contains(yf)?t?Df:Sf:t?Lf:Of}_detectNavbar(){return this._element.closest(Tf)!==null}_getOffset(){let{offset:e}=this._config;return typeof e=="string"?e.split(",").map(t=>Number.parseInt(t,10)):typeof e=="function"?t=>e(t,this._element):e}_getPopperConfig(){let e={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||this._config.display==="static")&&(ft.setDataAttribute(this._menu,"popper","static"),e.modifiers=[{name:"applyStyles",enabled:!1}]),O(O({},e),He(this._config.popperConfig,[void 0,e]))}_selectMenuItem({key:e,target:t}){let i=j.find(Af,this._menu).filter(r=>An(r));i.length&&Do(i,t,e===zs,!i.includes(t)).focus()}static jQueryInterface(e){return this.each(function(){let t=n.getOrCreateInstance(this,e);if(typeof e=="string"){if(typeof t[e]=="undefined")throw new TypeError(`No method named "${e}"`);t[e]()}})}static clearMenus(e){if(e.button===ff||e.type==="keyup"&&e.key!==Vs)return;let t=j.find(xf);for(let i of t){let r=n.getInstance(i);if(!r||r._config.autoClose===!1)continue;let o=e.composedPath(),s=o.includes(r._menu);if(o.includes(r._element)||r._config.autoClose==="inside"&&!s||r._config.autoClose==="outside"&&s||r._menu.contains(e.target)&&(e.type==="keyup"&&e.key===Vs||/input|select|option|textarea|form/i.test(e.target.tagName)))continue;let a={relatedTarget:r._element};e.type==="click"&&(a.clickEvent=e),r._completeHide(a)}}static dataApiKeydownHandler(e){let t=/input|textarea/i.test(e.target.tagName),i=e.key===uf,r=[df,zs].includes(e.key);if(!r&&!i||t&&!i)return;e.preventDefault();let o=this.matches(Kt)?this:j.prev(this,Kt)[0]||j.next(this,Kt)[0]||j.findOne(Kt,e.delegateTarget.parentNode),s=n.getOrCreateInstance(o);if(r){e.stopPropagation(),s.show(),s._selectMenuItem(e);return}s._isShown()&&(e.stopPropagation(),s.hide(),o.focus())}};x.on(document,Sa,Kt,St.dataApiKeydownHandler);x.on(document,Sa,Ki,St.dataApiKeydownHandler);x.on(document,Aa,St.clearMenus);x.on(document,vf,St.clearMenus);x.on(document,Aa,Kt,function(n){n.preventDefault(),St.getOrCreateInstance(this).toggle()});Qe(St);var Da="backdrop",Pf="fade",js="show",Ws=`mousedown.bs.${Da}`,Ff={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Bf={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"},er=class extends Qt{constructor(e){super(),this._config=this._getConfig(e),this._isAppended=!1,this._element=null}static get Default(){return Ff}static get DefaultType(){return Bf}static get NAME(){return Da}show(e){if(!this._config.isVisible){He(e);return}this._append();let t=this._getElement();this._config.isAnimated&&ii(t),t.classList.add(js),this._emulateAnimation(()=>{He(e)})}hide(e){if(!this._config.isVisible){He(e);return}this._getElement().classList.remove(js),this._emulateAnimation(()=>{this.dispose(),He(e)})}dispose(){this._isAppended&&(x.off(this._element,Ws),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){let e=document.createElement("div");e.className=this._config.className,this._config.isAnimated&&e.classList.add(Pf),this._element=e}return this._element}_configAfterMerge(e){return e.rootElement=Tt(e.rootElement),e}_append(){if(this._isAppended)return;let e=this._getElement();this._config.rootElement.append(e),x.on(e,Ws,()=>{He(this._config.clickCallback)}),this._isAppended=!0}_emulateAnimation(e){pa(e,this._getElement(),this._config.isAnimated)}},$f="focustrap",Vf="bs.focustrap",tr=`.${Vf}`,zf=`focusin${tr}`,jf=`keydown.tab${tr}`,Wf="Tab",qf="forward",qs="backward",Uf={autofocus:!0,trapElement:null},Yf={autofocus:"boolean",trapElement:"element"},nr=class extends Qt{constructor(e){super(),this._config=this._getConfig(e),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return Uf}static get DefaultType(){return Yf}static get NAME(){return $f}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),x.off(document,tr),x.on(document,zf,e=>this._handleFocusin(e)),x.on(document,jf,e=>this._handleKeydown(e)),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,x.off(document,tr))}_handleFocusin(e){let{trapElement:t}=this._config;if(e.target===document||e.target===t||t.contains(e.target))return;let i=j.focusableChildren(t);i.length===0?t.focus():this._lastTabNavDirection===qs?i[i.length-1].focus():i[0].focus()}_handleKeydown(e){e.key===Wf&&(this._lastTabNavDirection=e.shiftKey?qs:qf)}},Us=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",Ys=".sticky-top",Wi="padding-right",Gs="margin-right",ni=class{constructor(){this._element=document.body}getWidth(){let e=document.documentElement.clientWidth;return Math.abs(window.innerWidth-e)}hide(){let e=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,Wi,t=>t+e),this._setElementAttributes(Us,Wi,t=>t+e),this._setElementAttributes(Ys,Gs,t=>t-e)}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,Wi),this._resetElementAttributes(Us,Wi),this._resetElementAttributes(Ys,Gs)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(e,t,i){let r=this.getWidth(),o=s=>{if(s!==this._element&&window.innerWidth>s.clientWidth+r)return;this._saveInitialAttribute(s,t);let a=window.getComputedStyle(s).getPropertyValue(t);s.style.setProperty(t,`${i(Number.parseFloat(a))}px`)};this._applyManipulationCallback(e,o)}_saveInitialAttribute(e,t){let i=e.style.getPropertyValue(t);i&&ft.setDataAttribute(e,t,i)}_resetElementAttributes(e,t){let i=r=>{let o=ft.getDataAttribute(r,t);if(o===null){r.style.removeProperty(t);return}ft.removeDataAttribute(r,t),r.style.setProperty(t,o)};this._applyManipulationCallback(e,i)}_applyManipulationCallback(e,t){if(dt(e)){t(e);return}for(let i of j.find(e,this._element))t(i)}},Gf="modal",Kf="bs.modal",Xe=`.${Kf}`,Xf=".data-api",Qf="Escape",Jf=`hide${Xe}`,Zf=`hidePrevented${Xe}`,Oa=`hidden${Xe}`,La=`show${Xe}`,eh=`shown${Xe}`,th=`resize${Xe}`,nh=`click.dismiss${Xe}`,ih=`mousedown.dismiss${Xe}`,rh=`keydown.dismiss${Xe}`,oh=`click${Xe}${Xf}`,Ks="modal-open",sh="fade",Xs="show",mo="modal-static",ah=".modal.show",lh=".modal-dialog",ch=".modal-body",uh='[data-bs-toggle="modal"]',dh={backdrop:!0,focus:!0,keyboard:!0},fh={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"},tt=class n extends je{constructor(e,t){super(e,t),this._dialog=j.findOne(lh,this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new ni,this._addEventListeners()}static get Default(){return dh}static get DefaultType(){return fh}static get NAME(){return Gf}toggle(e){return this._isShown?this.hide():this.show(e)}show(e){this._isShown||this._isTransitioning||x.trigger(this._element,La,{relatedTarget:e}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(Ks),this._adjustDialog(),this._backdrop.show(()=>this._showElement(e)))}hide(){!this._isShown||this._isTransitioning||x.trigger(this._element,Jf).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(Xs),this._queueCallback(()=>this._hideModal(),this._element,this._isAnimated()))}dispose(){x.off(window,Xe),x.off(this._dialog,Xe),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new er({isVisible:!!this._config.backdrop,isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new nr({trapElement:this._element})}_showElement(e){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;let t=j.findOne(ch,this._dialog);t&&(t.scrollTop=0),ii(this._element),this._element.classList.add(Xs);let i=()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,x.trigger(this._element,eh,{relatedTarget:e})};this._queueCallback(i,this._dialog,this._isAnimated())}_addEventListeners(){x.on(this._element,rh,e=>{if(e.key===Qf){if(this._config.keyboard){this.hide();return}this._triggerBackdropTransition()}}),x.on(window,th,()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()}),x.on(this._element,ih,e=>{x.one(this._element,nh,t=>{if(!(this._element!==e.target||this._element!==t.target)){if(this._config.backdrop==="static"){this._triggerBackdropTransition();return}this._config.backdrop&&this.hide()}})})}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide(()=>{document.body.classList.remove(Ks),this._resetAdjustments(),this._scrollBar.reset(),x.trigger(this._element,Oa)})}_isAnimated(){return this._element.classList.contains(sh)}_triggerBackdropTransition(){if(x.trigger(this._element,Zf).defaultPrevented)return;let t=this._element.scrollHeight>document.documentElement.clientHeight,i=this._element.style.overflowY;i==="hidden"||this._element.classList.contains(mo)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(mo),this._queueCallback(()=>{this._element.classList.remove(mo),this._queueCallback(()=>{this._element.style.overflowY=i},this._dialog)},this._dialog),this._element.focus())}_adjustDialog(){let e=this._element.scrollHeight>document.documentElement.clientHeight,t=this._scrollBar.getWidth(),i=t>0;if(i&&!e){let r=Ke()?"paddingLeft":"paddingRight";this._element.style[r]=`${t}px`}if(!i&&e){let r=Ke()?"paddingRight":"paddingLeft";this._element.style[r]=`${t}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(e,t){return this.each(function(){let i=n.getOrCreateInstance(this,e);if(typeof e=="string"){if(typeof i[e]=="undefined")throw new TypeError(`No method named "${e}"`);i[e](t)}})}};x.on(document,oh,uh,function(n){let e=j.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&n.preventDefault(),x.one(e,La,r=>{r.defaultPrevented||x.one(e,Oa,()=>{An(this)&&this.focus()})});let t=j.findOne(ah);t&&tt.getInstance(t).hide(),tt.getOrCreateInstance(e).toggle(this)});rr(tt);Qe(tt);var hh="offcanvas",ph="bs.offcanvas",mt=`.${ph}`,Ma=".data-api",mh=`load${mt}${Ma}`,gh="Escape",Qs="show",Js="showing",Zs="hiding",vh="offcanvas-backdrop",ka=".offcanvas.show",yh=`show${mt}`,Eh=`shown${mt}`,bh=`hide${mt}`,ea=`hidePrevented${mt}`,Na=`hidden${mt}`,_h=`resize${mt}`,wh=`click${mt}${Ma}`,xh=`keydown.dismiss${mt}`,Th='[data-bs-toggle="offcanvas"]',Ch={backdrop:!0,keyboard:!0,scroll:!1},Ah={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"},Dt=class n extends je{constructor(e,t){super(e,t),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return Ch}static get DefaultType(){return Ah}static get NAME(){return hh}toggle(e){return this._isShown?this.hide():this.show(e)}show(e){if(this._isShown||x.trigger(this._element,yh,{relatedTarget:e}).defaultPrevented)return;this._isShown=!0,this._backdrop.show(),this._config.scroll||new ni().hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Js);let i=()=>{(!this._config.scroll||this._config.backdrop)&&this._focustrap.activate(),this._element.classList.add(Qs),this._element.classList.remove(Js),x.trigger(this._element,Eh,{relatedTarget:e})};this._queueCallback(i,this._element,!0)}hide(){if(!this._isShown||x.trigger(this._element,bh).defaultPrevented)return;this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(Zs),this._backdrop.hide();let t=()=>{this._element.classList.remove(Qs,Zs),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||new ni().reset(),x.trigger(this._element,Na)};this._queueCallback(t,this._element,!0)}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){let e=()=>{if(this._config.backdrop==="static"){x.trigger(this._element,ea);return}this.hide()},t=!!this._config.backdrop;return new er({className:vh,isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?e:null})}_initializeFocusTrap(){return new nr({trapElement:this._element})}_addEventListeners(){x.on(this._element,xh,e=>{if(e.key===gh){if(this._config.keyboard){this.hide();return}x.trigger(this._element,ea)}})}static jQueryInterface(e){return this.each(function(){let t=n.getOrCreateInstance(this,e);if(typeof e=="string"){if(t[e]===void 0||e.startsWith("_")||e==="constructor")throw new TypeError(`No method named "${e}"`);t[e](this)}})}};x.on(document,wh,Th,function(n){let e=j.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&n.preventDefault(),Ct(this))return;x.one(e,Na,()=>{An(this)&&this.focus()});let t=j.findOne(ka);t&&t!==e&&Dt.getInstance(t).hide(),Dt.getOrCreateInstance(e).toggle(this)});x.on(window,mh,()=>{for(let n of j.find(ka))Dt.getOrCreateInstance(n).show()});x.on(window,_h,()=>{for(let n of j.find("[aria-modal][class*=show][class*=offcanvas-]"))getComputedStyle(n).position!=="fixed"&&Dt.getOrCreateInstance(n).hide()});rr(Dt);Qe(Dt);var Sh=/^aria-[\w-]*$/i,Ia={"*":["class","dir","id","lang","role",Sh],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],dd:[],div:[],dl:[],dt:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Dh=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Oh=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Lh=(n,e)=>{let t=n.nodeName.toLowerCase();return e.includes(t)?Dh.has(t)?!!Oh.test(n.nodeValue):!0:e.filter(i=>i instanceof RegExp).some(i=>i.test(t))};function Mh(n,e,t){if(!n.length)return n;if(t&&typeof t=="function")return t(n);let r=new window.DOMParser().parseFromString(n,"text/html"),o=[].concat(...r.body.querySelectorAll("*"));for(let s of o){let a=s.nodeName.toLowerCase();if(!Object.keys(e).includes(a)){s.remove();continue}let l=[].concat(...s.attributes),c=[].concat(e["*"]||[],e[a]||[]);for(let u of l)Lh(u,c)||s.removeAttribute(u.nodeName)}return r.body.innerHTML}var kh="TemplateFactory",Nh={allowList:Ia,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Ih={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Rh={entry:"(string|element|function|null)",selector:"(string|element)"},So=class extends Qt{constructor(e){super(),this._config=this._getConfig(e)}static get Default(){return Nh}static get DefaultType(){return Ih}static get NAME(){return kh}getContent(){return Object.values(this._config.content).map(e=>this._resolvePossibleFunction(e)).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(e){return this._checkContent(e),this._config.content=O(O({},this._config.content),e),this}toHtml(){let e=document.createElement("div");e.innerHTML=this._maybeSanitize(this._config.template);for(let[r,o]of Object.entries(this._config.content))this._setContent(e,o,r);let t=e.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&t.classList.add(...i.split(" ")),t}_typeCheckConfig(e){super._typeCheckConfig(e),this._checkContent(e.content)}_checkContent(e){for(let[t,i]of Object.entries(e))super._typeCheckConfig({selector:t,entry:i},Rh)}_setContent(e,t,i){let r=j.findOne(i,e);if(r){if(t=this._resolvePossibleFunction(t),!t){r.remove();return}if(dt(t)){this._putElementInTemplate(Tt(t),r);return}if(this._config.html){r.innerHTML=this._maybeSanitize(t);return}r.textContent=t}}_maybeSanitize(e){return this._config.sanitize?Mh(e,this._config.allowList,this._config.sanitizeFn):e}_resolvePossibleFunction(e){return He(e,[void 0,this])}_putElementInTemplate(e,t){if(this._config.html){t.innerHTML="",t.append(e);return}t.textContent=e.textContent}},Hh="tooltip",Ph=new Set(["sanitize","allowList","sanitizeFn"]),go="fade",Fh="modal",qi="show",Bh=".tooltip-inner",ta=`.${Fh}`,na="hide.bs.modal",ei="hover",vo="focus",yo="click",$h="manual",Vh="hide",zh="hidden",jh="show",Wh="shown",qh="inserted",Uh="click",Yh="focusin",Gh="focusout",Kh="mouseenter",Xh="mouseleave",Qh={AUTO:"auto",TOP:"top",RIGHT:Ke()?"left":"right",BOTTOM:"bottom",LEFT:Ke()?"right":"left"},Jh={allowList:Ia,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},Zh={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"},ht=class n extends je{constructor(e,t){if(typeof Vi=="undefined")throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org/docs/v2/)");super(e,t),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return Jh}static get DefaultType(){return Zh}static get NAME(){return Hh}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){if(this._isEnabled){if(this._isShown()){this._leave();return}this._enter()}}dispose(){clearTimeout(this._timeout),x.off(this._element.closest(ta),na,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if(this._element.style.display==="none")throw new Error("Please use show on visible elements");if(!(this._isWithContent()&&this._isEnabled))return;let e=x.trigger(this._element,this.constructor.eventName(jh)),i=(fa(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(e.defaultPrevented||!i)return;this._disposePopper();let r=this._getTipElement();this._element.setAttribute("aria-describedby",r.getAttribute("id"));let{container:o}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(o.append(r),x.trigger(this._element,this.constructor.eventName(qh))),this._popper=this._createPopper(r),r.classList.add(qi),"ontouchstart"in document.documentElement)for(let a of[].concat(...document.body.children))x.on(a,"mouseover",Xi);let s=()=>{x.trigger(this._element,this.constructor.eventName(Wh)),this._isHovered===!1&&this._leave(),this._isHovered=!1};this._queueCallback(s,this.tip,this._isAnimated())}hide(){if(!this._isShown()||x.trigger(this._element,this.constructor.eventName(Vh)).defaultPrevented)return;if(this._getTipElement().classList.remove(qi),"ontouchstart"in document.documentElement)for(let r of[].concat(...document.body.children))x.off(r,"mouseover",Xi);this._activeTrigger[yo]=!1,this._activeTrigger[vo]=!1,this._activeTrigger[ei]=!1,this._isHovered=null;let i=()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),x.trigger(this._element,this.constructor.eventName(zh)))};this._queueCallback(i,this.tip,this._isAnimated())}update(){this._popper&&this._popper.update()}_isWithContent(){return!!this._getTitle()}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(e){let t=this._getTemplateFactory(e).toHtml();if(!t)return null;t.classList.remove(go,qi),t.classList.add(`bs-${this.constructor.NAME}-auto`);let i=$u(this.constructor.NAME).toString();return t.setAttribute("id",i),this._isAnimated()&&t.classList.add(go),t}setContent(e){this._newContent=e,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(e){return this._templateFactory?this._templateFactory.changeContent(e):this._templateFactory=new So(ae(O({},this._config),{content:e,extraClass:this._resolvePossibleFunction(this._config.customClass)})),this._templateFactory}_getContentForTemplate(){return{[Bh]:this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(e){return this.constructor.getOrCreateInstance(e.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(go)}_isShown(){return this.tip&&this.tip.classList.contains(qi)}_createPopper(e){let t=He(this._config.placement,[this,e,this._element]),i=Qh[t.toUpperCase()];return Jn(this._element,e,this._getPopperConfig(i))}_getOffset(){let{offset:e}=this._config;return typeof e=="string"?e.split(",").map(t=>Number.parseInt(t,10)):typeof e=="function"?t=>e(t,this._element):e}_resolvePossibleFunction(e){return He(e,[this._element,this._element])}_getPopperConfig(e){let t={placement:e,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:i=>{this._getTipElement().setAttribute("data-popper-placement",i.state.placement)}}]};return O(O({},t),He(this._config.popperConfig,[void 0,t]))}_setListeners(){let e=this._config.trigger.split(" ");for(let t of e)if(t==="click")x.on(this._element,this.constructor.eventName(Uh),this._config.selector,i=>{let r=this._initializeOnDelegatedTarget(i);r._activeTrigger[yo]=!(r._isShown()&&r._activeTrigger[yo]),r.toggle()});else if(t!==$h){let i=t===ei?this.constructor.eventName(Kh):this.constructor.eventName(Yh),r=t===ei?this.constructor.eventName(Xh):this.constructor.eventName(Gh);x.on(this._element,i,this._config.selector,o=>{let s=this._initializeOnDelegatedTarget(o);s._activeTrigger[o.type==="focusin"?vo:ei]=!0,s._enter()}),x.on(this._element,r,this._config.selector,o=>{let s=this._initializeOnDelegatedTarget(o);s._activeTrigger[o.type==="focusout"?vo:ei]=s._element.contains(o.relatedTarget),s._leave()})}this._hideModalHandler=()=>{this._element&&this.hide()},x.on(this._element.closest(ta),na,this._hideModalHandler)}_fixTitle(){let e=this._element.getAttribute("title");e&&(!this._element.getAttribute("aria-label")&&!this._element.textContent.trim()&&this._element.setAttribute("aria-label",e),this._element.setAttribute("data-bs-original-title",e),this._element.removeAttribute("title"))}_enter(){if(this._isShown()||this._isHovered){this._isHovered=!0;return}this._isHovered=!0,this._setTimeout(()=>{this._isHovered&&this.show()},this._config.delay.show)}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout(()=>{this._isHovered||this.hide()},this._config.delay.hide))}_setTimeout(e,t){clearTimeout(this._timeout),this._timeout=setTimeout(e,t)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(e){let t=ft.getDataAttributes(this._element);for(let i of Object.keys(t))Ph.has(i)&&delete t[i];return e=O(O({},t),typeof e=="object"&&e?e:{}),e=this._mergeConfigObj(e),e=this._configAfterMerge(e),this._typeCheckConfig(e),e}_configAfterMerge(e){return e.container=e.container===!1?document.body:Tt(e.container),typeof e.delay=="number"&&(e.delay={show:e.delay,hide:e.delay}),typeof e.title=="number"&&(e.title=e.title.toString()),typeof e.content=="number"&&(e.content=e.content.toString()),e}_getDelegateConfig(){let e={};for(let[t,i]of Object.entries(this._config))this.constructor.Default[t]!==i&&(e[t]=i);return e.selector=!1,e.trigger="manual",e}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(e){return this.each(function(){let t=n.getOrCreateInstance(this,e);if(typeof e=="string"){if(typeof t[e]=="undefined")throw new TypeError(`No method named "${e}"`);t[e]()}})}};Qe(ht);var ep="popover",tp=".popover-header",np=".popover-body",ip=ae(O({},ht.Default),{content:"",offset:[0,8],placement:"right",template:'',trigger:"click"}),rp=ae(O({},ht.DefaultType),{content:"(null|string|element|function)"}),Cn=class n extends ht{static get Default(){return ip}static get DefaultType(){return rp}static get NAME(){return ep}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{[tp]:this._getTitle(),[np]:this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(e){return this.each(function(){let t=n.getOrCreateInstance(this,e);if(typeof e=="string"){if(typeof t[e]=="undefined")throw new TypeError(`No method named "${e}"`);t[e]()}})}};Qe(Cn);var op="scrollspy",sp="bs.scrollspy",Mo=`.${sp}`,ap=".data-api",lp=`activate${Mo}`,ia=`click${Mo}`,cp=`load${Mo}${ap}`,up="dropdown-item",_n="active",dp='[data-bs-spy="scroll"]',Eo="[href]",fp=".nav, .list-group",ra=".nav-link",hp=".nav-item",pp=".list-group-item",mp=`${ra}, ${hp} > ${ra}, ${pp}`,gp=".dropdown",vp=".dropdown-toggle",yp={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},Ep={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"},ir=class n extends je{constructor(e,t){super(e,t),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement=getComputedStyle(this._element).overflowY==="visible"?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return yp}static get DefaultType(){return Ep}static get NAME(){return op}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(let e of this._observableSections.values())this._observer.observe(e)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(e){return e.target=Tt(e.target)||document.body,e.rootMargin=e.offset?`${e.offset}px 0px -30%`:e.rootMargin,typeof e.threshold=="string"&&(e.threshold=e.threshold.split(",").map(t=>Number.parseFloat(t))),e}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(x.off(this._config.target,ia),x.on(this._config.target,ia,Eo,e=>{let t=this._observableSections.get(e.target.hash);if(t){e.preventDefault();let i=this._rootElement||window,r=t.offsetTop-this._element.offsetTop;if(i.scrollTo){i.scrollTo({top:r,behavior:"smooth"});return}i.scrollTop=r}}))}_getNewObserver(){let e={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver(t=>this._observerCallback(t),e)}_observerCallback(e){let t=s=>this._targetLinks.get(`#${s.target.id}`),i=s=>{this._previousScrollData.visibleEntryTop=s.target.offsetTop,this._process(t(s))},r=(this._rootElement||document.documentElement).scrollTop,o=r>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=r;for(let s of e){if(!s.isIntersecting){this._activeTarget=null,this._clearActiveClass(t(s));continue}let a=s.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(o&&a){if(i(s),!r)return;continue}!o&&!a&&i(s)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;let e=j.find(Eo,this._config.target);for(let t of e){if(!t.hash||Ct(t))continue;let i=j.findOne(decodeURI(t.hash),this._element);An(i)&&(this._targetLinks.set(decodeURI(t.hash),t),this._observableSections.set(t.hash,i))}}_process(e){this._activeTarget!==e&&(this._clearActiveClass(this._config.target),this._activeTarget=e,e.classList.add(_n),this._activateParents(e),x.trigger(this._element,lp,{relatedTarget:e}))}_activateParents(e){if(e.classList.contains(up)){j.findOne(vp,e.closest(gp)).classList.add(_n);return}for(let t of j.parents(e,fp))for(let i of j.prev(t,mp))i.classList.add(_n)}_clearActiveClass(e){e.classList.remove(_n);let t=j.find(`${Eo}.${_n}`,e);for(let i of t)i.classList.remove(_n)}static jQueryInterface(e){return this.each(function(){let t=n.getOrCreateInstance(this,e);if(typeof e=="string"){if(t[e]===void 0||e.startsWith("_")||e==="constructor")throw new TypeError(`No method named "${e}"`);t[e]()}})}};x.on(window,cp,()=>{for(let n of j.find(dp))ir.getOrCreateInstance(n)});Qe(ir);var bp="tab",_p="bs.tab",en=`.${_p}`,wp=`hide${en}`,xp=`hidden${en}`,Tp=`show${en}`,Cp=`shown${en}`,Ap=`click${en}`,Sp=`keydown${en}`,Dp=`load${en}`,Op="ArrowLeft",oa="ArrowRight",Lp="ArrowUp",sa="ArrowDown",bo="Home",aa="End",Xt="active",la="fade",_o="show",Mp="dropdown",Ra=".dropdown-toggle",kp=".dropdown-menu",wo=`:not(${Ra})`,Np='.list-group, .nav, [role="tablist"]',Ip=".nav-item, .list-group-item",Rp=`.nav-link${wo}, .list-group-item${wo}, [role="tab"]${wo}`,Ha='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',xo=`${Rp}, ${Ha}`,Hp=`.${Xt}[data-bs-toggle="tab"], .${Xt}[data-bs-toggle="pill"], .${Xt}[data-bs-toggle="list"]`,Jt=class n extends je{constructor(e){super(e),this._parent=this._element.closest(Np),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),x.on(this._element,Sp,t=>this._keydown(t)))}static get NAME(){return bp}show(){let e=this._element;if(this._elemIsActive(e))return;let t=this._getActiveElem(),i=t?x.trigger(t,wp,{relatedTarget:e}):null;x.trigger(e,Tp,{relatedTarget:t}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(t,e),this._activate(e,t))}_activate(e,t){if(!e)return;e.classList.add(Xt),this._activate(j.getElementFromSelector(e));let i=()=>{if(e.getAttribute("role")!=="tab"){e.classList.add(_o);return}e.removeAttribute("tabindex"),e.setAttribute("aria-selected",!0),this._toggleDropDown(e,!0),x.trigger(e,Cp,{relatedTarget:t})};this._queueCallback(i,e,e.classList.contains(la))}_deactivate(e,t){if(!e)return;e.classList.remove(Xt),e.blur(),this._deactivate(j.getElementFromSelector(e));let i=()=>{if(e.getAttribute("role")!=="tab"){e.classList.remove(_o);return}e.setAttribute("aria-selected",!1),e.setAttribute("tabindex","-1"),this._toggleDropDown(e,!1),x.trigger(e,xp,{relatedTarget:t})};this._queueCallback(i,e,e.classList.contains(la))}_keydown(e){if(![Op,oa,Lp,sa,bo,aa].includes(e.key))return;e.stopPropagation(),e.preventDefault();let t=this._getChildren().filter(r=>!Ct(r)),i;if([bo,aa].includes(e.key))i=t[e.key===bo?0:t.length-1];else{let r=[oa,sa].includes(e.key);i=Do(t,e.target,r,!0)}i&&(i.focus({preventScroll:!0}),n.getOrCreateInstance(i).show())}_getChildren(){return j.find(xo,this._parent)}_getActiveElem(){return this._getChildren().find(e=>this._elemIsActive(e))||null}_setInitialAttributes(e,t){this._setAttributeIfNotExists(e,"role","tablist");for(let i of t)this._setInitialAttributesOnChild(i)}_setInitialAttributesOnChild(e){e=this._getInnerElement(e);let t=this._elemIsActive(e),i=this._getOuterElement(e);e.setAttribute("aria-selected",t),i!==e&&this._setAttributeIfNotExists(i,"role","presentation"),t||e.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(e,"role","tab"),this._setInitialAttributesOnTargetPanel(e)}_setInitialAttributesOnTargetPanel(e){let t=j.getElementFromSelector(e);t&&(this._setAttributeIfNotExists(t,"role","tabpanel"),e.id&&this._setAttributeIfNotExists(t,"aria-labelledby",`${e.id}`))}_toggleDropDown(e,t){let i=this._getOuterElement(e);if(!i.classList.contains(Mp))return;let r=(o,s)=>{let a=j.findOne(o,i);a&&a.classList.toggle(s,t)};r(Ra,Xt),r(kp,_o),i.setAttribute("aria-expanded",t)}_setAttributeIfNotExists(e,t,i){e.hasAttribute(t)||e.setAttribute(t,i)}_elemIsActive(e){return e.classList.contains(Xt)}_getInnerElement(e){return e.matches(xo)?e:j.findOne(xo,e)}_getOuterElement(e){return e.closest(Ip)||e}static jQueryInterface(e){return this.each(function(){let t=n.getOrCreateInstance(this);if(typeof e=="string"){if(t[e]===void 0||e.startsWith("_")||e==="constructor")throw new TypeError(`No method named "${e}"`);t[e]()}})}};x.on(document,Ap,Ha,function(n){["A","AREA"].includes(this.tagName)&&n.preventDefault(),!Ct(this)&&Jt.getOrCreateInstance(this).show()});x.on(window,Dp,()=>{for(let n of j.find(Hp))Jt.getOrCreateInstance(n)});Qe(Jt);var Pp="toast",Fp="bs.toast",Lt=`.${Fp}`,Bp=`mouseover${Lt}`,$p=`mouseout${Lt}`,Vp=`focusin${Lt}`,zp=`focusout${Lt}`,jp=`hide${Lt}`,Wp=`hidden${Lt}`,qp=`show${Lt}`,Up=`shown${Lt}`,Yp="fade",ca="hide",Ui="show",Yi="showing",Gp={animation:"boolean",autohide:"boolean",delay:"number"},Kp={animation:!0,autohide:!0,delay:5e3},pt=class n extends je{constructor(e,t){super(e,t),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return Kp}static get DefaultType(){return Gp}static get NAME(){return Pp}show(){if(x.trigger(this._element,qp).defaultPrevented)return;this._clearTimeout(),this._config.animation&&this._element.classList.add(Yp);let t=()=>{this._element.classList.remove(Yi),x.trigger(this._element,Up),this._maybeScheduleHide()};this._element.classList.remove(ca),ii(this._element),this._element.classList.add(Ui,Yi),this._queueCallback(t,this._element,this._config.animation)}hide(){if(!this.isShown()||x.trigger(this._element,jp).defaultPrevented)return;let t=()=>{this._element.classList.add(ca),this._element.classList.remove(Yi,Ui),x.trigger(this._element,Wp)};this._element.classList.add(Yi),this._queueCallback(t,this._element,this._config.animation)}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(Ui),super.dispose()}isShown(){return this._element.classList.contains(Ui)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout(()=>{this.hide()},this._config.delay)))}_onInteraction(e,t){switch(e.type){case"mouseover":case"mouseout":{this._hasMouseInteraction=t;break}case"focusin":case"focusout":{this._hasKeyboardInteraction=t;break}}if(t){this._clearTimeout();return}let i=e.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){x.on(this._element,Bp,e=>this._onInteraction(e,!0)),x.on(this._element,$p,e=>this._onInteraction(e,!1)),x.on(this._element,Vp,e=>this._onInteraction(e,!0)),x.on(this._element,zp,e=>this._onInteraction(e,!1))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(e){return this.each(function(){let t=n.getOrCreateInstance(this,e);if(typeof e=="string"){if(typeof t[e]=="undefined")throw new TypeError(`No method named "${e}"`);t[e](this)}})}};rr(pt);Qe(pt);var Xp=function(){"use strict";let htmx={onLoad:null,process:null,on:null,off:null,trigger:null,ajax:null,find:null,findAll:null,closest:null,values:function(n,e){return getInputValues(n,e||"post").values},remove:null,addClass:null,removeClass:null,toggleClass:null,takeClass:null,swap:null,defineExtension:null,removeExtension:null,logAll:null,logNone:null,logger:null,config:{historyEnabled:!0,historyCacheSize:10,refreshOnHistoryMiss:!1,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:20,includeIndicatorStyles:!0,indicatorClass:"htmx-indicator",requestClass:"htmx-request",addedClass:"htmx-added",settlingClass:"htmx-settling",swappingClass:"htmx-swapping",allowEval:!0,allowScriptTags:!0,inlineScriptNonce:"",inlineStyleNonce:"",attributesToSettle:["class","style","width","height"],withCredentials:!1,timeout:0,wsReconnectDelay:"full-jitter",wsBinaryType:"blob",disableSelector:"[hx-disable], [data-hx-disable]",scrollBehavior:"instant",defaultFocusScroll:!1,getCacheBusterParam:!1,globalViewTransitions:!1,methodsThatUseUrlParams:["get","delete"],selfRequestsOnly:!0,ignoreTitle:!1,scrollIntoViewOnBoost:!0,triggerSpecsCache:null,disableInheritance:!1,responseHandling:[{code:"204",swap:!1},{code:"[23]..",swap:!0},{code:"[45]..",swap:!1,error:!0}],allowNestedOobSwaps:!0,historyRestoreAsHxRequest:!0},parseInterval:null,location,_:null,version:"2.0.6"};htmx.onLoad=onLoadHelper,htmx.process=processNode,htmx.on=addEventListenerImpl,htmx.off=removeEventListenerImpl,htmx.trigger=triggerEvent,htmx.ajax=ajaxHelper,htmx.find=find,htmx.findAll=findAll,htmx.closest=closest,htmx.remove=removeElement,htmx.addClass=addClassToElement,htmx.removeClass=removeClassFromElement,htmx.toggleClass=toggleClassOnElement,htmx.takeClass=takeClassForElement,htmx.swap=swap,htmx.defineExtension=defineExtension,htmx.removeExtension=removeExtension,htmx.logAll=logAll,htmx.logNone=logNone,htmx.parseInterval=parseInterval,htmx._=internalEval;let internalAPI={addTriggerHandler,bodyContains,canAccessLocalStorage,findThisElement,filterValues,swap,hasAttribute,getAttributeValue,getClosestAttributeValue,getClosestMatch,getExpressionVars,getHeaders,getInputValues,getInternalData,getSwapSpecification,getTriggerSpecs,getTarget,makeFragment,mergeObjects,makeSettleInfo,oobSwap,querySelectorExt,settleImmediately,shouldCancel,triggerEvent,triggerErrorEvent,withExtensions},VERBS=["get","post","put","delete","patch"],VERB_SELECTOR=VERBS.map(function(n){return"[hx-"+n+"], [data-hx-"+n+"]"}).join(", ");function parseInterval(n){if(n==null)return;let e=NaN;return n.slice(-2)=="ms"?e=parseFloat(n.slice(0,-2)):n.slice(-1)=="s"?e=parseFloat(n.slice(0,-1))*1e3:n.slice(-1)=="m"?e=parseFloat(n.slice(0,-1))*1e3*60:e=parseFloat(n),isNaN(e)?void 0:e}function getRawAttribute(n,e){return n instanceof Element&&n.getAttribute(e)}function hasAttribute(n,e){return!!n.hasAttribute&&(n.hasAttribute(e)||n.hasAttribute("data-"+e))}function getAttributeValue(n,e){return getRawAttribute(n,e)||getRawAttribute(n,"data-"+e)}function parentElt(n){let e=n.parentElement;return!e&&n.parentNode instanceof ShadowRoot?n.parentNode:e}function getDocument(){return document}function getRootNode(n,e){return n.getRootNode?n.getRootNode({composed:e}):getDocument()}function getClosestMatch(n,e){for(;n&&!e(n);)n=parentElt(n);return n||null}function getAttributeValueWithDisinheritance(n,e,t){let i=getAttributeValue(e,t),r=getAttributeValue(e,"hx-disinherit");var o=getAttributeValue(e,"hx-inherit");if(n!==e){if(htmx.config.disableInheritance)return o&&(o==="*"||o.split(" ").indexOf(t)>=0)?i:null;if(r&&(r==="*"||r.split(" ").indexOf(t)>=0))return"unset"}return i}function getClosestAttributeValue(n,e){let t=null;if(getClosestMatch(n,function(i){return!!(t=getAttributeValueWithDisinheritance(n,asElement(i),e))}),t!=="unset")return t}function matches(n,e){return n instanceof Element&&n.matches(e)}function getStartTag(n){let t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i.exec(n);return t?t[1].toLowerCase():""}function parseHTML(n){return new DOMParser().parseFromString(n,"text/html")}function takeChildrenFor(n,e){for(;e.childNodes.length>0;)n.append(e.childNodes[0])}function duplicateScript(n){let e=getDocument().createElement("script");return forEach(n.attributes,function(t){e.setAttribute(t.name,t.value)}),e.textContent=n.textContent,e.async=!1,htmx.config.inlineScriptNonce&&(e.nonce=htmx.config.inlineScriptNonce),e}function isJavaScriptScriptNode(n){return n.matches("script")&&(n.type==="text/javascript"||n.type==="module"||n.type==="")}function normalizeScriptTags(n){Array.from(n.querySelectorAll("script")).forEach(e=>{if(isJavaScriptScriptNode(e)){let t=duplicateScript(e),i=e.parentNode;try{i.insertBefore(t,e)}catch(r){logError(r)}finally{e.remove()}}})}function makeFragment(n){let e=n.replace(/]*)?>[\s\S]*?<\/head>/i,""),t=getStartTag(e),i;if(t==="html"){i=new DocumentFragment;let o=parseHTML(n);takeChildrenFor(i,o.body),i.title=o.title}else if(t==="body"){i=new DocumentFragment;let o=parseHTML(e);takeChildrenFor(i,o.body),i.title=o.title}else{let o=parseHTML('");i=o.querySelector("template").content,i.title=o.title;var r=i.querySelector("title");r&&r.parentNode===i&&(r.remove(),i.title=r.innerText)}return i&&(htmx.config.allowScriptTags?normalizeScriptTags(i):i.querySelectorAll("script").forEach(o=>o.remove())),i}function maybeCall(n){n&&n()}function isType(n,e){return Object.prototype.toString.call(n)==="[object "+e+"]"}function isFunction(n){return typeof n=="function"}function isRawObject(n){return isType(n,"Object")}function getInternalData(n){let e="htmx-internal-data",t=n[e];return t||(t=n[e]={}),t}function toArray(n){let e=[];if(n)for(let t=0;t=0}function bodyContains(n){return n.getRootNode({composed:!0})===document}function splitOnWhitespace(n){return n.trim().split(/\s+/)}function mergeObjects(n,e){for(let t in e)e.hasOwnProperty(t)&&(n[t]=e[t]);return n}function parseJSON(n){try{return JSON.parse(n)}catch(e){return logError(e),null}}function canAccessLocalStorage(){let n="htmx:sessionStorageTest";try{return sessionStorage.setItem(n,n),sessionStorage.removeItem(n),!0}catch(e){return!1}}function normalizePath(n){let e=new URL(n,"http://x");return e&&(n=e.pathname+e.search),n!="/"&&(n=n.replace(/\/+$/,"")),n}function internalEval(str){return maybeEval(getDocument().body,function(){return eval(str)})}function onLoadHelper(n){return htmx.on("htmx:load",function(t){n(t.detail.elt)})}function logAll(){htmx.logger=function(n,e,t){console&&console.log(e,n,t)}}function logNone(){htmx.logger=null}function find(n,e){return typeof n!="string"?n.querySelector(e):find(getDocument(),n)}function findAll(n,e){return typeof n!="string"?n.querySelectorAll(e):findAll(getDocument(),n)}function getWindow(){return window}function removeElement(n,e){n=resolveTarget(n),e?getWindow().setTimeout(function(){removeElement(n),n=null},e):parentElt(n).removeChild(n)}function asElement(n){return n instanceof Element?n:null}function asHtmlElement(n){return n instanceof HTMLElement?n:null}function asString(n){return typeof n=="string"?n:null}function asParentNode(n){return n instanceof Element||n instanceof Document||n instanceof DocumentFragment?n:null}function addClassToElement(n,e,t){n=asElement(resolveTarget(n)),n&&(t?getWindow().setTimeout(function(){addClassToElement(n,e),n=null},t):n.classList&&n.classList.add(e))}function removeClassFromElement(n,e,t){let i=asElement(resolveTarget(n));i&&(t?getWindow().setTimeout(function(){removeClassFromElement(i,e),i=null},t):i.classList&&(i.classList.remove(e),i.classList.length===0&&i.removeAttribute("class")))}function toggleClassOnElement(n,e){n=resolveTarget(n),n.classList.toggle(e)}function takeClassForElement(n,e){n=resolveTarget(n),forEach(n.parentElement.children,function(t){removeClassFromElement(t,e)}),addClassToElement(asElement(n),e)}function closest(n,e){return n=asElement(resolveTarget(n)),n?n.closest(e):null}function startsWith(n,e){return n.substring(0,e.length)===e}function endsWith(n,e){return n.substring(n.length-e.length)===e}function normalizeSelector(n){let e=n.trim();return startsWith(e,"<")&&endsWith(e,"/>")?e.substring(1,e.length-2):e}function querySelectorAllExt(n,e,t){if(e.indexOf("global ")===0)return querySelectorAllExt(n,e.slice(7),!0);n=resolveTarget(n);let i=[];{let s=0,a=0;for(let l=0;l"&&s--}a0;){let s=normalizeSelector(i.shift()),a;s.indexOf("closest ")===0?a=closest(asElement(n),normalizeSelector(s.slice(8))):s.indexOf("find ")===0?a=find(asParentNode(n),normalizeSelector(s.slice(5))):s==="next"||s==="nextElementSibling"?a=asElement(n).nextElementSibling:s.indexOf("next ")===0?a=scanForwardQuery(n,normalizeSelector(s.slice(5)),!!t):s==="previous"||s==="previousElementSibling"?a=asElement(n).previousElementSibling:s.indexOf("previous ")===0?a=scanBackwardsQuery(n,normalizeSelector(s.slice(9)),!!t):s==="document"?a=document:s==="window"?a=window:s==="body"?a=document.body:s==="root"?a=getRootNode(n,!!t):s==="host"?a=n.getRootNode().host:o.push(s),a&&r.push(a)}if(o.length>0){let s=o.join(","),a=asParentNode(getRootNode(n,!!t));r.push(...toArray(a.querySelectorAll(s)))}return r}var scanForwardQuery=function(n,e,t){let i=asParentNode(getRootNode(n,t)).querySelectorAll(e);for(let r=0;r=0;r--){let o=i[r];if(o.compareDocumentPosition(n)===Node.DOCUMENT_POSITION_FOLLOWING)return o}};function querySelectorExt(n,e){return typeof n!="string"?querySelectorAllExt(n,e)[0]:querySelectorAllExt(getDocument().body,n)[0]}function resolveTarget(n,e){return typeof n=="string"?find(asParentNode(e)||document,n):n}function processEventArgs(n,e,t,i){return isFunction(e)?{target:getDocument().body,event:asString(n),listener:e,options:t}:{target:resolveTarget(n),event:asString(e),listener:t,options:i}}function addEventListenerImpl(n,e,t,i){return ready(function(){let o=processEventArgs(n,e,t,i);o.target.addEventListener(o.event,o.listener,o.options)}),isFunction(e)?e:t}function removeEventListenerImpl(n,e,t){return ready(function(){let i=processEventArgs(n,e,t);i.target.removeEventListener(i.event,i.listener)}),isFunction(e)?e:t}let DUMMY_ELT=getDocument().createElement("output");function findAttributeTargets(n,e){let t=getClosestAttributeValue(n,e);if(t){if(t==="this")return[findThisElement(n,e)];{let i=querySelectorAllExt(n,t);if(/(^|,)(\s*)inherit(\s*)($|,)/.test(t)){let o=asElement(getClosestMatch(n,function(s){return s!==n&&hasAttribute(asElement(s),e)}));o&&i.push(...findAttributeTargets(o,e))}return i.length===0?(logError('The selector "'+t+'" on '+e+" returned no matches!"),[DUMMY_ELT]):i}}}function findThisElement(n,e){return asElement(getClosestMatch(n,function(t){return getAttributeValue(asElement(t),e)!=null}))}function getTarget(n){let e=getClosestAttributeValue(n,"hx-target");return e?e==="this"?findThisElement(n,"hx-target"):querySelectorExt(n,e):getInternalData(n).boosted?getDocument().body:n}function shouldSettleAttribute(n){return htmx.config.attributesToSettle.includes(n)}function cloneAttributes(n,e){forEach(n.attributes,function(t){!e.hasAttribute(t.name)&&shouldSettleAttribute(t.name)&&n.removeAttribute(t.name)}),forEach(e.attributes,function(t){shouldSettleAttribute(t.name)&&n.setAttribute(t.name,t.value)})}function isInlineSwap(n,e){let t=getExtensions(e);for(let i=0;i0?(o=n.substring(0,n.indexOf(":")),r=n.substring(n.indexOf(":")+1)):o=n),e.removeAttribute("hx-swap-oob"),e.removeAttribute("data-hx-swap-oob");let s=querySelectorAllExt(i,r,!1);return s.length?(forEach(s,function(a){let l,c=e.cloneNode(!0);l=getDocument().createDocumentFragment(),l.appendChild(c),isInlineSwap(o,a)||(l=asParentNode(c));let u={shouldSwap:!0,target:a,fragment:l};triggerEvent(a,"htmx:oobBeforeSwap",u)&&(a=u.target,u.shouldSwap&&(handlePreservedElements(l),swapWithStyle(o,a,a,l,t),restorePreservedElements()),forEach(t.elts,function(d){triggerEvent(d,"htmx:oobAfterSwap",u)}))}),e.parentNode.removeChild(e)):(e.parentNode.removeChild(e),triggerErrorEvent(getDocument().body,"htmx:oobErrorNoTarget",{content:e})),n}function restorePreservedElements(){let n=find("#--htmx-preserve-pantry--");if(n){for(let e of[...n.children]){let t=find("#"+e.id);t.parentNode.moveBefore(e,t),t.remove()}n.remove()}}function handlePreservedElements(n){forEach(findAll(n,"[hx-preserve], [data-hx-preserve]"),function(e){let t=getAttributeValue(e,"id"),i=getDocument().getElementById(t);if(i!=null)if(e.moveBefore){let r=find("#--htmx-preserve-pantry--");r==null&&(getDocument().body.insertAdjacentHTML("afterend","
"),r=find("#--htmx-preserve-pantry--")),r.moveBefore(i,null)}else e.parentNode.replaceChild(i,e)})}function handleAttributes(n,e,t){forEach(e.querySelectorAll("[id]"),function(i){let r=getRawAttribute(i,"id");if(r&&r.length>0){let o=r.replace("'","\\'"),s=i.tagName.replace(":","\\:"),a=asParentNode(n),l=a&&a.querySelector(s+"[id='"+o+"']");if(l&&l!==a){let c=i.cloneNode();cloneAttributes(i,l),t.tasks.push(function(){cloneAttributes(i,c)})}}})}function makeAjaxLoadTask(n){return function(){removeClassFromElement(n,htmx.config.addedClass),processNode(asElement(n)),processFocus(asParentNode(n)),triggerEvent(n,"htmx:load")}}function processFocus(n){let e="[autofocus]",t=asHtmlElement(matches(n,e)?n:n.querySelector(e));t!=null&&t.focus()}function insertNodesBefore(n,e,t,i){for(handleAttributes(n,t,i);t.childNodes.length>0;){let r=t.firstChild;addClassToElement(asElement(r),htmx.config.addedClass),n.insertBefore(r,e),r.nodeType!==Node.TEXT_NODE&&r.nodeType!==Node.COMMENT_NODE&&i.tasks.push(makeAjaxLoadTask(r))}}function stringHash(n,e){let t=0;for(;t0}function swap(n,e,t,i){i||(i={});let r=null,o=null,s=function(){maybeCall(i.beforeSwapCallback),n=resolveTarget(n);let c=i.contextElement?getRootNode(i.contextElement,!1):getDocument(),u=document.activeElement,d={};d={elt:u,start:u?u.selectionStart:null,end:u?u.selectionEnd:null};let p=makeSettleInfo(n);if(t.swapStyle==="textContent")n.textContent=e;else{let m=makeFragment(e);if(p.title=i.title||m.title,i.historyRequest&&(m=m.querySelector("[hx-history-elt],[data-hx-history-elt]")||m),i.selectOOB){let v=i.selectOOB.split(",");for(let w=0;w0?getWindow().setTimeout(y,t.settleDelay):y()},a=htmx.config.globalViewTransitions;t.hasOwnProperty("transition")&&(a=t.transition);let l=i.contextElement||getDocument();if(a&&triggerEvent(l,"htmx:beforeTransition",i.eventInfo)&&typeof Promise!="undefined"&&document.startViewTransition){let c=new Promise(function(d,p){r=d,o=p}),u=s;s=function(){document.startViewTransition(function(){return u(),c})}}try{t!=null&&t.swapDelay&&t.swapDelay>0?getWindow().setTimeout(s,t.swapDelay):s()}catch(c){throw triggerErrorEvent(l,"htmx:swapError",i.eventInfo),maybeCall(o),c}}function handleTriggerHeader(n,e,t){let i=n.getResponseHeader(e);if(i.indexOf("{")===0){let r=parseJSON(i);for(let o in r)if(r.hasOwnProperty(o)){let s=r[o];isRawObject(s)?t=s.target!==void 0?s.target:t:s={value:s},triggerEvent(t,o,s)}}else{let r=i.split(",");for(let o=0;o0;){let s=e[0];if(s==="]"){if(i--,i===0){o===null&&(r=r+"true"),e.shift(),r+=")})";try{let a=maybeEval(n,function(){return Function(r)()},function(){return!0});return a.source=r,a}catch(a){return triggerErrorEvent(getDocument().body,"htmx:syntax:error",{error:a,source:r}),null}}}else s==="["&&i++;isPossibleRelativeReference(s,o,t)?r+="(("+t+"."+s+") ? ("+t+"."+s+") : (window."+s+"))":r=r+s,o=e.shift()}}}function consumeUntil(n,e){let t="";for(;n.length>0&&!e.test(n[0]);)t+=n.shift();return t}function consumeCSSSelector(n){let e;return n.length>0&&COMBINED_SELECTOR_START.test(n[0])?(n.shift(),e=consumeUntil(n,COMBINED_SELECTOR_END).trim(),n.shift()):e=consumeUntil(n,WHITESPACE_OR_COMMA),e}let INPUT_SELECTOR="input, textarea, select";function parseAndCacheTrigger(n,e,t){let i=[],r=tokenizeString(e);do{consumeUntil(r,NOT_WHITESPACE);let a=r.length,l=consumeUntil(r,/[,\[\s]/);if(l!=="")if(l==="every"){let c={trigger:"every"};consumeUntil(r,NOT_WHITESPACE),c.pollInterval=parseInterval(consumeUntil(r,/[,\[\s]/)),consumeUntil(r,NOT_WHITESPACE);var o=maybeGenerateConditional(n,r,"event");o&&(c.eventFilter=o),i.push(c)}else{let c={trigger:l};var o=maybeGenerateConditional(n,r,"event");for(o&&(c.eventFilter=o),consumeUntil(r,NOT_WHITESPACE);r.length>0&&r[0]!==",";){let d=r.shift();if(d==="changed")c.changed=!0;else if(d==="once")c.once=!0;else if(d==="consume")c.consume=!0;else if(d==="delay"&&r[0]===":")r.shift(),c.delay=parseInterval(consumeUntil(r,WHITESPACE_OR_COMMA));else if(d==="from"&&r[0]===":"){if(r.shift(),COMBINED_SELECTOR_START.test(r[0]))var s=consumeCSSSelector(r);else{var s=consumeUntil(r,WHITESPACE_OR_COMMA);if(s==="closest"||s==="find"||s==="next"||s==="previous"){r.shift();let y=consumeCSSSelector(r);y.length>0&&(s+=" "+y)}}c.from=s}else d==="target"&&r[0]===":"?(r.shift(),c.target=consumeCSSSelector(r)):d==="throttle"&&r[0]===":"?(r.shift(),c.throttle=parseInterval(consumeUntil(r,WHITESPACE_OR_COMMA))):d==="queue"&&r[0]===":"?(r.shift(),c.queue=consumeUntil(r,WHITESPACE_OR_COMMA)):d==="root"&&r[0]===":"?(r.shift(),c[d]=consumeCSSSelector(r)):d==="threshold"&&r[0]===":"?(r.shift(),c[d]=consumeUntil(r,WHITESPACE_OR_COMMA)):triggerErrorEvent(n,"htmx:syntax:error",{token:r.shift()});consumeUntil(r,NOT_WHITESPACE)}i.push(c)}r.length===a&&triggerErrorEvent(n,"htmx:syntax:error",{token:r.shift()}),consumeUntil(r,NOT_WHITESPACE)}while(r[0]===","&&r.shift());return t&&(t[e]=i),i}function getTriggerSpecs(n){let e=getAttributeValue(n,"hx-trigger"),t=[];if(e){let i=htmx.config.triggerSpecsCache;t=i&&i[e]||parseAndCacheTrigger(n,e,i)}return t.length>0?t:matches(n,"form")?[{trigger:"submit"}]:matches(n,'input[type="button"], input[type="submit"]')?[{trigger:"click"}]:matches(n,INPUT_SELECTOR)?[{trigger:"change"}]:[{trigger:"click"}]}function cancelPolling(n){getInternalData(n).cancelled=!0}function processPolling(n,e,t){let i=getInternalData(n);i.timeout=getWindow().setTimeout(function(){bodyContains(n)&&i.cancelled!==!0&&(maybeFilterEvent(t,n,makeEvent("hx:poll:trigger",{triggerSpec:t,target:n}))||e(n),processPolling(n,e,t))},t.pollInterval)}function isLocalLink(n){return location.hostname===n.hostname&&getRawAttribute(n,"href")&&getRawAttribute(n,"href").indexOf("#")!==0}function eltIsDisabled(n){return closest(n,htmx.config.disableSelector)}function boostElement(n,e,t){if(n instanceof HTMLAnchorElement&&isLocalLink(n)&&(n.target===""||n.target==="_self")||n.tagName==="FORM"&&String(getRawAttribute(n,"method")).toLowerCase()!=="dialog"){e.boosted=!0;let i,r;if(n.tagName==="A")i="get",r=getRawAttribute(n,"href");else{let o=getRawAttribute(n,"method");i=o?o.toLowerCase():"get",r=getRawAttribute(n,"action"),(r==null||r==="")&&(r=location.href),i==="get"&&r.includes("?")&&(r=r.replace(/\?[^#]+/,""))}t.forEach(function(o){addEventListener(n,function(s,a){let l=asElement(s);if(eltIsDisabled(l)){cleanUpElement(l);return}issueAjaxRequest(i,r,l,a)},e,o,!0)})}}function shouldCancel(n,e){return!!((n.type==="submit"||n.type==="click")&&(e=asElement(n.target)||e,e.tagName==="FORM"||e.form&&e.type==="submit"||(e=e.closest("a"),e&&e.href&&(e.getAttribute("href")==="#"||e.getAttribute("href").indexOf("#")!==0))))}function ignoreBoostedAnchorCtrlClick(n,e){return getInternalData(n).boosted&&n instanceof HTMLAnchorElement&&e.type==="click"&&(e.ctrlKey||e.metaKey)}function maybeFilterEvent(n,e,t){let i=n.eventFilter;if(i)try{return i.call(e,t)!==!0}catch(r){let o=i.source;return triggerErrorEvent(getDocument().body,"htmx:eventFilter:error",{error:r,source:o}),!0}return!1}function addEventListener(n,e,t,i,r){let o=getInternalData(n),s;i.from?s=querySelectorAllExt(n,i.from):s=[n],i.changed&&("lastValue"in o||(o.lastValue=new WeakMap),s.forEach(function(a){o.lastValue.has(i)||o.lastValue.set(i,new WeakMap),o.lastValue.get(i).set(a,a.value)})),forEach(s,function(a){let l=function(c){if(!bodyContains(n)){a.removeEventListener(i.trigger,l);return}if(ignoreBoostedAnchorCtrlClick(n,c)||((r||shouldCancel(c,n))&&c.preventDefault(),maybeFilterEvent(i,n,c)))return;let u=getInternalData(c);if(u.triggerSpec=i,u.handledFor==null&&(u.handledFor=[]),u.handledFor.indexOf(n)<0){if(u.handledFor.push(n),i.consume&&c.stopPropagation(),i.target&&c.target&&!matches(asElement(c.target),i.target))return;if(i.once){if(o.triggeredOnce)return;o.triggeredOnce=!0}if(i.changed){let d=c.target,p=d.value,y=o.lastValue.get(i);if(y.has(d)&&y.get(d)===p)return;y.set(d,p)}if(o.delayed&&clearTimeout(o.delayed),o.throttle)return;i.throttle>0?o.throttle||(triggerEvent(n,"htmx:trigger"),e(n,c),o.throttle=getWindow().setTimeout(function(){o.throttle=null},i.throttle)):i.delay>0?o.delayed=getWindow().setTimeout(function(){triggerEvent(n,"htmx:trigger"),e(n,c)},i.delay):(triggerEvent(n,"htmx:trigger"),e(n,c))}};t.listenerInfos==null&&(t.listenerInfos=[]),t.listenerInfos.push({trigger:i.trigger,listener:l,on:a}),a.addEventListener(i.trigger,l)})}let windowIsScrolling=!1,scrollHandler=null;function initScrollHandler(){scrollHandler||(scrollHandler=function(){windowIsScrolling=!0},window.addEventListener("scroll",scrollHandler),window.addEventListener("resize",scrollHandler),setInterval(function(){windowIsScrolling&&(windowIsScrolling=!1,forEach(getDocument().querySelectorAll("[hx-trigger*='revealed'],[data-hx-trigger*='revealed']"),function(n){maybeReveal(n)}))},200))}function maybeReveal(n){!hasAttribute(n,"data-hx-revealed")&&isScrolledIntoView(n)&&(n.setAttribute("data-hx-revealed","true"),getInternalData(n).initHash?triggerEvent(n,"revealed"):n.addEventListener("htmx:afterProcessNode",function(){triggerEvent(n,"revealed")},{once:!0}))}function loadImmediately(n,e,t,i){let r=function(){t.loaded||(t.loaded=!0,triggerEvent(n,"htmx:trigger"),e(n))};i>0?getWindow().setTimeout(r,i):r()}function processVerbs(n,e,t){let i=!1;return forEach(VERBS,function(r){if(hasAttribute(n,"hx-"+r)){let o=getAttributeValue(n,"hx-"+r);i=!0,e.path=o,e.verb=r,t.forEach(function(s){addTriggerHandler(n,s,e,function(a,l){let c=asElement(a);if(eltIsDisabled(c)){cleanUpElement(c);return}issueAjaxRequest(r,o,c,l)})})}}),i}function addTriggerHandler(n,e,t,i){if(e.trigger==="revealed")initScrollHandler(),addEventListener(n,i,t,e),maybeReveal(asElement(n));else if(e.trigger==="intersect"){let r={};e.root&&(r.root=querySelectorExt(n,e.root)),e.threshold&&(r.threshold=parseFloat(e.threshold)),new IntersectionObserver(function(s){for(let a=0;a0?(t.polling=!0,processPolling(asElement(n),i,e)):addEventListener(n,i,t,e)}function shouldProcessHxOn(n){let e=asElement(n);if(!e)return!1;let t=e.attributes;for(let i=0;i", "+o).join(""))}else return[]}function maybeSetLastButtonClicked(n){let e=getTargetButton(n.target),t=getRelatedFormData(n);t&&(t.lastButtonClicked=e)}function maybeUnsetLastButtonClicked(n){let e=getRelatedFormData(n);e&&(e.lastButtonClicked=null)}function getTargetButton(n){return closest(asElement(n),"button, input[type='submit']")}function getRelatedForm(n){return n.form||closest(n,"form")}function getRelatedFormData(n){let e=getTargetButton(n.target);if(!e)return;let t=getRelatedForm(e);return getInternalData(t)}function initButtonTracking(n){n.addEventListener("click",maybeSetLastButtonClicked),n.addEventListener("focusin",maybeSetLastButtonClicked),n.addEventListener("focusout",maybeUnsetLastButtonClicked)}function addHxOnEventHandler(n,e,t){let i=getInternalData(n);Array.isArray(i.onHandlers)||(i.onHandlers=[]);let r,o=function(s){maybeEval(n,function(){eltIsDisabled(n)||(r||(r=new Function("event",t)),r.call(n,s))})};n.addEventListener(e,o),i.onHandlers.push({event:e,listener:o})}function processHxOnWildcard(n){deInitOnHandlers(n);for(let e=0;ehtmx.config.historyCacheSize;)o.shift();for(;o.length>0;)try{sessionStorage.setItem("htmx-history-cache",JSON.stringify(o));break}catch(a){triggerErrorEvent(getDocument().body,"htmx:historyCacheError",{cause:a,cache:o}),o.shift()}}function getCachedHistory(n){if(!canAccessLocalStorage())return null;n=normalizePath(n);let e=parseJSON(sessionStorage.getItem("htmx-history-cache"))||[];for(let t=0;t=200&&this.status<400?(i.response=this.response,triggerEvent(getDocument().body,"htmx:historyCacheMissLoad",i),swap(i.historyElt,i.response,t,{contextElement:i.historyElt,historyRequest:!0}),setCurrentPathForHistory(i.path),triggerEvent(getDocument().body,"htmx:historyRestore",{path:n,cacheMiss:!0,serverResponse:i.response})):triggerErrorEvent(getDocument().body,"htmx:historyCacheMissLoadError",i)},triggerEvent(getDocument().body,"htmx:historyCacheMiss",i)&&e.send()}function restoreHistory(n){saveCurrentPageToHistory(),n=n||location.pathname+location.search;let e=getCachedHistory(n);if(e){let t={swapStyle:"innerHTML",swapDelay:0,settleDelay:0,scroll:e.scroll},i={path:n,item:e,historyElt:getHistoryElement(),swapSpec:t};triggerEvent(getDocument().body,"htmx:historyCacheHit",i)&&(swap(i.historyElt,e.content,t,{contextElement:i.historyElt,title:e.title}),setCurrentPathForHistory(i.path),triggerEvent(getDocument().body,"htmx:historyRestore",i))}else htmx.config.refreshOnHistoryMiss?htmx.location.reload(!0):loadHistoryFromServer(n)}function addRequestIndicatorClasses(n){let e=findAttributeTargets(n,"hx-indicator");return e==null&&(e=[n]),forEach(e,function(t){let i=getInternalData(t);i.requestCount=(i.requestCount||0)+1,t.classList.add.call(t.classList,htmx.config.requestClass)}),e}function disableElements(n){let e=findAttributeTargets(n,"hx-disabled-elt");return e==null&&(e=[]),forEach(e,function(t){let i=getInternalData(t);i.requestCount=(i.requestCount||0)+1,t.setAttribute("disabled",""),t.setAttribute("data-disabled-by-htmx","")}),e}function removeRequestIndicators(n,e){forEach(n.concat(e),function(t){let i=getInternalData(t);i.requestCount=(i.requestCount||1)-1}),forEach(n,function(t){getInternalData(t).requestCount===0&&t.classList.remove.call(t.classList,htmx.config.requestClass)}),forEach(e,function(t){getInternalData(t).requestCount===0&&(t.removeAttribute("disabled"),t.removeAttribute("data-disabled-by-htmx"))})}function haveSeenNode(n,e){for(let t=0;te.indexOf(r)<0):i=i.filter(r=>r!==e),t.delete(n),forEach(i,r=>t.append(n,r))}}function getValueFromInput(n){return n instanceof HTMLSelectElement&&n.multiple?toArray(n.querySelectorAll("option:checked")).map(function(e){return e.value}):n instanceof HTMLInputElement&&n.files?toArray(n.files):n.value}function processInputValue(n,e,t,i,r){if(!(i==null||haveSeenNode(n,i))){if(n.push(i),shouldInclude(i)){let o=getRawAttribute(i,"name");addValueToFormData(o,getValueFromInput(i),e),r&&validateElement(i,t)}i instanceof HTMLFormElement&&(forEach(i.elements,function(o){n.indexOf(o)>=0?removeValueFromFormData(o.name,getValueFromInput(o),e):n.push(o),r&&validateElement(o,t)}),new FormData(i).forEach(function(o,s){o instanceof File&&o.name===""||addValueToFormData(s,o,e)}))}}function validateElement(n,e){let t=n;t.willValidate&&(triggerEvent(t,"htmx:validation:validate"),t.checkValidity()||(e.push({elt:t,message:t.validationMessage,validity:t.validity}),triggerEvent(t,"htmx:validation:failed",{message:t.validationMessage,validity:t.validity})))}function overrideFormData(n,e){for(let t of e.keys())n.delete(t);return e.forEach(function(t,i){n.append(i,t)}),n}function getInputValues(n,e){let t=[],i=new FormData,r=new FormData,o=[],s=getInternalData(n);s.lastButtonClicked&&!bodyContains(s.lastButtonClicked)&&(s.lastButtonClicked=null);let a=n instanceof HTMLFormElement&&n.noValidate!==!0||getAttributeValue(n,"hx-validate")==="true";if(s.lastButtonClicked&&(a=a&&s.lastButtonClicked.formNoValidate!==!0),e!=="get"&&processInputValue(t,r,o,getRelatedForm(n),a),processInputValue(t,i,o,n,a),s.lastButtonClicked||n.tagName==="BUTTON"||n.tagName==="INPUT"&&getRawAttribute(n,"type")==="submit"){let c=s.lastButtonClicked||n,u=getRawAttribute(c,"name");addValueToFormData(u,c.value,r)}let l=findAttributeTargets(n,"hx-include");return forEach(l,function(c){processInputValue(t,i,o,asElement(c),a),matches(c,"form")||forEach(asParentNode(c).querySelectorAll(INPUT_SELECTOR),function(u){processInputValue(t,i,o,u,a)})}),overrideFormData(i,r),{errors:o,formData:i,values:formDataProxy(i)}}function appendParam(n,e,t){n!==""&&(n+="&"),String(t)==="[object Object]"&&(t=JSON.stringify(t));let i=encodeURIComponent(t);return n+=encodeURIComponent(e)+"="+i,n}function urlEncode(n){n=formDataFromObject(n);let e="";return n.forEach(function(t,i){e=appendParam(e,i,t)}),e}function getHeaders(n,e,t){let i={"HX-Request":"true","HX-Trigger":getRawAttribute(n,"id"),"HX-Trigger-Name":getRawAttribute(n,"name"),"HX-Target":getAttributeValue(e,"id"),"HX-Current-URL":location.href};return getValuesForElement(n,"hx-headers",!1,i),t!==void 0&&(i["HX-Prompt"]=t),getInternalData(n).boosted&&(i["HX-Boosted"]="true"),i}function filterValues(n,e){let t=getClosestAttributeValue(e,"hx-params");if(t){if(t==="none")return new FormData;if(t==="*")return n;if(t.indexOf("not ")===0)return forEach(t.slice(4).split(","),function(i){i=i.trim(),n.delete(i)}),n;{let i=new FormData;return forEach(t.split(","),function(r){r=r.trim(),n.has(r)&&n.getAll(r).forEach(function(o){i.append(r,o)})}),i}}else return n}function isAnchorLink(n){return!!getRawAttribute(n,"href")&&getRawAttribute(n,"href").indexOf("#")>=0}function getSwapSpecification(n,e){let t=e||getClosestAttributeValue(n,"hx-swap"),i={swapStyle:getInternalData(n).boosted?"innerHTML":htmx.config.defaultSwapStyle,swapDelay:htmx.config.defaultSwapDelay,settleDelay:htmx.config.defaultSettleDelay};if(htmx.config.scrollIntoViewOnBoost&&getInternalData(n).boosted&&!isAnchorLink(n)&&(i.show="top"),t){let s=splitOnWhitespace(t);if(s.length>0)for(let a=0;a0?r.join(":"):null;i.scroll=u,i.scrollTarget=o}else if(l.indexOf("show:")===0){var r=l.slice(5).split(":");let d=r.pop();var o=r.length>0?r.join(":"):null;i.show=d,i.showTarget=o}else if(l.indexOf("focus-scroll:")===0){let c=l.slice(13);i.focusScroll=c=="true"}else a==0?i.swapStyle=l:logError("Unknown modifier in hx-swap: "+l)}}return i}function usesFormData(n){return getClosestAttributeValue(n,"hx-encoding")==="multipart/form-data"||matches(n,"form")&&getRawAttribute(n,"enctype")==="multipart/form-data"}function encodeParamsForBody(n,e,t){let i=null;return withExtensions(e,function(r){i==null&&(i=r.encodeParameters(n,t,e))}),i!=null?i:usesFormData(e)?overrideFormData(new FormData,formDataFromObject(t)):urlEncode(t)}function makeSettleInfo(n){return{tasks:[],elts:[n]}}function updateScrollState(n,e){let t=n[0],i=n[n.length-1];if(e.scroll){var r=null;e.scrollTarget&&(r=asElement(querySelectorExt(t,e.scrollTarget))),e.scroll==="top"&&(t||r)&&(r=r||t,r.scrollTop=0),e.scroll==="bottom"&&(i||r)&&(r=r||i,r.scrollTop=r.scrollHeight),typeof e.scroll=="number"&&getWindow().setTimeout(function(){window.scrollTo(0,e.scroll)},0)}if(e.show){var r=null;if(e.showTarget){let s=e.showTarget;e.showTarget==="window"&&(s="body"),r=asElement(querySelectorExt(t,s))}e.show==="top"&&(t||r)&&(r=r||t,r.scrollIntoView({block:"start",behavior:htmx.config.scrollBehavior})),e.show==="bottom"&&(i||r)&&(r=r||i,r.scrollIntoView({block:"end",behavior:htmx.config.scrollBehavior}))}}function getValuesForElement(n,e,t,i,r){if(i==null&&(i={}),n==null)return i;let o=getAttributeValue(n,e);if(o){let s=o.trim(),a=t;if(s==="unset")return null;s.indexOf("javascript:")===0?(s=s.slice(11),a=!0):s.indexOf("js:")===0&&(s=s.slice(3),a=!0),s.indexOf("{")!==0&&(s="{"+s+"}");let l;a?l=maybeEval(n,function(){return r?Function("event","return ("+s+")").call(n,r):Function("return ("+s+")").call(n)},{}):l=parseJSON(s);for(let c in l)l.hasOwnProperty(c)&&i[c]==null&&(i[c]=l[c])}return getValuesForElement(asElement(parentElt(n)),e,t,i,r)}function maybeEval(n,e,t){return htmx.config.allowEval?e():(triggerErrorEvent(n,"htmx:evalDisallowedError"),t)}function getHXVarsForElement(n,e,t){return getValuesForElement(n,"hx-vars",!0,t,e)}function getHXValsForElement(n,e,t){return getValuesForElement(n,"hx-vals",!1,t,e)}function getExpressionVars(n,e){return mergeObjects(getHXVarsForElement(n,e),getHXValsForElement(n,e))}function safelySetHeaderValue(n,e,t){if(t!==null)try{n.setRequestHeader(e,t)}catch(i){n.setRequestHeader(e,encodeURIComponent(t)),n.setRequestHeader(e+"-URI-AutoEncoded","true")}}function getPathFromResponse(n){if(n.responseURL)try{let e=new URL(n.responseURL);return e.pathname+e.search}catch(e){triggerErrorEvent(getDocument().body,"htmx:badResponseUrl",{url:n.responseURL})}}function hasHeader(n,e){return e.test(n.getAllResponseHeaders())}function ajaxHelper(n,e,t){if(n=n.toLowerCase(),t){if(t instanceof Element||typeof t=="string")return issueAjaxRequest(n,e,null,null,{targetOverride:resolveTarget(t)||DUMMY_ELT,returnPromise:!0});{let i=resolveTarget(t.target);return(t.target&&!i||t.source&&!i&&!resolveTarget(t.source))&&(i=DUMMY_ELT),issueAjaxRequest(n,e,resolveTarget(t.source),t.event,{handler:t.handler,headers:t.headers,values:t.values,targetOverride:i,swapOverride:t.swap,select:t.select,returnPromise:!0})}}else return issueAjaxRequest(n,e,null,null,{returnPromise:!0})}function hierarchyForElt(n){let e=[];for(;n;)e.push(n),n=n.parentElement;return e}function verifyPath(n,e,t){let i=new URL(e,location.protocol!=="about:"?location.href:window.origin),o=(location.protocol!=="about:"?location.origin:window.origin)===i.origin;return htmx.config.selfRequestsOnly&&!o?!1:triggerEvent(n,"htmx:validateUrl",mergeObjects({url:i,sameHost:o},t))}function formDataFromObject(n){if(n instanceof FormData)return n;let e=new FormData;for(let t in n)n.hasOwnProperty(t)&&(n[t]&&typeof n[t].forEach=="function"?n[t].forEach(function(i){e.append(t,i)}):typeof n[t]=="object"&&!(n[t]instanceof Blob)?e.append(t,JSON.stringify(n[t])):e.append(t,n[t]));return e}function formDataArrayProxy(n,e,t){return new Proxy(t,{get:function(i,r){return typeof r=="number"?i[r]:r==="length"?i.length:r==="push"?function(o){i.push(o),n.append(e,o)}:typeof i[r]=="function"?function(){i[r].apply(i,arguments),n.delete(e),i.forEach(function(o){n.append(e,o)})}:i[r]&&i[r].length===1?i[r][0]:i[r]},set:function(i,r,o){return i[r]=o,n.delete(e),i.forEach(function(s){n.append(e,s)}),!0}})}function formDataProxy(n){return new Proxy(n,{get:function(e,t){if(typeof t=="symbol"){let r=Reflect.get(e,t);return typeof r=="function"?function(){return r.apply(n,arguments)}:r}if(t==="toJSON")return()=>Object.fromEntries(n);if(t in e&&typeof e[t]=="function")return function(){return n[t].apply(n,arguments)};let i=n.getAll(t);if(i.length!==0)return i.length===1?i[0]:formDataArrayProxy(e,t,i)},set:function(e,t,i){return typeof t!="string"?!1:(e.delete(t),i&&typeof i.forEach=="function"?i.forEach(function(r){e.append(t,r)}):typeof i=="object"&&!(i instanceof Blob)?e.append(t,JSON.stringify(i)):e.append(t,i),!0)},deleteProperty:function(e,t){return typeof t=="string"&&e.delete(t),!0},ownKeys:function(e){return Reflect.ownKeys(Object.fromEntries(e))},getOwnPropertyDescriptor:function(e,t){return Reflect.getOwnPropertyDescriptor(Object.fromEntries(e),t)}})}function issueAjaxRequest(n,e,t,i,r,o){let s=null,a=null;if(r=r!=null?r:{},r.returnPromise&&typeof Promise!="undefined")var l=new Promise(function(U,Z){s=U,a=Z});t==null&&(t=getDocument().body);let c=r.handler||handleAjaxResponse,u=r.select||null;if(!bodyContains(t))return maybeCall(s),l;let d=r.targetOverride||asElement(getTarget(t));if(d==null||d==DUMMY_ELT)return triggerErrorEvent(t,"htmx:targetError",{target:getClosestAttributeValue(t,"hx-target")}),maybeCall(a),l;let p=getInternalData(t),y=p.lastButtonClicked;if(y){let U=getRawAttribute(y,"formaction");U!=null&&(e=U);let Z=getRawAttribute(y,"formmethod");if(Z!=null)if(VERBS.includes(Z.toLowerCase()))n=Z;else return maybeCall(s),l}let m=getClosestAttributeValue(t,"hx-confirm");if(o===void 0&&triggerEvent(t,"htmx:confirm",{target:d,elt:t,path:e,verb:n,triggeringEvent:i,etc:r,issueRequest:function(oe){return issueAjaxRequest(n,e,t,i,r,!!oe)},question:m})===!1)return maybeCall(s),l;let v=t,w=getClosestAttributeValue(t,"hx-sync"),T=null,_=!1;if(w){let U=w.split(":"),Z=U[0].trim();if(Z==="this"?v=findThisElement(t,"hx-sync"):v=asElement(querySelectorExt(t,Z)),w=(U[1]||"drop").trim(),p=getInternalData(v),w==="drop"&&p.xhr&&p.abortable!==!0)return maybeCall(s),l;if(w==="abort"){if(p.xhr)return maybeCall(s),l;_=!0}else w==="replace"?triggerEvent(v,"htmx:abort"):w.indexOf("queue")===0&&(T=(w.split(" ")[1]||"last").trim())}if(p.xhr)if(p.abortable)triggerEvent(v,"htmx:abort");else{if(T==null){if(i){let U=getInternalData(i);U&&U.triggerSpec&&U.triggerSpec.queue&&(T=U.triggerSpec.queue)}T==null&&(T="last")}return p.queuedRequests==null&&(p.queuedRequests=[]),T==="first"&&p.queuedRequests.length===0?p.queuedRequests.push(function(){issueAjaxRequest(n,e,t,i,r)}):T==="all"?p.queuedRequests.push(function(){issueAjaxRequest(n,e,t,i,r)}):T==="last"&&(p.queuedRequests=[],p.queuedRequests.push(function(){issueAjaxRequest(n,e,t,i,r)})),maybeCall(s),l}let S=new XMLHttpRequest;p.xhr=S,p.abortable=_;let A=function(){p.xhr=null,p.abortable=!1,p.queuedRequests!=null&&p.queuedRequests.length>0&&p.queuedRequests.shift()()},K=getClosestAttributeValue(t,"hx-prompt");if(K){var z=prompt(K);if(z===null||!triggerEvent(t,"htmx:prompt",{prompt:z,target:d}))return maybeCall(s),A(),l}if(m&&!o&&!confirm(m))return maybeCall(s),A(),l;let L=getHeaders(t,d,z);n!=="get"&&!usesFormData(t)&&(L["Content-Type"]="application/x-www-form-urlencoded"),r.headers&&(L=mergeObjects(L,r.headers));let H=getInputValues(t,n),N=H.errors,Y=H.formData;r.values&&overrideFormData(Y,formDataFromObject(r.values));let B=formDataFromObject(getExpressionVars(t,i)),ie=overrideFormData(Y,B),J=filterValues(ie,t);htmx.config.getCacheBusterParam&&n==="get"&&J.set("org.htmx.cache-buster",getRawAttribute(d,"id")||"true"),(e==null||e==="")&&(e=location.href);let Te=getValuesForElement(t,"hx-request"),Ce=getInternalData(t).boosted,se=htmx.config.methodsThatUseUrlParams.indexOf(n)>=0,ne={boosted:Ce,useUrlParams:se,formData:J,parameters:formDataProxy(J),unfilteredFormData:ie,unfilteredParameters:formDataProxy(ie),headers:L,elt:t,target:d,verb:n,errors:N,withCredentials:r.credentials||Te.credentials||htmx.config.withCredentials,timeout:r.timeout||Te.timeout||htmx.config.timeout,path:e,triggeringEvent:i};if(!triggerEvent(t,"htmx:configRequest",ne))return maybeCall(s),A(),l;if(e=ne.path,n=ne.verb,L=ne.headers,J=formDataFromObject(ne.parameters),N=ne.errors,se=ne.useUrlParams,N&&N.length>0)return triggerEvent(t,"htmx:validation:halted",ne),maybeCall(s),A(),l;let qe=e.split("#"),Re=qe[0],W=qe[1],M=e;if(se&&(M=Re,!J.keys().next().done&&(M.indexOf("?")<0?M+="?":M+="&",M+=urlEncode(J),W&&(M+="#"+W))),!verifyPath(t,M,ne))return triggerErrorEvent(t,"htmx:invalidPath",ne),maybeCall(a),A(),l;if(S.open(n.toUpperCase(),M,!0),S.overrideMimeType("text/html"),S.withCredentials=ne.withCredentials,S.timeout=ne.timeout,!Te.noHeaders){for(let U in L)if(L.hasOwnProperty(U)){let Z=L[U];safelySetHeaderValue(S,U,Z)}}let D={xhr:S,target:d,requestConfig:ne,etc:r,boosted:Ce,select:u,pathInfo:{requestPath:e,finalRequestPath:M,responsePath:null,anchor:W}};if(S.onload=function(){try{let U=hierarchyForElt(t);if(D.pathInfo.responsePath=getPathFromResponse(S),c(t,D),D.keepIndicators!==!0&&removeRequestIndicators($,V),triggerEvent(t,"htmx:afterRequest",D),triggerEvent(t,"htmx:afterOnLoad",D),!bodyContains(t)){let Z=null;for(;U.length>0&&Z==null;){let oe=U.shift();bodyContains(oe)&&(Z=oe)}Z&&(triggerEvent(Z,"htmx:afterRequest",D),triggerEvent(Z,"htmx:afterOnLoad",D))}maybeCall(s)}catch(U){throw triggerErrorEvent(t,"htmx:onLoadError",mergeObjects({error:U},D)),U}finally{A()}},S.onerror=function(){removeRequestIndicators($,V),triggerErrorEvent(t,"htmx:afterRequest",D),triggerErrorEvent(t,"htmx:sendError",D),maybeCall(a),A()},S.onabort=function(){removeRequestIndicators($,V),triggerErrorEvent(t,"htmx:afterRequest",D),triggerErrorEvent(t,"htmx:sendAbort",D),maybeCall(a),A()},S.ontimeout=function(){removeRequestIndicators($,V),triggerErrorEvent(t,"htmx:afterRequest",D),triggerErrorEvent(t,"htmx:timeout",D),maybeCall(a),A()},!triggerEvent(t,"htmx:beforeRequest",D))return maybeCall(s),A(),l;var $=addRequestIndicatorClasses(t),V=disableElements(t);forEach(["loadstart","loadend","progress","abort"],function(U){forEach([S,S.upload],function(Z){Z.addEventListener(U,function(oe){triggerEvent(t,"htmx:xhr:"+U,{lengthComputable:oe.lengthComputable,loaded:oe.loaded,total:oe.total})})})}),triggerEvent(t,"htmx:beforeSend",D);let q=se?null:encodeParamsForBody(S,t,J);return S.send(q),l}function determineHistoryUpdates(n,e){let t=e.xhr,i=null,r=null;if(hasHeader(t,/HX-Push:/i)?(i=t.getResponseHeader("HX-Push"),r="push"):hasHeader(t,/HX-Push-Url:/i)?(i=t.getResponseHeader("HX-Push-Url"),r="push"):hasHeader(t,/HX-Replace-Url:/i)&&(i=t.getResponseHeader("HX-Replace-Url"),r="replace"),i)return i==="false"?{}:{type:r,path:i};let o=e.pathInfo.finalRequestPath,s=e.pathInfo.responsePath,a=getClosestAttributeValue(n,"hx-push-url"),l=getClosestAttributeValue(n,"hx-replace-url"),c=getInternalData(n).boosted,u=null,d=null;return a?(u="push",d=a):l?(u="replace",d=l):c&&(u="push",d=s||o),d?d==="false"?{}:(d==="true"&&(d=s||o),e.pathInfo.anchor&&d.indexOf("#")===-1&&(d=d+"#"+e.pathInfo.anchor),{type:u,path:d}):{}}function codeMatches(n,e){var t=new RegExp(n.code);return t.test(e.toString(10))}function resolveResponseHandling(n){for(var e=0;e ."+htmx.config.indicatorClass+"{opacity:0} ."+htmx.config.requestClass+" ."+htmx.config.indicatorClass+"{opacity:1; transition: opacity 200ms ease-in;} ."+htmx.config.requestClass+"."+htmx.config.indicatorClass+"{opacity:1; transition: opacity 200ms ease-in;} ")}}function getMetaConfig(){let n=getDocument().querySelector('meta[name="htmx-config"]');return n?parseJSON(n.content):null}function mergeMetaConfig(){let n=getMetaConfig();n&&(htmx.config=mergeObjects(htmx.config,n))}return ready(function(){mergeMetaConfig(),insertIndicatorStyles();let n=getDocument().body;processNode(n);let e=getDocument().querySelectorAll("[hx-trigger='restored'],[data-hx-trigger='restored']");n.addEventListener("htmx:abort",function(i){let r=i.target,o=getInternalData(r);o&&o.xhr&&o.xhr.abort()});let t=window.onpopstate?window.onpopstate.bind(window):null;window.onpopstate=function(i){i.state&&i.state.htmx?(restoreHistory(),forEach(e,function(r){triggerEvent(r,"htmx:restored",{document:getDocument(),triggerEvent})})):t&&t(i)},getWindow().setTimeout(function(){triggerEvent(n,"htmx:load",{}),n=null},0)}),htmx}(),T_=Xp;function ko(n,e){n.split(/\s+/).forEach(t=>{e(t)})}var oi=class{constructor(){this._events={}}on(e,t){ko(e,i=>{let r=this._events[i]||[];r.push(t),this._events[i]=r})}off(e,t){var i=arguments.length;if(i===0){this._events={};return}ko(e,r=>{if(i===1){delete this._events[r];return}let o=this._events[r];o!==void 0&&(o.splice(o.indexOf(t),1),this._events[r]=o)})}trigger(e,...t){var i=this;ko(e,r=>{let o=i._events[r];o!==void 0&&o.forEach(s=>{s.apply(i,t)})})}};function No(n){return n.plugins={},class extends n{constructor(){super(...arguments),this.plugins={names:[],settings:{},requested:{},loaded:{}}}static define(e,t){n.plugins[e]={name:e,fn:t}}initializePlugins(e){var t,i;let r=this,o=[];if(Array.isArray(e))e.forEach(s=>{typeof s=="string"?o.push(s):(r.plugins.settings[s.name]=s.options,o.push(s.name))});else if(e)for(t in e)e.hasOwnProperty(t)&&(r.plugins.settings[t]=e[t],o.push(t));for(;i=o.shift();)r.require(i)}loadPlugin(e){var t=this,i=t.plugins,r=n.plugins[e];if(!n.plugins.hasOwnProperty(e))throw new Error('Unable to find "'+e+'" plugin');i.requested[e]=!0,i.loaded[e]=r.fn.apply(t,[t.plugins.settings[e]||{}]),i.names.push(e)}require(e){var t=this,i=t.plugins;if(!t.plugins.loaded.hasOwnProperty(e)){if(i.requested[e])throw new Error('Plugin has circular dependency ("'+e+'")');t.loadPlugin(e)}return i.loaded[e]}}}var si=n=>(n=n.filter(Boolean),n.length<2?n[0]||"":Jp(n)==1?"["+n.join("")+"]":"(?:"+n.join("|")+")"),Io=n=>{if(!Qp(n))return n.join("");let e="",t=0,i=()=>{t>1&&(e+="{"+t+"}")};return n.forEach((r,o)=>{if(r===n[o-1]){t++;return}i(),e+=r,t=1}),i(),e},Ro=n=>{let e=Array.from(n);return si(e)},Qp=n=>new Set(n).size!==n.length,Mt=n=>(n+"").replace(/([\$\(\)\*\+\.\?\[\]\^\{\|\}\\])/gu,"\\$1"),Jp=n=>n.reduce((e,t)=>Math.max(e,Zp(t)),0),Zp=n=>Array.from(n).length;var Ho=n=>{if(n.length===1)return[[n]];let e=[],t=n.substring(1);return Ho(t).forEach(function(r){let o=r.slice(0);o[0]=n.charAt(0)+o[0],e.push(o),o=r.slice(0),o.unshift(n.charAt(0)),e.push(o)}),e};var em=[[0,65535]],tm="[\u0300-\u036F\xB7\u02BE\u02BC]",or,$a,nm=3,Po={},Pa={"/":"\u2044\u2215",0:"\u07C0",a:"\u2C65\u0250\u0251",aa:"\uA733",ae:"\xE6\u01FD\u01E3",ao:"\uA735",au:"\uA737",av:"\uA739\uA73B",ay:"\uA73D",b:"\u0180\u0253\u0183",c:"\uA73F\u0188\u023C\u2184",d:"\u0111\u0257\u0256\u1D05\u018C\uABB7\u0501\u0266",e:"\u025B\u01DD\u1D07\u0247",f:"\uA77C\u0192",g:"\u01E5\u0260\uA7A1\u1D79\uA77F\u0262",h:"\u0127\u2C68\u2C76\u0265",i:"\u0268\u0131",j:"\u0249\u0237",k:"\u0199\u2C6A\uA741\uA743\uA745\uA7A3",l:"\u0142\u019A\u026B\u2C61\uA749\uA747\uA781\u026D",m:"\u0271\u026F\u03FB",n:"\uA7A5\u019E\u0272\uA791\u1D0E\u043B\u0509",o:"\xF8\u01FF\u0254\u0275\uA74B\uA74D\u1D11",oe:"\u0153",oi:"\u01A3",oo:"\uA74F",ou:"\u0223",p:"\u01A5\u1D7D\uA751\uA753\uA755\u03C1",q:"\uA757\uA759\u024B",r:"\u024D\u027D\uA75B\uA7A7\uA783",s:"\xDF\u023F\uA7A9\uA785\u0282",t:"\u0167\u01AD\u0288\u2C66\uA787",th:"\xFE",tz:"\uA729",u:"\u0289",v:"\u028B\uA75F\u028C",vy:"\uA761",w:"\u2C73",y:"\u01B4\u024F\u1EFF",z:"\u01B6\u0225\u0240\u2C6C\uA763",hv:"\u0195"};for(let n in Pa){let e=Pa[n]||"";for(let t=0;t{or===void 0&&(or=lm(n||em))},Fa=(n,e="NFKD")=>n.normalize(e),ai=n=>Array.from(n).reduce((e,t)=>e+om(t),""),om=n=>(n=Fa(n).toLowerCase().replace(im,e=>Po[e]||""),Fa(n,"NFC"));function*sm(n){for(let[e,t]of n)for(let i=e;i<=t;i++){let r=String.fromCharCode(i),o=ai(r);o!=r.toLowerCase()&&(o.length>nm||o.length!=0&&(yield{folded:o,composed:r,code_point:i}))}}var am=n=>{let e={},t=(i,r)=>{let o=e[i]||new Set,s=new RegExp("^"+Ro(o)+"$","iu");r.match(s)||(o.add(Mt(r)),e[i]=o)};for(let i of sm(n))t(i.folded,i.folded),t(i.folded,i.composed);return e},lm=n=>{let e=am(n),t={},i=[];for(let o in e){let s=e[o];s&&(t[o]=Ro(s)),o.length>1&&i.push(Mt(o))}i.sort((o,s)=>s.length-o.length);let r=si(i);return $a=new RegExp("^"+r,"u"),t},cm=(n,e=1)=>{let t=0;return n=n.map(i=>(or[i]&&(t+=i.length),or[i]||i)),t>=e?Io(n):""},um=(n,e=1)=>(e=Math.max(e,n.length-1),si(Ho(n).map(t=>cm(t,e)))),Ba=(n,e=!0)=>{let t=n.length>1?1:0;return si(n.map(i=>{let r=[],o=e?i.length():i.length()-1;for(let s=0;s{for(let t of e){if(t.start!=n.start||t.end!=n.end||t.substrs.join("")!==n.substrs.join(""))continue;let i=n.parts,r=s=>{for(let a of i){if(a.start===s.start&&a.substr===s.substr)return!1;if(!(s.length==1||a.length==1)&&(s.starta.start||a.starts.start))return!0}return!1};if(!(t.parts.filter(r).length>0))return!0}return!1},sr=class n{constructor(){ee(this,"parts");ee(this,"substrs");ee(this,"start");ee(this,"end");this.parts=[],this.substrs=[],this.start=0,this.end=0}add(e){e&&(this.parts.push(e),this.substrs.push(e.substr),this.start=Math.min(e.start,this.start),this.end=Math.max(e.end,this.end))}last(){return this.parts[this.parts.length-1]}length(){return this.parts.length}clone(e,t){let i=new n,r=JSON.parse(JSON.stringify(this.parts)),o=r.pop();for(let l of r)i.add(l);let s=t.substr.substring(0,e-o.start),a=s.length;return i.add({start:o.start,end:o.start+a,length:a,substr:s}),i}},Va=n=>{rm(),n=ai(n);let e="",t=[new sr];for(let i=0;i0){l=l.sort((u,d)=>u.length()-d.length());for(let u of l)dm(u,t)||t.push(u);continue}if(i>0&&c.size==1&&!c.has("3")){e+=Ba(t,!1);let u=new sr,d=t[0];d&&u.add(d.last()),t=[u]}}return e+=Ba(t,!0),e};var za=(n,e)=>{if(n)return n[e]},ja=(n,e)=>{if(n){for(var t,i=e.split(".");(t=i.shift())&&(n=n[t]););return n}},ar=(n,e,t)=>{var i,r;return!n||(n=n+"",e.regex==null)||(r=n.search(e.regex),r===-1)?0:(i=e.string.length/n.length,r===0&&(i+=.5),i*t)},lr=(n,e)=>{var t=n[e];if(typeof t=="function")return t;t&&!Array.isArray(t)&&(n[e]=[t])},li=(n,e)=>{if(Array.isArray(n))n.forEach(e);else for(var t in n)n.hasOwnProperty(t)&&e(n[t],t)},Wa=(n,e)=>typeof n=="number"&&typeof e=="number"?n>e?1:ne?1:e>n?-1:0);var cr=class{constructor(e,t){ee(this,"items");ee(this,"settings");this.items=e,this.settings=t||{diacritics:!0}}tokenize(e,t,i){if(!e||!e.length)return[];let r=[],o=e.split(/\s+/);var s;return i&&(s=new RegExp("^("+Object.keys(i).map(Mt).join("|")+"):(.*)$")),o.forEach(a=>{let l,c=null,u=null;s&&(l=a.match(s))&&(c=l[1],a=l[2]),a.length>0&&(this.settings.diacritics?u=Va(a)||null:u=Mt(a),u&&t&&(u="\\b"+u)),r.push({string:a,regex:u?new RegExp(u,"iu"):null,field:c})}),r}getScoreFunction(e,t){var i=this.prepareSearch(e,t);return this._getScoreFunction(i)}_getScoreFunction(e){let t=e.tokens,i=t.length;if(!i)return function(){return 0};let r=e.options.fields,o=e.weights,s=r.length,a=e.getAttrFn;if(!s)return function(){return 1};let l=function(){return s===1?function(c,u){let d=r[0].field;return ar(a(u,d),c,o[d]||1)}:function(c,u){var d=0;if(c.field){let p=a(u,c.field);!c.regex&&p?d+=1/s:d+=ar(p,c,1)}else li(o,(p,y)=>{d+=ar(a(u,y),c,p)});return d/s}}();return i===1?function(c){return l(t[0],c)}:e.options.conjunction==="and"?function(c){var u,d=0;for(let p of t){if(u=l(p,c),u<=0)return 0;d+=u}return d/i}:function(c){var u=0;return li(t,d=>{u+=l(d,c)}),u/i}}getSortFunction(e,t){var i=this.prepareSearch(e,t);return this._getSortFunction(i)}_getSortFunction(e){var t,i=[];let r=this,o=e.options,s=!e.query&&o.sort_empty?o.sort_empty:o.sort;if(typeof s=="function")return s.bind(this);let a=function(c,u){return c==="$score"?u.score:e.getAttrFn(r.items[u.id],c)};if(s)for(let c of s)(e.query||c.field!=="$score")&&i.push(c);if(e.query){t=!0;for(let c of i)if(c.field==="$score"){t=!1;break}t&&i.unshift({field:"$score",direction:"desc"})}else i=i.filter(c=>c.field!=="$score");return i.length?function(c,u){var d,p;for(let y of i)if(p=y.field,d=(y.direction==="desc"?-1:1)*Wa(a(p,c),a(p,u)),d)return d;return 0}:null}prepareSearch(e,t){let i={};var r=Object.assign({},t);if(lr(r,"sort"),lr(r,"sort_empty"),r.fields){lr(r,"fields");let o=[];r.fields.forEach(s=>{typeof s=="string"&&(s={field:s,weight:1}),o.push(s),i[s.field]="weight"in s?s.weight:1}),r.fields=o}return{options:r,query:e.toLowerCase().trim(),tokens:this.tokenize(e,r.respect_word_boundaries,i),total:0,items:[],weights:i,getAttrFn:r.nesting?ja:za}}search(e,t){var i=this,r,o;o=this.prepareSearch(e,t),t=o.options,e=o.query;let s=t.score||i._getScoreFunction(o);e.length?li(i.items,(l,c)=>{r=s(l),(t.filter===!1||r>0)&&o.items.push({score:r,id:c})}):li(i.items,(l,c)=>{o.items.push({score:1,id:c})});let a=i._getSortFunction(o);return a&&o.items.sort(a),o.total=o.items.length,typeof t.limit=="number"&&(o.items=o.items.slice(0,t.limit)),o}};var We=n=>typeof n=="undefined"||n===null?null:ci(n),ci=n=>typeof n=="boolean"?n?"1":"0":n+"",ur=n=>(n+"").replace(/&/g,"&").replace(//g,">").replace(/"/g,"""),qa=(n,e)=>e>0?window.setTimeout(n,e):(n.call(null),null),Ua=(n,e)=>{var t;return function(i,r){var o=this;t&&(o.loading=Math.max(o.loading-1,0),clearTimeout(t)),t=setTimeout(function(){t=null,o.loadedSearches[i]=!0,n.call(o,i,r)},e)}},Fo=(n,e,t)=>{var i,r=n.trigger,o={};n.trigger=function(){var s=arguments[0];if(e.indexOf(s)!==-1)o[s]=arguments;else return r.apply(n,arguments)},t.apply(n,[]),n.trigger=r;for(i of e)i in o&&r.apply(n,o[i])},Ya=n=>({start:n.selectionStart||0,length:(n.selectionEnd||0)-(n.selectionStart||0)}),fe=(n,e=!1)=>{n&&(n.preventDefault(),e&&n.stopPropagation())},Se=(n,e,t,i)=>{n.addEventListener(e,t,i)},kt=(n,e)=>{if(!e||!e[n])return!1;var t=(e.altKey?1:0)+(e.ctrlKey?1:0)+(e.shiftKey?1:0)+(e.metaKey?1:0);return t===1},dr=(n,e)=>{let t=n.getAttribute("id");return t||(n.setAttribute("id",e),e)},Bo=n=>n.replace(/[\\"']/g,"\\$&"),Nt=(n,e)=>{e&&n.append(e)},ve=(n,e)=>{if(Array.isArray(n))n.forEach(e);else for(var t in n)n.hasOwnProperty(t)&&e(n[t],t)};var nt=n=>{if(n.jquery)return n[0];if(n instanceof HTMLElement)return n;if($o(n)){var e=document.createElement("template");return e.innerHTML=n.trim(),e.content.firstChild}return document.querySelector(n)},$o=n=>typeof n=="string"&&n.indexOf("<")>-1,Ga=n=>n.replace(/['"\\]/g,"\\$&"),fr=(n,e)=>{var t=document.createEvent("HTMLEvents");t.initEvent(e,!0,!1),n.dispatchEvent(t)},ui=(n,e)=>{Object.assign(n.style,e)},Pe=(n,...e)=>{var t=Ka(e);n=Xa(n),n.map(i=>{t.map(r=>{i.classList.add(r)})})},gt=(n,...e)=>{var t=Ka(e);n=Xa(n),n.map(i=>{t.map(r=>{i.classList.remove(r)})})},Ka=n=>{var e=[];return ve(n,t=>{typeof t=="string"&&(t=t.trim().split(/[\t\n\f\r\s]/)),Array.isArray(t)&&(e=e.concat(t))}),e.filter(Boolean)},Xa=n=>(Array.isArray(n)||(n=[n]),n),hr=(n,e,t)=>{if(!(t&&!t.contains(n)))for(;n&&n.matches;){if(n.matches(e))return n;n=n.parentNode}},Vo=(n,e=0)=>e>0?n[n.length-1]:n[0],Qa=n=>Object.keys(n).length===0,zo=(n,e)=>{if(!n)return-1;e=e||n.nodeName;for(var t=0;n=n.previousElementSibling;)n.matches(e)&&t++;return t},le=(n,e)=>{ve(e,(t,i)=>{t==null?n.removeAttribute(i):n.setAttribute(i,""+t)})},di=(n,e)=>{n.parentNode&&n.parentNode.replaceChild(e,n)};var Ja=(n,e)=>{if(e===null)return;if(typeof e=="string"){if(!e.length)return;e=new RegExp(e,"i")}let t=o=>{var s=o.data.match(e);if(s&&o.data.length>0){var a=document.createElement("span");a.className="highlight";var l=o.splitText(s.index);l.splitText(s[0].length);var c=l.cloneNode(!0);return a.appendChild(c),di(l,a),1}return 0},i=o=>{o.nodeType===1&&o.childNodes&&!/(script|style)/i.test(o.tagName)&&(o.className!=="highlight"||o.tagName!=="SPAN")&&Array.from(o.childNodes).forEach(s=>{r(s)})},r=o=>o.nodeType===3?t(o):(i(o),0);r(n)},Za=n=>{var e=n.querySelectorAll("span.highlight");Array.prototype.forEach.call(e,function(t){var i=t.parentNode;i.replaceChild(t.firstChild,t),i.normalize()})};var fm=typeof navigator=="undefined"?!1:/Mac/.test(navigator.userAgent),fi=fm?"metaKey":"ctrlKey";var jo={options:[],optgroups:[],plugins:[],delimiter:",",splitOn:null,persist:!0,diacritics:!0,create:null,createOnBlur:!1,createFilter:null,highlight:!0,openOnFocus:!0,shouldOpen:null,maxOptions:50,maxItems:null,hideSelected:null,duplicates:!1,addPrecedence:!1,selectOnTab:!1,preload:null,allowEmptyOption:!1,refreshThrottle:300,loadThrottle:300,loadingClass:"loading",dataAttr:null,optgroupField:"optgroup",valueField:"value",labelField:"text",disabledField:"disabled",optgroupLabelField:"label",optgroupValueField:"value",lockOptgroupOrder:!1,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"ts-wrapper",controlClass:"ts-control",dropdownClass:"ts-dropdown",dropdownContentClass:"ts-dropdown-content",itemClass:"item",optionClass:"option",dropdownParent:null,controlInput:'',copyClassesToDropdown:!1,placeholder:null,hidePlaceholder:null,shouldLoad:function(n){return n.length>0},render:{}};function pr(n,e){var t=Object.assign({},jo,e),i=t.dataAttr,r=t.labelField,o=t.valueField,s=t.disabledField,a=t.optgroupField,l=t.optgroupLabelField,c=t.optgroupValueField,u=n.tagName.toLowerCase(),d=n.getAttribute("placeholder")||n.getAttribute("data-placeholder");if(!d&&!t.allowEmptyOption){let v=n.querySelector('option[value=""]');v&&(d=v.textContent)}var p={placeholder:d,options:[],optgroups:[],items:[],maxItems:null},y=()=>{var v,w=p.options,T={},_=1;let S=0;var A=L=>{var H=Object.assign({},L.dataset),N=i&&H[i];return typeof N=="string"&&N.length&&(H=Object.assign(H,JSON.parse(N))),H},K=(L,H)=>{var N=We(L.value);if(N!=null&&!(!N&&!t.allowEmptyOption)){if(T.hasOwnProperty(N)){if(H){var Y=T[N][a];Y?Array.isArray(Y)?Y.push(H):T[N][a]=[Y,H]:T[N][a]=H}}else{var B=A(L);B[r]=B[r]||L.textContent,B[o]=B[o]||N,B[s]=B[s]||L.disabled,B[a]=B[a]||H,B.$option=L,B.$order=B.$order||++S,T[N]=B,w.push(B)}L.selected&&p.items.push(N)}},z=L=>{var H,N;N=A(L),N[l]=N[l]||L.getAttribute("label")||"",N[c]=N[c]||_++,N[s]=N[s]||L.disabled,N.$order=N.$order||++S,p.optgroups.push(N),H=N[c],ve(L.children,Y=>{K(Y,H)})};p.maxItems=n.hasAttribute("multiple")?null:1,ve(n.children,L=>{v=L.tagName.toLowerCase(),v==="optgroup"?z(L):v==="option"&&K(L)})},m=()=>{let v=n.getAttribute(i);if(v)p.options=JSON.parse(v),ve(p.options,T=>{p.items.push(T[o])});else{var w=n.value.trim()||"";if(!t.allowEmptyOption&&!w.length)return;let T=w.split(t.delimiter);ve(T,_=>{let S={};S[r]=_,S[o]=_,p.options.push(S)}),p.items=T}};return u==="select"?y():m(),Object.assign({},jo,p,e)}var nl=0,_e=class extends No(oi){constructor(e,t){super(),this.order=0,this.isOpen=!1,this.isDisabled=!1,this.isReadOnly=!1,this.isInvalid=!1,this.isValid=!0,this.isLocked=!1,this.isFocused=!1,this.isInputHidden=!1,this.isSetup=!1,this.ignoreFocus=!1,this.ignoreHover=!1,this.hasOptions=!1,this.lastValue="",this.caretPos=0,this.loading=0,this.loadedSearches={},this.activeOption=null,this.activeItems=[],this.optgroups={},this.options={},this.userOptions={},this.items=[],this.refreshTimeout=null,nl++;var i,r=nt(e);if(r.tomselect)throw new Error("Tom Select already initialized on this element");r.tomselect=this;var o=window.getComputedStyle&&window.getComputedStyle(r,null);i=o.getPropertyValue("direction");let s=pr(r,t);this.settings=s,this.input=r,this.tabIndex=r.tabIndex||0,this.is_select_tag=r.tagName.toLowerCase()==="select",this.rtl=/rtl/i.test(i),this.inputId=dr(r,"tomselect-"+nl),this.isRequired=r.required,this.sifter=new cr(this.options,{diacritics:s.diacritics}),s.mode=s.mode||(s.maxItems===1?"single":"multi"),typeof s.hideSelected!="boolean"&&(s.hideSelected=s.mode==="multi"),typeof s.hidePlaceholder!="boolean"&&(s.hidePlaceholder=s.mode!=="multi");var a=s.createFilter;typeof a!="function"&&(typeof a=="string"&&(a=new RegExp(a)),a instanceof RegExp?s.createFilter=w=>a.test(w):s.createFilter=w=>this.settings.duplicates||!this.options[w]),this.initializePlugins(s.plugins),this.setupCallbacks(),this.setupTemplates();let l=nt("
"),c=nt("
"),u=this._render("dropdown"),d=nt('
'),p=this.input.getAttribute("class")||"",y=s.mode;var m;if(Pe(l,s.wrapperClass,p,y),Pe(c,s.controlClass),Nt(l,c),Pe(u,s.dropdownClass,y),s.copyClassesToDropdown&&Pe(u,p),Pe(d,s.dropdownContentClass),Nt(u,d),nt(s.dropdownParent||l).appendChild(u),$o(s.controlInput)){m=nt(s.controlInput);var v=["autocorrect","autocapitalize","autocomplete","spellcheck"];ve(v,w=>{r.getAttribute(w)&&le(m,{[w]:r.getAttribute(w)})}),m.tabIndex=-1,c.appendChild(m),this.focus_node=m}else s.controlInput?(m=nt(s.controlInput),this.focus_node=m):(m=nt(""),this.focus_node=c);this.wrapper=l,this.dropdown=u,this.dropdown_content=d,this.control=c,this.control_input=m,this.setup()}setup(){let e=this,t=e.settings,i=e.control_input,r=e.dropdown,o=e.dropdown_content,s=e.wrapper,a=e.control,l=e.input,c=e.focus_node,u={passive:!0},d=e.inputId+"-ts-dropdown";le(o,{id:d}),le(c,{role:"combobox","aria-haspopup":"listbox","aria-expanded":"false","aria-controls":d});let p=dr(c,e.inputId+"-ts-control"),y="label[for='"+Ga(e.inputId)+"']",m=document.querySelector(y),v=e.focus.bind(e);if(m){Se(m,"click",v),le(m,{for:p});let _=dr(m,e.inputId+"-ts-label");le(c,{"aria-labelledby":_}),le(o,{"aria-labelledby":_})}if(s.style.width=l.style.width,e.plugins.names.length){let _="plugin-"+e.plugins.names.join(" plugin-");Pe([s,r],_)}(t.maxItems===null||t.maxItems>1)&&e.is_select_tag&&le(l,{multiple:"multiple"}),t.placeholder&&le(i,{placeholder:t.placeholder}),!t.splitOn&&t.delimiter&&(t.splitOn=new RegExp("\\s*"+Mt(t.delimiter)+"+\\s*")),t.load&&t.loadThrottle&&(t.load=Ua(t.load,t.loadThrottle)),Se(r,"mousemove",()=>{e.ignoreHover=!1}),Se(r,"mouseenter",_=>{var S=hr(_.target,"[data-selectable]",r);S&&e.onOptionHover(_,S)},{capture:!0}),Se(r,"click",_=>{let S=hr(_.target,"[data-selectable]");S&&(e.onOptionSelect(_,S),fe(_,!0))}),Se(a,"click",_=>{var S=hr(_.target,"[data-ts-item]",a);if(S&&e.onItemSelect(_,S)){fe(_,!0);return}i.value==""&&(e.onClick(),fe(_,!0))}),Se(c,"keydown",_=>e.onKeyDown(_)),Se(i,"keypress",_=>e.onKeyPress(_)),Se(i,"input",_=>e.onInput(_)),Se(c,"blur",_=>e.onBlur(_)),Se(c,"focus",_=>e.onFocus(_)),Se(i,"paste",_=>e.onPaste(_));let w=_=>{let S=_.composedPath()[0];if(!s.contains(S)&&!r.contains(S)){e.isFocused&&e.blur(),e.inputState();return}S==i&&e.isOpen?_.stopPropagation():fe(_,!0)},T=()=>{e.isOpen&&e.positionDropdown()};Se(document,"mousedown",w),Se(window,"scroll",T,u),Se(window,"resize",T,u),this._destroy=()=>{document.removeEventListener("mousedown",w),window.removeEventListener("scroll",T),window.removeEventListener("resize",T),m&&m.removeEventListener("click",v)},this.revertSettings={innerHTML:l.innerHTML,tabIndex:l.tabIndex},l.tabIndex=-1,l.insertAdjacentElement("afterend",e.wrapper),e.sync(!1),t.items=[],delete t.optgroups,delete t.options,Se(l,"invalid",()=>{e.isValid&&(e.isValid=!1,e.isInvalid=!0,e.refreshState())}),e.updateOriginalInput(),e.refreshItems(),e.close(!1),e.inputState(),e.isSetup=!0,l.disabled?e.disable():l.readOnly?e.setReadOnly(!0):e.enable(),e.on("change",this.onChange),Pe(l,"tomselected","ts-hidden-accessible"),e.trigger("initialize"),t.preload===!0&&e.preload()}setupOptions(e=[],t=[]){this.addOptions(e),ve(t,i=>{this.registerOptionGroup(i)})}setupTemplates(){var e=this,t=e.settings.labelField,i=e.settings.optgroupLabelField,r={optgroup:o=>{let s=document.createElement("div");return s.className="optgroup",s.appendChild(o.options),s},optgroup_header:(o,s)=>'
'+s(o[i])+"
",option:(o,s)=>"
"+s(o[t])+"
",item:(o,s)=>"
"+s(o[t])+"
",option_create:(o,s)=>'
Add '+s(o.input)+"
",no_results:()=>'
No results found
',loading:()=>'
',not_loading:()=>{},dropdown:()=>"
"};e.settings.render=Object.assign({},r,e.settings.render)}setupCallbacks(){var e,t,i={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",item_select:"onItemSelect",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",optgroup_add:"onOptionGroupAdd",optgroup_remove:"onOptionGroupRemove",optgroup_clear:"onOptionGroupClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType",load:"onLoad",focus:"onFocus",blur:"onBlur"};for(e in i)t=this.settings[i[e]],t&&this.on(e,t)}sync(e=!0){let t=this,i=e?pr(t.input,{delimiter:t.settings.delimiter}):t.settings;t.setupOptions(i.options,i.optgroups),t.setValue(i.items||[],!0),t.lastQuery=null}onClick(){var e=this;if(e.activeItems.length>0){e.clearActiveItems(),e.focus();return}e.isFocused&&e.isOpen?e.blur():e.focus()}onMouseDown(){}onChange(){fr(this.input,"input"),fr(this.input,"change")}onPaste(e){var t=this;if(t.isInputHidden||t.isLocked){fe(e);return}t.settings.splitOn&&setTimeout(()=>{var i=t.inputValue();if(i.match(t.settings.splitOn)){var r=i.trim().split(t.settings.splitOn);ve(r,o=>{We(o)&&(this.options[o]?t.addItem(o):t.createItem(o))})}},0)}onKeyPress(e){var t=this;if(t.isLocked){fe(e);return}var i=String.fromCharCode(e.keyCode||e.which);if(t.settings.create&&t.settings.mode==="multi"&&i===t.settings.delimiter){t.createItem(),fe(e);return}}onKeyDown(e){var t=this;if(t.ignoreHover=!0,t.isLocked){e.keyCode!==9&&fe(e);return}switch(e.keyCode){case 65:if(kt(fi,e)&&t.control_input.value==""){fe(e),t.selectAll();return}break;case 27:t.isOpen&&(fe(e,!0),t.close()),t.clearActiveItems();return;case 40:if(!t.isOpen&&t.hasOptions)t.open();else if(t.activeOption){let i=t.getAdjacent(t.activeOption,1);i&&t.setActiveOption(i)}fe(e);return;case 38:if(t.activeOption){let i=t.getAdjacent(t.activeOption,-1);i&&t.setActiveOption(i)}fe(e);return;case 13:t.canSelect(t.activeOption)?(t.onOptionSelect(e,t.activeOption),fe(e)):t.settings.create&&t.createItem()?fe(e):document.activeElement==t.control_input&&t.isOpen&&fe(e);return;case 37:t.advanceSelection(-1,e);return;case 39:t.advanceSelection(1,e);return;case 9:t.settings.selectOnTab&&(t.canSelect(t.activeOption)&&(t.onOptionSelect(e,t.activeOption),fe(e)),t.settings.create&&t.createItem()&&fe(e));return;case 8:case 46:t.deleteSelection(e);return}t.isInputHidden&&!kt(fi,e)&&fe(e)}onInput(e){if(this.isLocked)return;let t=this.inputValue();if(this.lastValue!==t){if(this.lastValue=t,t==""){this._onInput();return}this.refreshTimeout&&window.clearTimeout(this.refreshTimeout),this.refreshTimeout=qa(()=>{this.refreshTimeout=null,this._onInput()},this.settings.refreshThrottle)}}_onInput(){let e=this.lastValue;this.settings.shouldLoad.call(this,e)&&this.load(e),this.refreshOptions(),this.trigger("type",e)}onOptionHover(e,t){this.ignoreHover||this.setActiveOption(t,!1)}onFocus(e){var t=this,i=t.isFocused;if(t.isDisabled||t.isReadOnly){t.blur(),fe(e);return}t.ignoreFocus||(t.isFocused=!0,t.settings.preload==="focus"&&t.preload(),i||t.trigger("focus"),t.activeItems.length||(t.inputState(),t.refreshOptions(!!t.settings.openOnFocus)),t.refreshState())}onBlur(e){if(document.hasFocus()!==!1){var t=this;if(t.isFocused){t.isFocused=!1,t.ignoreFocus=!1;var i=()=>{t.close(),t.setActiveItem(),t.setCaret(t.items.length),t.trigger("blur")};t.settings.create&&t.settings.createOnBlur?t.createItem(null,i):i()}}}onOptionSelect(e,t){var i,r=this;t.parentElement&&t.parentElement.matches("[data-disabled]")||(t.classList.contains("create")?r.createItem(null,()=>{r.settings.closeAfterSelect&&r.close()}):(i=t.dataset.value,typeof i!="undefined"&&(r.lastQuery=null,r.addItem(i),r.settings.closeAfterSelect&&r.close(),!r.settings.hideSelected&&e.type&&/click/.test(e.type)&&r.setActiveOption(t))))}canSelect(e){return!!(this.isOpen&&e&&this.dropdown_content.contains(e))}onItemSelect(e,t){var i=this;return!i.isLocked&&i.settings.mode==="multi"?(fe(e),i.setActiveItem(t,e),!0):!1}canLoad(e){return!(!this.settings.load||this.loadedSearches.hasOwnProperty(e))}load(e){let t=this;if(!t.canLoad(e))return;Pe(t.wrapper,t.settings.loadingClass),t.loading++;let i=t.loadCallback.bind(t);t.settings.load.call(t,e,i)}loadCallback(e,t){let i=this;i.loading=Math.max(i.loading-1,0),i.lastQuery=null,i.clearActiveOption(),i.setupOptions(e,t),i.refreshOptions(i.isFocused&&!i.isInputHidden),i.loading||gt(i.wrapper,i.settings.loadingClass),i.trigger("load",e,t)}preload(){var e=this.wrapper.classList;e.contains("preloaded")||(e.add("preloaded"),this.load(""))}setTextboxValue(e=""){var t=this.control_input,i=t.value!==e;i&&(t.value=e,fr(t,"update"),this.lastValue=e)}getValue(){return this.is_select_tag&&this.input.hasAttribute("multiple")?this.items:this.items.join(this.settings.delimiter)}setValue(e,t){var i=t?[]:["change"];Fo(this,i,()=>{this.clear(t),this.addItems(e,t)})}setMaxItems(e){e===0&&(e=null),this.settings.maxItems=e,this.refreshState()}setActiveItem(e,t){var i=this,r,o,s,a,l,c;if(i.settings.mode!=="single"){if(!e){i.clearActiveItems(),i.isFocused&&i.inputState();return}if(r=t&&t.type.toLowerCase(),r==="click"&&kt("shiftKey",t)&&i.activeItems.length){for(c=i.getLastActive(),s=Array.prototype.indexOf.call(i.control.children,c),a=Array.prototype.indexOf.call(i.control.children,e),s>a&&(l=s,s=a,a=l),o=s;o<=a;o++)e=i.control.children[o],i.activeItems.indexOf(e)===-1&&i.setActiveItemClass(e);fe(t)}else r==="click"&&kt(fi,t)||r==="keydown"&&kt("shiftKey",t)?e.classList.contains("active")?i.removeActiveItem(e):i.setActiveItemClass(e):(i.clearActiveItems(),i.setActiveItemClass(e));i.inputState(),i.isFocused||i.focus()}}setActiveItemClass(e){let t=this,i=t.control.querySelector(".last-active");i&>(i,"last-active"),Pe(e,"active last-active"),t.trigger("item_select",e),t.activeItems.indexOf(e)==-1&&t.activeItems.push(e)}removeActiveItem(e){var t=this.activeItems.indexOf(e);this.activeItems.splice(t,1),gt(e,"active")}clearActiveItems(){gt(this.activeItems,"active"),this.activeItems=[]}setActiveOption(e,t=!0){e!==this.activeOption&&(this.clearActiveOption(),e&&(this.activeOption=e,le(this.focus_node,{"aria-activedescendant":e.getAttribute("id")}),le(e,{"aria-selected":"true"}),Pe(e,"active"),t&&this.scrollToOption(e)))}scrollToOption(e,t){if(!e)return;let i=this.dropdown_content,r=i.clientHeight,o=i.scrollTop||0,s=e.offsetHeight,a=e.getBoundingClientRect().top-i.getBoundingClientRect().top+o;a+s>r+o?this.scroll(a-r+s,t):a{e.setActiveItemClass(i)}))}inputState(){var e=this;e.control.contains(e.control_input)&&(le(e.control_input,{placeholder:e.settings.placeholder}),e.activeItems.length>0||!e.isFocused&&e.settings.hidePlaceholder&&e.items.length>0?(e.setTextboxValue(),e.isInputHidden=!0):(e.settings.hidePlaceholder&&e.items.length>0&&le(e.control_input,{placeholder:""}),e.isInputHidden=!1),e.wrapper.classList.toggle("input-hidden",e.isInputHidden))}inputValue(){return this.control_input.value.trim()}focus(){var e=this;e.isDisabled||e.isReadOnly||(e.ignoreFocus=!0,e.control_input.offsetWidth?e.control_input.focus():e.focus_node.focus(),setTimeout(()=>{e.ignoreFocus=!1,e.onFocus()},0))}blur(){this.focus_node.blur(),this.onBlur()}getScoreFunction(e){return this.sifter.getScoreFunction(e,this.getSearchOptions())}getSearchOptions(){var e=this.settings,t=e.sortField;return typeof e.sortField=="string"&&(t=[{field:e.sortField}]),{fields:e.searchField,conjunction:e.searchConjunction,sort:t,nesting:e.nesting}}search(e){var t,i,r=this,o=this.getSearchOptions();if(r.settings.score&&(i=r.settings.score.call(r,e),typeof i!="function"))throw new Error('Tom Select "score" setting must be a function that returns a function');return e!==r.lastQuery?(r.lastQuery=e,t=r.sifter.search(e,Object.assign(o,{score:i})),r.currentResults=t):t=Object.assign({},r.currentResults),r.settings.hideSelected&&(t.items=t.items.filter(s=>{let a=We(s.id);return!(a&&r.items.indexOf(a)!==-1)})),t}refreshOptions(e=!0){var t,i,r,o,s,a,l,c,u,d;let p={},y=[];var m=this,v=m.inputValue();let w=v===m.lastQuery||v==""&&m.lastQuery==null;var T=m.search(v),_=null,S=m.settings.shouldOpen||!1,A=m.dropdown_content;w&&(_=m.activeOption,_&&(u=_.closest("[data-group]"))),o=T.items.length,typeof m.settings.maxOptions=="number"&&(o=Math.min(o,m.settings.maxOptions)),o>0&&(S=!0);let K=(L,H)=>{let N=p[L];if(N!==void 0){let B=y[N];if(B!==void 0)return[N,B.fragment]}let Y=document.createDocumentFragment();return N=y.length,y.push({fragment:Y,order:H,optgroup:L}),[N,Y]};for(t=0;t0&&(B=B.cloneNode(!0),le(B,{id:N.$id+"-clone-"+i,"aria-selected":null}),B.classList.add("ts-cloned"),gt(B,"active"),m.activeOption&&m.activeOption.dataset.value==H&&u&&u.dataset.group===s.toString()&&(_=B)),Ce.appendChild(B),s!=""&&(p[s]=Te)}}m.settings.lockOptgroupOrder&&y.sort((L,H)=>L.order-H.order),l=document.createDocumentFragment(),ve(y,L=>{let H=L.fragment,N=L.optgroup;if(!H||!H.children.length)return;let Y=m.optgroups[N];if(Y!==void 0){let B=document.createDocumentFragment(),ie=m.render("optgroup_header",Y);Nt(B,ie),Nt(B,H);let J=m.render("optgroup",{group:Y,options:B});Nt(l,J)}else Nt(l,H)}),A.innerHTML="",Nt(A,l),m.settings.highlight&&(Za(A),T.query.length&&T.tokens.length&&ve(T.tokens,L=>{Ja(A,L.regex)}));var z=L=>{let H=m.render(L,{input:v});return H&&(S=!0,A.insertBefore(H,A.firstChild)),H};if(m.loading?z("loading"):m.settings.shouldLoad.call(m,v)?T.items.length===0&&z("no_results"):z("not_loading"),c=m.canCreate(v),c&&(d=z("option_create")),m.hasOptions=T.items.length>0||c,S){if(T.items.length>0){if(!_&&m.settings.mode==="single"&&m.items[0]!=null&&(_=m.getOption(m.items[0])),!A.contains(_)){let L=0;d&&!m.settings.addPrecedence&&(L=1),_=m.selectable()[L]}}else d&&(_=d);e&&!m.isOpen&&(m.open(),m.scrollToOption(_,"auto")),m.setActiveOption(_)}else m.clearActiveOption(),e&&m.isOpen&&m.close(!1)}selectable(){return this.dropdown_content.querySelectorAll("[data-selectable]")}addOption(e,t=!1){let i=this;if(Array.isArray(e))return i.addOptions(e,t),!1;let r=We(e[i.settings.valueField]);return r===null||i.options.hasOwnProperty(r)?!1:(e.$order=e.$order||++i.order,e.$id=i.inputId+"-opt-"+e.$order,i.options[r]=e,i.lastQuery=null,t&&(i.userOptions[r]=t,i.trigger("option_add",r,e)),r)}addOptions(e,t=!1){ve(e,i=>{this.addOption(i,t)})}registerOption(e){return this.addOption(e)}registerOptionGroup(e){var t=We(e[this.settings.optgroupValueField]);return t===null?!1:(e.$order=e.$order||++this.order,this.optgroups[t]=e,t)}addOptionGroup(e,t){var i;t[this.settings.optgroupValueField]=e,(i=this.registerOptionGroup(t))&&this.trigger("optgroup_add",i,t)}removeOptionGroup(e){this.optgroups.hasOwnProperty(e)&&(delete this.optgroups[e],this.clearCache(),this.trigger("optgroup_remove",e))}clearOptionGroups(){this.optgroups={},this.clearCache(),this.trigger("optgroup_clear")}updateOption(e,t){let i=this;var r,o;let s=We(e),a=We(t[i.settings.valueField]);if(s===null)return;let l=i.options[s];if(l==null)return;if(typeof a!="string")throw new Error("Value must be set in option data");let c=i.getOption(s),u=i.getItem(s);if(t.$order=t.$order||l.$order,delete i.options[s],i.uncacheValue(a),i.options[a]=t,c){if(i.dropdown_content.contains(c)){let d=i._render("option",t);di(c,d),i.activeOption===c&&i.setActiveOption(d)}c.remove()}u&&(o=i.items.indexOf(s),o!==-1&&i.items.splice(o,1,a),r=i._render("item",t),u.classList.contains("active")&&Pe(r,"active"),di(u,r)),i.lastQuery=null}removeOption(e,t){let i=this;e=ci(e),i.uncacheValue(e),delete i.userOptions[e],delete i.options[e],i.lastQuery=null,i.trigger("option_remove",e),i.removeItem(e,t)}clearOptions(e){let t=(e||this.clearFilter).bind(this);this.loadedSearches={},this.userOptions={},this.clearCache();let i={};ve(this.options,(r,o)=>{t(r,o)&&(i[o]=r)}),this.options=this.sifter.items=i,this.lastQuery=null,this.trigger("option_clear")}clearFilter(e,t){return this.items.indexOf(t)>=0}getOption(e,t=!1){let i=We(e);if(i===null)return null;let r=this.options[i];if(r!=null){if(r.$div)return r.$div;if(t)return this._render("option",r)}return null}getAdjacent(e,t,i="option"){var r=this,o;if(!e)return null;i=="item"?o=r.controlChildren():o=r.dropdown_content.querySelectorAll("[data-selectable]");for(let s=0;s0?o[s+1]:o[s-1];return null}getItem(e){if(typeof e=="object")return e;var t=We(e);return t!==null?this.control.querySelector(`[data-value="${Bo(t)}"]`):null}addItems(e,t){var i=this,r=Array.isArray(e)?e:[e];r=r.filter(s=>i.items.indexOf(s)===-1);let o=r[r.length-1];r.forEach(s=>{i.isPending=s!==o,i.addItem(s,t)})}addItem(e,t){var i=t?[]:["change","dropdown_close"];Fo(this,i,()=>{var r,o;let s=this,a=s.settings.mode,l=We(e);if(!(l&&s.items.indexOf(l)!==-1&&(a==="single"&&s.close(),a==="single"||!s.settings.duplicates))&&!(l===null||!s.options.hasOwnProperty(l))&&(a==="single"&&s.clear(t),!(a==="multi"&&s.isFull()))){if(r=s._render("item",s.options[l]),s.control.contains(r)&&(r=r.cloneNode(!0)),o=s.isFull(),s.items.splice(s.caretPos,0,l),s.insertAtCaret(r),s.isSetup){if(!s.isPending&&s.settings.hideSelected){let c=s.getOption(l),u=s.getAdjacent(c,1);u&&s.setActiveOption(u)}!s.isPending&&!s.settings.closeAfterSelect&&s.refreshOptions(s.isFocused&&a!=="single"),s.settings.closeAfterSelect!=!1&&s.isFull()?s.close():s.isPending||s.positionDropdown(),s.trigger("item_add",l,r),s.isPending||s.updateOriginalInput({silent:t})}(!s.isPending||!o&&s.isFull())&&(s.inputState(),s.refreshState())}})}removeItem(e=null,t){let i=this;if(e=i.getItem(e),!e)return;var r,o;let s=e.dataset.value;r=zo(e),e.remove(),e.classList.contains("active")&&(o=i.activeItems.indexOf(e),i.activeItems.splice(o,1),gt(e,"active")),i.items.splice(r,1),i.lastQuery=null,!i.settings.persist&&i.userOptions.hasOwnProperty(s)&&i.removeOption(s,t),r{}){arguments.length===3&&(t=arguments[2]),typeof t!="function"&&(t=()=>{});var i=this,r=i.caretPos,o;if(e=e||i.inputValue(),!i.canCreate(e))return t(),!1;i.lock();var s=!1,a=l=>{if(i.unlock(),!l||typeof l!="object")return t();var c=We(l[i.settings.valueField]);if(typeof c!="string")return t();i.setTextboxValue(),i.addOption(l,!0),i.setCaret(r),i.addItem(c),t(l),s=!0};return typeof i.settings.create=="function"?o=i.settings.create.call(this,e,a):o={[i.settings.labelField]:e,[i.settings.valueField]:e},s||a(o),!0}refreshItems(){var e=this;e.lastQuery=null,e.isSetup&&e.addItems(e.items),e.updateOriginalInput(),e.refreshState()}refreshState(){let e=this;e.refreshValidityState();let t=e.isFull(),i=e.isLocked;e.wrapper.classList.toggle("rtl",e.rtl);let r=e.wrapper.classList;r.toggle("focus",e.isFocused),r.toggle("disabled",e.isDisabled),r.toggle("readonly",e.isReadOnly),r.toggle("required",e.isRequired),r.toggle("invalid",!e.isValid),r.toggle("locked",i),r.toggle("full",t),r.toggle("input-active",e.isFocused&&!e.isInputHidden),r.toggle("dropdown-active",e.isOpen),r.toggle("has-options",Qa(e.options)),r.toggle("has-items",e.items.length>0)}refreshValidityState(){var e=this;e.input.validity&&(e.isValid=e.input.validity.valid,e.isInvalid=!e.isValid)}isFull(){return this.settings.maxItems!==null&&this.items.length>=this.settings.maxItems}updateOriginalInput(e={}){let t=this;var i,r;let o=t.input.querySelector('option[value=""]');if(t.is_select_tag){let l=function(c,u,d){return c||(c=nt('")),c!=o&&t.input.append(c),s.push(c),(c!=o||a>0)&&(c.selected=!0),c},s=[],a=t.input.querySelectorAll("option:checked").length;t.input.querySelectorAll("option:checked").forEach(c=>{c.selected=!1}),t.items.length==0&&t.settings.mode=="single"?l(o,"",""):t.items.forEach(c=>{if(i=t.options[c],r=i[t.settings.labelField]||"",s.includes(i.$option)){let u=t.input.querySelector(`option[value="${Bo(c)}"]:not(:checked)`);l(u,c,r)}else i.$option=l(i.$option,c,r)})}else t.input.value=t.getValue();t.isSetup&&(e.silent||t.trigger("change",t.getValue()))}open(){var e=this;e.isLocked||e.isOpen||e.settings.mode==="multi"&&e.isFull()||(e.isOpen=!0,le(e.focus_node,{"aria-expanded":"true"}),e.refreshState(),ui(e.dropdown,{visibility:"hidden",display:"block"}),e.positionDropdown(),ui(e.dropdown,{visibility:"visible",display:"block"}),e.focus(),e.trigger("dropdown_open",e.dropdown))}close(e=!0){var t=this,i=t.isOpen;e&&(t.setTextboxValue(),t.settings.mode==="single"&&t.items.length&&t.inputState()),t.isOpen=!1,le(t.focus_node,{"aria-expanded":"false"}),ui(t.dropdown,{display:"none"}),t.settings.hideSelected&&t.clearActiveOption(),t.refreshState(),i&&t.trigger("dropdown_close",t.dropdown)}positionDropdown(){if(this.settings.dropdownParent==="body"){var e=this.control,t=e.getBoundingClientRect(),i=e.offsetHeight+t.top+window.scrollY,r=t.left+window.scrollX;ui(this.dropdown,{width:t.width+"px",top:i+"px",left:r+"px"})}}clear(e){var t=this;if(t.items.length){var i=t.controlChildren();ve(i,r=>{t.removeItem(r,!0)}),t.inputState(),e||t.updateOriginalInput(),t.trigger("clear")}}insertAtCaret(e){let t=this,i=t.caretPos,r=t.control;r.insertBefore(e,r.children[i]||null),t.setCaret(i+1)}deleteSelection(e){var t,i,r,o,s=this;t=e&&e.keyCode===8?-1:1,i=Ya(s.control_input);let a=[];if(s.activeItems.length)o=Vo(s.activeItems,t),r=zo(o),t>0&&r++,ve(s.activeItems,l=>a.push(l));else if((s.isFocused||s.settings.mode==="single")&&s.items.length){let l=s.controlChildren(),c;t<0&&i.start===0&&i.length===0?c=l[s.caretPos-1]:t>0&&i.start===s.inputValue().length&&(c=l[s.caretPos]),c!==void 0&&a.push(c)}if(!s.shouldDelete(a,e))return!1;for(fe(e,!0),typeof r!="undefined"&&s.setCaret(r);a.length;)s.removeItem(a.pop());return s.inputState(),s.positionDropdown(),s.refreshOptions(!1),!0}shouldDelete(e,t){let i=e.map(r=>r.dataset.value);return!(!i.length||typeof this.settings.onDelete=="function"&&this.settings.onDelete(i,t)===!1)}advanceSelection(e,t){var i,r,o=this;o.rtl&&(e*=-1),!o.inputValue().length&&(kt(fi,t)||kt("shiftKey",t)?(i=o.getLastActive(e),i?i.classList.contains("active")?r=o.getAdjacent(i,e,"item"):r=i:e>0?r=o.control_input.nextElementSibling:r=o.control_input.previousElementSibling,r&&(r.classList.contains("active")&&o.removeActiveItem(i),o.setActiveItemClass(r))):o.moveCaret(e))}moveCaret(e){}getLastActive(e){let t=this.control.querySelector(".last-active");if(t)return t;var i=this.control.querySelectorAll(".active");if(i)return Vo(i,e)}setCaret(e){this.caretPos=this.items.length}controlChildren(){return Array.from(this.control.querySelectorAll("[data-ts-item]"))}lock(){this.setLocked(!0)}unlock(){this.setLocked(!1)}setLocked(e=this.isReadOnly||this.isDisabled){this.isLocked=e,this.refreshState()}disable(){this.setDisabled(!0),this.close()}enable(){this.setDisabled(!1)}setDisabled(e){this.focus_node.tabIndex=e?-1:this.tabIndex,this.isDisabled=e,this.input.disabled=e,this.control_input.disabled=e,this.setLocked()}setReadOnly(e){this.isReadOnly=e,this.input.readOnly=e,this.control_input.readOnly=e,this.setLocked()}destroy(){var e=this,t=e.revertSettings;e.trigger("destroy"),e.off(),e.wrapper.remove(),e.dropdown.remove(),e.input.innerHTML=t.innerHTML,e.input.tabIndex=t.tabIndex,gt(e.input,"tomselected","ts-hidden-accessible"),e._destroy(),delete e.input.tomselect}render(e,t){var i,r;let o=this;if(typeof this.settings.render[e]!="function"||(r=o.settings.render[e].call(this,t,ur),!r))return null;if(r=nt(r),e==="option"||e==="option_create"?t[o.settings.disabledField]?le(r,{"aria-disabled":"true"}):le(r,{"data-selectable":""}):e==="optgroup"&&(i=t.group[o.settings.optgroupValueField],le(r,{"data-group":i}),t.group[o.settings.disabledField]&&le(r,{"data-disabled":""})),e==="option"||e==="item"){let s=ci(t[o.settings.valueField]);le(r,{"data-value":s}),e==="item"?(Pe(r,o.settings.itemClass),le(r,{"data-ts-item":""})):(Pe(r,o.settings.optionClass),le(r,{role:"option",id:t.$id}),t.$div=r,o.options[s]=t)}return r}_render(e,t){let i=this.render(e,t);if(i==null)throw"HTMLElement expected";return i}clearCache(){ve(this.options,e=>{e.$div&&(e.$div.remove(),delete e.$div)})}uncacheValue(e){let t=this.getOption(e);t&&t.remove()}canCreate(e){return this.settings.create&&e.length>0&&this.settings.createFilter.call(this,e)}hook(e,t,i){var r=this,o=r[t];r[t]=function(){var s,a;return e==="after"&&(s=o.apply(r,arguments)),a=i.apply(r,arguments),e==="instead"?a:(e==="before"&&(s=o.apply(r,arguments)),s)}}};var wm=(n,e,t,i)=>{n.addEventListener(e,t,i)};function il(){wm(this.input,"change",()=>{this.sync()})}var xm=n=>typeof n=="undefined"||n===null?null:Tm(n),Tm=n=>typeof n=="boolean"?n?"1":"0":n+"",rl=(n,e=!1)=>{n&&(n.preventDefault(),e&&n.stopPropagation())},Cm=n=>{if(n.jquery)return n[0];if(n instanceof HTMLElement)return n;if(Am(n)){var e=document.createElement("template");return e.innerHTML=n.trim(),e.content.firstChild}return document.querySelector(n)},Am=n=>typeof n=="string"&&n.indexOf("<")>-1;function ol(n){var e=this,t=e.onOptionSelect;e.settings.hideSelected=!1;let i=Object.assign({className:"tomselect-checkbox",checkedClassNames:void 0,uncheckedClassNames:void 0},n);var r=function(a,l){l?(a.checked=!0,i.uncheckedClassNames&&a.classList.remove(...i.uncheckedClassNames),i.checkedClassNames&&a.classList.add(...i.checkedClassNames)):(a.checked=!1,i.checkedClassNames&&a.classList.remove(...i.checkedClassNames),i.uncheckedClassNames&&a.classList.add(...i.uncheckedClassNames))},o=function(a){setTimeout(()=>{var l=a.querySelector("input."+i.className);l instanceof HTMLInputElement&&r(l,a.classList.contains("selected"))},1)};e.hook("after","setupTemplates",()=>{var s=e.settings.render.option;e.settings.render.option=(a,l)=>{var c=Cm(s.call(e,a,l)),u=document.createElement("input");i.className&&u.classList.add(i.className),u.addEventListener("click",function(p){rl(p)}),u.type="checkbox";let d=xm(a[e.settings.valueField]);return r(u,!!(d&&e.items.indexOf(d)>-1)),c.prepend(u),c}}),e.on("item_remove",s=>{var a=e.getOption(s);a&&(a.classList.remove("selected"),o(a))}),e.on("item_add",s=>{var a=e.getOption(s);a&&o(a)}),e.hook("instead","onOptionSelect",(s,a)=>{if(a.classList.contains("selected")){a.classList.remove("selected"),e.removeItem(a.dataset.value),e.refreshOptions(),rl(s,!0);return}t.call(e,s,a),o(a)})}var Sm=n=>{if(n.jquery)return n[0];if(n instanceof HTMLElement)return n;if(Dm(n)){var e=document.createElement("template");return e.innerHTML=n.trim(),e.content.firstChild}return document.querySelector(n)},Dm=n=>typeof n=="string"&&n.indexOf("<")>-1;function sl(n){let e=this,t=Object.assign({className:"clear-button",title:"Clear All",html:i=>`
`},n);e.on("initialize",()=>{var i=Sm(t.html(t));i.addEventListener("click",r=>{e.isLocked||(e.clear(),e.settings.mode==="single"&&e.settings.allowEmptyOption&&e.addItem(""),r.preventDefault(),r.stopPropagation())}),e.control.appendChild(i)})}var Om=(n,e=!1)=>{n&&(n.preventDefault(),e&&n.stopPropagation())},Dn=(n,e,t,i)=>{n.addEventListener(e,t,i)},Lm=(n,e)=>{if(Array.isArray(n))n.forEach(e);else for(var t in n)n.hasOwnProperty(t)&&e(n[t],t)},Mm=n=>{if(n.jquery)return n[0];if(n instanceof HTMLElement)return n;if(km(n)){var e=document.createElement("template");return e.innerHTML=n.trim(),e.content.firstChild}return document.querySelector(n)},km=n=>typeof n=="string"&&n.indexOf("<")>-1,Nm=(n,e)=>{Lm(e,(t,i)=>{t==null?n.removeAttribute(i):n.setAttribute(i,""+t)})},Im=(n,e)=>{var t;(t=n.parentNode)==null||t.insertBefore(e,n.nextSibling)},Rm=(n,e)=>{var t;(t=n.parentNode)==null||t.insertBefore(e,n)},Hm=(n,e)=>{do{var t;if(e=(t=e)==null?void 0:t.previousElementSibling,n==e)return!0}while(e&&e.previousElementSibling);return!1};function al(){var n=this;if(n.settings.mode!=="multi")return;var e=n.lock,t=n.unlock;let i=!0,r;n.hook("after","setupTemplates",()=>{var o=n.settings.render.item;n.settings.render.item=(s,a)=>{let l=Mm(o.call(n,s,a));Nm(l,{draggable:"true"});let c=v=>{i||Om(v),v.stopPropagation()},u=v=>{r=l,setTimeout(()=>{l.classList.add("ts-dragging")},0)},d=v=>{v.preventDefault(),l.classList.add("ts-drag-over"),y(l,r)},p=()=>{l.classList.remove("ts-drag-over")},y=(v,w)=>{w!==void 0&&(Hm(w,l)?Im(v,w):Rm(v,w))},m=()=>{var v;document.querySelectorAll(".ts-drag-over").forEach(T=>T.classList.remove("ts-drag-over")),(v=r)==null||v.classList.remove("ts-dragging"),r=void 0;var w=[];n.control.querySelectorAll("[data-value]").forEach(T=>{if(T.dataset.value){let _=T.dataset.value;_&&w.push(_)}}),n.setValue(w)};return Dn(l,"mousedown",c),Dn(l,"dragstart",u),Dn(l,"dragenter",d),Dn(l,"dragover",d),Dn(l,"dragleave",p),Dn(l,"dragend",m),l}}),n.hook("instead","lock",()=>(i=!1,e.call(n))),n.hook("instead","unlock",()=>(i=!0,t.call(n)))}var Pm=(n,e=!1)=>{n&&(n.preventDefault(),e&&n.stopPropagation())},Fm=n=>{if(n.jquery)return n[0];if(n instanceof HTMLElement)return n;if(Bm(n)){var e=document.createElement("template");return e.innerHTML=n.trim(),e.content.firstChild}return document.querySelector(n)},Bm=n=>typeof n=="string"&&n.indexOf("<")>-1;function ll(n){let e=this,t=Object.assign({title:"Untitled",headerClass:"dropdown-header",titleRowClass:"dropdown-header-title",labelClass:"dropdown-header-label",closeClass:"dropdown-header-close",html:i=>'
'+i.title+'×
'},n);e.on("initialize",()=>{var i=Fm(t.html(t)),r=i.querySelector("."+t.closeClass);r&&r.addEventListener("click",o=>{Pm(o,!0),e.close()}),e.dropdown.insertBefore(i,e.dropdown.firstChild)})}var $m=(n,e)=>{if(Array.isArray(n))n.forEach(e);else for(var t in n)n.hasOwnProperty(t)&&e(n[t],t)},Vm=(n,...e)=>{var t=zm(e);n=jm(n),n.map(i=>{t.map(r=>{i.classList.remove(r)})})},zm=n=>{var e=[];return $m(n,t=>{typeof t=="string"&&(t=t.trim().split(/[\t\n\f\r\s]/)),Array.isArray(t)&&(e=e.concat(t))}),e.filter(Boolean)},jm=n=>(Array.isArray(n)||(n=[n]),n),Wm=(n,e)=>{if(!n)return-1;e=e||n.nodeName;for(var t=0;n=n.previousElementSibling;)n.matches(e)&&t++;return t};function cl(){var n=this;n.hook("instead","setCaret",e=>{n.settings.mode==="single"||!n.control.contains(n.control_input)?e=n.items.length:(e=Math.max(0,Math.min(n.items.length,e)),e!=n.caretPos&&!n.isPending&&n.controlChildren().forEach((t,i)=>{i{if(!n.isFocused)return;let t=n.getLastActive(e);if(t){let i=Wm(t);n.setCaret(e>0?i+1:i),n.setActiveItem(),Vm(t,"last-active")}else n.setCaret(n.caretPos+e)})}var qm=(n,e=!1)=>{n&&(n.preventDefault(),e&&n.stopPropagation())},Um=(n,e,t,i)=>{n.addEventListener(e,t,i)},Ym=(n,e)=>{if(Array.isArray(n))n.forEach(e);else for(var t in n)n.hasOwnProperty(t)&&e(n[t],t)},ul=n=>{if(n.jquery)return n[0];if(n instanceof HTMLElement)return n;if(Gm(n)){var e=document.createElement("template");return e.innerHTML=n.trim(),e.content.firstChild}return document.querySelector(n)},Gm=n=>typeof n=="string"&&n.indexOf("<")>-1,Km=(n,...e)=>{var t=Xm(e);n=Qm(n),n.map(i=>{t.map(r=>{i.classList.add(r)})})},Xm=n=>{var e=[];return Ym(n,t=>{typeof t=="string"&&(t=t.trim().split(/[\t\n\f\r\s]/)),Array.isArray(t)&&(e=e.concat(t))}),e.filter(Boolean)},Qm=n=>(Array.isArray(n)||(n=[n]),n);function dl(){let n=this;n.settings.shouldOpen=!0,n.hook("before","setup",()=>{n.focus_node=n.control,Km(n.control_input,"dropdown-input");let e=ul('