linny-r 1.1.23 → 1.2.1

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.
@@ -747,6 +747,52 @@ img.inline-cancel-btn {
747
747
  cursor: pointer;
748
748
  }
749
749
 
750
+ /* styles for the NEW SCALAR dialog */
751
+ #new-scale-unit-modal {
752
+ z-index: 115; /* on top of the SCALARS modal */
753
+ }
754
+
755
+ #new-scale-unit-dlg {
756
+ width: min-content;
757
+ height: min-content;
758
+ max-height: 450px;
759
+ }
760
+
761
+ #new-scale-unit-name {
762
+ width: 70px;
763
+ }
764
+
765
+ #new-scale-unit-scalar {
766
+ width: 115px;
767
+ }
768
+
769
+ #new-scale-unit-base {
770
+ width: 70px;
771
+ }
772
+
773
+ /* styles for the SCALE UNITS dialog */
774
+ #scale-units-modal {
775
+ z-index: 110; /* on top of the SETTINGS dialog */
776
+ }
777
+
778
+ #scale-units-dlg {
779
+ width: 270px;
780
+ height: min-content;
781
+ max-height: 450px;
782
+ }
783
+
784
+ #scale-units-buttons > img.btn {
785
+ height: 20px;
786
+ width: 20px;
787
+ }
788
+
789
+ #scale-units-scroll-area {
790
+ margin: 2px;
791
+ width: calc(100% - 4px);
792
+ max-height: 250px;
793
+ overflow-y: auto;
794
+ border-top: 1px solid Silver;
795
+ }
750
796
 
751
797
  /* styles for the MODEL SETTINGS dialog */
752
798
  #settings-dlg {
@@ -754,6 +800,18 @@ img.inline-cancel-btn {
754
800
  height: min-content;
755
801
  }
756
802
 
803
+ #settings-scale-units-btn {
804
+ margin-left: 0px;
805
+ margin-right: 7px;
806
+ margin-top: -3px;
807
+ cursor: pointer;
808
+ filter: brightness(85%);
809
+ }
810
+
811
+ #settings-scale-units-btn:hover {
812
+ filter: brightness(200%);
813
+ }
814
+
757
815
  #password-dlg {
758
816
  width: min-content;
759
817
  height: min-content;
