green-screen-react 0.3.0 → 0.4.0

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/dist/index.mjs CHANGED
@@ -1,7 +1,236 @@
1
1
  // src/components/GreenScreenTerminal.tsx
2
- import { useState as useState4, useEffect as useEffect4, useRef as useRef4, useCallback as useCallback3, useMemo as useMemo2 } from "react";
2
+ import { useState as useState5, useEffect as useEffect4, useRef as useRef4, useCallback as useCallback3, useMemo as useMemo2 } from "react";
3
3
 
4
- // src/hooks/useTN5250.ts
4
+ // src/adapters/RestAdapter.ts
5
+ var RestAdapter = class {
6
+ constructor(options) {
7
+ this.baseUrl = options.baseUrl.replace(/\/+$/, "");
8
+ this.staticHeaders = options.headers || {};
9
+ this.getHeaders = options.getHeaders;
10
+ }
11
+ async buildHeaders() {
12
+ const dynamic = this.getHeaders ? await this.getHeaders() : {};
13
+ return {
14
+ "Content-Type": "application/json",
15
+ ...this.staticHeaders,
16
+ ...dynamic
17
+ };
18
+ }
19
+ async request(method, path, body) {
20
+ const headers = await this.buildHeaders();
21
+ const response = await fetch(`${this.baseUrl}${path}`, {
22
+ method,
23
+ headers,
24
+ body: body ? JSON.stringify(body) : void 0
25
+ });
26
+ if (!response.ok) {
27
+ const detail = await response.json().catch(() => ({}));
28
+ throw new Error(detail?.detail || `HTTP ${response.status}`);
29
+ }
30
+ return response.json();
31
+ }
32
+ async getScreen() {
33
+ try {
34
+ return await this.request("GET", "/screen");
35
+ } catch (e) {
36
+ const message = e instanceof Error ? e.message : String(e);
37
+ if (message.includes("503") || message.includes("404")) {
38
+ return null;
39
+ }
40
+ throw e;
41
+ }
42
+ }
43
+ async getStatus() {
44
+ return this.request("GET", "/status");
45
+ }
46
+ async sendText(text) {
47
+ return this.request("POST", "/send-text", { text });
48
+ }
49
+ async sendKey(key) {
50
+ return this.request("POST", "/send-key", { key });
51
+ }
52
+ async connect(config) {
53
+ return this.request("POST", "/connect", config);
54
+ }
55
+ async disconnect() {
56
+ return this.request("POST", "/disconnect");
57
+ }
58
+ async reconnect() {
59
+ return this.request("POST", "/reconnect");
60
+ }
61
+ };
62
+
63
+ // src/adapters/WebSocketAdapter.ts
64
+ var WebSocketAdapter = class {
65
+ constructor(options = {}) {
66
+ this.ws = null;
67
+ this.screen = null;
68
+ this.status = { connected: false, status: "disconnected" };
69
+ this.pendingResolvers = /* @__PURE__ */ new Map();
70
+ this.screenListeners = /* @__PURE__ */ new Set();
71
+ this.statusListeners = /* @__PURE__ */ new Set();
72
+ this.workerUrl = (options.workerUrl || "http://localhost:3001").replace(/\/+$/, "");
73
+ }
74
+ /** Subscribe to real-time screen updates */
75
+ onScreen(listener) {
76
+ this.screenListeners.add(listener);
77
+ return () => this.screenListeners.delete(listener);
78
+ }
79
+ /** Subscribe to status changes */
80
+ onStatus(listener) {
81
+ this.statusListeners.add(listener);
82
+ return () => this.statusListeners.delete(listener);
83
+ }
84
+ async getScreen() {
85
+ return this.screen;
86
+ }
87
+ async getStatus() {
88
+ return this.status;
89
+ }
90
+ async sendText(text) {
91
+ return this.sendAndWaitForScreen({ type: "text", text });
92
+ }
93
+ async sendKey(key) {
94
+ return this.sendAndWaitForScreen({ type: "key", key });
95
+ }
96
+ async connect(config) {
97
+ await this.ensureWebSocket();
98
+ if (!config) {
99
+ return { success: false, error: "ConnectConfig required" };
100
+ }
101
+ return new Promise((resolve) => {
102
+ const timeout = setTimeout(() => {
103
+ resolve({ success: false, error: "Connection timeout" });
104
+ }, 3e4);
105
+ const onMessage = (event) => {
106
+ try {
107
+ const msg = JSON.parse(event.data);
108
+ if (msg.type === "connected") {
109
+ clearTimeout(timeout);
110
+ this.ws?.removeEventListener("message", onMessage);
111
+ resolve({ success: true });
112
+ } else if (msg.type === "error") {
113
+ clearTimeout(timeout);
114
+ this.ws?.removeEventListener("message", onMessage);
115
+ resolve({ success: false, error: msg.message });
116
+ }
117
+ } catch {
118
+ }
119
+ };
120
+ this.ws?.addEventListener("message", onMessage);
121
+ this.wsSend({
122
+ type: "connect",
123
+ host: config.host,
124
+ port: config.port,
125
+ protocol: config.protocol,
126
+ username: config.username,
127
+ password: config.password
128
+ });
129
+ });
130
+ }
131
+ async disconnect() {
132
+ this.wsSend({ type: "disconnect" });
133
+ this.status = { connected: false, status: "disconnected" };
134
+ if (this.ws) {
135
+ this.ws.close();
136
+ this.ws = null;
137
+ }
138
+ return { success: true };
139
+ }
140
+ async reconnect() {
141
+ return { success: false, error: "Use disconnect() then connect() instead" };
142
+ }
143
+ /** Close the WebSocket without sending disconnect */
144
+ dispose() {
145
+ if (this.ws) {
146
+ this.ws.close();
147
+ this.ws = null;
148
+ }
149
+ }
150
+ async ensureWebSocket() {
151
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) return;
152
+ return new Promise((resolve, reject) => {
153
+ const wsUrl = this.workerUrl.replace(/^http/, "ws") + "/ws";
154
+ this.ws = new WebSocket(wsUrl);
155
+ this.ws.onopen = () => resolve();
156
+ this.ws.onerror = () => reject(new Error("WebSocket connection failed"));
157
+ this.ws.onmessage = (event) => {
158
+ try {
159
+ const msg = JSON.parse(event.data);
160
+ this.handleMessage(msg);
161
+ } catch {
162
+ }
163
+ };
164
+ this.ws.onclose = () => {
165
+ this.status = { connected: false, status: "disconnected" };
166
+ for (const listener of this.statusListeners) listener(this.status);
167
+ };
168
+ });
169
+ }
170
+ handleMessage(msg) {
171
+ switch (msg.type) {
172
+ case "screen":
173
+ this.screen = msg.data;
174
+ for (const listener of this.screenListeners) listener(msg.data);
175
+ const screenResolver = this.pendingResolvers.get("screen");
176
+ if (screenResolver) {
177
+ this.pendingResolvers.delete("screen");
178
+ screenResolver(msg.data);
179
+ }
180
+ break;
181
+ case "status":
182
+ this.status = msg.data;
183
+ for (const listener of this.statusListeners) listener(msg.data);
184
+ break;
185
+ case "error":
186
+ const errorResolver = this.pendingResolvers.get("screen");
187
+ if (errorResolver) {
188
+ this.pendingResolvers.delete("screen");
189
+ errorResolver(null);
190
+ }
191
+ break;
192
+ }
193
+ }
194
+ sendAndWaitForScreen(msg) {
195
+ return new Promise((resolve) => {
196
+ const timeout = setTimeout(() => {
197
+ this.pendingResolvers.delete("screen");
198
+ resolve({ success: true, ...this.screenToResult() });
199
+ }, 5e3);
200
+ this.pendingResolvers.set("screen", (screen) => {
201
+ clearTimeout(timeout);
202
+ if (screen) {
203
+ resolve({
204
+ success: true,
205
+ cursor_row: screen.cursor_row,
206
+ cursor_col: screen.cursor_col,
207
+ content: screen.content,
208
+ screen_signature: screen.screen_signature
209
+ });
210
+ } else {
211
+ resolve({ success: false, error: "No screen data received" });
212
+ }
213
+ });
214
+ this.wsSend(msg);
215
+ });
216
+ }
217
+ screenToResult() {
218
+ if (!this.screen) return {};
219
+ return {
220
+ cursor_row: this.screen.cursor_row,
221
+ cursor_col: this.screen.cursor_col,
222
+ content: this.screen.content,
223
+ screen_signature: this.screen.screen_signature
224
+ };
225
+ }
226
+ wsSend(data) {
227
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
228
+ this.ws.send(JSON.stringify(data));
229
+ }
230
+ }
231
+ };
232
+
233
+ // src/hooks/useTerminal.ts
5
234
  import { useState, useCallback, useEffect, useRef } from "react";
