Nano zoom fix #11
This commit is contained in:
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
12
.idea/SSH-Project-JB.iml
generated
Normal file
12
.idea/SSH-Project-JB.iml
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/SSH-Project-JB.iml" filepath="$PROJECT_DIR$/.idea/SSH-Project-JB.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start-vite": "cross-env BROWSER=none WDS_SOCKET_PORT=0 vite --port 8080",
|
"start-vite": "cross-env BROWSER=none WDS_SOCKET_PORT=0 vite --port 8080",
|
||||||
"start-server": "node 'D:/Programming Projects/SSH-Project/ssh-project/backend/server.js'",
|
"start-server": "node ./start.js",
|
||||||
"start": "npm run start-vite && npm run start-server",
|
"start": "npm run start-vite && npm run start-server",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
.hide-sidebar-button {
|
.hide-sidebar-button {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
right: 10px;
|
right: 25px;
|
||||||
background-color: rgb(108, 108, 108);
|
background-color: rgb(108, 108, 108);
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
|
|||||||
@@ -16,85 +16,92 @@ const App = () => {
|
|||||||
const [isSideBarHidden, setIsSideBarHidden] = useState(false);
|
const [isSideBarHidden, setIsSideBarHidden] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Initialize the terminal and the fit addon
|
console.log('Initializing terminal...');
|
||||||
terminal.current = new Terminal({
|
terminal.current = new Terminal({
|
||||||
cursorBlink: true,
|
cursorBlink: true,
|
||||||
theme: {
|
theme: { background: '#1e1e1e', foreground: '#ffffff' },
|
||||||
background: '#1e1e1e',
|
|
||||||
foreground: '#ffffff',
|
|
||||||
},
|
|
||||||
macOptionIsMeta: true,
|
macOptionIsMeta: true,
|
||||||
allowProposedApi: true,
|
allowProposedApi: true,
|
||||||
scrollback: 1000, // Allow scrollback so the terminal doesn't lose state
|
fontSize: 14,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initialize and attach the fit addon to the terminal
|
|
||||||
fitAddon.current = new FitAddon();
|
fitAddon.current = new FitAddon();
|
||||||
terminal.current.loadAddon(fitAddon.current);
|
terminal.current.loadAddon(fitAddon.current);
|
||||||
|
|
||||||
terminal.current.open(terminalRef.current);
|
if (terminalRef.current) {
|
||||||
|
terminal.current.open(terminalRef.current);
|
||||||
|
console.log('Terminal opened successfully.');
|
||||||
|
} else {
|
||||||
|
console.error('Terminal reference is not valid!');
|
||||||
|
}
|
||||||
|
|
||||||
// Resize terminal to fit the container initially
|
|
||||||
fitAddon.current.fit();
|
|
||||||
|
|
||||||
// Adjust terminal size on window resize
|
|
||||||
const resizeListener = () => {
|
|
||||||
fitAddon.current.fit();
|
|
||||||
};
|
|
||||||
window.addEventListener('resize', resizeListener);
|
|
||||||
|
|
||||||
// Monitor terminal data (activity)
|
|
||||||
terminal.current.onData((data) => {
|
terminal.current.onData((data) => {
|
||||||
if (socket.current && socket.current.readyState === WebSocket.OPEN) {
|
if (socket.current && socket.current.readyState === WebSocket.OPEN) {
|
||||||
socket.current.send(data);
|
socket.current.send(data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add specific resize call for certain programs like nano or vim
|
const resizeTerminal = () => {
|
||||||
const resizeTerminalOnStart = () => {
|
if (terminalRef.current) {
|
||||||
// Resize immediately after starting vim/nano or other programs
|
fitAddon.current.fit();
|
||||||
fitAddon.current.fit();
|
notifyServerOfResize();
|
||||||
terminal.current.clear();
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
terminal.current.onData((data) => {
|
const notifyServerOfResize = () => {
|
||||||
if (data.includes('nano') || data.includes('vim')) {
|
if (socket.current && socket.current.readyState === WebSocket.OPEN) {
|
||||||
// Trigger resize immediately when these programs start
|
const { rows, cols } = terminal.current;
|
||||||
resizeTerminalOnStart();
|
socket.current.send(
|
||||||
|
JSON.stringify({
|
||||||
|
type: 'resize',
|
||||||
|
rows,
|
||||||
|
cols,
|
||||||
|
height: terminalRef.current.offsetHeight,
|
||||||
|
width: terminalRef.current.offsetWidth,
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
resizeTerminal();
|
||||||
|
window.addEventListener('resize', resizeTerminal);
|
||||||
|
|
||||||
// Cleanup on component unmount
|
|
||||||
return () => {
|
return () => {
|
||||||
terminal.current.dispose();
|
terminal.current.dispose();
|
||||||
if (socket.current) {
|
if (socket.current) {
|
||||||
socket.current.close();
|
socket.current.close();
|
||||||
}
|
}
|
||||||
window.removeEventListener('resize', resizeListener);
|
window.removeEventListener('resize', resizeTerminal);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleConnect = () => {
|
const handleConnect = () => {
|
||||||
|
console.log('Connecting...');
|
||||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
const wsUrl = `${protocol}//${window.location.host}/ws/`; // Use current host and "/ws/" endpoint
|
const wsUrl = `${protocol}//${window.location.host}/ws/`;
|
||||||
|
console.log(`WebSocket URL: ${wsUrl}`);
|
||||||
|
|
||||||
socket.current = new WebSocket(wsUrl);
|
socket.current = new WebSocket(wsUrl);
|
||||||
|
|
||||||
socket.current.onopen = () => {
|
socket.current.onopen = () => {
|
||||||
|
console.log('WebSocket connection opened');
|
||||||
terminal.current.writeln(`Connected to WebSocket server at ${wsUrl}`);
|
terminal.current.writeln(`Connected to WebSocket server at ${wsUrl}`);
|
||||||
socket.current.send(JSON.stringify({ host, username, password }));
|
socket.current.send(JSON.stringify({ host, username, password }));
|
||||||
setIsConnected(true);
|
setIsConnected(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.current.onmessage = (event) => {
|
socket.current.onmessage = (event) => {
|
||||||
|
console.log('Received message:', event.data);
|
||||||
terminal.current.write(event.data);
|
terminal.current.write(event.data);
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.current.onerror = (error) => {
|
socket.current.onerror = (error) => {
|
||||||
|
console.error('WebSocket error:', error);
|
||||||
terminal.current.writeln(`WebSocket error: ${error.message}`);
|
terminal.current.writeln(`WebSocket error: ${error.message}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.current.onclose = () => {
|
socket.current.onclose = () => {
|
||||||
|
console.log('WebSocket connection closed');
|
||||||
terminal.current.writeln('Disconnected from WebSocket server.');
|
terminal.current.writeln('Disconnected from WebSocket server.');
|
||||||
setIsConnected(false);
|
setIsConnected(false);
|
||||||
};
|
};
|
||||||
@@ -106,47 +113,49 @@ const App = () => {
|
|||||||
|
|
||||||
const handleSideBarHiding = () => {
|
const handleSideBarHiding = () => {
|
||||||
setIsSideBarHidden((prevState) => !prevState);
|
setIsSideBarHidden((prevState) => !prevState);
|
||||||
|
if (!isSideBarHidden) {
|
||||||
|
setTimeout(() => {
|
||||||
|
fitAddon.current.fit();
|
||||||
|
notifyServerOfResize();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="app-container">
|
<div className="app-container">
|
||||||
<div className="main-content">
|
<div className="main-content">
|
||||||
<div className={`sidebar ${isSideBarHidden ? 'hidden' : ''}`}>
|
<div className={`sidebar ${isSideBarHidden ? 'hidden' : ''}`}>
|
||||||
<h2>Connection Details</h2>
|
<h2>Connection Details</h2>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Host"
|
placeholder="Host"
|
||||||
value={host}
|
value={host}
|
||||||
onChange={(e) => handleInputChange(e, setHost)}
|
onChange={(e) => handleInputChange(e, setHost)}
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Username"
|
placeholder="Username"
|
||||||
value={username}
|
value={username}
|
||||||
onChange={(e) => handleInputChange(e, setUsername)}
|
onChange={(e) => handleInputChange(e, setUsername)}
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="Password"
|
placeholder="Password"
|
||||||
value={password}
|
value={password}
|
||||||
onChange={(e) => handleInputChange(e, setPassword)}
|
onChange={(e) => handleInputChange(e, setPassword)}
|
||||||
/>
|
/>
|
||||||
<button onClick={handleConnect} disabled={isConnected}>
|
<button onClick={handleConnect} disabled={isConnected}>
|
||||||
{isConnected ? 'Connected' : 'Start Session'}
|
{isConnected ? 'Connected' : 'Start Session'}
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ref={terminalRef} className="terminal-container"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ref={terminalRef} className="terminal-container"></div>
|
<button className="hide-sidebar-button" onClick={handleSideBarHiding}>
|
||||||
|
{isSideBarHidden ? '+' : '-'}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Hide button always positioned in the bottom-right corner */}
|
|
||||||
<button
|
|
||||||
className="hide-sidebar-button"
|
|
||||||
onClick={handleSideBarHiding}
|
|
||||||
>
|
|
||||||
{isSideBarHidden ? '+' : '-'}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
12
frontend/start.js
Normal file
12
frontend/start.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// start.js
|
||||||
|
const { spawn } = require('child_process');
|
||||||
|
|
||||||
|
const child = spawn('node', ["\"D:/Programming Projects/SSH-Project-JB/backend/server.js\""], {
|
||||||
|
stdio: 'inherit', // this is key for interactivity
|
||||||
|
shell: true, // use system shell
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('exit', function (code, signal) {
|
||||||
|
console.log('child process exited with ' +
|
||||||
|
`code ${code} and signal ${signal}`);
|
||||||
|
});
|
||||||
128
package-lock.json
generated
128
package-lock.json
generated
@@ -1,13 +1,90 @@
|
|||||||
{
|
{
|
||||||
"name": "ssh-project",
|
"name": "SSH-Project-JB",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
"xterm-addon-fit": "^0.8.0"
|
"xterm-addon-fit": "^0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cross-env": {
|
||||||
|
"version": "7.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
||||||
|
"integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
|
||||||
|
"dependencies": {
|
||||||
|
"cross-spawn": "^7.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"cross-env": "src/bin/cross-env.js",
|
||||||
|
"cross-env-shell": "src/bin/cross-env-shell.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.14",
|
||||||
|
"npm": ">=6",
|
||||||
|
"yarn": ">=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cross-spawn": {
|
||||||
|
"version": "7.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
|
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||||
|
"dependencies": {
|
||||||
|
"path-key": "^3.1.0",
|
||||||
|
"shebang-command": "^2.0.0",
|
||||||
|
"which": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/isexe": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||||
|
},
|
||||||
|
"node_modules/path-key": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/shebang-command": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||||
|
"dependencies": {
|
||||||
|
"shebang-regex": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/shebang-regex": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/which": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||||
|
"dependencies": {
|
||||||
|
"isexe": "^2.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"node-which": "bin/node-which"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/xterm": {
|
"node_modules/xterm": {
|
||||||
"version": "5.3.0",
|
"version": "5.3.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -24,6 +101,55 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"cross-env": {
|
||||||
|
"version": "7.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
||||||
|
"integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
|
||||||
|
"requires": {
|
||||||
|
"cross-spawn": "^7.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cross-spawn": {
|
||||||
|
"version": "7.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
|
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||||
|
"requires": {
|
||||||
|
"path-key": "^3.1.0",
|
||||||
|
"shebang-command": "^2.0.0",
|
||||||
|
"which": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"isexe": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||||
|
},
|
||||||
|
"path-key": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
|
||||||
|
},
|
||||||
|
"shebang-command": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||||
|
"requires": {
|
||||||
|
"shebang-regex": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shebang-regex": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
|
||||||
|
},
|
||||||
|
"which": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||||
|
"requires": {
|
||||||
|
"isexe": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"xterm": {
|
"xterm": {
|
||||||
"version": "5.3.0",
|
"version": "5.3.0",
|
||||||
"peer": true
|
"peer": true
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
"xterm-addon-fit": "^0.8.0"
|
"xterm-addon-fit": "^0.8.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user