@@ -958,6 +1016,7 @@ td.a-box > div.abox {
958
1016
 
959
1017
  td.a-name {
960
1018
  width: 208px;
1019
+ max-width: 208px;
961
1020
  white-space: nowrap;
962
1021
  overflow: hidden;
963
1022
  text-overflow: ellipsis;
@@ -966,6 +1025,7 @@ td.a-name {
966
1025
 
967
1026
  td.a-weight {
968
1027
  width: 124px;
1028
+ max-width: 124px;
969
1029
  white-space: nowrap;
970
1030
  overflow: hidden;
971
1031
  text-overflow: ellipsis;
@@ -1546,7 +1606,7 @@ td.export {
1546
1606
  }
1547
1607
 
1548
1608
  #expression-dlg {
1549
- width: 545px;
1609
+ width: 550px;
1550
1610
  height: 325px;
1551
1611
  }
1552
1612
 
@@ -1905,6 +1965,7 @@ div.io-box {
1905
1965
  border-top: 1px solid Silver;
1906
1966
  }
1907
1967
 
1968
+ #scale-units-table,
1908
1969
  #dataset-table,
1909
1970
  #dataset-modif-table,
1910
1971
  #equation-table,
@@ -2025,24 +2086,91 @@ tr.sel-set {
2025
2086
  background-color: #eff0ff;
2026
2087
  }
2027
2088
 
2028
- td.outcome:before {
2089
+ tr.def-sel {
2090
+ color: #400090;
2091
+ font-weight: bold;
2092
+ }
2093
+
2094
+ td.modif::before {
2095
+ content: ' \2045';
2096
+ color: #b00080;
2097
+ margin-right: 2px;
2098
+ }
2099
+
2100
+ td.outcome::before {
2029
2101
  content: ' \25C8';
2102
+ color: #b00080;
2103
+ margin-right: 1px;
2030
2104
  }
2031
2105
 
2032
- td.array:before {
2033
- content: ' \2637';
2106
+ td.array::before {
2107
+ content: ' \2263';
2108
+ color: #b00080;
2109
+ margin-right: 1px;
2110
+ }
2111
+
2112
+ td.series::before {
2113
+ content: ' \28B8';
2114
+ color: #b00080;
2115
+ margin-left: -4px;
2034
2116
  }
2035
2117
 
2036
- td.blackbox:before {
2118
+ td.outcome.modif::before {
2119
+ content: ' \25C8\2045';
2120
+ color: #b00080;
2121
+ margin-right: 2px;
2122
+ }
2123
+
2124
+ td.array.modif::before {
2125
+ content: ' \2263\2045';
2126
+ color: #b00080;
2127
+ margin-right: 1px;
2128
+ }
2129
+
2130
+ td.series.modif::before {
2131
+ content: ' \28B8\2045';
2132
+ color: #b00080;
2133
+ margin-left: -4px;
2134
+ }
2135
+
2136
+ td.blackbox::before {
2037
2137
  content: ' \25FC';
2138
+ color: #b00080;
2139
+ }
2140
+
2141
+ td.blackbox.series::before {
2142
+ content: ' \25FC\28B8';
2143
+ color: #b00080;
2038
2144
  }
2039
2145
 
2040
- td.blackbox.array:before {
2041
- content: ' \25FC\2637';
2146
+ td.blackbox.array::before {
2147
+ content: ' \25FC\2263';
2148
+ color: #b00080;
2042
2149
  }
2043
2150
 
2044
- td.blackbox.outcome:before {
2151
+ td.blackbox.outcome::before {
2045
2152
  content: ' \25FC\25C8';
2153
+ color: #b00080;
2154
+ }
2155
+
2156
+ td.blackbox.modif::before {
2157
+ content: ' \25FC\2045';
2158
+ color: #b00080;
2159
+ }
2160
+
2161
+ td.blackbox.series.modif::before {
2162
+ content: ' \25FC\28B8\2045';
2163
+ color: #b00080;
2164
+ }
2165
+
2166
+ td.blackbox.array.modif::before {
2167
+ content: ' \25FC\2263\2045';
2168
+ color: #b00080;
2169
+ }
2170
+
2171
+ td.blackbox.outcome.modif::before {
2172
+ content: ' \25FC\25C8\2045';
2173
+ color: #b00080;
2046
2174
  }
2047
2175
 
2048
2176
  td.dataset-selector {
@@ -2169,7 +2297,7 @@ td.equation-expression {
2169
2297
  /* SERIES modal dialog */
2170
2298
  #series-dlg {
2171
2299
  width: 165px;
2172
- height: 320px;
2300
+ height: 341px;
2173
2301
  }
2174
2302
 
2175
2303
  #series-default-lbl {
@@ -2184,36 +2312,49 @@ td.equation-expression {
2184
2312
  left: 79px;
2185
2313
  width: calc(100% - 83px);
2186
2314
  font-size: 12px;
2187
- margin-bottom: 2px;
2315
+ }
2316
+
2317
+ #series-unit-lbl {
2318
+ position: absolute;
2319
+ top: 47px;
2320
+ left: 2px;
2321
+ }
2322
+
2323
+ #series-unit {
2324
+ position: absolute;
2325
+ top: 46px;
2326
+ left: 32px;
2327
+ width: 70px;
2328
+ font-size: 12px;
2188
2329
  }
2189
2330
 
2190
2331
  #series-periodic {
2191
2332
  position: absolute;
2192
- top: 45px;
2333
+ top: 66px;
2193
2334
  left: 0px;
2194
2335
  }
2195
2336
 
2196
2337
  #series-periodic-lbl {
2197
2338
  position: absolute;
2198
- top: 47px;
2339
+ top: 68px;
2199
2340
  left: 22px;
2200
2341
  }
2201
2342
 
2202
2343
  #series-array {
2203
2344
  position: absolute;
2204
- top: 45px;
2345
+ top: 66px;
2205
2346
  left: 77px;
2206
2347
  }
2207
2348
 
2208
2349
  #series-array-lbl {
2209
2350
  position: absolute;
2210
- top: 47px;
2351
+ top: 68px;
2211
2352
  left: 99px;
2212
2353
  }
2213
2354
 
2214
2355
  #series-no-time-msg {
2215
2356
  position: absolute;
2216
- top: 66px;
2357
+ top: 87px;
2217
2358
  left: 1px;
2218
2359
  width: calc(100% - 2px);
2219
2360
  height: 30px;
@@ -2227,22 +2368,21 @@ td.equation-expression {
2227
2368
 
2228
2369
  #series-time-step-lbl {
2229
2370
  position: absolute;
2230
- top: 68px;
2371
+ top: 89px;
2231
2372
  left: 2px;
2232
2373
  }
2233
2374
 
2234
2375
  #series-time-scale {
2235
2376
  position: absolute;
2236
- top: 67px;
2377
+ top: 88px;
2237
2378
  left: 60px;
2238
2379
  width: 50px;
2239
2380
  font-size: 12px;
2240
- margin-bottom: 2px;
2241
2381
  }
2242
2382
 
2243
2383
  #series-time-unit {
2244
2384
  position: absolute;
2245
- top: 67px;
2385
+ top: 88px;
2246
2386
  left: 116px;
2247
2387
  height: 19px;
2248
2388
  width: 45px;
@@ -2251,13 +2391,13 @@ td.equation-expression {
2251
2391
 
2252
2392
  #series-method-lbl {
2253
2393
  position: absolute;
2254
- top: 91px;
2394
+ top: 112px;
2255
2395
  left: 2px;
2256
2396
  }
2257
2397
 
2258
2398
  #series-method {
2259
2399
  position: absolute;
2260
- top: 89px;
2400
+ top: 110px;
2261
2401
  left: 50px;
2262
2402
  height: 21px;
2263
2403
  width: 111px;
@@ -2266,7 +2406,7 @@ td.equation-expression {
2266
2406
 
2267
2407
  #series-remote {
2268
2408
  position: absolute;
2269
- top: 113px;
2409
+ top: 134px;
2270
2410
  left: 3px;
2271
2411
  width: calc(100% - 8px);
2272
2412
  }
@@ -2278,7 +2418,7 @@ td.equation-expression {
2278
2418
 
2279
2419
  #series-data-lbl {
2280
2420
  position: absolute;
2281
- top: 133px;
2421
+ top: 154px;
2282
2422
  left: 2px;
2283
2423
  }
2284
2424
 
@@ -2286,7 +2426,7 @@ td.equation-expression {
2286
2426
  position: absolute;
2287
2427
  bottom: 13px;
2288
2428
  width: calc(100% - 6px);
2289
- height: calc(100% - 165px);
2429
+ height: calc(100% - 186px);
2290
2430
  margin: 3px;
2291
2431
  }
2292
2432
 
@@ -2966,9 +3106,9 @@ td.sa-not-run {
2966
3106
  display: none;
2967
3107
  z-index: 20;
2968
3108
  margin: 0;
2969
- width: 425px;
3109
+ width: 450px;
2970
3110
  height: 275px;
2971
- min-width: 425px;
3111
+ min-width: 450px;
2972
3112
  min-height: 250px;
2973
3113
  max-height: 99vh;
2974
3114
  max-width: 99vw;
@@ -3050,7 +3190,7 @@ td.sa-not-run {
3050
3190
  position: absolute;
3051
3191
  top: -2px;
3052
3192
  left: 72px;
3053
- width: 140px;
3193
+ width: 170px;
3054
3194
  }
3055
3195
 
3056
3196
  /* enhance brightness for dark v-btn buttons */
@@ -3449,20 +3589,41 @@ div.no-colors {
3449
3589
  width: calc(100% - 6px);
3450
3590
  }
3451
3591
 
3592
+ #xp-iterator-dlg {
3593
+ width: 130px;
3594
+ height: min-content;
3595
+ }
3596
+
3597
+ #xp-iterator-table {
3598
+ margin: 2px;
3599
+ }
3600
+
3601
+ input.range-limit {
3602
+ height: 15px !important;
3603
+ width: 30px;
3604
+ text-align: center;
3605
+ }
3606
+
3452
3607
  /* the EDIT SETTINGS DIMENSIONS dialog allows editing these dimensions */
3453
- /* NOTE: many styles in common with the EDIT ACTOR DIMENSIONS dialog */
3454
- #xp-settings-dlg {
3608
+ /* NOTE: many styles in common with the EDIT COMBINATIONS dialog and */
3609
+ /* the EDIT ACTOR DIMENSIONS dialog */
3610
+ #xp-settings-dlg,
3611
+ #xp-combination-dlg {
3455
3612
  width: 270px;
3456
3613
  height: 236px;
3457
3614
  }
