@rabbitio/ui-kit 1.0.0-beta.43 → 1.0.0-beta.45

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 (113) hide show
  1. package/.husky/pre-push +1 -1
  2. package/dist/index.cjs +1389 -102
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.css +23630 -0
  5. package/dist/index.css.map +1 -1
  6. package/dist/index.modern.js +1185 -57
  7. package/dist/index.modern.js.map +1 -1
  8. package/dist/index.module.js +1379 -103
  9. package/dist/index.module.js.map +1 -1
  10. package/dist/index.umd.js +1388 -106
  11. package/dist/index.umd.js.map +1 -1
  12. package/package.json +6 -1
  13. package/src/assets/image/icons/arrow-tosca.svg +3 -0
  14. package/src/assets/image/icons/arrow-white.svg +14 -0
  15. package/src/assets/image/icons/failed-validation-icon.svg +15 -0
  16. package/src/assets/image/icons/successful-validation-icon.svg +10 -0
  17. package/src/components/atoms/BackgroundTitle/BackgroundTitle.jsx +44 -0
  18. package/src/components/atoms/BackgroundTitle/background-title.module.scss +52 -0
  19. package/src/components/atoms/Validation/Validation.jsx +130 -0
  20. package/src/components/atoms/Validation/validation.module.scss +15 -0
  21. package/src/components/atoms/buttons/Close/Close.jsx +64 -0
  22. package/src/components/atoms/buttons/Close/close.module.scss +75 -0
  23. package/src/components/atoms/buttons/LinkButton/LinkButton.jsx +121 -0
  24. package/src/components/atoms/buttons/LinkButton/link-button.module.scss +45 -0
  25. package/src/components/organisms/Dialog/Dialog.jsx +515 -0
  26. package/src/components/organisms/Dialog/DialogButtons/DialogButtons.jsx +122 -0
  27. package/src/components/organisms/Dialog/DialogButtons/dialog-buttons.module.scss +25 -0
  28. package/src/components/organisms/Dialog/DialogStep/DialogStep.jsx +664 -0
  29. package/src/components/organisms/Dialog/DialogStep/dialog-step.module.scss +362 -0
  30. package/src/components/organisms/Dialog/dialog.module.scss +223 -0
  31. package/src/constants/organisms/dialog/DialogStep/dialogStep.js +1 -0
  32. package/src/constants/organisms/dialog/dialog.js +29 -0
  33. package/src/index.js +10 -0
  34. package/stories/stubs/exampleContent.jsx +20 -0
  35. package/styles/fonts/NunitoSans-Bold.ttf +0 -0
  36. package/styles/fonts/NunitoSans-ExtraBold.ttf +0 -0
  37. package/styles/fonts/NunitoSans-Light.ttf +0 -0
  38. package/styles/fonts/NunitoSans-Regular.ttf +0 -0
  39. package/styles/fonts/NunitoSans-SemiBold.ttf +0 -0
  40. package/styles/index.scss +14 -13
  41. package/coverage/base.css +0 -224
  42. package/coverage/block-navigation.js +0 -87
  43. package/coverage/clover.xml +0 -6516
  44. package/coverage/coverage-final.json +0 -43
  45. package/coverage/favicon.png +0 -0
  46. package/coverage/index.html +0 -416
  47. package/coverage/prettify.css +0 -1
  48. package/coverage/prettify.js +0 -2
  49. package/coverage/rabbit-ui-kit/index.html +0 -116
  50. package/coverage/rabbit-ui-kit/index.js.html +0 -88
  51. package/coverage/rabbit-ui-kit/src/common/adapters/axiosAdapter.js.html +0 -190
  52. package/coverage/rabbit-ui-kit/src/common/adapters/index.html +0 -116
  53. package/coverage/rabbit-ui-kit/src/common/amountUtils.js.html +0 -1393
  54. package/coverage/rabbit-ui-kit/src/common/errorUtils.js.html +0 -211
  55. package/coverage/rabbit-ui-kit/src/common/external-apis/apiGroups.js.html +0 -250
  56. package/coverage/rabbit-ui-kit/src/common/external-apis/index.html +0 -131
  57. package/coverage/rabbit-ui-kit/src/common/external-apis/ipAddressProviders.js.html +0 -499
  58. package/coverage/rabbit-ui-kit/src/common/fiatCurrenciesService.js.html +0 -568
  59. package/coverage/rabbit-ui-kit/src/common/index.html +0 -146
  60. package/coverage/rabbit-ui-kit/src/common/models/blockchain.js.html +0 -115
  61. package/coverage/rabbit-ui-kit/src/common/models/coin.js.html +0 -556
  62. package/coverage/rabbit-ui-kit/src/common/models/index.html +0 -146
  63. package/coverage/rabbit-ui-kit/src/common/models/protocol.js.html +0 -100
  64. package/coverage/rabbit-ui-kit/src/common/utils/cache.js.html +0 -889
  65. package/coverage/rabbit-ui-kit/src/common/utils/emailAPI.js.html +0 -139
  66. package/coverage/rabbit-ui-kit/src/common/utils/index.html +0 -161
  67. package/coverage/rabbit-ui-kit/src/common/utils/logging/index.html +0 -131
  68. package/coverage/rabbit-ui-kit/src/common/utils/logging/logger.js.html +0 -229
  69. package/coverage/rabbit-ui-kit/src/common/utils/logging/logsStorage.js.html +0 -268
  70. package/coverage/rabbit-ui-kit/src/common/utils/postponeExecution.js.html +0 -118
  71. package/coverage/rabbit-ui-kit/src/common/utils/safeStringify.js.html +0 -235
  72. package/coverage/rabbit-ui-kit/src/components/atoms/AssetIcon/AssetIcon.jsx.html +0 -250
  73. package/coverage/rabbit-ui-kit/src/components/atoms/AssetIcon/index.html +0 -116
  74. package/coverage/rabbit-ui-kit/src/components/atoms/LoadingDots/LoadingDots.jsx.html +0 -256
  75. package/coverage/rabbit-ui-kit/src/components/atoms/LoadingDots/index.html +0 -116
  76. package/coverage/rabbit-ui-kit/src/components/atoms/SupportChat/SupportChat.jsx.html +0 -229
  77. package/coverage/rabbit-ui-kit/src/components/atoms/SupportChat/index.html +0 -116
  78. package/coverage/rabbit-ui-kit/src/components/atoms/buttons/Button/Button.jsx.html +0 -802
  79. package/coverage/rabbit-ui-kit/src/components/atoms/buttons/Button/index.html +0 -116
  80. package/coverage/rabbit-ui-kit/src/components/hooks/index.html +0 -131
  81. package/coverage/rabbit-ui-kit/src/components/hooks/useCallHandlingErrors.js.html +0 -163
  82. package/coverage/rabbit-ui-kit/src/components/hooks/useReferredState.js.html +0 -157
  83. package/coverage/rabbit-ui-kit/src/components/utils/index.html +0 -146
  84. package/coverage/rabbit-ui-kit/src/components/utils/inputValueProviders.js.html +0 -259
  85. package/coverage/rabbit-ui-kit/src/components/utils/uiUtils.js.html +0 -127
  86. package/coverage/rabbit-ui-kit/src/components/utils/urlQueryUtils.js.html +0 -346
  87. package/coverage/rabbit-ui-kit/src/index.html +0 -116
  88. package/coverage/rabbit-ui-kit/src/index.js.html +0 -250
  89. package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/cacheAndConcurrentRequestsResolver.js.html +0 -1762
  90. package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/cachedRobustExternalApiCallerService.js.html +0 -649
  91. package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/cancelProcessing.js.html +0 -172
  92. package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/concurrentCalculationsMetadataHolder.js.html +0 -394
  93. package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/externalApiProvider.js.html +0 -553
  94. package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/externalServicesStatsCollector.js.html +0 -331
  95. package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/index.html +0 -206
  96. package/coverage/rabbit-ui-kit/src/robustExteranlApiCallerService/robustExternalAPICallerService.js.html +0 -1249
  97. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/index.html +0 -131
  98. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/swapProvider.js.html +0 -727
  99. package/coverage/rabbit-ui-kit/src/swaps-lib/external-apis/swapspaceSwapProvider.js.html +0 -2899
  100. package/coverage/rabbit-ui-kit/src/swaps-lib/models/baseSwapCreationInfo.js.html +0 -214
  101. package/coverage/rabbit-ui-kit/src/swaps-lib/models/existingSwap.js.html +0 -304
  102. package/coverage/rabbit-ui-kit/src/swaps-lib/models/existingSwapWithFiatData.js.html +0 -487
  103. package/coverage/rabbit-ui-kit/src/swaps-lib/models/index.html +0 -146
  104. package/coverage/rabbit-ui-kit/src/swaps-lib/services/index.html +0 -116
  105. package/coverage/rabbit-ui-kit/src/swaps-lib/services/publicSwapService.js.html +0 -2191
  106. package/coverage/rabbit-ui-kit/src/swaps-lib/utils/index.html +0 -116
  107. package/coverage/rabbit-ui-kit/src/swaps-lib/utils/swapUtils.js.html +0 -742
  108. package/coverage/rabbit-ui-kit/stories/atoms/LoadingDots.stories.jsx.html +0 -226
  109. package/coverage/rabbit-ui-kit/stories/atoms/buttons/Button.stories.jsx.html +0 -946
  110. package/coverage/rabbit-ui-kit/stories/atoms/buttons/index.html +0 -116
  111. package/coverage/rabbit-ui-kit/stories/atoms/index.html +0 -116
  112. package/coverage/sort-arrow-sprite.png +0 -0
  113. package/coverage/sorter.js +0 -196
