@grnsft/if 0.0.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.
Files changed (285) hide show
  1. package/.devcontainer/devcontainer.json +38 -0
  2. package/.editorconfig +8 -0
  3. package/.env.example +9 -0
  4. package/.eslintignore +4 -0
  5. package/.eslintrc.json +8 -0
  6. package/.github/ISSUE_TEMPLATE/agenda.md +36 -0
  7. package/.github/ISSUE_TEMPLATE/blank-issue.md +10 -0
  8. package/.github/ISSUE_TEMPLATE/feedback.md +42 -0
  9. package/.github/ISSUE_TEMPLATE/model-plugin.md +63 -0
  10. package/.github/ISSUE_TEMPLATE/user-story.md +10 -0
  11. package/.github/PULL_REQUEST_TEMPLATE.md +21 -0
  12. package/.github/workflows/nodejs-ci.yml +34 -0
  13. package/.gitmodules +3 -0
  14. package/.prettierrc.js +3 -0
  15. package/CONTRIBUTING.md +194 -0
  16. package/LICENSE +21 -0
  17. package/Makefile +16 -0
  18. package/README.md +67 -0
  19. package/build/__mocks__/azure/index.d.ts +11 -0
  20. package/build/__mocks__/azure/index.js +132 -0
  21. package/build/__mocks__/boavizta/countries.json +138 -0
  22. package/build/__mocks__/boavizta/instance_types.json +625 -0
  23. package/build/__mocks__/boavizta/providers.json +1 -0
  24. package/build/__mocks__/fs/index.d.ts +3 -0
  25. package/build/__mocks__/fs/index.js +56 -0
  26. package/build/__mocks__/model-universe/index.d.ts +33 -0
  27. package/build/__mocks__/model-universe/index.js +68 -0
  28. package/build/__mocks__/watt-time/data.json +119 -0
  29. package/build/__tests__/integration/ompl/index.test.d.ts +1 -0
  30. package/build/__tests__/integration/ompl/index.test.js +61 -0
  31. package/build/__tests__/unit/lib/azure-importer/index.test.d.ts +1 -0
  32. package/build/__tests__/unit/lib/azure-importer/index.test.js +152 -0
  33. package/build/__tests__/unit/lib/boavizta/index.test.d.ts +1 -0
  34. package/build/__tests__/unit/lib/boavizta/index.test.js +579 -0
  35. package/build/__tests__/unit/lib/case-studies/aveva.test.d.ts +1 -0
  36. package/build/__tests__/unit/lib/case-studies/aveva.test.js +36 -0
  37. package/build/__tests__/unit/lib/case-studies/emem.test.d.ts +1 -0
  38. package/build/__tests__/unit/lib/case-studies/emem.test.js +108 -0
  39. package/build/__tests__/unit/lib/case-studies/eshoppen.test.d.ts +1 -0
  40. package/build/__tests__/unit/lib/case-studies/eshoppen.test.js +53 -0
  41. package/build/__tests__/unit/lib/case-studies/sci-accenture.test.d.ts +1 -0
  42. package/build/__tests__/unit/lib/case-studies/sci-accenture.test.js +23 -0
  43. package/build/__tests__/unit/lib/ccf/index.test.d.ts +1 -0
  44. package/build/__tests__/unit/lib/ccf/index.test.js +223 -0
  45. package/build/__tests__/unit/lib/cloud-instance-metadata/index.test.d.ts +1 -0
  46. package/build/__tests__/unit/lib/cloud-instance-metadata/index.test.js +73 -0
  47. package/build/__tests__/unit/lib/sci/index.test.d.ts +1 -0
  48. package/build/__tests__/unit/lib/sci/index.test.js +106 -0
  49. package/build/__tests__/unit/lib/sci-e/index.test.d.ts +1 -0
  50. package/build/__tests__/unit/lib/sci-e/index.test.js +30 -0
  51. package/build/__tests__/unit/lib/sci-m/index.test.d.ts +1 -0
  52. package/build/__tests__/unit/lib/sci-m/index.test.js +58 -0
  53. package/build/__tests__/unit/lib/sci-o/index.test.d.ts +1 -0
  54. package/build/__tests__/unit/lib/sci-o/index.test.js +42 -0
  55. package/build/__tests__/unit/lib/shell-imp/index.test.d.ts +1 -0
  56. package/build/__tests__/unit/lib/shell-imp/index.test.js +21 -0
  57. package/build/__tests__/unit/lib/tdp-finder/index.test.d.ts +1 -0
  58. package/build/__tests__/unit/lib/tdp-finder/index.test.js +62 -0
  59. package/build/__tests__/unit/lib/teads-aws/index.test.d.ts +1 -0
  60. package/build/__tests__/unit/lib/teads-aws/index.test.js +170 -0
  61. package/build/__tests__/unit/lib/teads-curve/index.test.d.ts +1 -0
  62. package/build/__tests__/unit/lib/teads-curve/index.test.js +146 -0
  63. package/build/__tests__/unit/lib/watt-time/index.test.d.ts +1 -0
  64. package/build/__tests__/unit/lib/watt-time/index.test.js +106 -0
  65. package/build/__tests__/unit/util/args.test.d.ts +1 -0
  66. package/build/__tests__/unit/util/args.test.js +92 -0
  67. package/build/__tests__/unit/util/models-universe.test.d.ts +1 -0
  68. package/build/__tests__/unit/util/models-universe.test.js +211 -0
  69. package/build/__tests__/unit/util/observatory.test.d.ts +1 -0
  70. package/build/__tests__/unit/util/observatory.test.js +91 -0
  71. package/build/__tests__/unit/util/supercomputer.test.d.ts +1 -0
  72. package/build/__tests__/unit/util/supercomputer.test.js +231 -0
  73. package/build/__tests__/unit/util/yaml.test.d.ts +1 -0
  74. package/build/__tests__/unit/util/yaml.test.js +59 -0
  75. package/build/config/config.d.ts +32 -0
  76. package/build/config/config.js +74 -0
  77. package/build/config/index.d.ts +2 -0
  78. package/build/config/index.js +8 -0
  79. package/build/config/strings.d.ts +14 -0
  80. package/build/config/strings.js +30 -0
  81. package/build/index.d.ts +1 -0
  82. package/build/index.js +46 -0
  83. package/build/lib/azure-importer/index.d.ts +55 -0
  84. package/build/lib/azure-importer/index.js +314 -0
  85. package/build/lib/boavizta/index.d.ts +53 -0
  86. package/build/lib/boavizta/index.js +254 -0
  87. package/build/lib/case-studies/aveva-model.d.ts +29 -0
  88. package/build/lib/case-studies/aveva-model.js +53 -0
  89. package/build/lib/case-studies/emem-model.d.ts +42 -0
  90. package/build/lib/case-studies/emem-model.js +93 -0
  91. package/build/lib/case-studies/eshoppen-model.d.ts +24 -0
  92. package/build/lib/case-studies/eshoppen-model.js +123 -0
  93. package/build/lib/case-studies/index.d.ts +4 -0
  94. package/build/lib/case-studies/index.js +21 -0
  95. package/build/lib/case-studies/sci-accenture-model.d.ts +10 -0
  96. package/build/lib/case-studies/sci-accenture-model.js +37 -0
  97. package/build/lib/ccf/aws-embodied.json +5591 -0
  98. package/build/lib/ccf/aws-instances.json +21116 -0
  99. package/build/lib/ccf/aws-use.json +79 -0
  100. package/build/lib/ccf/azure-embodied.json +6547 -0
  101. package/build/lib/ccf/azure-instances.json +8332 -0
  102. package/build/lib/ccf/azure-use.json +58 -0
  103. package/build/lib/ccf/gcp-embodied.json +3049 -0
  104. package/build/lib/ccf/gcp-instances.json +3880 -0
  105. package/build/lib/ccf/gcp-use.json +58 -0
  106. package/build/lib/ccf/index.d.ts +63 -0
  107. package/build/lib/ccf/index.js +338 -0
  108. package/build/lib/cloud-instance-metadata/aws-instances.json +1 -0
  109. package/build/lib/cloud-instance-metadata/azure-instances.json +1 -0
  110. package/build/lib/cloud-instance-metadata/index.d.ts +15 -0
  111. package/build/lib/cloud-instance-metadata/index.js +104 -0
  112. package/build/lib/index.d.ts +15 -0
  113. package/build/lib/index.js +32 -0
  114. package/build/lib/interfaces/ccf.d.ts +19 -0
  115. package/build/lib/interfaces/ccf.js +3 -0
  116. package/build/lib/interfaces/index.d.ts +7 -0
  117. package/build/lib/interfaces/index.js +18 -0
  118. package/build/lib/sci/index.d.ts +13 -0
  119. package/build/lib/sci/index.js +131 -0
  120. package/build/lib/sci-e/index.d.ts +38 -0
  121. package/build/lib/sci-e/index.js +85 -0
  122. package/build/lib/sci-m/index.d.ts +10 -0
  123. package/build/lib/sci-m/index.js +124 -0
  124. package/build/lib/sci-o/index.d.ts +17 -0
  125. package/build/lib/sci-o/index.js +52 -0
  126. package/build/lib/shell-imp/index.d.ts +32 -0
  127. package/build/lib/shell-imp/index.js +82 -0
  128. package/build/lib/tdp-finder/index.d.ts +19 -0
  129. package/build/lib/tdp-finder/index.js +98 -0
  130. package/build/lib/teads-aws/aws-embodied.json +1 -0
  131. package/build/lib/teads-aws/aws-instances.json +1 -0
  132. package/build/lib/teads-aws/index.d.ts +58 -0
  133. package/build/lib/teads-aws/index.js +208 -0
  134. package/build/lib/teads-curve/index.d.ts +52 -0
  135. package/build/lib/teads-curve/index.js +158 -0
  136. package/build/lib/watt-time/index.d.ts +18 -0
  137. package/build/lib/watt-time/index.js +204 -0
  138. package/build/types/azure-importer.d.ts +29 -0
  139. package/build/types/azure-importer.js +3 -0
  140. package/build/types/boavizta.d.ts +7 -0
  141. package/build/types/boavizta.js +3 -0
  142. package/build/types/common.d.ts +7 -0
  143. package/build/types/common.js +9 -0
  144. package/build/types/impl.d.ts +40 -0
  145. package/build/types/impl.js +3 -0
  146. package/build/types/models-universe.d.ts +24 -0
  147. package/build/types/models-universe.js +3 -0
  148. package/build/types/process-args.d.ts +7 -0
  149. package/build/types/process-args.js +3 -0
  150. package/build/types/supercomputer.d.ts +4 -0
  151. package/build/types/supercomputer.js +3 -0
  152. package/build/util/args.d.ts +8 -0
  153. package/build/util/args.js +48 -0
  154. package/build/util/errors.d.ts +6 -0
  155. package/build/util/errors.js +22 -0
  156. package/build/util/helpers.d.ts +4 -0
  157. package/build/util/helpers.js +18 -0
  158. package/build/util/models-universe.d.ts +28 -0
  159. package/build/util/models-universe.js +95 -0
  160. package/build/util/observatory.d.ts +20 -0
  161. package/build/util/observatory.js +31 -0
  162. package/build/util/supercomputer.d.ts +30 -0
  163. package/build/util/supercomputer.js +109 -0
  164. package/build/util/validations.d.ts +25 -0
  165. package/build/util/validations.js +52 -0
  166. package/build/util/yaml.d.ts +13 -0
  167. package/build/util/yaml.js +36 -0
  168. package/coverage/clover.xml +1172 -0
  169. package/coverage/coverage-final.json +27 -0
  170. package/coverage/lcov-report/base.css +224 -0
  171. package/coverage/lcov-report/block-navigation.js +87 -0
  172. package/coverage/lcov-report/config/config.ts.html +310 -0
  173. package/coverage/lcov-report/config/index.html +146 -0
  174. package/coverage/lcov-report/config/index.ts.html +91 -0
  175. package/coverage/lcov-report/config/strings.ts.html +118 -0
  176. package/coverage/lcov-report/favicon.png +0 -0
  177. package/coverage/lcov-report/index.html +341 -0
  178. package/coverage/lcov-report/lib/boavizta/index.html +116 -0
  179. package/coverage/lcov-report/lib/boavizta/index.ts.html +1171 -0
  180. package/coverage/lcov-report/lib/case-studies/aveva-model.ts.html +277 -0
  181. package/coverage/lcov-report/lib/case-studies/emem-model.ts.html +439 -0
  182. package/coverage/lcov-report/lib/case-studies/eshoppen-model.ts.html +550 -0
  183. package/coverage/lcov-report/lib/case-studies/index.html +176 -0
  184. package/coverage/lcov-report/lib/case-studies/index.ts.html +97 -0
  185. package/coverage/lcov-report/lib/case-studies/sci-accenture-model.ts.html +232 -0
  186. package/coverage/lcov-report/lib/ccf/index.html +116 -0
  187. package/coverage/lcov-report/lib/ccf/index.ts.html +1339 -0
  188. package/coverage/lcov-report/lib/cloud-instance-metadata/index.html +116 -0
  189. package/coverage/lcov-report/lib/cloud-instance-metadata/index.ts.html +370 -0
  190. package/coverage/lcov-report/lib/index.html +116 -0
  191. package/coverage/lcov-report/lib/index.ts.html +121 -0
  192. package/coverage/lcov-report/lib/sci/index.html +116 -0
  193. package/coverage/lcov-report/lib/sci/index.ts.html +571 -0
  194. package/coverage/lcov-report/lib/sci-e/index.html +116 -0
  195. package/coverage/lcov-report/lib/sci-e/index.ts.html +403 -0
  196. package/coverage/lcov-report/lib/sci-m/index.html +116 -0
  197. package/coverage/lcov-report/lib/sci-m/index.ts.html +487 -0
  198. package/coverage/lcov-report/lib/sci-o/index.html +116 -0
  199. package/coverage/lcov-report/lib/sci-o/index.ts.html +265 -0
  200. package/coverage/lcov-report/lib/shell-imp/index.html +116 -0
  201. package/coverage/lcov-report/lib/shell-imp/index.ts.html +376 -0
  202. package/coverage/lcov-report/lib/teads-aws/index.html +116 -0
  203. package/coverage/lcov-report/lib/teads-aws/index.ts.html +823 -0
  204. package/coverage/lcov-report/lib/teads-curve/index.html +116 -0
  205. package/coverage/lcov-report/lib/teads-curve/index.ts.html +625 -0
  206. package/coverage/lcov-report/lib/watt-time/index.html +116 -0
  207. package/coverage/lcov-report/lib/watt-time/index.ts.html +829 -0
  208. package/coverage/lcov-report/prettify.css +1 -0
  209. package/coverage/lcov-report/prettify.js +2 -0
  210. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  211. package/coverage/lcov-report/sorter.js +196 -0
  212. package/coverage/lcov-report/types/common.ts.html +109 -0
  213. package/coverage/lcov-report/types/index.html +116 -0
  214. package/coverage/lcov-report/util/args.ts.html +244 -0
  215. package/coverage/lcov-report/util/index.html +176 -0
  216. package/coverage/lcov-report/util/models-universe.ts.html +679 -0
  217. package/coverage/lcov-report/util/observatory.ts.html +229 -0
  218. package/coverage/lcov-report/util/supercomputer.ts.html +466 -0
  219. package/coverage/lcov-report/util/yaml.ts.html +193 -0
  220. package/coverage/lcov.info +2094 -0
  221. package/docs/implementations/tdp-finder.md +36 -0
  222. package/examples/impls/case-studies/accenture.yml +155 -0
  223. package/examples/impls/case-studies/aveva.yaml +48 -0
  224. package/examples/impls/case-studies/azure-yassine.yaml +67 -0
  225. package/examples/impls/case-studies/boavizta.yml +26 -0
  226. package/examples/impls/case-studies/dow_msft.yml +173 -0
  227. package/examples/impls/case-studies/farm-insights.yaml +35 -0
  228. package/examples/impls/case-studies/gsf-website.yaml +93 -0
  229. package/examples/impls/case-studies/msft-eshoppen.yaml +162 -0
  230. package/examples/impls/case-studies/msft-green-ai.yaml +58 -0
  231. package/examples/impls/case-studies/ntt-data-on-premise.yaml +201 -0
  232. package/examples/impls/tdp-finder-test.yml +19 -0
  233. package/examples/impls/test/azure.yml +26 -0
  234. package/examples/impls/test/ccf.yml +19 -0
  235. package/examples/impls/test/complex-pipeline.yml +67 -0
  236. package/examples/impls/test/if-demo.yml +51 -0
  237. package/examples/impls/test/metadata.yml +20 -0
  238. package/examples/impls/test/nesting.yml +65 -0
  239. package/examples/impls/test/sci-e.yml +21 -0
  240. package/examples/impls/test/sci-m.yml +24 -0
  241. package/examples/impls/test/sci-o.yml +28 -0
  242. package/examples/impls/test/sci.yml +27 -0
  243. package/examples/impls/test/shell.yml +18 -0
  244. package/examples/impls/test/toto.yaml +22 -0
  245. package/examples/ompls/azure.yml +145 -0
  246. package/examples/ompls/ccf.yml +27 -0
  247. package/examples/ompls/complex-pipeline.yml +105 -0
  248. package/examples/ompls/full-sci.yml +64 -0
  249. package/examples/ompls/if-demo.yml +493 -0
  250. package/examples/ompls/metadata.yml +29 -0
  251. package/examples/ompls/nesting.yml +107 -0
  252. package/examples/ompls/sci-e.yml +23 -0
  253. package/examples/ompls/sci-m.yml +33 -0
  254. package/examples/ompls/sci-o.yml +29 -0
  255. package/examples/ompls/sci.yml +36 -0
  256. package/examples/ompls/shell.yml +23 -0
  257. package/jest.config.js +14 -0
  258. package/package.json +71 -0
  259. package/scripts/impact-test.sh +12 -0
  260. package/src/__mocks__/boavizta/countries.json +138 -0
  261. package/src/__mocks__/boavizta/instance_types.json +625 -0
  262. package/src/__mocks__/boavizta/providers.json +1 -0
  263. package/src/__mocks__/watt-time/data.json +119 -0
  264. package/src/config/units.yaml +125 -0
  265. package/src/lib/ccf/aws-embodied.json +5591 -0
  266. package/src/lib/ccf/aws-instances.json +21116 -0
  267. package/src/lib/ccf/aws-use.json +79 -0
  268. package/src/lib/ccf/azure-embodied.json +6547 -0
  269. package/src/lib/ccf/azure-instances.json +8332 -0
  270. package/src/lib/ccf/azure-use.json +58 -0
  271. package/src/lib/ccf/gcp-embodied.json +3049 -0
  272. package/src/lib/ccf/gcp-instances.json +3880 -0
  273. package/src/lib/ccf/gcp-use.json +58 -0
  274. package/src/lib/cloud-instance-metadata/aws-instances.json +1 -0
  275. package/src/lib/cloud-instance-metadata/azure-instances.json +1 -0
  276. package/src/lib/shell-imp/sampler +30 -0
  277. package/src/lib/tdp-finder/README.md +7 -0
  278. package/src/lib/tdp-finder/boavizta_data.csv +1768 -0
  279. package/src/lib/tdp-finder/data.csv +4460 -0
  280. package/src/lib/tdp-finder/data2.csv +2162 -0
  281. package/src/lib/teads-aws/aws-embodied.json +1 -0
  282. package/src/lib/teads-aws/aws-instances.json +1 -0
  283. package/tsconfig.test.json +39 -0
  284. package/tsconfig.tsbuildinfo +1 -0
  285. package/yarn-error.log +5854 -0