3458
3615
 
3459
- #xp-actor-s-header,
3616
+ #xp-actor-dimension-header,
3617
+ #xp-combination-s-header,
3618
+ #xp-combination-d-header,
3460
3619
  #xp-settings-s-header,
3461
3620
  #xp-settings-d-header {
3462
3621
  margin: 2px;
3463
3622
  }
3464
3623
 
3465
- #xp-actor-s-header > img,
3624
+ #xp-actor-dimension-header > img,
3625
+ #xp-combination-s-header > img,
3626
+ #xp-combination-d-header > img,
3466
3627
  #xp-settings-s-header > img,
3467
3628
  #xp-settings-d-header > img {
3468
3629
  margin-left: 5px;
@@ -3470,6 +3631,8 @@ div.no-colors {
3470
3631
  vertical-align: bottom;
3471
3632
  }
3472
3633
 
3634
+ #xp-combination-s-scroll-area,
3635
+ #xp-combination-d-scroll-area,
3473
3636
  #xp-settings-s-scroll-area,
3474
3637
  #xp-settings-d-scroll-area {
3475
3638
  width: 266px;
@@ -3479,6 +3642,8 @@ div.no-colors {
3479
3642
  }
3480
3643
 
3481
3644
  #xp-actor-dimension-table,
3645
+ #xp-combination-s-table,
3646
+ #xp-combination-d-table,
3482
3647
  #xp-settings-s-table,
