@seedtactics/insight-client 17.0.1-beta.12 → 17.0.1-beta.13
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 +11 -0
- package/dist/assets/ProgramHighlight-CnZe9PDO.js +3 -0
- package/dist/assets/index-Dxxgr-QV.js +367 -0
- package/dist/cell-status/current-status.d.ts +1 -0
- package/dist/cell-status/current-status.js +2 -0
- package/dist/cell-status/loading.d.ts +6 -0
- package/dist/cell-status/loading.js +11 -3
- package/dist/cell-status/material-details.d.ts +2 -2
- package/dist/cell-status/material-details.js +26 -13
- package/dist/components/analysis/BufferChart.js +3 -2
- package/dist/components/operations/RecentCycleChart.js +16 -21
- package/dist/components/station-monitor/CancelLoadButton.js +2 -0
- package/dist/components/station-monitor/InvalidateCycle.js +3 -2
- package/dist/components/station-monitor/LoadStation.js +4 -3
- package/dist/components/station-monitor/PrintedLabel.js +15 -19
- package/dist/components/station-monitor/SystemOverview.js +3 -2
- package/dist/extension.d.ts +1 -0
- package/dist/extension.js +1 -0
- package/dist/index.html +2 -39
- package/dist/network/websocket.d.ts +1 -0
- package/dist/network/websocket.js +122 -36
- package/package.json +17 -17
- package/dist/assets/ProgramHighlight-C6zSEXCX.js +0 -3
- package/dist/assets/index-kk-GRa5i.js +0 -388
|
@@ -33,36 +33,90 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
33
33
|
import { ServerEvent } from "./api.js";
|
|
34
34
|
import { JobsBackend, LogBackend } from "./backend.js";
|
|
35
35
|
import { fmsInformation } from "./server-settings.js";
|
|
36
|
-
import {
|
|
37
|
-
import { lastEventCounter, onLoadCurrentSt, onLoadLast30Jobs, onLoadLast30Log,
|
|
36
|
+
import { useEffect, useRef } from "react";
|
|
37
|
+
import { lastEventCounter, onLoadCurrentSt, onLoadLast30Jobs, onLoadLast30Log, onLiveServerEvent, onHistoricalServerEvent, } from "../cell-status/loading.js";
|
|
38
38
|
import { addDays } from "date-fns";
|
|
39
39
|
import { last30SchIds } from "../cell-status/scheduled-jobs.js";
|
|
40
|
+
import { HashSet, OrderedMap } from "@seedtactics/immutable-collections";
|
|
40
41
|
import { atom, useAtomValue, useSetAtom } from "jotai";
|
|
41
42
|
const websocketReconnectingAtom = atom(false);
|
|
42
43
|
export const websocketReconnecting = websocketReconnectingAtom;
|
|
44
|
+
// True while the websocket is open and this connection has loaded or received a current status, so
|
|
45
|
+
// the retained current status reflects the server. Loading the historical jobs and log does not
|
|
46
|
+
// affect it.
|
|
47
|
+
const currentStatusIsLiveRW = atom(false);
|
|
48
|
+
export const currentStatusIsLive = currentStatusIsLiveRW;
|
|
49
|
+
const websocketSessionAtom = atom({ id: 0, statusFromSocket: false });
|
|
50
|
+
// Only historical effects wait for HTTP catch-up. A fresh session discards its predecessor's
|
|
51
|
+
// unapplied buffer and reloads from lastEventCounter, which has not advanced past that history.
|
|
52
|
+
const bufferedLogAtom = atom(null);
|
|
53
|
+
// HTTP can include entries whose socket messages arrive after the response. Suppress those exact
|
|
54
|
+
// identities, never all counters below a maximum: live publication is not guaranteed to be ordered.
|
|
55
|
+
const loadedLogCountersAtom = atom(HashSet.empty());
|
|
43
56
|
const errorLoadingLast30RW = atom(null);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
.
|
|
53
|
-
|
|
57
|
+
const errorLoadingLogRW = atom(null);
|
|
58
|
+
export const errorLoadingLast30 = atom((get) => get(errorLoadingLast30RW) ?? get(errorLoadingLogRW));
|
|
59
|
+
function isCurrentSession(get, session) {
|
|
60
|
+
return get(websocketSessionAtom).id === session;
|
|
61
|
+
}
|
|
62
|
+
function loadCurrentStatus(get, set, session) {
|
|
63
|
+
return JobsBackend.currentStatus().then((st) => {
|
|
64
|
+
const current = get(websocketSessionAtom);
|
|
65
|
+
if (current.id !== session || current.statusFromSocket)
|
|
66
|
+
return;
|
|
67
|
+
set(onLoadCurrentSt, st);
|
|
68
|
+
set(currentStatusIsLiveRW, true);
|
|
69
|
+
});
|
|
54
70
|
}
|
|
55
|
-
function
|
|
71
|
+
function loadHistory(get, set, session, from, retryDelay = 1000) {
|
|
56
72
|
const now = new Date();
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
.
|
|
73
|
+
const request = from === null ? LogBackend.get(addDays(now, -30), now) : LogBackend.recent(from, undefined);
|
|
74
|
+
return request.then((log) => {
|
|
75
|
+
if (!isCurrentSession(get, session))
|
|
76
|
+
return;
|
|
77
|
+
const buffered = get(bufferedLogAtom) ?? OrderedMap.empty();
|
|
78
|
+
const merged = log.reduce((entries, entry) => entries.set(entry.counter, entry), buffered);
|
|
79
|
+
set(onLoadLast30Log, merged.valuesToAscLazySeq().toRArray());
|
|
80
|
+
set(loadedLogCountersAtom, HashSet.from(merged.keys()));
|
|
81
|
+
set(bufferedLogAtom, null);
|
|
82
|
+
set(errorLoadingLogRW, null);
|
|
83
|
+
}, (e) => {
|
|
84
|
+
if (!isCurrentSession(get, session))
|
|
85
|
+
return;
|
|
86
|
+
set(errorLoadingLogRW, e.message ?? "Error loading log history");
|
|
87
|
+
// Keep buffering and retry from the same applied position without interrupting live status.
|
|
88
|
+
setTimeout(() => {
|
|
89
|
+
if (isCurrentSession(get, session)) {
|
|
90
|
+
void loadHistory(get, set, session, from, Math.min(retryDelay * 2, 30000));
|
|
91
|
+
}
|
|
92
|
+
}, retryDelay);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function loadConnection(get, set, session) {
|
|
96
|
+
const from = get(lastEventCounter);
|
|
97
|
+
const schIds = get(last30SchIds);
|
|
98
|
+
const curStProm = loadCurrentStatus(get, set, session);
|
|
99
|
+
const jobsProm = JobsBackend.recent(addDays(new Date(), -30), from !== null && schIds ? Array.from(schIds) : []).then((j) => {
|
|
100
|
+
if (isCurrentSession(get, session))
|
|
101
|
+
set(onLoadLast30Jobs, j);
|
|
102
|
+
});
|
|
103
|
+
const logProm = loadHistory(get, set, session, from);
|
|
104
|
+
finishLoading([curStProm, jobsProm, logProm], get, set, session);
|
|
105
|
+
}
|
|
106
|
+
function finishLoading(loads, get, set, session) {
|
|
107
|
+
Promise.all(loads)
|
|
108
|
+
.catch((e) => {
|
|
109
|
+
if (isCurrentSession(get, session))
|
|
110
|
+
set(errorLoadingLast30RW, e.message ?? "Error");
|
|
111
|
+
})
|
|
112
|
+
.finally(() => {
|
|
113
|
+
if (isCurrentSession(get, session))
|
|
114
|
+
set(websocketReconnectingAtom, false);
|
|
115
|
+
});
|
|
63
116
|
}
|
|
64
117
|
class ReconnectingWebsocket {
|
|
65
118
|
constructor(url) {
|
|
119
|
+
this.session = null;
|
|
66
120
|
this.userCalledClose = false;
|
|
67
121
|
this.reconnectAttempts = 0;
|
|
68
122
|
this.url = url;
|
|
@@ -71,6 +125,12 @@ class ReconnectingWebsocket {
|
|
|
71
125
|
close() {
|
|
72
126
|
this.userCalledClose = true;
|
|
73
127
|
this.ws?.close();
|
|
128
|
+
this.endSession(false);
|
|
129
|
+
}
|
|
130
|
+
endSession(reconnecting) {
|
|
131
|
+
const session = this.session;
|
|
132
|
+
this.session = null;
|
|
133
|
+
this.handleClose?.(session, reconnecting);
|
|
74
134
|
}
|
|
75
135
|
connect() {
|
|
76
136
|
if (this.userCalledClose)
|
|
@@ -83,7 +143,7 @@ class ReconnectingWebsocket {
|
|
|
83
143
|
localWs.addEventListener("open", () => {
|
|
84
144
|
clearTimeout(connectTimeout);
|
|
85
145
|
this.reconnectAttempts = 0;
|
|
86
|
-
this.handleOpen?.();
|
|
146
|
+
this.session = this.handleOpen?.() ?? null;
|
|
87
147
|
});
|
|
88
148
|
localWs.addEventListener("close", () => {
|
|
89
149
|
clearTimeout(connectTimeout);
|
|
@@ -91,7 +151,7 @@ class ReconnectingWebsocket {
|
|
|
91
151
|
if (this.userCalledClose) {
|
|
92
152
|
return;
|
|
93
153
|
}
|
|
94
|
-
this.
|
|
154
|
+
this.endSession(true);
|
|
95
155
|
const delay = Math.min(1000 * Math.pow(1.5, this.reconnectAttempts), 30000);
|
|
96
156
|
setTimeout(() => {
|
|
97
157
|
this.reconnectAttempts++;
|
|
@@ -99,7 +159,7 @@ class ReconnectingWebsocket {
|
|
|
99
159
|
}, delay);
|
|
100
160
|
});
|
|
101
161
|
localWs.addEventListener("message", (evt) => {
|
|
102
|
-
this.handleMessage?.(evt);
|
|
162
|
+
this.handleMessage?.(evt, this.session);
|
|
103
163
|
});
|
|
104
164
|
// Browsers expose websocket failures as opaque events with no useful detail.
|
|
105
165
|
// Reconnect handling is driven by close/open, so avoid polluting stderr by
|
|
@@ -107,25 +167,51 @@ class ReconnectingWebsocket {
|
|
|
107
167
|
}
|
|
108
168
|
}
|
|
109
169
|
const onOpenAtom = atom(null, (get, set) => {
|
|
110
|
-
const
|
|
111
|
-
|
|
170
|
+
const session = get(websocketSessionAtom).id + 1;
|
|
171
|
+
set(websocketSessionAtom, { id: session, statusFromSocket: false });
|
|
112
172
|
set(websocketReconnectingAtom, true);
|
|
173
|
+
set(currentStatusIsLiveRW, false);
|
|
113
174
|
set(errorLoadingLast30RW, null);
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
loadInitial(set);
|
|
119
|
-
}
|
|
175
|
+
set(errorLoadingLogRW, null);
|
|
176
|
+
set(bufferedLogAtom, OrderedMap.empty());
|
|
177
|
+
loadConnection(get, set, session);
|
|
178
|
+
return session;
|
|
120
179
|
});
|
|
121
|
-
|
|
180
|
+
// Every close, including disposal, ends the socket's own session; only an unexpected close
|
|
181
|
+
// reconnects. A connection cannot end a newer connection's session.
|
|
182
|
+
const onCloseAtom = atom(null, (get, set, session, reconnecting) => {
|
|
183
|
+
if (reconnecting)
|
|
184
|
+
set(websocketReconnectingAtom, true);
|
|
185
|
+
if (session === null || !isCurrentSession(get, session))
|
|
186
|
+
return;
|
|
187
|
+
set(websocketSessionAtom, { id: session + 1, statusFromSocket: false });
|
|
188
|
+
set(currentStatusIsLiveRW, false);
|
|
189
|
+
set(bufferedLogAtom, null);
|
|
190
|
+
});
|
|
191
|
+
const onMessageAtom = atom(null, (get, set, evt, session) => {
|
|
192
|
+
if (session === null || !isCurrentSession(get, session))
|
|
193
|
+
return;
|
|
122
194
|
const serverEvt = ServerEvent.fromJS(JSON.parse(evt.data));
|
|
123
|
-
|
|
195
|
+
const eventAndTime = { evt: serverEvt, now: new Date(), expire: true };
|
|
196
|
+
set(onLiveServerEvent, eventAndTime);
|
|
197
|
+
const log = serverEvt.logEntry;
|
|
198
|
+
const buffered = get(bufferedLogAtom);
|
|
199
|
+
if (!log || !get(loadedLogCountersAtom).has(log.counter)) {
|
|
200
|
+
if (log && buffered !== null) {
|
|
201
|
+
set(bufferedLogAtom, buffered.set(log.counter, log));
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
set(onHistoricalServerEvent, eventAndTime);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (serverEvt.newCurrentStatus) {
|
|
208
|
+
set(websocketSessionAtom, { id: session, statusFromSocket: true });
|
|
209
|
+
set(currentStatusIsLiveRW, true);
|
|
210
|
+
}
|
|
124
211
|
});
|
|
125
212
|
export function WebsocketConnection() {
|
|
126
213
|
const onOpen = useSetAtom(onOpenAtom);
|
|
127
|
-
const
|
|
128
|
-
const onReconnecting = useCallback(() => setReconnecting(true), [setReconnecting]);
|
|
214
|
+
const onClose = useSetAtom(onCloseAtom);
|
|
129
215
|
const onMessage = useSetAtom(onMessageAtom);
|
|
130
216
|
const fmsInfoLoadable = useAtomValue(fmsInformation);
|
|
131
217
|
const websocketRef = useRef(null);
|
|
@@ -151,7 +237,7 @@ export function WebsocketConnection() {
|
|
|
151
237
|
}
|
|
152
238
|
const websocket = new ReconnectingWebsocket(uri);
|
|
153
239
|
websocket.handleOpen = onOpen;
|
|
154
|
-
websocket.
|
|
240
|
+
websocket.handleClose = onClose;
|
|
155
241
|
websocket.handleMessage = onMessage;
|
|
156
242
|
websocketRef.current = websocket;
|
|
157
243
|
return () => {
|
|
@@ -160,6 +246,6 @@ export function WebsocketConnection() {
|
|
|
160
246
|
websocketRef.current = null;
|
|
161
247
|
}
|
|
162
248
|
};
|
|
163
|
-
}, [fmsInfoLoadable, onMessage, onOpen,
|
|
249
|
+
}, [fmsInfoLoadable, onMessage, onOpen, onClose]);
|
|
164
250
|
return null;
|
|
165
251
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seedtactics/insight-client",
|
|
3
|
-
"version": "17.0.1-beta.
|
|
3
|
+
"version": "17.0.1-beta.13",
|
|
4
4
|
"license": "BSD-3-Clause",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "https://github.com/SeedTactics/fms-insight"
|
|
@@ -42,14 +42,14 @@
|
|
|
42
42
|
"date-fns": "^4.4.0",
|
|
43
43
|
"highlight.js": "^11.12.0",
|
|
44
44
|
"jdenticon": "^3.3.0",
|
|
45
|
-
"jotai": "^
|
|
45
|
+
"jotai": "^3.0.0",
|
|
46
46
|
"jotai-family": "^1.1.0",
|
|
47
47
|
"jsbarcode": "^3.12.3",
|
|
48
48
|
"oidc-client-ts": "^3.5.0",
|
|
49
|
-
"react": "^19.
|
|
49
|
+
"react": "^19.3.0",
|
|
50
50
|
"react-calendar": "^6.0.1",
|
|
51
|
-
"react-dom": "^19.
|
|
52
|
-
"react-error-boundary": "^6.1.
|
|
51
|
+
"react-dom": "^19.3.0",
|
|
52
|
+
"react-error-boundary": "^6.1.6",
|
|
53
53
|
"react-resize-detector": "^12.3.0",
|
|
54
54
|
"react-timeago": "^8.3.0",
|
|
55
55
|
"react-to-print": "^3.3.0",
|
|
@@ -61,21 +61,21 @@
|
|
|
61
61
|
"@types/d3-sankey": "^0.12.5",
|
|
62
62
|
"@types/d3-scale": "^4.0.9",
|
|
63
63
|
"@types/d3-shape": "^3.2.0",
|
|
64
|
-
"@types/node": "^26.
|
|
65
|
-
"@types/react": "^19.
|
|
66
|
-
"@types/react-dom": "^19.
|
|
64
|
+
"@types/node": "^26.6.3",
|
|
65
|
+
"@types/react": "^19.3.0",
|
|
66
|
+
"@types/react-dom": "^19.3.0",
|
|
67
67
|
"@vitejs/plugin-react": "^6.1.1",
|
|
68
|
-
"@vitest/browser-playwright": "^
|
|
69
|
-
"jsdom": "^30.
|
|
68
|
+
"@vitest/browser-playwright": "^5.0.2",
|
|
69
|
+
"jsdom": "^30.1.1",
|
|
70
70
|
"nswag": "^14.7.1",
|
|
71
|
-
"oxfmt": "^0.
|
|
72
|
-
"oxlint": "^1.
|
|
73
|
-
"oxlint-tsgolint": "^7.0.
|
|
74
|
-
"playwright": "^1.
|
|
71
|
+
"oxfmt": "^0.71.0",
|
|
72
|
+
"oxlint": "^1.86.0",
|
|
73
|
+
"oxlint-tsgolint": "^7.0.2003",
|
|
74
|
+
"playwright": "^1.63.0",
|
|
75
75
|
"typescript": "^7.0.2",
|
|
76
|
-
"vite": "^8.
|
|
77
|
-
"vitest": "^
|
|
78
|
-
"vitest-browser-react": "^2.
|
|
76
|
+
"vite": "^8.3.1",
|
|
77
|
+
"vitest": "^5.0.2",
|
|
78
|
+
"vitest-browser-react": "^2.3.0"
|
|
79
79
|
},
|
|
80
80
|
"scripts": {
|
|
81
81
|
"type-check": "tsc --noEmit --skipLibCheck",
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
(function(){var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=((n,r,o)=>(o=n==null?{}:e(i(n)),s(r||!n||!n.__esModule||!a.call(n,`default`)?t(o,`default`,{value:n,enumerable:!0}):o,n)))(o(((e,t)=>{function n(e){return e instanceof Map?e.clear=e.delete=e.set=function(){throw Error(`map is read-only`)}:e instanceof Set&&(e.add=e.clear=e.delete=function(){throw Error(`set is read-only`)}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach(t=>{let r=e[t],i=typeof r;(i===`object`||i===`function`)&&!Object.isFrozen(r)&&n(r)}),e}var r=class{constructor(e){e.data===void 0&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}};function i(e){return e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`).replace(/'/g,`'`)}function a(e,...t){let n=Object.create(null);for(let t in e)n[t]=e[t];return t.forEach(function(e){for(let t in e)n[t]=e[t]}),n}let o=e=>!!e.scope,s=(e,{prefix:t})=>{if(e.startsWith(`language:`))return e.replace(`language:`,`language-`);if(e.includes(`.`)){let n=e.split(`.`);return[`${t}${n.shift()}`,...n.map((e,t)=>`${e}${`_`.repeat(t+1)}`)].join(` `)}return`${t}${e}`};var c=class{constructor(e,t){this.buffer=``,this.classPrefix=t.classPrefix,e.walk(this)}addText(e){this.buffer+=i(e)}openNode(e){if(!o(e))return;let t=s(e.scope,{prefix:this.classPrefix});this.span(t)}closeNode(e){o(e)&&(this.buffer+=`</span>`)}value(){return this.buffer}span(e){this.buffer+=`<span class="${e}">`}};let l=(e={})=>{let t={children:[]};return Object.assign(t,e),t};var u=class e{constructor(){this.rootNode=l(),this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){let t=l({scope:e});this.add(t),this.stack.push(t)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,t){return typeof t==`string`?e.addText(t):t.children&&(e.openNode(t),t.children.forEach(t=>this._walk(e,t)),e.closeNode(t)),e}static _collapse(t){typeof t!=`string`&&t.children&&(t.children.every(e=>typeof e==`string`)?t.children=[t.children.join(``)]:t.children.forEach(t=>{e._collapse(t)}))}},d=class extends u{constructor(e){super(),this.options=e}addText(e){e!==``&&this.add(e)}startScope(e){this.openNode(e)}endScope(){this.closeNode()}__addSublanguage(e,t){let n=e.root;t&&(n.scope=`language:${t}`),this.add(n)}toHTML(){return new c(this,this.options).value()}finalize(){return this.closeAllNodes(),!0}};function f(e){return e?typeof e==`string`?e:e.source:null}function p(e){return g(`(?=`,e,`)`)}function m(e){return g(`(?:`,e,`)*`)}function h(e){return g(`(?:`,e,`)?`)}function g(...e){return e.map(e=>f(e)).join(``)}function _(e){let t=e[e.length-1];return typeof t==`object`&&t.constructor===Object?(e.splice(e.length-1,1),t):{}}function v(...e){return`(`+(_(e).capture?``:`?:`)+e.map(e=>f(e)).join(`|`)+`)`}function y(e){return RegExp(e.toString()+`|`).exec(``).length-1}function ee(e,t){let n=e&&e.exec(t);return n&&n.index===0}let b=new RegExp(v(/\[(?:[^\\\]]|\\.)*\]/,/\(\?<(?![=!])[^>]+>/,/\(\?'[^']+'/,/\(\??/,/\\([1-9][0-9]*)/,/\\./));function x(e,{joinWith:t}){let n=0;return e.map(e=>{n+=1;let t=n,r=f(e),i=``;for(;r.length>0;){let e=b.exec(r);if(!e){i+=r;break}i+=r.substring(0,e.index),r=r.substring(e.index+e[0].length),e[0][0]===`\\`&&e[1]?i+=`\\`+String(Number(e[1])+t):(i+=e[0],(e[0]===`(`||/^\(\?[<']/.test(e[0]))&&n++)}return i}).map(e=>`(${e})`).join(t)}let S=/\b\B/,C=`[a-zA-Z]\\w*`,w=`[a-zA-Z_]\\w*`,T=`\\b\\d+(\\.\\d+)?`,E=`(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)`,D=`\\b(0b[01]+)`,O=(e={})=>{let t=/^#![ ]*\//;return e.binary&&(e.begin=g(t,/.*\b/,e.binary,/\b.*/)),a({scope:`meta`,begin:t,end:/$/,relevance:0,"on:begin":(e,t)=>{e.index!==0&&t.ignoreMatch()}},e)},k={begin:`\\\\[\\s\\S]`,relevance:0},A={scope:`string`,begin:`'`,end:`'`,illegal:`\\n`,contains:[k]},j={scope:`string`,begin:`"`,end:`"`,illegal:`\\n`,contains:[k]},M={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},N=function(e,t,n={}){let r=a({scope:`comment`,begin:e,end:t,contains:[]},n);r.contains.push({scope:`doctag`,begin:`[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)`,end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0});let i=v(`I`,`a`,`is`,`so`,`us`,`to`,`at`,`if`,`in`,`it`,`on`,/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/);return r.contains.push({begin:g(/[ ]+/,`(`,i,/[.]?[:]?([.][ ]|[ ])/,`){3}`)}),r},P=N(`//`,`$`),F=N(`/\\*`,`\\*/`),I=N(`#`,`$`);var L=Object.freeze({__proto__:null,APOS_STRING_MODE:A,BACKSLASH_ESCAPE:k,BINARY_NUMBER_MODE:{scope:`number`,begin:D,relevance:0},BINARY_NUMBER_RE:D,COMMENT:N,C_BLOCK_COMMENT_MODE:F,C_LINE_COMMENT_MODE:P,C_NUMBER_MODE:{scope:`number`,begin:E,relevance:0},C_NUMBER_RE:E,END_SAME_AS_BEGIN:function(e){return Object.assign(e,{"on:begin":(e,t)=>{t.data._beginMatch=e[1]},"on:end":(e,t)=>{t.data._beginMatch!==e[1]&&t.ignoreMatch()}})},HASH_COMMENT_MODE:I,IDENT_RE:C,MATCH_NOTHING_RE:S,METHOD_GUARD:{begin:`\\.\\s*[a-zA-Z_]\\w*`,relevance:0},NUMBER_MODE:{scope:`number`,begin:T,relevance:0},NUMBER_RE:T,PHRASAL_WORDS_MODE:M,QUOTE_STRING_MODE:j,REGEXP_MODE:{scope:`regexp`,begin:/\/(?=[^/\n]*\/)/,end:/\/[gimuy]*/,contains:[k,{begin:/\[/,end:/\]/,relevance:0,contains:[k]}]},RE_STARTERS_RE:`!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~`,SHEBANG:O,TITLE_MODE:{scope:`title`,begin:C,relevance:0},UNDERSCORE_IDENT_RE:w,UNDERSCORE_TITLE_MODE:{scope:`title`,begin:w,relevance:0}});function R(e,t){e.input[e.index-1]===`.`&&t.ignoreMatch()}function z(e,t){e.className!==void 0&&(e.scope=e.className,delete e.className)}function B(e,t){t&&e.beginKeywords&&(e.begin=`\\b(`+e.beginKeywords.split(` `).join(`|`)+`)(?!\\.)(?=\\b|\\s)`,e.__beforeBegin=R,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,e.relevance===void 0&&(e.relevance=0))}function te(e,t){Array.isArray(e.illegal)&&(e.illegal=v(...e.illegal))}function ne(e,t){if(e.match){if(e.begin||e.end)throw Error(`begin & end are not supported with match`);e.begin=e.match,delete e.match}}function re(e,t){e.relevance===void 0&&(e.relevance=1)}let ie=(e,t)=>{if(!e.beforeMatch)return;if(e.starts)throw Error(`beforeMatch cannot be used with starts`);let n=Object.assign({},e);Object.keys(e).forEach(t=>{delete e[t]}),e.keywords=n.keywords,e.begin=g(n.beforeMatch,p(n.begin)),e.starts={relevance:0,contains:[Object.assign(n,{endsParent:!0})]},e.relevance=0,delete n.beforeMatch},ae=[`of`,`and`,`for`,`in`,`not`,`or`,`if`,`then`,`parent`,`list`,`value`];function V(e,t,n=`keyword`){let r=Object.create(null);return typeof e==`string`?i(n,e.split(` `)):Array.isArray(e)?i(n,e):Object.keys(e).forEach(function(n){Object.assign(r,V(e[n],t,n))}),r;function i(e,n){t&&(n=n.map(e=>e.toLowerCase())),n.forEach(function(t){let n=t.split(`|`);r[n[0]]=[e,oe(n[0],n[1])]})}}function oe(e,t){return t?Number(t):+!se(e)}function se(e){return ae.includes(e.toLowerCase())}let H={},U=e=>{console.error(e)},W=(e,...t)=>{console.log(`WARN: ${e}`,...t)},G=(e,t)=>{H[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),H[`${e}/${t}`]=!0)},K=Error();function q(e,t,{key:n}){let r=0,i=e[n],a={},o={};for(let e=1;e<=t.length;e++)o[e+r]=i[e],a[e+r]=!0,r+=y(t[e-1]);e[n]=o,e[n]._emit=a,e[n]._multi=!0}function ce(e){if(Array.isArray(e.begin)){if(e.skip||e.excludeBegin||e.returnBegin)throw U(`skip, excludeBegin, returnBegin not compatible with beginScope: {}`),K;if(typeof e.beginScope!=`object`||e.beginScope===null)throw U(`beginScope must be object`),K;q(e,e.begin,{key:`beginScope`}),e.begin=x(e.begin,{joinWith:``})}}function le(e){if(Array.isArray(e.end)){if(e.skip||e.excludeEnd||e.returnEnd)throw U(`skip, excludeEnd, returnEnd not compatible with endScope: {}`),K;if(typeof e.endScope!=`object`||e.endScope===null)throw U(`endScope must be object`),K;q(e,e.end,{key:`endScope`}),e.end=x(e.end,{joinWith:``})}}function ue(e){e.scope&&typeof e.scope==`object`&&e.scope!==null&&(e.beginScope=e.scope,delete e.scope)}function de(e){ue(e),typeof e.beginScope==`string`&&(e.beginScope={_wrap:e.beginScope}),typeof e.endScope==`string`&&(e.endScope={_wrap:e.endScope}),ce(e),le(e)}function fe(e){function t(t,n){return new RegExp(f(t),`m`+(e.case_insensitive?`i`:``)+(e.unicodeRegex?`u`:``)+(n?`g`:``))}class n{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,t){t.position=this.position++,this.matchIndexes[this.matchAt]=t,this.regexes.push([t,e]),this.matchAt+=y(e)+1}compile(){this.regexes.length===0&&(this.exec=()=>null);let e=this.regexes.map(e=>e[1]);this.matcherRe=t(x(e,{joinWith:`|`}),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;let t=this.matcherRe.exec(e);if(!t)return null;let n=t.findIndex((e,t)=>t>0&&e!==void 0),r=this.matchIndexes[n];return t.splice(0,n),Object.assign(t,r)}}class r{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];let t=new n;return this.rules.slice(e).forEach(([e,n])=>t.addRule(e,n)),t.compile(),this.multiRegexes[e]=t,t}resumingScanAtSamePosition(){return this.regexIndex!==0}considerAll(){this.regexIndex=0}addRule(e,t){this.rules.push([e,t]),t.type===`begin`&&this.count++}exec(e){let t=this.getMatcher(this.regexIndex);t.lastIndex=this.lastIndex;let n=t.exec(e);if(this.resumingScanAtSamePosition()&&!(n&&n.index===this.lastIndex)){let t=this.getMatcher(0);t.lastIndex=this.lastIndex+1,n=t.exec(e)}return n&&(this.regexIndex+=n.position+1,this.regexIndex===this.count&&this.considerAll()),n}}function i(e){let t=new r;return e.contains.forEach(e=>t.addRule(e.begin,{rule:e,type:`begin`})),e.terminatorEnd&&t.addRule(e.terminatorEnd,{type:`end`}),e.illegal&&t.addRule(e.illegal,{type:`illegal`}),t}function o(n,r){let a=n;if(n.isCompiled)return a;[z,ne,de,ie].forEach(e=>e(n,r)),e.compilerExtensions.forEach(e=>e(n,r)),n.__beforeBegin=null,[B,te,re].forEach(e=>e(n,r)),n.isCompiled=!0;let s=null;return typeof n.keywords==`object`&&n.keywords.$pattern&&(n.keywords=Object.assign({},n.keywords),s=n.keywords.$pattern,delete n.keywords.$pattern),s||=/\w+/,n.keywords&&=V(n.keywords,e.case_insensitive),a.keywordPatternRe=t(s,!0),r&&(n.begin||=/\B|\b/,a.beginRe=t(a.begin),!n.end&&!n.endsWithParent&&(n.end=/\B|\b/),n.end&&(a.endRe=t(a.end)),a.terminatorEnd=f(a.end)||``,n.endsWithParent&&r.terminatorEnd&&(a.terminatorEnd+=(n.end?`|`:``)+r.terminatorEnd)),n.illegal&&(a.illegalRe=t(n.illegal)),n.contains||=[],n.contains=[].concat(...n.contains.map(function(e){return pe(e===`self`?n:e)})),n.contains.forEach(function(e){o(e,a)}),n.starts&&o(n.starts,r),a.matcher=i(a),a}if(e.compilerExtensions||=[],e.contains&&e.contains.includes(`self`))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return e.classNameAliases=a(e.classNameAliases||{}),o(e)}function J(e){return e?e.endsWithParent||J(e.starts):!1}function pe(e){return e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map(function(t){return a(e,{variants:null},t)})),e.cachedVariants?e.cachedVariants:J(e)?a(e,{starts:e.starts?a(e.starts):null}):Object.isFrozen(e)?a(e):e}var me=`11.12.0`,he=class extends Error{constructor(e,t){super(e),this.name=`HTMLInjectionError`,this.html=t}};let Y=i,X=a,Z=Symbol(`nomatch`),Q=function(e){let t=Object.create(null),i=Object.create(null),a=[],o=!0,s=`Could not find the language '{}', did you forget to load/include a language module?`,c={disableAutodetect:!0,name:`Plain text`,contains:[]},l={ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:`hljs-`,cssSelector:`pre code`,languages:null,__emitter:d};function u(e){return l.noHighlightRe.test(e)}function f(e){let t=e.className+` `;t+=e.parentNode?e.parentNode.className:``;let n=l.languageDetectRe.exec(t);if(n){let t=M(n[1]);return t||(W(s.replace(`{}`,n[1])),W(`Falling back to no-highlight mode for this block.`,e)),t?n[1]:`no-highlight`}return t.split(/\s+/).find(e=>u(e)||M(e))}function _(e,t,n){let r=``,i=``;typeof t==`object`?(r=e,n=t.ignoreIllegals,i=t.language):(G(`10.7.0`,`highlight(lang, code, ...args) has been deprecated.`),G(`10.7.0`,`Please use highlight(code, options) instead.
|
|
2
|
-
https://github.com/highlightjs/highlight.js/issues/2277`),i=e,r=t),n===void 0&&(n=!0);let a={code:r,language:i};z(`before:highlight`,a);let o=a.result?a.result:y(a.language,a.code,n);return o.code=a.code,z(`after:highlight`,o),o}function y(e,n,i,a){let c=Object.create(null);function u(e,t){return e.keywords[t]}function d(){if(!k.keywords){j.addText(N);return}let e=0;k.keywordPatternRe.lastIndex=0;let t=k.keywordPatternRe.exec(N),n=``;for(;t;){n+=N.substring(e,t.index);let r=E.case_insensitive?t[0].toLowerCase():t[0],i=u(k,r);if(i){let[e,a]=i;if(j.addText(n),n=``,c[r]=(c[r]||0)+1,c[r]<=7&&(P+=a),e.startsWith(`_`))n+=t[0];else{let n=E.classNameAliases[e]||e;m(t[0],n)}}else n+=t[0];e=k.keywordPatternRe.lastIndex,t=k.keywordPatternRe.exec(N)}n+=N.substring(e),j.addText(n)}function f(){if(N===``)return;let e=null;if(typeof k.subLanguage==`string`){if(!t[k.subLanguage]){j.addText(N);return}e=y(k.subLanguage,N,!0,A[k.subLanguage]),A[k.subLanguage]=e._top}else e=x(N,k.subLanguage.length?k.subLanguage:null);k.relevance>0&&(P+=e.relevance),j.__addSublanguage(e._emitter,e.language)}function p(){k.subLanguage==null?d():f(),N=``}function m(e,t){e!==``&&(j.startScope(t),j.addText(e),j.endScope())}function h(e,t){let n=1,r=t.length-1;for(;n<=r;){if(!e._emit[n]){n++;continue}let r=E.classNameAliases[e[n]]||e[n],i=t[n];r?m(i,r):(N=i,d(),N=``),n++}}function g(e,t){return e.scope&&typeof e.scope==`string`&&j.openNode(E.classNameAliases[e.scope]||e.scope),e.beginScope&&(e.beginScope._wrap?(m(N,E.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap),N=``):e.beginScope._multi&&(h(e.beginScope,t),N=``)),k=Object.create(e,{parent:{value:k}}),k}function _(e,t,n){let i=ee(e.endRe,n);if(i){if(e[`on:end`]){let n=new r(e);e[`on:end`](t,n),n.isMatchIgnored&&(i=!1)}if(i){for(;e.endsParent&&e.parent;)e=e.parent;return e}}if(e.endsWithParent)return _(e.parent,t,n)}function v(e){return k.matcher.regexIndex===0?(N+=e[0],1):(L=!0,0)}function b(e){let t=e[0],n=e.rule,i=new r(n),a=[n.__beforeBegin,n[`on:begin`]];for(let n of a)if(n&&(n(e,i),i.isMatchIgnored))return v(t);return n.skip?N+=t:(n.excludeBegin&&(N+=t),p(),!n.returnBegin&&!n.excludeBegin&&(N=t)),g(n,e),n.returnBegin?0:t.length}function S(e){let t=e[0],r=n.substring(e.index),i=_(k,e,r);if(!i)return Z;let a=k;k.endScope&&k.endScope._wrap?(p(),m(t,k.endScope._wrap)):k.endScope&&k.endScope._multi?(p(),h(k.endScope,e)):a.skip?N+=t:(a.returnEnd||a.excludeEnd||(N+=t),p(),a.excludeEnd&&(N=t));do k.scope&&j.closeNode(),!k.skip&&!k.subLanguage&&(P+=k.relevance),k=k.parent;while(k!==i.parent);return i.starts&&g(i.starts,e),a.returnEnd?0:t.length}function C(){let e=[];for(let t=k;t!==E;t=t.parent)t.scope&&e.unshift(t.scope);e.forEach(e=>j.openNode(e))}let w={};function T(t,r){let a=r&&r[0];if(N+=t,a==null)return p(),0;if(w.type===`begin`&&r.type===`end`&&w.index===r.index&&a===``){if(N+=n.slice(r.index,r.index+1),!o){let t=Error(`0 width match regex (${e})`);throw t.languageName=e,t.badRule=w.rule,t}return 1}if(w=r,r.type===`begin`)return b(r);if(r.type===`illegal`&&!i){let e=Error(`Illegal lexeme "`+a+`" for mode "`+(k.scope||`<unnamed>`)+`"`);throw e.mode=k,e}if(r.type===`end`){let e=S(r);if(e!==Z)return e}if(r.type===`illegal`&&a===``)return r.index===n.length||(N+=`
|
|
3
|
-
`),1;if(I>1e5&&I>r.index*3)throw Error(`potential infinite loop, way more iterations than matches`);return N+=a,a.length}let E=M(e);if(!E)throw U(s.replace(`{}`,e)),Error(`Unknown language: "`+e+`"`);let D=fe(E),O=``,k=a||D,A={},j=new l.__emitter(l);C();let N=``,P=0,F=0,I=0,L=!1;try{if(E.__emitTokens)E.__emitTokens(n,j);else{for(k.matcher.considerAll();;){I++,L?L=!1:k.matcher.considerAll(),k.matcher.lastIndex=F;let e=k.matcher.exec(n);if(!e)break;let t=T(n.substring(F,e.index),e);F=e.index+t}T(n.substring(F))}return j.finalize(),O=j.toHTML(),{language:e,value:O,relevance:P,illegal:!1,_emitter:j,_top:k}}catch(t){if(t.message&&t.message.includes(`Illegal`))return{language:e,value:Y(n),illegal:!0,relevance:0,_illegalBy:{message:t.message,index:F,context:n.slice(F-100,F+100),mode:t.mode,resultSoFar:O},_emitter:j};if(o)return{language:e,value:Y(n),illegal:!1,relevance:0,errorRaised:t,_emitter:j,_top:k};throw t}}function b(e){let t={value:Y(e),illegal:!1,relevance:0,_top:c,_emitter:new l.__emitter(l)};return t._emitter.addText(e),t}function x(e,n){n=n||l.languages||Object.keys(t);let r=b(e),i=n.filter(M).filter(P).map(t=>y(t,e,!1));i.unshift(r);let[a,o]=i.sort((e,t)=>{if(e.relevance!==t.relevance)return t.relevance-e.relevance;if(e.language&&t.language){if(M(e.language).supersetOf===t.language)return 1;if(M(t.language).supersetOf===e.language)return-1}return 0}),s=a;return s.secondBest=o,s}function S(e,t,n){let r=t&&i[t]||n;e.classList.add(`hljs`),e.classList.add(`language-${r}`)}function C(e){let t=null,n=f(e);if(u(n))return;if(z(`before:highlightElement`,{el:e,language:n}),e.dataset.highlighted){console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",e);return}if(e.children.length>0&&(l.ignoreUnescapedHTML||(console.warn(`One of your code blocks includes unescaped HTML. This is a potentially serious security risk.`),console.warn(`https://github.com/highlightjs/highlight.js/wiki/security`),console.warn(`The element with unescaped HTML:`),console.warn(e)),l.throwUnescapedHTML))throw new he(`One of your code blocks includes unescaped HTML.`,e.innerHTML);t=e;let r=t.textContent,i=n?_(r,{language:n,ignoreIllegals:!0}):x(r);e.innerHTML=i.value,e.dataset.highlighted=`yes`,S(e,n,i.language),e.result={language:i.language,re:i.relevance,relevance:i.relevance},i.secondBest&&(e.secondBest={language:i.secondBest.language,relevance:i.secondBest.relevance}),z(`after:highlightElement`,{el:e,result:i,text:r})}function w(e){l=X(l,e)}let T=()=>{O(),G(`10.6.0`,`initHighlighting() deprecated. Use highlightAll() now.`)};function E(){O(),G(`10.6.0`,`initHighlightingOnLoad() deprecated. Use highlightAll() now.`)}let D=!1;function O(){function e(){O()}if(document.readyState===`loading`){D||window.addEventListener(`DOMContentLoaded`,e,!1),D=!0;return}document.querySelectorAll(l.cssSelector).forEach(C)}function k(n,r){let i=null;try{i=r(e)}catch(e){if(U(`Language definition for '{}' could not be registered.`.replace(`{}`,n)),o)U(e);else throw e;i=c}i.name||(i.name=n),t[n]=i,i.rawDefinition=r.bind(null,e),i.aliases&&N(i.aliases,{languageName:n})}function A(e){delete t[e];for(let t of Object.keys(i))i[t]===e&&delete i[t]}function j(){return Object.keys(t)}function M(e){return e=(e||``).toLowerCase(),t[e]||t[i[e]]}function N(e,{languageName:t}){typeof e==`string`&&(e=[e]),e.forEach(e=>{i[e.toLowerCase()]=t})}function P(e){let t=M(e);return t&&!t.disableAutodetect}function F(e){e[`before:highlightBlock`]&&!e[`before:highlightElement`]&&(e[`before:highlightElement`]=t=>{e[`before:highlightBlock`](Object.assign({block:t.el},t))}),e[`after:highlightBlock`]&&!e[`after:highlightElement`]&&(e[`after:highlightElement`]=t=>{e[`after:highlightBlock`](Object.assign({block:t.el},t))})}function I(e){F(e),a.push(e)}function R(e){let t=a.indexOf(e);t!==-1&&a.splice(t,1)}function z(e,t){let n=e;a.forEach(function(e){e[n]&&e[n](t)})}function B(e){return G(`10.7.0`,`highlightBlock will be removed entirely in v12.0`),G(`10.7.0`,`Please use highlightElement now.`),C(e)}Object.assign(e,{highlight:_,highlightAuto:x,highlightAll:O,highlightElement:C,highlightBlock:B,configure:w,initHighlighting:T,initHighlightingOnLoad:E,registerLanguage:k,unregisterLanguage:A,listLanguages:j,getLanguage:M,registerAliases:N,autoDetection:P,inherit:X,addPlugin:I,removePlugin:R}),e.debugMode=function(){o=!1},e.safeMode=function(){o=!0},e.versionString=me,e.regex={concat:g,lookahead:p,either:v,optional:h,anyNumberOfTimes:m};for(let e in L)typeof L[e]==`object`&&n(L[e]);return Object.assign(e,L),e},$=Q({});$.newInstance=()=>Q({}),t.exports=$,$.HighlightJS=$,$.default=$}))()).default;function l(e){let t=e.regex,n={$pattern:/[A-Z]+|%/,keyword:[`THEN`,`ELSE`,`ENDIF`,`IF`,`GOTO`,`DO`,`WHILE`,`WH`,`END`,`CALL`,`SUB`,`ENDSUB`,`EQ`,`NE`,`LT`,`GT`,`LE`,`GE`,`AND`,`OR`,`XOR`,`%`],built_in:[`ATAN`,`ABS`,`ACOS`,`ASIN`,`COS`,`EXP`,`FIX`,`FUP`,`ROUND`,`LN`,`SIN`,`SQRT`,`TAN`,`EXISTS`]},r=/\b/;function i(e,t){if(e.index===0)return;let n=e.input[e.index-1];n>=`0`&&n<=`9`||n!==`_`&&t.ignoreMatch()}let a=/[+-]?((\.\d+)|(\d+)(\.\d*)?)/,o=/[GM]\s*\d+(\.\d+)?/,s=/T\s*\d+/,c=/O\s*\d+/,l=/O<.+>/,u=/[ABCUVWXYZ]\s*/,d=/[FHIJKPQRS]\s*/;return{name:`G-code (ISO 6983)`,aliases:[`nc`],case_insensitive:!0,disableAutodetect:!0,keywords:n,contains:[e.COMMENT(/\(/,/\)/),e.COMMENT(/;/,/$/),e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,{scope:`title.function`,variants:[{match:t.concat(r,o)},{begin:o,"on:begin":i},{match:t.concat(r,s)},{begin:s,"on:begin":i}]},{scope:`symbol`,variants:[{match:t.concat(r,c)},{begin:c,"on:begin":i},{match:t.concat(r,l)},{begin:l,"on:begin":i},{match:/\*\s*\d+\s*$/}]},{scope:`operator`,match:/^N\s*\d+/},{scope:`variable`,match:/-?#\s*\d+/},{scope:`property`,variants:[{match:t.concat(r,u,a)},{begin:t.concat(u,a),"on:begin":i}]},{scope:`params`,variants:[{match:t.concat(r,d,a)},{begin:t.concat(d,a),"on:begin":i}]}]}}c.registerLanguage(`gcode`,l),self.addEventListener(`message`,e=>{self.postMessage(c.highlight(e.data,{language:`gcode`}).value,[])})})();
|