6
235
  function useTerminalConnection(adapter) {
7
236
  const [status, setStatus] = useState(null);
@@ -122,9 +351,6 @@ function useTerminalInput(adapter) {
122
351
  }, [adapter]);
123
352
  return { loading, error, sendText, sendKey };
124
353
  }
125
- var useTN5250Connection = useTerminalConnection;
126
- var useTN5250Screen = useTerminalScreen;
127
- var useTN5250Terminal = useTerminalInput;
128
354
 
129
355
  // src/hooks/useTypingAnimation.ts
130
356
  import { useState as useState2, useEffect as useEffect2, useRef as useRef2, useCallback as useCallback2, useMemo } from "react";
@@ -572,8 +798,8 @@ function TerminalBootLoader({
572
798
  );
573
799
  }
574
800
 
575
- // src/components/GreenScreenTerminal.tsx
576
- import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
801
+ // src/components/Icons.tsx
802
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
577
803
  var TerminalIcon = ({ size = 14 }) => /* @__PURE__ */ jsxs2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
578
804
  /* @__PURE__ */ jsx2("polyline", { points: "4 17 10 11 4 5" }),
579
805
  /* @__PURE__ */ jsx2("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
@@ -605,6 +831,10 @@ var RefreshIcon = ({ size = 12, className }) => /* @__PURE__ */ jsxs2("svg", { w
605
831
  ] });
606
832
  var KeyIcon = ({ size = 12, style: s }) => /* @__PURE__ */ jsx2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: s, children: /* @__PURE__ */ jsx2("path", { d: "M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4" }) });