3483
3648
  #xp-settings-d-table {
3484
3649
  background-color: white;
@@ -3488,6 +3653,8 @@ div.no-colors {
3488
3653
  }
3489
3654
 
3490
3655
  #xp-actor-dimension-table > tbody > tr:hover,
3656
+ #xp-combination-s-table > tbody > tr:hover,
3657
+ #xp-combination-d-table > tbody > tr:hover,
3491
3658
  #xp-settings-s-table > tbody > tr:hover,
3492
3659
  #xp-settings-d-table > tbody > tr:hover,
3493
3660
  #xp-clusters-table > tbody > tr:hover {
@@ -3495,33 +3662,43 @@ div.no-colors {
3495
3662
  }
3496
3663
 
3497
3664
  #xp-actor-dimension-table > tbody > tr > td,
3665
+ #xp-combination-s-table > tbody > tr > td,
3498
3666
  #xp-settings-s-table > tbody > tr > td,
3499
3667
  #xp-clusters-table > tbody > tr > td {
3500
3668
  border: 1px solid Silver;
3501
3669
  }
3502
3670
 
3671
+ #xp-combination-selector-dlg {
3672
+ width: 395px;
3673
+ height: 45px;
3674
+ }
3675
+
3503
3676
  #xp-settings-selector-dlg {
3504
3677
  width: 370px;
3505
3678
  height: 45px;
3506
3679
  }
3507
3680
 
3508
3681
  #xp-actor-selector-code,
3682
+ #xp-combination-selector-code,
3509
3683
  #xp-settings-selector-code {
3510
3684
  width: 80px;
3511
3685
  }
3512
3686
 
3687
+ #xp-combination-selector-string,
3513
3688
  #xp-settings-selector-string {
3514
3689
  width: 182px;
3515
3690
  font-family: monospace;
3516
3691
  }
3517
3692
 
3693
+ #xp-combination-dimension-dlg,
3518
3694
  #xp-settings-dimension-dlg {
3519
- width: 295px;
3695
+ width: 305px;
3520
3696
  height: 45px;
3521
3697
  }
3522
3698
 
3699
+ #xp-combination-dimension-string,
3523
3700
  #xp-settings-dimension-string {
3524
- width: 234px;
3701
+ width: 244px;
3525
3702
  }
3526
3703
 
3527
3704
  span.sd-clear {
@@ -3855,6 +4032,11 @@ select.i-param {
3855
4032
  max-width: calc(100% - 15px);
3856
4033
  }
3857
4034
 
4035
+ #confirm-load-from-repo-dlg {
4036
+ width: 400px;
4037
+ height: 85px;
4038
+ }
4039
+
3858
4040
  #confirm-delete-from-repo-dlg {
