netbox-super-cli 1.1.0__tar.gz → 1.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/.pre-commit-config.yaml +1 -0
  2. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/CHANGELOG.md +44 -0
  3. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/PKG-INFO +23 -1
  4. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/README.md +21 -0
  5. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/architecture/http-client.md +8 -5
  6. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/architecture/schema-loading.md +5 -1
  7. netbox_super_cli-1.2.0/docs/assets/tui/detail.svg +190 -0
  8. netbox_super_cli-1.2.0/docs/assets/tui/filter.svg +199 -0
  9. netbox_super_cli-1.2.0/docs/assets/tui/list.svg +185 -0
  10. netbox_super_cli-1.2.0/docs/assets/tui/picker.svg +188 -0
  11. netbox_super_cli-1.2.0/docs/assets/tui/search.svg +192 -0
  12. netbox_super_cli-1.2.0/docs/guides/interactive-tui.md +197 -0
  13. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/guides/writes-and-safety.md +9 -1
  14. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/index.md +1 -0
  15. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/mkdocs.yml +1 -0
  16. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/_version.py +1 -1
  17. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/builder/build.py +1 -1
  18. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/app.py +2 -0
  19. netbox_super_cli-1.2.0/nsc/cli/tui_commands.py +69 -0
  20. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/schema/models.py +19 -1
  21. netbox_super_cli-1.2.0/nsc/tui/__init__.py +30 -0
  22. netbox_super_cli-1.2.0/nsc/tui/_bindings.py +17 -0
  23. netbox_super_cli-1.2.0/nsc/tui/app.py +109 -0
  24. netbox_super_cli-1.2.0/nsc/tui/bulk.py +113 -0
  25. netbox_super_cli-1.2.0/nsc/tui/catalog.py +51 -0
  26. netbox_super_cli-1.2.0/nsc/tui/columns.py +62 -0
  27. netbox_super_cli-1.2.0/nsc/tui/errors.py +44 -0
  28. netbox_super_cli-1.2.0/nsc/tui/filters.py +130 -0
  29. netbox_super_cli-1.2.0/nsc/tui/fk.py +128 -0
  30. netbox_super_cli-1.2.0/nsc/tui/forms.py +111 -0
  31. netbox_super_cli-1.2.0/nsc/tui/keymap.py +87 -0
  32. netbox_super_cli-1.2.0/nsc/tui/nav.py +21 -0
  33. netbox_super_cli-1.2.0/nsc/tui/relations.py +65 -0
  34. netbox_super_cli-1.2.0/nsc/tui/screens/bulk_edit_form.py +238 -0
  35. netbox_super_cli-1.2.0/nsc/tui/screens/columns.py +76 -0
  36. netbox_super_cli-1.2.0/nsc/tui/screens/detail.py +371 -0
  37. netbox_super_cli-1.2.0/nsc/tui/screens/edit_form.py +248 -0
  38. netbox_super_cli-1.2.0/nsc/tui/screens/filter.py +252 -0
  39. netbox_super_cli-1.2.0/nsc/tui/screens/global_search.py +175 -0
  40. netbox_super_cli-1.2.0/nsc/tui/screens/list.py +290 -0
  41. netbox_super_cli-1.2.0/nsc/tui/screens/picker.py +102 -0
  42. netbox_super_cli-1.2.0/nsc/tui/screens/record_picker.py +116 -0
  43. netbox_super_cli-1.2.0/nsc/tui/search.py +65 -0
  44. netbox_super_cli-1.2.0/nsc/tui/selection.py +37 -0
  45. netbox_super_cli-1.2.0/nsc/tui/styles.tcss +169 -0
  46. netbox_super_cli-1.2.0/nsc/tui/view.py +46 -0
  47. netbox_super_cli-1.2.0/nsc/tui/widgets/_modal.py +40 -0
  48. netbox_super_cli-1.2.0/nsc/tui/widgets/bulk_diff.py +43 -0
  49. netbox_super_cli-1.2.0/nsc/tui/widgets/bulk_summary.py +56 -0
  50. netbox_super_cli-1.2.0/nsc/tui/widgets/confirm.py +22 -0
  51. netbox_super_cli-1.2.0/nsc/tui/widgets/diff.py +36 -0
  52. netbox_super_cli-1.2.0/nsc/tui/widgets/help.py +66 -0
  53. netbox_super_cli-1.2.0/nsc/tui/widgets/nav_tree.py +34 -0
  54. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/pyproject.toml +4 -1
  55. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/skills/netbox-super-cli/SKILL.md +3 -0
  56. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/builder/test_request_body_shape.py +32 -0
  57. netbox_super_cli-1.2.0/tests/cli/test_lazy_textual_import.py +59 -0
  58. netbox_super_cli-1.2.0/tests/cli/test_tui_command.py +111 -0
  59. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/schema/test_models.py +24 -1
  60. netbox_super_cli-1.2.0/tests/scripts/__init__.py +0 -0
  61. netbox_super_cli-1.2.0/tests/skill/__init__.py +0 -0
  62. netbox_super_cli-1.2.0/tests/tui/__init__.py +0 -0
  63. netbox_super_cli-1.2.0/tests/tui/test_app.py +137 -0
  64. netbox_super_cli-1.2.0/tests/tui/test_bindings.py +12 -0
  65. netbox_super_cli-1.2.0/tests/tui/test_bulk_apply.py +122 -0
  66. netbox_super_cli-1.2.0/tests/tui/test_bulk_diff.py +109 -0
  67. netbox_super_cli-1.2.0/tests/tui/test_bulk_diff_modal.py +242 -0
  68. netbox_super_cli-1.2.0/tests/tui/test_bulk_edit_form.py +576 -0
  69. netbox_super_cli-1.2.0/tests/tui/test_bulk_import_isolation.py +44 -0
  70. netbox_super_cli-1.2.0/tests/tui/test_bulk_summary.py +47 -0
  71. netbox_super_cli-1.2.0/tests/tui/test_catalog.py +99 -0
  72. netbox_super_cli-1.2.0/tests/tui/test_column_chooser.py +117 -0
  73. netbox_super_cli-1.2.0/tests/tui/test_columns.py +50 -0
  74. netbox_super_cli-1.2.0/tests/tui/test_detail_screen.py +543 -0
  75. netbox_super_cli-1.2.0/tests/tui/test_diff.py +99 -0
  76. netbox_super_cli-1.2.0/tests/tui/test_diff_modal.py +96 -0
  77. netbox_super_cli-1.2.0/tests/tui/test_edit_form.py +555 -0
  78. netbox_super_cli-1.2.0/tests/tui/test_errors.py +29 -0
  79. netbox_super_cli-1.2.0/tests/tui/test_filter_screen.py +373 -0
  80. netbox_super_cli-1.2.0/tests/tui/test_filters.py +139 -0
  81. netbox_super_cli-1.2.0/tests/tui/test_fk_resolve.py +130 -0
  82. netbox_super_cli-1.2.0/tests/tui/test_forms.py +90 -0
  83. netbox_super_cli-1.2.0/tests/tui/test_global_search.py +193 -0
  84. netbox_super_cli-1.2.0/tests/tui/test_help_overlay.py +97 -0
  85. netbox_super_cli-1.2.0/tests/tui/test_keymap.py +197 -0
  86. netbox_super_cli-1.2.0/tests/tui/test_list_screen.py +696 -0
  87. netbox_super_cli-1.2.0/tests/tui/test_picker.py +158 -0
  88. netbox_super_cli-1.2.0/tests/tui/test_record_picker.py +223 -0
  89. netbox_super_cli-1.2.0/tests/tui/test_relations.py +138 -0
  90. netbox_super_cli-1.2.0/tests/tui/test_search.py +69 -0
  91. netbox_super_cli-1.2.0/tests/tui/test_selection.py +99 -0
  92. netbox_super_cli-1.2.0/tests/tui/test_view.py +27 -0
  93. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/uv.lock +73 -1
  94. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/.github/workflows/bench.yml +0 -0
  95. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/.github/workflows/claude.yml +0 -0
  96. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/.github/workflows/docs.yml +0 -0
  97. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/.github/workflows/e2e.yml +0 -0
  98. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/.github/workflows/lint.yml +0 -0
  99. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/.github/workflows/release.yml +0 -0
  100. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/.github/workflows/test.yml +0 -0
  101. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/.gitignore +0 -0
  102. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/.python-version +0 -0
  103. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/AGENTS.md +0 -0
  104. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/CLAUDE.md +0 -0
  105. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/LICENSE +0 -0
  106. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/architecture/caching.md +0 -0
  107. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/architecture/command-generation.md +0 -0
  108. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/architecture/overview.md +0 -0
  109. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/contributing/adding-bundled-schemas.md +0 -0
  110. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/contributing/branching.md +0 -0
  111. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/contributing/development.md +0 -0
  112. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/contributing/release-process.md +0 -0
  113. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/getting-started/concepts.md +0 -0
  114. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/getting-started/first-run.md +0 -0
  115. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/getting-started/install.md +0 -0
  116. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/guides/ci-and-automation.md +0 -0
  117. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/guides/managing-profiles.md +0 -0
  118. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/guides/output-formats.md +0 -0
  119. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/guides/using-with-ai-agents.md +0 -0
  120. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/guides/working-with-plugins.md +0 -0
  121. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/reference/cli.md +0 -0
  122. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/reference/config.md +0 -0
  123. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/reference/exit-codes.md +0 -0
  124. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/docs/reference/schemas.md +0 -0
  125. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/justfile +0 -0
  126. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/__init__.py +0 -0
  127. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/__main__.py +0 -0
  128. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/aliases/__init__.py +0 -0
  129. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/aliases/resolver.py +0 -0
  130. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/auth/__init__.py +0 -0
  131. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/auth/verify.py +0 -0
  132. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/builder/__init__.py +0 -0
  133. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cache/__init__.py +0 -0
  134. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cache/store.py +0 -0
  135. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/__init__.py +0 -0
  136. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/aliases_commands.py +0 -0
  137. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/cache_commands.py +0 -0
  138. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/commands_dump.py +0 -0
  139. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/config_commands.py +0 -0
  140. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/globals.py +0 -0
  141. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/handlers.py +0 -0
  142. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/init_commands.py +0 -0
  143. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/login_commands.py +0 -0
  144. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/profiles_commands.py +0 -0
  145. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/registration.py +0 -0
  146. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/runtime.py +0 -0
  147. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/skill_commands.py +0 -0
  148. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/writes/__init__.py +0 -0
  149. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/writes/apply.py +0 -0
  150. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/writes/bulk.py +0 -0
  151. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/writes/coercion.py +0 -0
  152. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/writes/confirmation.py +0 -0
  153. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/writes/input.py +0 -0
  154. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/cli/writes/preflight.py +0 -0
  155. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/config/__init__.py +0 -0
  156. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/config/loader.py +0 -0
  157. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/config/models.py +0 -0
  158. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/config/settings.py +0 -0
  159. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/config/writer.py +0 -0
  160. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/http/__init__.py +0 -0
  161. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/http/audit.py +0 -0
  162. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/http/client.py +0 -0
  163. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/http/errors.py +0 -0
  164. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/http/retry.py +0 -0
  165. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/model/__init__.py +0 -0
  166. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/model/command_model.py +0 -0
  167. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/output/__init__.py +0 -0
  168. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/output/_console.py +0 -0
  169. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/output/csv_.py +0 -0
  170. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/output/errors.py +0 -0
  171. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/output/explain.py +0 -0
  172. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/output/flatten.py +0 -0
  173. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/output/headers.py +0 -0
  174. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/output/json_.py +0 -0
  175. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/output/jsonl.py +0 -0
  176. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/output/render.py +0 -0
  177. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/output/table.py +0 -0
  178. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/output/yaml_.py +0 -0
  179. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/schema/__init__.py +0 -0
  180. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/schema/hashing.py +0 -0
  181. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/schema/loader.py +0 -0
  182. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/schema/source.py +0 -0
  183. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/schemas/__init__.py +0 -0
  184. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/schemas/bundled/__init__.py +0 -0
  185. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/schemas/bundled/manifest.yaml +0 -0
  186. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/schemas/bundled/netbox-4.5.10.json.gz +0 -0
  187. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/schemas/bundled/netbox-4.6.0.json.gz +0 -0
  188. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/nsc/skill/__init__.py +0 -0
  189. {netbox_super_cli-1.1.0/tests → netbox_super_cli-1.2.0/nsc/tui/screens}/__init__.py +0 -0
  190. {netbox_super_cli-1.1.0/tests/aliases → netbox_super_cli-1.2.0/nsc/tui/widgets}/__init__.py +0 -0
  191. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/scripts/gen_docs.py +0 -0
  192. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/scripts/sync_agents_md.py +0 -0
  193. {netbox_super_cli-1.1.0/tests/auth → netbox_super_cli-1.2.0/tests}/__init__.py +0 -0
  194. {netbox_super_cli-1.1.0/tests/benchmarks → netbox_super_cli-1.2.0/tests/aliases}/__init__.py +0 -0
  195. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/aliases/test_resolver.py +0 -0
  196. {netbox_super_cli-1.1.0/tests/builder → netbox_super_cli-1.2.0/tests/auth}/__init__.py +0 -0
  197. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/auth/test_verify.py +0 -0
  198. {netbox_super_cli-1.1.0/tests/cache → netbox_super_cli-1.2.0/tests/benchmarks}/__init__.py +0 -0
  199. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/benchmarks/test_startup.py +0 -0
  200. {netbox_super_cli-1.1.0/tests/cli → netbox_super_cli-1.2.0/tests/builder}/__init__.py +0 -0
  201. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/builder/test_build.py +0 -0
  202. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/builder/test_default_columns.py +0 -0
  203. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/builder/test_redaction_marking.py +0 -0
  204. {netbox_super_cli-1.1.0/tests/cli/writes → netbox_super_cli-1.2.0/tests/cache}/__init__.py +0 -0
  205. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cache/test_prune.py +0 -0
  206. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cache/test_store.py +0 -0
  207. {netbox_super_cli-1.1.0/tests/config → netbox_super_cli-1.2.0/tests/cli}/__init__.py +0 -0
  208. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_aliases_commands.py +0 -0
  209. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_app_smoke.py +0 -0
  210. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_cache_commands.py +0 -0
  211. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_commands_dump.py +0 -0
  212. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_completion_smoke.py +0 -0
  213. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_config_commands.py +0 -0
  214. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_explain.py +0 -0
  215. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_globals_color.py +0 -0
  216. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_handlers.py +0 -0
  217. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_init_commands.py +0 -0
  218. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_login_commands.py +0 -0
  219. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_meta_subcommands_under_broken_config.py +0 -0
  220. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_ndjson_input.py +0 -0
  221. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_profiles_commands.py +0 -0
  222. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_registration.py +0 -0
  223. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_respx_integration.py +0 -0
  224. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_runtime.py +0 -0
  225. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_runtime_color.py +0 -0
  226. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_skill_commands.py +0 -0
  227. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_stdin_sniffer.py +0 -0
  228. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/test_writes_respx.py +0 -0
  229. {netbox_super_cli-1.1.0/tests/http → netbox_super_cli-1.2.0/tests/cli/writes}/__init__.py +0 -0
  230. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/writes/test_apply.py +0 -0
  231. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/writes/test_bulk.py +0 -0
  232. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/writes/test_confirmation.py +0 -0
  233. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/writes/test_handler_helpers.py +0 -0
  234. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/writes/test_handlers_audit.py +0 -0
  235. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/writes/test_input.py +0 -0
  236. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/cli/writes/test_preflight.py +0 -0
  237. {netbox_super_cli-1.1.0/tests/model → netbox_super_cli-1.2.0/tests/config}/__init__.py +0 -0
  238. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/config/test_loader.py +0 -0
  239. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/config/test_models.py +0 -0
  240. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/config/test_writer_atomicity.py +0 -0
  241. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/config/test_writer_dotted_paths.py +0 -0
  242. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/config/test_writer_roundtrip.py +0 -0
  243. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/conftest.py +0 -0
  244. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/e2e/README.md +0 -0
  245. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/e2e/__init__.py +0 -0
  246. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/e2e/conftest.py +0 -0
  247. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/e2e/docker-compose.yml +0 -0
  248. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/e2e/test_audit_redaction.py +0 -0
  249. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/e2e/test_auth_error_envelope.py +0 -0
  250. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/e2e/test_bulk_create_with_loop_fallback.py +0 -0
  251. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/e2e/test_full_cycle.py +0 -0
  252. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/e2e/test_login.py +0 -0
  253. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/e2e/test_ndjson.py +0 -0
  254. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/e2e/test_preflight_blocks_apply.py +0 -0
  255. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/e2e/test_validation_error_envelope_from_netbox.py +0 -0
  256. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/e2e/wait_for_netbox.sh +0 -0
  257. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/fixtures/profiles/single_profile.yaml +0 -0
  258. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/fixtures/responses/auth_401.json +0 -0
  259. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/fixtures/responses/circuits_providers_list.json +0 -0
  260. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/fixtures/responses/dcim_devices_get.json +0 -0
  261. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/fixtures/responses/dcim_devices_list_p1.json +0 -0
  262. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/fixtures/responses/dcim_devices_list_p2.json +0 -0
  263. {netbox_super_cli-1.1.0/tests/output → netbox_super_cli-1.2.0/tests/http}/__init__.py +0 -0
  264. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/http/test_audit.py +0 -0
  265. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/http/test_audit_permissions.py +0 -0
  266. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/http/test_audit_redaction.py +0 -0
  267. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/http/test_client.py +0 -0
  268. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/http/test_client_redaction_threading.py +0 -0
  269. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/http/test_errors.py +0 -0
  270. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/http/test_retry.py +0 -0
  271. {netbox_super_cli-1.1.0/tests/schema → netbox_super_cli-1.2.0/tests/model}/__init__.py +0 -0
  272. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/model/test_command_model.py +0 -0
  273. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/model/test_request_body_shape.py +0 -0
  274. {netbox_super_cli-1.1.0/tests/scripts → netbox_super_cli-1.2.0/tests/output}/__init__.py +0 -0
  275. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_console.py +0 -0
  276. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_csv.py +0 -0
  277. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_errors.py +0 -0
  278. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_errors_aliases.py +0 -0
  279. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_errors_color.py +0 -0
  280. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_explain.py +0 -0
  281. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_explain_color.py +0 -0
  282. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_flatten.py +0 -0
  283. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_input_error_envelope.py +0 -0
  284. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_json.py +0 -0
  285. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_jsonl.py +0 -0
  286. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_render_dispatch.py +0 -0
  287. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_table.py +0 -0
  288. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_table_color.py +0 -0
  289. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/output/test_yaml.py +0 -0
  290. {netbox_super_cli-1.1.0/tests/skill → netbox_super_cli-1.2.0/tests/schema}/__init__.py +0 -0
  291. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/schema/test_hashing.py +0 -0
  292. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/schema/test_loader.py +0 -0
  293. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/schema/test_source.py +0 -0
  294. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/schema/test_source_ttl.py +0 -0
  295. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/scripts/test_gen_docs.py +0 -0
  296. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/scripts/test_sync_agents_md.py +0 -0
  297. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/skill/test_bundle.py +0 -0
  298. {netbox_super_cli-1.1.0 → netbox_super_cli-1.2.0}/tests/test_packaging.py +0 -0
