MarcSkovMadsen commited on
Commit
597e03a
1 Parent(s): 0ac4332

Upload 5 files

Browse files
Files changed (5) hide show
  1. README.md +16 -4
  2. index.html +338 -18
  3. index.js +197 -0
  4. index.py +93 -0
  5. requirements.txt +2 -0
README.md CHANGED
@@ -1,11 +1,23 @@
1
  ---
2
  title: Streaming Indicators
3
- emoji: 😻
4
- colorFrom: purple
5
- colorTo: yellow
6
  sdk: static
7
  pinned: false
8
  license: mit
9
  ---
10
 
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: Streaming Indicators
3
+ emoji:
4
+ colorFrom: green
5
+ colorTo: red
6
  sdk: static
7
  pinned: false
8
  license: mit
9
  ---
10
 
11
+ See [streaming_indicators](https://awesome-panel.org/resources/streaming_indicators/) by [awesome-panel.org](https://awesome-panel.org) for more info.
12
+
13
+ ## Serve
14
+
15
+ ```python
16
+ panel serve *.py --autoreload
17
+ ```
18
+
19
+ ## Build
20
+
21
+ ```bash
22
+ panel convert *.py --to pyodide-worker
23
+ ```
index.html CHANGED
@@ -1,19 +1,339 @@
1
  <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <!DOCTYPE html>
2
+ <html lang="en" >
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Streaming Indicators</title>
6
+ <link rel="apple-touch-icon" sizes="180x180" href="https://cdn.holoviz.org/panel/1.3.1/dist/images/apple-touch-icon.png">
7
+ <link rel="icon" href="https://cdn.holoviz.org/panel/1.3.1/dist/images/favicon.ico" type=""><meta name="name" content="Streaming Indicators"> <style>
8
+ html, body {
9
+ display: flow-root;
10
+ box-sizing: border-box;
11
+ height: 100%;
12
+ margin: 0;
13
+ padding: 0;
14
+ }
15
+ </style>
16
+ <style>
17
+
18
+ :host(.pn-loading) .pn-loading-msg,
19
+ .pn-loading .pn-loading-msg {
20
+ color: var(--panel-on-background-color, black) !important;
21
+ }
22
+
23
+ </style>
24
+
25
+ <style type="text/css">
26
+ :host(.pn-loading),
27
+ .pn-loading {
28
+ overflow: hidden;
29
+ }
30
+
31
+ :host(.pn-loading):before,
32
+ .pn-loading:before {
33
+ position: absolute;
34
+ height: 100%;
35
+ width: 100%;
36
+ content: '';
37
+ z-index: 1000;
38
+ background-color: rgb(255, 255, 255, 0.5);
39
+ border-color: lightgray;
40
+ background-repeat: no-repeat;
41
+ background-position: center;
42
+ background-size: auto 50%;
43
+ border-width: 1px;
44
+ cursor: progress;
45
+ }
46
+
47
+ :host(.pn-loading) .pn-loading-msg,
48
+ .pn-loading .pn-loading-msg {
49
+ position: absolute;
50
+ top: 72%;
51
+ font-size: 2em;
52
+ color: black;
53
+ width: 100%;
54
+ text-align: center;
55
+ }
56
+
57
+
58
+ :host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {
59
+ background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=");
60
+ background-size: auto calc(min(50%, 400px));
61
+ }
62
+ </style><script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-3.3.0.min.js"></script>
63
+ <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.3.0.min.js"></script>
64
+ <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.3.0.min.js"></script>
65
+ <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.3.0.min.js"></script>
66
+ <script type="text/javascript" src="https://cdn.holoviz.org/panel/1.3.1/dist/panel.min.js"></script>
67
+
68
+ <script type="text/javascript">
69
+ Bokeh.set_log_level("info");
70
+ </script><!-- Template CSS -->
71
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans">
72
+ <link rel="stylesheet" href="https://cdn.holoviz.org/panel/1.3.1/dist/bundled/theme/dark.css">
73
+ <link rel="stylesheet" href="https://cdn.holoviz.org/panel/1.3.1/dist/bundled/fastbasetemplate/fast.css">
74
+ <link rel="stylesheet" href="https://cdn.holoviz.org/panel/1.3.1/dist/bundled/fastlisttemplate/fast_list_template.css">
75
+ <style type="text/css">
76
+
77
+ :host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {
78
+ background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=");
79
+ background-size: auto calc(min(50%, 400px));
80
+ }
81
+ </style>
82
+ <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans" />
83
+
84
+ <style>
85
+ :root {
86
+ --background-color: #181818;
87
+ --body-font: Open Sans, sans-serif;
88
+ --corner-radius: 3;
89
+ --header-background: #00A170;
90
+ --header-color: #ffffff;
91
+ --sidebar-width: 330px;
92
+ }
93
+ body {
94
+ color: #ffffff;
95
+ background-color: var(--background-color);
96
+ font-family: var(--body-font);
97
+ }
98
+ #header a {
99
+ color: currentColor;
100
+ }
101
+ #header-design-provider {
102
+ --neutral-fill-hover: var(--header-background);
103
+ --neutral-fill-rest: var(--header-background);
104
+ --neutral-foreground-rest: var(--header-color);
105
+ background: var(--header-background);
106
+ color: var(--header-color);
107
+ }
108
+ #sidebar {
109
+ min-width: var(--sidebar-width);
110
+ max-width: var(--sidebar-width);
111
+ }
112
+ </style>
113
+
114
+ <!-- Template JS -->
115
+ <script src="https://cdn.holoviz.org/panel/1.3.1/dist/bundled/fastbasetemplate/fast_template.js"></script>
116
+ <script src="https://cdn.holoviz.org/panel/1.3.1/dist/bundled/@microsoft/fast-components@2.30.6/dist/fast-components.js" type="module"></script>
117
+ <script src="https://cdn.holoviz.org/panel/1.3.1/dist/bundled/fast/js/fast_design.js" type="module"></script>
118
+
119
+ <!-- Fast Script -->
120
+ <script type="text/javascript">
121
+ document.addEventListener('DOMContentLoaded', (event) => {
122
+ const header_design = new window.fastDesignProvider("#header-design-provider");
123
+ const body_design = window.bodyDesign = new window.fastDesignProvider("#body-design-provider");
124
+ body_design.setLuminance(0.1);
125
+ body_design.setAccentColor("#00A170")
126
+ body_design.setNeutralColor("#000000");
127
+ header_design.setLuminance(0.1);
128
+ header_design.setAccentColor("#ffffff");
129
+ header_design.setNeutralColor("#ffffff");
130
+ });
131
+ </script>
132
+ </head>
133
+ <body class="pn-loading pn-arc">
134
+ <fast-design-system-provider id="body-design-provider" use-defaults>
135
+ <div id="container">
136
+ <fast-design-system-provider id="header-design-provider">
137
+ <nav id="header" >
138
+ <div class="app-header">
139
+ <a class="title" href="https://awesome-panel.org" >&nbsp;Awesome Panel</a>
140
+ <span class="title">-</span>
141
+ <a class="title" href="" >Streaming Indicators</a>
142
+ </div>
143
+ <div id="header-items">
144
+ </div>
145
+ <div class="pn-busy-container" id="busy-container">
146
+ <div id="dc27639d-6954-4159-b9e2-54e13851f586" data-root-id="p1016" style="display: contents;"></div>
147
+ </div>
148
+ <fast-tooltip anchor="busy-container" position="left">
149
+ Busy Indicator
150
+ </fast-tooltip>
151
+ </nav>
152
+ </fast-design-system-provider>
153
+
154
+ <div class="row" id="content">
155
+
156
+ <div class="main" id="main">
157
+ <div class="card-margin stretch_width">
158
+ <div class="pn-wrapper">
159
+ <span class="fullscreen-button" onclick="toggleFullScreen(this)">
160
+ <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 18 18">
161
+ <path d="M4.5 11H3v4h4v-1.5H4.5V11zM3 7h1.5V4.5H7V3H3v4zm10.5 6.5H11V15h4v-4h-1.5v2.5zM11 3v1.5h2.5V7H15V3h-4z"/>
162
+ </svg>
163
+ </span>
164
+ <div id="b743e158-f85d-48fe-a5b1-d55d64457f34" data-root-id="p1019" style="display: contents;"></div>
165
+ </div>
166
+ </div>
167
+ </div>
168
+ <fast-dialog id="pn-Modal" hidden>
169
+ <fast-button class="pn-modal-close" id="pn-closeModal">&times;</fast-button>
170
+ <div>
171
+ </div>
172
+ </fast-dialog>
173
+ </div>
174
+ </div>
175
+ </fast-design-system-provider>
176
+
177
+ <script type="text/javascript">
178
+
179
+ </script>
180
+
181
+ <script type="text/javascript">
182
+ function openNav() {
183
+ document.getElementById("sidebar").classList.remove("hidden");
184
+ document.getElementById("sidebar-button").onclick = closeNav;
185
+ }
186
+
187
+ function closeNav() {
188
+ document.getElementById("sidebar").classList.add("hidden");
189
+ document.getElementById("sidebar-button").onclick = openNav;
190
+ }
191
+
192
+ var modal = document.getElementById("pn-Modal");
193
+ var span = document.getElementById("pn-closeModal");
194
+
195
+ span.onclick = function() {
196
+ modal.style.display = "none";
197
+ }
198
+
199
+ window.onclick = function(event) {
200
+ if (event.target == modal) {
201
+ modal.style.display = "none";
202
+ }
203
+ }
204
+ </script>
205
+
206
+ <div id="f0d93c75-04ce-412f-9f11-ea02a25b0b6a" data-root-id="p1009" style="display: contents;"></div>
207
+ <div id="ab651035-4297-49e7-9e0e-e325fbde91bc" data-root-id="p1012" style="display: contents;"></div>
208
+ <div id="c48707f6-64d2-4938-bf38-4bd1a0e1d042" data-root-id="p1002" style="display: contents;"></div>
209
+ <div id="b60c8fe2-e0b0-4bac-bbd6-b727c1bfc3a6" data-root-id="p1013" style="display: contents;"></div>
210
+
211
+
212
+ <script type="text/javascript">
213
+ const pyodideWorker = new Worker("./index.js");
214
+ pyodideWorker.busy = false
215
+ pyodideWorker.queue = []
216
+
217
+ function send_change(jsdoc, event) {
218
+ if (event.setter_id != null && event.setter_id == 'py') {
219
+ return
220
+ } else if (pyodideWorker.busy && event.model && event.attr) {
221
+ let events = []
222
+ for (const old_event of pyodideWorker.queue) {
223
+ if (!(old_event.model === event.model && old_event.attr === event.attr)) {
224
+ events.push(old_event)
225
+ }
226
+ }
227
+ events.push(event)
228
+ pyodideWorker.queue = events
229
+ return
230
+ }
231
+ const patch = jsdoc.create_json_patch([event])
232
+ pyodideWorker.busy = true
233
+ pyodideWorker.postMessage({type: 'patch', patch: patch})
234
+ }
235
+
236
+ pyodideWorker.onmessage = async (event) => {
237
+ const msg = event.data
238
+
239
+ const body = document.getElementsByTagName('body')[0]
240
+ const loading_msgs = document.getElementsByClassName('pn-loading-msg')
241
+ if (msg.type === 'idle') {
242
+ if (pyodideWorker.queue.length) {
243
+ const patch = pyodideWorker.jsdoc.create_json_patch(pyodideWorker.queue)
244
+ pyodideWorker.busy = true
245
+ pyodideWorker.queue = []
246
+ pyodideWorker.postMessage({type: 'patch', patch: patch})
247
+ } else {
248
+ pyodideWorker.busy = false
249
+ }
250
+ } else if (msg.type === 'status') {
251
+ let loading_msg
252
+ if (loading_msgs.length) {
253
+ loading_msg = loading_msgs[0]
254
+ } else if (body.classList.contains('pn-loading')) {
255
+ loading_msg = document.createElement('div')
256
+ loading_msg.classList.add('pn-loading-msg')
257
+ body.appendChild(loading_msg)
258
+ }
259
+ if (loading_msg != null) {
260
+ loading_msg.innerHTML = msg.msg
261
+ }
262
+ } else if (msg.type === 'render') {
263
+ const docs_json = JSON.parse(msg.docs_json)
264
+ const render_items = JSON.parse(msg.render_items)
265
+ const root_ids = JSON.parse(msg.root_ids)
266
+
267
+ // Remap roots in message to element IDs
268
+ const root_els = document.querySelectorAll('[data-root-id]')
269
+ const data_roots = []
270
+ for (const el of root_els) {
271
+ el.innerHTML = ''
272
+ data_roots.push([el.getAttribute('data-root-id'), el.id])
273
+ }
274
+ data_roots.sort((a, b) => a[0]<b[0] ? -1: 1)
275
+ const roots = {}
276
+ for (let i=0; i<data_roots.length; i++) {
277
+ roots[root_ids[i]] = data_roots[i][1]
278
+ }
279
+ render_items[0]['roots'] = roots
280
+ render_items[0]['root_ids'] = root_ids
281
+
282
+ // Embed content
283
+ const [views] = await Bokeh.embed.embed_items(docs_json, render_items)
284
+
285
+ // Remove loading spinner and message
286
+ body.classList.remove("pn-loading", "arc")
287
+ for (const loading_msg of loading_msgs) {
288
+ loading_msg.remove()
289
+ }
290
+
291
+ // Setup bi-directional syncing
292
+ pyodideWorker.jsdoc = jsdoc = [...views.roots.values()][0].model.document
293
+ jsdoc.on_change(send_change.bind(null, jsdoc), false)
294
+ pyodideWorker.postMessage({'type': 'rendered'})
295
+ pyodideWorker.postMessage({'type': 'location', location: JSON.stringify(window.location)})
296
+ } else if (msg.type === 'patch') {
297
+ pyodideWorker.jsdoc.apply_json_patch(msg.patch, msg.buffers, setter_id='py')
298
+ }
299
+ };
300
+ </script>
301
+ <script type="application/json" id="p1109">
302
+ {"225512b5-1496-4b2a-bcb3-fb1b6aa765ca":{"version":"3.3.0","title":"Streaming Indicators","roots":[{"type":"object","name":"panel.models.location.Location","id":"p1002","attributes":{"name":"location","reload":false}},{"type":"object","name":"panel.models.markup.HTML","id":"p1009","attributes":{"name":"js_area","stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1061","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"type":"object","name":"ImportedStyleSheet","id":"p1058","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/bundled/theme/fast.css"}}],"width":0,"height":0,"margin":0,"sizing_mode":"fixed","align":"start","disable_math":true}},{"type":"object","name":"panel.models.reactive_html.ReactiveHTML","id":"p1012","attributes":{"name":"actions","subscribed_events":{"type":"set","entries":["dom_event"]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1062","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"margin":0,"align":"start","data":{"type":"object","name":"TemplateActions1","id":"p1010","attributes":{"name":"TemplateActions00202"}},"scripts":{"type":"map","entries":[["open_modal",["document.getElementById(&amp;#x27;pn-Modal&amp;#x27;).style.display = &amp;#x27;block&amp;#x27;"]],["close_modal",["document.getElementById(&amp;#x27;pn-Modal&amp;#x27;).style.display = &amp;#x27;none&amp;#x27;"]]]}}},{"type":"object","name":"panel.models.browser.BrowserInfo","id":"p1013","attributes":{"name":"browser_info"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1016","attributes":{"name":"busy_indicator","css_classes":["loader","light"],"stylesheets":[":host { --loading-spinner-size: 20px; }","\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1063","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"type":"object","name":"ImportedStyleSheet","id":"p1064","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loadingspinner.css"}},{"id":"p1058"}],"min_width":20,"min_height":20,"margin":[5,10],"align":"start"}},{"type":"object","name":"panel.models.reactive_html.ReactiveHTML","id":"p1019","attributes":{"name":"main-140455927946768","tags":["main"],"subscribed_events":{"type":"set","entries":["dom_event"]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1065","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"margin":0,"sizing_mode":"stretch_width","align":"start","attrs":{"type":"map","entries":[["flexbox",[["style",["flex_wrap","justify_content","flex_direction","align_content","align_items"],"display: flex; flex-wrap: {flex_wrap}; justify-content: {justify_content}; flex-direction: {flex_direction}; align-content: {align_content}; align-items: {align_items}; height: 100%;"]]]]},"children":{"type":"map","entries":[["flex-item",[{"type":"object","name":"panel.models.markup.HTML","id":"p1021","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1066","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 0&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1023","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1067","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 1&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1025","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1068","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 2&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1027","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1069","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 3&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1029","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1070","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 4&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1031","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1071","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 5&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1033","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1072","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 6&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1035","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1073","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 7&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1037","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1074","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 8&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1039","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1075","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 9&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1041","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1076","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 10&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1043","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1077","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 11&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1045","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1078","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 12&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1047","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1079","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 13&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1049","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1080","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 14&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1051","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1081","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 15&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1053","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1082","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 16&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1055","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1083","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&amp;lt;div style=&amp;quot;font-size: 18pt; color: #00A170&amp;quot;&amp;gt;Sensor 17&amp;lt;/div&amp;gt;\n&amp;lt;div style=&amp;quot;font-size: 54pt; color: #00A170&amp;quot;&amp;gt;77%&amp;lt;/div&amp;gt;"}}]]]},"data":{"type":"object","name":"FlexBox1","id":"p1017","attributes":{"name":"FlexBox00192"}},"html":"&amp;lt;div id=&amp;quot;flexbox-${id}&amp;quot; style=&amp;quot;display: flex; flex-wrap: ${flex_wrap}; justify-content: ${justify_content}; flex-direction: ${flex_direction}; align-content: ${align_content}; align-items: ${align_items}; height: 100%;&amp;quot;&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-0-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-1-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-2-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-3-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-4-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-5-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-6-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-7-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-8-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-9-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-10-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-11-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-12-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-13-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-14-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-15-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-16-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n &amp;lt;div id=&amp;quot;flex-item-17-${id}&amp;quot; style=&amp;quot;display: contents;&amp;quot;&amp;gt;\n\n &amp;lt;/div&amp;gt;\n\n&amp;lt;/div&amp;gt;","looped":["flex-item"],"nodes":["flexbox","flex-item-0","flex-item-1","flex-item-2","flex-item-3","flex-item-4","flex-item-5","flex-item-6","flex-item-7","flex-item-8","flex-item-9","flex-item-10","flex-item-11","flex-item-12","flex-item-13","flex-item-14","flex-item-15","flex-item-16","flex-item-17"]}}],"defs":[{"type":"model","name":"ReactiveHTML1"},{"type":"model","name":"FlexBox1","properties":[{"name":"align_content","kind":"Any","default":"flex-start"},{"name":"align_items","kind":"Any","default":"flex-start"},{"name":"flex_direction","kind":"Any","default":"row"},{"name":"flex_wrap","kind":"Any","default":"wrap"},{"name":"justify_content","kind":"Any","default":"flex-start"}]},{"type":"model","name":"FloatPanel1","properties":[{"name":"config","kind":"Any","default":{"type":"map"}},{"name":"contained","kind":"Any","default":true},{"name":"position","kind":"Any","default":"right-top"},{"name":"offsetx","kind":"Any","default":null},{"name":"offsety","kind":"Any","default":null},{"name":"theme","kind":"Any","default":"primary"},{"name":"status","kind":"Any","default":"normalized"}]},{"type":"model","name":"GridStack1","properties":[{"name":"mode","kind":"Any","default":"warn"},{"name":"ncols","kind":"Any","default":null},{"name":"nrows","kind":"Any","default":null},{"name":"allow_resize","kind":"Any","default":true},{"name":"allow_drag","kind":"Any","default":true},{"name":"state","kind":"Any","default":[]}]},{"type":"model","name":"drag1","properties":[{"name":"slider_width","kind":"Any","default":5},{"name":"slider_color","kind":"Any","default":"black"},{"name":"value","kind":"Any","default":50}]},{"type":"model","name":"click1","properties":[{"name":"terminal_output","kind":"Any","default":""},{"name":"debug_name","kind":"Any","default":""},{"name":"clears","kind":"Any","default":0}]},{"type":"model","name":"toggle_value1","properties":[{"name":"active_icons","kind":"Any","default":{"type":"map"}},{"name":"options","kind":"Any","default":{"type":"map","entries":[["favorite","heart"]]}},{"name":"value","kind":"Any","default":[]},{"name":"_reactions","kind":"Any","default":[]},{"name":"_base_url","kind":"Any","default":"https://tabler-icons.io/static/tabler-icons/icons/"}]},{"type":"model","name":"copy_to_clipboard1","properties":[{"name":"value","kind":"Any","default":null},{"name":"fill","kind":"Any","default":"none"}]},{"type":"model","name":"FastWrapper1","properties":[{"name":"object","kind":"Any","default":null},{"name":"style","kind":"Any","default":null}]},{"type":"model","name":"NotificationAreaBase1","properties":[{"name":"js_events","kind":"Any","default":{"type":"map"}},{"name":"position","kind":"Any","default":"bottom-right"},{"name":"_clear","kind":"Any","default":0}]},{"type":"model","name":"NotificationArea1","properties":[{"name":"js_events","kind":"Any","default":{"type":"map"}},{"name":"notifications","kind":"Any","default":[]},{"name":"position","kind":"Any","default":"bottom-right"},{"name":"_clear","kind":"Any","default":0},{"name":"types","kind":"Any","default":[{"type":"map","entries":[["type","warning"],["background","#ffc107"],["icon",{"type":"map","entries":[["className","fas fa-exclamation-triangle"],["tagName","i"],["color","white"]]}]]},{"type":"map","entries":[["type","info"],["background","#007bff"],["icon",{"type":"map","entries":[["className","fas fa-info-circle"],["tagName","i"],["color","white"]]}]]}]}]},{"type":"model","name":"Notification","properties":[{"name":"background","kind":"Any","default":null},{"name":"duration","kind":"Any","default":3000},{"name":"icon","kind":"Any","default":null},{"name":"message","kind":"Any","default":""},{"name":"notification_type","kind":"Any","default":null},{"name":"_destroyed","kind":"Any","default":false}]},{"type":"model","name":"TemplateActions1","properties":[{"name":"open_modal","kind":"Any","default":0},{"name":"close_modal","kind":"Any","default":0}]},{"type":"model","name":"BootstrapTemplateActions1","properties":[{"name":"open_modal","kind":"Any","default":0},{"name":"close_modal","kind":"Any","default":0}]},{"type":"model","name":"MaterialTemplateActions1","properties":[{"name":"open_modal","kind":"Any","default":0},{"name":"close_modal","kind":"Any","default":0}]}]}}
303
+ </script>
304
+ <script type="text/javascript">
305
+ (function() {
306
+ const fn = function() {
307
+ Bokeh.safely(function() {
308
+ (function(root) {
309
+ function embed_document(root) {
310
+ const docs_json = document.getElementById('p1109').textContent;
311
+ const render_items = [{"docid":"225512b5-1496-4b2a-bcb3-fb1b6aa765ca","roots":{"p1002":"c48707f6-64d2-4938-bf38-4bd1a0e1d042","p1009":"f0d93c75-04ce-412f-9f11-ea02a25b0b6a","p1012":"ab651035-4297-49e7-9e0e-e325fbde91bc","p1013":"b60c8fe2-e0b0-4bac-bbd6-b727c1bfc3a6","p1016":"dc27639d-6954-4159-b9e2-54e13851f586","p1019":"b743e158-f85d-48fe-a5b1-d55d64457f34"},"root_ids":["p1002","p1009","p1012","p1013","p1016","p1019"]}];
312
+ root.Bokeh.embed.embed_items(docs_json, render_items);
313
+ }
314
+ if (root.Bokeh !== undefined) {
315
+ embed_document(root);
316
+ } else {
317
+ let attempts = 0;
318
+ const timer = setInterval(function(root) {
319
+ if (root.Bokeh !== undefined) {
320
+ clearInterval(timer);
321
+ embed_document(root);
322
+ } else {
323
+ attempts++;
324
+ if (attempts > 100) {
325
+ clearInterval(timer);
326
+ console.log("Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing");
327
+ }
328
+ }
329
+ }, 10, root)
330
+ }
331
+ })(window);
332
+ });
333
+ };
334
+ if (document.readyState != "loading") fn();
335
+ else document.addEventListener("DOMContentLoaded", fn);
336
+ })();
337
+ </script>
338
+ </body>
339
+ </html>
index.js ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ importScripts("https://cdn.jsdelivr.net/pyodide/v0.24.1/pyc/pyodide.js");
2
+
3
+ function sendPatch(patch, buffers, msg_id) {
4
+ self.postMessage({
5
+ type: 'patch',
6
+ patch: patch,
7
+ buffers: buffers
8
+ })
9
+ }
10
+
11
+ async function startApplication() {
12
+ console.log("Loading pyodide!");
13
+ self.postMessage({type: 'status', msg: 'Loading pyodide'})
14
+ self.pyodide = await loadPyodide();
15
+ self.pyodide.globals.set("sendPatch", sendPatch);
16
+ console.log("Loaded!");
17
+ await self.pyodide.loadPackage("micropip");
18
+ const env_spec = ['https://cdn.holoviz.org/panel/wheels/bokeh-3.3.0-py3-none-any.whl', 'https://cdn.holoviz.org/panel/1.3.1/dist/wheels/panel-1.3.1-py3-none-any.whl', 'pyodide-http==0.2.1', 'numpy']
19
+ for (const pkg of env_spec) {
20
+ let pkg_name;
21
+ if (pkg.endsWith('.whl')) {
22
+ pkg_name = pkg.split('/').slice(-1)[0].split('-')[0]
23
+ } else {
24
+ pkg_name = pkg
25
+ }
26
+ self.postMessage({type: 'status', msg: `Installing ${pkg_name}`})
27
+ try {
28
+ await self.pyodide.runPythonAsync(`
29
+ import micropip
30
+ await micropip.install('${pkg}');
31
+ `);
32
+ } catch(e) {
33
+ console.log(e)
34
+ self.postMessage({
35
+ type: 'status',
36
+ msg: `Error while installing ${pkg_name}`
37
+ });
38
+ }
39
+ }
40
+ console.log("Packages loaded!");
41
+ self.postMessage({type: 'status', msg: 'Executing code'})
42
+ const code = `
43
+
44
+ import asyncio
45
+
46
+ from panel.io.pyodide import init_doc, write_doc
47
+
48
+ init_doc()
49
+
50
+ """
51
+ Source: https://awesome-panel.org/resources/streaming_indicators/
52
+ """
53
+ from asyncio import create_task, get_event_loop, sleep
54
+
55
+ import numpy as np
56
+ import panel as pn
57
+
58
+ ACCENT = "#00A170"
59
+ OK_COLOR=ACCENT
60
+ ERROR_COLOR = "#a10031"
61
+ ALERT = 80
62
+ COLORS = [(ALERT, OK_COLOR), (100, ERROR_COLOR)]
63
+ INITIAL_VALUE = ALERT-3
64
+
65
+ N=18 # Number of indicators
66
+
67
+ # Can be removed when https://github.com/holoviz/panel/pull/6194 is released
68
+ CSS_FIX = """
69
+ :host(.pn-loading) .pn-loading-msg,
70
+ .pn-loading .pn-loading-msg {
71
+ color: var(--panel-on-background-color, black) !important;
72
+ }
73
+ """
74
+ if not CSS_FIX in pn.config.raw_css:
75
+ pn.config.raw_css.append(CSS_FIX)
76
+
77
+ async def update_values(values):
78
+ """Some random updating of values."""
79
+ while True:
80
+ # Replace with your own code.
81
+ new_value = np.copy(values.rx.value)
82
+
83
+ new_value += np.random.randint(5, size=N) -2
84
+ new_value[new_value<0]=0
85
+ new_value[new_value>99]=99
86
+
87
+ values.rx.value = new_value
88
+
89
+ await sleep(1)
90
+
91
+ @pn.cache # We use caching to share values across all sessions
92
+ def get_values():
93
+ # We use Reactive Expressions https://param.holoviz.org/user_guide/Reactive_Expressions.html
94
+ return pn.rx([INITIAL_VALUE]*N)
95
+
96
+ @pn.cache # We use caching to only update values once across all sessions
97
+ def create_update_values_task():
98
+ values = get_values()
99
+ create_task(update_values(values))
100
+
101
+ def get_styles(value):
102
+ if value<=ALERT:
103
+ return {"border": f"1px solid {OK_COLOR}", "padding": "1em", "border-radius": "3px"}
104
+ return {"border": f"1px solid {ERROR_COLOR}", "padding": "1em", "border-radius": "3px"}
105
+
106
+ def create_indicator(index, values):
107
+ title =f"Sensor {index}"
108
+ value = values[index]
109
+
110
+ return pn.indicators.Number(
111
+ name=title,
112
+ value=value,
113
+ format="{value}%",
114
+ colors=COLORS,
115
+ margin=10,
116
+ styles=pn.rx(get_styles)(value),
117
+ width=165
118
+ )
119
+
120
+ def create_component():
121
+ values = get_values()
122
+ indicators = tuple(create_indicator(i, values) for i in range(len(values.rx.value)))
123
+ layout = pn.FlexBox(*indicators)
124
+ return layout
125
+
126
+ if pn.state.served or pn.state._is_pyodide:
127
+ pn.extension()
128
+
129
+ if get_event_loop().is_running():
130
+ # We can only start the stream if the event loop is running
131
+ create_update_values_task()
132
+
133
+ pn.template.FastListTemplate(
134
+ site="Awesome Panel",
135
+ site_url="https://awesome-panel.org",
136
+ title="Streaming Indicators",
137
+ accent=ACCENT,
138
+ theme="dark",
139
+ theme_toggle=False,
140
+ main=[create_component()],
141
+ main_layout=None,
142
+ ).servable()
143
+
144
+ await write_doc()
145
+ `
146
+
147
+ try {
148
+ const [docs_json, render_items, root_ids] = await self.pyodide.runPythonAsync(code)
149
+ self.postMessage({
150
+ type: 'render',
151
+ docs_json: docs_json,
152
+ render_items: render_items,
153
+ root_ids: root_ids
154
+ })
155
+ } catch(e) {
156
+ const traceback = `${e}`
157
+ const tblines = traceback.split('\n')
158
+ self.postMessage({
159
+ type: 'status',
160
+ msg: tblines[tblines.length-2]
161
+ });
162
+ throw e
163
+ }
164
+ }
165
+
166
+ self.onmessage = async (event) => {
167
+ const msg = event.data
168
+ if (msg.type === 'rendered') {
169
+ self.pyodide.runPythonAsync(`
170
+ from panel.io.state import state
171
+ from panel.io.pyodide import _link_docs_worker
172
+
173
+ _link_docs_worker(state.curdoc, sendPatch, setter='js')
174
+ `)
175
+ } else if (msg.type === 'patch') {
176
+ self.pyodide.globals.set('patch', msg.patch)
177
+ self.pyodide.runPythonAsync(`
178
+ state.curdoc.apply_json_patch(patch.to_py(), setter='js')
179
+ `)
180
+ self.postMessage({type: 'idle'})
181
+ } else if (msg.type === 'location') {
182
+ self.pyodide.globals.set('location', msg.location)
183
+ self.pyodide.runPythonAsync(`
184
+ import json
185
+ from panel.io.state import state
186
+ from panel.util import edit_readonly
187
+ if state.location:
188
+ loc_data = json.loads(location)
189
+ with edit_readonly(state.location):
190
+ state.location.param.update({
191
+ k: v for k, v in loc_data.items() if k in state.location.param
192
+ })
193
+ `)
194
+ }
195
+ }
196
+
197
+ startApplication()
index.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Source: https://awesome-panel.org/resources/streaming_indicators/
3
+ """
4
+ from asyncio import create_task, get_event_loop, sleep
5
+
6
+ import numpy as np
7
+ import panel as pn
8
+
9
+ ACCENT = "#00A170"
10
+ OK_COLOR=ACCENT
11
+ ERROR_COLOR = "#a10031"
12
+ ALERT = 80
13
+ COLORS = [(ALERT, OK_COLOR), (100, ERROR_COLOR)]
14
+ INITIAL_VALUE = ALERT-3
15
+
16
+ N=18 # Number of indicators
17
+
18
+ # Can be removed when https://github.com/holoviz/panel/pull/6194 is released
19
+ CSS_FIX = """
20
+ :host(.pn-loading) .pn-loading-msg,
21
+ .pn-loading .pn-loading-msg {
22
+ color: var(--panel-on-background-color, black) !important;
23
+ }
24
+ """
25
+ if not CSS_FIX in pn.config.raw_css:
26
+ pn.config.raw_css.append(CSS_FIX)
27
+
28
+ async def update_values(values):
29
+ """Some random updating of values."""
30
+ while True:
31
+ # Replace with your own code.
32
+ new_value = np.copy(values.rx.value)
33
+
34
+ new_value += np.random.randint(5, size=N) -2
35
+ new_value[new_value<0]=0
36
+ new_value[new_value>99]=99
37
+
38
+ values.rx.value = new_value
39
+
40
+ await sleep(1)
41
+
42
+ @pn.cache # We use caching to share values across all sessions
43
+ def get_values():
44
+ # We use Reactive Expressions https://param.holoviz.org/user_guide/Reactive_Expressions.html
45
+ return pn.rx([INITIAL_VALUE]*N)
46
+
47
+ @pn.cache # We use caching to only update values once across all sessions
48
+ def create_update_values_task():
49
+ values = get_values()
50
+ create_task(update_values(values))
51
+
52
+ def get_styles(value):
53
+ if value<=ALERT:
54
+ return {"border": f"1px solid {OK_COLOR}", "padding": "1em", "border-radius": "3px"}
55
+ return {"border": f"1px solid {ERROR_COLOR}", "padding": "1em", "border-radius": "3px"}
56
+
57
+ def create_indicator(index, values):
58
+ title =f"Sensor {index}"
59
+ value = values[index]
60
+
61
+ return pn.indicators.Number(
62
+ name=title,
63
+ value=value,
64
+ format="{value}%",
65
+ colors=COLORS,
66
+ margin=10,
67
+ styles=pn.rx(get_styles)(value),
68
+ width=165
69
+ )
70
+
71
+ def create_component():
72
+ values = get_values()
73
+ indicators = tuple(create_indicator(i, values) for i in range(len(values.rx.value)))
74
+ layout = pn.FlexBox(*indicators)
75
+ return layout
76
+
77
+ if pn.state.served or pn.state._is_pyodide:
78
+ pn.extension()
79
+
80
+ if get_event_loop().is_running():
81
+ # We can only start the stream if the event loop is running
82
+ create_update_values_task()
83
+
84
+ pn.template.FastListTemplate(
85
+ site="Awesome Panel",
86
+ site_url="https://awesome-panel.org",
87
+ title="Streaming Indicators",
88
+ accent=ACCENT,
89
+ theme="dark",
90
+ theme_toggle=False,
91
+ main=[create_component()],
92
+ main_layout=None,
93
+ ).servable()
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ panel
2
+ numpy