File size: 19,927 Bytes
14356bb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Genesis AI β€” System Flowchart</title>
<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: 'Segoe UI', Arial, sans-serif; background: #f0f4f0; color: #1a1a2e; padding: 36px; }

h1 { font-size: 24px; font-weight: 700; color: #1a6b2f; padding-bottom: 10px;
     border-bottom: 3px solid #1a6b2f; margin-bottom: 4px; }
.sub { font-size: 12px; color: #777; margin-bottom: 36px; }

/* ── section card ── */
.card { background: #fff; border-radius: 14px; box-shadow: 0 2px 16px rgba(0,0,0,.08);
        padding: 28px 32px; margin-bottom: 30px; }
.card-title { font-size: 13px; font-weight: 700; letter-spacing: .6px; text-transform: uppercase;
              color: #1a6b2f; margin-bottom: 18px; }

/* ── mermaid override ── */
.mermaid { font-size: 13px; }
.mermaid svg { width: 100%; height: auto; }

/* ── legend ── */
.legend { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
.leg { display: flex; align-items: center; gap: 6px; font-size: 11px; color: #555; }
.leg-dot { width: 14px; height: 14px; border-radius: 3px; flex-shrink: 0; }

/* ── table ── */
table { width: 100%; border-collapse: collapse; font-size: 12px; }
thead tr { background: #1a6b2f; color: #fff; }
thead th { padding: 10px 14px; text-align: left; font-weight: 600; }
tbody tr:nth-child(even) { background: #f5faf5; }
tbody td { padding: 9px 14px; border-bottom: 1px solid #e5ede5; vertical-align: top; }
td:first-child { font-weight: 700; color: #1a6b2f; white-space: nowrap; }
td code { font-family: Consolas, monospace; font-size: 11px; background: #eef4ee;
           padding: 2px 6px; border-radius: 3px; }
.badge { display: inline-block; font-size: 10px; font-weight: 700; padding: 2px 7px;
         border-radius: 10px; margin-right: 4px; }
.fe  { background: #e3f2fd; color: #1565c0; }
.be  { background: #fff3e0; color: #c84b00; }
.py  { background: #e8f5e9; color: #1b5e20; }
.out { background: #f3e5f5; color: #6a1b9a; }
</style>
</head>
<body>

<h1>Genesis AI β€” Complete System Flowchart</h1>
<p class="sub">End-to-end flow: Excel upload &rarr; Python pipeline &rarr; JSON outputs &rarr; React dashboard</p>

<!-- ══════════════════════════════════════════════════════════════ -->
<!-- MASTER FLOW                                                    -->
<!-- ══════════════════════════════════════════════════════════════ -->
<div class="card">
  <div class="card-title">Master Flow β€” Upload to Dashboard</div>

  <div class="mermaid">
flowchart TD
  A([" πŸ‘€ User\nOpens Dashboard "]) --> B

  subgraph FE ["  REACT FRONTEND  (localhost:5173)  "]
    B["Header.jsx\nShows file badge\n+ Upload button"]
    B --> C["UploadModal.jsx\nUser picks .xlsx file"]
    C --> D["POST /api/upload\nfetch() with FormData"]
    D2["DataContext.jsx\nfetchKey() per tab"]
    D3["Dashboard tabs render\nResults / PPA / Market / Recs …"]
    D2 --> D3
  end

  subgraph BE ["  FASTAPI BACKEND  (localhost:8000)  "]
    E["upload_server.py\n@app.post('/api/upload')\nSaves .xlsx to _uploads/"]
    F["background thread\n_run_pipeline()"]
    E --> F
    G["GET /api/data/{key}\n@app.get('/api/data/{key}')\nReads output/{key}.json"]
  end

  subgraph PY ["  PYTHON PIPELINE  (pipeline/)  "]
    P1["loader.py\nload_data()\nRead 1_Source_Data sheet\ncompute Price = Val/Vol"]
    P2["run.py\nread_brand_config()\nFocal brand + competitors\nfrom 2_Brand_Config sheet"]
    P3["modelling.py\nbuild_wide_pivot()\nOne table per CHΓ—RG grain"]
    P4["diagnostics.py\nrun_diagnostics()\nCorrelation, CV, RPI checks"]
    P5["modelling.py\nrun_elasticity_models()\nOLS regression per grain\nBest Adj-RΒ² spec selected"]
    P6["proxies.py\nassign_proxies()\nWrong-sign grains get\nborrowed elasticity"]
    P7["exporters/stats.py\nexporters/market.py\nexporters/ppa.py\nexporters/analytics.py\nexporters/recommendations.py"]
    P1 --> P2 --> P3 --> P4 --> P5 --> P6 --> P7
  end

  subgraph OUT ["  OUTPUT FILES  (output/)  "]
    J1["models.json\nstats.json\nfreq_anchors.json"]
    J2["trend.json Β· ms.json\nvol_salience.json\nval_share.json\ncomp_ms.json Β· vtm.json"]
    J3["ppa_mt.json\nppa_tt.json"]
    J4["interaction.json\ngrowth_decomp.json\npgi.json"]
    J5["recs_full.json"]
  end

  D --> E
  F --> P1
  P7 --> J1
  P7 --> J2
  P7 --> J3
  P7 --> J4
  P7 --> J5
  J1 & J2 & J3 & J4 & J5 --> G
  G --> D2

  style FE fill:#e3f2fd,stroke:#1565c0,color:#0d1b4b
  style BE fill:#fff3e0,stroke:#c84b00,color:#3e2000
  style PY fill:#e8f5e9,stroke:#2e7d32,color:#1b2e1b
  style OUT fill:#f3e5f5,stroke:#7b1fa2,color:#2e0040
  </div>

  <div class="legend">
    <div class="leg"><div class="leg-dot" style="background:#bbdefb;border:1.5px solid #1565c0"></div> React Frontend</div>
    <div class="leg"><div class="leg-dot" style="background:#ffe0b2;border:1.5px solid #c84b00"></div> FastAPI Backend</div>
    <div class="leg"><div class="leg-dot" style="background:#c8e6c9;border:1.5px solid #2e7d32"></div> Python Pipeline</div>
    <div class="leg"><div class="leg-dot" style="background:#e1bee7;border:1.5px solid #7b1fa2"></div> JSON Outputs</div>
  </div>
</div>

<!-- ══════════════════════════════════════════════════════════════ -->
<!-- API FLOW                                                       -->
<!-- ══════════════════════════════════════════════════════════════ -->
<div class="card">
  <div class="card-title">API Sequence β€” Upload &rarr; Poll &rarr; Fetch Data</div>

  <div class="mermaid">
sequenceDiagram
  participant UI   as React (browser)
  participant API  as FastAPI :8000
  participant PL   as Pipeline (subprocess)
  participant FS   as output/*.json

  UI->>API: POST /api/upload  (FormData: file.xlsx)
  API-->>UI: 200 { ok:true, filename }
  Note over API: background thread starts

  loop every 2 s while status == "running"
    UI->>API: GET /api/upload/status
    API-->>UI: { status, message, elapsed_s }
  end

  Note over PL: loader β†’ config β†’ pivot β†’ diag β†’ OLS β†’ proxies β†’ export
  API->>PL: subprocess python -m pipeline.run --input file.xlsx
  PL-->>FS: writes 16 Γ— *.json to output/

  API-->>UI: status = "done"

  loop for each of 16 data keys
    UI->>API: GET /api/data/{key}
    API->>FS: reads output/{key}.json
    FS-->>API: JSON bytes
    API-->>UI: JSON response
  end

  Note over UI: Dashboard tabs render with fresh data
  </div>
</div>

<!-- ══════════════════════════════════════════════════════════════ -->
<!-- PIPELINE STEPS DETAIL                                         -->
<!-- ══════════════════════════════════════════════════════════════ -->
<div class="card">
  <div class="card-title">Pipeline Steps &mdash; Detailed Breakdown</div>

  <div class="mermaid">
flowchart LR
  classDef step fill:#e8f5e9,stroke:#2e7d32,color:#1b2e1b,rx:8
  classDef json fill:#f3e5f5,stroke:#7b1fa2,color:#2e0040,rx:8
  classDef file fill:#fff3e0,stroke:#c84b00,color:#3e2000,rx:4

  S1["STEP 1\nloader.py\nload_data()"]:::step
  S2["STEP 2\nrun.py\nread_brand_config()"]:::step
  S3["STEP 3\nmodelling.py\nbuild_wide_pivot()"]:::step
  S4["STEP 4\ndiagnostics.py\nrun_diagnostics()"]:::step
  S5["STEP 5\nmodelling.py\nrun_elasticity_models()"]:::step
  S6["STEP 6\nproxies.py\nassign_proxies()"]:::step

  E1["stats.py\nexport_stats()"]:::step
  E2["market.py\nexport_market()"]:::step
  E3["ppa.py\nexport_ppa()"]:::step
  E4["analytics.py\nexport_analytics()"]:::step
  E5["recommendations.py\nexport_recs()"]:::step

  J1["models.json\nstats.json\nfreq_anchors.json"]:::json
  J2["trend.json\nms.json\nvol_salience.json\nval_share.json\ncomp_ms.json\nvtm.json"]:::json
  J3["ppa_mt.json\nppa_tt.json"]:::json
  J4["interaction.json\ngrowth_decomp.json\npgi.json"]:::json
  J5["recs_full.json"]:::json

  S1 --> S2 --> S3 --> S4 --> S5 --> S6
  S6 --> E1 & E2 & E3 & E4 & E5
  E1 --> J1
  E2 --> J2
  E3 --> J3
  E4 --> J4
  E5 --> J5
  </div>
</div>

<!-- ══════════════════════════════════════════════════════════════ -->
<!-- STEP TABLE                                                     -->
<!-- ══════════════════════════════════════════════════════════════ -->
<div class="card">
  <div class="card-title">Step-by-Step Reference Table</div>

  <table>
    <thead>
      <tr>
        <th>Step</th>
        <th>Layer</th>
        <th>File</th>
        <th>Function / Endpoint</th>
        <th>What it does</th>
        <th>Output</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td><span class="badge fe">FE</span></td>
        <td><code>Header.jsx</code></td>
        <td>Upload button click</td>
        <td>Opens UploadModal; shows active filename badge from localStorage</td>
        <td>β€”</td>
      </tr>
      <tr>
        <td>2</td>
        <td><span class="badge fe">FE</span></td>
        <td><code>UploadModal.jsx</code></td>
        <td><code>handleUpload()</code></td>
        <td>Sends <code>POST /api/upload</code> with FormData; polls <code>/api/upload/status</code> every 2 s</td>
        <td>Filename stored in localStorage</td>
      </tr>
      <tr>
        <td>3</td>
        <td><span class="badge be">BE</span></td>
        <td><code>upload_server.py</code></td>
        <td><code>POST /api/upload</code></td>
        <td>Validates extension, saves .xlsx to <code>_uploads/</code>, spawns background thread</td>
        <td><code>{ ok: true, filename }</code></td>
      </tr>
      <tr>
        <td>4</td>
        <td><span class="badge be">BE</span></td>
        <td><code>upload_server.py</code></td>
        <td><code>_run_pipeline()</code></td>
        <td>Calls <code>python -m pipeline.run --input file.xlsx --output output/</code> via subprocess.Popen (streams live)</td>
        <td>Terminal log</td>
      </tr>
      <tr>
        <td>5</td>
        <td><span class="badge py">PY</span></td>
        <td><code>pipeline/loader.py</code></td>
        <td><code>load_data()</code></td>
        <td>Reads sheet <em>1_Source_Data</em>; computes Price = Value / Volume; drops nulls</td>
        <td>DataFrame</td>
      </tr>
      <tr>
        <td>6</td>
        <td><span class="badge py">PY</span></td>
        <td><code>pipeline/run.py</code></td>
        <td><code>read_brand_config()</code></td>
        <td>Reads sheet <em>2_Brand_Config</em>; extracts focal brand + competitors</td>
        <td>brand config dict</td>
      </tr>
      <tr>
        <td>7</td>
        <td><span class="badge py">PY</span></td>
        <td><code>pipeline/modelling.py</code></td>
        <td><code>build_wide_pivot()</code></td>
        <td>One wide table per Channel Γ— Region grain with focal + competitor columns</td>
        <td>wide DataFrame</td>
      </tr>
      <tr>
        <td>8</td>
        <td><span class="badge py">PY</span></td>
        <td><code>pipeline/diagnostics.py</code></td>
        <td><code>run_diagnostics()</code></td>
        <td>Pearson correlation, CV, RPI checks per grain; writes Excel diagnostics file</td>
        <td><code>*_Diagnostics.xlsx</code></td>
      </tr>
      <tr>
        <td>9</td>
        <td><span class="badge py">PY</span></td>
        <td><code>pipeline/modelling.py</code></td>
        <td><code>run_elasticity_models()</code></td>
        <td>OLS regression on all spec combos; selects best Adj-RΒ² with correct sign; clamps to [βˆ’6, 0]</td>
        <td>results DataFrame</td>
      </tr>
      <tr>
        <td>10</td>
        <td><span class="badge py">PY</span></td>
        <td><code>pipeline/proxies.py</code></td>
        <td><code>assign_proxies()</code></td>
        <td>Wrong-sign grains borrow elasticity from adjacent/nearby grains</td>
        <td>final elasticities</td>
      </tr>
      <tr>
        <td>11</td>
        <td><span class="badge py">PY</span></td>
        <td><code>pipeline/exporters/stats.py</code></td>
        <td><code>export_stats()</code></td>
        <td>Writes elasticity results + brand KPIs</td>
        <td><code>models.json, stats.json, freq_anchors.json</code></td>
      </tr>
      <tr>
        <td>12</td>
        <td><span class="badge py">PY</span></td>
        <td><code>pipeline/exporters/market.py</code></td>
        <td><code>export_market()</code></td>
        <td>Writes time-series, market share, volume/value share</td>
        <td><code>trend.json, ms.json, vol_salience.json, val_share.json, comp_ms.json, vtm.json</code></td>
      </tr>
      <tr>
        <td>13</td>
        <td><span class="badge py">PY</span></td>
        <td><code>pipeline/exporters/ppa.py</code></td>
        <td><code>export_ppa()</code></td>
        <td>Reads sheets <em>3_PPA_MT</em> and <em>4_PPA_TT</em> from original xlsx</td>
        <td><code>ppa_mt.json, ppa_tt.json</code></td>
      </tr>
      <tr>
        <td>14</td>
        <td><span class="badge py">PY</span></td>
        <td><code>pipeline/exporters/analytics.py</code></td>
        <td><code>export_analytics()</code></td>
        <td>Cross-brand correlations, growth decomposition, price gradient index</td>
        <td><code>interaction.json, growth_decomp.json, pgi.json</code></td>
      </tr>
      <tr>
        <td>15</td>
        <td><span class="badge py">PY</span></td>
        <td><code>pipeline/exporters/recommendations.py</code></td>
        <td><code>export_recs()</code></td>
        <td>Builds pricing recommendation cards per pack using elasticities</td>
        <td><code>recs_full.json</code></td>
      </tr>
      <tr>
        <td>16</td>
        <td><span class="badge be">BE</span></td>
        <td><code>upload_server.py</code></td>
        <td><code>GET /api/data/{key}</code></td>
        <td>Reads <code>output/{key}.json</code> and returns as JSON response to React</td>
        <td>JSON to browser</td>
      </tr>
      <tr>
        <td>17</td>
        <td><span class="badge fe">FE</span></td>
        <td><code>DataContext.jsx</code></td>
        <td><code>fetchKey()</code></td>
        <td>Tries <code>/api/data/{key}</code> first; falls back to <code>/data/{key}.json</code> (static)</td>
        <td>React state updated</td>
      </tr>
      <tr>
        <td>18</td>
        <td><span class="badge fe">FE</span></td>
        <td><code>src/components/tabs/</code></td>
        <td>All tab components</td>
        <td>Read from DataContext and render charts, tables, recommendation cards</td>
        <td>Dashboard UI</td>
      </tr>
    </tbody>
  </table>
</div>

<!-- ══════════════════════════════════════════════════════════════ -->
<!-- DATA SERVING β€” TWO-TIER                                       -->
<!-- ══════════════════════════════════════════════════════════════ -->
<div class="card">
  <div class="card-title">Data Serving β€” Two-Tier Fallback</div>

  <div class="mermaid">
flowchart TD
  A["React: fetchKey(key)"] --> B{"FastAPI server\nreachable?"}
  B -- Yes --> C["GET /api/data/{key}\nlocalhost:8000"]
  B -- No  --> D["GET /data/{key}.json\nVite static (public/data/)"]
  C -- "200 OK" --> E["Use API response\n(always fresh)"]
  C -- "404 / error" --> D
  D -- "200 OK" --> F["Use static file\n(last pipeline run)"]
  D -- "404 / error" --> G["null β€” tab shows empty state"]

  style E fill:#e8f5e9,stroke:#2e7d32
  style F fill:#fff3e0,stroke:#c84b00
  style G fill:#fce4ec,stroke:#b71c1c
  </div>
</div>

<!-- ══════════════════════════════════════════════════════════════ -->
<!-- FILE MAP                                                       -->
<!-- ══════════════════════════════════════════════════════════════ -->
<div class="card">
  <div class="card-title">Output File Map β€” JSON Key &rarr; Dashboard Tab</div>

  <table>
    <thead>
      <tr>
        <th>JSON file</th>
        <th>API key</th>
        <th>Pipeline exporter</th>
        <th>Dashboard tab / component</th>
      </tr>
    </thead>
    <tbody>
      <tr><td><code>models.json</code></td><td><code>models</code></td><td>stats.py</td><td>Results β€” elasticity table</td></tr>
      <tr><td><code>stats.json</code></td><td><code>stats</code></td><td>stats.py</td><td>Header KPIs, brand summary</td></tr>
      <tr><td><code>freq_anchors.json</code></td><td><code>freq_anchors</code></td><td>stats.py</td><td>Results β€” frequency anchors</td></tr>
      <tr><td><code>trend.json</code></td><td><code>trend</code></td><td>market.py</td><td>Trends tab β€” time-series chart</td></tr>
      <tr><td><code>ms.json</code></td><td><code>ms</code></td><td>market.py</td><td>Market Share tab</td></tr>
      <tr><td><code>vol_salience.json</code></td><td><code>vol_salience</code></td><td>market.py</td><td>Growth tab β€” pack salience</td></tr>
      <tr><td><code>val_share.json</code></td><td><code>val_share</code></td><td>market.py</td><td>Growth tab β€” value share</td></tr>
      <tr><td><code>comp_ms.json</code></td><td><code>comp_ms</code></td><td>market.py</td><td>Market Share β€” all brands</td></tr>
      <tr><td><code>vtm.json</code></td><td><code>vtm</code></td><td>market.py</td><td>Results β€” volume-to-market</td></tr>
      <tr><td><code>ppa_mt.json</code></td><td><code>ppa_mt</code></td><td>ppa.py</td><td>PPA tab β€” Modern Trade</td></tr>
      <tr><td><code>ppa_tt.json</code></td><td><code>ppa_tt</code></td><td>ppa.py</td><td>PPA tab β€” Traditional Trade</td></tr>
      <tr><td><code>interaction.json</code></td><td><code>interaction</code></td><td>analytics.py</td><td>Interaction tab β€” correlation matrix</td></tr>
      <tr><td><code>growth_decomp.json</code></td><td><code>growth_decomp</code></td><td>analytics.py</td><td>Growth tab β€” decomposition chart</td></tr>
      <tr><td><code>pgi.json</code></td><td><code>pgi</code></td><td>analytics.py</td><td>Methodology tab β€” price gradient</td></tr>
      <tr><td><code>recs_full.json</code></td><td><code>recs / recs_full</code></td><td>recommendations.py</td><td>Recommendations tab β€” cards</td></tr>
    </tbody>
  </table>
</div>

<script>
  mermaid.initialize({
    startOnLoad: true,
    theme: 'default',
    themeVariables: {
      primaryColor: '#e8f5e9',
      primaryTextColor: '#1b2e1b',
      primaryBorderColor: '#2e7d32',
      lineColor: '#2e7d32',
      secondaryColor: '#fff3e0',
      tertiaryColor: '#f3e5f5',
      fontSize: '13px',
    },
    flowchart: { curve: 'basis', padding: 20 },
    sequence:  { actorMargin: 80, messageMargin: 40, mirrorActors: false },
  })
</script>
</body>
</html>