@@ -1,1762 +0,0 @@
1
-
2
- <!doctype html>
3
- <html lang="en">
4
-
5
- <head>
6
- <title>Code coverage report for rabbit-ui-kit/src/robustExteranlApiCallerService/cacheAndConcurrentRequestsResolver.js</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">rabbit-ui-kit/src/robustExteranlApiCallerService</a> cacheAndConcurrentRequestsResolver.js</h1>
23
- <div class='clearfix'>
24
-
25
- <div class='fl pad1y space-right2'>
26
- <span class="strong">59.21% </span>
27
- <span class="quiet">Statements</span>
28
- <span class='fraction'>331/559</span>
29
- </div>
30
-
31
-
32
- <div class='fl pad1y space-right2'>
33
- <span class="strong">34.61% </span>
34
- <span class="quiet">Branches</span>
35
- <span class='fraction'>9/26</span>
36
- </div>
37
-
38
-
39
- <div class='fl pad1y space-right2'>
40
- <span class="strong">50% </span>
41
- <span class="quiet">Functions</span>
42
- <span class='fraction'>9/18</span>
43
- </div>
44
-
45
-
46
- <div class='fl pad1y space-right2'>
47
- <span class="strong">59.21% </span>
48
- <span class="quiet">Lines</span>
49
- <span class='fraction'>331/559</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>
315
- <a name='L250'></a><a href='#L250'>250</a>
316
- <a name='L251'></a><a href='#L251'>251</a>
317
- <a name='L252'></a><a href='#L252'>252</a>
318
- <a name='L253'></a><a href='#L253'>253</a>
319
- <a name='L254'></a><a href='#L254'>254</a>
320
- <a name='L255'></a><a href='#L255'>255</a>
321
- <a name='L256'></a><a href='#L256'>256</a>
322
- <a name='L257'></a><a href='#L257'>257</a>
323
- <a name='L258'></a><a href='#L258'>258</a>
324
- <a name='L259'></a><a href='#L259'>259</a>
325
- <a name='L260'></a><a href='#L260'>260</a>
326
- <a name='L261'></a><a href='#L261'>261</a>
327
- <a name='L262'></a><a href='#L262'>262</a>
328
- <a name='L263'></a><a href='#L263'>263</a>
329
- <a name='L264'></a><a href='#L264'>264</a>
330
- <a name='L265'></a><a href='#L265'>265</a>
331
- <a name='L266'></a><a href='#L266'>266</a>
332
- <a name='L267'></a><a href='#L267'>267</a>
333
- <a name='L268'></a><a href='#L268'>268</a>
334
- <a name='L269'></a><a href='#L269'>269</a>
335
- <a name='L270'></a><a href='#L270'>270</a>
336
- <a name='L271'></a><a href='#L271'>271</a>
337
- <a name='L272'></a><a href='#L272'>272</a>
338
- <a name='L273'></a><a href='#L273'>273</a>
339
- <a name='L274'></a><a href='#L274'>274</a>
340
- <a name='L275'></a><a href='#L275'>275</a>
341
- <a name='L276'></a><a href='#L276'>276</a>
342
- <a name='L277'></a><a href='#L277'>277</a>
343
- <a name='L278'></a><a href='#L278'>278</a>
344
- <a name='L279'></a><a href='#L279'>279</a>
345
- <a name='L280'></a><a href='#L280'>280</a>
346
- <a name='L281'></a><a href='#L281'>281</a>
347
- <a name='L282'></a><a href='#L282'>282</a>
348
- <a name='L283'></a><a href='#L283'>283</a>
349
- <a name='L284'></a><a href='#L284'>284</a>
350
- <a name='L285'></a><a href='#L285'>285</a>
351
- <a name='L286'></a><a href='#L286'>286</a>
352
- <a name='L287'></a><a href='#L287'>287</a>
353
- <a name='L288'></a><a href='#L288'>288</a>
354
- <a name='L289'></a><a href='#L289'>289</a>
355
- <a name='L290'></a><a href='#L290'>290</a>
356
- <a name='L291'></a><a href='#L291'>291</a>
357
- <a name='L292'></a><a href='#L292'>292</a>
358
- <a name='L293'></a><a href='#L293'>293</a>
359
- <a name='L294'></a><a href='#L294'>294</a>
360
- <a name='L295'></a><a href='#L295'>295</a>
361
- <a name='L296'></a><a href='#L296'>296</a>
362
- <a name='L297'></a><a href='#L297'>297</a>
363
- <a name='L298'></a><a href='#L298'>298</a>
364
- <a name='L299'></a><a href='#L299'>299</a>
365
- <a name='L300'></a><a href='#L300'>300</a>
366
- <a name='L301'></a><a href='#L301'>301</a>
367
- <a name='L302'></a><a href='#L302'>302</a>
368
- <a name='L303'></a><a href='#L303'>303</a>
369
- <a name='L304'></a><a href='#L304'>304</a>
370
- <a name='L305'></a><a href='#L305'>305</a>
371
- <a name='L306'></a><a href='#L306'>306</a>
372
- <a name='L307'></a><a href='#L307'>307</a>
373
- <a name='L308'></a><a href='#L308'>308</a>
374
- <a name='L309'></a><a href='#L309'>309</a>
375
- <a name='L310'></a><a href='#L310'>310</a>
376
- <a name='L311'></a><a href='#L311'>311</a>
377
- <a name='L312'></a><a href='#L312'>312</a>
378
- <a name='L313'></a><a href='#L313'>313</a>
379
- <a name='L314'></a><a href='#L314'>314</a>
380
- <a name='L315'></a><a href='#L315'>315</a>
381
- <a name='L316'></a><a href='#L316'>316</a>
382
- <a name='L317'></a><a href='#L317'>317</a>
383
- <a name='L318'></a><a href='#L318'>318</a>
384
- <a name='L319'></a><a href='#L319'>319</a>
385
- <a name='L320'></a><a href='#L320'>320</a>
386
- <a name='L321'></a><a href='#L321'>321</a>
387
- <a name='L322'></a><a href='#L322'>322</a>
388
- <a name='L323'></a><a href='#L323'>323</a>
389
- <a name='L324'></a><a href='#L324'>324</a>
390
- <a name='L325'></a><a href='#L325'>325</a>
391
- <a name='L326'></a><a href='#L326'>326</a>
392
- <a name='L327'></a><a href='#L327'>327</a>
393
- <a name='L328'></a><a href='#L328'>328</a>
394
- <a name='L329'></a><a href='#L329'>329</a>
395
- <a name='L330'></a><a href='#L330'>330</a>
396
- <a name='L331'></a><a href='#L331'>331</a>
397
- <a name='L332'></a><a href='#L332'>332</a>
398
- <a name='L333'></a><a href='#L333'>333</a>
399
- <a name='L334'></a><a href='#L334'>334</a>
400
- <a name='L335'></a><a href='#L335'>335</a>
401
- <a name='L336'></a><a href='#L336'>336</a>
402
- <a name='L337'></a><a href='#L337'>337</a>
403
- <a name='L338'></a><a href='#L338'>338</a>
404
- <a name='L339'></a><a href='#L339'>339</a>
405
- <a name='L340'></a><a href='#L340'>340</a>
406
- <a name='L341'></a><a href='#L341'>341</a>
407
- <a name='L342'></a><a href='#L342'>342</a>
408
- <a name='L343'></a><a href='#L343'>343</a>
409
- <a name='L344'></a><a href='#L344'>344</a>
410
- <a name='L345'></a><a href='#L345'>345</a>
411
- <a name='L346'></a><a href='#L346'>346</a>
412
- <a name='L347'></a><a href='#L347'>347</a>
413
- <a name='L348'></a><a href='#L348'>348</a>
414
- <a name='L349'></a><a href='#L349'>349</a>
415
- <a name='L350'></a><a href='#L350'>350</a>
416
- <a name='L351'></a><a href='#L351'>351</a>
417
- <a name='L352'></a><a href='#L352'>352</a>
418
- <a name='L353'></a><a href='#L353'>353</a>
419
- <a name='L354'></a><a href='#L354'>354</a>
420
- <a name='L355'></a><a href='#L355'>355</a>
421
- <a name='L356'></a><a href='#L356'>356</a>
422
- <a name='L357'></a><a href='#L357'>357</a>
423
- <a name='L358'></a><a href='#L358'>358</a>
424
- <a name='L359'></a><a href='#L359'>359</a>
425
- <a name='L360'></a><a href='#L360'>360</a>
426
- <a name='L361'></a><a href='#L361'>361</a>
427
- <a name='L362'></a><a href='#L362'>362</a>
428
- <a name='L363'></a><a href='#L363'>363</a>
429
- <a name='L364'></a><a href='#L364'>364</a>
430
- <a name='L365'></a><a href='#L365'>365</a>
431
- <a name='L366'></a><a href='#L366'>366</a>
432
- <a name='L367'></a><a href='#L367'>367</a>
433
- <a name='L368'></a><a href='#L368'>368</a>
434
- <a name='L369'></a><a href='#L369'>369</a>
435
- <a name='L370'></a><a href='#L370'>370</a>
436
- <a name='L371'></a><a href='#L371'>371</a>
437
- <a name='L372'></a><a href='#L372'>372</a>
438
- <a name='L373'></a><a href='#L373'>373</a>
439
- <a name='L374'></a><a href='#L374'>374</a>
440
- <a name='L375'></a><a href='#L375'>375</a>
441
- <a name='L376'></a><a href='#L376'>376</a>
442
- <a name='L377'></a><a href='#L377'>377</a>
443
- <a name='L378'></a><a href='#L378'>378</a>
444
- <a name='L379'></a><a href='#L379'>379</a>
445
- <a name='L380'></a><a href='#L380'>380</a>
446
- <a name='L381'></a><a href='#L381'>381</a>
447
- <a name='L382'></a><a href='#L382'>382</a>
448
- <a name='L383'></a><a href='#L383'>383</a>
449
- <a name='L384'></a><a href='#L384'>384</a>
450
- <a name='L385'></a><a href='#L385'>385</a>
451
- <a name='L386'></a><a href='#L386'>386</a>
452
- <a name='L387'></a><a href='#L387'>387</a>
453
- <a name='L388'></a><a href='#L388'>388</a>
454
- <a name='L389'></a><a href='#L389'>389</a>
455
- <a name='L390'></a><a href='#L390'>390</a>
456
- <a name='L391'></a><a href='#L391'>391</a>
457
- <a name='L392'></a><a href='#L392'>392</a>
458
- <a name='L393'></a><a href='#L393'>393</a>
459
- <a name='L394'></a><a href='#L394'>394</a>
460
- <a name='L395'></a><a href='#L395'>395</a>
461
- <a name='L396'></a><a href='#L396'>396</a>
462
- <a name='L397'></a><a href='#L397'>397</a>
463
- <a name='L398'></a><a href='#L398'>398</a>
464
- <a name='L399'></a><a href='#L399'>399</a>
465
- <a name='L400'></a><a href='#L400'>400</a>
466
- <a name='L401'></a><a href='#L401'>401</a>
467
- <a name='L402'></a><a href='#L402'>402</a>
468
- <a name='L403'></a><a href='#L403'>403</a>
469
- <a name='L404'></a><a href='#L404'>404</a>
470
- <a name='L405'></a><a href='#L405'>405</a>
471
- <a name='L406'></a><a href='#L406'>406</a>
472
- <a name='L407'></a><a href='#L407'>407</a>
473
- <a name='L408'></a><a href='#L408'>408</a>
474
- <a name='L409'></a><a href='#L409'>409</a>
475
- <a name='L410'></a><a href='#L410'>410</a>
476
- <a name='L411'></a><a href='#L411'>411</a>
477
- <a name='L412'></a><a href='#L412'>412</a>
478
- <a name='L413'></a><a href='#L413'>413</a>
479
- <a name='L414'></a><a href='#L414'>414</a>
480
- <a name='L415'></a><a href='#L415'>415</a>
481
- <a name='L416'></a><a href='#L416'>416</a>
482
- <a name='L417'></a><a href='#L417'>417</a>
483
- <a name='L418'></a><a href='#L418'>418</a>
484
- <a name='L419'></a><a href='#L419'>419</a>
485
- <a name='L420'></a><a href='#L420'>420</a>
486
- <a name='L421'></a><a href='#L421'>421</a>
487
- <a name='L422'></a><a href='#L422'>422</a>
488
- <a name='L423'></a><a href='#L423'>423</a>
489
- <a name='L424'></a><a href='#L424'>424</a>
490
- <a name='L425'></a><a href='#L425'>425</a>
491
- <a name='L426'></a><a href='#L426'>426</a>
492
- <a name='L427'></a><a href='#L427'>427</a>
493
- <a name='L428'></a><a href='#L428'>428</a>
494
- <a name='L429'></a><a href='#L429'>429</a>
495
- <a name='L430'></a><a href='#L430'>430</a>
496
- <a name='L431'></a><a href='#L431'>431</a>
497
- <a name='L432'></a><a href='#L432'>432</a>
498
- <a name='L433'></a><a href='#L433'>433</a>
499
- <a name='L434'></a><a href='#L434'>434</a>
500
- <a name='L435'></a><a href='#L435'>435</a>
501
- <a name='L436'></a><a href='#L436'>436</a>
502
- <a name='L437'></a><a href='#L437'>437</a>
503
- <a name='L438'></a><a href='#L438'>438</a>
504
- <a name='L439'></a><a href='#L439'>439</a>
505
- <a name='L440'></a><a href='#L440'>440</a>
506
- <a name='L441'></a><a href='#L441'>441</a>
507
- <a name='L442'></a><a href='#L442'>442</a>
508
- <a name='L443'></a><a href='#L443'>443</a>
509
- <a name='L444'></a><a href='#L444'>444</a>
510
- <a name='L445'></a><a href='#L445'>445</a>
511
- <a name='L446'></a><a href='#L446'>446</a>
512
- <a name='L447'></a><a href='#L447'>447</a>
513
- <a name='L448'></a><a href='#L448'>448</a>
514
- <a name='L449'></a><a href='#L449'>449</a>
515
- <a name='L450'></a><a href='#L450'>450</a>
516
- <a name='L451'></a><a href='#L451'>451</a>
517
- <a name='L452'></a><a href='#L452'>452</a>
518
- <a name='L453'></a><a href='#L453'>453</a>
519
- <a name='L454'></a><a href='#L454'>454</a>
520
- <a name='L455'></a><a href='#L455'>455</a>
521
- <a name='L456'></a><a href='#L456'>456</a>
522
- <a name='L457'></a><a href='#L457'>457</a>
523
- <a name='L458'></a><a href='#L458'>458</a>
524
- <a name='L459'></a><a href='#L459'>459</a>
525
- <a name='L460'></a><a href='#L460'>460</a>
526
- <a name='L461'></a><a href='#L461'>461</a>
527
- <a name='L462'></a><a href='#L462'>462</a>
528
- <a name='L463'></a><a href='#L463'>463</a>
529
- <a name='L464'></a><a href='#L464'>464</a>
530
- <a name='L465'></a><a href='#L465'>465</a>
531
- <a name='L466'></a><a href='#L466'>466</a>
532
- <a name='L467'></a><a href='#L467'>467</a>
533
- <a name='L468'></a><a href='#L468'>468</a>
534
- <a name='L469'></a><a href='#L469'>469</a>
535
- <a name='L470'></a><a href='#L470'>470</a>
536
- <a name='L471'></a><a href='#L471'>471</a>
537
- <a name='L472'></a><a href='#L472'>472</a>
538
- <a name='L473'></a><a href='#L473'>473</a>
539
- <a name='L474'></a><a href='#L474'>474</a>
540
- <a name='L475'></a><a href='#L475'>475</a>
541
- <a name='L476'></a><a href='#L476'>476</a>
542
- <a name='L477'></a><a href='#L477'>477</a>
543
- <a name='L478'></a><a href='#L478'>478</a>
544
- <a name='L479'></a><a href='#L479'>479</a>
545
- <a name='L480'></a><a href='#L480'>480</a>
546
- <a name='L481'></a><a href='#L481'>481</a>
547
- <a name='L482'></a><a href='#L482'>482</a>
548
- <a name='L483'></a><a href='#L483'>483</a>
549
- <a name='L484'></a><a href='#L484'>484</a>
550
- <a name='L485'></a><a href='#L485'>485</a>
551
- <a name='L486'></a><a href='#L486'>486</a>
552
- <a name='L487'></a><a href='#L487'>487</a>
553
- <a name='L488'></a><a href='#L488'>488</a>
554
- <a name='L489'></a><a href='#L489'>489</a>
555
- <a name='L490'></a><a href='#L490'>490</a>
556
- <a name='L491'></a><a href='#L491'>491</a>
557
- <a name='L492'></a><a href='#L492'>492</a>
558
- <a name='L493'></a><a href='#L493'>493</a>
559
- <a name='L494'></a><a href='#L494'>494</a>
560
- <a name='L495'></a><a href='#L495'>495</a>
561
- <a name='L496'></a><a href='#L496'>496</a>
562
- <a name='L497'></a><a href='#L497'>497</a>
563
- <a name='L498'></a><a href='#L498'>498</a>
564
- <a name='L499'></a><a href='#L499'>499</a>
565
- <a name='L500'></a><a href='#L500'>500</a>
566
- <a name='L501'></a><a href='#L501'>501</a>
567
- <a name='L502'></a><a href='#L502'>502</a>
568
- <a name='L503'></a><a href='#L503'>503</a>
569
- <a name='L504'></a><a href='#L504'>504</a>
570
- <a name='L505'></a><a href='#L505'>505</a>
571
- <a name='L506'></a><a href='#L506'>506</a>
572
- <a name='L507'></a><a href='#L507'>507</a>
573
- <a name='L508'></a><a href='#L508'>508</a>
574
- <a name='L509'></a><a href='#L509'>509</a>
575
- <a name='L510'></a><a href='#L510'>510</a>
576
- <a name='L511'></a><a href='#L511'>511</a>
577
- <a name='L512'></a><a href='#L512'>512</a>
578
- <a name='L513'></a><a href='#L513'>513</a>
579
- <a name='L514'></a><a href='#L514'>514</a>
580
- <a name='L515'></a><a href='#L515'>515</a>
581
- <a name='L516'></a><a href='#L516'>516</a>
582
- <a name='L517'></a><a href='#L517'>517</a>
583
- <a name='L518'></a><a href='#L518'>518</a>
584
- <a name='L519'></a><a href='#L519'>519</a>
585
- <a name='L520'></a><a href='#L520'>520</a>
586
- <a name='L521'></a><a href='#L521'>521</a>
587
- <a name='L522'></a><a href='#L522'>522</a>
588
- <a name='L523'></a><a href='#L523'>523</a>
589
- <a name='L524'></a><a href='#L524'>524</a>
590
- <a name='L525'></a><a href='#L525'>525</a>
591
- <a name='L526'></a><a href='#L526'>526</a>
592
- <a name='L527'></a><a href='#L527'>527</a>
593
- <a name='L528'></a><a href='#L528'>528</a>
594
- <a name='L529'></a><a href='#L529'>529</a>
595
- <a name='L530'></a><a href='#L530'>530</a>
596
- <a name='L531'></a><a href='#L531'>531</a>
597
- <a name='L532'></a><a href='#L532'>532</a>
598
- <a name='L533'></a><a href='#L533'>533</a>
599
- <a name='L534'></a><a href='#L534'>534</a>
600
- <a name='L535'></a><a href='#L535'>535</a>
601
- <a name='L536'></a><a href='#L536'>536</a>
602
- <a name='L537'></a><a href='#L537'>537</a>
603
- <a name='L538'></a><a href='#L538'>538</a>
604
- <a name='L539'></a><a href='#L539'>539</a>
605
- <a name='L540'></a><a href='#L540'>540</a>
606
- <a name='L541'></a><a href='#L541'>541</a>
607
- <a name='L542'></a><a href='#L542'>542</a>
608
- <a name='L543'></a><a href='#L543'>543</a>
609
- <a name='L544'></a><a href='#L544'>544</a>
610
- <a name='L545'></a><a href='#L545'>545</a>
611
- <a name='L546'></a><a href='#L546'>546</a>
612
- <a name='L547'></a><a href='#L547'>547</a>
613
- <a name='L548'></a><a href='#L548'>548</a>
614
- <a name='L549'></a><a href='#L549'>549</a>
615
- <a name='L550'></a><a href='#L550'>550</a>
616
- <a name='L551'></a><a href='#L551'>551</a>
617
- <a name='L552'></a><a href='#L552'>552</a>
618
- <a name='L553'></a><a href='#L553'>553</a>
619
- <a name='L554'></a><a href='#L554'>554</a>
620
- <a name='L555'></a><a href='#L555'>555</a>
621
- <a name='L556'></a><a href='#L556'>556</a>
622
- <a name='L557'></a><a href='#L557'>557</a>
623
- <a name='L558'></a><a href='#L558'>558</a>
624
- <a name='L559'></a><a href='#L559'>559</a>
625
- <a name='L560'></a><a href='#L560'>560</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
626
- <span class="cline-any cline-yes">1x</span>
627
- <span class="cline-any cline-yes">1x</span>
628
- <span class="cline-any cline-yes">1x</span>
629
- <span class="cline-any cline-yes">1x</span>
630
- <span class="cline-any cline-yes">1x</span>
631
- <span class="cline-any cline-yes">1x</span>
632
- <span class="cline-any cline-yes">1x</span>
633
- <span class="cline-any cline-yes">1x</span>
634
- <span class="cline-any cline-yes">1x</span>
635
- <span class="cline-any cline-yes">1x</span>
636
- <span class="cline-any cline-yes">1x</span>
637
- <span class="cline-any cline-yes">1x</span>
638
- <span class="cline-any cline-yes">1x</span>
639
- <span class="cline-any cline-yes">1x</span>
640
- <span class="cline-any cline-yes">1x</span>
641
- <span class="cline-any cline-yes">1x</span>
642
- <span class="cline-any cline-yes">1x</span>
643
- <span class="cline-any cline-yes">1x</span>
644
- <span class="cline-any cline-yes">1x</span>
645
- <span class="cline-any cline-yes">1x</span>
646
- <span class="cline-any cline-yes">1x</span>
647
- <span class="cline-any cline-yes">1x</span>
648
- <span class="cline-any cline-yes">1x</span>
649
- <span class="cline-any cline-yes">1x</span>
650
- <span class="cline-any cline-yes">1x</span>
651
- <span class="cline-any cline-yes">1x</span>
652
- <span class="cline-any cline-yes">1x</span>
653
- <span class="cline-any cline-yes">1x</span>
654
- <span class="cline-any cline-yes">1x</span>
655
- <span class="cline-any cline-yes">1x</span>
656
- <span class="cline-any cline-yes">1x</span>
657
- <span class="cline-any cline-yes">1x</span>
658
- <span class="cline-any cline-yes">1x</span>
659
- <span class="cline-any cline-yes">1x</span>
660
- <span class="cline-any cline-yes">1x</span>
661
- <span class="cline-any cline-yes">1x</span>
662
- <span class="cline-any cline-yes">1x</span>
663
- <span class="cline-any cline-yes">1x</span>
664
- <span class="cline-any cline-yes">1x</span>
665
- <span class="cline-any cline-yes">1x</span>
666
- <span class="cline-any cline-yes">1x</span>
667
- <span class="cline-any cline-yes">1x</span>
668
- <span class="cline-any cline-yes">1x</span>
669
- <span class="cline-any cline-yes">1x</span>
670
- <span class="cline-any cline-yes">1x</span>
671
- <span class="cline-any cline-yes">1x</span>
672
- <span class="cline-any cline-yes">1x</span>
673
- <span class="cline-any cline-yes">1x</span>
674
- <span class="cline-any cline-yes">1x</span>
675
- <span class="cline-any cline-yes">1x</span>
676
- <span class="cline-any cline-yes">1x</span>
677
- <span class="cline-any cline-yes">1x</span>
678
- <span class="cline-any cline-yes">1x</span>
679
- <span class="cline-any cline-yes">1x</span>
680
- <span class="cline-any cline-yes">1x</span>
681
- <span class="cline-any cline-yes">1x</span>
682
- <span class="cline-any cline-yes">1x</span>
683
- <span class="cline-any cline-no">&nbsp;</span>
684
- <span class="cline-any cline-no">&nbsp;</span>
685
- <span class="cline-any cline-no">&nbsp;</span>
686
- <span class="cline-any cline-no">&nbsp;</span>
687
- <span class="cline-any cline-no">&nbsp;</span>
688
- <span class="cline-any cline-no">&nbsp;</span>
689
- <span class="cline-any cline-no">&nbsp;</span>
690
- <span class="cline-any cline-no">&nbsp;</span>
691
- <span class="cline-any cline-no">&nbsp;</span>
692
- <span class="cline-any cline-no">&nbsp;</span>
693
- <span class="cline-any cline-no">&nbsp;</span>
694
- <span class="cline-any cline-no">&nbsp;</span>
695
- <span class="cline-any cline-yes">1x</span>
696
- <span class="cline-any cline-yes">1x</span>
697
- <span class="cline-any cline-yes">1x</span>
698
- <span class="cline-any cline-yes">1x</span>
699
- <span class="cline-any cline-yes">1x</span>
700
- <span class="cline-any cline-yes">1x</span>
701
- <span class="cline-any cline-yes">1x</span>
702
- <span class="cline-any cline-yes">1x</span>
703
- <span class="cline-any cline-yes">1x</span>
704
- <span class="cline-any cline-yes">1x</span>
705
- <span class="cline-any cline-yes">1x</span>
706
- <span class="cline-any cline-yes">1x</span>
707
- <span class="cline-any cline-yes">1x</span>
708
- <span class="cline-any cline-yes">1x</span>
709
- <span class="cline-any cline-yes">1x</span>
710
- <span class="cline-any cline-yes">1x</span>
711
- <span class="cline-any cline-yes">1x</span>
712
- <span class="cline-any cline-yes">1x</span>
713
- <span class="cline-any cline-yes">1x</span>
714
- <span class="cline-any cline-yes">1x</span>
715
- <span class="cline-any cline-yes">1x</span>
716
- <span class="cline-any cline-yes">1x</span>
717
- <span class="cline-any cline-yes">1x</span>
718
- <span class="cline-any cline-yes">1x</span>
719
- <span class="cline-any cline-yes">1x</span>
720
- <span class="cline-any cline-yes">1x</span>
721
- <span class="cline-any cline-yes">1x</span>
722
- <span class="cline-any cline-yes">1x</span>
723
- <span class="cline-any cline-yes">1x</span>
724
- <span class="cline-any cline-yes">1x</span>
725
- <span class="cline-any cline-yes">1x</span>
726
- <span class="cline-any cline-yes">1x</span>
727
- <span class="cline-any cline-yes">1x</span>
728
- <span class="cline-any cline-yes">1x</span>
729
- <span class="cline-any cline-yes">1x</span>
730
- <span class="cline-any cline-yes">1x</span>
731
- <span class="cline-any cline-yes">1x</span>
732
- <span class="cline-any cline-yes">1x</span>
733
- <span class="cline-any cline-yes">1x</span>
734
- <span class="cline-any cline-yes">1x</span>
735
- <span class="cline-any cline-yes">1x</span>
736
- <span class="cline-any cline-yes">1x</span>
737
- <span class="cline-any cline-no">&nbsp;</span>
738
- <span class="cline-any cline-no">&nbsp;</span>
739
- <span class="cline-any cline-no">&nbsp;</span>
740
- <span class="cline-any cline-no">&nbsp;</span>
741
- <span class="cline-any cline-no">&nbsp;</span>
742
- <span class="cline-any cline-no">&nbsp;</span>
743
- <span class="cline-any cline-no">&nbsp;</span>
744
- <span class="cline-any cline-no">&nbsp;</span>
745
- <span class="cline-any cline-no">&nbsp;</span>
746
- <span class="cline-any cline-no">&nbsp;</span>
747
- <span class="cline-any cline-no">&nbsp;</span>
748
- <span class="cline-any cline-no">&nbsp;</span>
749
- <span class="cline-any cline-no">&nbsp;</span>
750
- <span class="cline-any cline-no">&nbsp;</span>
751
- <span class="cline-any cline-no">&nbsp;</span>
752
- <span class="cline-any cline-yes">1x</span>
753
- <span class="cline-any cline-yes">1x</span>
754
- <span class="cline-any cline-yes">1x</span>
755
- <span class="cline-any cline-yes">1x</span>
756
- <span class="cline-any cline-yes">1x</span>
757
- <span class="cline-any cline-yes">1x</span>
758
- <span class="cline-any cline-yes">1x</span>
759
- <span class="cline-any cline-yes">1x</span>
760
- <span class="cline-any cline-yes">1x</span>
761
- <span class="cline-any cline-yes">1x</span>
762
- <span class="cline-any cline-yes">1x</span>
763
- <span class="cline-any cline-yes">1x</span>
764
- <span class="cline-any cline-yes">1x</span>
765
- <span class="cline-any cline-yes">1x</span>
766
- <span class="cline-any cline-yes">1x</span>
767
- <span class="cline-any cline-yes">1x</span>
768
- <span class="cline-any cline-yes">1x</span>
769
- <span class="cline-any cline-yes">1x</span>
770
- <span class="cline-any cline-yes">1x</span>
771
- <span class="cline-any cline-yes">1x</span>
772
- <span class="cline-any cline-yes">1x</span>
773
- <span class="cline-any cline-yes">1x</span>
774
- <span class="cline-any cline-yes">1x</span>
775
- <span class="cline-any cline-yes">1x</span>
776
- <span class="cline-any cline-yes">1x</span>
777
- <span class="cline-any cline-yes">1x</span>
778
- <span class="cline-any cline-yes">1x</span>
779
- <span class="cline-any cline-yes">1x</span>
780
- <span class="cline-any cline-yes">1x</span>
781
- <span class="cline-any cline-yes">1x</span>
782
- <span class="cline-any cline-no">&nbsp;</span>
783
- <span class="cline-any cline-no">&nbsp;</span>
784
- <span class="cline-any cline-no">&nbsp;</span>
785
- <span class="cline-any cline-yes">1x</span>
786
- <span class="cline-any cline-yes">1x</span>
787
- <span class="cline-any cline-yes">1x</span>
788
- <span class="cline-any cline-no">&nbsp;</span>
789
- <span class="cline-any cline-no">&nbsp;</span>
790
- <span class="cline-any cline-no">&nbsp;</span>
791
- <span class="cline-any cline-no">&nbsp;</span>
792
- <span class="cline-any cline-no">&nbsp;</span>
793
- <span class="cline-any cline-yes">1x</span>
794
- <span class="cline-any cline-yes">1x</span>
795
- <span class="cline-any cline-yes">1x</span>
796
- <span class="cline-any cline-yes">1x</span>
797
- <span class="cline-any cline-yes">1x</span>
798
- <span class="cline-any cline-yes">1x</span>
799
- <span class="cline-any cline-yes">1x</span>
800
- <span class="cline-any cline-yes">1x</span>
801
- <span class="cline-any cline-yes">1x</span>
802
- <span class="cline-any cline-yes">1x</span>
803
- <span class="cline-any cline-no">&nbsp;</span>
804
- <span class="cline-any cline-no">&nbsp;</span>
805
- <span class="cline-any cline-no">&nbsp;</span>
806
- <span class="cline-any cline-no">&nbsp;</span>
807
- <span class="cline-any cline-no">&nbsp;</span>
808
- <span class="cline-any cline-no">&nbsp;</span>
809
- <span class="cline-any cline-yes">1x</span>
810
- <span class="cline-any cline-yes">1x</span>
811
- <span class="cline-any cline-yes">1x</span>
812
- <span class="cline-any cline-yes">1x</span>
813
- <span class="cline-any cline-yes">1x</span>
814
- <span class="cline-any cline-yes">1x</span>
815
- <span class="cline-any cline-yes">1x</span>
816
- <span class="cline-any cline-yes">1x</span>
817
- <span class="cline-any cline-yes">1x</span>
818
- <span class="cline-any cline-yes">1x</span>
819
- <span class="cline-any cline-yes">1x</span>
820
- <span class="cline-any cline-yes">1x</span>
821
- <span class="cline-any cline-yes">1x</span>
822
- <span class="cline-any cline-no">&nbsp;</span>
823
- <span class="cline-any cline-no">&nbsp;</span>
824
- <span class="cline-any cline-no">&nbsp;</span>
825
- <span class="cline-any cline-no">&nbsp;</span>
826
- <span class="cline-any cline-no">&nbsp;</span>
827
- <span class="cline-any cline-no">&nbsp;</span>
828
- <span class="cline-any cline-yes">1x</span>
829
- <span class="cline-any cline-yes">1x</span>
830
- <span class="cline-any cline-yes">1x</span>
831
- <span class="cline-any cline-yes">1x</span>
832
- <span class="cline-any cline-yes">1x</span>
833
- <span class="cline-any cline-yes">1x</span>
834
- <span class="cline-any cline-yes">1x</span>
835
- <span class="cline-any cline-yes">1x</span>
836
- <span class="cline-any cline-yes">1x</span>
837
- <span class="cline-any cline-yes">1x</span>
838
- <span class="cline-any cline-yes">1x</span>
839
- <span class="cline-any cline-yes">1x</span>
840
- <span class="cline-any cline-yes">1x</span>
841
- <span class="cline-any cline-yes">1x</span>
842
- <span class="cline-any cline-yes">1x</span>
843
- <span class="cline-any cline-yes">1x</span>
844
- <span class="cline-any cline-yes">1x</span>
845
- <span class="cline-any cline-yes">1x</span>
846
- <span class="cline-any cline-yes">1x</span>
847
- <span class="cline-any cline-yes">1x</span>
848
- <span class="cline-any cline-yes">1x</span>
849
- <span class="cline-any cline-yes">1x</span>
850
- <span class="cline-any cline-yes">1x</span>
851
- <span class="cline-any cline-yes">1x</span>
852
- <span class="cline-any cline-yes">1x</span>
853
- <span class="cline-any cline-yes">1x</span>
854
- <span class="cline-any cline-yes">1x</span>
855
- <span class="cline-any cline-yes">1x</span>
856
- <span class="cline-any cline-yes">1x</span>
857
- <span class="cline-any cline-yes">1x</span>
858
- <span class="cline-any cline-yes">1x</span>
859
- <span class="cline-any cline-yes">1x</span>
860
- <span class="cline-any cline-yes">1x</span>
861
- <span class="cline-any cline-yes">1x</span>
862
- <span class="cline-any cline-yes">1x</span>
863
- <span class="cline-any cline-yes">1x</span>
864
- <span class="cline-any cline-yes">1x</span>
865
- <span class="cline-any cline-yes">1x</span>
866
- <span class="cline-any cline-yes">1x</span>
867
- <span class="cline-any cline-yes">1x</span>
868
- <span class="cline-any cline-yes">1x</span>
869
- <span class="cline-any cline-yes">1x</span>
870
- <span class="cline-any cline-yes">1x</span>
871
- <span class="cline-any cline-yes">1x</span>
872
- <span class="cline-any cline-yes">1x</span>
873
- <span class="cline-any cline-yes">1x</span>
874
- <span class="cline-any cline-yes">1x</span>
875
- <span class="cline-any cline-no">&nbsp;</span>
876
- <span class="cline-any cline-no">&nbsp;</span>
877
- <span class="cline-any cline-yes">1x</span>
878
- <span class="cline-any cline-yes">1x</span>
879
- <span class="cline-any cline-no">&nbsp;</span>
880
- <span class="cline-any cline-no">&nbsp;</span>
881
- <span class="cline-any cline-yes">1x</span>
882
- <span class="cline-any cline-yes">1x</span>
883
- <span class="cline-any cline-yes">1x</span>
884
- <span class="cline-any cline-yes">1x</span>
885
- <span class="cline-any cline-yes">1x</span>
886
- <span class="cline-any cline-yes">1x</span>
887
- <span class="cline-any cline-yes">1x</span>
888
- <span class="cline-any cline-yes">1x</span>
889
- <span class="cline-any cline-yes">1x</span>
890
- <span class="cline-any cline-yes">1x</span>
891
- <span class="cline-any cline-yes">1x</span>
892
- <span class="cline-any cline-yes">1x</span>
893
- <span class="cline-any cline-yes">1x</span>
894
- <span class="cline-any cline-yes">1x</span>
895
- <span class="cline-any cline-no">&nbsp;</span>
896
- <span class="cline-any cline-no">&nbsp;</span>
897
- <span class="cline-any cline-yes">1x</span>
898
- <span class="cline-any cline-yes">1x</span>
899
- <span class="cline-any cline-yes">1x</span>
900
- <span class="cline-any cline-yes">1x</span>
901
- <span class="cline-any cline-yes">1x</span>
902
- <span class="cline-any cline-yes">1x</span>
903
- <span class="cline-any cline-yes">1x</span>
904
- <span class="cline-any cline-yes">1x</span>
905
- <span class="cline-any cline-yes">1x</span>
906
- <span class="cline-any cline-yes">1x</span>
907
- <span class="cline-any cline-yes">1x</span>
908
- <span class="cline-any cline-yes">1x</span>
909
- <span class="cline-any cline-yes">1x</span>
910
- <span class="cline-any cline-yes">1x</span>
911
- <span class="cline-any cline-yes">1x</span>
912
- <span class="cline-any cline-yes">1x</span>
913
- <span class="cline-any cline-no">&nbsp;</span>
914
- <span class="cline-any cline-no">&nbsp;</span>
915
- <span class="cline-any cline-no">&nbsp;</span>
916
- <span class="cline-any cline-no">&nbsp;</span>
917
- <span class="cline-any cline-no">&nbsp;</span>
918
- <span class="cline-any cline-no">&nbsp;</span>
919
- <span class="cline-any cline-no">&nbsp;</span>
920
- <span class="cline-any cline-no">&nbsp;</span>
921
- <span class="cline-any cline-no">&nbsp;</span>
922
- <span class="cline-any cline-no">&nbsp;</span>
923
- <span class="cline-any cline-no">&nbsp;</span>
924
- <span class="cline-any cline-no">&nbsp;</span>
925
- <span class="cline-any cline-no">&nbsp;</span>
926
- <span class="cline-any cline-no">&nbsp;</span>
927
- <span class="cline-any cline-no">&nbsp;</span>
928
- <span class="cline-any cline-no">&nbsp;</span>
929
- <span class="cline-any cline-no">&nbsp;</span>
930
- <span class="cline-any cline-no">&nbsp;</span>
931
- <span class="cline-any cline-no">&nbsp;</span>
932
- <span class="cline-any cline-no">&nbsp;</span>
933
- <span class="cline-any cline-no">&nbsp;</span>
934
- <span class="cline-any cline-no">&nbsp;</span>
935
- <span class="cline-any cline-no">&nbsp;</span>
936
- <span class="cline-any cline-no">&nbsp;</span>
937
- <span class="cline-any cline-no">&nbsp;</span>
938
- <span class="cline-any cline-no">&nbsp;</span>
939
- <span class="cline-any cline-no">&nbsp;</span>
940
- <span class="cline-any cline-no">&nbsp;</span>
941
- <span class="cline-any cline-no">&nbsp;</span>
942
- <span class="cline-any cline-no">&nbsp;</span>
943
- <span class="cline-any cline-no">&nbsp;</span>
944
- <span class="cline-any cline-no">&nbsp;</span>
945
- <span class="cline-any cline-no">&nbsp;</span>
946
- <span class="cline-any cline-no">&nbsp;</span>
947
- <span class="cline-any cline-no">&nbsp;</span>
948
- <span class="cline-any cline-no">&nbsp;</span>
949
- <span class="cline-any cline-no">&nbsp;</span>
950
- <span class="cline-any cline-yes">1x</span>
951
- <span class="cline-any cline-yes">1x</span>
952
- <span class="cline-any cline-no">&nbsp;</span>
953
- <span class="cline-any cline-no">&nbsp;</span>
954
- <span class="cline-any cline-no">&nbsp;</span>
955
- <span class="cline-any cline-yes">1x</span>
956
- <span class="cline-any cline-yes">1x</span>
957
- <span class="cline-any cline-no">&nbsp;</span>
958
- <span class="cline-any cline-no">&nbsp;</span>
959
- <span class="cline-any cline-no">&nbsp;</span>
960
- <span class="cline-any cline-yes">1x</span>
961
- <span class="cline-any cline-yes">1x</span>
962
- <span class="cline-any cline-no">&nbsp;</span>
963
- <span class="cline-any cline-no">&nbsp;</span>
964
- <span class="cline-any cline-no">&nbsp;</span>
965
- <span class="cline-any cline-no">&nbsp;</span>
966
- <span class="cline-any cline-no">&nbsp;</span>
967
- <span class="cline-any cline-no">&nbsp;</span>
968
- <span class="cline-any cline-no">&nbsp;</span>
969
- <span class="cline-any cline-no">&nbsp;</span>
970
- <span class="cline-any cline-no">&nbsp;</span>
971
- <span class="cline-any cline-no">&nbsp;</span>
972
- <span class="cline-any cline-no">&nbsp;</span>
973
- <span class="cline-any cline-no">&nbsp;</span>
974
- <span class="cline-any cline-no">&nbsp;</span>
975
- <span class="cline-any cline-yes">1x</span>
976
- <span class="cline-any cline-yes">1x</span>
977
- <span class="cline-any cline-yes">1x</span>
978
- <span class="cline-any cline-yes">1x</span>
979
- <span class="cline-any cline-yes">1x</span>
980
- <span class="cline-any cline-yes">1x</span>
981
- <span class="cline-any cline-yes">1x</span>
982
- <span class="cline-any cline-yes">1x</span>
983
- <span class="cline-any cline-yes">1x</span>
984
- <span class="cline-any cline-yes">1x</span>
985
- <span class="cline-any cline-yes">1x</span>
986
- <span class="cline-any cline-yes">1x</span>
987
- <span class="cline-any cline-yes">1x</span>
988
- <span class="cline-any cline-yes">1x</span>
989
- <span class="cline-any cline-yes">1x</span>
990
- <span class="cline-any cline-yes">1x</span>
991
- <span class="cline-any cline-yes">1x</span>
992
- <span class="cline-any cline-yes">1x</span>
993
- <span class="cline-any cline-yes">1x</span>
994
- <span class="cline-any cline-yes">1x</span>
995
- <span class="cline-any cline-yes">1x</span>
996
- <span class="cline-any cline-yes">1x</span>
997
- <span class="cline-any cline-yes">1x</span>
998
- <span class="cline-any cline-yes">1x</span>
999
- <span class="cline-any cline-yes">1x</span>
1000
- <span class="cline-any cline-yes">1x</span>
1001
- <span class="cline-any cline-yes">1x</span>
1002
- <span class="cline-any cline-yes">1x</span>
1003
- <span class="cline-any cline-yes">1x</span>
1004
- <span class="cline-any cline-yes">1x</span>
1005
- <span class="cline-any cline-yes">1x</span>
1006
- <span class="cline-any cline-yes">1x</span>
1007
- <span class="cline-any cline-yes">1x</span>
1008
- <span class="cline-any cline-yes">1x</span>
1009
- <span class="cline-any cline-yes">1x</span>
1010
- <span class="cline-any cline-yes">1x</span>
1011
- <span class="cline-any cline-yes">1x</span>
1012
- <span class="cline-any cline-no">&nbsp;</span>
1013
- <span class="cline-any cline-no">&nbsp;</span>
1014
- <span class="cline-any cline-no">&nbsp;</span>
1015
- <span class="cline-any cline-no">&nbsp;</span>
1016
- <span class="cline-any cline-no">&nbsp;</span>
1017
- <span class="cline-any cline-no">&nbsp;</span>
1018
- <span class="cline-any cline-no">&nbsp;</span>
1019
- <span class="cline-any cline-no">&nbsp;</span>
1020
- <span class="cline-any cline-no">&nbsp;</span>
1021
- <span class="cline-any cline-no">&nbsp;</span>
1022
- <span class="cline-any cline-no">&nbsp;</span>
1023
- <span class="cline-any cline-no">&nbsp;</span>
1024
- <span class="cline-any cline-no">&nbsp;</span>
1025
- <span class="cline-any cline-no">&nbsp;</span>
1026
- <span class="cline-any cline-yes">1x</span>
1027
- <span class="cline-any cline-yes">1x</span>
1028
- <span class="cline-any cline-yes">1x</span>
1029
- <span class="cline-any cline-yes">1x</span>
1030
- <span class="cline-any cline-yes">1x</span>
1031
- <span class="cline-any cline-yes">1x</span>
1032
- <span class="cline-any cline-yes">1x</span>
1033
- <span class="cline-any cline-yes">1x</span>
1034
- <span class="cline-any cline-yes">1x</span>
1035
- <span class="cline-any cline-yes">1x</span>
1036
- <span class="cline-any cline-yes">1x</span>
1037
- <span class="cline-any cline-no">&nbsp;</span>
1038
- <span class="cline-any cline-no">&nbsp;</span>
1039
- <span class="cline-any cline-no">&nbsp;</span>
1040
- <span class="cline-any cline-no">&nbsp;</span>
1041
- <span class="cline-any cline-no">&nbsp;</span>
1042
- <span class="cline-any cline-no">&nbsp;</span>
1043
- <span class="cline-any cline-no">&nbsp;</span>
1044
- <span class="cline-any cline-no">&nbsp;</span>
1045
- <span class="cline-any cline-no">&nbsp;</span>
1046
- <span class="cline-any cline-no">&nbsp;</span>
1047
- <span class="cline-any cline-no">&nbsp;</span>
1048
- <span class="cline-any cline-no">&nbsp;</span>
1049
- <span class="cline-any cline-no">&nbsp;</span>
1050
- <span class="cline-any cline-no">&nbsp;</span>
1051
- <span class="cline-any cline-no">&nbsp;</span>
1052
- <span class="cline-any cline-no">&nbsp;</span>
1053
- <span class="cline-any cline-no">&nbsp;</span>
1054
- <span class="cline-any cline-no">&nbsp;</span>
1055
- <span class="cline-any cline-no">&nbsp;</span>
1056
- <span class="cline-any cline-no">&nbsp;</span>
1057
- <span class="cline-any cline-no">&nbsp;</span>
1058
- <span class="cline-any cline-no">&nbsp;</span>
1059
- <span class="cline-any cline-no">&nbsp;</span>
1060
- <span class="cline-any cline-no">&nbsp;</span>
1061
- <span class="cline-any cline-no">&nbsp;</span>
1062
- <span class="cline-any cline-no">&nbsp;</span>
1063
- <span class="cline-any cline-yes">1x</span>
1064
- <span class="cline-any cline-yes">1x</span>
1065
- <span class="cline-any cline-yes">1x</span>
1066
- <span class="cline-any cline-yes">1x</span>
1067
- <span class="cline-any cline-yes">1x</span>
1068
- <span class="cline-any cline-yes">1x</span>
1069
- <span class="cline-any cline-yes">1x</span>
1070
- <span class="cline-any cline-yes">1x</span>
1071
- <span class="cline-any cline-yes">1x</span>
1072
- <span class="cline-any cline-yes">1x</span>
1073
- <span class="cline-any cline-yes">1x</span>
1074
- <span class="cline-any cline-yes">1x</span>
1075
- <span class="cline-any cline-no">&nbsp;</span>
1076
- <span class="cline-any cline-no">&nbsp;</span>
1077
- <span class="cline-any cline-no">&nbsp;</span>
1078
- <span class="cline-any cline-yes">1x</span>
1079
- <span class="cline-any cline-no">&nbsp;</span>
1080
- <span class="cline-any cline-no">&nbsp;</span>
1081
- <span class="cline-any cline-yes">1x</span>
1082
- <span class="cline-any cline-yes">1x</span>
1083
- <span class="cline-any cline-yes">1x</span>
1084
- <span class="cline-any cline-no">&nbsp;</span>
1085
- <span class="cline-any cline-no">&nbsp;</span>
1086
- <span class="cline-any cline-no">&nbsp;</span>
1087
- <span class="cline-any cline-no">&nbsp;</span>
1088
- <span class="cline-any cline-no">&nbsp;</span>
1089
- <span class="cline-any cline-no">&nbsp;</span>
1090
- <span class="cline-any cline-no">&nbsp;</span>
1091
- <span class="cline-any cline-no">&nbsp;</span>
1092
- <span class="cline-any cline-no">&nbsp;</span>
1093
- <span class="cline-any cline-no">&nbsp;</span>
1094
- <span class="cline-any cline-no">&nbsp;</span>
1095
- <span class="cline-any cline-no">&nbsp;</span>
1096
- <span class="cline-any cline-no">&nbsp;</span>
1097
- <span class="cline-any cline-yes">1x</span>
1098
- <span class="cline-any cline-yes">1x</span>
1099
- <span class="cline-any cline-yes">1x</span>
1100
- <span class="cline-any cline-yes">1x</span>
1101
- <span class="cline-any cline-yes">1x</span>
1102
- <span class="cline-any cline-yes">1x</span>
1103
- <span class="cline-any cline-yes">1x</span>
1104
- <span class="cline-any cline-yes">2x</span>
1105
- <span class="cline-any cline-yes">2x</span>
1106
- <span class="cline-any cline-yes">2x</span>
1107
- <span class="cline-any cline-no">&nbsp;</span>
1108
- <span class="cline-any cline-no">&nbsp;</span>
1109
- <span class="cline-any cline-yes">2x</span>
1110
- <span class="cline-any cline-yes">1x</span>
1111
- <span class="cline-any cline-yes">1x</span>
1112
- <span class="cline-any cline-yes">1x</span>
1113
- <span class="cline-any cline-yes">1x</span>
1114
- <span class="cline-any cline-yes">1x</span>
1115
- <span class="cline-any cline-yes">1x</span>
1116
- <span class="cline-any cline-yes">1x</span>
1117
- <span class="cline-any cline-yes">1x</span>
1118
- <span class="cline-any cline-yes">1x</span>
1119
- <span class="cline-any cline-yes">1x</span>
1120
- <span class="cline-any cline-yes">1x</span>
1121
- <span class="cline-any cline-yes">1x</span>
1122
- <span class="cline-any cline-yes">1x</span>
1123
- <span class="cline-any cline-yes">1x</span>
1124
- <span class="cline-any cline-no">&nbsp;</span>
1125
- <span class="cline-any cline-no">&nbsp;</span>
1126
- <span class="cline-any cline-no">&nbsp;</span>
1127
- <span class="cline-any cline-no">&nbsp;</span>
1128
- <span class="cline-any cline-no">&nbsp;</span>
1129
- <span class="cline-any cline-no">&nbsp;</span>
1130
- <span class="cline-any cline-no">&nbsp;</span>
1131
- <span class="cline-any cline-no">&nbsp;</span>
1132
- <span class="cline-any cline-no">&nbsp;</span>
1133
- <span class="cline-any cline-no">&nbsp;</span>
1134
- <span class="cline-any cline-no">&nbsp;</span>
1135
- <span class="cline-any cline-no">&nbsp;</span>
1136
- <span class="cline-any cline-no">&nbsp;</span>
1137
- <span class="cline-any cline-no">&nbsp;</span>
1138
- <span class="cline-any cline-no">&nbsp;</span>
1139
- <span class="cline-any cline-no">&nbsp;</span>
1140
- <span class="cline-any cline-no">&nbsp;</span>
1141
- <span class="cline-any cline-no">&nbsp;</span>
1142
- <span class="cline-any cline-no">&nbsp;</span>
1143
- <span class="cline-any cline-no">&nbsp;</span>
1144
- <span class="cline-any cline-no">&nbsp;</span>
1145
- <span class="cline-any cline-no">&nbsp;</span>
1146
- <span class="cline-any cline-no">&nbsp;</span>
1147
- <span class="cline-any cline-no">&nbsp;</span>
1148
- <span class="cline-any cline-no">&nbsp;</span>
1149
- <span class="cline-any cline-no">&nbsp;</span>
1150
- <span class="cline-any cline-no">&nbsp;</span>
1151
- <span class="cline-any cline-no">&nbsp;</span>
1152
- <span class="cline-any cline-no">&nbsp;</span>
1153
- <span class="cline-any cline-no">&nbsp;</span>
1154
- <span class="cline-any cline-no">&nbsp;</span>
1155
- <span class="cline-any cline-no">&nbsp;</span>
1156
- <span class="cline-any cline-no">&nbsp;</span>
1157
- <span class="cline-any cline-no">&nbsp;</span>
1158
- <span class="cline-any cline-no">&nbsp;</span>
1159
- <span class="cline-any cline-no">&nbsp;</span>
1160
- <span class="cline-any cline-no">&nbsp;</span>
1161
- <span class="cline-any cline-no">&nbsp;</span>
1162
- <span class="cline-any cline-no">&nbsp;</span>
1163
- <span class="cline-any cline-no">&nbsp;</span>
1164
- <span class="cline-any cline-no">&nbsp;</span>
1165
- <span class="cline-any cline-no">&nbsp;</span>
1166
- <span class="cline-any cline-no">&nbsp;</span>
1167
- <span class="cline-any cline-no">&nbsp;</span>
1168
- <span class="cline-any cline-no">&nbsp;</span>
1169
- <span class="cline-any cline-no">&nbsp;</span>
1170
- <span class="cline-any cline-no">&nbsp;</span>
1171
- <span class="cline-any cline-no">&nbsp;</span>
1172
- <span class="cline-any cline-no">&nbsp;</span>
1173
- <span class="cline-any cline-no">&nbsp;</span>
1174
- <span class="cline-any cline-no">&nbsp;</span>
1175
- <span class="cline-any cline-no">&nbsp;</span>
1176
- <span class="cline-any cline-no">&nbsp;</span>
1177
- <span class="cline-any cline-no">&nbsp;</span>
1178
- <span class="cline-any cline-no">&nbsp;</span>
1179
- <span class="cline-any cline-no">&nbsp;</span>
1180
- <span class="cline-any cline-no">&nbsp;</span>
1181
- <span class="cline-any cline-no">&nbsp;</span>
1182
- <span class="cline-any cline-no">&nbsp;</span>
1183
- <span class="cline-any cline-yes">1x</span>
1184
- <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import { v4 } from "uuid";
1185
- &nbsp;
1186
- import { improveAndRethrow } from "../common/errorUtils.js";
1187
- import { Logger } from "../common/utils/logging/logger.js";
1188
- &nbsp;
1189
- /**
1190
- * This util helps to avoid duplicated calls to a shared resource.
1191
- * It tracks is there currently active calculation for the specific cache id and make all other requests
1192
- * with the same cache id waiting for this active calculation to be finished. When the calculation ends
1193
- * the resolver allows all the waiting requesters to get the data from cache and start their own calculations.
1194
- *
1195
- * This class should be instantiated inside some other service where you need to request some resource concurrently.
1196
- * Rules:
1197
- * 1. When you need to make a request inside your main service call 'getCachedOrWaitForCachedOrAcquireLock'
1198
- * on the instance of this class and await for the result. If the flag allowing to start calculation is true
1199
- * then you can request data inside your main service. Otherwise you should use the cached data as an another
1200
- * requester just finished the most resent requesting and there is actual data in the cache that
1201
- * is returned to you here.
1202
- * 1.1 Also you can acquire a lock directly if you don't want to get cached data. Use the corresponding method 'acquireLock'.
1203
- *
1204
- * 2. If you start requesting (when you successfully acquired the lock) then after receiving the result of your
1205
- * requesting you should call the 'saveCachedData' so the retrieved data will appear in the cache.
1206
- *
1207
- * 3. If you successfully acquired the lock then you should after calling the 'saveCachedData' call
1208
- * the 'releaseLock' - this is mandatory to release the lock and allow other requesters to perform their requests.
1209
- * WARNING: If for any reason you forget to call this method then this class instance will wait perpetually for
1210
- * the lock releasing and all your attempts to request the data will constantly fail. So usually call it
1211
- * inside the 'finally' block.
1212
- *
1213
- * TODO: [tests, critical++] add unit tests - massively used logic and can produce sophisticated concurrency bugs
1214
- */
1215
- export class CacheAndConcurrentRequestsResolver {
1216
- /**
1217
- * @param bio {string} unique identifier for the exact service
1218
- * @param cache {Cache} cache
1219
- * @param cacheTtl {number|null} time to live for cache ms. 0 or null means the cache cannot expire
1220
- * @param [maxCallAttemptsToWaitForAlreadyRunningRequest=100] {number} number of request allowed to do waiting for
1221
- * result before we fail the original request. Use custom value only if you need to make the attempts count
1222
- * and polling interval changes.
1223
- * @param [timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished=1000] {number}
1224
- * timeout ms for polling for a result. if you change maxCallAttemptsToWaitForAlreadyRunningRequest
1225
- * then this parameter maybe also require the custom value.
1226
- * @param [removeExpiredCacheAutomatically=true] {boolean}
1227
- */
1228
- constructor(
1229
- bio,
1230
- cache,
1231
- cacheTtl,
1232
- removeExpiredCacheAutomatically = true,
1233
- maxCallAttemptsToWaitForAlreadyRunningRequest = 100,
1234
- timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished = 1000
1235
- ) {
1236
- if (
1237
- cacheTtl != null &amp;&amp;
1238
- cacheTtl &lt;
1239
- timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished *
1240
- 2
1241
- ) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1242
- <span class="cstat-no" title="statement not covered" > /*</span>
1243
- <span class="cstat-no" title="statement not covered" > * During the lifetime of this service e.g. if the data is being retrieved slowly we can get</span>
1244
- <span class="cstat-no" title="statement not covered" > * RACE CONDITION when we constantly retrieve data and during retrieval it is expired, so we are trying</span>
1245
- <span class="cstat-no" title="statement not covered" > * to retrieve it again and again.</span>
1246
- <span class="cstat-no" title="statement not covered" > * We have a protection mechanism that we will wait no more than</span>
1247
- <span class="cstat-no" title="statement not covered" > * maxCallAttemptsToWaitForAlreadyRunningRequest * timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished</span>
1248
- <span class="cstat-no" title="statement not covered" > * but this additional check is aimed to reduce potential loading time for some requests.</span>
1249
- <span class="cstat-no" title="statement not covered" > */</span>
1250
- <span class="cstat-no" title="statement not covered" > throw new Error(</span>
1251
- <span class="cstat-no" title="statement not covered" > `DEV: Wrong parameters passed to construct ${bio} - TTL ${cacheTtl} should be 2 times greater than ${timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished}`</span>
1252
- <span class="cstat-no" title="statement not covered" > );</span>
1253
- <span class="cstat-no" title="statement not covered" > }</span>
1254
- this._bio = bio;
1255
- this._cache = cache;
1256
- this._cacheTtlMs = cacheTtl != null ? cacheTtl <span class="branch-0 cbranch-no" title="branch not covered" >: null;</span>
1257
- this._maxExecutionTimeMs =
1258
- maxCallAttemptsToWaitForAlreadyRunningRequest *
1259
- timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished;
1260
- this._removeExpiredCacheAutomatically = removeExpiredCacheAutomatically;
1261
- this._requestsManager = new ManagerOfRequestsToTheSameResource(
1262
- bio,
1263
- maxCallAttemptsToWaitForAlreadyRunningRequest,
1264
- timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished
1265
- );
1266
- }
1267
- &nbsp;
1268
- /**
1269
- * When using this service this is the major method you should call to get data by cache id.
1270
- * This method checks is there cached data and ether
1271
- * - returns you flag that you can start requesting data from the shared resource
1272
- * - or if there is already started calculation waits until it is finished (removed from this service)
1273
- * and returns you the retrieved data
1274
- * - or just returns you the cached data
1275
- *
1276
- * 'canStartDataRetrieval' equal true means that the lock was acquired, and you should manually call 'saveCachedData'
1277
- * if needed and then 'releaseLock' to mark this calculation as finished so other
1278
- * requesters can take their share of the resource.
1279
- *
1280
- * @param cacheId {string}
1281
- * @return {Promise&lt;({
1282
- * canStartDataRetrieval: true,
1283
- * cachedData: any,
1284
- * lockId: string
1285
- * }|{
1286
- * canStartDataRetrieval: false,
1287
- * cachedData: any
1288
- * })&gt;}
1289
- */
1290
- async getCachedOrWaitForCachedOrAcquireLock(cacheId) {
1291
- try {
1292
- const startedAtTimestamp = Date.now();
1293
- let cached = this._cache.get(cacheId);
1294
- let cachedDataBackupIsPresentButExpired = null;
1295
- if (cached != null <span class="branch-0 cbranch-no" title="branch not covered" >&amp;&amp; !this._removeExpiredCacheAutomatically)</span> <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1296
- <span class="cstat-no" title="statement not covered" > const lastUpdateTimestamp =</span>
1297
- <span class="cstat-no" title="statement not covered" > this._cache.getLastUpdateTimestamp(cacheId);</span>
1298
- <span class="cstat-no" title="statement not covered" > if (</span>
1299
- <span class="cstat-no" title="statement not covered" > (lastUpdateTimestamp ?? 0) + this._cacheTtlMs &lt;</span>
1300
- <span class="cstat-no" title="statement not covered" > Date.now()</span>
1301
- <span class="cstat-no" title="statement not covered" > ) {</span>
1302
- <span class="cstat-no" title="statement not covered" > /*</span>
1303
- <span class="cstat-no" title="statement not covered" > * Here we are manually clearing 'cached' value retrieved from cache to force the data loading.</span>
1304
- <span class="cstat-no" title="statement not covered" > * But we save its value first to the backup variable to be able to return this value if ongoing</span>
1305
- <span class="cstat-no" title="statement not covered" > * requesting fails.</span>
1306
- <span class="cstat-no" title="statement not covered" > */</span>
1307
- <span class="cstat-no" title="statement not covered" > cachedDataBackupIsPresentButExpired = cached;</span>
1308
- <span class="cstat-no" title="statement not covered" > cached = null;</span>
1309
- <span class="cstat-no" title="statement not covered" > }</span>
1310
- <span class="cstat-no" title="statement not covered" > }</span>
1311
- let calculationId = null;
1312
- let isRetrievedCacheExpired = true;
1313
- let isWaitingForActiveCalculationSucceeded;
1314
- let weStillHaveSomeTimeToProceedExecution = true;
1315
- while (
1316
- calculationId == null &amp;&amp;
1317
- cached == null &amp;&amp;
1318
- isRetrievedCacheExpired &amp;&amp;
1319
- weStillHaveSomeTimeToProceedExecution
1320
- ) {
1321
- const result =
1322
- await this._requestsManager.startCalculationOrWaitForActiveToFinish(
1323
- cacheId
1324
- );
1325
- calculationId = typeof result === "string" ? result <span class="branch-0 cbranch-no" title="branch not covered" >: null;</span>
1326
- isWaitingForActiveCalculationSucceeded =
1327
- typeof result === "boolean" <span class="branch-0 cbranch-no" title="branch not covered" >? result </span>: null;
1328
- cached = this._cache.get(cacheId);
1329
- isRetrievedCacheExpired =
1330
- isWaitingForActiveCalculationSucceeded <span class="branch-0 cbranch-no" title="branch not covered" >&amp;&amp; cached == null;</span>
1331
- weStillHaveSomeTimeToProceedExecution =
1332
- Date.now() - startedAtTimestamp &lt; this._maxExecutionTimeMs;
1333
- }
1334
- if (calculationId) {
1335
- return {
1336
- canStartDataRetrieval: true,
1337
- cachedData: cached ?? cachedDataBackupIsPresentButExpired,
1338
- lockId: calculationId,
1339
- };
1340
- }
1341
- <span class="cstat-no" title="statement not covered" ><span class="branch-0 cbranch-no" title="branch not covered" ></span></span>
1342
- <span class="cstat-no" title="statement not covered" > return {</span>
1343
- <span class="cstat-no" title="statement not covered" > canStartDataRetrieval: false,</span>
1344
- cachedData: cached ?? cachedDataBackupIsPresentButExpired,
1345
- };
1346
- } <span class="branch-0 cbranch-no" title="branch not covered" >catch (e) {</span>
1347
- <span class="cstat-no" title="statement not covered" > improveAndRethrow(</span>
1348
- <span class="cstat-no" title="statement not covered" > e,</span>
1349
- <span class="cstat-no" title="statement not covered" > `${this._bio}.getCachedOrWaitForCachedOrAcquireLock`</span>
1350
- <span class="cstat-no" title="statement not covered" > );</span>
1351
- <span class="cstat-no" title="statement not covered" > }</span>
1352
- }
1353
- &nbsp;
1354
- /**
1355
- * Returns just the current cache value for the given id.
1356
- * Doesn't wait for the active calculation, doesn't acquire lock, just retrieves the current cache as it is.
1357
- *
1358
- * @param cacheId {string}
1359
- * @return {any}
1360
- */
1361
- <span class="fstat-no" title="function not covered" > getCached(cacheId) {</span>
1362
- <span class="cstat-no" title="statement not covered" > try {</span>
1363
- <span class="cstat-no" title="statement not covered" > return this._cache.get(cacheId);</span>
1364
- <span class="cstat-no" title="statement not covered" > } catch (e) {</span>
1365
- <span class="cstat-no" title="statement not covered" > improveAndRethrow(e, "getCached");</span>
1366
- <span class="cstat-no" title="statement not covered" > }</span>
1367
- <span class="cstat-no" title="statement not covered" > }</span>
1368
- &nbsp;
1369
- _getTtl() {
1370
- return this._removeExpiredCacheAutomatically ? this._cacheTtlMs <span class="branch-0 cbranch-no" title="branch not covered" >: null;</span>
1371
- }
1372
- &nbsp;
1373
- /**
1374
- * Directly acquires the lock despite on cached data availability.
1375
- * So if this method returns result === true you can start the data retrieval.
1376
- *
1377
- * @param cacheId {string}
1378
- * @return {Promise&lt;{ result: true, lockId: string }|{ result: false }&gt;}
1379
- */
1380
- <span class="fstat-no" title="function not covered" > async acquireLock(cacheId) {</span>
1381
- <span class="cstat-no" title="statement not covered" > try {</span>
1382
- <span class="cstat-no" title="statement not covered" > return await this._requestsManager.acquireLock(cacheId);</span>
1383
- <span class="cstat-no" title="statement not covered" > } catch (e) {</span>
1384
- <span class="cstat-no" title="statement not covered" > improveAndRethrow(e, "acquireLock");</span>
1385
- <span class="cstat-no" title="statement not covered" > }</span>
1386
- <span class="cstat-no" title="statement not covered" > }</span>
1387
- &nbsp;
1388
- /**
1389
- * This method should be called only if you acquired a lock successfully.
1390
- *
1391
- * If the current lock id is not equal to the passed one the passed data will be ignored.
1392
- * Or you can do the synchronous data merging on your side and pass the
1393
- * wasDataMergedSynchronouslyWithMostRecentCacheState=true so your data will be stored
1394
- * despite on the lockId.
1395
- * WARNING: you should do this only if you are sure you perform the synchronous update.
1396
- *
1397
- * @param cacheId {string}
1398
- * @param lockId {string}
1399
- * @param data {any}
1400
- * @param [sessionDependentData=true] {boolean}
1401
- * @param [wasDataMergedSynchronouslyWithMostRecentCacheState=false]
1402
- */
1403
- saveCachedData(
1404
- cacheId,
1405
- lockId,
1406
- data,
1407
- sessionDependentData = true,
1408
- wasDataMergedSynchronouslyWithMostRecentCacheState = false
1409
- ) {
1410
- try {
1411
- if (
1412
- wasDataMergedSynchronouslyWithMostRecentCacheState ||
1413
- this._requestsManager.isTheLockActiveOne(cacheId, lockId)
1414
- ) {
1415
- /* We save passed data only if the &lt;caller&gt; has the currently acquired lockId.
1416
- * If the passed lockId is not the active one it means that other code cleared/stopped the lock
1417
- * acquired by the &lt;caller&gt; recently due to some urgent/more prior changes.
1418
- *
1419
- * But we allow user to pass the 'wasDataMergedSynchronouslyWithMostRecentCacheState' flag
1420
- * that tells us that the user had taken the most recent cache value and merged his new data
1421
- * with that cached value (AFTER possibly performing async data retrieval). This means that we
1422
- * can ignore the fact that his lockId is no more relevant and save the passed data
1423
- * as it is synchronously merged with the most recent cached data. (Synchronously merged means that
1424
- * the lost update cannot occur during the merge time as JS execute the synchronous functions\
1425
- * till the end).
1426
- */
1427
- if (sessionDependentData) {
1428
- this._cache.putSessionDependentData(
1429
- cacheId,
1430
- data,
1431
- this._getTtl()
1432
- );
1433
- }<span class="branch-0 cbranch-no" title="branch not covered" > else {</span>
1434
- <span class="cstat-no" title="statement not covered" > this._cache.put(cacheId, data, this._getTtl());</span>
1435
- <span class="cstat-no" title="statement not covered" > }</span>
1436
- }
1437
- } <span class="branch-0 cbranch-no" title="branch not covered" >catch (e) {</span>
1438
- <span class="cstat-no" title="statement not covered" > improveAndRethrow(e, `${this._bio}.saveCachedData`);</span>
1439
- <span class="cstat-no" title="statement not covered" > }</span>
1440
- }
1441
- &nbsp;
1442
- /**
1443
- * Should be called then and only then if you successfully acquired a lock with the lock id.
1444
- *
1445
- * @param cacheId {string}
1446
- * @param lockId {string}
1447
- */
1448
- releaseLock(cacheId, lockId) {
1449
- try {
1450
- if (this._requestsManager.isTheLockActiveOne(cacheId, lockId)) {
1451
- this._requestsManager.finishActiveCalculation(cacheId);
1452
- }
1453
- } <span class="branch-0 cbranch-no" title="branch not covered" >catch (e) {</span>
1454
- <span class="cstat-no" title="statement not covered" > improveAndRethrow(e, `${this._bio}.releaseLock`);</span>
1455
- <span class="cstat-no" title="statement not covered" > }</span>
1456
- }
1457
- &nbsp;
1458
- /**
1459
- * Actualized currently present cached data by key. Applies the provided function to the cached data.
1460
- *
1461
- * @param cacheId {string} id of cache entry
1462
- * @param synchronousCurrentCacheProcessor (function|null} synchronous function accepting cache entry. Should return
1463
- * an object in following format:
1464
- * {
1465
- * isModified: boolean,
1466
- * data: any
1467
- * }
1468
- * the flag signals whether data was changed during the processing or not
1469
- * @param [sessionDependent=true] {boolean} whether to mark the cache entry as session-dependent
1470
- */
1471
- <span class="fstat-no" title="function not covered" > actualizeCachedData(</span>
1472
- <span class="cstat-no" title="statement not covered" > cacheId,</span>
1473
- <span class="cstat-no" title="statement not covered" > synchronousCurrentCacheProcessor,</span>
1474
- <span class="cstat-no" title="statement not covered" > sessionDependent = true</span>
1475
- <span class="cstat-no" title="statement not covered" > ) {</span>
1476
- <span class="cstat-no" title="statement not covered" > try {</span>
1477
- <span class="cstat-no" title="statement not covered" > const cached = this._cache.get(cacheId);</span>
1478
- <span class="cstat-no" title="statement not covered" > const result = synchronousCurrentCacheProcessor(cached);</span>
1479
- <span class="cstat-no" title="statement not covered" > if (result?.isModified &amp;&amp; result?.data != null) {</span>
1480
- <span class="cstat-no" title="statement not covered" > if (sessionDependent) {</span>
1481
- <span class="cstat-no" title="statement not covered" > this._cache.putSessionDependentData(</span>
1482
- <span class="cstat-no" title="statement not covered" > cacheId,</span>
1483
- <span class="cstat-no" title="statement not covered" > result?.data,</span>
1484
- <span class="cstat-no" title="statement not covered" > this._getTtl()</span>
1485
- <span class="cstat-no" title="statement not covered" > );</span>
1486
- <span class="cstat-no" title="statement not covered" > } else {</span>
1487
- <span class="cstat-no" title="statement not covered" > this._cache.put(cacheId, result?.data, this._getTtl());</span>
1488
- <span class="cstat-no" title="statement not covered" > }</span>
1489
- <span class="cstat-no" title="statement not covered" ></span>
1490
- <span class="cstat-no" title="statement not covered" > /* Here we call the lock releasing to ensure the currently active calculation will be ignored.</span>
1491
- <span class="cstat-no" title="statement not covered" > * This is needed to ensure no 'lost update'.</span>
1492
- <span class="cstat-no" title="statement not covered" > * Lost update can occur if we change data in this method and after that some calculation finishes</span>
1493
- <span class="cstat-no" title="statement not covered" > * having the earlier data as its base to calculate its data set result. And the earlier data</span>
1494
- <span class="cstat-no" title="statement not covered" > * has no changes applied inside this method, so we will lose them.</span>
1495
- <span class="cstat-no" title="statement not covered" > *</span>
1496
- <span class="cstat-no" title="statement not covered" > * This is not so good solution: ideally, we should acquire lock before performing any data updating.</span>
1497
- <span class="cstat-no" title="statement not covered" > * But the goal of this method is to provide an instant ability to update the cached data.</span>
1498
- <span class="cstat-no" title="statement not covered" > * And if we start acquiring the lock here the data update can be postponed significantly.</span>
1499
- <span class="cstat-no" title="statement not covered" > * And this kills the desired nature of this method.</span>
1500
- <span class="cstat-no" title="statement not covered" > * So we better lose some data retrieval (means abusing the resource a bit) than lose</span>
1501
- <span class="cstat-no" title="statement not covered" > * the instant update expected after this method execution.</span>
1502
- <span class="cstat-no" title="statement not covered" > */</span>
1503
- <span class="cstat-no" title="statement not covered" > this._requestsManager.finishActiveCalculation(cacheId);</span>
1504
- <span class="cstat-no" title="statement not covered" > }</span>
1505
- <span class="cstat-no" title="statement not covered" > } catch (e) {</span>
1506
- <span class="cstat-no" title="statement not covered" > improveAndRethrow(e, `${this._bio}.actualizeCachedData`);</span>
1507
- <span class="cstat-no" title="statement not covered" > }</span>
1508
- <span class="cstat-no" title="statement not covered" > }</span>
1509
- &nbsp;
1510
- <span class="fstat-no" title="function not covered" > invalidate(key) {</span>
1511
- <span class="cstat-no" title="statement not covered" > this._cache.invalidate(key);</span>
1512
- <span class="cstat-no" title="statement not covered" > this._requestsManager.finishActiveCalculation(key);</span>
1513
- <span class="cstat-no" title="statement not covered" > }</span>
1514
- &nbsp;
1515
- <span class="fstat-no" title="function not covered" > invalidateContaining(keyPart) {</span>
1516
- <span class="cstat-no" title="statement not covered" > this._cache.invalidateContaining(keyPart);</span>
1517
- <span class="cstat-no" title="statement not covered" > this._requestsManager.finishAllActiveCalculations(keyPart);</span>
1518
- <span class="cstat-no" title="statement not covered" > }</span>
1519
- &nbsp;
1520
- <span class="fstat-no" title="function not covered" > markAsExpiredButDontRemove(key) {</span>
1521
- <span class="cstat-no" title="statement not covered" > if (this._removeExpiredCacheAutomatically) {</span>
1522
- <span class="cstat-no" title="statement not covered" > this._cache.markCacheItemAsExpiredButDontRemove(</span>
1523
- <span class="cstat-no" title="statement not covered" > key,</span>
1524
- <span class="cstat-no" title="statement not covered" > this._cacheTtlMs</span>
1525
- <span class="cstat-no" title="statement not covered" > );</span>
1526
- <span class="cstat-no" title="statement not covered" > } else {</span>
1527
- <span class="cstat-no" title="statement not covered" > this._cache.setLastUpdateTimestamp(</span>
1528
- <span class="cstat-no" title="statement not covered" > key,</span>
1529
- <span class="cstat-no" title="statement not covered" > Date.now() - this._cacheTtlMs - 1</span>
1530
- <span class="cstat-no" title="statement not covered" > );</span>
1531
- <span class="cstat-no" title="statement not covered" > }</span>
1532
- <span class="cstat-no" title="statement not covered" > this._requestsManager.finishAllActiveCalculations(key);</span>
1533
- <span class="cstat-no" title="statement not covered" > }</span>
1534
- }
1535
- &nbsp;
1536
- /**
1537
- * Util class to control access to a resource when it can be called in parallel for the same result.
1538
- * (E.g. getting today coins-fiat rates from some API).
1539
- */
1540
- class ManagerOfRequestsToTheSameResource {
1541
- /**
1542
- * @param bio {string} resource-related identifier for logging
1543
- * @param [maxPollsCount=100] {number} max number of attempts to wait when waiting for a lock acquisition
1544
- * @param [timeoutDuration=1000] {number} timeout between the polls for a lock acquisition
1545
- */
1546
- constructor(bio, maxPollsCount = 100, timeoutDuration = 1000) {
1547
- this.bio = bio;
1548
- this.maxPollsCount = maxPollsCount;
1549
- this.timeoutDuration = timeoutDuration;
1550
- this._activeCalculationsIds = new Map();
1551
- this._nextCalculationIds = new Map();
1552
- }
1553
- &nbsp;
1554
- /**
1555
- * If there is no active calculation just creates uuid and returns it.
1556
- * If there is active calculation waits until it removed from the active calculation uuid variable.
1557
- *
1558
- * @param requestHash {string}
1559
- * @return {Promise&lt;string|boolean&gt;} returns uuid of new active calculation or true if waiting for active
1560
- * calculation succeed or false if max attempts count exceeded
1561
- */
1562
- async startCalculationOrWaitForActiveToFinish(requestHash) {
1563
- try {
1564
- const activeCalculationIdForHash =
1565
- this._activeCalculationsIds.get(requestHash);
1566
- if (activeCalculationIdForHash == null) {
1567
- const id = v4();
1568
- this._activeCalculationsIds.set(requestHash, id);
1569
- return id;
1570
- }
1571
- <span class="cstat-no" title="statement not covered" ><span class="branch-0 cbranch-no" title="branch not covered" ></span></span>
1572
- <span class="cstat-no" title="statement not covered" > return await this._waitForCalculationIdToFinish(</span>
1573
- <span class="cstat-no" title="statement not covered" > requestHash,</span>
1574
- <span class="cstat-no" title="statement not covered" > activeCalculationIdForHash,</span>
1575
- <span class="cstat-no" title="statement not covered" > 0</span>
1576
- <span class="cstat-no" title="statement not covered" > );</span>
1577
- <span class="cstat-no" title="statement not covered" > } catch (e) {</span>
1578
- <span class="cstat-no" title="statement not covered" > Logger.logError(</span>
1579
- <span class="cstat-no" title="statement not covered" > e,</span>
1580
- <span class="cstat-no" title="statement not covered" > `startCalculationOrWaitForActiveToFinish_${this.bio}`</span>
1581
- <span class="cstat-no" title="statement not covered" > );</span>
1582
- <span class="cstat-no" title="statement not covered" > }</span>
1583
- <span class="cstat-no" title="statement not covered" ></span>
1584
- <span class="cstat-no" title="statement not covered" > return null;</span>
1585
- }
1586
- &nbsp;
1587
- /**
1588
- * Acquires lock to the resource by the provided hash.
1589
- *
1590
- * @param requestHash {string}
1591
- * @return {Promise&lt;{ result: true, lockId: string }|{ result: false }&gt;} result is true if the lock is successfully
1592
- * acquired, false if the max allowed time to wait for acquisition expired or any unexpected error occurs
1593
- * during the waiting.
1594
- */
1595
- <span class="fstat-no" title="function not covered" > async acquireLock(requestHash) {</span>
1596
- <span class="cstat-no" title="statement not covered" > try {</span>
1597
- <span class="cstat-no" title="statement not covered" > const activeId = this._activeCalculationsIds.get(requestHash);</span>
1598
- <span class="cstat-no" title="statement not covered" > const nextId = v4();</span>
1599
- <span class="cstat-no" title="statement not covered" > if (activeId == null) {</span>
1600
- <span class="cstat-no" title="statement not covered" > this._activeCalculationsIds.set(requestHash, nextId);</span>
1601
- <span class="cstat-no" title="statement not covered" > return { result: true, lockId: nextId };</span>
1602
- <span class="cstat-no" title="statement not covered" > }</span>
1603
- <span class="cstat-no" title="statement not covered" ></span>
1604
- <span class="cstat-no" title="statement not covered" > const currentNext = this._nextCalculationIds.get(requestHash) ?? [];</span>
1605
- <span class="cstat-no" title="statement not covered" > currentNext.push(nextId);</span>
1606
- <span class="cstat-no" title="statement not covered" > this._nextCalculationIds.set(requestHash, currentNext);</span>
1607
- <span class="cstat-no" title="statement not covered" ></span>
1608
- <span class="cstat-no" title="statement not covered" > const waitingResult = await this._waitForCalculationIdToFinish(</span>
1609
- <span class="cstat-no" title="statement not covered" > requestHash,</span>
1610
- <span class="cstat-no" title="statement not covered" > activeId,</span>
1611
- <span class="cstat-no" title="statement not covered" > 0,</span>
1612
- <span class="cstat-no" title="statement not covered" > nextId</span>
1613
- <span class="cstat-no" title="statement not covered" > );</span>
1614
- <span class="cstat-no" title="statement not covered" > return {</span>
1615
- <span class="cstat-no" title="statement not covered" > result: waitingResult,</span>
1616
- <span class="cstat-no" title="statement not covered" > lockId: waitingResult ? nextId : undefined,</span>
1617
- <span class="cstat-no" title="statement not covered" > };</span>
1618
- <span class="cstat-no" title="statement not covered" > } catch (e) {</span>
1619
- <span class="cstat-no" title="statement not covered" > improveAndRethrow(e, "acquireLock");</span>
1620
- <span class="cstat-no" title="statement not covered" > }</span>
1621
- <span class="cstat-no" title="statement not covered" > }</span>
1622
- &nbsp;
1623
- /**
1624
- * Clears active calculation id.
1625
- * WARNING: if you forget to call this method the start* one will perform maxPollsCount attempts before finishing
1626
- * @param requestHash {string} hash of request. Helps to distinct the request for the same resource but
1627
- * having different request parameters and hold a dedicated calculation id per this hash
1628
- */
1629
- finishActiveCalculation(requestHash = "default") {
1630
- try {
1631
- this._activeCalculationsIds.delete(requestHash);
1632
- const next = this._nextCalculationIds.get(requestHash) ?? [];
1633
- if (next.length) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1634
- <span class="cstat-no" title="statement not covered" > this._activeCalculationsIds.set(requestHash, next[0]);</span>
1635
- <span class="cstat-no" title="statement not covered" > this._nextCalculationIds.set(requestHash, next.slice(1));</span>
1636
- <span class="cstat-no" title="statement not covered" > }</span>
1637
- } <span class="branch-0 cbranch-no" title="branch not covered" >catch (e) {</span>
1638
- <span class="cstat-no" title="statement not covered" > improveAndRethrow(e, "finishActiveCalculation");</span>
1639
- <span class="cstat-no" title="statement not covered" > }</span>
1640
- }
1641
- &nbsp;
1642
- <span class="fstat-no" title="function not covered" > finishAllActiveCalculations(keyPart = "") {</span>
1643
- <span class="cstat-no" title="statement not covered" > try {</span>
1644
- <span class="cstat-no" title="statement not covered" > Array.from(this._activeCalculationsIds.keys()).forEach((hash) =&gt; {</span>
1645
- <span class="cstat-no" title="statement not covered" > if (</span>
1646
- <span class="cstat-no" title="statement not covered" > typeof hash === "string" &amp;&amp;</span>
1647
- <span class="cstat-no" title="statement not covered" > new RegExp(keyPart).test(hash)</span>
1648
- <span class="cstat-no" title="statement not covered" > ) {</span>
1649
- <span class="cstat-no" title="statement not covered" > this.finishActiveCalculation(hash);</span>
1650
- <span class="cstat-no" title="statement not covered" > }</span>
1651
- <span class="cstat-no" title="statement not covered" > });</span>
1652
- <span class="cstat-no" title="statement not covered" > } catch (e) {</span>
1653
- <span class="cstat-no" title="statement not covered" > improveAndRethrow(e, "finishAllActiveCalculations");</span>
1654
- <span class="cstat-no" title="statement not covered" > }</span>
1655
- <span class="cstat-no" title="statement not covered" > }</span>
1656
- &nbsp;
1657
- /**
1658
- * @param requestHash {string}
1659
- * @param lockId {string}
1660
- * @return {boolean}
1661
- */
1662
- isTheLockActiveOne(requestHash, lockId) {
1663
- try {
1664
- return this._activeCalculationsIds.get(requestHash) === lockId;
1665
- } <span class="branch-0 cbranch-no" title="branch not covered" >catch (e) {</span>
1666
- <span class="cstat-no" title="statement not covered" > improveAndRethrow(e, "isTheLockActiveOne");</span>
1667
- <span class="cstat-no" title="statement not covered" > }</span>
1668
- }
1669
- &nbsp;
1670
- /**
1671
- * @param requestHash {string}
1672
- * @param activeCalculationId {string|null}
1673
- * @param [attemptIndex=0] {number}
1674
- * @param waitForCalculationId {string|null} if you want to wait for an exact id to appear as active then pass this parameter
1675
- * @return {Promise&lt;boolean&gt;} true
1676
- * - if the given calculation id is no more an active one
1677
- * - or it is equal to waitForCalculationId
1678
- * false
1679
- * - if waiting period exceeds the max allowed waiting time or unexpected error occurs
1680
- * @private
1681
- */
1682
- <span class="fstat-no" title="function not covered" > async _waitForCalculationIdToFinish(</span>
1683
- <span class="cstat-no" title="statement not covered" > requestHash,</span>
1684
- <span class="cstat-no" title="statement not covered" > activeCalculationId,</span>
1685
- <span class="cstat-no" title="statement not covered" > attemptIndex = 0,</span>
1686
- <span class="cstat-no" title="statement not covered" > waitForCalculationId = null</span>
1687
- <span class="cstat-no" title="statement not covered" > ) {</span>
1688
- <span class="cstat-no" title="statement not covered" > try {</span>
1689
- <span class="cstat-no" title="statement not covered" > if (attemptIndex + 1 &gt; this.maxPollsCount) {</span>
1690
- <span class="cstat-no" title="statement not covered" > // Max number of polls for active calculation id change is achieved. So we return false.</span>
1691
- <span class="cstat-no" title="statement not covered" > return false;</span>
1692
- <span class="cstat-no" title="statement not covered" > }</span>
1693
- <span class="cstat-no" title="statement not covered" ></span>
1694
- <span class="cstat-no" title="statement not covered" > const currentId = this._activeCalculationsIds.get(requestHash);</span>
1695
- <span class="cstat-no" title="statement not covered" > if (</span>
1696
- <span class="cstat-no" title="statement not covered" > waitForCalculationId == null</span>
1697
- <span class="cstat-no" title="statement not covered" > ? currentId !== activeCalculationId</span>
1698
- <span class="cstat-no" title="statement not covered" > : currentId === waitForCalculationId</span>
1699
- <span class="cstat-no" title="statement not covered" > ) {</span>
1700
- <span class="cstat-no" title="statement not covered" > /* We return true depending on the usage of this function:</span>
1701
- <span class="cstat-no" title="statement not covered" > * 1. if there is calculation id that we should wait for to become an active then we return true only</span>
1702
- <span class="cstat-no" title="statement not covered" > * if this id becomes the active one.</span>
1703
- <span class="cstat-no" title="statement not covered" > *</span>
1704
- <span class="cstat-no" title="statement not covered" > * Theoretically we can fail to wait for the desired calculation id. This can be caused by wrong use of</span>
1705
- <span class="cstat-no" title="statement not covered" > * this service or by any other mistakes/errors. But this waiting function will return false anyway if</span>
1706
- <span class="cstat-no" title="statement not covered" > * the number of polls done exceeds the max allowed.</span>
1707
- <span class="cstat-no" title="statement not covered" > *</span>
1708
- <span class="cstat-no" title="statement not covered" > * 2. if we just wait for the currently active calculation id to be finished then we return true</span>
1709
- <span class="cstat-no" title="statement not covered" > * when we notice that the current active id differs from the original passed into this function.</span>
1710
- <span class="cstat-no" title="statement not covered" > */</span>
1711
- <span class="cstat-no" title="statement not covered" > return true;</span>
1712
- <span class="cstat-no" title="statement not covered" > } else {</span>
1713
- <span class="cstat-no" title="statement not covered" > /* The original calculation id is still the active one, so we are scheduling a new attempt to check</span>
1714
- <span class="cstat-no" title="statement not covered" > * whether the active calculation id changed or not in timeoutDuration milliseconds.</span>
1715
- <span class="cstat-no" title="statement not covered" > */</span>
1716
- <span class="cstat-no" title="statement not covered" > const it = this;</span>
1717
- <span class="cstat-no" title="statement not covered" > return new Promise((resolve, reject) =&gt; {</span>
1718
- <span class="cstat-no" title="statement not covered" > setTimeout(function () {</span>
1719
- <span class="cstat-no" title="statement not covered" > try {</span>
1720
- <span class="cstat-no" title="statement not covered" > resolve(</span>
1721
- <span class="cstat-no" title="statement not covered" > it._waitForCalculationIdToFinish(</span>
1722
- <span class="cstat-no" title="statement not covered" > requestHash,</span>
1723
- <span class="cstat-no" title="statement not covered" > activeCalculationId,</span>
1724
- <span class="cstat-no" title="statement not covered" > attemptIndex + 1</span>
1725
- <span class="cstat-no" title="statement not covered" > )</span>
1726
- <span class="cstat-no" title="statement not covered" > );</span>
1727
- <span class="cstat-no" title="statement not covered" > } catch (e) {</span>
1728
- <span class="cstat-no" title="statement not covered" > reject(e);</span>
1729
- <span class="cstat-no" title="statement not covered" > }</span>
1730
- <span class="cstat-no" title="statement not covered" > }, this.timeoutDuration);</span>
1731
- <span class="cstat-no" title="statement not covered" > });</span>
1732
- <span class="cstat-no" title="statement not covered" > }</span>
1733
- <span class="cstat-no" title="statement not covered" > } catch (e) {</span>
1734
- <span class="cstat-no" title="statement not covered" > Logger.logError(</span>
1735
- <span class="cstat-no" title="statement not covered" > e,</span>
1736
- <span class="cstat-no" title="statement not covered" > "_waitForCalculationIdToFinish",</span>
1737
- <span class="cstat-no" title="statement not covered" > "Failed to wait for active calculation id change."</span>
1738
- <span class="cstat-no" title="statement not covered" > );</span>
1739
- <span class="cstat-no" title="statement not covered" > return false;</span>
1740
- <span class="cstat-no" title="statement not covered" > }</span>
1741
- <span class="cstat-no" title="statement not covered" > }</span>
1742
- }
1743
- &nbsp;</pre></td></tr></table></pre>
1744
-
1745
- <div class='push'></div><!-- for sticky footer -->
1746
- </div><!-- /wrapper -->
1747
- <div class='footer quiet pad2 space-top1 center small'>
1748
- Code coverage generated by
1749
- <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1750
- at 2024-04-30T09:26:13.398Z
1751
- </div>
1752
- <script src="../../../prettify.js"></script>
1753
- <script>
1754
- window.onload = function () {
1755
- prettyPrint();
1756
- };
1757
- </script>
1758
- <script src="../../../sorter.js"></script>
1759
- <script src="../../../block-navigation.js"></script>
1760
- </body>
1761
- </html>
1762
-