@@ -30,6 +30,7 @@ repos:
30
30
  - "ruamel.yaml>=0.18"
31
31
  - structlog>=24.1
32
32
  - platformdirs>=4.2
33
+ - textual>=0.50
33
34
  - types-PyYAML>=6.0
34
35
  args: [--strict]
35
36
  files: ^(nsc|scripts)/
@@ -2,6 +2,50 @@
2
2
 
3
3
  All notable changes to netbox-super-cli are tracked here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) loosely. From v1.0.0 onward, releases follow [Semantic Versioning](https://semver.org/) and the version in `pyproject.toml` matches the git tag. Pre-1.0 milestones (Phase 1-5) were pinned by tag while `pyproject.toml` stayed at `0.0.1`.
4
4
 
5
+ ## v1.2.0 — 2026-06-24
6
+
7
+ Minor release. Adds an **interactive terminal UI** — a keyboard-driven, fully
8
+ schema-generic front end over the same command model the CLI uses.
9
+
10
+ ### Added
11
+
12
+ - **`nsc tui` — interactive TUI** (aliases: `nsc interactive`, `nsc i`). A
13
+ Textual app to browse, filter, edit, bulk-edit and search NetBox from the
14
+ keyboard, generated entirely from the OpenAPI-derived command model (works for
15
+ every resource and plugin, no per-model wiring). Textual is imported lazily so
16
+ the regular CLI's startup path is unchanged. See the
17
+ [Interactive TUI guide](https://thomaschristory.github.io/netbox-super-cli/guides/interactive-tui/).
18
+ - **Resource picker** — a collapsible tree of resources grouped by tag, with
19
+ fuzzy filtering (matching groups auto-expand) and expand/collapse-all.
20
+ - **List view** — paginated tables with vim/arrow navigation, multi-select,
21
+ refresh, and an async loading wheel that keeps the input responsive.
22
+ - **Filter builder** (`/`) — a web-UI-like form of curated common fields
23
+ (enum dropdowns, conventional field names), a search box over every query
24
+ parameter, foreign-key record pickers (applied as `…_id`), a raw
25
+ `key=value` line, and removable active-filter chips.
26
+ - **Inline record editing** — the detail view is the edit surface: edit a
27
+ field in place, stage changes, and save them all in one `PATCH` after a
28
+ confirmation diff. Create and delete are supported; foreign keys open a
29
+ searchable picker.
30
+ - **Relationship drill-down** — schema-derived relationship tabs (a device's
31
+ interfaces, modules, cables, …) open a pre-filtered list.
32
+ - **Bulk edit** — set chosen fields across a multi-selection (prepopulated
33
+ from the records' shared value), preview a per-record diff, and apply with a
34
+ progress bar and per-record partial-failure reporting.
35
+ - **Column chooser** (`f`) — toggle and reorder visible columns; the choice
36
+ persists per resource in `~/.nsc/config.yaml` (shared with the CLI's
37
+ `--columns`).
38
+ - **Global search** (`Ctrl`+`F`) — search across a curated set of common
39
+ object types at once, with results grouped by type and a live spinner.
40
+ - **Help overlay** (`?`) — a per-context keymap generated from the live
41
+ bindings, so it can never drift.
42
+ - New dependency: `textual` (loaded only by the TUI).
43
+
44
+ ### Documentation
45
+
46
+ - New [Interactive TUI guide](https://thomaschristory.github.io/netbox-super-cli/guides/interactive-tui/)
47
+ with screenshots, linked from the Home page and the README.
48
+
5
49
  ## v1.1.0 — 2026-06-18
6
50
 
7
51
  Minor release. Hardens the audit log and schema loader against the security
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: netbox-super-cli
3
- Version: 1.1.0
3
+ Version: 1.2.0
4
4
  Summary: Dynamic NetBox CLI generated from the live OpenAPI schema.
5
5
  Project-URL: Homepage, https://github.com/thomaschristory/netbox-super-cli
6
6
  Project-URL: Issues, https://github.com/thomaschristory/netbox-super-cli/issues
@@ -23,6 +23,7 @@ Requires-Dist: pydantic>=2.7
23
23
  Requires-Dist: rich>=13.7
24
24
  Requires-Dist: ruamel-yaml>=0.18
25
25
  Requires-Dist: structlog>=24.1
26
+ Requires-Dist: textual>=0.50
26
27
  Requires-Dist: typer<0.27,>=0.26
27
28
  Description-Content-Type: text/markdown
28
29
 
@@ -38,6 +39,7 @@ A Python CLI for [NetBox](https://netbox.dev/) that builds its command tree dyna
38
39
  - **Multi-instance.** Named profiles per NetBox instance, plus env-var overrides.
39
40
  - **Safe by default.** POST/PATCH/PUT/DELETE preview as dry-runs unless you pass `--apply`.
40
41
  - **Agent-friendly.** Deterministic command shape, machine-readable JSON output, stable error envelope with documented exit codes.
42
+ - **Interactive TUI.** `nsc tui` opens a keyboard-driven terminal UI — see below.
41
43
 
42
44
  ## Install
43
45
 
@@ -55,6 +57,26 @@ uv sync
55
57
  uv run nsc --version
56
58
  ```
57
59
 
60
+ ## Interactive TUI
61
+
62
+ `nsc tui` (aliases `nsc interactive`, `nsc i`) opens a full-screen,
63
+ keyboard-driven UI over your NetBox — browse, filter, edit, bulk-edit and search
64
+ across object types without writing a command. Like the CLI it is generated from
65
+ the live schema, so it works for every resource and plugin.
66
+
67
+ ![The nsc interactive TUI](docs/assets/tui/list.svg)
68
+
69
+ ```sh
70
+ nsc tui # land on the resource picker
71
+ nsc tui devices # jump straight into the devices list
72
+ ```
73
+
74
+ Highlights: a collapsible resource picker, a web-UI-style filter builder (`/`),
75
+ inline record editing with a confirm-diff save, schema-derived relationship
76
+ drill-down, bulk edit with a per-record preview, a persisted column chooser
77
+ (`f`), and global search (`Ctrl`+`F`). Full walkthrough in the
78
+ [Interactive TUI guide](https://thomaschristory.github.io/netbox-super-cli/guides/interactive-tui/).
79
+
58
80
  ## Reading
59
81
 
60
82
  ```sh
@@ -10,6 +10,7 @@ A Python CLI for [NetBox](https://netbox.dev/) that builds its command tree dyna
10
10
  - **Multi-instance.** Named profiles per NetBox instance, plus env-var overrides.
11
11
  - **Safe by default.** POST/PATCH/PUT/DELETE preview as dry-runs unless you pass `--apply`.
12
12
  - **Agent-friendly.** Deterministic command shape, machine-readable JSON output, stable error envelope with documented exit codes.
13
+ - **Interactive TUI.** `nsc tui` opens a keyboard-driven terminal UI — see below.
13
14
 
14
15
  ## Install
15
16
 
@@ -27,6 +28,26 @@ uv sync
27
28
  uv run nsc --version
28
29
  ```
29
30
 
31
+ ## Interactive TUI
32
+
33
+ `nsc tui` (aliases `nsc interactive`, `nsc i`) opens a full-screen,
34
+ keyboard-driven UI over your NetBox — browse, filter, edit, bulk-edit and search
35
+ across object types without writing a command. Like the CLI it is generated from
36
+ the live schema, so it works for every resource and plugin.
37
+
38
+ ![The nsc interactive TUI](docs/assets/tui/list.svg)
39
+
40
+ ```sh
41
+ nsc tui # land on the resource picker
42
+ nsc tui devices # jump straight into the devices list
43
+ ```
44
+
45
+ Highlights: a collapsible resource picker, a web-UI-style filter builder (`/`),
46
+ inline record editing with a confirm-diff save, schema-derived relationship
47
+ drill-down, bulk edit with a per-record preview, a persisted column chooser
48
+ (`f`), and global search (`Ctrl`+`F`). Full walkthrough in the
49
+ [Interactive TUI guide](https://thomaschristory.github.io/netbox-super-cli/guides/interactive-tui/).
50
+
30
51
  ## Reading
31
52
 
32
53
  ```sh
@@ -42,19 +42,22 @@ Each line of `audit.jsonl` is a JSON object with:
42
42
 
43
43
  - `schema_version`, `timestamp` (UTC ISO8601, `…Z`)
44
44
  - `operation_id`, `method`, `url`
45
- - `request.headers` (sensitive headers, incl. `Authorization`, rewritten
46
- to `"<redacted>"` — the key stays, the value is masked)
45
+ - `request.headers` (sensitive headers `Authorization`, `Cookie`,
46
+ `Set-Cookie`, `X-API-Key`, `Proxy-Authorization`rewritten to
47
+ `"<redacted>"`; the key stays, the value is masked)
47
48
  - `request.query`, `request.body` (sensitive `sensitive_paths` fields
48
49
  rewritten to `"<redacted>"`); bodies over 256 KB collapse to
49
50
  `{"_truncated": true, "_size_bytes": N}` with `request.body_truncated`
50
- - `response.status_code`, `response.headers`, `response.body` (same
51
+ - `response.status_code`, `response.headers` (redacted with the same
52
+ sensitive-header set as the request side), `response.body` (same
51
53
  256 KB truncation via `response.body_truncated`); `response` is `null`
52
54
  on a transport failure
53
55
  - `duration_ms`, `attempt_n`, `final_attempt`, `error_kind`
54
56
  - `dry_run`, `preflight_blocked`, `record_indices`, `applied`, `explain`
55
57
 
56
- The audit file is append-only and rotates to `audit.jsonl.1` at 10 MB;
57
- failed writes do NOT unredact. See
58
+ The audit file is append-only and rotates to `audit.jsonl.1` at 10 MB; it is
59
+ created owner-only (`0600`) inside a `0700` logs directory, and failed writes do
60
+ NOT unredact. See
58
61
  [Writes and safety](../guides/writes-and-safety.md) for the full redaction
59
62
  contract.
60
63
 
@@ -17,7 +17,11 @@ and an optional `--refresh-schema` override:
17
17
  3. Live fetch from the active profile's `schema_url` (explicit) or
18
18
  `{profile.url}/api/schema/?format=json`. The fetched body is hashed;
19
19
  if a cache file already exists at that hash it's loaded directly,
20
- otherwise the command-model is rebuilt and saved.
20
+ otherwise the command-model is rebuilt and saved. The fetch is bounded:
21
+ the loader streams raw wire bytes under a 64 MB cap, requests
22
+ `Accept-Encoding: identity`, and any `.gz`/`Content-Encoding` body is
23
+ decompressed incrementally to the same cap — so an oversized or
24
+ decompression-bomb schema is rejected rather than exhausting memory.
21
25
  4. On fetch failure: the newest valid cached entry for the profile
22
26
  (warns once on stderr), sorted by mtime.
23
27
  5. Bundled snapshot — the **last (newest) entry** in
@@ -0,0 +1,190 @@
1
+ <svg class="rich-terminal" viewBox="0 0 1385 830.8" xmlns="http://www.w3.org/2000/svg">
2
+ <!-- Generated with Rich https://www.textualize.io -->
3
+ <style>
4
+
5
+ @font-face {
6
+ font-family: "Fira Code";
7
+ src: local("FiraCode-Regular"),
8
+ url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
9
+ url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
10
+ font-style: normal;
11
+ font-weight: 400;
12
+ }
13
+ @font-face {
14
+ font-family: "Fira Code";
15
+ src: local("FiraCode-Bold"),
16
+ url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
17
+ url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
18
+ font-style: bold;
19
+ font-weight: 700;
20
+ }
21
+
22
+ .terminal-3309028997-matrix {
23
+ font-family: Fira Code, monospace;
24
+ font-size: 20px;
25
+ line-height: 24.4px;
26
+ font-variant-east-asian: full-width;
27
+ }
28
+
29
+ .terminal-3309028997-title {
30
+ font-size: 18px;
31
+ font-weight: bold;
32
+ font-family: arial;
33
+ }
34
+
35
+ .terminal-3309028997-r1 { fill: #c5c8c6 }
36
+ .terminal-3309028997-r2 { fill: #e0e0e0 }
37
+ .terminal-3309028997-r3 { fill: #e0e0e0;font-weight: bold }
38
+ .terminal-3309028997-r4 { fill: #272727 }
39
+ .terminal-3309028997-r5 { fill: #ddedf9;font-weight: bold }
40
+ .terminal-3309028997-r6 { fill: #000000 }
41
+ .terminal-3309028997-r7 { fill: #797979 }
42
+ .terminal-3309028997-r8 { fill: #262626 }
43
+ .terminal-3309028997-r9 { fill: #0178d4 }
44
+ .terminal-3309028997-r10 { fill: #ffa62b;font-weight: bold }
45
+ </style>
46
+
47
+ <defs>
48
+ <clipPath id="terminal-3309028997-clip-terminal">
49
+ <rect x="0" y="0" width="1365.3999999999999" height="779.8" />
50
+ </clipPath>
51
+ <clipPath id="terminal-3309028997-line-0">
52
+ <rect x="0" y="1.5" width="1366.4" height="24.65"/>
53
+ </clipPath>
54
+ <clipPath id="terminal-3309028997-line-1">
55
+ <rect x="0" y="25.9" width="1366.4" height="24.65"/>
56
+ </clipPath>
57
+ <clipPath id="terminal-3309028997-line-2">
58
+ <rect x="0" y="50.3" width="1366.4" height="24.65"/>
59
+ </clipPath>
60
+ <clipPath id="terminal-3309028997-line-3">
61
+ <rect x="0" y="74.7" width="1366.4" height="24.65"/>
62
+ </clipPath>
63
+ <clipPath id="terminal-3309028997-line-4">
64
+ <rect x="0" y="99.1" width="1366.4" height="24.65"/>
65
+ </clipPath>
66
+ <clipPath id="terminal-3309028997-line-5">
67
+ <rect x="0" y="123.5" width="1366.4" height="24.65"/>
68
+ </clipPath>
69
+ <clipPath id="terminal-3309028997-line-6">
70
+ <rect x="0" y="147.9" width="1366.4" height="24.65"/>
71
+ </clipPath>
72
+ <clipPath id="terminal-3309028997-line-7">
73
+ <rect x="0" y="172.3" width="1366.4" height="24.65"/>
74
+ </clipPath>
75
+ <clipPath id="terminal-3309028997-line-8">
76
+ <rect x="0" y="196.7" width="1366.4" height="24.65"/>
77
+ </clipPath>
78
+ <clipPath id="terminal-3309028997-line-9">
79
+ <rect x="0" y="221.1" width="1366.4" height="24.65"/>
80
+ </clipPath>
81
+ <clipPath id="terminal-3309028997-line-10">
82
+ <rect x="0" y="245.5" width="1366.4" height="24.65"/>
83
+ </clipPath>
84
+ <clipPath id="terminal-3309028997-line-11">
85
+ <rect x="0" y="269.9" width="1366.4" height="24.65"/>
86
+ </clipPath>
87
+ <clipPath id="terminal-3309028997-line-12">
88
+ <rect x="0" y="294.3" width="1366.4" height="24.65"/>
89
+ </clipPath>
90
+ <clipPath id="terminal-3309028997-line-13">
91
+ <rect x="0" y="318.7" width="1366.4" height="24.65"/>
92
+ </clipPath>
93
+ <clipPath id="terminal-3309028997-line-14">
94
+ <rect x="0" y="343.1" width="1366.4" height="24.65"/>
95
+ </clipPath>
96
+ <clipPath id="terminal-3309028997-line-15">
97
+ <rect x="0" y="367.5" width="1366.4" height="24.65"/>
98
+ </clipPath>
99
+ <clipPath id="terminal-3309028997-line-16">
100
+ <rect x="0" y="391.9" width="1366.4" height="24.65"/>
101
+ </clipPath>
102
+ <clipPath id="terminal-3309028997-line-17">
103
+ <rect x="0" y="416.3" width="1366.4" height="24.65"/>
104
+ </clipPath>
105
+ <clipPath id="terminal-3309028997-line-18">
106
+ <rect x="0" y="440.7" width="1366.4" height="24.65"/>
107
+ </clipPath>
108
+ <clipPath id="terminal-3309028997-line-19">
109
+ <rect x="0" y="465.1" width="1366.4" height="24.65"/>
110
+ </clipPath>
111
+ <clipPath id="terminal-3309028997-line-20">
112
+ <rect x="0" y="489.5" width="1366.4" height="24.65"/>
113
+ </clipPath>
114
+ <clipPath id="terminal-3309028997-line-21">
115
+ <rect x="0" y="513.9" width="1366.4" height="24.65"/>
116
+ </clipPath>
117
+ <clipPath id="terminal-3309028997-line-22">
118
+ <rect x="0" y="538.3" width="1366.4" height="24.65"/>
119
+ </clipPath>
120
+ <clipPath id="terminal-3309028997-line-23">
121
+ <rect x="0" y="562.7" width="1366.4" height="24.65"/>
122
+ </clipPath>
123
+ <clipPath id="terminal-3309028997-line-24">
124
+ <rect x="0" y="587.1" width="1366.4" height="24.65"/>
125
+ </clipPath>
126
+ <clipPath id="terminal-3309028997-line-25">
127
+ <rect x="0" y="611.5" width="1366.4" height="24.65"/>
128
+ </clipPath>
129
+ <clipPath id="terminal-3309028997-line-26">
130
+ <rect x="0" y="635.9" width="1366.4" height="24.65"/>
131
+ </clipPath>
132
+ <clipPath id="terminal-3309028997-line-27">
133
+ <rect x="0" y="660.3" width="1366.4" height="24.65"/>
134
+ </clipPath>
135
+ <clipPath id="terminal-3309028997-line-28">
136
+ <rect x="0" y="684.7" width="1366.4" height="24.65"/>
137
+ </clipPath>
138
+ <clipPath id="terminal-3309028997-line-29">
139
+ <rect x="0" y="709.1" width="1366.4" height="24.65"/>
140
+ </clipPath>
141
+ <clipPath id="terminal-3309028997-line-30">
142
+ <rect x="0" y="733.5" width="1366.4" height="24.65"/>
143
+ </clipPath>
144
+ </defs>
145
+
146
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1383" height="828.8" rx="8"/><text class="terminal-3309028997-title" fill="#c5c8c6" text-anchor="middle" x="691" y="27">nsc&#160;tui</text>
147
+ <g transform="translate(26,22)">
148
+ <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
149
+ <circle cx="22" cy="0" r="7" fill="#febc2e"/>
150
+ <circle cx="44" cy="0" r="7" fill="#28c840"/>
151
+ </g>
152
+
153
+ <g transform="translate(9, 41)" clip-path="url(#terminal-3309028997-clip-terminal)">
154
+ <rect fill="#242f38" x="0" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="12.2" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="24.4" y="1.5" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="85.4" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="97.6" y="1.5" width="500.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="597.8" y="1.5" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="744.2" y="1.5" width="500.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1244.4" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1256.6" y="1.5" width="0" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1256.6" y="1.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1354.2" y="1.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d3740" x="0" y="25.9" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d3740" x="244" y="25.9" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#2d3740" x="475.8" y="25.9" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="25.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="0" y="50.3" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="244" y="50.3" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#0178d4" x="475.8" y="50.3" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="50.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="74.7" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="74.7" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="74.7" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="74.7" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="99.1" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="99.1" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="99.1" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="99.1" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="123.5" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="123.5" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="123.5" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="123.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="147.9" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="147.9" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="147.9" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="147.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="172.3" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="172.3" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="172.3" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="172.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="196.7" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="196.7" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="196.7" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="196.7" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="221.1" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="221.1" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="221.1" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="221.1" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="245.5" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="245.5" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="245.5" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="245.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="269.9" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="269.9" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="269.9" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="269.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="294.3" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="294.3" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="294.3" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="294.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="318.7" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="318.7" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="318.7" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="318.7" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="343.1" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="343.1" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="343.1" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="343.1" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="367.5" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="367.5" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="367.5" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="367.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="391.9" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="391.9" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="391.9" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="391.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="416.3" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="416.3" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="416.3" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="416.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="440.7" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="440.7" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="440.7" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="440.7" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="465.1" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="465.1" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="465.1" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="465.1" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="489.5" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="489.5" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="489.5" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="489.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="513.9" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="513.9" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="513.9" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="513.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="538.3" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="538.3" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="538.3" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="538.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="562.7" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="562.7" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="562.7" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="562.7" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="587.1" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="587.1" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="587.1" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#003054" x="1342" y="587.1" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="611.5" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="611.5" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="611.5" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#000000" x="1342" y="611.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="635.9" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="635.9" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="635.9" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#000000" x="1342" y="635.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="660.3" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="660.3" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="660.3" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#000000" x="1342" y="660.3" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="0" y="684.7" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="244" y="684.7" width="231.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#272727" x="475.8" y="684.7" width="866.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#000000" x="1342" y="684.7" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="0" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="12.2" y="709.1" width="73.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="85.4" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="97.6" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="109.8" y="709.1" width="158.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="268.4" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="280.6" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="292.8" y="709.1" width="244" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="536.8" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="549" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="561.2" y="709.1" width="134.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="695.4" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="707.6" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="719.8" y="709.1" width="134.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="854" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="866.2" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="878.4" y="709.1" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="1000.4" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="1012.6" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="1024.8" y="709.1" width="183" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="1207.8" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="1220" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="1232.2" y="709.1" width="134.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="0" y="733.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="12.2" y="733.5" width="73.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="85.4" y="733.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#121212" x="97.6" y="733.5" width="1268.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="0" y="757.9" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="61" y="757.9" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="170.8" y="757.9" width="134.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="305" y="757.9" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="414.8" y="757.9" width="36.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="451.4" y="757.9" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="512.4" y="757.9" width="36.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="549" y="757.9" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="610" y="757.9" width="48.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="658.8" y="757.9" width="170.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="829.6" y="757.9" width="48.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="878.4" y="757.9" width="85.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="963.8" y="757.9" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1024.8" y="757.9" width="61" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1085.8" y="757.9" width="36.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1122.4" y="757.9" width="134.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1256.6" y="757.9" width="36.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#242f38" x="1293.2" y="757.9" width="73.2" height="24.65" shape-rendering="crispEdges"/>
155
+ <g class="terminal-3309028997-matrix">
156
+ <text class="terminal-3309028997-r2" x="12.2" y="20" textLength="12.2" clip-path="url(#terminal-3309028997-line-0)">⭘</text><text class="terminal-3309028997-r2" x="597.8" y="20" textLength="146.4" clip-path="url(#terminal-3309028997-line-0)">devices&#160;#111</text><text class="terminal-3309028997-r1" x="1366.4" y="20" textLength="12.2" clip-path="url(#terminal-3309028997-line-0)">
157
+ </text><text class="terminal-3309028997-r3" x="0" y="44.4" textLength="244" clip-path="url(#terminal-3309028997-line-1)">&#160;field&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r3" x="244" y="44.4" textLength="231.8" clip-path="url(#terminal-3309028997-line-1)">&#160;value&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="44.4" textLength="12.2" clip-path="url(#terminal-3309028997-line-1)">
158
+ </text><text class="terminal-3309028997-r5" x="0" y="68.8" textLength="244" clip-path="url(#terminal-3309028997-line-2)">&#160;name&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r5" x="244" y="68.8" textLength="231.8" clip-path="url(#terminal-3309028997-line-2)">&#160;dmi01-akron-pdu01&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="68.8" textLength="12.2" clip-path="url(#terminal-3309028997-line-2)">
159
+ </text><text class="terminal-3309028997-r2" x="0" y="93.2" textLength="244" clip-path="url(#terminal-3309028997-line-3)">&#160;device_type&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="93.2" textLength="12.2" clip-path="url(#terminal-3309028997-line-3)">
160
+ </text><text class="terminal-3309028997-r2" x="0" y="117.6" textLength="244" clip-path="url(#terminal-3309028997-line-4)">&#160;role&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r2" x="244" y="117.6" textLength="231.8" clip-path="url(#terminal-3309028997-line-4)">&#160;PDU&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="117.6" textLength="12.2" clip-path="url(#terminal-3309028997-line-4)">
161
+ </text><text class="terminal-3309028997-r2" x="0" y="142" textLength="244" clip-path="url(#terminal-3309028997-line-5)">&#160;tenant&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="142" textLength="12.2" clip-path="url(#terminal-3309028997-line-5)">
162
+ </text><text class="terminal-3309028997-r2" x="0" y="166.4" textLength="244" clip-path="url(#terminal-3309028997-line-6)">&#160;platform&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="166.4" textLength="12.2" clip-path="url(#terminal-3309028997-line-6)">
163
+ </text><text class="terminal-3309028997-r2" x="0" y="190.8" textLength="244" clip-path="url(#terminal-3309028997-line-7)">&#160;serial&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r2" x="244" y="190.8" textLength="231.8" clip-path="url(#terminal-3309028997-line-7)">&#160;6457-2371&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="190.8" textLength="12.2" clip-path="url(#terminal-3309028997-line-7)">
164
+ </text><text class="terminal-3309028997-r2" x="0" y="215.2" textLength="244" clip-path="url(#terminal-3309028997-line-8)">&#160;asset_tag&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="215.2" textLength="12.2" clip-path="url(#terminal-3309028997-line-8)">
165
+ </text><text class="terminal-3309028997-r2" x="0" y="239.6" textLength="244" clip-path="url(#terminal-3309028997-line-9)">&#160;site&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r2" x="244" y="239.6" textLength="231.8" clip-path="url(#terminal-3309028997-line-9)">&#160;DM-Akron&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="239.6" textLength="12.2" clip-path="url(#terminal-3309028997-line-9)">
166
+ </text><text class="terminal-3309028997-r2" x="0" y="264" textLength="244" clip-path="url(#terminal-3309028997-line-10)">&#160;location&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="264" textLength="12.2" clip-path="url(#terminal-3309028997-line-10)">
167
+ </text><text class="terminal-3309028997-r2" x="0" y="288.4" textLength="244" clip-path="url(#terminal-3309028997-line-11)">&#160;rack&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="288.4" textLength="12.2" clip-path="url(#terminal-3309028997-line-11)">
168
+ </text><text class="terminal-3309028997-r2" x="0" y="312.8" textLength="244" clip-path="url(#terminal-3309028997-line-12)">&#160;position&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="312.8" textLength="12.2" clip-path="url(#terminal-3309028997-line-12)">
169
+ </text><text class="terminal-3309028997-r2" x="0" y="337.2" textLength="244" clip-path="url(#terminal-3309028997-line-13)">&#160;face&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="337.2" textLength="12.2" clip-path="url(#terminal-3309028997-line-13)">
170
+ </text><text class="terminal-3309028997-r2" x="0" y="361.6" textLength="244" clip-path="url(#terminal-3309028997-line-14)">&#160;latitude&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="361.6" textLength="12.2" clip-path="url(#terminal-3309028997-line-14)">
171
+ </text><text class="terminal-3309028997-r2" x="0" y="386" textLength="244" clip-path="url(#terminal-3309028997-line-15)">&#160;longitude&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="386" textLength="12.2" clip-path="url(#terminal-3309028997-line-15)">
172
+ </text><text class="terminal-3309028997-r2" x="0" y="410.4" textLength="244" clip-path="url(#terminal-3309028997-line-16)">&#160;status&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="410.4" textLength="12.2" clip-path="url(#terminal-3309028997-line-16)">
173
+ </text><text class="terminal-3309028997-r2" x="0" y="434.8" textLength="244" clip-path="url(#terminal-3309028997-line-17)">&#160;airflow&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="434.8" textLength="12.2" clip-path="url(#terminal-3309028997-line-17)">
174
+ </text><text class="terminal-3309028997-r2" x="0" y="459.2" textLength="244" clip-path="url(#terminal-3309028997-line-18)">&#160;primary_ip4&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="459.2" textLength="12.2" clip-path="url(#terminal-3309028997-line-18)">
175
+ </text><text class="terminal-3309028997-r2" x="0" y="483.6" textLength="244" clip-path="url(#terminal-3309028997-line-19)">&#160;primary_ip6&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="483.6" textLength="12.2" clip-path="url(#terminal-3309028997-line-19)">
176
+ </text><text class="terminal-3309028997-r2" x="0" y="508" textLength="244" clip-path="url(#terminal-3309028997-line-20)">&#160;oob_ip&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="508" textLength="12.2" clip-path="url(#terminal-3309028997-line-20)">
177
+ </text><text class="terminal-3309028997-r2" x="0" y="532.4" textLength="244" clip-path="url(#terminal-3309028997-line-21)">&#160;cluster&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="532.4" textLength="12.2" clip-path="url(#terminal-3309028997-line-21)">
178
+ </text><text class="terminal-3309028997-r2" x="0" y="556.8" textLength="244" clip-path="url(#terminal-3309028997-line-22)">&#160;virtual_chassis&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="556.8" textLength="12.2" clip-path="url(#terminal-3309028997-line-22)">
179
+ </text><text class="terminal-3309028997-r2" x="0" y="581.2" textLength="244" clip-path="url(#terminal-3309028997-line-23)">&#160;vc_position&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="581.2" textLength="12.2" clip-path="url(#terminal-3309028997-line-23)">
180
+ </text><text class="terminal-3309028997-r2" x="0" y="605.6" textLength="244" clip-path="url(#terminal-3309028997-line-24)">&#160;vc_priority&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r6" x="1342" y="605.6" textLength="24.4" clip-path="url(#terminal-3309028997-line-24)">▁▁</text><text class="terminal-3309028997-r1" x="1366.4" y="605.6" textLength="12.2" clip-path="url(#terminal-3309028997-line-24)">
181
+ </text><text class="terminal-3309028997-r2" x="0" y="630" textLength="244" clip-path="url(#terminal-3309028997-line-25)">&#160;description&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="630" textLength="12.2" clip-path="url(#terminal-3309028997-line-25)">
182
+ </text><text class="terminal-3309028997-r2" x="0" y="654.4" textLength="244" clip-path="url(#terminal-3309028997-line-26)">&#160;owner&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="654.4" textLength="12.2" clip-path="url(#terminal-3309028997-line-26)">
183
+ </text><text class="terminal-3309028997-r2" x="0" y="678.8" textLength="244" clip-path="url(#terminal-3309028997-line-27)">&#160;comments&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="678.8" textLength="12.2" clip-path="url(#terminal-3309028997-line-27)">
184
+ </text><text class="terminal-3309028997-r2" x="0" y="703.2" textLength="244" clip-path="url(#terminal-3309028997-line-28)">&#160;config_template&#160;&#160;&#160;&#160;</text><text class="terminal-3309028997-r1" x="1366.4" y="703.2" textLength="12.2" clip-path="url(#terminal-3309028997-line-28)">
185
+ </text><text class="terminal-3309028997-r2" x="12.2" y="727.6" textLength="73.2" clip-path="url(#terminal-3309028997-line-29)">cables</text><text class="terminal-3309028997-r7" x="109.8" y="727.6" textLength="158.6" clip-path="url(#terminal-3309028997-line-29)">console-ports</text><text class="terminal-3309028997-r7" x="292.8" y="727.6" textLength="244" clip-path="url(#terminal-3309028997-line-29)">console-server-ports</text><text class="terminal-3309028997-r7" x="561.2" y="727.6" textLength="134.2" clip-path="url(#terminal-3309028997-line-29)">device-bays</text><text class="terminal-3309028997-r7" x="719.8" y="727.6" textLength="134.2" clip-path="url(#terminal-3309028997-line-29)">front-ports</text><text class="terminal-3309028997-r7" x="878.4" y="727.6" textLength="122" clip-path="url(#terminal-3309028997-line-29)">interfaces</text><text class="terminal-3309028997-r7" x="1024.8" y="727.6" textLength="183" clip-path="url(#terminal-3309028997-line-29)">inventory-items</text><text class="terminal-3309028997-r7" x="1232.2" y="727.6" textLength="134.2" clip-path="url(#terminal-3309028997-line-29)">mac-address</text><text class="terminal-3309028997-r1" x="1366.4" y="727.6" textLength="12.2" clip-path="url(#terminal-3309028997-line-29)">
186
+ </text><text class="terminal-3309028997-r8" x="0" y="752" textLength="12.2" clip-path="url(#terminal-3309028997-line-30)">╸</text><text class="terminal-3309028997-r9" x="12.2" y="752" textLength="73.2" clip-path="url(#terminal-3309028997-line-30)">━━━━━━</text><text class="terminal-3309028997-r8" x="85.4" y="752" textLength="12.2" clip-path="url(#terminal-3309028997-line-30)">╺</text><text class="terminal-3309028997-r8" x="97.6" y="752" textLength="1268.8" clip-path="url(#terminal-3309028997-line-30)">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text class="terminal-3309028997-r1" x="1366.4" y="752" textLength="12.2" clip-path="url(#terminal-3309028997-line-30)">
187
+ </text><text class="terminal-3309028997-r10" x="0" y="776.4" textLength="61" clip-path="url(#terminal-3309028997-line-31)">&#160;tab&#160;</text><text class="terminal-3309028997-r2" x="61" y="776.4" textLength="109.8" clip-path="url(#terminal-3309028997-line-31)">Next&#160;tab&#160;</text><text class="terminal-3309028997-r10" x="170.8" y="776.4" textLength="134.2" clip-path="url(#terminal-3309028997-line-31)">&#160;shift+tab&#160;</text><text class="terminal-3309028997-r2" x="305" y="776.4" textLength="109.8" clip-path="url(#terminal-3309028997-line-31)">Prev&#160;tab&#160;</text><text class="terminal-3309028997-r10" x="414.8" y="776.4" textLength="36.6" clip-path="url(#terminal-3309028997-line-31)">&#160;q&#160;</text><text class="terminal-3309028997-r2" x="451.4" y="776.4" textLength="61" clip-path="url(#terminal-3309028997-line-31)">Quit&#160;</text><text class="terminal-3309028997-r10" x="512.4" y="776.4" textLength="36.6" clip-path="url(#terminal-3309028997-line-31)">&#160;?&#160;</text><text class="terminal-3309028997-r2" x="549" y="776.4" textLength="61" clip-path="url(#terminal-3309028997-line-31)">Help&#160;</text><text class="terminal-3309028997-r10" x="610" y="776.4" textLength="48.8" clip-path="url(#terminal-3309028997-line-31)">&#160;^p&#160;</text><text class="terminal-3309028997-r2" x="658.8" y="776.4" textLength="170.8" clip-path="url(#terminal-3309028997-line-31)">Find&#160;resource&#160;</text><text class="terminal-3309028997-r10" x="829.6" y="776.4" textLength="48.8" clip-path="url(#terminal-3309028997-line-31)">&#160;^f&#160;</text><text class="terminal-3309028997-r2" x="878.4" y="776.4" textLength="85.4" clip-path="url(#terminal-3309028997-line-31)">Search&#160;</text><text class="terminal-3309028997-r10" x="963.8" y="776.4" textLength="61" clip-path="url(#terminal-3309028997-line-31)">&#160;esc&#160;</text><text class="terminal-3309028997-r2" x="1024.8" y="776.4" textLength="61" clip-path="url(#terminal-3309028997-line-31)">Back&#160;</text><text class="terminal-3309028997-r10" x="1085.8" y="776.4" textLength="36.6" clip-path="url(#terminal-3309028997-line-31)">&#160;e&#160;</text><text class="terminal-3309028997-r2" x="1122.4" y="776.4" textLength="134.2" clip-path="url(#terminal-3309028997-line-31)">Edit&#160;field&#160;</text><text class="terminal-3309028997-r10" x="1256.6" y="776.4" textLength="36.6" clip-path="url(#terminal-3309028997-line-31)">&#160;s&#160;</text><text class="terminal-3309028997-r2" x="1293.2" y="776.4" textLength="73.2" clip-path="url(#terminal-3309028997-line-31)">Save&#160;c</text>
188
+ </g>
189
+ </g>
190
+ </svg>