607
833
  var MinimizeIcon = () => /* @__PURE__ */ jsx2("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx2("path", { d: "M4 14h6v6M3 21l7-7M20 10h-6V4M21 3l-7 7" }) });
834
+
835
+ // src/components/InlineSignIn.tsx
836
+ import { useState as useState4 } from "react";
837
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
608
838
  var PROTOCOL_OPTIONS = [
609
839
  { value: "tn5250", label: "TN5250 (IBM i)" },
610
840
  { value: "tn3270", label: "TN3270 (Mainframe)" },
@@ -647,42 +877,56 @@ function InlineSignIn({ defaultProtocol, loading, error, onConnect }) {
647
877
  color: "var(--gs-muted, #94a3b8)",
648
878
  fontFamily: "var(--gs-font)"
649
879
  };
650
- return /* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit, className: "gs-signin", children: [
651
- /* @__PURE__ */ jsxs2("div", { style: { textAlign: "center", marginBottom: "16px" }, children: [
652
- /* @__PURE__ */ jsx2(TerminalIcon, { size: 28 }),
653
- /* @__PURE__ */ jsx2("div", { style: { fontSize: "11px", letterSpacing: "0.15em", textTransform: "uppercase", color: "var(--gs-muted)", marginTop: "8px" }, children: "Connect to Host" })
880
+ return /* @__PURE__ */ jsxs3("form", { onSubmit: handleSubmit, className: "gs-signin", children: [
881
+ /* @__PURE__ */ jsxs3("div", { style: { textAlign: "center", marginBottom: "16px" }, children: [
882
+ /* @__PURE__ */ jsx3(TerminalIcon, { size: 28 }),
883
+ /* @__PURE__ */ jsx3("div", { style: { fontSize: "11px", letterSpacing: "0.15em", textTransform: "uppercase", color: "var(--gs-muted)", marginTop: "8px" }, children: "Connect to Host" })
654
884
  ] }),
655
- /* @__PURE__ */ jsxs2("div", { className: "gs-signin-row", children: [
656
- /* @__PURE__ */ jsxs2("div", { style: { flex: 1 }, children: [
657
- /* @__PURE__ */ jsx2("label", { style: labelStyle, children: "Host" }),
658
- /* @__PURE__ */ jsx2("input", { style: inputStyle, value: host, onChange: (e) => setHost(e.target.value), placeholder: "192.168.1.100", required: true, autoFocus: true })
885
+ /* @__PURE__ */ jsxs3("div", { className: "gs-signin-row", children: [
886
+ /* @__PURE__ */ jsxs3("div", { style: { flex: 1 }, children: [
887
+ /* @__PURE__ */ jsx3("label", { style: labelStyle, children: "Host" }),
888
+ /* @__PURE__ */ jsx3("input", { style: inputStyle, value: host, onChange: (e) => setHost(e.target.value), placeholder: "192.168.1.100", required: true, autoFocus: true })
659
889
  ] }),
660
- /* @__PURE__ */ jsxs2("div", { style: { width: "72px" }, children: [
661
- /* @__PURE__ */ jsx2("label", { style: labelStyle, children: "Port" }),
662
- /* @__PURE__ */ jsx2("input", { style: inputStyle, value: port, onChange: (e) => setPort(e.target.value), placeholder: "23", type: "number", min: "1", max: "65535" })
890
+ /* @__PURE__ */ jsxs3("div", { style: { width: "72px" }, children: [
891
+ /* @__PURE__ */ jsx3("label", { style: labelStyle, children: "Port" }),
892
+ /* @__PURE__ */ jsx3("input", { style: inputStyle, value: port, onChange: (e) => setPort(e.target.value), placeholder: "23", type: "number", min: "1", max: "65535" })
663
893
  ] })
664
894
  ] }),
665
- /* @__PURE__ */ jsxs2("div", { children: [
666
- /* @__PURE__ */ jsx2("label", { style: labelStyle, children: "Protocol" }),
667
- /* @__PURE__ */ jsx2("select", { style: { ...inputStyle, appearance: "none" }, value: selectedProtocol, onChange: (e) => setSelectedProtocol(e.target.value), children: PROTOCOL_OPTIONS.map((o) => /* @__PURE__ */ jsx2("option", { value: o.value, children: o.label }, o.value)) })
895
+ /* @__PURE__ */ jsxs3("div", { children: [
896
+ /* @__PURE__ */ jsx3("label", { style: labelStyle, children: "Protocol" }),
897
+ /* @__PURE__ */ jsx3("select", { style: { ...inputStyle, appearance: "none" }, value: selectedProtocol, onChange: (e) => setSelectedProtocol(e.target.value), children: PROTOCOL_OPTIONS.map((o) => /* @__PURE__ */ jsx3("option", { value: o.value, children: o.label }, o.value)) })
668
898
  ] }),
669
- /* @__PURE__ */ jsxs2("div", { children: [
670
- /* @__PURE__ */ jsx2("label", { style: labelStyle, children: "Username" }),
671
- /* @__PURE__ */ jsx2("input", { style: inputStyle, value: username, onChange: (e) => setUsername(e.target.value), required: true, autoComplete: "username" })
899
+ /* @__PURE__ */ jsxs3("div", { children: [
900
+ /* @__PURE__ */ jsx3("label", { style: labelStyle, children: "Username" }),
901
+ /* @__PURE__ */ jsx3("input", { style: inputStyle, value: username, onChange: (e) => setUsername(e.target.value), required: true, autoComplete: "username" })
672
902
  ] }),
673
- /* @__PURE__ */ jsxs2("div", { children: [
674
- /* @__PURE__ */ jsx2("label", { style: labelStyle, children: "Password" }),
675
- /* @__PURE__ */ jsx2("input", { style: inputStyle, type: "password", value: password, onChange: (e) => setPassword(e.target.value), required: true, autoComplete: "current-password" })
903
+ /* @__PURE__ */ jsxs3("div", { children: [
904
+ /* @__PURE__ */ jsx3("label", { style: labelStyle, children: "Password" }),
905
+ /* @__PURE__ */ jsx3("input", { style: inputStyle, type: "password", value: password, onChange: (e) => setPassword(e.target.value), required: true, autoComplete: "current-password" })
676
906
  ] }),
677
- error && /* @__PURE__ */ jsxs2("div", { style: { color: "#FF6B00", fontSize: "11px", fontFamily: "var(--gs-font)", display: "flex", alignItems: "center", gap: "6px" }, children: [
678
- /* @__PURE__ */ jsx2(AlertTriangleIcon, { size: 12 }),
679
- /* @__PURE__ */ jsx2("span", { children: error })
907
+ error && /* @__PURE__ */ jsxs3("div", { style: { color: "#FF6B00", fontSize: "11px", fontFamily: "var(--gs-font)", display: "flex", alignItems: "center", gap: "6px" }, children: [
908
+ /* @__PURE__ */ jsx3(AlertTriangleIcon, { size: 12 }),
909
+ /* @__PURE__ */ jsx3("span", { children: error })
680
910
  ] }),
681
- /* @__PURE__ */ jsx2("button", { type: "submit", disabled: loading || !host || !username || !password, className: "gs-signin-btn", children: loading ? "Connecting..." : "Connect" })
911
+ /* @__PURE__ */ jsx3("button", { type: "submit", disabled: loading || !host || !username || !password, className: "gs-signin-btn", children: loading ? "Connecting..." : "Connect" })
682
912
  ] });
683
913
  }
914
+
915
+ // src/components/GreenScreenTerminal.tsx
916
+ import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
917
+ var noopResult = { success: false, error: "No adapter configured" };
918
+ var noopAdapter = {
919
+ getScreen: async () => null,
920
+ getStatus: async () => ({ connected: false, status: "disconnected" }),
921
+ sendText: async () => noopResult,
922
+ sendKey: async () => noopResult,
923
+ connect: async () => noopResult,
924
+ disconnect: async () => noopResult,
925
+ reconnect: async () => noopResult
926
+ };
684
927
  function GreenScreenTerminal({
685
- adapter,
928
+ adapter: externalAdapter,
929
+ baseUrl,
686
930
  protocol,
687
931
  protocolProfile: customProfile,
688
932
  screenData: externalScreenData,
@@ -695,7 +939,7 @@ function GreenScreenTerminal({
695
939
  showHeader = true,
696
940
  typingAnimation = true,
697
941
  typingBudgetMs = 60,
698
- inlineSignIn = false,
942
+ inlineSignIn = true,
699
943
  defaultProtocol: signInDefaultProtocol,
700
944
  onSignIn,
701
945
  bootLoader,
@@ -708,6 +952,16 @@ function GreenScreenTerminal({
708
952
  style
709
953
  }) {
710
954
  const profile = customProfile ?? getProtocolProfile(protocol);
955
+ const [internalAdapter, setInternalAdapter] = useState5(null);
956
+ const baseUrlAdapter = useMemo2(
957
+ () => baseUrl ? new RestAdapter({ baseUrl }) : null,
958
+ [baseUrl]
959
+ );
960
+ const defaultWsAdapter = useMemo2(
961
+ () => !externalAdapter && !baseUrl ? new WebSocketAdapter() : null,
962
+ [externalAdapter, baseUrl]
963
+ );
964
+ const adapter = externalAdapter ?? baseUrlAdapter ?? internalAdapter ?? defaultWsAdapter ?? noopAdapter;
711
965
  const shouldPoll = pollInterval > 0 && !externalScreenData;
712
966
  const { data: polledScreenData, error: screenError } = useTerminalScreen(adapter, pollInterval, shouldPoll);
713
967
  const { sendText: _sendText, sendKey: _sendKey } = useTerminalInput(adapter);
@@ -732,11 +986,11 @@ function GreenScreenTerminal({
732
986
  }, [screenData, onScreenChange]);
733
987
  const sendText = useCallback3(async (text) => _sendText(text), [_sendText]);
734
988
  const sendKey = useCallback3(async (key) => _sendKey(key), [_sendKey]);
735
- const [inputText, setInputText] = useState4("");
736
- const [isFocused, setIsFocused] = useState4(false);
989
+ const [inputText, setInputText] = useState5("");
990
+ const [isFocused, setIsFocused] = useState5(false);
737
991
  const terminalRef = useRef4(null);
738
992
  const inputRef = useRef4(null);
739
- const [syncedCursor, setSyncedCursor] = useState4(null);
993
+ const [syncedCursor, setSyncedCursor] = useState5(null);
740
994
  const prevRawContentRef = useRef4("");
741
995
  useEffect4(() => {
742
996
  const newContent = rawScreenData?.content || "";
@@ -746,8 +1000,8 @@ function GreenScreenTerminal({
746
1000
  }
747
1001
  prevRawContentRef.current = newContent;
748
1002
  }, [rawScreenData?.content]);
749
- const [autoReconnectAttempt, setAutoReconnectAttempt] = useState4(0);
750
- const [isAutoReconnecting, setIsAutoReconnecting] = useState4(false);
1003
+ const [autoReconnectAttempt, setAutoReconnectAttempt] = useState5(0);
1004
+ const [isAutoReconnecting, setIsAutoReconnecting] = useState5(false);
751
1005
  const reconnectTimeoutRef = useRef4(null);
752
1006
  const wasConnectedRef = useRef4(false);
753
1007
  const isConnectedRef = useRef4(false);
@@ -792,10 +1046,17 @@ function GreenScreenTerminal({
792
1046
  }, [connStatus?.connected, autoReconnectAttempt, isAutoReconnecting, reconnecting, reconnect, autoReconnectEnabled, maxAttempts, onNotification]);
793
1047
  const handleSignIn = useCallback3(async (config) => {
794
1048
  onSignIn?.(config);
1049
+ if (!externalAdapter && !baseUrlAdapter) {
1050
+ const port = config.port ? `:${config.port}` : "";
1051
+ const newAdapter = new RestAdapter({ baseUrl: `http://${config.host}${port}` });
1052
+ setInternalAdapter(newAdapter);
1053
+ await newAdapter.connect(config);
1054
+ return;
1055
+ }
795
1056
  await connect(config);
796
- }, [connect, onSignIn]);
797
- const [showBootLoader, setShowBootLoader] = useState4(bootLoader !== false);
798
- const [bootFadingOut, setBootFadingOut] = useState4(false);
1057
+ }, [connect, onSignIn, externalAdapter, baseUrlAdapter]);
1058
+ const [showBootLoader, setShowBootLoader] = useState5(bootLoader !== false);
1059
+ const [bootFadingOut, setBootFadingOut] = useState5(false);
799
1060
  useEffect4(() => {
800
1061
  if (screenData?.content && showBootLoader) {
801
1062
  setBootFadingOut(true);
@@ -940,21 +1201,21 @@ function GreenScreenTerminal({
940
1201
  let match;
941
1202
  let segmentIndex = 0;
942
1203
  while ((match = underscoreRegex.exec(text)) !== null) {
943
- if (match.index > lastIndex) segments.push(/* @__PURE__ */ jsx2("span", { children: text.substring(lastIndex, match.index) }, `${keyPrefix}-t-${segmentIndex}`));
1204
+ if (match.index > lastIndex) segments.push(/* @__PURE__ */ jsx4("span", { children: text.substring(lastIndex, match.index) }, `${keyPrefix}-t-${segmentIndex}`));
944
1205
  const count = match[0].length;
945
- segments.push(/* @__PURE__ */ jsx2("span", { style: { borderBottom: "1px solid var(--gs-green, #10b981)", display: "inline-block", width: `${count}ch` }, children: " ".repeat(count) }, `${keyPrefix}-u-${segmentIndex}`));
1206
+ segments.push(/* @__PURE__ */ jsx4("span", { style: { borderBottom: "1px solid var(--gs-green, #10b981)", display: "inline-block", width: `${count}ch` }, children: " ".repeat(count) }, `${keyPrefix}-u-${segmentIndex}`));
946
1207
  lastIndex = match.index + match[0].length;
947
1208
  segmentIndex++;
948
1209
  }
949
- if (lastIndex < text.length) segments.push(/* @__PURE__ */ jsx2("span", { children: text.substring(lastIndex) }, `${keyPrefix}-e`));
950
- return segments.length > 0 ? /* @__PURE__ */ jsx2(Fragment, { children: segments }) : /* @__PURE__ */ jsx2(Fragment, { children: text });
1210
+ if (lastIndex < text.length) segments.push(/* @__PURE__ */ jsx4("span", { children: text.substring(lastIndex) }, `${keyPrefix}-e`));
1211
+ return segments.length > 0 ? /* @__PURE__ */ jsx4(Fragment, { children: segments }) : /* @__PURE__ */ jsx4(Fragment, { children: text });
951
1212
  }, []);
952
1213
  const renderRowWithFields = useCallback3((line, rowIndex, fields) => {
953
1214
  const inputFields = fields.filter((f) => f.row === rowIndex && f.is_input);
954
1215
  const highlightedFields = fields.filter((f) => f.row === rowIndex && f.is_protected && f.is_highlighted);
955
1216
  const reverseFields = fields.filter((f) => f.row === rowIndex && f.is_protected && f.is_reverse);
956
1217
  const allRowFields = [...inputFields, ...highlightedFields, ...reverseFields];
957
- if (allRowFields.length === 0) return /* @__PURE__ */ jsx2("span", { children: renderTextWithUnderlines(line, `r${rowIndex}`) });
1218
+ if (allRowFields.length === 0) return /* @__PURE__ */ jsx4("span", { children: renderTextWithUnderlines(line, `r${rowIndex}`) });
958
1219
  const sorted = [...allRowFields].sort((a, b) => a.col - b.col);
959
1220
  const segs = [];
960
1221
  let lastEnd = 0;
@@ -962,35 +1223,35 @@ function GreenScreenTerminal({
962
1223
  sorted.forEach((field, idx) => {
963
1224
  const fs = field.col;
964
1225
  const fe = Math.min(field.col + field.length, cols);
965
- if (fs > lastEnd) segs.push(/* @__PURE__ */ jsx2("span", { children: renderTextWithUnderlines(line.substring(lastEnd, fs), `r${rowIndex}p${idx}`) }, `t${idx}`));
1226
+ if (fs > lastEnd) segs.push(/* @__PURE__ */ jsx4("span", { children: renderTextWithUnderlines(line.substring(lastEnd, fs), `r${rowIndex}p${idx}`) }, `t${idx}`));
966
1227
  const fc = line.substring(fs, fe);
967
1228
  if (field.is_input) {
968
1229
  const w = field.length >= 30 ? Math.max(field.length, 40) : field.length;
969
- segs.push(/* @__PURE__ */ jsx2("span", { className: "gs-input-field", style: { borderBottom: "2px solid var(--gs-green, #10b981)", display: "inline-block", minWidth: `${w}ch` }, children: fc }, `f${idx}`));
1230
+ segs.push(/* @__PURE__ */ jsx4("span", { className: "gs-input-field", style: { borderBottom: "2px solid var(--gs-green, #10b981)", display: "inline-block", minWidth: `${w}ch` }, children: fc }, `f${idx}`));
970
1231
  } else if (field.is_reverse) {
971
- segs.push(/* @__PURE__ */ jsx2("span", { style: { color: "#ef4444", fontWeight: "bold" }, children: fc }, `v${idx}`));
1232
+ segs.push(/* @__PURE__ */ jsx4("span", { style: { color: "#ef4444", fontWeight: "bold" }, children: fc }, `v${idx}`));
972
1233
  } else {
973
- segs.push(/* @__PURE__ */ jsx2("span", { style: { color: "var(--gs-white, #FFFFFF)" }, children: fc }, `h${idx}`));
1234
+ segs.push(/* @__PURE__ */ jsx4("span", { style: { color: "var(--gs-white, #FFFFFF)" }, children: fc }, `h${idx}`));
974
1235
  }
975
1236
  lastEnd = fe;
976
1237
  });
977
- if (lastEnd < line.length) segs.push(/* @__PURE__ */ jsx2("span", { children: renderTextWithUnderlines(line.substring(lastEnd), `r${rowIndex}e`) }, "te"));
978
- return /* @__PURE__ */ jsx2(Fragment, { children: segs });
1238
+ if (lastEnd < line.length) segs.push(/* @__PURE__ */ jsx4("span", { children: renderTextWithUnderlines(line.substring(lastEnd), `r${rowIndex}e`) }, "te"));
1239
+ return /* @__PURE__ */ jsx4(Fragment, { children: segs });
979
1240
  }, [renderTextWithUnderlines, screenData?.cols, profile.defaultCols]);
980
1241
  const renderScreen = () => {
981
1242
  if (showBootLoader && !screenData?.content) {
982
1243
  if (bootLoader === false) return null;
983
- if (bootLoader) return /* @__PURE__ */ jsx2(Fragment, { children: bootLoader });
984
- return /* @__PURE__ */ jsx2(TerminalBootLoader, { brandText: profile.bootText });
1244
+ if (bootLoader) return /* @__PURE__ */ jsx4(Fragment, { children: bootLoader });
1245
+ return /* @__PURE__ */ jsx4(TerminalBootLoader, { brandText: profile.bootText });
985
1246
  }
986
- if (bootFadingOut && screenData?.content) return /* @__PURE__ */ jsx2("div", { className: "gs-fade-in", children: renderScreenContent() });
1247
+ if (bootFadingOut && screenData?.content) return /* @__PURE__ */ jsx4("div", { className: "gs-fade-in", children: renderScreenContent() });
987
1248
  if (!screenData?.content) {
988
1249
  if (inlineSignIn && !connStatus?.connected) {
989
- return /* @__PURE__ */ jsx2("div", { style: { width: `${screenData?.cols || profile.defaultCols}ch`, height: `${(screenData?.rows || profile.defaultRows) * 21}px`, display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx2(InlineSignIn, { defaultProtocol: signInDefaultProtocol || protocol || "tn5250", loading: reconnecting, error: connectError, onConnect: handleSignIn }) });
1250
+ return /* @__PURE__ */ jsx4("div", { style: { width: `${screenData?.cols || profile.defaultCols}ch`, height: `${(screenData?.rows || profile.defaultRows) * 21}px`, display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx4(InlineSignIn, { defaultProtocol: signInDefaultProtocol || protocol || "tn5250", loading: reconnecting, error: connectError, onConnect: handleSignIn }) });
990
1251
  }
991
- return /* @__PURE__ */ jsx2("div", { style: { width: `${screenData?.cols || profile.defaultCols}ch`, height: `${(screenData?.rows || profile.defaultRows) * 21}px`, display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsxs2("div", { style: { textAlign: "center" }, children: [
992
- /* @__PURE__ */ jsx2("div", { style: { color: "#808080", marginBottom: "12px" }, children: /* @__PURE__ */ jsx2(TerminalIcon, { size: 40 }) }),
993
- /* @__PURE__ */ jsx2("p", { style: { fontFamily: "var(--gs-font)", fontSize: "12px", color: "#808080" }, children: connStatus?.connected ? "Waiting for screen data..." : "Not connected" })
1252
+ return /* @__PURE__ */ jsx4("div", { style: { width: `${screenData?.cols || profile.defaultCols}ch`, height: `${(screenData?.rows || profile.defaultRows) * 21}px`, display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsxs4("div", { style: { textAlign: "center" }, children: [
1253
+ /* @__PURE__ */ jsx4("div", { style: { color: "#808080", marginBottom: "12px" }, children: /* @__PURE__ */ jsx4(TerminalIcon, { size: 40 }) }),
1254
+ /* @__PURE__ */ jsx4("p", { style: { fontFamily: "var(--gs-font)", fontSize: "12px", color: "#808080" }, children: connStatus?.connected ? "Waiting for screen data..." : "Not connected" })
994
1255
  ] }) });
995
1256
  }
996
1257
  return renderScreenContent();
@@ -1007,7 +1268,7 @@ function GreenScreenTerminal({
1007
1268
  const cursor = getCursorPos();
1008
1269
  const hasInputFields = fields.some((f) => f.is_input);
1009
1270
  const hasCursor = screenData.cursor_row !== void 0 && screenData.cursor_col !== void 0 && (hasInputFields || screenData.cursor_row !== 0 || screenData.cursor_col !== 0);
1010
- return /* @__PURE__ */ jsxs2("div", { style: { fontFamily: "var(--gs-font)", fontSize: "13px", position: "relative", width: `${cols}ch` }, children: [
1271
+ return /* @__PURE__ */ jsxs4("div", { style: { fontFamily: "var(--gs-font)", fontSize: "13px", position: "relative", width: `${cols}ch` }, children: [
1011
1272
  rows.map((line, index) => {
1012
1273
  let displayLine = line;
1013
1274
  if (hasCursor && index === cursor.row && inputText && !animatedCursorPos) {
@@ -1015,12 +1276,12 @@ function GreenScreenTerminal({
1015
1276
  displayLine = (line.substring(0, baseCol) + inputText + line.substring(baseCol + inputText.length)).substring(0, cols).padEnd(cols, " ");
1016
1277
  }
1017
1278
  const headerSegments = index === 0 ? profile.colors.parseHeaderRow(displayLine) : null;
1018
- return /* @__PURE__ */ jsxs2("div", { className: headerSegments ? "" : profile.colors.getRowColorClass(index, displayLine, termRows), style: { height: `${ROW_HEIGHT}px`, lineHeight: `${ROW_HEIGHT}px`, whiteSpace: "pre", position: "relative" }, children: [
1019
- headerSegments ? headerSegments.map((seg, i) => /* @__PURE__ */ jsx2("span", { className: seg.colorClass, children: seg.text }, i)) : renderRowWithFields(displayLine, index, fields),
1020
- hasCursor && index === cursor.row && /* @__PURE__ */ jsx2("span", { className: "gs-cursor", style: { position: "absolute", left: `${cursor.col}ch`, width: "1ch", height: `${ROW_HEIGHT}px`, top: 0, pointerEvents: "none" } })
1279
+ return /* @__PURE__ */ jsxs4("div", { className: headerSegments ? "" : profile.colors.getRowColorClass(index, displayLine, termRows), style: { height: `${ROW_HEIGHT}px`, lineHeight: `${ROW_HEIGHT}px`, whiteSpace: "pre", position: "relative" }, children: [
1280
+ headerSegments ? headerSegments.map((seg, i) => /* @__PURE__ */ jsx4("span", { className: seg.colorClass, children: seg.text }, i)) : renderRowWithFields(displayLine, index, fields),
1281
+ hasCursor && index === cursor.row && /* @__PURE__ */ jsx4("span", { className: "gs-cursor", style: { position: "absolute", left: `${cursor.col}ch`, width: "1ch", height: `${ROW_HEIGHT}px`, top: 0, pointerEvents: "none" } })
1021
1282
  ] }, index);
1022
1283
  }),
1023
- screenData.cursor_row !== void 0 && screenData.cursor_col !== void 0 && /* @__PURE__ */ jsxs2("span", { style: { position: "absolute", bottom: 0, right: 0, fontFamily: "var(--gs-font)", fontSize: "10px", color: "var(--gs-green, #10b981)", pointerEvents: "none", opacity: 0.6 }, children: [
1284
+ screenData.cursor_row !== void 0 && screenData.cursor_col !== void 0 && /* @__PURE__ */ jsxs4("span", { style: { position: "absolute", bottom: 0, right: 0, fontFamily: "var(--gs-font)", fontSize: "10px", color: "var(--gs-green, #10b981)", pointerEvents: "none", opacity: 0.6 }, children: [
1024
1285
  String(screenData.cursor_row + 1).padStart(2, "0"),
1025
1286
  "/",
1026
1287
  String(screenData.cursor_col + 1).padStart(3, "0")
@@ -1050,49 +1311,49 @@ function GreenScreenTerminal({
1050
1311
  return "#64748b";
1051
1312
  }
1052
1313
  };
1053
- return /* @__PURE__ */ jsxs2("div", { className: `gs-terminal ${isFocused ? "gs-terminal-focused" : ""} ${className || ""}`, style, children: [
1054
- showHeader && /* @__PURE__ */ jsx2("div", { className: "gs-header", children: embedded ? /* @__PURE__ */ jsxs2(Fragment, { children: [
1055
- /* @__PURE__ */ jsxs2("span", { className: "gs-header-left", children: [
1056
- /* @__PURE__ */ jsx2(TerminalIcon, { size: 14 }),
1057
- /* @__PURE__ */ jsx2("span", { children: "TERMINAL" }),
1058
- isFocused && /* @__PURE__ */ jsx2("span", { className: "gs-badge-focused", children: "FOCUSED" }),
1059
- screenData?.timestamp && /* @__PURE__ */ jsx2("span", { className: "gs-timestamp", children: new Date(screenData.timestamp).toLocaleTimeString() }),
1060
- /* @__PURE__ */ jsx2("span", { className: "gs-hint", children: readOnly ? "Read-only" : isFocused ? "ESC to exit focus" : "Click to control" })
1314
+ return /* @__PURE__ */ jsxs4("div", { className: `gs-terminal ${isFocused ? "gs-terminal-focused" : ""} ${className || ""}`, style, children: [
1315
+ showHeader && /* @__PURE__ */ jsx4("div", { className: "gs-header", children: embedded ? /* @__PURE__ */ jsxs4(Fragment, { children: [
1316
+ /* @__PURE__ */ jsxs4("span", { className: "gs-header-left", children: [
1317
+ /* @__PURE__ */ jsx4(TerminalIcon, { size: 14 }),
1318
+ /* @__PURE__ */ jsx4("span", { children: "TERMINAL" }),
1319
+ isFocused && /* @__PURE__ */ jsx4("span", { className: "gs-badge-focused", children: "FOCUSED" }),
1320
+ screenData?.timestamp && /* @__PURE__ */ jsx4("span", { className: "gs-timestamp", children: new Date(screenData.timestamp).toLocaleTimeString() }),
1321
+ /* @__PURE__ */ jsx4("span", { className: "gs-hint", children: readOnly ? "Read-only" : isFocused ? "ESC to exit focus" : "Click to control" })
1061
1322
  ] }),
1062
- /* @__PURE__ */ jsxs2("div", { className: "gs-header-right", children: [
1063
- connStatus?.status && /* @__PURE__ */ jsx2(KeyIcon, { size: 12, style: { color: getStatusColor(connStatus.status) } }),
1064
- connStatus && (connStatus.connected ? /* @__PURE__ */ jsx2(WifiIcon, { size: 12, style: { color: "var(--gs-green, #10b981)" } }) : /* @__PURE__ */ jsx2(WifiOffIcon, { size: 12, style: { color: "#FF6B00" } })),
1065
- onMinimize && /* @__PURE__ */ jsx2("button", { onClick: (e) => {
1323
+ /* @__PURE__ */ jsxs4("div", { className: "gs-header-right", children: [
1324
+ connStatus?.status && /* @__PURE__ */ jsx4(KeyIcon, { size: 12, style: { color: getStatusColor(connStatus.status) } }),
1325
+ connStatus && (connStatus.connected ? /* @__PURE__ */ jsx4(WifiIcon, { size: 12, style: { color: "var(--gs-green, #10b981)" } }) : /* @__PURE__ */ jsx4(WifiOffIcon, { size: 12, style: { color: "#FF6B00" } })),
1326
+ onMinimize && /* @__PURE__ */ jsx4("button", { onClick: (e) => {
1066
1327
  e.stopPropagation();
1067
1328
  onMinimize();
1068
- }, className: "gs-btn-icon", title: "Minimize terminal", children: /* @__PURE__ */ jsx2(MinimizeIcon, {}) }),
1329
+ }, className: "gs-btn-icon", title: "Minimize terminal", children: /* @__PURE__ */ jsx4(MinimizeIcon, {}) }),
1069
1330
  headerRight
1070
1331
  ] })
1071
- ] }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
1072
- /* @__PURE__ */ jsxs2("span", { className: "gs-header-left", children: [
1073
- /* @__PURE__ */ jsx2(TerminalIcon, { size: 14 }),
1074
- /* @__PURE__ */ jsx2("span", { children: profile.headerLabel }),
1075
- isFocused && /* @__PURE__ */ jsx2("span", { className: "gs-badge-focused", children: "FOCUSED" }),
1076
- screenData?.timestamp && /* @__PURE__ */ jsx2("span", { className: "gs-timestamp", children: new Date(screenData.timestamp).toLocaleTimeString() }),
1077
- /* @__PURE__ */ jsx2("span", { className: "gs-hint", children: readOnly ? "Read-only mode" : isFocused ? "ESC to exit focus" : "Click terminal to control" })
1332
+ ] }) : /* @__PURE__ */ jsxs4(Fragment, { children: [
1333
+ /* @__PURE__ */ jsxs4("span", { className: "gs-header-left", children: [
1334
+ /* @__PURE__ */ jsx4(TerminalIcon, { size: 14 }),
1335
+ /* @__PURE__ */ jsx4("span", { children: profile.headerLabel }),
1336
+ isFocused && /* @__PURE__ */ jsx4("span", { className: "gs-badge-focused", children: "FOCUSED" }),
1337
+ screenData?.timestamp && /* @__PURE__ */ jsx4("span", { className: "gs-timestamp", children: new Date(screenData.timestamp).toLocaleTimeString() }),
1338
+ /* @__PURE__ */ jsx4("span", { className: "gs-hint", children: readOnly ? "Read-only mode" : isFocused ? "ESC to exit focus" : "Click terminal to control" })
1078
1339
  ] }),
1079
- /* @__PURE__ */ jsxs2("div", { className: "gs-header-right", children: [
1080
- connStatus && /* @__PURE__ */ jsx2("div", { className: "gs-status-group", children: connStatus.connected ? /* @__PURE__ */ jsxs2(Fragment, { children: [
1081
- /* @__PURE__ */ jsx2(WifiIcon, { size: 12, style: { color: "var(--gs-green, #10b981)" } }),
1082
- /* @__PURE__ */ jsx2("span", { className: "gs-host", children: connStatus.host })
1083
- ] }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
1084
- /* @__PURE__ */ jsx2(WifiOffIcon, { size: 12, style: { color: "#FF6B00" } }),
1085
- /* @__PURE__ */ jsx2("span", { className: "gs-disconnected-text", children: isAutoReconnecting || reconnecting ? `RECONNECTING${autoReconnectAttempt > 0 ? ` (${autoReconnectAttempt}/${maxAttempts})` : "..."}` : autoReconnectAttempt >= maxAttempts ? "DISCONNECTED (auto-retry exhausted)" : "DISCONNECTED" }),
1086
- /* @__PURE__ */ jsx2("button", { onClick: handleReconnect, disabled: reconnecting || isAutoReconnecting, className: "gs-btn-icon", title: "Reconnect", children: /* @__PURE__ */ jsx2(RefreshIcon, { size: 12, className: reconnecting || isAutoReconnecting ? "gs-spin" : "" }) })
1340
+ /* @__PURE__ */ jsxs4("div", { className: "gs-header-right", children: [
1341
+ connStatus && /* @__PURE__ */ jsx4("div", { className: "gs-status-group", children: connStatus.connected ? /* @__PURE__ */ jsxs4(Fragment, { children: [
1342
+ /* @__PURE__ */ jsx4(WifiIcon, { size: 12, style: { color: "var(--gs-green, #10b981)" } }),
1343
+ /* @__PURE__ */ jsx4("span", { className: "gs-host", children: connStatus.host })
1344
+ ] }) : /* @__PURE__ */ jsxs4(Fragment, { children: [
1345
+ /* @__PURE__ */ jsx4(WifiOffIcon, { size: 12, style: { color: "#FF6B00" } }),
1346
+ /* @__PURE__ */ jsx4("span", { className: "gs-disconnected-text", children: isAutoReconnecting || reconnecting ? `RECONNECTING${autoReconnectAttempt > 0 ? ` (${autoReconnectAttempt}/${maxAttempts})` : "..."}` : autoReconnectAttempt >= maxAttempts ? "DISCONNECTED (auto-retry exhausted)" : "DISCONNECTED" }),
1347
+ /* @__PURE__ */ jsx4("button", { onClick: handleReconnect, disabled: reconnecting || isAutoReconnecting, className: "gs-btn-icon", title: "Reconnect", children: /* @__PURE__ */ jsx4(RefreshIcon, { size: 12, className: reconnecting || isAutoReconnecting ? "gs-spin" : "" }) })
1087
1348
  ] }) }),
1088
- connStatus?.status && /* @__PURE__ */ jsxs2("div", { className: "gs-status-group", children: [
1089
- /* @__PURE__ */ jsx2(KeyIcon, { size: 12, style: { color: getStatusColor(connStatus.status) } }),
1090
- connStatus.username && /* @__PURE__ */ jsx2("span", { className: "gs-host", children: connStatus.username })
1349
+ connStatus?.status && /* @__PURE__ */ jsxs4("div", { className: "gs-status-group", children: [
1350
+ /* @__PURE__ */ jsx4(KeyIcon, { size: 12, style: { color: getStatusColor(connStatus.status) } }),
1351
+ connStatus.username && /* @__PURE__ */ jsx4("span", { className: "gs-host", children: connStatus.username })
1091
1352
  ] }),
1092
1353
  headerRight
1093
1354
  ] })
1094
1355
  ] }) }),
1095
- /* @__PURE__ */ jsx2("div", { className: "gs-body", children: /* @__PURE__ */ jsxs2(
1356
+ /* @__PURE__ */ jsx4("div", { className: "gs-body", children: /* @__PURE__ */ jsxs4(
1096
1357
  "div",
1097
1358
  {
1098
1359
  ref: terminalRef,
@@ -1100,17 +1361,17 @@ function GreenScreenTerminal({
1100
1361
  className: `gs-screen ${embedded ? "gs-screen-embedded" : ""}`,
1101
1362
  style: !embedded ? { width: `calc(${screenData?.cols || profile.defaultCols}ch + 24px)`, fontSize: (screenData?.cols ?? profile.defaultCols) > 80 ? "11px" : "13px", fontFamily: "var(--gs-font)" } : void 0,
1102
1363
  children: [
1103
- screenError != null && /* @__PURE__ */ jsxs2("div", { className: "gs-error-banner", children: [
1104
- /* @__PURE__ */ jsx2(AlertTriangleIcon, { size: 14 }),
1105
- /* @__PURE__ */ jsx2("span", { children: String(screenError) })
1364
+ screenError != null && /* @__PURE__ */ jsxs4("div", { className: "gs-error-banner", children: [
1365
+ /* @__PURE__ */ jsx4(AlertTriangleIcon, { size: 14 }),
1366
+ /* @__PURE__ */ jsx4("span", { children: String(screenError) })
1106
1367
  ] }),
1107
- /* @__PURE__ */ jsx2("div", { className: "gs-screen-content", children: renderScreen() }),
1368
+ /* @__PURE__ */ jsx4("div", { className: "gs-screen-content", children: renderScreen() }),
1108
1369
  overlay,
1109
- connStatus && !connStatus.connected && screenData && /* @__PURE__ */ jsxs2("div", { className: "gs-overlay", children: [
1110
- /* @__PURE__ */ jsx2(WifiOffIcon, { size: 28 }),
1111
- /* @__PURE__ */ jsx2("span", { children: isAutoReconnecting || reconnecting ? "Reconnecting..." : "Disconnected" })
1370
+ connStatus && !connStatus.connected && screenData && /* @__PURE__ */ jsxs4("div", { className: "gs-overlay", children: [
1371
+ /* @__PURE__ */ jsx4(WifiOffIcon, { size: 28 }),
1372
+ /* @__PURE__ */ jsx4("span", { children: isAutoReconnecting || reconnecting ? "Reconnecting..." : "Disconnected" })
1112
1373
  ] }),
1113
- /* @__PURE__ */ jsx2(
1374
+ /* @__PURE__ */ jsx4(
1114
1375
  "input",
1115
1376
  {
1116
1377
  ref: inputRef,
@@ -1130,66 +1391,6 @@ function GreenScreenTerminal({
1130
1391
  ) })
1131
1392
  ] });
1132
1393
  }
1133
- var TN5250Terminal = GreenScreenTerminal;
1134
-
1135
- // src/adapters/RestAdapter.ts
1136
- var RestAdapter = class {
1137
- constructor(options) {
1138
- this.baseUrl = options.baseUrl.replace(/\/+$/, "");
1139
- this.staticHeaders = options.headers || {};
1140
- this.getHeaders = options.getHeaders;
1141
- }
1142
- async buildHeaders() {
1143
- const dynamic = this.getHeaders ? await this.getHeaders() : {};
1144
- return {
1145
- "Content-Type": "application/json",
1146
- ...this.staticHeaders,
1147
- ...dynamic
1148
- };
1149
- }
1150
- async request(method, path, body) {
1151
- const headers = await this.buildHeaders();
1152
- const response = await fetch(`${this.baseUrl}${path}`, {
1153
- method,
1154
- headers,
1155
- body: body ? JSON.stringify(body) : void 0
1156
- });
1157
- if (!response.ok) {
1158
- const detail = await response.json().catch(() => ({}));
1159
- throw new Error(detail?.detail || `HTTP ${response.status}`);
1160
- }
1161
- return response.json();
1162
- }
1163
- async getScreen() {
1164
- try {
1165
- return await this.request("GET", "/screen");
1166
- } catch (e) {
1167
- const message = e instanceof Error ? e.message : String(e);
1168
- if (message.includes("503") || message.includes("404")) {
1169
- return null;
1170
- }
1171
- throw e;
1172
- }
1173
- }
1174
- async getStatus() {
1175
- return this.request("GET", "/status");
1176
- }
1177
- async sendText(text) {
1178
- return this.request("POST", "/send-text", { text });
1179
- }
1180
- async sendKey(key) {
1181
- return this.request("POST", "/send-key", { key });
1182
- }
1183
- async connect(config) {
1184
- return this.request("POST", "/connect", config);
1185
- }
1186
- async disconnect() {
1187
- return this.request("POST", "/disconnect");
1188
- }
1189
- async reconnect() {
1190
- return this.request("POST", "/reconnect");
1191
- }
1192
- };
1193
1394
 
1194
1395
  // src/utils/rendering.ts
1195
1396
  function getRowColorClass(rowIndex, rowContent) {
@@ -1199,10 +1400,18 @@ function parseHeaderRow(line) {
1199
1400
  return getProtocolProfile("tn5250").colors.parseHeaderRow(line);
1200
1401
  }
1201
1402
  export {
1403
+ AlertTriangleIcon,
1202
1404
  GreenScreenTerminal,
1405
+ InlineSignIn,
1406
+ KeyIcon,
1407
+ MinimizeIcon,
1408
+ RefreshIcon,
1203
1409
  RestAdapter,
1204
- TN5250Terminal,
1205
1410
  TerminalBootLoader,
1411
+ TerminalIcon,
1412
+ WebSocketAdapter,
1413
+ WifiIcon,
1414
+ WifiOffIcon,
1206
1415
  getProtocolProfile,
1207
1416
  getRowColorClass,
1208
1417
  hp6530Profile,
@@ -1211,9 +1420,6 @@ export {
1211
1420
  positionToRowCol,
1212
1421
  tn3270Profile,
1213
1422
  tn5250Profile,
1214
- useTN5250Connection,
1215
- useTN5250Screen,
1216
- useTN5250Terminal,
1217
1423
  useTerminalConnection,
1218
1424
  useTerminalInput,
1219
1425
  useTerminalScreen,