3859
4041
  width: 270px;
3860
4042
  height: 120px;
@@ -3866,12 +4048,14 @@ select.i-param {
3866
4048
  font-weight: bold;
3867
4049
  }
3868
4050
 
4051
+ #confirm-load-from-repo-mod-name,
3869
4052
  #confirm-delete-from-repo-mod-name {
3870
4053
  word-break: keep-all;
3871
4054
  white-space: nowrap;
3872
4055
  font-family: monospace;
3873
4056
  }
3874
4057
 
4058
+ #confirm-load-from-repo-msg,
3875
4059
  #confirm-delete-from-repo-msg {
3876
4060
  height: calc(100% - 55px);
3877
4061
  }
@@ -4396,6 +4580,7 @@ div.call-stack-expr {
4396
4580
  height: min-content;
4397
4581
  }
4398
4582
 
4583
+ #confirm-load-from-repo-msg,
4399
4584
  #confirm-delete-from-repo-msg,
4400
4585
  #check-update-msg {
4401
4586
  width: calc(100% - 8px);
@@ -4404,6 +4589,7 @@ div.call-stack-expr {
4404
4589
  }
4405
4590
 
4406
4591
  #confirm-move-buttons,
4592
+ #confirm-load-from-repo-buttons,
4407
4593
  #confirm-delete-from-repo-buttons,
4408
4594
  #check-update-buttons {
4409
4595
  width: 100%;
@@ -4414,6 +4600,7 @@ div.call-stack-expr {
4414
4600
  }
4415
4601
 
4416
4602
  #confirm-move-buttons > img,
4603
+ #confirm-load-from-repo-buttons > img,
4417
4604
  #confirm-delete-from-repo-buttons > img,
4418
4605
  #check-update-buttons > img {
4419
4606
  float: none;
