pict-section-flow 0.0.17 → 0.0.19
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.
- package/README.md +18 -18
- package/docs/Architecture.md +1 -1
- package/docs/Data_Model.md +2 -2
- package/docs/Getting_Started.md +5 -5
- package/docs/Implementation_Reference.md +6 -6
- package/docs/Layout_Persistence.md +3 -3
- package/docs/README.md +12 -12
- package/docs/Theme_Integration.md +150 -0
- package/docs/_cover.md +1 -1
- package/docs/_sidebar.md +7 -6
- package/docs/_version.json +7 -0
- package/docs/api/PictFlowCard.md +6 -6
- package/docs/api/PictFlowCardPropertiesPanel.md +2 -2
- package/docs/api/addConnection.md +4 -4
- package/docs/api/addNode.md +6 -6
- package/docs/api/autoLayout.md +2 -2
- package/docs/api/getFlowData.md +5 -5
- package/docs/api/marshalToView.md +3 -3
- package/docs/api/openPanel.md +2 -2
- package/docs/api/registerHandler.md +3 -3
- package/docs/api/registerNodeType.md +3 -3
- package/docs/api/removeConnection.md +5 -5
- package/docs/api/removeNode.md +6 -6
- package/docs/api/saveLayout.md +2 -2
- package/docs/api/screenToSVGCoords.md +2 -2
- package/docs/api/selectNode.md +3 -3
- package/docs/api/setTheme.md +2 -2
- package/docs/api/setZoom.md +3 -3
- package/docs/api/toggleFullscreen.md +2 -2
- package/docs/card-help/EACH.md +3 -3
- package/docs/card-help/FREAD.md +5 -5
- package/docs/card-help/FWRITE.md +5 -5
- package/docs/card-help/GET.md +2 -2
- package/docs/card-help/ITE.md +3 -3
- package/docs/card-help/LOG.md +4 -4
- package/docs/card-help/NOTE.md +1 -1
- package/docs/card-help/PREV.md +2 -2
- package/docs/card-help/SET.md +5 -5
- package/docs/card-help/SPKL.md +2 -2
- package/docs/card-help/STAT.md +3 -3
- package/docs/card-help/SW.md +4 -4
- package/docs/css/docuserve.css +277 -23
- package/docs/index.html +2 -2
- package/docs/retold-catalog.json +1 -1
- package/docs/retold-keyword-index.json +1 -1
- package/example_applications/simple_cards/css/flowexample.css +2 -2
- package/example_applications/simple_cards/source/card-help-content.js +12 -12
- package/example_applications/simple_cards/source/cards/FlowCard-DataPreview.js +1 -1
- package/example_applications/simple_cards/source/sample-flows.js +410 -0
- package/example_applications/simple_cards/source/views/PictView-FlowExample-About.js +5 -5
- package/example_applications/simple_cards/source/views/PictView-FlowExample-Documentation.js +5 -5
- package/example_applications/simple_cards/source/views/PictView-FlowExample-FileWriteInfo.js +4 -4
- package/example_applications/simple_cards/source/views/PictView-FlowExample-MainWorkspace.js +141 -8
- package/example_applications/simple_cards/source/views/PictView-FlowExample-TopBar.js +2 -2
- package/package.json +8 -7
- package/source/Pict-Section-Flow.js +26 -0
- package/source/providers/PictProvider-Flow-CSS.js +435 -61
- package/source/providers/PictProvider-Flow-ConnectorShapes.js +9 -5
- package/source/providers/PictProvider-Flow-NodeTypes.js +10 -0
- package/source/providers/PictProvider-Flow-PanelChrome.js +7 -17
- package/source/providers/PictProvider-Flow-Theme.js +7 -7
- package/source/providers/edges/Edge-Bezier.js +41 -0
- package/source/providers/edges/Edge-Orthogonal.js +37 -0
- package/source/providers/edges/Edge-OrthogonalSnap.js +72 -0
- package/source/providers/edges/Edge-Perimeter-Linear.js +31 -0
- package/source/providers/edges/Edge-Perimeter-Orthogonal.js +39 -0
- package/source/providers/edges/Edge-Perimeter.js +48 -0
- package/source/providers/edges/Edge-PerimeterMath.js +92 -0
- package/source/providers/edges/Edge-Straight.js +24 -0
- package/source/providers/layouts/Layout-Circular.js +203 -0
- package/source/providers/layouts/Layout-Coerce.js +40 -0
- package/source/providers/layouts/Layout-Columnar.js +134 -0
- package/source/providers/layouts/Layout-Custom.js +27 -0
- package/source/providers/layouts/Layout-ForcedFromCenter.js +256 -0
- package/source/providers/layouts/Layout-Grid.js +134 -0
- package/source/providers/layouts/Layout-Layered.js +209 -0
- package/source/providers/layouts/Layout-Tabular.js +94 -0
- package/source/services/PictService-Flow-ConnectionRenderer.js +532 -28
- package/source/services/PictService-Flow-DataManager.js +12 -1
- package/source/services/PictService-Flow-InteractionManager.js +39 -42
- package/source/services/PictService-Flow-Layout.js +305 -121
- package/source/services/PictService-Flow-PortRenderer.js +108 -26
- package/source/services/PictService-Flow-RenderManager.js +41 -11
- package/source/views/PictView-Flow-FloatingToolbar.js +69 -61
- package/source/views/PictView-Flow-Node.js +47 -6
- package/source/views/PictView-Flow-PropertiesPanel.js +46 -53
- package/source/views/PictView-Flow-Toolbar.js +1065 -485
- package/source/views/PictView-Flow.js +455 -7
- package/test/Layout_tests.js +1400 -0
- package/test/PortRenderer_tests.js +11 -2
|
@@ -37,120 +37,154 @@ class PictProviderFlowCSS extends libFableServiceProviderBase
|
|
|
37
37
|
/* ── Design Tokens ─────────────────────────────────────
|
|
38
38
|
Override these custom properties to theme the flow diagram.
|
|
39
39
|
Node-type classes (.pict-flow-node-{type}) can scope-override
|
|
40
|
-
any variable for per-type variation.
|
|
40
|
+
any variable for per-type variation.
|
|
41
|
+
|
|
42
|
+
Defaults reference the host application's pict-provider-theme
|
|
43
|
+
tokens (--theme-color-*) when available, with hardcoded
|
|
44
|
+
fallbacks so the editor still looks reasonable in unthemed
|
|
45
|
+
contexts. Internal flow themes (sketch, blueprint, etc.) keep
|
|
46
|
+
layering on top via .pict-flow-container scoped overrides. */
|
|
41
47
|
|
|
42
48
|
/* Text */
|
|
43
|
-
--pf-text-primary: #2c3e50;
|
|
44
|
-
--pf-text-heading: #1a252f;
|
|
45
|
-
--pf-text-secondary: #7f8c8d;
|
|
46
|
-
--pf-text-tertiary: #8e99a4;
|
|
47
|
-
--pf-text-placeholder: #95a5a6;
|
|
49
|
+
--pf-text-primary: var(--theme-color-text-primary, #2c3e50);
|
|
50
|
+
--pf-text-heading: var(--theme-color-text-primary, #1a252f);
|
|
51
|
+
--pf-text-secondary: var(--theme-color-text-secondary, #7f8c8d);
|
|
52
|
+
--pf-text-tertiary: var(--theme-color-text-muted, #8e99a4);
|
|
53
|
+
--pf-text-placeholder: var(--theme-color-text-placeholder, #95a5a6);
|
|
48
54
|
|
|
49
55
|
/* Node */
|
|
50
|
-
--pf-node-body-fill: #ffffff;
|
|
51
|
-
--pf-node-body-stroke: #d0d4d8;
|
|
52
|
-
--pf-node-body-stroke-hover: #b0b8c0;
|
|
56
|
+
--pf-node-body-fill: var(--theme-color-background-panel, #ffffff);
|
|
57
|
+
--pf-node-body-stroke: var(--theme-color-border-default, #d0d4d8);
|
|
58
|
+
--pf-node-body-stroke-hover: var(--theme-color-border-strong, #b0b8c0);
|
|
53
59
|
--pf-node-body-stroke-width: 1;
|
|
54
60
|
--pf-node-body-radius: 8px;
|
|
55
|
-
--pf-node-shadow: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.10));
|
|
56
|
-
--pf-node-shadow-hover: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.15));
|
|
61
|
+
--pf-node-shadow: drop-shadow(0 1px 3px var(--theme-color-shadow-color, rgba(0, 0, 0, 0.10)));
|
|
62
|
+
--pf-node-shadow-hover: drop-shadow(0 2px 6px var(--theme-color-shadow-color, rgba(0, 0, 0, 0.15)));
|
|
57
63
|
--pf-node-shadow-selected: drop-shadow(0 2px 8px rgba(52, 152, 219, 0.25));
|
|
58
|
-
--pf-node-shadow-dragging: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.20));
|
|
59
|
-
--pf-node-title-fill: #ffffff;
|
|
64
|
+
--pf-node-shadow-dragging: drop-shadow(0 4px 12px var(--theme-color-shadow-color, rgba(0, 0, 0, 0.20)));
|
|
65
|
+
--pf-node-title-fill: var(--theme-color-background-panel, #ffffff);
|
|
60
66
|
--pf-node-title-size: 11.5px;
|
|
61
67
|
--pf-node-title-weight: 600;
|
|
62
|
-
--pf-node-title-bar-color: #2c3e50;
|
|
63
|
-
--pf-node-type-label-fill: #a0a8b0;
|
|
64
|
-
--pf-node-selected-stroke: #3498db;
|
|
68
|
+
--pf-node-title-bar-color: var(--theme-color-text-primary, #2c3e50);
|
|
69
|
+
--pf-node-type-label-fill: var(--theme-color-text-muted, #a0a8b0);
|
|
70
|
+
--pf-node-selected-stroke: var(--theme-color-brand-primary, #3498db);
|
|
65
71
|
|
|
66
72
|
/* Node Variants */
|
|
67
73
|
--pf-node-start-fill: #eafaf1;
|
|
68
|
-
--pf-node-start-stroke: #27ae60;
|
|
74
|
+
--pf-node-start-stroke: var(--theme-color-status-success, #27ae60);
|
|
69
75
|
--pf-node-end-fill: #e8f8f5;
|
|
70
76
|
--pf-node-end-stroke: #1abc9c;
|
|
71
77
|
--pf-node-halt-fill: #fdedec;
|
|
72
|
-
--pf-node-halt-stroke: #e74c3c;
|
|
78
|
+
--pf-node-halt-stroke: var(--theme-color-status-error, #e74c3c);
|
|
73
79
|
--pf-node-decision-fill: #fff9e6;
|
|
74
|
-
--pf-node-decision-stroke: #f39c12;
|
|
80
|
+
--pf-node-decision-stroke: var(--theme-color-status-warning, #f39c12);
|
|
81
|
+
|
|
82
|
+
/* ── Color roles ───────────────────────────────────────
|
|
83
|
+
Generic, theme-aware semantic colors that node types and
|
|
84
|
+
individual cards opt into via a ColorRole field. The
|
|
85
|
+
"-soft" variant is the tinted background; the bare role is
|
|
86
|
+
the title-bar / outline / accent stroke.
|
|
87
|
+
|
|
88
|
+
Hosts can override any of these tokens at .pict-flow-container
|
|
89
|
+
scope (or at their own scope) without touching JS. Built-in
|
|
90
|
+
node types resolve their visuals through these tokens, so
|
|
91
|
+
theming a role automatically retints every card that uses it.
|
|
92
|
+
|
|
93
|
+
Soft tints use color-mix() — supported in Chrome 111+,
|
|
94
|
+
Safari 16.2+, Firefox 113+. The hardcoded fallbacks keep the
|
|
95
|
+
editor presentable on older engines. */
|
|
96
|
+
--pf-color-success: var(--theme-color-status-success, #27ae60);
|
|
97
|
+
--pf-color-success-soft: color-mix(in srgb, var(--pf-color-success) 12%, transparent);
|
|
98
|
+
--pf-color-warning: var(--theme-color-status-warning, #f39c12);
|
|
99
|
+
--pf-color-warning-soft: color-mix(in srgb, var(--pf-color-warning) 14%, transparent);
|
|
100
|
+
--pf-color-error: var(--theme-color-status-error, #e74c3c);
|
|
101
|
+
--pf-color-error-soft: color-mix(in srgb, var(--pf-color-error) 12%, transparent);
|
|
102
|
+
--pf-color-info: var(--theme-color-status-info, #3498db);
|
|
103
|
+
--pf-color-info-soft: color-mix(in srgb, var(--pf-color-info) 12%, transparent);
|
|
104
|
+
--pf-color-accent: var(--theme-color-brand-accent, #1abc9c);
|
|
105
|
+
--pf-color-accent-soft: color-mix(in srgb, var(--pf-color-accent) 14%, transparent);
|
|
106
|
+
--pf-color-neutral: var(--theme-color-text-primary, #2c3e50);
|
|
107
|
+
--pf-color-neutral-soft: var(--theme-color-background-panel, #ffffff);
|
|
108
|
+
--pf-color-neutral-onfill: var(--theme-color-background-panel, #ffffff);
|
|
75
109
|
|
|
76
110
|
/* Ports */
|
|
77
|
-
--pf-port-input-fill: #3498db;
|
|
78
|
-
--pf-port-output-fill: #2ecc71;
|
|
79
|
-
--pf-port-stroke: #ffffff;
|
|
111
|
+
--pf-port-input-fill: var(--theme-color-status-info, #3498db);
|
|
112
|
+
--pf-port-output-fill: var(--theme-color-status-success, #2ecc71);
|
|
113
|
+
--pf-port-stroke: var(--theme-color-background-panel, #ffffff);
|
|
80
114
|
--pf-port-stroke-width: 2;
|
|
81
115
|
--pf-port-label-bg: rgba(255, 253, 240, 0.5);
|
|
82
|
-
--pf-port-label-text: #2c3e50;
|
|
116
|
+
--pf-port-label-text: var(--theme-color-text-primary, #2c3e50);
|
|
83
117
|
|
|
84
118
|
/* Port Type Colors */
|
|
85
|
-
--pf-port-event-in-fill: #3498db;
|
|
86
|
-
--pf-port-event-out-fill: #2ecc71;
|
|
119
|
+
--pf-port-event-in-fill: var(--theme-color-status-info, #3498db);
|
|
120
|
+
--pf-port-event-out-fill: var(--theme-color-status-success, #2ecc71);
|
|
87
121
|
--pf-port-setting-fill: #e67e22;
|
|
88
122
|
--pf-port-value-fill: #f1c40f;
|
|
89
|
-
--pf-port-error-fill: #e74c3c;
|
|
123
|
+
--pf-port-error-fill: var(--theme-color-status-error, #e74c3c);
|
|
90
124
|
|
|
91
125
|
/* Connection Type Colors (match source port) */
|
|
92
|
-
--pf-connection-event-in-stroke: #3498db;
|
|
93
|
-
--pf-connection-event-out-stroke: #2ecc71;
|
|
126
|
+
--pf-connection-event-in-stroke: var(--theme-color-status-info, #3498db);
|
|
127
|
+
--pf-connection-event-out-stroke: var(--theme-color-status-success, #2ecc71);
|
|
94
128
|
--pf-connection-setting-stroke: #e67e22;
|
|
95
129
|
--pf-connection-value-stroke: #f1c40f;
|
|
96
|
-
--pf-connection-error-stroke: #e74c3c;
|
|
130
|
+
--pf-connection-error-stroke: var(--theme-color-status-error, #e74c3c);
|
|
97
131
|
|
|
98
132
|
/* Connections */
|
|
99
|
-
--pf-connection-stroke: #95a5a6;
|
|
100
|
-
--pf-connection-stroke-hover: #7f8c8d;
|
|
101
|
-
--pf-connection-selected-stroke: #3498db;
|
|
133
|
+
--pf-connection-stroke: var(--theme-color-border-strong, #95a5a6);
|
|
134
|
+
--pf-connection-stroke-hover: var(--theme-color-text-secondary, #7f8c8d);
|
|
135
|
+
--pf-connection-selected-stroke: var(--theme-color-brand-primary, #3498db);
|
|
102
136
|
|
|
103
137
|
/* Panels */
|
|
104
|
-
--pf-panel-bg: #ffffff;
|
|
105
|
-
--pf-panel-border: #d0d4d8;
|
|
138
|
+
--pf-panel-bg: var(--theme-color-background-panel, #ffffff);
|
|
139
|
+
--pf-panel-border: var(--theme-color-border-default, #d0d4d8);
|
|
106
140
|
--pf-panel-radius: 8px;
|
|
107
|
-
--pf-panel-shadow: 0 4px 12px rgba(0,0,0,0.10), 0 1px 3px rgba(0,0,0,0.06);
|
|
108
|
-
--pf-panel-titlebar-bg: #f7f8fa;
|
|
109
|
-
--pf-panel-titlebar-border: #e8eaed;
|
|
110
|
-
--pf-panel-title-color: #2c3e50;
|
|
141
|
+
--pf-panel-shadow: 0 4px 12px var(--theme-color-shadow-color, rgba(0, 0, 0, 0.10)), 0 1px 3px var(--theme-color-shadow-color, rgba(0, 0, 0, 0.06));
|
|
142
|
+
--pf-panel-titlebar-bg: var(--theme-color-background-secondary, #f7f8fa);
|
|
143
|
+
--pf-panel-titlebar-border: var(--theme-color-border-light, #e8eaed);
|
|
144
|
+
--pf-panel-title-color: var(--theme-color-text-primary, #2c3e50);
|
|
111
145
|
|
|
112
146
|
/* Tabs */
|
|
113
|
-
--pf-tab-text: #8e99a4;
|
|
114
|
-
--pf-tab-text-hover: #5a6a7a;
|
|
147
|
+
--pf-tab-text: var(--theme-color-text-muted, #8e99a4);
|
|
148
|
+
--pf-tab-text-hover: var(--theme-color-text-secondary, #5a6a7a);
|
|
115
149
|
--pf-tab-active-border: var(--pf-node-selected-stroke);
|
|
116
|
-
--pf-resize-handle-hover: #e0e3e6;
|
|
150
|
+
--pf-resize-handle-hover: var(--theme-color-border-light, #e0e3e6);
|
|
117
151
|
|
|
118
152
|
/* Forms & Inputs */
|
|
119
|
-
--pf-input-border: #d5d8dc;
|
|
120
|
-
--pf-input-border-focus: #3498db;
|
|
121
|
-
--pf-divider-light: #ecf0f1;
|
|
122
|
-
--pf-divider-medium: #e8eaed;
|
|
153
|
+
--pf-input-border: var(--theme-color-border-default, #d5d8dc);
|
|
154
|
+
--pf-input-border-focus: var(--theme-color-focus-outline, #3498db);
|
|
155
|
+
--pf-divider-light: var(--theme-color-border-light, #ecf0f1);
|
|
156
|
+
--pf-divider-medium: var(--theme-color-border-light, #e8eaed);
|
|
123
157
|
|
|
124
158
|
/* Buttons */
|
|
125
|
-
--pf-button-border: #bdc3c7;
|
|
126
|
-
--pf-button-hover-border: #95a5a6;
|
|
127
|
-
--pf-button-hover-bg: #ecf0f1;
|
|
128
|
-
--pf-button-active-bg: #d5dbdb;
|
|
129
|
-
--pf-button-danger-text: #e74c3c;
|
|
159
|
+
--pf-button-border: var(--theme-color-border-default, #bdc3c7);
|
|
160
|
+
--pf-button-hover-border: var(--theme-color-border-strong, #95a5a6);
|
|
161
|
+
--pf-button-hover-bg: var(--theme-color-background-hover, #ecf0f1);
|
|
162
|
+
--pf-button-active-bg: var(--theme-color-background-selected, #d5dbdb);
|
|
163
|
+
--pf-button-danger-text: var(--theme-color-status-error, #e74c3c);
|
|
130
164
|
--pf-button-danger-hover-bg: #fdedec;
|
|
131
|
-
--pf-button-close-color: #b0b8c0;
|
|
165
|
+
--pf-button-close-color: var(--theme-color-text-muted, #b0b8c0);
|
|
132
166
|
|
|
133
167
|
/* Badges */
|
|
134
|
-
--pf-badge-category-bg: #f0f2f4;
|
|
135
|
-
--pf-badge-category-text: #6b7b8d;
|
|
168
|
+
--pf-badge-category-bg: var(--theme-color-background-tertiary, #f0f2f4);
|
|
169
|
+
--pf-badge-category-text: var(--theme-color-text-secondary, #6b7b8d);
|
|
136
170
|
--pf-badge-code-bg: #eaf2f8;
|
|
137
171
|
--pf-badge-code-text: #2980b9;
|
|
138
172
|
|
|
139
173
|
/* Info Panel */
|
|
140
|
-
--pf-port-item-bg: #f8f9fa;
|
|
174
|
+
--pf-port-item-bg: var(--theme-color-background-secondary, #f8f9fa);
|
|
141
175
|
|
|
142
176
|
/* Toolbar */
|
|
143
|
-
--pf-toolbar-bg: #ffffff;
|
|
144
|
-
--pf-toolbar-border: #e0e0e0;
|
|
177
|
+
--pf-toolbar-bg: var(--theme-color-background-panel, #ffffff);
|
|
178
|
+
--pf-toolbar-border: var(--theme-color-border-default, #e0e0e0);
|
|
145
179
|
|
|
146
180
|
/* Palette Cards */
|
|
147
|
-
--pf-card-border: #d5d8dc;
|
|
148
|
-
--pf-card-hover-bg: #eaf2f8;
|
|
181
|
+
--pf-card-border: var(--theme-color-border-default, #d5d8dc);
|
|
182
|
+
--pf-card-hover-bg: var(--theme-color-background-hover, #eaf2f8);
|
|
149
183
|
--pf-card-hover-shadow: 0 1px 3px rgba(52, 152, 219, 0.15);
|
|
150
184
|
|
|
151
185
|
/* Canvas */
|
|
152
|
-
--pf-canvas-bg: #fafafa;
|
|
153
|
-
--pf-grid-stroke: #e8e8e8;
|
|
186
|
+
--pf-canvas-bg: var(--theme-color-background-secondary, #fafafa);
|
|
187
|
+
--pf-grid-stroke: var(--theme-color-border-light, #e8e8e8);
|
|
154
188
|
|
|
155
189
|
position: relative;
|
|
156
190
|
width: 100%;
|
|
@@ -330,6 +364,94 @@ class PictProviderFlowCSS extends libFableServiceProviderBase
|
|
|
330
364
|
stroke: var(--pf-node-halt-stroke);
|
|
331
365
|
stroke-width: 1.5;
|
|
332
366
|
}
|
|
367
|
+
|
|
368
|
+
/* ── Color-role variants ────────────────────────────────
|
|
369
|
+
Cards opt into a role via ColorRole on the node-type config or
|
|
370
|
+
a per-node override. The renderer adds .pict-flow-node-color-{role}
|
|
371
|
+
to the node group, which pulls fill/stroke/title-bar colors from
|
|
372
|
+
the --pf-color-* tokens — those in turn track the host's
|
|
373
|
+
--theme-color-* tokens so light/dark/palette swaps propagate.
|
|
374
|
+
|
|
375
|
+
Roles deliberately don't override .pict-flow-node-body-content-*
|
|
376
|
+
styling — the body content's visual identity is the consumer's
|
|
377
|
+
responsibility. */
|
|
378
|
+
.pict-flow-node-color-success .pict-flow-node-body {
|
|
379
|
+
fill: var(--pf-color-success-soft);
|
|
380
|
+
stroke: var(--pf-color-success);
|
|
381
|
+
stroke-width: 1.5;
|
|
382
|
+
}
|
|
383
|
+
.pict-flow-node-color-success .pict-flow-node-title-bar,
|
|
384
|
+
.pict-flow-node-color-success .pict-flow-node-title-bar-bottom {
|
|
385
|
+
fill: var(--pf-color-success);
|
|
386
|
+
}
|
|
387
|
+
.pict-flow-node-color-success .pict-flow-node-bracket {
|
|
388
|
+
stroke: var(--pf-color-success);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.pict-flow-node-color-warning .pict-flow-node-body {
|
|
392
|
+
fill: var(--pf-color-warning-soft);
|
|
393
|
+
stroke: var(--pf-color-warning);
|
|
394
|
+
stroke-width: 1.5;
|
|
395
|
+
}
|
|
396
|
+
.pict-flow-node-color-warning .pict-flow-node-title-bar,
|
|
397
|
+
.pict-flow-node-color-warning .pict-flow-node-title-bar-bottom {
|
|
398
|
+
fill: var(--pf-color-warning);
|
|
399
|
+
}
|
|
400
|
+
.pict-flow-node-color-warning .pict-flow-node-bracket {
|
|
401
|
+
stroke: var(--pf-color-warning);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.pict-flow-node-color-error .pict-flow-node-body {
|
|
405
|
+
fill: var(--pf-color-error-soft);
|
|
406
|
+
stroke: var(--pf-color-error);
|
|
407
|
+
stroke-width: 1.5;
|
|
408
|
+
}
|
|
409
|
+
.pict-flow-node-color-error .pict-flow-node-title-bar,
|
|
410
|
+
.pict-flow-node-color-error .pict-flow-node-title-bar-bottom {
|
|
411
|
+
fill: var(--pf-color-error);
|
|
412
|
+
}
|
|
413
|
+
.pict-flow-node-color-error .pict-flow-node-bracket {
|
|
414
|
+
stroke: var(--pf-color-error);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.pict-flow-node-color-info .pict-flow-node-body {
|
|
418
|
+
fill: var(--pf-color-info-soft);
|
|
419
|
+
stroke: var(--pf-color-info);
|
|
420
|
+
stroke-width: 1.5;
|
|
421
|
+
}
|
|
422
|
+
.pict-flow-node-color-info .pict-flow-node-title-bar,
|
|
423
|
+
.pict-flow-node-color-info .pict-flow-node-title-bar-bottom {
|
|
424
|
+
fill: var(--pf-color-info);
|
|
425
|
+
}
|
|
426
|
+
.pict-flow-node-color-info .pict-flow-node-bracket {
|
|
427
|
+
stroke: var(--pf-color-info);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
.pict-flow-node-color-accent .pict-flow-node-body {
|
|
431
|
+
fill: var(--pf-color-accent-soft);
|
|
432
|
+
stroke: var(--pf-color-accent);
|
|
433
|
+
stroke-width: 1.5;
|
|
434
|
+
}
|
|
435
|
+
.pict-flow-node-color-accent .pict-flow-node-title-bar,
|
|
436
|
+
.pict-flow-node-color-accent .pict-flow-node-title-bar-bottom {
|
|
437
|
+
fill: var(--pf-color-accent);
|
|
438
|
+
}
|
|
439
|
+
.pict-flow-node-color-accent .pict-flow-node-bracket {
|
|
440
|
+
stroke: var(--pf-color-accent);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.pict-flow-node-color-neutral .pict-flow-node-body {
|
|
444
|
+
fill: var(--pf-color-neutral-soft);
|
|
445
|
+
stroke: var(--pf-color-neutral);
|
|
446
|
+
stroke-width: 1;
|
|
447
|
+
}
|
|
448
|
+
.pict-flow-node-color-neutral .pict-flow-node-title-bar,
|
|
449
|
+
.pict-flow-node-color-neutral .pict-flow-node-title-bar-bottom {
|
|
450
|
+
fill: var(--pf-color-neutral);
|
|
451
|
+
}
|
|
452
|
+
.pict-flow-node-color-neutral .pict-flow-node-bracket {
|
|
453
|
+
stroke: var(--pf-color-neutral);
|
|
454
|
+
}
|
|
333
455
|
`;
|
|
334
456
|
}
|
|
335
457
|
|
|
@@ -396,6 +518,187 @@ class PictProviderFlowCSS extends libFableServiceProviderBase
|
|
|
396
518
|
.pict-flow-node-port-labels-hover:hover .pict-flow-port-label-bg {
|
|
397
519
|
opacity: 1;
|
|
398
520
|
}
|
|
521
|
+
|
|
522
|
+
/* Port-hint beziers — drawn from the badge to the actual dot
|
|
523
|
+
when an edge theme has rerouted the connection. Hidden by
|
|
524
|
+
default; PortRenderer / NodeView toggle data-active on hover. */
|
|
525
|
+
.pict-flow-port-hint {
|
|
526
|
+
fill: none;
|
|
527
|
+
stroke: var(--pf-connection-stroke-hover, #3498db);
|
|
528
|
+
stroke-width: 1.75;
|
|
529
|
+
stroke-dasharray: 4 3;
|
|
530
|
+
stroke-linecap: round;
|
|
531
|
+
opacity: 0;
|
|
532
|
+
pointer-events: none;
|
|
533
|
+
transition: opacity 0.18s ease;
|
|
534
|
+
}
|
|
535
|
+
.pict-flow-port-hint[data-active="true"] {
|
|
536
|
+
opacity: 0.7;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/* ── Layout-algorithm popup: tightened layout + form styling ── */
|
|
540
|
+
.pict-flow-popup-layout-algorithm-row {
|
|
541
|
+
display: flex;
|
|
542
|
+
flex-direction: column;
|
|
543
|
+
gap: 4px;
|
|
544
|
+
padding: 6px 10px 4px;
|
|
545
|
+
}
|
|
546
|
+
.pict-flow-popup-layout-algorithm-row > .pict-flow-popup-settings-label {
|
|
547
|
+
font-size: 10px;
|
|
548
|
+
font-weight: 700;
|
|
549
|
+
text-transform: uppercase;
|
|
550
|
+
letter-spacing: 0.05em;
|
|
551
|
+
opacity: 0.7;
|
|
552
|
+
margin: 0;
|
|
553
|
+
}
|
|
554
|
+
.pict-flow-popup-layout-algorithm-controls {
|
|
555
|
+
display: flex;
|
|
556
|
+
align-items: stretch;
|
|
557
|
+
gap: 4px;
|
|
558
|
+
}
|
|
559
|
+
.pict-flow-popup-layout-algorithm-select {
|
|
560
|
+
flex: 1 1 auto;
|
|
561
|
+
min-width: 0;
|
|
562
|
+
}
|
|
563
|
+
.pict-flow-popup-collapse-toggle {
|
|
564
|
+
flex: 0 0 auto;
|
|
565
|
+
width: 28px;
|
|
566
|
+
padding: 0;
|
|
567
|
+
border: 1px solid var(--pf-button-border, #ccc);
|
|
568
|
+
border-radius: 3px;
|
|
569
|
+
background: var(--pf-toolbar-bg, #fff);
|
|
570
|
+
color: var(--pf-text-secondary, #5a6470);
|
|
571
|
+
cursor: pointer;
|
|
572
|
+
display: inline-flex;
|
|
573
|
+
align-items: center;
|
|
574
|
+
justify-content: center;
|
|
575
|
+
transition: background-color 0.15s, color 0.15s, border-color 0.15s;
|
|
576
|
+
}
|
|
577
|
+
.pict-flow-popup-collapse-toggle:hover {
|
|
578
|
+
background-color: var(--pf-button-hover-bg, #eef);
|
|
579
|
+
color: var(--pf-text-primary, #2c3e50);
|
|
580
|
+
}
|
|
581
|
+
/* "Open" state: pressed-in look so the user sees that the form
|
|
582
|
+
below is being driven by this gear. */
|
|
583
|
+
.pict-flow-popup-collapse-toggle[aria-expanded="true"] {
|
|
584
|
+
background-color: var(--pf-button-active-bg, #d6e4f0);
|
|
585
|
+
color: var(--pf-text-primary, #2c3e50);
|
|
586
|
+
border-color: var(--pf-button-hover-border, #3498db);
|
|
587
|
+
}
|
|
588
|
+
.pict-flow-popup-collapse-toggle svg {
|
|
589
|
+
display: block;
|
|
590
|
+
}
|
|
591
|
+
/* Subordinate description text — sits under a control (algorithm
|
|
592
|
+
dropdown, edge-theme dropdown, etc.) and explains it. Indented
|
|
593
|
+
from the section's left edge with a faint left rule so the
|
|
594
|
+
visual hierarchy is unambiguous: SECTION LABEL > control >
|
|
595
|
+
description. */
|
|
596
|
+
.pict-flow-popup-control-description {
|
|
597
|
+
font-size: 11px;
|
|
598
|
+
line-height: 1.4;
|
|
599
|
+
color: var(--pf-text-secondary, #5a6470);
|
|
600
|
+
padding: 4px 12px 8px 28px;
|
|
601
|
+
margin-left: 14px;
|
|
602
|
+
border-left: 2px solid var(--pf-divider-light, #e6e6e6);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/* The form host. Acts as the collapsible container around the
|
|
606
|
+
pict-section-form metacontroller's emitted markup. */
|
|
607
|
+
.pict-flow-popup-layout-form-host {
|
|
608
|
+
margin: 0 10px 8px;
|
|
609
|
+
padding: 8px 10px;
|
|
610
|
+
background: var(--pf-toolbar-bg, #fafafa);
|
|
611
|
+
border: 1px solid var(--pf-button-border, #e0e0e0);
|
|
612
|
+
border-radius: 6px;
|
|
613
|
+
overflow: hidden;
|
|
614
|
+
max-height: 600px;
|
|
615
|
+
transition: max-height 0.22s ease, padding 0.22s ease,
|
|
616
|
+
margin 0.22s ease, border-color 0.22s ease, opacity 0.18s ease;
|
|
617
|
+
opacity: 1;
|
|
618
|
+
}
|
|
619
|
+
.pict-flow-popup-layout-form-host[data-collapsed="true"] {
|
|
620
|
+
max-height: 0;
|
|
621
|
+
padding-top: 0;
|
|
622
|
+
padding-bottom: 0;
|
|
623
|
+
margin-top: 0;
|
|
624
|
+
margin-bottom: 0;
|
|
625
|
+
border-color: transparent;
|
|
626
|
+
opacity: 0;
|
|
627
|
+
}
|
|
628
|
+
.pict-flow-popup-layout-form-host > div { width: 100%; }
|
|
629
|
+
|
|
630
|
+
/* Form contents — make the auto-rendered sections look professional.
|
|
631
|
+
The section headings stay visible; the redundant per-section
|
|
632
|
+
"Group: Defaults" h3 is suppressed. */
|
|
633
|
+
.pict-flow-popup-layout-form .pict-form-view {
|
|
634
|
+
display: block;
|
|
635
|
+
}
|
|
636
|
+
.pict-flow-popup-layout-form .pict-form-section {
|
|
637
|
+
margin: 0;
|
|
638
|
+
padding: 0;
|
|
639
|
+
}
|
|
640
|
+
.pict-flow-popup-layout-form .pict-form-section h2 {
|
|
641
|
+
font-size: 10px;
|
|
642
|
+
font-weight: 700;
|
|
643
|
+
text-transform: uppercase;
|
|
644
|
+
letter-spacing: 0.05em;
|
|
645
|
+
opacity: 0.6;
|
|
646
|
+
margin: 8px 0 4px;
|
|
647
|
+
padding: 0;
|
|
648
|
+
border-bottom: 1px solid var(--pf-button-border, #e6e6e6);
|
|
649
|
+
padding-bottom: 3px;
|
|
650
|
+
}
|
|
651
|
+
.pict-flow-popup-layout-form .pict-form-section:first-child h2,
|
|
652
|
+
.pict-flow-popup-layout-form .pict-form-section h2:first-child {
|
|
653
|
+
margin-top: 0;
|
|
654
|
+
}
|
|
655
|
+
/* Group headings ("Group: Defaults") are noise — every algorithm
|
|
656
|
+
has exactly one group right now. Hide them. */
|
|
657
|
+
.pict-flow-popup-layout-form .pict-form-section h3 {
|
|
658
|
+
display: none;
|
|
659
|
+
}
|
|
660
|
+
/* Each row of inputs lives in a flat <div> as alternating
|
|
661
|
+
<span>label</span><input> pairs. Lay them out in a balanced grid. */
|
|
662
|
+
.pict-flow-popup-layout-form .pict-form-section > div > div {
|
|
663
|
+
display: flex;
|
|
664
|
+
flex-wrap: wrap;
|
|
665
|
+
gap: 4px 14px;
|
|
666
|
+
margin: 4px 0;
|
|
667
|
+
align-items: center;
|
|
668
|
+
}
|
|
669
|
+
.pict-flow-popup-layout-form .pict-form-section span {
|
|
670
|
+
font-size: 12px;
|
|
671
|
+
color: var(--pf-text-primary, #2c3e50);
|
|
672
|
+
line-height: 1.4;
|
|
673
|
+
margin: 0;
|
|
674
|
+
}
|
|
675
|
+
.pict-flow-popup-layout-form input[type="number"],
|
|
676
|
+
.pict-flow-popup-layout-form input[type="text"],
|
|
677
|
+
.pict-flow-popup-layout-form select {
|
|
678
|
+
width: 88px;
|
|
679
|
+
padding: 2px 6px;
|
|
680
|
+
border: 1px solid var(--pf-button-border, #ccc);
|
|
681
|
+
border-radius: 3px;
|
|
682
|
+
font-size: 12px;
|
|
683
|
+
line-height: 1.3;
|
|
684
|
+
background: #fff;
|
|
685
|
+
color: var(--pf-text-primary, #2c3e50);
|
|
686
|
+
margin-left: -8px; /* tighten gap between label and its input */
|
|
687
|
+
}
|
|
688
|
+
.pict-flow-popup-layout-form select {
|
|
689
|
+
width: auto;
|
|
690
|
+
min-width: 110px;
|
|
691
|
+
}
|
|
692
|
+
.pict-flow-popup-layout-form input[type="number"]:focus,
|
|
693
|
+
.pict-flow-popup-layout-form input[type="text"]:focus,
|
|
694
|
+
.pict-flow-popup-layout-form select:focus {
|
|
695
|
+
outline: none;
|
|
696
|
+
border-color: var(--pf-button-hover-border, #3498db);
|
|
697
|
+
box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.15);
|
|
698
|
+
}
|
|
699
|
+
.pict-flow-popup-layout-form input[type="checkbox"] {
|
|
700
|
+
margin: 0 4px 0 0;
|
|
701
|
+
}
|
|
399
702
|
`;
|
|
400
703
|
}
|
|
401
704
|
|
|
@@ -407,6 +710,34 @@ class PictProviderFlowCSS extends libFableServiceProviderBase
|
|
|
407
710
|
getConnectionCSS()
|
|
408
711
|
{
|
|
409
712
|
return /*css*/`
|
|
713
|
+
/* Arrowhead markers use CSS-driven fills so they follow --pf-* tokens
|
|
714
|
+
(which in turn map to host --theme-color-* tokens). The polygon's
|
|
715
|
+
fill attribute is the fallback when CSS does not reach the marker. */
|
|
716
|
+
.pict-flow-svg .pict-flow-arrowhead-default {
|
|
717
|
+
fill: var(--pf-connection-stroke);
|
|
718
|
+
}
|
|
719
|
+
.pict-flow-svg .pict-flow-arrowhead-selected {
|
|
720
|
+
fill: var(--pf-connection-selected-stroke);
|
|
721
|
+
}
|
|
722
|
+
.pict-flow-svg .pict-flow-arrowhead-tether {
|
|
723
|
+
fill: var(--pf-connection-stroke);
|
|
724
|
+
}
|
|
725
|
+
.pict-flow-svg .pict-flow-arrowhead-event-in {
|
|
726
|
+
fill: var(--pf-connection-event-in-stroke);
|
|
727
|
+
}
|
|
728
|
+
.pict-flow-svg .pict-flow-arrowhead-event-out {
|
|
729
|
+
fill: var(--pf-connection-event-out-stroke);
|
|
730
|
+
}
|
|
731
|
+
.pict-flow-svg .pict-flow-arrowhead-setting {
|
|
732
|
+
fill: var(--pf-connection-setting-stroke);
|
|
733
|
+
}
|
|
734
|
+
.pict-flow-svg .pict-flow-arrowhead-value {
|
|
735
|
+
fill: var(--pf-connection-value-stroke);
|
|
736
|
+
}
|
|
737
|
+
.pict-flow-svg .pict-flow-arrowhead-error {
|
|
738
|
+
fill: var(--pf-connection-error-stroke);
|
|
739
|
+
}
|
|
740
|
+
|
|
410
741
|
.pict-flow-connection {
|
|
411
742
|
fill: none;
|
|
412
743
|
stroke: var(--pf-connection-stroke);
|
|
@@ -787,6 +1118,26 @@ class PictProviderFlowCSS extends libFableServiceProviderBase
|
|
|
787
1118
|
cursor: pointer;
|
|
788
1119
|
flex: 0 0 28px;
|
|
789
1120
|
}
|
|
1121
|
+
|
|
1122
|
+
/* Suppress native number-input spinner buttons on every input
|
|
1123
|
+
inside a properties panel. Panels live inside <foreignObject>;
|
|
1124
|
+
browsers (Chromium / WebKit) render the up/down spinner chrome
|
|
1125
|
+
as native overlays that don't always respect SVG transforms or
|
|
1126
|
+
the parent tab pane's display:none — leaving stale spinner
|
|
1127
|
+
artifacts hanging around when the user switches tabs or pans
|
|
1128
|
+
the diagram. The user can still type numbers; they just don't
|
|
1129
|
+
get clickable spinners. (If we ever want spinners back, build
|
|
1130
|
+
them as real DOM elements next to the input, not native chrome.) */
|
|
1131
|
+
.pict-flow-panel input[type="number"] {
|
|
1132
|
+
-moz-appearance: textfield;
|
|
1133
|
+
appearance: textfield;
|
|
1134
|
+
}
|
|
1135
|
+
.pict-flow-panel input[type="number"]::-webkit-outer-spin-button,
|
|
1136
|
+
.pict-flow-panel input[type="number"]::-webkit-inner-spin-button {
|
|
1137
|
+
-webkit-appearance: none;
|
|
1138
|
+
appearance: none;
|
|
1139
|
+
margin: 0;
|
|
1140
|
+
}
|
|
790
1141
|
`;
|
|
791
1142
|
}
|
|
792
1143
|
|
|
@@ -954,6 +1305,29 @@ class PictProviderFlowCSS extends libFableServiceProviderBase
|
|
|
954
1305
|
align-items: center;
|
|
955
1306
|
margin-left: 0.15em;
|
|
956
1307
|
}
|
|
1308
|
+
/* Split button — visible as one connected unit; the two halves
|
|
1309
|
+
route to different actions. Used for "Auto" so clicking the
|
|
1310
|
+
icon/text applies the current layout while the chevron half
|
|
1311
|
+
opens the algorithm popup with a generous hit area. */
|
|
1312
|
+
.pict-flow-toolbar-btn-split {
|
|
1313
|
+
display: inline-flex;
|
|
1314
|
+
align-items: stretch;
|
|
1315
|
+
}
|
|
1316
|
+
.pict-flow-toolbar-btn-split-main {
|
|
1317
|
+
border-top-right-radius: 0;
|
|
1318
|
+
border-bottom-right-radius: 0;
|
|
1319
|
+
border-right: 1px solid var(--pf-button-border);
|
|
1320
|
+
margin-right: -1px; /* collapse the seam between the two buttons */
|
|
1321
|
+
}
|
|
1322
|
+
.pict-flow-toolbar-btn-split-chevron {
|
|
1323
|
+
border-top-left-radius: 0;
|
|
1324
|
+
border-bottom-left-radius: 0;
|
|
1325
|
+
padding-left: 0.55em;
|
|
1326
|
+
padding-right: 0.55em;
|
|
1327
|
+
}
|
|
1328
|
+
.pict-flow-toolbar-btn-split-chevron .pict-flow-toolbar-btn-chevron {
|
|
1329
|
+
margin: 0;
|
|
1330
|
+
}
|
|
957
1331
|
.pict-flow-toolbar-right {
|
|
958
1332
|
margin-left: auto;
|
|
959
1333
|
border-right: none;
|
|
@@ -1075,7 +1449,7 @@ class PictProviderFlowCSS extends libFableServiceProviderBase
|
|
|
1075
1449
|
border-radius: 6px;
|
|
1076
1450
|
box-shadow: 0 4px 16px rgba(0,0,0,0.12);
|
|
1077
1451
|
min-width: 240px;
|
|
1078
|
-
max-height:
|
|
1452
|
+
max-height: 80vh;
|
|
1079
1453
|
overflow-y: auto;
|
|
1080
1454
|
padding: 0.35em 0;
|
|
1081
1455
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
@@ -409,14 +409,18 @@ class PictProviderFlowConnectorShapes extends libFableServiceProviderBase
|
|
|
409
409
|
|
|
410
410
|
let tmpMarkup = '';
|
|
411
411
|
|
|
412
|
-
// Normal connection arrowhead
|
|
412
|
+
// Normal connection arrowhead — class-driven fill so the host theme's
|
|
413
|
+
// --theme-color-* tokens (mapped to --pf-connection-stroke etc. in
|
|
414
|
+
// PictProvider-Flow-CSS) flow through automatically. The polygon's
|
|
415
|
+
// `fill` attribute is kept as a fallback for environments that
|
|
416
|
+
// ignore CSS rules on marker children.
|
|
413
417
|
tmpMarkup += '<marker id="flow-arrowhead-' + pViewIdentifier + '"'
|
|
414
418
|
+ ' markerWidth="' + tmpConnectionMarker.MarkerWidth + '"'
|
|
415
419
|
+ ' markerHeight="' + tmpConnectionMarker.MarkerHeight + '"'
|
|
416
420
|
+ ' refX="' + tmpConnectionMarker.RefX + '"'
|
|
417
421
|
+ ' refY="' + tmpConnectionMarker.RefY + '"'
|
|
418
422
|
+ ' orient="auto" markerUnits="strokeWidth">'
|
|
419
|
-
+ '<polygon points="' + tmpConnectionMarker.Points + '" fill="' + tmpConnectionMarker.Fill + '" />'
|
|
423
|
+
+ '<polygon class="pict-flow-arrowhead pict-flow-arrowhead-default" points="' + tmpConnectionMarker.Points + '" fill="' + tmpConnectionMarker.Fill + '" />'
|
|
420
424
|
+ '</marker>';
|
|
421
425
|
|
|
422
426
|
// Per-port-type connection arrowheads
|
|
@@ -437,7 +441,7 @@ class PictProviderFlowConnectorShapes extends libFableServiceProviderBase
|
|
|
437
441
|
+ ' refX="' + tmpConnectionMarker.RefX + '"'
|
|
438
442
|
+ ' refY="' + tmpConnectionMarker.RefY + '"'
|
|
439
443
|
+ ' orient="auto" markerUnits="strokeWidth">'
|
|
440
|
-
+ '<polygon points="' + tmpConnectionMarker.Points + '" fill="' + tmpPortTypeColors[tmpType] + '" />'
|
|
444
|
+
+ '<polygon class="pict-flow-arrowhead pict-flow-arrowhead-' + tmpType + '" points="' + tmpConnectionMarker.Points + '" fill="' + tmpPortTypeColors[tmpType] + '" />'
|
|
441
445
|
+ '</marker>';
|
|
442
446
|
}
|
|
443
447
|
|
|
@@ -448,7 +452,7 @@ class PictProviderFlowConnectorShapes extends libFableServiceProviderBase
|
|
|
448
452
|
+ ' refX="' + tmpSelectedMarker.RefX + '"'
|
|
449
453
|
+ ' refY="' + tmpSelectedMarker.RefY + '"'
|
|
450
454
|
+ ' orient="auto" markerUnits="strokeWidth">'
|
|
451
|
-
+ '<polygon points="' + tmpSelectedMarker.Points + '" fill="' + tmpSelectedMarker.Fill + '" />'
|
|
455
|
+
+ '<polygon class="pict-flow-arrowhead pict-flow-arrowhead-selected" points="' + tmpSelectedMarker.Points + '" fill="' + tmpSelectedMarker.Fill + '" />'
|
|
452
456
|
+ '</marker>';
|
|
453
457
|
|
|
454
458
|
// Tether arrowhead
|
|
@@ -458,7 +462,7 @@ class PictProviderFlowConnectorShapes extends libFableServiceProviderBase
|
|
|
458
462
|
+ ' refX="' + tmpTetherMarker.RefX + '"'
|
|
459
463
|
+ ' refY="' + tmpTetherMarker.RefY + '"'
|
|
460
464
|
+ ' orient="auto" markerUnits="strokeWidth">'
|
|
461
|
-
+ '<polygon points="' + tmpTetherMarker.Points + '" fill="' + tmpTetherMarker.Fill + '" />'
|
|
465
|
+
+ '<polygon class="pict-flow-arrowhead pict-flow-arrowhead-tether" points="' + tmpTetherMarker.Points + '" fill="' + tmpTetherMarker.Fill + '" />'
|
|
462
466
|
+ '</marker>';
|
|
463
467
|
|
|
464
468
|
return tmpMarkup;
|