linny-r 1.1.0 → 1.1.2
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 +34 -33
- package/console.js +14 -16
- package/package.json +2 -3
- package/server.js +16 -16
- package/static/index.html +2 -2
package/README.md
CHANGED
@@ -39,24 +39,31 @@ The response should be the version number of Node.js, for example: v18.9.0.
|
|
39
39
|
|
40
40
|
### Installing Linny-R
|
41
41
|
It is advisable to install Linny-R in a directory on your computer, not in a cloud.
|
42
|
-
In this installation guide, this directory is
|
43
|
-
|
42
|
+
In this installation guide, the path to this directory is denoted by `WORKING_DIRECTORY`,
|
43
|
+
but on a Windows machine you may choose something like `C:\Users\xyz\Documents\Linny-R`,
|
44
|
+
and on a macOS machine probably `/Users/xyz/Linny-R`.
|
44
45
|
|
45
|
-
|
46
|
+
To install Linny-R in this directory, type at the command line prompt:
|
46
47
|
|
47
|
-
|
48
|
+
``npm install --prefix WORKING_DIRECTORY linny-r``
|
49
|
+
|
50
|
+
WORKING_DIRECTORY should now contain a new sub-directory `node_modules`,
|
48
51
|
and two JSON files `package.json` and `package-lock.json` that should **not** be removed,
|
49
52
|
or you will have to re-install Linny-R.
|
50
53
|
|
51
|
-
|
52
|
-
|
54
|
+
After installation has been completed, `WORKING_DIRECTORY` will also have a sub-directory `user`
|
55
|
+
and a script file to facilitate (single click) launch: on a macOS machine the shell script `linny-r.command`,
|
56
|
+
on a Windows machine the batch script `linny-r.bat`.
|
57
|
+
|
58
|
+
When configuring Linny-R for a network environment
|
59
|
+
where individual users each have their personal work space (e.g., a virtual drive U:),
|
60
|
+
you can instruct Linny-R to create the `user` directory in this work space
|
61
|
+
by adding the argument `workspace=[path]` to the `node` command that you use to start the Linny-R server.
|
53
62
|
|
54
|
-
The directory should contain
|
63
|
+
The `node_modules` directory should contain two sub-directories: `@xmldom` and `linny-r`.
|
64
|
+
The `linny-r` directory should contain this file `README.md`,
|
55
65
|
the files `server.js` and `console.js` that will be run by Node.js,
|
56
66
|
and the sub-directory `static`.
|
57
|
-
After installation has been completed, it will have two more subdirectories `user` and `node_modules`,
|
58
|
-
and a script file to facilitate (single click) launch: on a macOS machine the shell script `linny-r.command`,
|
59
|
-
on a Windows machine the batch script `linny-r.bat`.
|
60
67
|
|
61
68
|
The `static` directory should contain three HTML files:
|
62
69
|
|
@@ -68,20 +75,12 @@ It should also contain the style sheet `linny-r.css` required by the GUI.
|
|
68
75
|
|
69
76
|
The subdirectories of `static` contain files that are served to the browser by the script `server.js` when it is running in Node.js.
|
70
77
|
|
71
|
-
After installation has completed,
|
78
|
+
After installation has completed, `WORKING_DIRECTORY` should have this directory tree structure:
|
72
79
|
|
73
80
|
<pre>
|
74
|
-
|
81
|
+
WORKING_DIRECTORY
|
75
82
|
|
|
76
|
-
+-
|
77
|
-
| |
|
78
|
-
| + fonts
|
79
|
-
| |
|
80
|
-
| +- images
|
81
|
-
| |
|
82
|
-
| +- scripts
|
83
|
-
| |
|
84
|
-
| +- sounds
|
83
|
+
+- node_modules
|
85
84
|
|
|
86
85
|
+- user
|
87
86
|
|
|
@@ -95,7 +94,7 @@ Linny-R
|
|
95
94
|
|
|
96
95
|
+-solver
|
97
96
|
</pre>
|
98
|
-
|
97
|
+
|
99
98
|
The sub-directories of the `user` directory are used by Linny-R to store files.
|
100
99
|
|
101
100
|
* `channel` and `callback` will be used to interact with Linny-R via its *Receiver*
|
@@ -138,7 +137,7 @@ How to do this is explained on the page "Installing LP_solve on a Mac" on the Li
|
|
138
137
|
https://linny-r.info
|
139
138
|
|
140
139
|
When you have downloaded the file (just `lp_solve` for macOS, `lp_solve.exe` for Windows),
|
141
|
-
you must copy or move this file to
|
140
|
+
you must copy or move this file to your `WORKING_DIRECTORY`,
|
142
141
|
as this is where Linny-R will look for it when it does not find Gurobi.
|
143
142
|
|
144
143
|
On a macOS machine, you must then make the file `lp_solve` executable.
|
@@ -161,12 +160,13 @@ If you reach this stage, Linny-R will be able to run LP_solve.
|
|
161
160
|
### Running Linny-R
|
162
161
|
|
163
162
|
Open the Command Line Interface (CLI) of your computer.
|
164
|
-
On macOS,
|
163
|
+
On macOS, open `Terminal`, change to your `WORKING_DIRECTORY` and type:
|
165
164
|
|
166
|
-
|
167
|
-
Then type:
|
165
|
+
``node node_modules/linny-r/server``
|
168
166
|
|
169
|
-
|
167
|
+
On Windows, open `Command Prompt`, change to your `WORKING_DIRECTORY` and type:
|
168
|
+
|
169
|
+
``node node_modules\linny-r\server``
|
170
170
|
|
171
171
|
The response should be something similar to:
|
172
172
|
|
@@ -175,7 +175,8 @@ Node.js server for Linny-R version 1.0
|
|
175
175
|
Node.js version: v18.9.0
|
176
176
|
</pre>
|
177
177
|
|
178
|
-
followed by some data on your Linny-R configuration.
|
178
|
+
followed by some data on your Linny-R configuration.
|
179
|
+
The last line will be something like:
|
179
180
|
|
180
181
|
<pre>
|
181
182
|
Listening at: http://127.0.0.1:5050
|
@@ -219,11 +220,11 @@ Solve block 1 a
|
|
219
220
|
Optionally, you can add more arguments to the `node` command:
|
220
221
|
|
221
222
|
<pre>
|
223
|
+
dpi=[number] to overrule the default resolution (300 dpi) for Inkscape
|
222
224
|
launch to automatically launch Linny-R in your default browser
|
223
225
|
port=[number] to overrule the default port number (5050)
|
224
226
|
solver=[name] to overrule the default sequence (Gurobi, LP_solve)
|
225
227
|
workspace=[path] to overrule the default path for the user directory
|
226
|
-
dpi=[number] to overrule the default resolution (300 dpi) for Inkscape
|
227
228
|
</pre>
|
228
229
|
|
229
230
|
### Installing Inkscape
|
@@ -257,7 +258,7 @@ To facilitate start-up, you can create a shortcut icon on your desktop.
|
|
257
258
|
On a Windows machine, change to your Linny-R folder, right-click on the batch file `linny-r.bat`,
|
258
259
|
and select the *Create shortcut* option.
|
259
260
|
Then right-click on the shortcut file to edit its properties, and click the *Change Icon* button.
|
260
|
-
The dialog that then appears will allow you to go to the sub-folder `static\images`,
|
261
|
+
The dialog that then appears will allow you to go to the sub-folder `node_modules\linny-r\static\images`,
|
261
262
|
where you should select the file `linny-r.ico`.
|
262
263
|
Finally, rename the shortcut to `Linny-R` and move or copy it to your desktop.
|
263
264
|
|
@@ -267,7 +268,7 @@ On a macOS machine, open Terminal and change to your Linny-R directory, and then
|
|
267
268
|
|
268
269
|
to make the script file executable.
|
269
270
|
To set the icon, click on the icon of `linny-r.command` (which still is plain) and open the Info dialog by pressing ``Cmd+I``.
|
270
|
-
Then open your Linny-R folder in the Finder, change to the sub-folder `static/images`,
|
271
|
+
Then open your Linny-R folder in the Finder, change to the sub-folder `node_modules/linny-r/static/images`,
|
271
272
|
and from there drag/drop the file `linny-r.icns` on the icon shown in the top left corner of the Info dialog.
|
272
273
|
|
273
274
|
|
@@ -289,9 +290,9 @@ In that case, you can stop Node.js by stopping the Terminal.
|
|
289
290
|
|
290
291
|
The console-only version of Linny-R allows you to run a Linny-R model without a web browser.
|
291
292
|
This may be useful when you want run models from a script (shell script, Python, ...).
|
292
|
-
If you open a CLI box, change to
|
293
|
+
If you open a CLI box, change to your `WORKING_DIRECTORY`, and then type:
|
293
294
|
|
294
|
-
``node console``
|
295
|
+
``node node_modules/linny-r/console`` _(on Windows, use backslashes)_
|
295
296
|
|
296
297
|
you will see the command line options that allow you to run models in various ways.
|
297
298
|
|
package/console.js
CHANGED
@@ -41,31 +41,29 @@ SOFTWARE.
|
|
41
41
|
// (this will make the "module" files linny-r-xxx.js export their properties)
|
42
42
|
global.NODE = true;
|
43
43
|
|
44
|
-
const VERSION_NUMBER = '1.0.0';
|
45
|
-
|
46
|
-
const MAIN_DIRECTORY = process.cwd();
|
47
|
-
|
48
|
-
// Load the required Node.js modules
|
49
44
|
const
|
45
|
+
VERSION_NUMBER = '1.1.2',
|
46
|
+
WORKING_DIRECTORY = process.cwd(),
|
47
|
+
path = require('path'),
|
48
|
+
MAIN_DIRECTORY = path.join(WORKING_DIRECTORY, 'node_modules', 'linny-r'),
|
49
|
+
// Load the required Node.js modules
|
50
50
|
fs = require('fs'),
|
51
51
|
os = require('os'),
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
// Get the platform name (win32, macOS, linux) of the user's computer
|
56
|
-
const PLATFORM = os.platform();
|
52
|
+
readline = require('readline'),
|
53
|
+
// Get the platform name (win32, macOS, linux) of the user's computer
|
54
|
+
PLATFORM = os.platform();
|
57
55
|
|
58
56
|
// Immediately output some configuration information to the console
|
59
57
|
console.log('\nNode.js Linny-R console version', VERSION_NUMBER);
|
60
58
|
console.log('Node.js version:', process.version);
|
61
59
|
console.log('Platform:', PLATFORM, '(' + os.type() + ')');
|
62
60
|
console.log('Main directory:', MAIN_DIRECTORY);
|
61
|
+
console.log('Working directory:', WORKING_DIRECTORY);
|
63
62
|
|
64
|
-
// Load the MILP solver (dependent on Node.js: `fs`, `os` and `path`)
|
65
|
-
const MILPSolver = require('./static/scripts/linny-r-milp.js');
|
66
|
-
|
67
|
-
// Load the browser-compatible Linny-R scripts
|
68
63
|
const
|
64
|
+
// Load the MILP solver (dependent on Node.js: `fs`, `os` and `path`)
|
65
|
+
MILPSolver = require('./static/scripts/linny-r-milp.js'),
|
66
|
+
// Load the browser-compatible Linny-R scripts
|
69
67
|
config = require('./static/scripts/linny-r-config.js'),
|
70
68
|
utils = require('./static/scripts/linny-r-utils.js'),
|
71
69
|
vm = require('./static/scripts/linny-r-vm.js'),
|
@@ -681,7 +679,7 @@ function commandLineSettings() {
|
|
681
679
|
preferred_solver: '',
|
682
680
|
solver: '',
|
683
681
|
solver_path: '',
|
684
|
-
user_dir: path.join(
|
682
|
+
user_dir: path.join(WORKING_DIRECTORY, 'user')
|
685
683
|
};
|
686
684
|
let show_usage = process.argv.length < 3;
|
687
685
|
for(let i = 2; i < process.argv.length; i++) {
|
@@ -812,7 +810,7 @@ function commandLineSettings() {
|
|
812
810
|
}
|
813
811
|
// Check if lp_solve(.exe) exists in main directory
|
814
812
|
const
|
815
|
-
sp = path.join(
|
813
|
+
sp = path.join(WORKING_DIRECTORY,
|
816
814
|
'lp_solve' + (PLATFORM.startsWith('win') ? '.exe' : '')),
|
817
815
|
need_lps = !settings.solver || settings.preferred_solver === 'lp_solve';
|
818
816
|
try {
|
package/package.json
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
{
|
2
2
|
"name": "linny-r",
|
3
|
-
"version": "1.1.
|
3
|
+
"version": "1.1.2",
|
4
4
|
"description": "Executable graphical language with WYSIWYG editor for MILP models",
|
5
5
|
"main": "server.js",
|
6
6
|
"scripts": {
|
7
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
8
|
-
"install" : "scripts/install.js"
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
9
8
|
},
|
10
9
|
"dependencies": {
|
11
10
|
"@xmldom/xmldom": ">=0.8.2"
|
package/server.js
CHANGED
@@ -39,15 +39,17 @@ SOFTWARE.
|
|
39
39
|
|
40
40
|
const
|
41
41
|
// The version number of this Linny-R server in Node.js
|
42
|
-
VERSION_NUMBER = '1.
|
42
|
+
VERSION_NUMBER = '1.1.2',
|
43
43
|
|
44
44
|
// The URL of the official Linny-R website (with the most recent release)
|
45
45
|
PUBLIC_LINNY_R_URL = 'https://sysmod.tbm.tudelft.nl/linny-r',
|
46
46
|
|
47
47
|
// The current working directory (from where Node.js was started) is
|
48
48
|
// assumed to be the main directory
|
49
|
-
|
50
|
-
|
49
|
+
path = require('path'),
|
50
|
+
WORKING_DIRECTORY = process.cwd(),
|
51
|
+
MAIN_DIRECTORY = path.join(WORKING_DIRECTORY, 'node_modules', 'linny-r'),
|
52
|
+
|
51
53
|
// Get the required built-in Node.js modules
|
52
54
|
child_process = require('child_process'),
|
53
55
|
crypto = require('crypto'),
|
@@ -55,7 +57,6 @@ const
|
|
55
57
|
http = require('http'),
|
56
58
|
https = require('https'),
|
57
59
|
os = require('os'),
|
58
|
-
path = require('path'),
|
59
60
|
|
60
61
|
// Get the platform name (win32, macOS, linux) of the user's computer
|
61
62
|
PLATFORM = os.platform();
|
@@ -65,6 +66,7 @@ console.log('\nNode.js server for Linny-R version', VERSION_NUMBER);
|
|
65
66
|
console.log('Node.js version:', process.version);
|
66
67
|
console.log('Platform:', PLATFORM, '(' + os.type() + ')');
|
67
68
|
console.log('Main directory:', MAIN_DIRECTORY);
|
69
|
+
console.log('Working directory:', WORKING_DIRECTORY);
|
68
70
|
|
69
71
|
// Only then require the Node.js modules that are not "built-in"
|
70
72
|
|
@@ -104,8 +106,6 @@ const SOLVER = new MILPSolver(SETTINGS, WORKSPACE);
|
|
104
106
|
// Create launch script
|
105
107
|
createLaunchScript();
|
106
108
|
|
107
|
-
verifyScriptFiles();
|
108
|
-
|
109
109
|
// Create the HTTP server
|
110
110
|
const SERVER = http.createServer((req, res) => {
|
111
111
|
const u = new URL(req.url, 'http://127.0.0.1:' + SETTINGS.port);
|
@@ -831,11 +831,11 @@ function receiver(res, sp) {
|
|
831
831
|
let
|
832
832
|
rpath = anyOSpath(sp.get('path') || ''),
|
833
833
|
rfile = anyOSpath(sp.get('file') || '');
|
834
|
-
// Assume that path is relative
|
834
|
+
// Assume that path is relative to channel directory unless it starts with
|
835
835
|
// a (back)slash or specifiess drive or volume
|
836
836
|
if(!(rpath.startsWith(path.sep) || rpath.indexOf(':') >= 0 ||
|
837
|
-
rpath.startsWith(
|
838
|
-
rpath = path.join(
|
837
|
+
rpath.startsWith(WORKING_DIRECTORY))) {
|
838
|
+
rpath = path.join(WORKING_DIRECTORY, rpath);
|
839
839
|
}
|
840
840
|
// Verify that the channel path exists
|
841
841
|
try {
|
@@ -1321,7 +1321,7 @@ function commandLineSettings() {
|
|
1321
1321
|
preferred_solver: '',
|
1322
1322
|
solver: '',
|
1323
1323
|
solver_path: '',
|
1324
|
-
user_dir: path.join(
|
1324
|
+
user_dir: path.join(WORKING_DIRECTORY, 'user')
|
1325
1325
|
};
|
1326
1326
|
for(let i = 2; i < process.argv.length; i++) {
|
1327
1327
|
const lca = process.argv[i].toLowerCase();
|
@@ -1410,9 +1410,9 @@ function commandLineSettings() {
|
|
1410
1410
|
'WARNING: Failed to access the Gurobi command line application');
|
1411
1411
|
}
|
1412
1412
|
}
|
1413
|
-
// Check if lp_solve(.exe) exists in
|
1413
|
+
// Check if lp_solve(.exe) exists in working directory
|
1414
1414
|
const
|
1415
|
-
sp = path.join(
|
1415
|
+
sp = path.join(WORKING_DIRECTORY,
|
1416
1416
|
'lp_solve' + (PLATFORM.startsWith('win') ? '.exe' : '')),
|
1417
1417
|
need_lps = !settings.solver || settings.preferred_solver === 'lp_solve';
|
1418
1418
|
try {
|
@@ -1518,17 +1518,17 @@ function createLaunchScript() {
|
|
1518
1518
|
'# cd ',
|
1519
1519
|
'',
|
1520
1520
|
'# Then this command to launch the Linny-R server should work:',
|
1521
|
-
'node server launch'
|
1521
|
+
'node ' + path.join('node_modules', 'linny-r', 'server') + ' launch'
|
1522
1522
|
];
|
1523
1523
|
let sp;
|
1524
1524
|
if(PLATFORM.startsWith('win')) {
|
1525
|
-
sp = path.join(
|
1525
|
+
sp = path.join(WORKING_DIRECTORY, 'linny-r.bat');
|
1526
1526
|
lines[1] += 'C:\\path\\to\\main\\Linny-R\\directory';
|
1527
1527
|
} else {
|
1528
|
-
sp = path.join(
|
1528
|
+
sp = path.join(WORKING_DIRECTORY, 'linny-r.command');
|
1529
1529
|
lines[1] += '/path/to/main/Linny-R/directory';
|
1530
1530
|
}
|
1531
|
-
lines[2] = 'cd ' +
|
1531
|
+
lines[2] = 'cd ' + WORKING_DIRECTORY;
|
1532
1532
|
try {
|
1533
1533
|
try {
|
1534
1534
|
fs.accessSync(sp);
|
package/static/index.html
CHANGED
@@ -51,6 +51,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
51
51
|
-->
|
52
52
|
|
53
53
|
<link rel="shortcut icon" type="image/png" href="images/icon.png">
|
54
|
+
<!-- NOTE: do not display the page until after software update check -->
|
55
|
+
<style>body { display: none; }</style>
|
54
56
|
<script>
|
55
57
|
var
|
56
58
|
// NODE = false indicates that modules need not export their properties
|
@@ -141,8 +143,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
141
143
|
}
|
142
144
|
|
143
145
|
function checkForUpdates() {
|
144
|
-
UI.check_update_modal.element('reload-btn').style.display = 'none';
|
145
|
-
UI.check_update_modal.element('restart-btn').style.display = 'none';
|
146
146
|
fetch('auto-check')
|
147
147
|
.then((response) => response.text())
|
148
148
|
.then((data) => {
|