@@ -45,6 +45,12 @@ const CONFIGURATION = {
45
45
  // Default properties for new models
46
46
  default_currency_unit: 'EUR',
47
47
  default_time_unit: 'hour',
48
+ // Standard scale units to be included in new models
49
+ scale_units: [
50
+ // Units can be defined as 3-tuples [name, scalar, base unit], e.g.,
51
+ // ['MJ', '1', '1'],
52
+ // ['kWh', '3.6', 'MJ']
53
+ ],
48
54
  default_scale_unit: '1', // 1 denotes "no unit" (abstract scale)
49
55
  // Font properties for SVG diagram
50
56
  // NOTE: When a font name comprises multiple words, it must be enclosed
@@ -130,8 +130,9 @@ class Controller {
130
130
  end_period: 'End at',
131
131
  look_ahead: 'Look-ahead'
132
132
  },
133
- ENTITY_PROPS: ['actors', 'clusters', 'processes', 'products', 'datasets',
134
- 'equations', 'links', 'constraints'],
133
+ ENTITY_PROPS: ['units', 'actors', 'clusters', 'processes', 'products',
134
+ 'datasets', 'equations', 'links', 'constraints'],
135
+ UNIT_PROPS: ['multiplier', 'base_unit'],
135
136
  ACTOR_PROPS: ['weight', 'comments'],
136
137
  CLUSTER_PROPS: ['comments', 'collapsed', 'ignore'],
137
138
  PROCESS_PROPS: ['comments', 'lower_bound', 'upper_bound', 'initial_level',
@@ -139,8 +140,8 @@ class Controller {
139
140
  PRODUCT_PROPS: ['comments', 'lower_bound', 'upper_bound', 'initial_level',
140
141
  'scale_unit', 'equal_bounds', 'price', 'is_source', 'is_sink', 'is_buffer',
141
142
  'is_data', 'integer_level', 'no_slack'],
142
- DATASET_PROPS: ['comments', 'default_value', 'time_scale', 'time_unit',
143
- 'method', 'periodic', 'array', 'url', 'default_selector'],
143
+ DATASET_PROPS: ['comments', 'default_value', 'scale_unit', 'time_scale',
144
+ 'time_unit', 'method', 'periodic', 'array', 'url', 'default_selector'],
144
145
  LINK_PROPS: ['comments', 'multiplier', 'relative_rate', 'share_of_cost',
145
146
  'flow_delay'],
146
147
  CONSTRAINT_PROPS: ['comments', 'no_slack', 'share_of_cost'],
@@ -152,7 +153,8 @@ class Controller {
152
153
  EXPERIMENT_PROPS: ['comments', 'configuration_dims',
153
154
  'column_scenario_dims', 'excluded_selectors'],
154
155
  };
155
- this.MC.ALL_PROPS = this.MC.ENTITY_PROPS + this.MC.ACTOR_PROPS +
156
+ this.MC.ALL_PROPS = this.MC.ENTITY_PROPS +
157
+ this.MC.UNIT_PROPS + this.MC.ACTOR_PROPS +
156
158
  this.MC.CLUSTER_PROPS + this.MC.PROCESS_PROPS +
157
159
  this.MC.PRODUCT_PROPS + this.MC.DATASET_PROPS + this.MC.LINK_PROPS +
158
160
  this.MC.CONSTRAINT_PROPS + this.MC.NOTE_PROPS + this.MC.CHART_PROPS +
@@ -277,9 +279,12 @@ class Controller {
277
279
  // Returns `name` without the object-attribute separator |, backslashes,
278
280
  // and leading and trailing whitespace, and with all internal whitespace
279
281
  // reduced to a single space.
280
- return name.replace(this.OA_SEPARATOR, ' ')
282
+ name = name.replace(this.OA_SEPARATOR, ' ')
281
283
  .replace(/\||\\/g, ' ').trim()
282
284
  .replace(/\s\s+/g, ' ');
285
+ // NOTE: this may still result in a single space, which is not a name
286
+ if(name === ' ') return '';
287
+ return name;
283
288
  }
284
289
 
285
290
  validName(name) {
@@ -311,6 +316,16 @@ class Controller {
311
316
  return n.replace(this.EQUATIONS_DATASET_NAME + '|',
312
317
  '<span class="eq">\u221Ax</span>');
313
318
  }
319
+
320
+ nameAsConstantString(n) {
321
+ // Returns name with single quotes if it equals an Linny-R constant
322
+ // or operator, or when it contains symbol separator characters or ']'
323
+ let quoted = CONSTANT_SYMBOLS.indexOf(n) >= 0 ||
324
+ MONADIC_OPERATORS.indexOf(n) >= 0 || n.indexOf(']') >= 0;
325
+ if(!quoted) SEPARATOR_CHARS.split('').forEach(
326
+ (c) => { if(n.indexOf(c) >= 0) quoted = true; });
327
+ return (quoted ? `'${n}'` : n);
328
+ }
314
329
 
315
330
  replaceEntity(str, en1, en2) {
316
331
  // Returns `en2` if `str` matches entity name `en1`; otherwise FALSE
@@ -329,7 +344,7 @@ class Controller {
329
344
  // Return FALSE to indicate "no replacement made"
330
345
  return false;
331
346
  }
332
-
347
+
333
348
  // Methods to notify modeler
334
349
 
335
350
  setMessage(msg, type, cause=null) {
@@ -437,6 +452,7 @@ class Controller {
437
452
  // while they can only be meaningfully performed by the GUI controller
438
453
  addListeners() {}
439
454
  readyToReset() {}
455
+ updateScaleUnitList() {}
440
456
  drawDiagram() {}
441
457
  drawSelection() {}
442
458
  drawObject() {}
@@ -958,6 +974,9 @@ class SensitivityAnalysis {
958
974
  // Class ExperimentManager controls the collection of experiments of the model
959
975
  class ExperimentManager {
960
976
  constructor() {
977
+ // NOTE: the properties below are relevant only for the GUI
978
+ this.experiment_table = null;
979
+ this.focal_table = null;
961
980
  }
962
981
 
963
982
  reset() {
@@ -989,6 +1008,7 @@ class ExperimentManager {
989
1008
  selectExperiment(title) {
990
1009
  const xi = MODEL.indexOfExperiment(title);
991
1010
  this.selected_experiment = (xi < 0 ? null : MODEL.experiments[xi]);
1011
+ this.focal_table = this.experiment_table;
992
1012
  this.updateDialog();
993
1013
  }
994
1014