@@ -0,0 +1,829 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for lib/watt-time/index.ts</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../../prettify.css" />
9
+ <link rel="stylesheet" href="../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../../index.html">All files</a> / <a href="index.html">lib/watt-time</a> index.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">78.78% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>78/99</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">45.45% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>25/55</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">88.23% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>15/17</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">78.57% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>77/98</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input oninput="onInput()" type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line medium'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a>
275
+ <a name='L210'></a><a href='#L210'>210</a>
276
+ <a name='L211'></a><a href='#L211'>211</a>
277
+ <a name='L212'></a><a href='#L212'>212</a>
278
+ <a name='L213'></a><a href='#L213'>213</a>
279
+ <a name='L214'></a><a href='#L214'>214</a>
280
+ <a name='L215'></a><a href='#L215'>215</a>
281
+ <a name='L216'></a><a href='#L216'>216</a>
282
+ <a name='L217'></a><a href='#L217'>217</a>
283
+ <a name='L218'></a><a href='#L218'>218</a>
284
+ <a name='L219'></a><a href='#L219'>219</a>
285
+ <a name='L220'></a><a href='#L220'>220</a>
286
+ <a name='L221'></a><a href='#L221'>221</a>
287
+ <a name='L222'></a><a href='#L222'>222</a>
288
+ <a name='L223'></a><a href='#L223'>223</a>
289
+ <a name='L224'></a><a href='#L224'>224</a>
290
+ <a name='L225'></a><a href='#L225'>225</a>
291
+ <a name='L226'></a><a href='#L226'>226</a>
292
+ <a name='L227'></a><a href='#L227'>227</a>
293
+ <a name='L228'></a><a href='#L228'>228</a>
294
+ <a name='L229'></a><a href='#L229'>229</a>
295
+ <a name='L230'></a><a href='#L230'>230</a>
296
+ <a name='L231'></a><a href='#L231'>231</a>
297
+ <a name='L232'></a><a href='#L232'>232</a>
298
+ <a name='L233'></a><a href='#L233'>233</a>
299
+ <a name='L234'></a><a href='#L234'>234</a>
300
+ <a name='L235'></a><a href='#L235'>235</a>
301
+ <a name='L236'></a><a href='#L236'>236</a>
302
+ <a name='L237'></a><a href='#L237'>237</a>
303
+ <a name='L238'></a><a href='#L238'>238</a>
304
+ <a name='L239'></a><a href='#L239'>239</a>
305
+ <a name='L240'></a><a href='#L240'>240</a>
306
+ <a name='L241'></a><a href='#L241'>241</a>
307
+ <a name='L242'></a><a href='#L242'>242</a>
308
+ <a name='L243'></a><a href='#L243'>243</a>
309
+ <a name='L244'></a><a href='#L244'>244</a>
310
+ <a name='L245'></a><a href='#L245'>245</a>
311
+ <a name='L246'></a><a href='#L246'>246</a>
312
+ <a name='L247'></a><a href='#L247'>247</a>
313
+ <a name='L248'></a><a href='#L248'>248</a>
314
+ <a name='L249'></a><a href='#L249'>249</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">3x</span>
315
+ <span class="cline-any cline-yes">3x</span>
316
+ <span class="cline-any cline-neutral">&nbsp;</span>
317
+ <span class="cline-any cline-neutral">&nbsp;</span>
318
+ <span class="cline-any cline-neutral">&nbsp;</span>
319
+ <span class="cline-any cline-yes">3x</span>
320
+ <span class="cline-any cline-neutral">&nbsp;</span>
321
+ <span class="cline-any cline-neutral">&nbsp;</span>
322
+ <span class="cline-any cline-neutral">&nbsp;</span>
323
+ <span class="cline-any cline-yes">3x</span>
324
+ <span class="cline-any cline-yes">3x</span>
325
+ <span class="cline-any cline-neutral">&nbsp;</span>
326
+ <span class="cline-any cline-yes">3x</span>
327
+ <span class="cline-any cline-yes">1x</span>
328
+ <span class="cline-any cline-yes">1x</span>
329
+ <span class="cline-any cline-neutral">&nbsp;</span>
330
+ <span class="cline-any cline-neutral">&nbsp;</span>
331
+ <span class="cline-any cline-yes">1x</span>
332
+ <span class="cline-any cline-neutral">&nbsp;</span>
333
+ <span class="cline-any cline-neutral">&nbsp;</span>
334
+ <span class="cline-any cline-yes">1x</span>
335
+ <span class="cline-any cline-yes">1x</span>
336
+ <span class="cline-any cline-no">&nbsp;</span>
337
+ <span class="cline-any cline-neutral">&nbsp;</span>
338
+ <span class="cline-any cline-yes">1x</span>
339
+ <span class="cline-any cline-neutral">&nbsp;</span>
340
+ <span class="cline-any cline-neutral">&nbsp;</span>
341
+ <span class="cline-any cline-yes">1x</span>
342
+ <span class="cline-any cline-neutral">&nbsp;</span>
343
+ <span class="cline-any cline-yes">1x</span>
344
+ <span class="cline-any cline-neutral">&nbsp;</span>
345
+ <span class="cline-any cline-neutral">&nbsp;</span>
346
+ <span class="cline-any cline-yes">1x</span>
347
+ <span class="cline-any cline-no">&nbsp;</span>
348
+ <span class="cline-any cline-neutral">&nbsp;</span>
349
+ <span class="cline-any cline-neutral">&nbsp;</span>
350
+ <span class="cline-any cline-yes">1x</span>
351
+ <span class="cline-any cline-no">&nbsp;</span>
352
+ <span class="cline-any cline-neutral">&nbsp;</span>
353
+ <span class="cline-any cline-neutral">&nbsp;</span>
354
+ <span class="cline-any cline-neutral">&nbsp;</span>
355
+ <span class="cline-any cline-yes">1x</span>
356
+ <span class="cline-any cline-no">&nbsp;</span>
357
+ <span class="cline-any cline-neutral">&nbsp;</span>
358
+ <span class="cline-any cline-neutral">&nbsp;</span>
359
+ <span class="cline-any cline-neutral">&nbsp;</span>
360
+ <span class="cline-any cline-yes">1x</span>
361
+ <span class="cline-any cline-neutral">&nbsp;</span>
362
+ <span class="cline-any cline-neutral">&nbsp;</span>
363
+ <span class="cline-any cline-neutral">&nbsp;</span>
364
+ <span class="cline-any cline-neutral">&nbsp;</span>
365
+ <span class="cline-any cline-neutral">&nbsp;</span>
366
+ <span class="cline-any cline-yes">1x</span>
367
+ <span class="cline-any cline-neutral">&nbsp;</span>
368
+ <span class="cline-any cline-neutral">&nbsp;</span>
369
+ <span class="cline-any cline-neutral">&nbsp;</span>
370
+ <span class="cline-any cline-neutral">&nbsp;</span>
371
+ <span class="cline-any cline-no">&nbsp;</span>
372
+ <span class="cline-any cline-neutral">&nbsp;</span>
373
+ <span class="cline-any cline-neutral">&nbsp;</span>
374
+ <span class="cline-any cline-neutral">&nbsp;</span>
375
+ <span class="cline-any cline-yes">1x</span>
376
+ <span class="cline-any cline-neutral">&nbsp;</span>
377
+ <span class="cline-any cline-neutral">&nbsp;</span>
378
+ <span class="cline-any cline-neutral">&nbsp;</span>
379
+ <span class="cline-any cline-neutral">&nbsp;</span>
380
+ <span class="cline-any cline-yes">5x</span>
381
+ <span class="cline-any cline-no">&nbsp;</span>
382
+ <span class="cline-any cline-neutral">&nbsp;</span>
383
+ <span class="cline-any cline-neutral">&nbsp;</span>
384
+ <span class="cline-any cline-yes">5x</span>
385
+ <span class="cline-any cline-neutral">&nbsp;</span>
386
+ <span class="cline-any cline-yes">5x</span>
387
+ <span class="cline-any cline-neutral">&nbsp;</span>
388
+ <span class="cline-any cline-yes">5x</span>
389
+ <span class="cline-any cline-neutral">&nbsp;</span>
390
+ <span class="cline-any cline-neutral">&nbsp;</span>
391
+ <span class="cline-any cline-neutral">&nbsp;</span>
392
+ <span class="cline-any cline-neutral">&nbsp;</span>
393
+ <span class="cline-any cline-neutral">&nbsp;</span>
394
+ <span class="cline-any cline-yes">5x</span>
395
+ <span class="cline-any cline-yes">6x</span>
396
+ <span class="cline-any cline-yes">6x</span>
397
+ <span class="cline-any cline-yes">6x</span>
398
+ <span class="cline-any cline-neutral">&nbsp;</span>
399
+ <span class="cline-any cline-neutral">&nbsp;</span>
400
+ <span class="cline-any cline-neutral">&nbsp;</span>
401
+ <span class="cline-any cline-neutral">&nbsp;</span>
402
+ <span class="cline-any cline-yes">78x</span>
403
+ <span class="cline-any cline-yes">6x</span>
404
+ <span class="cline-any cline-yes">1x</span>
405
+ <span class="cline-any cline-neutral">&nbsp;</span>
406
+ <span class="cline-any cline-neutral">&nbsp;</span>
407
+ <span class="cline-any cline-neutral">&nbsp;</span>
408
+ <span class="cline-any cline-yes">5x</span>
409
+ <span class="cline-any cline-neutral">&nbsp;</span>
410
+ <span class="cline-any cline-neutral">&nbsp;</span>
411
+ <span class="cline-any cline-yes">4x</span>
412
+ <span class="cline-any cline-neutral">&nbsp;</span>
413
+ <span class="cline-any cline-neutral">&nbsp;</span>
414
+ <span class="cline-any cline-neutral">&nbsp;</span>
415
+ <span class="cline-any cline-neutral">&nbsp;</span>
416
+ <span class="cline-any cline-neutral">&nbsp;</span>
417
+ <span class="cline-any cline-neutral">&nbsp;</span>
418
+ <span class="cline-any cline-neutral">&nbsp;</span>
419
+ <span class="cline-any cline-yes">6x</span>
420
+ <span class="cline-any cline-yes">6x</span>
421
+ <span class="cline-any cline-neutral">&nbsp;</span>
422
+ <span class="cline-any cline-neutral">&nbsp;</span>
423
+ <span class="cline-any cline-yes">78x</span>
424
+ <span class="cline-any cline-yes">13x</span>
425
+ <span class="cline-any cline-neutral">&nbsp;</span>
426
+ <span class="cline-any cline-neutral">&nbsp;</span>
427
+ <span class="cline-any cline-neutral">&nbsp;</span>
428
+ <span class="cline-any cline-yes">65x</span>
429
+ <span class="cline-any cline-neutral">&nbsp;</span>
430
+ <span class="cline-any cline-neutral">&nbsp;</span>
431
+ <span class="cline-any cline-neutral">&nbsp;</span>
432
+ <span class="cline-any cline-yes">45x</span>
433
+ <span class="cline-any cline-neutral">&nbsp;</span>
434
+ <span class="cline-any cline-neutral">&nbsp;</span>
435
+ <span class="cline-any cline-neutral">&nbsp;</span>
436
+ <span class="cline-any cline-neutral">&nbsp;</span>
437
+ <span class="cline-any cline-neutral">&nbsp;</span>
438
+ <span class="cline-any cline-neutral">&nbsp;</span>
439
+ <span class="cline-any cline-yes">20x</span>
440
+ <span class="cline-any cline-yes">20x</span>
441
+ <span class="cline-any cline-yes">20x</span>
442
+ <span class="cline-any cline-neutral">&nbsp;</span>
443
+ <span class="cline-any cline-yes">6x</span>
444
+ <span class="cline-any cline-neutral">&nbsp;</span>
445
+ <span class="cline-any cline-neutral">&nbsp;</span>
446
+ <span class="cline-any cline-neutral">&nbsp;</span>
447
+ <span class="cline-any cline-yes">5x</span>
448
+ <span class="cline-any cline-yes">6x</span>
449
+ <span class="cline-any cline-no">&nbsp;</span>
450
+ <span class="cline-any cline-no">&nbsp;</span>
451
+ <span class="cline-any cline-no">&nbsp;</span>
452
+ <span class="cline-any cline-neutral">&nbsp;</span>
453
+ <span class="cline-any cline-neutral">&nbsp;</span>
454
+ <span class="cline-any cline-yes">6x</span>
455
+ <span class="cline-any cline-no">&nbsp;</span>
456
+ <span class="cline-any cline-neutral">&nbsp;</span>
457
+ <span class="cline-any cline-yes">6x</span>
458
+ <span class="cline-any cline-no">&nbsp;</span>
459
+ <span class="cline-any cline-neutral">&nbsp;</span>
460
+ <span class="cline-any cline-neutral">&nbsp;</span>
461
+ <span class="cline-any cline-neutral">&nbsp;</span>
462
+ <span class="cline-any cline-neutral">&nbsp;</span>
463
+ <span class="cline-any cline-neutral">&nbsp;</span>
464
+ <span class="cline-any cline-yes">5x</span>
465
+ <span class="cline-any cline-yes">5x</span>
466
+ <span class="cline-any cline-no">&nbsp;</span>
467
+ <span class="cline-any cline-neutral">&nbsp;</span>
468
+ <span class="cline-any cline-neutral">&nbsp;</span>
469
+ <span class="cline-any cline-neutral">&nbsp;</span>
470
+ <span class="cline-any cline-yes">5x</span>
471
+ <span class="cline-any cline-no">&nbsp;</span>
472
+ <span class="cline-any cline-neutral">&nbsp;</span>
473
+ <span class="cline-any cline-yes">5x</span>
474
+ <span class="cline-any cline-no">&nbsp;</span>
475
+ <span class="cline-any cline-neutral">&nbsp;</span>
476
+ <span class="cline-any cline-yes">5x</span>
477
+ <span class="cline-any cline-yes">5x</span>
478
+ <span class="cline-any cline-yes">5x</span>
479
+ <span class="cline-any cline-neutral">&nbsp;</span>
480
+ <span class="cline-any cline-neutral">&nbsp;</span>
481
+ <span class="cline-any cline-neutral">&nbsp;</span>
482
+ <span class="cline-any cline-neutral">&nbsp;</span>
483
+ <span class="cline-any cline-yes">5x</span>
484
+ <span class="cline-any cline-neutral">&nbsp;</span>
485
+ <span class="cline-any cline-yes">5x</span>
486
+ <span class="cline-any cline-yes">5x</span>
487
+ <span class="cline-any cline-yes">6x</span>
488
+ <span class="cline-any cline-neutral">&nbsp;</span>
489
+ <span class="cline-any cline-neutral">&nbsp;</span>
490
+ <span class="cline-any cline-yes">6x</span>
491
+ <span class="cline-any cline-neutral">&nbsp;</span>
492
+ <span class="cline-any cline-neutral">&nbsp;</span>
493
+ <span class="cline-any cline-neutral">&nbsp;</span>
494
+ <span class="cline-any cline-neutral">&nbsp;</span>
495
+ <span class="cline-any cline-yes">6x</span>
496
+ <span class="cline-any cline-neutral">&nbsp;</span>
497
+ <span class="cline-any cline-neutral">&nbsp;</span>
498
+ <span class="cline-any cline-neutral">&nbsp;</span>
499
+ <span class="cline-any cline-yes">5x</span>
500
+ <span class="cline-any cline-yes">5x</span>
501
+ <span class="cline-any cline-no">&nbsp;</span>
502
+ <span class="cline-any cline-neutral">&nbsp;</span>
503
+ <span class="cline-any cline-neutral">&nbsp;</span>
504
+ <span class="cline-any cline-neutral">&nbsp;</span>
505
+ <span class="cline-any cline-neutral">&nbsp;</span>
506
+ <span class="cline-any cline-neutral">&nbsp;</span>
507
+ <span class="cline-any cline-yes">5x</span>
508
+ <span class="cline-any cline-neutral">&nbsp;</span>
509
+ <span class="cline-any cline-neutral">&nbsp;</span>
510
+ <span class="cline-any cline-neutral">&nbsp;</span>
511
+ <span class="cline-any cline-yes">5x</span>
512
+ <span class="cline-any cline-neutral">&nbsp;</span>
513
+ <span class="cline-any cline-yes">5x</span>
514
+ <span class="cline-any cline-no">&nbsp;</span>
515
+ <span class="cline-any cline-neutral">&nbsp;</span>
516
+ <span class="cline-any cline-yes">5x</span>
517
+ <span class="cline-any cline-neutral">&nbsp;</span>
518
+ <span class="cline-any cline-yes">5x</span>
519
+ <span class="cline-any cline-neutral">&nbsp;</span>
520
+ <span class="cline-any cline-neutral">&nbsp;</span>
521
+ <span class="cline-any cline-neutral">&nbsp;</span>
522
+ <span class="cline-any cline-neutral">&nbsp;</span>
523
+ <span class="cline-any cline-neutral">&nbsp;</span>
524
+ <span class="cline-any cline-yes">5x</span>
525
+ <span class="cline-any cline-neutral">&nbsp;</span>
526
+ <span class="cline-any cline-neutral">&nbsp;</span>
527
+ <span class="cline-any cline-neutral">&nbsp;</span>
528
+ <span class="cline-any cline-neutral">&nbsp;</span>
529
+ <span class="cline-any cline-neutral">&nbsp;</span>
530
+ <span class="cline-any cline-neutral">&nbsp;</span>
531
+ <span class="cline-any cline-neutral">&nbsp;</span>
532
+ <span class="cline-any cline-no">&nbsp;</span>
533
+ <span class="cline-any cline-neutral">&nbsp;</span>
534
+ <span class="cline-any cline-yes">5x</span>
535
+ <span class="cline-any cline-no">&nbsp;</span>
536
+ <span class="cline-any cline-neutral">&nbsp;</span>
537
+ <span class="cline-any cline-yes">5x</span>
538
+ <span class="cline-any cline-no">&nbsp;</span>
539
+ <span class="cline-any cline-neutral">&nbsp;</span>
540
+ <span class="cline-any cline-yes">5x</span>
541
+ <span class="cline-any cline-yes">60x</span>
542
+ <span class="cline-any cline-neutral">&nbsp;</span>
543
+ <span class="cline-any cline-neutral">&nbsp;</span>
544
+ <span class="cline-any cline-neutral">&nbsp;</span>
545
+ <span class="cline-any cline-neutral">&nbsp;</span>
546
+ <span class="cline-any cline-neutral">&nbsp;</span>
547
+ <span class="cline-any cline-neutral">&nbsp;</span>
548
+ <span class="cline-any cline-neutral">&nbsp;</span>
549
+ <span class="cline-any cline-yes">1x</span>
550
+ <span class="cline-any cline-yes">1x</span>
551
+ <span class="cline-any cline-yes">1x</span>
552
+ <span class="cline-any cline-no">&nbsp;</span>
553
+ <span class="cline-any cline-neutral">&nbsp;</span>
554
+ <span class="cline-any cline-yes">1x</span>
555
+ <span class="cline-any cline-yes">1x</span>
556
+ <span class="cline-any cline-neutral">&nbsp;</span>
557
+ <span class="cline-any cline-neutral">&nbsp;</span>
558
+ <span class="cline-any cline-neutral">&nbsp;</span>
559
+ <span class="cline-any cline-no">&nbsp;</span>
560
+ <span class="cline-any cline-neutral">&nbsp;</span>
561
+ <span class="cline-any cline-neutral">&nbsp;</span>
562
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import axios from 'axios';
563
+ import * as dayjs from 'dayjs';
564
+ &nbsp;
565
+ import {IOutputModelInterface} from '../interfaces';
566
+ &nbsp;
567
+ import {CONFIG} from '../../config';
568
+ &nbsp;
569
+ import {KeyValuePair} from '../../types/common';
570
+ &nbsp;
571
+ const {MODEL_IDS} = CONFIG;
572
+ const {WATT_TIME} = MODEL_IDS;
573
+ &nbsp;
574
+ export class WattTimeGridEmissions implements IOutputModelInterface {
575
+ authParams: object | undefined = undefined;
576
+ token = '';
577
+ staticParams: object | undefined;
578
+ name: string | undefined;
579
+ baseUrl = 'https://api2.watttime.org/v2';
580
+ &nbsp;
581
+ async authenticate(authParams: object): Promise&lt;void&gt; {
582
+ this.token = 'token' in authParams ? (<span class="branch-0 cbranch-no" title="branch not covered" >authParams['token'] as string) </span>: '';
583
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (this.token.startsWith('ENV_')) {
584
+ <span class="cstat-no" title="statement not covered" > this.token = process.env[this.token.slice(4)] ?? '';</span>
585
+ }
586
+ if (this.token === '') {
587
+ // Extracting username and password from authParams
588
+ let username =
589
+ 'username' in authParams ? (authParams['username'] as string) : <span class="branch-1 cbranch-no" title="branch not covered" >'';</span>
590
+ let password =
591
+ 'password' in authParams ? (authParams['password'] as string) : <span class="branch-1 cbranch-no" title="branch not covered" >'';</span>
592
+ &nbsp;
593
+ // if username or password is ENV_&lt;env_var_name&gt;, then extract the value from the environment variable
594
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (username.startsWith('ENV_')) {
595
+ <span class="cstat-no" title="statement not covered" > username = process.env[username.slice(4)] ?? '';</span>
596
+ }
597
+ &nbsp;
598
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (password.startsWith('ENV_')) {
599
+ <span class="cstat-no" title="statement not covered" > password = process.env[password.slice(4)] ?? '';</span>
600
+ }
601
+ &nbsp;
602
+ // WattTime API requires username and password / token
603
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (username === '' || password === '') {
604
+ <span class="cstat-no" title="statement not covered" > throw new Error('Missing username or password &amp; token');</span>
605
+ }
606
+ &nbsp;
607
+ // Login to WattTime API to get a token
608
+ const tokenResponse = await axios.get(`${this.baseUrl}/login`, {
609
+ auth: {
610
+ username,
611
+ password,
612
+ },
613
+ });
614
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (
615
+ tokenResponse === undefined ||
616
+ tokenResponse.data === undefined ||
617
+ !('token' in tokenResponse.data)
618
+ ) {
619
+ <span class="cstat-no" title="statement not covered" > throw new Error(</span>
620
+ 'Missing token in response. Invalid credentials provided.'
621
+ );
622
+ }
623
+ this.token = tokenResponse.data.token;
624
+ }
625
+ }
626
+ &nbsp;
627
+ async execute(inputs: object | object[] | undefined): Promise&lt;any[]&gt; {
628
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!Array.isArray(inputs)) {
629
+ <span class="cstat-no" title="statement not covered" > throw new Error('inputs should be an array');</span>
630
+ }
631
+ // validate inputs for location data + timestamp + duration
632
+ this.validateinputs(inputs);
633
+ // determine the earliest start and total duration of all input blocks
634
+ const {startTime, fetchDuration} = this.determineinputStartEnd(inputs);
635
+ // fetch data from WattTime API for the entire duration
636
+ const wattimedata = await this.fetchData({
637
+ timestamp: startTime.format(),
638
+ duration: fetchDuration,
639
+ ...inputs[0],
640
+ });
641
+ // for each input block, calculate the average emission
642
+ inputs.map((input: KeyValuePair) =&gt; {
643
+ const inputStart = dayjs(input.timestamp);
644
+ const inputEnd = inputStart.add(input.duration, 'seconds');
645
+ const {datapoints, data} = this.getWattTimeDataForDuration(
646
+ wattimedata,
647
+ inputStart,
648
+ inputEnd
649
+ );
650
+ const emissionSum = data.reduce((a: number, b: number) =&gt; a + b, 0);
651
+ if (datapoints === 0) {
652
+ throw new Error(
653
+ 'Did not receive data from WattTime API for the input block.'
654
+ );
655
+ }
656
+ input['grid-carbon-intensity'] = emissionSum / datapoints;
657
+ });
658
+ &nbsp;
659
+ return inputs;
660
+ }
661
+ &nbsp;
662
+ private getWattTimeDataForDuration(
663
+ wattimedata: KeyValuePair[],
664
+ inputStart: dayjs.Dayjs,
665
+ inputEnd: dayjs.Dayjs
666
+ ): {datapoints: number; data: number[]} {
667
+ let datapoints = 0;
668
+ const data = wattimedata.map((data: KeyValuePair) =&gt; {
669
+ // WattTime API returns full data for the entire duration.
670
+ // if the data point is before the input start, ignore it
671
+ if (dayjs(data.point_time).isBefore(inputStart)) {
672
+ return 0;
673
+ }
674
+ // if the data point is after the input end, ignore it.
675
+ // if the data point is exactly the same as the input end, ignore it
676
+ if (
677
+ dayjs(data.point_time).isAfter(inputEnd) ||
678
+ dayjs(data.point_time).format() === dayjs(inputEnd).format()
679
+ ) {
680
+ return 0;
681
+ }
682
+ // lbs/MWh to Kg/MWh by dividing by 0.453592 (0.453592 Kg/lbs)
683
+ // (Kg/MWh == g/kWh)
684
+ // convert to kg/KWh by dividing by 1000. (1MWh = 1000KWh)
685
+ // convert to g/KWh by multiplying by 1000. (1Kg = 1000g)
686
+ // hence each other cancel out and g/KWh is the same as kg/MWh
687
+ const grid_emission = data.value / 0.45359237;
688
+ datapoints += 1;
689
+ return grid_emission;
690
+ });
691
+ return {datapoints, data};
692
+ }
693
+ &nbsp;
694
+ private validateinputs(inputs: object[]) {
695
+ inputs.forEach((input: KeyValuePair) =&gt; {
696
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!('location' in input)) {
697
+ const {latitude, longitude} = <span class="cstat-no" title="statement not covered" >this.getLatitudeLongitudeFrominput(input);</span>
698
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (isNaN(latitude) || isNaN(longitude)) {</span>
699
+ <span class="cstat-no" title="statement not covered" > throw new Error('latitude or longitude is not a number');</span>
700
+ }
701
+ }
702
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!('timestamp' in input)) {
703
+ <span class="cstat-no" title="statement not covered" > throw new Error('timestamp is missing');</span>
704
+ }
705
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!('duration' in input)) {
706
+ <span class="cstat-no" title="statement not covered" > throw new Error('duration is missing');</span>
707
+ }
708
+ });
709
+ }
710
+ &nbsp;
711
+ private getLatitudeLongitudeFrominput(input: KeyValuePair) {
712
+ const location = input['location'].split(','); //split location into latitude and longitude
713
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (location.length !== 2) {
714
+ <span class="cstat-no" title="statement not covered" > throw new Error(</span>
715
+ 'location should be a comma separated string of latitude and longitude'
716
+ );
717
+ }
718
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (location[0] === '' || location[1] === '') {
719
+ <span class="cstat-no" title="statement not covered" > throw new Error('latitude or longitude is missing');</span>
720
+ }
721
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (location[0] === '0' || location[1] === '0') {
722
+ <span class="cstat-no" title="statement not covered" > throw new Error('latitude or longitude is missing');</span>
723
+ }
724
+ const latitude = parseFloat(location[0]); //convert latitude to float
725
+ const longitude = parseFloat(location[1]); //convert longitude to float
726
+ return {latitude, longitude};
727
+ }
728
+ &nbsp;
729
+ private determineinputStartEnd(inputs: object[]) {
730
+ // largest possible start time
731
+ let starttime = dayjs('9999-12-31');
732
+ // smallest possible end time
733
+ let endtime = dayjs('1970-01-01');
734
+ inputs.forEach((input: KeyValuePair) =&gt; {
735
+ const duration = input.duration;
736
+ &nbsp;
737
+ // if the input timestamp is before the current starttime, set it as the new starttime
738
+ starttime = dayjs(input.timestamp).isBefore(starttime)
739
+ ? dayjs(input.timestamp)
740
+ : starttime;
741
+ &nbsp;
742
+ // if the input timestamp + duration is after the current endtime, set it as the new endtime
743
+ endtime = dayjs(input.timestamp).add(duration, 'seconds').isAfter(endtime)
744
+ ? dayjs(input.timestamp).add(duration, 'seconds')
745
+ : <span class="branch-1 cbranch-no" title="branch not covered" >endtime;</span>
746
+ });
747
+ const fetchDuration = endtime.diff(starttime, 'seconds');
748
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (fetchDuration &gt; 32 * 24 * 60 * 60) {
749
+ <span class="cstat-no" title="statement not covered" > throw new Error(</span>
750
+ 'duration is too long.WattTime API only supports up to 32 days. All inputs must be within 32 days of each other. Duration of ' +
751
+ fetchDuration +
752
+ ' seconds is too long.'
753
+ );
754
+ }
755
+ return {startTime: starttime, fetchDuration};
756
+ }
757
+ &nbsp;
758
+ async fetchData(input: KeyValuePair): Promise&lt;KeyValuePair[]&gt; {
759
+ const duration = input.duration;
760
+ // WattTime API only supports up to 32 days
761
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (duration &gt; 32 * 24 * 60 * 60) {
762
+ <span class="cstat-no" title="statement not covered" > throw new Error('duration is too long');</span>
763
+ }
764
+ const {latitude, longitude} = this.getLatitudeLongitudeFrominput(input);
765
+ &nbsp;
766
+ const params = {
767
+ latitude: latitude,
768
+ longitude: longitude,
769
+ starttime: dayjs(input.timestamp).format('YYYY-MM-DDTHH:mm:ssZ'),
770
+ endtime: dayjs(input.timestamp).add(duration, 'seconds'),
771
+ };
772
+ const result = await axios
773
+ .get(`${this.baseUrl}/data`, {
774
+ params,
775
+ headers: {
776
+ Authorization: `Bearer ${this.token}`,
777
+ },
778
+ })
779
+ .catch(<span class="fstat-no" title="function not covered" >e </span>=&gt; {
780
+ <span class="cstat-no" title="statement not covered" > throw new Error('Error fetching data from WattTime API.' + e);</span>
781
+ });
782
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (result.status !== 200) {
783
+ <span class="cstat-no" title="statement not covered" > throw new Error('Error fetching data from WattTime API.' + result.status);</span>
784
+ }
785
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!('data' in result) || !Array.isArray(result.data)) {
786
+ <span class="cstat-no" title="statement not covered" > throw new Error('Invalid response from WattTime API.');</span>
787
+ }
788
+ return result.data.sort((a: any, b: any) =&gt; {
789
+ return dayjs(a.point_time).unix() &gt; dayjs(b.point_time).unix() ? 1 : -1;
790
+ });
791
+ }
792
+ &nbsp;
793
+ async configure(
794
+ name: string,
795
+ staticParams: object | undefined
796
+ ): Promise&lt;IOutputModelInterface&gt; {
797
+ this.staticParams = staticParams;
798
+ this.name = name;
799
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!staticParams) {
800
+ <span class="cstat-no" title="statement not covered" > throw new Error('Missing staticParams');</span>
801
+ }
802
+ await this.authenticate(staticParams);
803
+ return this;
804
+ }
805
+ &nbsp;
806
+ <span class="fstat-no" title="function not covered" > modelIdentifier(</span>): string {
807
+ <span class="cstat-no" title="statement not covered" > return WATT_TIME;</span>
808
+ }
809
+ }
810
+ &nbsp;</pre></td></tr></table></pre>
811
+
812
+ <div class='push'></div><!-- for sticky footer -->
813
+ </div><!-- /wrapper -->
814
+ <div class='footer quiet pad2 space-top1 center small'>
815
+ Code coverage generated by
816
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
817
+ at 2023-11-01T14:37:41.749Z
818
+ </div>
819
+ <script src="../../prettify.js"></script>
820
+ <script>
821
+ window.onload = function () {
822
+ prettyPrint();
823
+ };
824
+ </script>
825
+ <script src="../../sorter.js"></script>
826
+ <script src="../../block-navigation.js"></script>
827
+ </body>
828
+ </html>
829
+