linny-r 2.0.8 → 2.0.10
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 +3 -40
- package/package.json +6 -2
- package/server.js +19 -157
- package/static/images/solve-not-same-changed.png +0 -0
- package/static/images/solve-not-same-not-changed.png +0 -0
- package/static/images/solve-same-changed.png +0 -0
- package/static/images/solve-same-not-changed.png +0 -0
- package/static/index.html +137 -20
- package/static/linny-r.css +260 -23
- package/static/scripts/iro.min.js +7 -7
- package/static/scripts/linny-r-ctrl.js +126 -85
- package/static/scripts/linny-r-gui-actor-manager.js +23 -33
- package/static/scripts/linny-r-gui-chart-manager.js +56 -53
- package/static/scripts/linny-r-gui-constraint-editor.js +10 -14
- package/static/scripts/linny-r-gui-controller.js +644 -260
- package/static/scripts/linny-r-gui-dataset-manager.js +64 -66
- package/static/scripts/linny-r-gui-documentation-manager.js +11 -17
- package/static/scripts/linny-r-gui-equation-manager.js +22 -22
- package/static/scripts/linny-r-gui-experiment-manager.js +124 -141
- package/static/scripts/linny-r-gui-expression-editor.js +26 -12
- package/static/scripts/linny-r-gui-file-manager.js +42 -48
- package/static/scripts/linny-r-gui-finder.js +294 -55
- package/static/scripts/linny-r-gui-model-autosaver.js +2 -4
- package/static/scripts/linny-r-gui-monitor.js +35 -41
- package/static/scripts/linny-r-gui-paper.js +42 -70
- package/static/scripts/linny-r-gui-power-grid-manager.js +31 -34
- package/static/scripts/linny-r-gui-receiver.js +1 -2
- package/static/scripts/linny-r-gui-repository-browser.js +44 -46
- package/static/scripts/linny-r-gui-scale-unit-manager.js +32 -32
- package/static/scripts/linny-r-gui-sensitivity-analysis.js +61 -67
- package/static/scripts/linny-r-gui-undo-redo.js +94 -95
- package/static/scripts/linny-r-milp.js +20 -24
- package/static/scripts/linny-r-model.js +1932 -2274
- package/static/scripts/linny-r-utils.js +27 -27
- package/static/scripts/linny-r-vm.js +900 -998
- package/static/show-png.html +0 -113
@@ -542,8 +542,8 @@ function matchingNumber(m, s) {
|
|
542
542
|
function matchingNumberInList(ml, s) {
|
543
543
|
// Traverses list `ml` and returns the first matching number, or FALSE
|
544
544
|
// if no match is found.
|
545
|
-
for(
|
546
|
-
const n = matchingNumber(
|
545
|
+
for(const m of ml) {
|
546
|
+
const n = matchingNumber(m, s);
|
547
547
|
if(n !== false) return n;
|
548
548
|
}
|
549
549
|
return false;
|
@@ -680,19 +680,17 @@ function compareCombinations(c1, c2) {
|
|
680
680
|
//
|
681
681
|
|
682
682
|
function addDistinct(e, list) {
|
683
|
-
//
|
683
|
+
// Add element `e` to `list` only if it does not already occur in `list`.
|
684
684
|
if(list.indexOf(e) < 0) list.push(e);
|
685
685
|
}
|
686
686
|
|
687
687
|
function mergeDistinct(list, into) {
|
688
|
-
//
|
689
|
-
for(
|
690
|
-
addDistinct(list[i], into);
|
691
|
-
}
|
688
|
+
// Add elements of `list` to `into` if not already in `into`.
|
689
|
+
for(const e of list) addDistinct(e, into);
|
692
690
|
}
|
693
691
|
|
694
692
|
function iteratorSet(list) {
|
695
|
-
//
|
693
|
+
// Return TRUE iff list is something like ['i=1', 'i=2', 'i=3'].
|
696
694
|
if(list.length === 0) return false;
|
697
695
|
// Analyze the first element: must start with i=, j= or k=.
|
698
696
|
const
|
@@ -722,9 +720,7 @@ function iteratorSet(list) {
|
|
722
720
|
function integerSet(list) {
|
723
721
|
// Returns TRUE iff all elements in list evaluate as integer numbers.
|
724
722
|
if(list.length === 0) return false;
|
725
|
-
for(
|
726
|
-
if(list[i] - 0 != list[i]) return false;
|
727
|
-
}
|
723
|
+
for(const n of list) if(n - 0 != n) return false;
|
728
724
|
return true;
|
729
725
|
}
|
730
726
|
|
@@ -757,20 +753,18 @@ function tupelString(sl) {
|
|
757
753
|
}
|
758
754
|
|
759
755
|
function tupelSetString(ssl) {
|
760
|
-
//
|
756
|
+
// Return string of stringlists `sll` as set of tuples.
|
761
757
|
const tl = [];
|
762
|
-
for(
|
763
|
-
tl.push(tupelString(ssl[i]));
|
764
|
-
}
|
758
|
+
for(const ss of ssl) tl.push(tupelString(ss));
|
765
759
|
return setString(tl);
|
766
760
|
}
|
767
761
|
|
768
762
|
function tupelIndex(sl, ssl) {
|
769
|
-
//
|
763
|
+
// Return index of stringlist `sl` if it exists in `ssl`, otherwise -1.
|
770
764
|
for(let i = 0; i < ssl.length; i++) {
|
771
765
|
let n = 0;
|
772
|
-
for(
|
773
|
-
if(ssl[i].indexOf(
|
766
|
+
for(const s of sl) {
|
767
|
+
if(ssl[i].indexOf(s) < 0) break;
|
774
768
|
n++;
|
775
769
|
}
|
776
770
|
if(n == sl.length) return i;
|
@@ -779,20 +773,16 @@ function tupelIndex(sl, ssl) {
|
|
779
773
|
}
|
780
774
|
|
781
775
|
function intersection(sl1, sl2) {
|
782
|
-
//
|
776
|
+
// Return the list of common elements of stringlists `l1` and `l2`.
|
783
777
|
const shared = [];
|
784
|
-
for(
|
785
|
-
if(sl2.indexOf(sl1[i]) >= 0) shared.push(sl1[i]);
|
786
|
-
}
|
778
|
+
for(const s of sl1) if(sl2.indexOf(s) >= 0) shared.push(s);
|
787
779
|
return shared;
|
788
780
|
}
|
789
781
|
|
790
782
|
function complement(sl1, sl2) {
|
791
783
|
// Returns the list of elements of stringlist `l1` that are NOT in `l2`
|
792
784
|
const cmplmnt = [];
|
793
|
-
for(
|
794
|
-
if(sl2.indexOf(sl1[i]) < 0) cmplmnt.push(sl1[i]);
|
795
|
-
}
|
785
|
+
for(const s of sl1) if(sl2.indexOf(s) < 0) cmplmnt.push(s);
|
796
786
|
return cmplmnt;
|
797
787
|
}
|
798
788
|
|
@@ -800,6 +790,15 @@ function complement(sl1, sl2) {
|
|
800
790
|
// Functions that support loading and saving data and models
|
801
791
|
//
|
802
792
|
|
793
|
+
function asFileName(s) {
|
794
|
+
// Return string `s` with whitespace converted to a single dash, and
|
795
|
+
// special characters converted to underscores.
|
796
|
+
return s.normalize('NFKD').trim()
|
797
|
+
.replace(/[\s\-]+/g, '-')
|
798
|
+
.replace(/[^A-Za-z0-9_\-]/g, '_')
|
799
|
+
.replace(/^[\-\_]+|[\-\_]+$/g, '');
|
800
|
+
}
|
801
|
+
|
803
802
|
function xmlEncoded(str) {
|
804
803
|
// Replaces &, <, >, ' and " by their HTML entity code
|
805
804
|
return str.replace(/\&/g, '&').replace(/</g, '<'
|
@@ -843,8 +842,8 @@ function customizeXML(str) {
|
|
843
842
|
}
|
844
843
|
|
845
844
|
function cleanXML(node) {
|
846
|
-
//
|
847
|
-
// subtree under node
|
845
|
+
// Remove all unnamed text nodes and comment nodes from the XML
|
846
|
+
// subtree under node.
|
848
847
|
const cn = node.childNodes;
|
849
848
|
if(cn) {
|
850
849
|
for(let i = cn.length - 1; i >= 0; i--) {
|
@@ -1169,6 +1168,7 @@ if(NODE) module.exports = {
|
|
1169
1168
|
tupelIndex: tupelIndex,
|
1170
1169
|
intersection: intersection,
|
1171
1170
|
complement: complement,
|
1171
|
+
asFileName: asFileName,
|
1172
1172
|
xmlEncoded: xmlEncoded,
|
1173
1173
|
xmlDecoded: xmlDecoded,
|
1174
1174
|
customizeXML: customizeXML,
|