Commit be50bc6
feat(dashboards): Sim-built workspace dashboard behind a rollout flag (#8305)
* feat(dashboards): add table-backed dashboard resources behind rollout flag
* refactor(files): separate discovery from storage context
* fix(charts): keep pie labels readable and separate neutral colors
* feat(dashboards): compute percentages from row conditions
* refactor(dashboards): store dashboards as workspace files
Dashboards are now ordinary workspace files, handled like Sim pages, instead
of a separate resource. Creating or uploading `<Name>.dashboard` drops the
suffix and stamps `text/x-sim-dashboard`; the type is sticky across content
writes. The file viewer renders it live behind the `dashboards` flag, and the
public share viewer shows a workspace-only notice.
- Remove the dashboard resource: sidebar page, API routes, hooks, contracts,
application layer, Mothership dashboards/dashboard_folders tools, resource
tags, and the per-turn dashboardsEnabled payload.
- Revert the file discovery column (0385) and drop the dashboard folder
resource enum (0384); dashboards never shipped, so no backfill.
- Chat panel decides previewability and tab/picker icons from the file type,
not the name, so extensionless dashboards render and get the chart icon.
- Renderer: authored left label columns are kept intact, horizontal bar
frames grow with row count, and hovered rows get a label-and-bar highlight.
- Simplify the create-dashboard skill around one validated example.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* fix(dashboards): address review findings on chart layout and precision
- Size horizontal bar `.chart` previews by category count like dashboard panels.
- Keep the ECharts label column for percentage bar widths, resolve percentage
grid insets for the row highlight, and keep the time axis on the queried range.
- Show small readout values with significant digits instead of rounding to 0.
- Pass the dashboard's timezone-adjusted today to the range calendar.
- Decide the Chat panel's Markdown mode from the file record.
- Replace mock-call assertions in the EChartsView tests with DOM behavior.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* fix(charts): size grouped bar rows and keep the row highlight through resizes
Unstacked bar series sit side by side in a category row, so grouped charts keep
the ECharts label column and their rows fit every bar slot. The row highlight
redraws the active row after each render, so a resize moves it with the plot.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* fix(charts): keep authored tooltip arrays and drop the v2 chat mode override
Chart tooltip defaults now apply to every entry of an authored `tooltip`
array instead of replacing it with one object. Restore the v2 chat payload
to staging: the hard-coded `mode: 'agent'` came from the removed dashboard
resource work and would overwrite a resumed chat's saved mode.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* fix(charts): reserve the authored bar gap between grouped bars
Grouped horizontal bar rows now size their gap from the series `barGap` the way
ECharts does (pixels, a percentage of bar width, default 20%, overlap for
negative gaps) instead of a fixed 4px.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* fix(charts): format index-encoded pie tooltips and test dashboard refresh through the UI
Pie tooltips encoded by dimension index now use the custom formatter, resolving
the measure through the encode indexes ECharts passes it. The dashboard preview
test drops the mocked controls and callback-driven cases and clicks the real
Refresh button to check which analytics queries are invalidated; the range and
timezone math stays covered by the time tests.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* fix(charts): format bar tooltip values with each series' own value axis
Multi-axis bar charts now read the tooltip unit from the axis each series is
plotted on, so a secondary axis no longer inherits the first axis's format.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* test(dashboards): drop mock-call and rendered-text assertions
Removes assertions on mocked collaborators and rendered text from the
dashboard, chart and analytics tests per the repository testing rules, keeping
the observable checks (status codes, thrown errors, DOM roles, computed
summaries, emitted zoom ranges). Deletes the animated-number test, which had
no behavior left to assert.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* test(dashboards): drop redundant mock resets and default environment pragmas
The shared Vitest config already resets mocks and stubbed globals before each
test and defaults to the node environment.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* refactor(dashboards): move authoring guidance to Mothership like Sim Pages
Drop the create-dashboard built-in skill and its rollout gating in the skill
lists. Mothership now learns the dashboard format from a sim-dashboards
reference in its own research-and-deliverables skill, the pattern Sim Pages
use; Sim workspace built-ins stay Agent-block documents. The dashboards flag
still gates the viewer and table analytics.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* refactor(dashboards): give DashboardFeatureGate a props interface
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* feat(dashboards): report dashboard parse errors on file writes
The v2 file create, replace and edit responses now carry `diagnostics` for a
dashboard file: its parse errors, or an empty list. Writes are never blocked,
like the page lint; table columns and queries are still checked when panels
render. Parse errors are reported as `path: message` lines, and a block with
no recognized kind names the allowed kinds and unknown keys instead of Zod's
union dump.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* fix(dashboards): split diagnostics, switch panel query modes, return create revision
- One diagnostics entry per parse error instead of a newline-joined string.
- A panel choosing aggregate or columns drops the other mode's inherited
dashboard fields, so shared defaults serve table and aggregate panels.
- The v2 create response returns the revision it produced, like the replace and
edit responses.
- The analytics route test uses the shared createMockRequest helper.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* fix(dashboards): drop inherited ordering on query-mode switches and cap diagnostics size
A panel switching away from the dashboard's query mode no longer inherits its
sort or limit, which name aggregate aliases or top-N groups in one mode and
rows in the other. Write diagnostics check the 128 KB source limit before
decoding the payload.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* revert(dashboards): restore dashboards as a separate workspace resource
Reverts "store dashboards as workspace files" and "move authoring guidance to
Mothership like Sim Pages", restoring the dashboard resource: its page,
folders, APIs, resource tags, Mothership dashboards/dashboard_folders tools,
per-turn availability, the create-dashboard built-in skill, and file
discovery. Removes the write-time diagnostics that only applied to plain
files. Keeps the chart renderer fixes, readable parse errors, panel query-mode
handling, the create-response revision, and the test cleanups. The authoring
skill keeps its simplified form with the default-formatting note. Migrations
are regenerated on top of staging in the next commit.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* fix(dashboards): renumber resource migrations after staging and use central test mocks
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* fix(dashboards): list by folder, canonical folder paths, named props
The dashboard browser now asks for one folder's dashboards instead of
filtering the first 500 across the workspace, folder paths use the shared
segment encoder, and the README names the renumbered migrations.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* fix(dashboards): address review round on the restored resource
Fork payloads accept file discovery, dashboard queries are keyed and
invalidated per workspace, dashboard contexts open tabs and resolve in
organization chats, archived dashboard folders keep their paths, and the
folder dialog skips no-op moves and hides the edited subtree.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* fix(dashboards): cap dashboard folders and reject folder name collisions
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* fix(dashboards): name the dashboards page props
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* feat(mothership): send entitlements instead of dashboardsEnabled
Restores the entitlement evaluator registry removed in v1.0.0 and sends
the granted list with every Mothership turn; dashboards is the first
entitlement. Sim still enforces every gated operation.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* refactor(dashboards): give agent dashboard commands the files folder syntax
Dashboards take folder paths like files: create/list --folder, move --to
(/ is the root), rename and set-content as separate actions, and folder
create/move/delete by positional path with --recursive for non-empty
deletes. The UI routes keep folder ids.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* feat(dashboards): one Sim-built dashboard per workspace
A workspace now has a single dashboard that Sim builds. The Dashboards page
renders it directly, or an empty state until the first save. Folders, the
list, create, rename and move are removed; the agent reads and saves it with
dashboards get / set, and replacing existing content needs its revision. A
partial unique index enforces one live dashboard per workspace, and generic
file writes can no longer produce the dashboard content type.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* feat(dashboards): put Dashboard under New chat in the sidebar
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* feat(dashboards): headerless dashboard page with a grid-matched icon
The dashboard page renders only the dashboard (or its empty state), so the
header, its Delete action, and the delete route, hook, and use case go away.
A new EMCN Dashboard icon is drawn on the shared sidebar icon grid and
replaces the analytics ChartColumn on dashboard surfaces.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
* refactor(dashboards): drop file discovery for a content-type exclusion
With one dashboard per workspace, the listed/unlisted discovery column, its
migration, legacy-writer trigger, and the upload backfill script are no longer
needed. File listings, search, and workflow file pickers exclude the dashboard
content type instead, and the one-dashboard index is now migration 0392.
* refactor(dashboards): store dashboards in their own table
A dashboard is now a row in a dashboard table with its own id, keyed to its
workspace by a unique index (dropping it later allows several). Reads and
saves go through a small repository with a revision check, so the file-side
guards, exclusions, fixed file name, and dashboard file previews are gone.
Chat contexts reference dashboards by dashboardId, and saves are audited as
dashboard events.
* fix(dashboards): accept dashboard chat contexts and bound revisions
The chat request schema now admits dashboard contexts, revisions outside the
integer column range are rejected as validation errors, resource tabs only
fetch the dashboard when one is open, and the authoring guide notes that
range-pinned panels do not drag-zoom.
* fix(dashboards): named heading sizes and no redundant dashboard name lookups
The dashboard name is fixed, so resource tabs and chat chips no longer fetch
the dashboard to title it; dashboard headings use named text sizes.
* refactor(dashboards): keep the authoring reference in Mothership's skill
Mothership's create-dashboard skill now carries the dashboard syntax like
every other worker skill, so the builtin-create-dashboard workspace skill,
its source, and its flag gating are removed.
* fix(dashboards): server loading fallback and muted gate text
* chore(db): drop leftover script-migration test fixture change
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>1 parent 594894c commit be50bc6
131 files changed
Lines changed: 36223 additions & 362 deletions
File tree
- apps
- docs
- sim
- app
- api
- table/[tableId]/analytics
- v2/files
- [fileId]/content
- workspaces/[id]/dashboard
- o/[organizationId]
- home/components/composer
- workspace/[workspaceId]
- dashboards
- files
- components/file-viewer
- hooks
- home
- components
- chat-context-kind-registry
- message-content/components/special-tags
- mothership-view
- components
- add-resource-dropdown
- resource-content
- resource-registry
- resource-tabs
- user-input
- components
- providers
- w/components/sidebar
- components
- charts
- dashboards
- hooks/queries
- lib
- api/contracts
- v2
- openapi
- charts
- core/config
- dashboards
- application
- mothership
- agent-cli
- application
- chat
- generated
- resources
- tools/server
- table
- analytics
- application
- workflows/skills
- stores
- dashboards
- panel
- packages
- audit/src
- db
- migrations
- meta
- emcn/src
- components
- calendar
- charts
- tab-strip
- icons
- sim-cli/src/generated
- testing/src/mocks
- patches
- scripts
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
248 | 248 | | |
249 | 249 | | |
250 | 250 | | |
251 | | - | |
| 251 | + | |
252 | 252 | | |
253 | 253 | | |
254 | 254 | | |
| |||
4044 | 4044 | | |
4045 | 4045 | | |
4046 | 4046 | | |
4047 | | - | |
| 4047 | + | |
| 4048 | + | |
| 4049 | + | |
| 4050 | + | |
| 4051 | + | |
| 4052 | + | |
| 4053 | + | |
| 4054 | + | |
| 4055 | + | |
| 4056 | + | |
| 4057 | + | |
| 4058 | + | |
| 4059 | + | |
| 4060 | + | |
| 4061 | + | |
| 4062 | + | |
| 4063 | + | |
| 4064 | + | |
| 4065 | + | |
| 4066 | + | |
| 4067 | + | |
| 4068 | + | |
| 4069 | + | |
| 4070 | + | |
| 4071 | + | |
| 4072 | + | |
| 4073 | + | |
| 4074 | + | |
| 4075 | + | |
| 4076 | + | |
| 4077 | + | |
| 4078 | + | |
| 4079 | + | |
| 4080 | + | |
| 4081 | + | |
| 4082 | + | |
| 4083 | + | |
| 4084 | + | |
| 4085 | + | |
| 4086 | + | |
| 4087 | + | |
| 4088 | + | |
| 4089 | + | |
| 4090 | + | |
| 4091 | + | |
| 4092 | + | |
| 4093 | + | |
| 4094 | + | |
| 4095 | + | |
| 4096 | + | |
| 4097 | + | |
| 4098 | + | |
| 4099 | + | |
| 4100 | + | |
| 4101 | + | |
| 4102 | + | |
| 4103 | + | |
| 4104 | + | |
| 4105 | + | |
| 4106 | + | |
| 4107 | + | |
| 4108 | + | |
| 4109 | + | |
| 4110 | + | |
| 4111 | + | |
| 4112 | + | |
| 4113 | + | |
| 4114 | + | |
| 4115 | + | |
| 4116 | + | |
| 4117 | + | |
| 4118 | + | |
| 4119 | + | |
| 4120 | + | |
| 4121 | + | |
| 4122 | + | |
| 4123 | + | |
| 4124 | + | |
| 4125 | + | |
| 4126 | + | |
| 4127 | + | |
| 4128 | + | |
| 4129 | + | |
| 4130 | + | |
| 4131 | + | |
| 4132 | + | |
| 4133 | + | |
| 4134 | + | |
| 4135 | + | |
| 4136 | + | |
| 4137 | + | |
| 4138 | + | |
| 4139 | + | |
| 4140 | + | |
| 4141 | + | |
4048 | 4142 | | |
4049 | 4143 | | |
4050 | 4144 | | |
4051 | 4145 | | |
4052 | | - | |
| 4146 | + | |
4053 | 4147 | | |
4054 | 4148 | | |
4055 | 4149 | | |
4056 | 4150 | | |
4057 | | - | |
4058 | | - | |
| 4151 | + | |
| 4152 | + | |
4059 | 4153 | | |
4060 | 4154 | | |
4061 | 4155 | | |
| |||
5115 | 5209 | | |
5116 | 5210 | | |
5117 | 5211 | | |
| 5212 | + | |
| 5213 | + | |
| 5214 | + | |
| 5215 | + | |
| 5216 | + | |
| 5217 | + | |
| 5218 | + | |
| 5219 | + | |
| 5220 | + | |
| 5221 | + | |
| 5222 | + | |
| 5223 | + | |
| 5224 | + | |
| 5225 | + | |
| 5226 | + | |
| 5227 | + | |
| 5228 | + | |
| 5229 | + | |
| 5230 | + | |
| 5231 | + | |
| 5232 | + | |
| 5233 | + | |
| 5234 | + | |
| 5235 | + | |
| 5236 | + | |
| 5237 | + | |
| 5238 | + | |
| 5239 | + | |
| 5240 | + | |
| 5241 | + | |
5118 | 5242 | | |
5119 | 5243 | | |
5120 | 5244 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
44 | | - | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
45 | 48 | | |
46 | 49 | | |
47 | 50 | | |
| |||
78 | 81 | | |
79 | 82 | | |
80 | 83 | | |
81 | | - | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
82 | 89 | | |
83 | 90 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| |||
93 | 94 | | |
94 | 95 | | |
95 | 96 | | |
96 | | - | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
97 | 103 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
Lines changed: 2 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
234 | 234 | | |
235 | 235 | | |
236 | 236 | | |
| 237 | + | |
237 | 238 | | |
238 | 239 | | |
239 | 240 | | |
| |||
303 | 304 | | |
304 | 305 | | |
305 | 306 | | |
| 307 | + | |
306 | 308 | | |
307 | 309 | | |
308 | 310 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
55 | 56 | | |
56 | 57 | | |
57 | 58 | | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
69 | 72 | | |
70 | 73 | | |
71 | 74 | | |
72 | 75 | | |
73 | 76 | | |
74 | 77 | | |
| 78 | + | |
75 | 79 | | |
76 | 80 | | |
77 | 81 | | |
| |||
Lines changed: 10 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
Lines changed: 10 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
0 commit comments