apostrophe 2.221.0 → 2.221.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/lib/modules/apostrophe-caches/index.js +23 -1
  3. package/lib/modules/apostrophe-soft-redirects/index.js +21 -14
  4. package/package.json +1 -1
  5. package/test/caches.js +29 -0
  6. package/test/soft-redirects.js +16 -3
  7. package/.nyc_output/02d8fb44-f6bc-4ab4-8f47-22c7a42b887d.json +0 -1
  8. package/.nyc_output/14b3f5f0-7e4e-461b-a7d9-4b735f510bd7.json +0 -1
  9. package/.nyc_output/99acae99-becc-463d-ba35-9333f88d2694.json +0 -1
  10. package/.nyc_output/d071f9e0-3b11-44e6-9817-69f184dd064d.json +0 -1
  11. package/.nyc_output/ed000bec-7ff7-49bf-a109-d17bfe883433.json +0 -1
  12. package/.nyc_output/processinfo/02d8fb44-f6bc-4ab4-8f47-22c7a42b887d.json +0 -1
  13. package/.nyc_output/processinfo/14b3f5f0-7e4e-461b-a7d9-4b735f510bd7.json +0 -1
  14. package/.nyc_output/processinfo/99acae99-becc-463d-ba35-9333f88d2694.json +0 -1
  15. package/.nyc_output/processinfo/d071f9e0-3b11-44e6-9817-69f184dd064d.json +0 -1
  16. package/.nyc_output/processinfo/ed000bec-7ff7-49bf-a109-d17bfe883433.json +0 -1
  17. package/.nyc_output/processinfo/index.json +0 -1
  18. package/coverage/a3/defaults.js.html +0 -253
  19. package/coverage/a3/index.html +0 -131
  20. package/coverage/a3/index.js.html +0 -2338
  21. package/coverage/a3/lib/escape-host.js.html +0 -109
  22. package/coverage/a3/lib/index.html +0 -176
  23. package/coverage/a3/lib/mongodb-connect.js.html +0 -250
  24. package/coverage/a3/lib/moog-require.js.html +0 -790
  25. package/coverage/a3/lib/moog.js.html +0 -1711
  26. package/coverage/a3/lib/opentelemetry.js.html +0 -517
  27. package/coverage/a3/modules/@apostrophecms/admin-bar/index.html +0 -116
  28. package/coverage/a3/modules/@apostrophecms/admin-bar/index.js.html +0 -931
  29. package/coverage/a3/modules/@apostrophecms/any-doc-type/index.html +0 -116
  30. package/coverage/a3/modules/@apostrophecms/any-doc-type/index.js.html +0 -115
  31. package/coverage/a3/modules/@apostrophecms/any-page-type/index.html +0 -116
  32. package/coverage/a3/modules/@apostrophecms/any-page-type/index.js.html +0 -1105
  33. package/coverage/a3/modules/@apostrophecms/archive-page/index.html +0 -116
  34. package/coverage/a3/modules/@apostrophecms/archive-page/index.js.html +0 -97
  35. package/coverage/a3/modules/@apostrophecms/area/index.html +0 -116
  36. package/coverage/a3/modules/@apostrophecms/area/index.js.html +0 -2104
  37. package/coverage/a3/modules/@apostrophecms/area/lib/custom-tags/area.js.html +0 -469
  38. package/coverage/a3/modules/@apostrophecms/area/lib/custom-tags/index.html +0 -131
  39. package/coverage/a3/modules/@apostrophecms/area/lib/custom-tags/widget.js.html +0 -286
  40. package/coverage/a3/modules/@apostrophecms/asset/index.html +0 -116
  41. package/coverage/a3/modules/@apostrophecms/asset/index.js.html +0 -3982
  42. package/coverage/a3/modules/@apostrophecms/asset/lib/globalIcons.js.html +0 -346
  43. package/coverage/a3/modules/@apostrophecms/asset/lib/index.html +0 -116
  44. package/coverage/a3/modules/@apostrophecms/asset/lib/webpack/apos/index.html +0 -131
  45. package/coverage/a3/modules/@apostrophecms/asset/lib/webpack/apos/webpack.scss.js.html +0 -289
  46. package/coverage/a3/modules/@apostrophecms/asset/lib/webpack/apos/webpack.vue.js.html +0 -148
  47. package/coverage/a3/modules/@apostrophecms/asset/lib/webpack/index.html +0 -116
  48. package/coverage/a3/modules/@apostrophecms/asset/lib/webpack/src/index.html +0 -131
  49. package/coverage/a3/modules/@apostrophecms/asset/lib/webpack/src/webpack.es5.js.html +0 -184
  50. package/coverage/a3/modules/@apostrophecms/asset/lib/webpack/src/webpack.scss.js.html +0 -238
  51. package/coverage/a3/modules/@apostrophecms/asset/lib/webpack/utils.js.html +0 -958
  52. package/coverage/a3/modules/@apostrophecms/attachment/index.html +0 -116
  53. package/coverage/a3/modules/@apostrophecms/attachment/index.js.html +0 -3676
  54. package/coverage/a3/modules/@apostrophecms/attachment/lib/index.html +0 -116
  55. package/coverage/a3/modules/@apostrophecms/attachment/lib/legacy-migrations.js.html +0 -205
  56. package/coverage/a3/modules/@apostrophecms/attachment/lib/tasks/index.html +0 -116
  57. package/coverage/a3/modules/@apostrophecms/attachment/lib/tasks/rescale.js.html +0 -328
  58. package/coverage/a3/modules/@apostrophecms/busy/index.html +0 -116
  59. package/coverage/a3/modules/@apostrophecms/busy/index.js.html +0 -145
  60. package/coverage/a3/modules/@apostrophecms/cache/index.html +0 -116
  61. package/coverage/a3/modules/@apostrophecms/cache/index.js.html +0 -424
  62. package/coverage/a3/modules/@apostrophecms/db/index.html +0 -116
  63. package/coverage/a3/modules/@apostrophecms/db/index.js.html +0 -640
  64. package/coverage/a3/modules/@apostrophecms/doc/index.html +0 -116
  65. package/coverage/a3/modules/@apostrophecms/doc/index.js.html +0 -3937
  66. package/coverage/a3/modules/@apostrophecms/doc/lib/index.html +0 -116
  67. package/coverage/a3/modules/@apostrophecms/doc/lib/legacy-migrations.js.html +0 -622
  68. package/coverage/a3/modules/@apostrophecms/doc-type/index.html +0 -116
  69. package/coverage/a3/modules/@apostrophecms/doc-type/index.js.html +0 -8638
  70. package/coverage/a3/modules/@apostrophecms/doc-type/lib/autocomplete.js.html +0 -319
  71. package/coverage/a3/modules/@apostrophecms/doc-type/lib/index.html +0 -116
  72. package/coverage/a3/modules/@apostrophecms/email/index.html +0 -116
  73. package/coverage/a3/modules/@apostrophecms/email/index.js.html +0 -301
  74. package/coverage/a3/modules/@apostrophecms/error/index.html +0 -116
  75. package/coverage/a3/modules/@apostrophecms/error/index.js.html +0 -202
  76. package/coverage/a3/modules/@apostrophecms/express/index.html +0 -116
  77. package/coverage/a3/modules/@apostrophecms/express/index.js.html +0 -2116
  78. package/coverage/a3/modules/@apostrophecms/file/index.html +0 -116
  79. package/coverage/a3/modules/@apostrophecms/file/index.js.html +0 -367
  80. package/coverage/a3/modules/@apostrophecms/file-tag/index.html +0 -116
  81. package/coverage/a3/modules/@apostrophecms/file-tag/index.js.html +0 -127
  82. package/coverage/a3/modules/@apostrophecms/global/index.html +0 -116
  83. package/coverage/a3/modules/@apostrophecms/global/index.js.html +0 -535
  84. package/coverage/a3/modules/@apostrophecms/home-page/index.html +0 -116
  85. package/coverage/a3/modules/@apostrophecms/home-page/index.js.html +0 -94
  86. package/coverage/a3/modules/@apostrophecms/html-widget/index.html +0 -116
  87. package/coverage/a3/modules/@apostrophecms/html-widget/index.js.html +0 -271
  88. package/coverage/a3/modules/@apostrophecms/http/index.html +0 -116
  89. package/coverage/a3/modules/@apostrophecms/http/index.js.html +0 -976
  90. package/coverage/a3/modules/@apostrophecms/i18n/index.html +0 -116
  91. package/coverage/a3/modules/@apostrophecms/i18n/index.js.html +0 -2083
  92. package/coverage/a3/modules/@apostrophecms/image/index.html +0 -116
  93. package/coverage/a3/modules/@apostrophecms/image/index.js.html +0 -1486
  94. package/coverage/a3/modules/@apostrophecms/image-tag/index.html +0 -116
  95. package/coverage/a3/modules/@apostrophecms/image-tag/index.js.html +0 -127
  96. package/coverage/a3/modules/@apostrophecms/image-widget/index.html +0 -116
  97. package/coverage/a3/modules/@apostrophecms/image-widget/index.js.html +0 -145
  98. package/coverage/a3/modules/@apostrophecms/job/index.html +0 -116
  99. package/coverage/a3/modules/@apostrophecms/job/index.js.html +0 -1321
  100. package/coverage/a3/modules/@apostrophecms/launder/index.html +0 -116
  101. package/coverage/a3/modules/@apostrophecms/launder/index.js.html +0 -124
  102. package/coverage/a3/modules/@apostrophecms/lock/index.html +0 -116
  103. package/coverage/a3/modules/@apostrophecms/lock/index.js.html +0 -676
  104. package/coverage/a3/modules/@apostrophecms/login/index.html +0 -116
  105. package/coverage/a3/modules/@apostrophecms/login/index.js.html +0 -2617
  106. package/coverage/a3/modules/@apostrophecms/migration/index.html +0 -116
  107. package/coverage/a3/modules/@apostrophecms/migration/index.js.html +0 -970
  108. package/coverage/a3/modules/@apostrophecms/modal/index.html +0 -116
  109. package/coverage/a3/modules/@apostrophecms/modal/index.js.html +0 -193
  110. package/coverage/a3/modules/@apostrophecms/module/index.html +0 -116
  111. package/coverage/a3/modules/@apostrophecms/module/index.js.html +0 -2500
  112. package/coverage/a3/modules/@apostrophecms/module/lib/events.js.html +0 -547
  113. package/coverage/a3/modules/@apostrophecms/module/lib/index.html +0 -116
  114. package/coverage/a3/modules/@apostrophecms/notification/index.html +0 -116
  115. package/coverage/a3/modules/@apostrophecms/notification/index.js.html +0 -1315
  116. package/coverage/a3/modules/@apostrophecms/oembed/index.html +0 -116
  117. package/coverage/a3/modules/@apostrophecms/oembed/index.js.html +0 -781
  118. package/coverage/a3/modules/@apostrophecms/oembed/lib/index.html +0 -161
  119. package/coverage/a3/modules/@apostrophecms/oembed/lib/infogram.js.html +0 -178
  120. package/coverage/a3/modules/@apostrophecms/oembed/lib/vimeo.js.html +0 -124
  121. package/coverage/a3/modules/@apostrophecms/oembed/lib/wufoo.js.html +0 -256
  122. package/coverage/a3/modules/@apostrophecms/oembed/lib/youtube.js.html +0 -322
  123. package/coverage/a3/modules/@apostrophecms/oembed-field/index.html +0 -116
  124. package/coverage/a3/modules/@apostrophecms/oembed-field/index.js.html +0 -268
  125. package/coverage/a3/modules/@apostrophecms/page/index.html +0 -116
  126. package/coverage/a3/modules/@apostrophecms/page/index.js.html +0 -6955
  127. package/coverage/a3/modules/@apostrophecms/page/lib/index.html +0 -116
  128. package/coverage/a3/modules/@apostrophecms/page/lib/legacy-migrations.js.html +0 -568
  129. package/coverage/a3/modules/@apostrophecms/page-type/index.html +0 -116
  130. package/coverage/a3/modules/@apostrophecms/page-type/index.js.html +0 -1501
  131. package/coverage/a3/modules/@apostrophecms/pager/index.html +0 -116
  132. package/coverage/a3/modules/@apostrophecms/pager/index.js.html +0 -232
  133. package/coverage/a3/modules/@apostrophecms/permission/index.html +0 -116
  134. package/coverage/a3/modules/@apostrophecms/permission/index.js.html +0 -1057
  135. package/coverage/a3/modules/@apostrophecms/permission/lib/index.html +0 -116
  136. package/coverage/a3/modules/@apostrophecms/permission/lib/legacy-migrations.js.html +0 -160
  137. package/coverage/a3/modules/@apostrophecms/piece-page-type/index.html +0 -116
  138. package/coverage/a3/modules/@apostrophecms/piece-page-type/index.js.html +0 -1051
  139. package/coverage/a3/modules/@apostrophecms/piece-type/index.html +0 -116
  140. package/coverage/a3/modules/@apostrophecms/piece-type/index.js.html +0 -3103
  141. package/coverage/a3/modules/@apostrophecms/polymorphic-type/index.html +0 -116
  142. package/coverage/a3/modules/@apostrophecms/polymorphic-type/index.js.html +0 -157
  143. package/coverage/a3/modules/@apostrophecms/rich-text-widget/index.html +0 -116
  144. package/coverage/a3/modules/@apostrophecms/rich-text-widget/index.js.html +0 -1363
  145. package/coverage/a3/modules/@apostrophecms/schema/index.html +0 -116
  146. package/coverage/a3/modules/@apostrophecms/schema/index.js.html +0 -4603
  147. package/coverage/a3/modules/@apostrophecms/schema/lib/addFieldTypes.js.html +0 -3502
  148. package/coverage/a3/modules/@apostrophecms/schema/lib/index.html +0 -131
  149. package/coverage/a3/modules/@apostrophecms/schema/lib/joinr.js.html +0 -703
  150. package/coverage/a3/modules/@apostrophecms/search/index.html +0 -116
  151. package/coverage/a3/modules/@apostrophecms/search/index.js.html +0 -1222
  152. package/coverage/a3/modules/@apostrophecms/soft-redirect/index.html +0 -116
  153. package/coverage/a3/modules/@apostrophecms/soft-redirect/index.js.html +0 -343
  154. package/coverage/a3/modules/@apostrophecms/submitted-draft/index.html +0 -116
  155. package/coverage/a3/modules/@apostrophecms/submitted-draft/index.js.html +0 -595
  156. package/coverage/a3/modules/@apostrophecms/task/index.html +0 -116
  157. package/coverage/a3/modules/@apostrophecms/task/index.js.html +0 -1147
  158. package/coverage/a3/modules/@apostrophecms/template/index.html +0 -116
  159. package/coverage/a3/modules/@apostrophecms/template/index.js.html +0 -2731
  160. package/coverage/a3/modules/@apostrophecms/template/lib/bundlesLoader.js.html +0 -559
  161. package/coverage/a3/modules/@apostrophecms/template/lib/custom-tags/component.js.html +0 -310
  162. package/coverage/a3/modules/@apostrophecms/template/lib/custom-tags/fragment.js.html +0 -325
  163. package/coverage/a3/modules/@apostrophecms/template/lib/custom-tags/index.html +0 -146
  164. package/coverage/a3/modules/@apostrophecms/template/lib/custom-tags/render.js.html +0 -490
  165. package/coverage/a3/modules/@apostrophecms/template/lib/index.html +0 -131
  166. package/coverage/a3/modules/@apostrophecms/template/lib/nunjucksLoader.js.html +0 -658
  167. package/coverage/a3/modules/@apostrophecms/ui/index.html +0 -116
  168. package/coverage/a3/modules/@apostrophecms/ui/index.js.html +0 -181
  169. package/coverage/a3/modules/@apostrophecms/uploadfs/index.html +0 -116
  170. package/coverage/a3/modules/@apostrophecms/uploadfs/index.js.html +0 -286
  171. package/coverage/a3/modules/@apostrophecms/url/index.html +0 -116
  172. package/coverage/a3/modules/@apostrophecms/url/index.js.html +0 -733
  173. package/coverage/a3/modules/@apostrophecms/user/index.html +0 -116
  174. package/coverage/a3/modules/@apostrophecms/user/index.js.html +0 -1684
  175. package/coverage/a3/modules/@apostrophecms/user/lib/index.html +0 -116
  176. package/coverage/a3/modules/@apostrophecms/user/lib/legacy-migrations.js.html +0 -157
  177. package/coverage/a3/modules/@apostrophecms/util/index.html +0 -116
  178. package/coverage/a3/modules/@apostrophecms/util/index.js.html +0 -3424
  179. package/coverage/a3/modules/@apostrophecms/util/lib/index.html +0 -116
  180. package/coverage/a3/modules/@apostrophecms/util/lib/logger.js.html +0 -319
  181. package/coverage/a3/modules/@apostrophecms/video-widget/index.html +0 -116
  182. package/coverage/a3/modules/@apostrophecms/video-widget/index.js.html +0 -178
  183. package/coverage/a3/modules/@apostrophecms/widget-type/index.html +0 -116
  184. package/coverage/a3/modules/@apostrophecms/widget-type/index.js.html +0 -1225
  185. package/coverage/a3/test-lib/index.html +0 -131
  186. package/coverage/a3/test-lib/test.js.html +0 -232
  187. package/coverage/a3/test-lib/util.js.html +0 -373
  188. package/coverage/base.css +0 -224
  189. package/coverage/block-navigation.js +0 -87
  190. package/coverage/favicon.png +0 -0
  191. package/coverage/index.html +0 -1256
  192. package/coverage/prettify.css +0 -1
  193. package/coverage/prettify.js +0 -2
  194. package/coverage/sort-arrow-sprite.png +0 -0
  195. package/coverage/sorter.js +0 -196
@@ -1,1684 +0,0 @@
1
-
2
- <!doctype html>
3
- <html lang="en">
4
-
5
- <head>
6
- <title>Code coverage report for a3/modules/@apostrophecms/user/index.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">a3/modules/@apostrophecms/user</a> index.js</h1>
23
- <div class='clearfix'>
24
-
25
- <div class='fl pad1y space-right2'>
26
- <span class="strong">58.65% </span>
27
- <span class="quiet">Statements</span>
28
- <span class='fraction'>61/104</span>
29
- </div>
30
-
31
-
32
- <div class='fl pad1y space-right2'>
33
- <span class="strong">46.93% </span>
34
- <span class="quiet">Branches</span>
35
- <span class='fraction'>23/49</span>
36
- </div>
37
-
38
-
39
- <div class='fl pad1y space-right2'>
40
- <span class="strong">76.47% </span>
41
- <span class="quiet">Functions</span>
42
- <span class='fraction'>26/34</span>
43
- </div>
44
-
45
-
46
- <div class='fl pad1y space-right2'>
47
- <span class="strong">58.65% </span>
48
- <span class="quiet">Lines</span>
49
- <span class='fraction'>61/104</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></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
600
- <span class="cline-any cline-neutral">&nbsp;</span>
601
- <span class="cline-any cline-neutral">&nbsp;</span>
602
- <span class="cline-any cline-neutral">&nbsp;</span>
603
- <span class="cline-any cline-neutral">&nbsp;</span>
604
- <span class="cline-any cline-neutral">&nbsp;</span>
605
- <span class="cline-any cline-neutral">&nbsp;</span>
606
- <span class="cline-any cline-neutral">&nbsp;</span>
607
- <span class="cline-any cline-neutral">&nbsp;</span>
608
- <span class="cline-any cline-neutral">&nbsp;</span>
609
- <span class="cline-any cline-neutral">&nbsp;</span>
610
- <span class="cline-any cline-neutral">&nbsp;</span>
611
- <span class="cline-any cline-neutral">&nbsp;</span>
612
- <span class="cline-any cline-neutral">&nbsp;</span>
613
- <span class="cline-any cline-neutral">&nbsp;</span>
614
- <span class="cline-any cline-neutral">&nbsp;</span>
615
- <span class="cline-any cline-neutral">&nbsp;</span>
616
- <span class="cline-any cline-neutral">&nbsp;</span>
617
- <span class="cline-any cline-neutral">&nbsp;</span>
618
- <span class="cline-any cline-neutral">&nbsp;</span>
619
- <span class="cline-any cline-neutral">&nbsp;</span>
620
- <span class="cline-any cline-neutral">&nbsp;</span>
621
- <span class="cline-any cline-neutral">&nbsp;</span>
622
- <span class="cline-any cline-neutral">&nbsp;</span>
623
- <span class="cline-any cline-neutral">&nbsp;</span>
624
- <span class="cline-any cline-neutral">&nbsp;</span>
625
- <span class="cline-any cline-neutral">&nbsp;</span>
626
- <span class="cline-any cline-neutral">&nbsp;</span>
627
- <span class="cline-any cline-neutral">&nbsp;</span>
628
- <span class="cline-any cline-neutral">&nbsp;</span>
629
- <span class="cline-any cline-neutral">&nbsp;</span>
630
- <span class="cline-any cline-yes">90x</span>
631
- <span class="cline-any cline-yes">90x</span>
632
- <span class="cline-any cline-yes">90x</span>
633
- <span class="cline-any cline-neutral">&nbsp;</span>
634
- <span class="cline-any cline-yes">90x</span>
635
- <span class="cline-any cline-neutral">&nbsp;</span>
636
- <span class="cline-any cline-neutral">&nbsp;</span>
637
- <span class="cline-any cline-neutral">&nbsp;</span>
638
- <span class="cline-any cline-neutral">&nbsp;</span>
639
- <span class="cline-any cline-neutral">&nbsp;</span>
640
- <span class="cline-any cline-neutral">&nbsp;</span>
641
- <span class="cline-any cline-neutral">&nbsp;</span>
642
- <span class="cline-any cline-neutral">&nbsp;</span>
643
- <span class="cline-any cline-neutral">&nbsp;</span>
644
- <span class="cline-any cline-neutral">&nbsp;</span>
645
- <span class="cline-any cline-neutral">&nbsp;</span>
646
- <span class="cline-any cline-neutral">&nbsp;</span>
647
- <span class="cline-any cline-neutral">&nbsp;</span>
648
- <span class="cline-any cline-neutral">&nbsp;</span>
649
- <span class="cline-any cline-neutral">&nbsp;</span>
650
- <span class="cline-any cline-neutral">&nbsp;</span>
651
- <span class="cline-any cline-yes">90x</span>
652
- <span class="cline-any cline-neutral">&nbsp;</span>
653
- <span class="cline-any cline-neutral">&nbsp;</span>
654
- <span class="cline-any cline-neutral">&nbsp;</span>
655
- <span class="cline-any cline-neutral">&nbsp;</span>
656
- <span class="cline-any cline-neutral">&nbsp;</span>
657
- <span class="cline-any cline-neutral">&nbsp;</span>
658
- <span class="cline-any cline-neutral">&nbsp;</span>
659
- <span class="cline-any cline-neutral">&nbsp;</span>
660
- <span class="cline-any cline-neutral">&nbsp;</span>
661
- <span class="cline-any cline-neutral">&nbsp;</span>
662
- <span class="cline-any cline-neutral">&nbsp;</span>
663
- <span class="cline-any cline-neutral">&nbsp;</span>
664
- <span class="cline-any cline-neutral">&nbsp;</span>
665
- <span class="cline-any cline-neutral">&nbsp;</span>
666
- <span class="cline-any cline-neutral">&nbsp;</span>
667
- <span class="cline-any cline-neutral">&nbsp;</span>
668
- <span class="cline-any cline-neutral">&nbsp;</span>
669
- <span class="cline-any cline-neutral">&nbsp;</span>
670
- <span class="cline-any cline-neutral">&nbsp;</span>
671
- <span class="cline-any cline-neutral">&nbsp;</span>
672
- <span class="cline-any cline-neutral">&nbsp;</span>
673
- <span class="cline-any cline-neutral">&nbsp;</span>
674
- <span class="cline-any cline-neutral">&nbsp;</span>
675
- <span class="cline-any cline-neutral">&nbsp;</span>
676
- <span class="cline-any cline-neutral">&nbsp;</span>
677
- <span class="cline-any cline-neutral">&nbsp;</span>
678
- <span class="cline-any cline-neutral">&nbsp;</span>
679
- <span class="cline-any cline-neutral">&nbsp;</span>
680
- <span class="cline-any cline-neutral">&nbsp;</span>
681
- <span class="cline-any cline-neutral">&nbsp;</span>
682
- <span class="cline-any cline-neutral">&nbsp;</span>
683
- <span class="cline-any cline-neutral">&nbsp;</span>
684
- <span class="cline-any cline-neutral">&nbsp;</span>
685
- <span class="cline-any cline-neutral">&nbsp;</span>
686
- <span class="cline-any cline-neutral">&nbsp;</span>
687
- <span class="cline-any cline-neutral">&nbsp;</span>
688
- <span class="cline-any cline-neutral">&nbsp;</span>
689
- <span class="cline-any cline-neutral">&nbsp;</span>
690
- <span class="cline-any cline-neutral">&nbsp;</span>
691
- <span class="cline-any cline-neutral">&nbsp;</span>
692
- <span class="cline-any cline-neutral">&nbsp;</span>
693
- <span class="cline-any cline-neutral">&nbsp;</span>
694
- <span class="cline-any cline-neutral">&nbsp;</span>
695
- <span class="cline-any cline-neutral">&nbsp;</span>
696
- <span class="cline-any cline-neutral">&nbsp;</span>
697
- <span class="cline-any cline-neutral">&nbsp;</span>
698
- <span class="cline-any cline-neutral">&nbsp;</span>
699
- <span class="cline-any cline-neutral">&nbsp;</span>
700
- <span class="cline-any cline-neutral">&nbsp;</span>
701
- <span class="cline-any cline-neutral">&nbsp;</span>
702
- <span class="cline-any cline-neutral">&nbsp;</span>
703
- <span class="cline-any cline-neutral">&nbsp;</span>
704
- <span class="cline-any cline-neutral">&nbsp;</span>
705
- <span class="cline-any cline-neutral">&nbsp;</span>
706
- <span class="cline-any cline-neutral">&nbsp;</span>
707
- <span class="cline-any cline-neutral">&nbsp;</span>
708
- <span class="cline-any cline-neutral">&nbsp;</span>
709
- <span class="cline-any cline-neutral">&nbsp;</span>
710
- <span class="cline-any cline-neutral">&nbsp;</span>
711
- <span class="cline-any cline-neutral">&nbsp;</span>
712
- <span class="cline-any cline-neutral">&nbsp;</span>
713
- <span class="cline-any cline-neutral">&nbsp;</span>
714
- <span class="cline-any cline-neutral">&nbsp;</span>
715
- <span class="cline-any cline-neutral">&nbsp;</span>
716
- <span class="cline-any cline-neutral">&nbsp;</span>
717
- <span class="cline-any cline-neutral">&nbsp;</span>
718
- <span class="cline-any cline-neutral">&nbsp;</span>
719
- <span class="cline-any cline-neutral">&nbsp;</span>
720
- <span class="cline-any cline-neutral">&nbsp;</span>
721
- <span class="cline-any cline-neutral">&nbsp;</span>
722
- <span class="cline-any cline-neutral">&nbsp;</span>
723
- <span class="cline-any cline-neutral">&nbsp;</span>
724
- <span class="cline-any cline-neutral">&nbsp;</span>
725
- <span class="cline-any cline-neutral">&nbsp;</span>
726
- <span class="cline-any cline-neutral">&nbsp;</span>
727
- <span class="cline-any cline-neutral">&nbsp;</span>
728
- <span class="cline-any cline-neutral">&nbsp;</span>
729
- <span class="cline-any cline-neutral">&nbsp;</span>
730
- <span class="cline-any cline-neutral">&nbsp;</span>
731
- <span class="cline-any cline-neutral">&nbsp;</span>
732
- <span class="cline-any cline-neutral">&nbsp;</span>
733
- <span class="cline-any cline-neutral">&nbsp;</span>
734
- <span class="cline-any cline-neutral">&nbsp;</span>
735
- <span class="cline-any cline-neutral">&nbsp;</span>
736
- <span class="cline-any cline-neutral">&nbsp;</span>
737
- <span class="cline-any cline-neutral">&nbsp;</span>
738
- <span class="cline-any cline-yes">90x</span>
739
- <span class="cline-any cline-yes">90x</span>
740
- <span class="cline-any cline-yes">90x</span>
741
- <span class="cline-any cline-yes">90x</span>
742
- <span class="cline-any cline-yes">90x</span>
743
- <span class="cline-any cline-neutral">&nbsp;</span>
744
- <span class="cline-any cline-neutral">&nbsp;</span>
745
- <span class="cline-any cline-yes">90x</span>
746
- <span class="cline-any cline-neutral">&nbsp;</span>
747
- <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
751
- <span class="cline-any cline-neutral">&nbsp;</span>
752
- <span class="cline-any cline-neutral">&nbsp;</span>
753
- <span class="cline-any cline-no">&nbsp;</span>
754
- <span class="cline-any cline-no">&nbsp;</span>
755
- <span class="cline-any cline-neutral">&nbsp;</span>
756
- <span class="cline-any cline-neutral">&nbsp;</span>
757
- <span class="cline-any cline-neutral">&nbsp;</span>
758
- <span class="cline-any cline-neutral">&nbsp;</span>
759
- <span class="cline-any cline-neutral">&nbsp;</span>
760
- <span class="cline-any cline-neutral">&nbsp;</span>
761
- <span class="cline-any cline-yes">90x</span>
762
- <span class="cline-any cline-neutral">&nbsp;</span>
763
- <span class="cline-any cline-neutral">&nbsp;</span>
764
- <span class="cline-any cline-yes">18x</span>
765
- <span class="cline-any cline-yes">1x</span>
766
- <span class="cline-any cline-neutral">&nbsp;</span>
767
- <span class="cline-any cline-neutral">&nbsp;</span>
768
- <span class="cline-any cline-neutral">&nbsp;</span>
769
- <span class="cline-any cline-yes">18x</span>
770
- <span class="cline-any cline-neutral">&nbsp;</span>
771
- <span class="cline-any cline-neutral">&nbsp;</span>
772
- <span class="cline-any cline-neutral">&nbsp;</span>
773
- <span class="cline-any cline-neutral">&nbsp;</span>
774
- <span class="cline-any cline-yes">11x</span>
775
- <span class="cline-any cline-neutral">&nbsp;</span>
776
- <span class="cline-any cline-neutral">&nbsp;</span>
777
- <span class="cline-any cline-neutral">&nbsp;</span>
778
- <span class="cline-any cline-neutral">&nbsp;</span>
779
- <span class="cline-any cline-neutral">&nbsp;</span>
780
- <span class="cline-any cline-neutral">&nbsp;</span>
781
- <span class="cline-any cline-neutral">&nbsp;</span>
782
- <span class="cline-any cline-neutral">&nbsp;</span>
783
- <span class="cline-any cline-yes">28x</span>
784
- <span class="cline-any cline-no">&nbsp;</span>
785
- <span class="cline-any cline-neutral">&nbsp;</span>
786
- <span class="cline-any cline-neutral">&nbsp;</span>
787
- <span class="cline-any cline-neutral">&nbsp;</span>
788
- <span class="cline-any cline-yes">28x</span>
789
- <span class="cline-any cline-neutral">&nbsp;</span>
790
- <span class="cline-any cline-neutral">&nbsp;</span>
791
- <span class="cline-any cline-yes">28x</span>
792
- <span class="cline-any cline-neutral">&nbsp;</span>
793
- <span class="cline-any cline-yes">20x</span>
794
- <span class="cline-any cline-neutral">&nbsp;</span>
795
- <span class="cline-any cline-yes">20x</span>
796
- <span class="cline-any cline-neutral">&nbsp;</span>
797
- <span class="cline-any cline-neutral">&nbsp;</span>
798
- <span class="cline-any cline-neutral">&nbsp;</span>
799
- <span class="cline-any cline-neutral">&nbsp;</span>
800
- <span class="cline-any cline-neutral">&nbsp;</span>
801
- <span class="cline-any cline-neutral">&nbsp;</span>
802
- <span class="cline-any cline-neutral">&nbsp;</span>
803
- <span class="cline-any cline-neutral">&nbsp;</span>
804
- <span class="cline-any cline-yes">2x</span>
805
- <span class="cline-any cline-neutral">&nbsp;</span>
806
- <span class="cline-any cline-neutral">&nbsp;</span>
807
- <span class="cline-any cline-neutral">&nbsp;</span>
808
- <span class="cline-any cline-neutral">&nbsp;</span>
809
- <span class="cline-any cline-neutral">&nbsp;</span>
810
- <span class="cline-any cline-yes">2x</span>
811
- <span class="cline-any cline-neutral">&nbsp;</span>
812
- <span class="cline-any cline-neutral">&nbsp;</span>
813
- <span class="cline-any cline-neutral">&nbsp;</span>
814
- <span class="cline-any cline-neutral">&nbsp;</span>
815
- <span class="cline-any cline-neutral">&nbsp;</span>
816
- <span class="cline-any cline-yes">90x</span>
817
- <span class="cline-any cline-neutral">&nbsp;</span>
818
- <span class="cline-any cline-neutral">&nbsp;</span>
819
- <span class="cline-any cline-neutral">&nbsp;</span>
820
- <span class="cline-any cline-neutral">&nbsp;</span>
821
- <span class="cline-any cline-neutral">&nbsp;</span>
822
- <span class="cline-any cline-neutral">&nbsp;</span>
823
- <span class="cline-any cline-neutral">&nbsp;</span>
824
- <span class="cline-any cline-yes">90x</span>
825
- <span class="cline-any cline-neutral">&nbsp;</span>
826
- <span class="cline-any cline-neutral">&nbsp;</span>
827
- <span class="cline-any cline-neutral">&nbsp;</span>
828
- <span class="cline-any cline-neutral">&nbsp;</span>
829
- <span class="cline-any cline-neutral">&nbsp;</span>
830
- <span class="cline-any cline-neutral">&nbsp;</span>
831
- <span class="cline-any cline-neutral">&nbsp;</span>
832
- <span class="cline-any cline-neutral">&nbsp;</span>
833
- <span class="cline-any cline-neutral">&nbsp;</span>
834
- <span class="cline-any cline-yes">90x</span>
835
- <span class="cline-any cline-neutral">&nbsp;</span>
836
- <span class="cline-any cline-neutral">&nbsp;</span>
837
- <span class="cline-any cline-neutral">&nbsp;</span>
838
- <span class="cline-any cline-neutral">&nbsp;</span>
839
- <span class="cline-any cline-neutral">&nbsp;</span>
840
- <span class="cline-any cline-yes">90x</span>
841
- <span class="cline-any cline-yes">90x</span>
842
- <span class="cline-any cline-neutral">&nbsp;</span>
843
- <span class="cline-any cline-neutral">&nbsp;</span>
844
- <span class="cline-any cline-neutral">&nbsp;</span>
845
- <span class="cline-any cline-neutral">&nbsp;</span>
846
- <span class="cline-any cline-neutral">&nbsp;</span>
847
- <span class="cline-any cline-yes">90x</span>
848
- <span class="cline-any cline-neutral">&nbsp;</span>
849
- <span class="cline-any cline-neutral">&nbsp;</span>
850
- <span class="cline-any cline-neutral">&nbsp;</span>
851
- <span class="cline-any cline-neutral">&nbsp;</span>
852
- <span class="cline-any cline-neutral">&nbsp;</span>
853
- <span class="cline-any cline-yes">90x</span>
854
- <span class="cline-any cline-yes">90x</span>
855
- <span class="cline-any cline-neutral">&nbsp;</span>
856
- <span class="cline-any cline-neutral">&nbsp;</span>
857
- <span class="cline-any cline-neutral">&nbsp;</span>
858
- <span class="cline-any cline-neutral">&nbsp;</span>
859
- <span class="cline-any cline-neutral">&nbsp;</span>
860
- <span class="cline-any cline-neutral">&nbsp;</span>
861
- <span class="cline-any cline-neutral">&nbsp;</span>
862
- <span class="cline-any cline-neutral">&nbsp;</span>
863
- <span class="cline-any cline-neutral">&nbsp;</span>
864
- <span class="cline-any cline-neutral">&nbsp;</span>
865
- <span class="cline-any cline-neutral">&nbsp;</span>
866
- <span class="cline-any cline-no">&nbsp;</span>
867
- <span class="cline-any cline-no">&nbsp;</span>
868
- <span class="cline-any cline-no">&nbsp;</span>
869
- <span class="cline-any cline-no">&nbsp;</span>
870
- <span class="cline-any cline-neutral">&nbsp;</span>
871
- <span class="cline-any cline-neutral">&nbsp;</span>
872
- <span class="cline-any cline-neutral">&nbsp;</span>
873
- <span class="cline-any cline-neutral">&nbsp;</span>
874
- <span class="cline-any cline-neutral">&nbsp;</span>
875
- <span class="cline-any cline-neutral">&nbsp;</span>
876
- <span class="cline-any cline-neutral">&nbsp;</span>
877
- <span class="cline-any cline-neutral">&nbsp;</span>
878
- <span class="cline-any cline-neutral">&nbsp;</span>
879
- <span class="cline-any cline-neutral">&nbsp;</span>
880
- <span class="cline-any cline-neutral">&nbsp;</span>
881
- <span class="cline-any cline-neutral">&nbsp;</span>
882
- <span class="cline-any cline-yes">33x</span>
883
- <span class="cline-any cline-neutral">&nbsp;</span>
884
- <span class="cline-any cline-neutral">&nbsp;</span>
885
- <span class="cline-any cline-neutral">&nbsp;</span>
886
- <span class="cline-any cline-neutral">&nbsp;</span>
887
- <span class="cline-any cline-neutral">&nbsp;</span>
888
- <span class="cline-any cline-yes">33x</span>
889
- <span class="cline-any cline-yes">33x</span>
890
- <span class="cline-any cline-neutral">&nbsp;</span>
891
- <span class="cline-any cline-neutral">&nbsp;</span>
892
- <span class="cline-any cline-yes">33x</span>
893
- <span class="cline-any cline-yes">33x</span>
894
- <span class="cline-any cline-yes">33x</span>
895
- <span class="cline-any cline-yes">18x</span>
896
- <span class="cline-any cline-neutral">&nbsp;</span>
897
- <span class="cline-any cline-yes">15x</span>
898
- <span class="cline-any cline-yes">15x</span>
899
- <span class="cline-any cline-neutral">&nbsp;</span>
900
- <span class="cline-any cline-no">&nbsp;</span>
901
- <span class="cline-any cline-neutral">&nbsp;</span>
902
- <span class="cline-any cline-yes">15x</span>
903
- <span class="cline-any cline-neutral">&nbsp;</span>
904
- <span class="cline-any cline-neutral">&nbsp;</span>
905
- <span class="cline-any cline-neutral">&nbsp;</span>
906
- <span class="cline-any cline-neutral">&nbsp;</span>
907
- <span class="cline-any cline-neutral">&nbsp;</span>
908
- <span class="cline-any cline-neutral">&nbsp;</span>
909
- <span class="cline-any cline-neutral">&nbsp;</span>
910
- <span class="cline-any cline-neutral">&nbsp;</span>
911
- <span class="cline-any cline-neutral">&nbsp;</span>
912
- <span class="cline-any cline-neutral">&nbsp;</span>
913
- <span class="cline-any cline-neutral">&nbsp;</span>
914
- <span class="cline-any cline-yes">33x</span>
915
- <span class="cline-any cline-neutral">&nbsp;</span>
916
- <span class="cline-any cline-neutral">&nbsp;</span>
917
- <span class="cline-any cline-neutral">&nbsp;</span>
918
- <span class="cline-any cline-neutral">&nbsp;</span>
919
- <span class="cline-any cline-neutral">&nbsp;</span>
920
- <span class="cline-any cline-neutral">&nbsp;</span>
921
- <span class="cline-any cline-neutral">&nbsp;</span>
922
- <span class="cline-any cline-neutral">&nbsp;</span>
923
- <span class="cline-any cline-neutral">&nbsp;</span>
924
- <span class="cline-any cline-neutral">&nbsp;</span>
925
- <span class="cline-any cline-neutral">&nbsp;</span>
926
- <span class="cline-any cline-neutral">&nbsp;</span>
927
- <span class="cline-any cline-yes">33x</span>
928
- <span class="cline-any cline-yes">33x</span>
929
- <span class="cline-any cline-neutral">&nbsp;</span>
930
- <span class="cline-any cline-neutral">&nbsp;</span>
931
- <span class="cline-any cline-neutral">&nbsp;</span>
932
- <span class="cline-any cline-neutral">&nbsp;</span>
933
- <span class="cline-any cline-neutral">&nbsp;</span>
934
- <span class="cline-any cline-neutral">&nbsp;</span>
935
- <span class="cline-any cline-neutral">&nbsp;</span>
936
- <span class="cline-any cline-neutral">&nbsp;</span>
937
- <span class="cline-any cline-neutral">&nbsp;</span>
938
- <span class="cline-any cline-neutral">&nbsp;</span>
939
- <span class="cline-any cline-neutral">&nbsp;</span>
940
- <span class="cline-any cline-neutral">&nbsp;</span>
941
- <span class="cline-any cline-neutral">&nbsp;</span>
942
- <span class="cline-any cline-neutral">&nbsp;</span>
943
- <span class="cline-any cline-neutral">&nbsp;</span>
944
- <span class="cline-any cline-neutral">&nbsp;</span>
945
- <span class="cline-any cline-yes">90x</span>
946
- <span class="cline-any cline-neutral">&nbsp;</span>
947
- <span class="cline-any cline-neutral">&nbsp;</span>
948
- <span class="cline-any cline-neutral">&nbsp;</span>
949
- <span class="cline-any cline-neutral">&nbsp;</span>
950
- <span class="cline-any cline-neutral">&nbsp;</span>
951
- <span class="cline-any cline-neutral">&nbsp;</span>
952
- <span class="cline-any cline-neutral">&nbsp;</span>
953
- <span class="cline-any cline-neutral">&nbsp;</span>
954
- <span class="cline-any cline-neutral">&nbsp;</span>
955
- <span class="cline-any cline-neutral">&nbsp;</span>
956
- <span class="cline-any cline-neutral">&nbsp;</span>
957
- <span class="cline-any cline-neutral">&nbsp;</span>
958
- <span class="cline-any cline-neutral">&nbsp;</span>
959
- <span class="cline-any cline-neutral">&nbsp;</span>
960
- <span class="cline-any cline-neutral">&nbsp;</span>
961
- <span class="cline-any cline-neutral">&nbsp;</span>
962
- <span class="cline-any cline-neutral">&nbsp;</span>
963
- <span class="cline-any cline-neutral">&nbsp;</span>
964
- <span class="cline-any cline-neutral">&nbsp;</span>
965
- <span class="cline-any cline-neutral">&nbsp;</span>
966
- <span class="cline-any cline-neutral">&nbsp;</span>
967
- <span class="cline-any cline-neutral">&nbsp;</span>
968
- <span class="cline-any cline-neutral">&nbsp;</span>
969
- <span class="cline-any cline-neutral">&nbsp;</span>
970
- <span class="cline-any cline-yes">66x</span>
971
- <span class="cline-any cline-yes">45x</span>
972
- <span class="cline-any cline-neutral">&nbsp;</span>
973
- <span class="cline-any cline-yes">21x</span>
974
- <span class="cline-any cline-yes">21x</span>
975
- <span class="cline-any cline-yes">21x</span>
976
- <span class="cline-any cline-yes">21x</span>
977
- <span class="cline-any cline-neutral">&nbsp;</span>
978
- <span class="cline-any cline-neutral">&nbsp;</span>
979
- <span class="cline-any cline-neutral">&nbsp;</span>
980
- <span class="cline-any cline-neutral">&nbsp;</span>
981
- <span class="cline-any cline-neutral">&nbsp;</span>
982
- <span class="cline-any cline-neutral">&nbsp;</span>
983
- <span class="cline-any cline-neutral">&nbsp;</span>
984
- <span class="cline-any cline-yes">34x</span>
985
- <span class="cline-any cline-neutral">&nbsp;</span>
986
- <span class="cline-any cline-neutral">&nbsp;</span>
987
- <span class="cline-any cline-neutral">&nbsp;</span>
988
- <span class="cline-any cline-neutral">&nbsp;</span>
989
- <span class="cline-any cline-neutral">&nbsp;</span>
990
- <span class="cline-any cline-neutral">&nbsp;</span>
991
- <span class="cline-any cline-neutral">&nbsp;</span>
992
- <span class="cline-any cline-neutral">&nbsp;</span>
993
- <span class="cline-any cline-neutral">&nbsp;</span>
994
- <span class="cline-any cline-neutral">&nbsp;</span>
995
- <span class="cline-any cline-neutral">&nbsp;</span>
996
- <span class="cline-any cline-neutral">&nbsp;</span>
997
- <span class="cline-any cline-neutral">&nbsp;</span>
998
- <span class="cline-any cline-neutral">&nbsp;</span>
999
- <span class="cline-any cline-neutral">&nbsp;</span>
1000
- <span class="cline-any cline-neutral">&nbsp;</span>
1001
- <span class="cline-any cline-neutral">&nbsp;</span>
1002
- <span class="cline-any cline-neutral">&nbsp;</span>
1003
- <span class="cline-any cline-yes">34x</span>
1004
- <span class="cline-any cline-yes">34x</span>
1005
- <span class="cline-any cline-yes">34x</span>
1006
- <span class="cline-any cline-no">&nbsp;</span>
1007
- <span class="cline-any cline-neutral">&nbsp;</span>
1008
- <span class="cline-any cline-neutral">&nbsp;</span>
1009
- <span class="cline-any cline-yes">34x</span>
1010
- <span class="cline-any cline-neutral">&nbsp;</span>
1011
- <span class="cline-any cline-yes">33x</span>
1012
- <span class="cline-any cline-yes">29x</span>
1013
- <span class="cline-any cline-neutral">&nbsp;</span>
1014
- <span class="cline-any cline-yes">4x</span>
1015
- <span class="cline-any cline-neutral">&nbsp;</span>
1016
- <span class="cline-any cline-neutral">&nbsp;</span>
1017
- <span class="cline-any cline-neutral">&nbsp;</span>
1018
- <span class="cline-any cline-neutral">&nbsp;</span>
1019
- <span class="cline-any cline-neutral">&nbsp;</span>
1020
- <span class="cline-any cline-neutral">&nbsp;</span>
1021
- <span class="cline-any cline-neutral">&nbsp;</span>
1022
- <span class="cline-any cline-neutral">&nbsp;</span>
1023
- <span class="cline-any cline-neutral">&nbsp;</span>
1024
- <span class="cline-any cline-neutral">&nbsp;</span>
1025
- <span class="cline-any cline-neutral">&nbsp;</span>
1026
- <span class="cline-any cline-no">&nbsp;</span>
1027
- <span class="cline-any cline-no">&nbsp;</span>
1028
- <span class="cline-any cline-no">&nbsp;</span>
1029
- <span class="cline-any cline-neutral">&nbsp;</span>
1030
- <span class="cline-any cline-neutral">&nbsp;</span>
1031
- <span class="cline-any cline-neutral">&nbsp;</span>
1032
- <span class="cline-any cline-neutral">&nbsp;</span>
1033
- <span class="cline-any cline-yes">90x</span>
1034
- <span class="cline-any cline-neutral">&nbsp;</span>
1035
- <span class="cline-any cline-neutral">&nbsp;</span>
1036
- <span class="cline-any cline-neutral">&nbsp;</span>
1037
- <span class="cline-any cline-neutral">&nbsp;</span>
1038
- <span class="cline-any cline-neutral">&nbsp;</span>
1039
- <span class="cline-any cline-neutral">&nbsp;</span>
1040
- <span class="cline-any cline-neutral">&nbsp;</span>
1041
- <span class="cline-any cline-neutral">&nbsp;</span>
1042
- <span class="cline-any cline-neutral">&nbsp;</span>
1043
- <span class="cline-any cline-neutral">&nbsp;</span>
1044
- <span class="cline-any cline-no">&nbsp;</span>
1045
- <span class="cline-any cline-neutral">&nbsp;</span>
1046
- <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
1051
- <span class="cline-any cline-no">&nbsp;</span>
1052
- <span class="cline-any cline-neutral">&nbsp;</span>
1053
- <span class="cline-any cline-no">&nbsp;</span>
1054
- <span class="cline-any cline-neutral">&nbsp;</span>
1055
- <span class="cline-any cline-neutral">&nbsp;</span>
1056
- <span class="cline-any cline-neutral">&nbsp;</span>
1057
- <span class="cline-any cline-neutral">&nbsp;</span>
1058
- <span class="cline-any cline-no">&nbsp;</span>
1059
- <span class="cline-any cline-neutral">&nbsp;</span>
1060
- <span class="cline-any cline-no">&nbsp;</span>
1061
- <span class="cline-any cline-neutral">&nbsp;</span>
1062
- <span class="cline-any cline-neutral">&nbsp;</span>
1063
- <span class="cline-any cline-neutral">&nbsp;</span>
1064
- <span class="cline-any cline-neutral">&nbsp;</span>
1065
- <span class="cline-any cline-neutral">&nbsp;</span>
1066
- <span class="cline-any cline-no">&nbsp;</span>
1067
- <span class="cline-any cline-neutral">&nbsp;</span>
1068
- <span class="cline-any cline-neutral">&nbsp;</span>
1069
- <span class="cline-any cline-neutral">&nbsp;</span>
1070
- <span class="cline-any cline-neutral">&nbsp;</span>
1071
- <span class="cline-any cline-no">&nbsp;</span>
1072
- <span class="cline-any cline-neutral">&nbsp;</span>
1073
- <span class="cline-any cline-neutral">&nbsp;</span>
1074
- <span class="cline-any cline-neutral">&nbsp;</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-no">&nbsp;</span>
1079
- <span class="cline-any cline-neutral">&nbsp;</span>
1080
- <span class="cline-any cline-no">&nbsp;</span>
1081
- <span class="cline-any cline-no">&nbsp;</span>
1082
- <span class="cline-any cline-neutral">&nbsp;</span>
1083
- <span class="cline-any cline-no">&nbsp;</span>
1084
- <span class="cline-any cline-neutral">&nbsp;</span>
1085
- <span class="cline-any cline-neutral">&nbsp;</span>
1086
- <span class="cline-any cline-neutral">&nbsp;</span>
1087
- <span class="cline-any cline-neutral">&nbsp;</span>
1088
- <span class="cline-any cline-neutral">&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-neutral">&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-neutral">&nbsp;</span>
1096
- <span class="cline-any cline-no">&nbsp;</span>
1097
- <span class="cline-any cline-no">&nbsp;</span>
1098
- <span class="cline-any cline-no">&nbsp;</span>
1099
- <span class="cline-any cline-neutral">&nbsp;</span>
1100
- <span class="cline-any cline-neutral">&nbsp;</span>
1101
- <span class="cline-any cline-no">&nbsp;</span>
1102
- <span class="cline-any cline-neutral">&nbsp;</span>
1103
- <span class="cline-any cline-neutral">&nbsp;</span>
1104
- <span class="cline-any cline-neutral">&nbsp;</span>
1105
- <span class="cline-any cline-neutral">&nbsp;</span>
1106
- <span class="cline-any cline-neutral">&nbsp;</span>
1107
- <span class="cline-any cline-no">&nbsp;</span>
1108
- <span class="cline-any cline-neutral">&nbsp;</span>
1109
- <span class="cline-any cline-neutral">&nbsp;</span>
1110
- <span class="cline-any cline-neutral">&nbsp;</span>
1111
- <span class="cline-any cline-neutral">&nbsp;</span>
1112
- <span class="cline-any cline-neutral">&nbsp;</span>
1113
- <span class="cline-any cline-no">&nbsp;</span>
1114
- <span class="cline-any cline-no">&nbsp;</span>
1115
- <span class="cline-any cline-neutral">&nbsp;</span>
1116
- <span class="cline-any cline-neutral">&nbsp;</span>
1117
- <span class="cline-any cline-neutral">&nbsp;</span>
1118
- <span class="cline-any cline-neutral">&nbsp;</span>
1119
- <span class="cline-any cline-neutral">&nbsp;</span>
1120
- <span class="cline-any cline-yes">90x</span>
1121
- <span class="cline-any cline-neutral">&nbsp;</span>
1122
- <span class="cline-any cline-neutral">&nbsp;</span>
1123
- <span class="cline-any cline-neutral">&nbsp;</span>
1124
- <span class="cline-any cline-neutral">&nbsp;</span>
1125
- <span class="cline-any cline-neutral">&nbsp;</span>
1126
- <span class="cline-any cline-neutral">&nbsp;</span>
1127
- <span class="cline-any cline-neutral">&nbsp;</span>
1128
- <span class="cline-any cline-neutral">&nbsp;</span>
1129
- <span class="cline-any cline-neutral">&nbsp;</span>
1130
- <span class="cline-any cline-neutral">&nbsp;</span>
1131
- <span class="cline-any cline-neutral">&nbsp;</span>
1132
- <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">// The `@apostrophecms/user` module provides user accounts. It is **not** intended to
1133
- // be extended with new subclass modules. The `@apostrophecms/login` module only
1134
- // looks for instances of `@apostrophecms/user`. Of course you may implicitly subclass
1135
- // it at project level (not changing the name) in order to alter its behavior.
1136
- //
1137
- // ### Public "staff directories" vs. users
1138
- //
1139
- // In our experience, combining the concept of a "user" who can log in and do things
1140
- // with the concept of a "staff member" who appears in a staff directory is more
1141
- // trouble than it is worth.
1142
- //
1143
- // So for a staff directory, we suggest you create a separate `employee` module
1144
- // or similar, extending `@apostrophecms/piece-type`, unless it's true that basically
1145
- // everyone should be allowed to log in.
1146
- //
1147
- // ### `secrets` option
1148
- //
1149
- // For security the `password` property is not stored as plaintext and
1150
- // is not kept in the aposDocs collection. Instead, it is hashed and salted
1151
- // using the `credential` module and the resulting hash is stored
1152
- // in a separate `aposUsersSafe` collection.
1153
- //
1154
- // Additional secrets may be hashed in this way. If you set the
1155
- // `secrets` option to an array of property names, those properties
1156
- // are never stored directly to the database. Instead, only their
1157
- // hashes are stored, and only in `aposUsersSafe`.
1158
- //
1159
- // You may also call `apos.user.addSecret('name')` to add a new
1160
- // secret property. This is convenient when implementing a module
1161
- // such as `@apostrophecms/signup`.
1162
- &nbsp;
1163
- const credential = require('credential');
1164
- const prompts = require('prompts');
1165
- const Promise = require('bluebird');
1166
- &nbsp;
1167
- module.exports = {
1168
- extend: '@apostrophecms/piece-type',
1169
- options: {
1170
- alias: 'user',
1171
- name: '@apostrophecms/user',
1172
- label: 'apostrophe:user',
1173
- pluralLabel: 'apostrophe:users',
1174
- quickCreate: false,
1175
- searchable: false,
1176
- slugPrefix: 'user-',
1177
- localized: false,
1178
- editRole: 'admin',
1179
- publishRole: 'admin',
1180
- viewRole: 'admin',
1181
- showPermissions: true
1182
- },
1183
- fields(self) {
1184
- return {
1185
- add: {
1186
- title: {
1187
- type: 'string',
1188
- label: 'apostrophe:displayName',
1189
- required: true
1190
- },
1191
- disabled: {
1192
- type: 'boolean',
1193
- label: 'apostrophe:loginDisabled',
1194
- def: false
1195
- },
1196
- username: {
1197
- type: 'string',
1198
- label: 'apostrophe:username',
1199
- required: true,
1200
- following: 'title'
1201
- },
1202
- email: {
1203
- type: 'string',
1204
- label: 'apostrophe:email'
1205
- },
1206
- password: {
1207
- type: 'password',
1208
- label: 'apostrophe:password'
1209
- },
1210
- role: {
1211
- type: 'role',
1212
- choices: [
1213
- {
1214
- label: 'apostrophe:guest',
1215
- value: 'guest'
1216
- },
1217
- {
1218
- label: 'apostrophe:contributor',
1219
- value: 'contributor'
1220
- },
1221
- {
1222
- label: 'apostrophe:editor',
1223
- value: 'editor'
1224
- },
1225
- {
1226
- label: 'apostrophe:admin',
1227
- value: 'admin'
1228
- }
1229
- ],
1230
- def: 'guest',
1231
- required: true
1232
- }
1233
- },
1234
- remove: [ 'visibility' ],
1235
- group: {
1236
- basics: {
1237
- label: 'apostrophe:basics',
1238
- fields: [
1239
- 'title'
1240
- ]
1241
- },
1242
- utility: {
1243
- fields: [
1244
- 'username',
1245
- 'email',
1246
- 'password',
1247
- 'slug',
1248
- 'archived'
1249
- ]
1250
- },
1251
- permissions: {
1252
- label: 'apostrophe:permissions',
1253
- fields: [
1254
- 'disabled',
1255
- 'role'
1256
- ]
1257
- }
1258
- }
1259
- };
1260
- },
1261
- &nbsp;
1262
- filters: {
1263
- remove: [ 'visibility' ]
1264
- },
1265
- &nbsp;
1266
- columns: {
1267
- remove: [ 'visibility' ]
1268
- },
1269
- &nbsp;
1270
- async init(self) {
1271
- self.initializeCredential();
1272
- self.addOurArchivedPrefixFields();
1273
- self.enableSecrets();
1274
- self.addLegacyMigrations();
1275
- await self.ensureSafe();
1276
- },
1277
- apiRoutes(self) {
1278
- return {
1279
- post: {
1280
- <span class="fstat-no" title="function not covered" > as</span>ync uniqueUsername(req) {
1281
- const username = <span class="cstat-no" title="statement not covered" >self.apos.launder.string(req.body.username);</span>
1282
- const user = <span class="cstat-no" title="statement not covered" >self.find(req, { username: username }).project({</span>
1283
- _id: 1,
1284
- username: 1
1285
- }).toObject();
1286
- <span class="cstat-no" title="statement not covered" > if (user) {</span>
1287
- <span class="cstat-no" title="statement not covered" > throw self.apos.error('conflict');</span>
1288
- }
1289
- }
1290
- }
1291
- };
1292
- },
1293
- handlers(self) {
1294
- return {
1295
- beforeInsert: {
1296
- async ensurePassword(req, doc, options) {
1297
- if (!doc.password) {
1298
- doc.password = self.apos.util.generateId();
1299
- }
1300
- },
1301
- async insertSafe(req, doc, options) {
1302
- return self.insertOrUpdateSafe(req, doc, 'insert');
1303
- }
1304
- },
1305
- beforeUpdate: {
1306
- async updateSafe(req, doc, options) {
1307
- return self.insertOrUpdateSafe(req, doc, 'update');
1308
- }
1309
- },
1310
- beforeSave: {
1311
- // There is a migration that sets the role to admin if the role does
1312
- // not exist, accommodating databases prior to 3.0 beta 1. To keep this
1313
- // from becoming a possible security concern, refuse any new inserts/updates
1314
- // with no role
1315
- async requireRole(req, doc, options) {
1316
- <span class="missing-if-branch" title="if path not taken" >I</span>if (![ 'guest', 'editor', 'contributor', 'admin' ].includes(doc.role)) {
1317
- <span class="cstat-no" title="statement not covered" > throw self.apos.error('invalid', 'The role property of a user must be guest, editor, contributor or admin');</span>
1318
- }
1319
- },
1320
- async invalidatePriorLogins(req, doc, options) {
1321
- const effectiveUserId = req.user &amp;&amp; req.user._id;
1322
- // Invalidate prior login sessions if the password field changes or
1323
- // the user is newly marked as disabled.
1324
- if (doc._id &amp;&amp; doc._passwordUpdated &amp;&amp; (effectiveUserId !== doc._id)) {
1325
- // Invalidate old sessions
1326
- doc.loginInvalidBefore = Date.now();
1327
- // Just delete old bearer tokens
1328
- return self.apos.login.bearerTokens.removeMany({
1329
- userId: doc._id
1330
- });
1331
- }
1332
- }
1333
- },
1334
- // Reflect email and username changes in the safe after deduplicating in the piece
1335
- afterArchive: {
1336
- async updateSafe(req, piece) {
1337
- await self.insertOrUpdateSafe(req, piece, 'update');
1338
- }
1339
- },
1340
- afterRescue: {
1341
- // Reflect email and username changes in the safe after deduplicating in the piece
1342
- async updateSafe(req, piece) {
1343
- await self.insertOrUpdateSafe(req, piece, 'update');
1344
- }
1345
- }
1346
- };
1347
- },
1348
- methods(self) {
1349
- return {
1350
- &nbsp;
1351
- // Add `username` and `email` to the list of fields that automatically get uniquely prefixed
1352
- // when a user is in the archive, so that they can be reused by another piece. When
1353
- // the piece is rescued from the archive the prefix is removed again, unless the username
1354
- // or email address has been claimed by another user in the meanwhile.
1355
- &nbsp;
1356
- addOurArchivedPrefixFields() {
1357
- self.addDeduplicatePrefixFields([
1358
- 'username',
1359
- 'email'
1360
- ]);
1361
- },
1362
- &nbsp;
1363
- // See `options.secrets` and also the `addSecret` method. `enableSecrets`
1364
- // is part of the implementation and should not be called directly.
1365
- &nbsp;
1366
- enableSecrets() {
1367
- self.secrets = self.options.secrets || [];
1368
- },
1369
- &nbsp;
1370
- // Index and obtain access to the `aposUsersSafe` MongoDB collection as `self.safe`.
1371
- &nbsp;
1372
- async ensureSafe() {
1373
- await self.ensureSafeCollection();
1374
- await self.ensureSafeIndexes();
1375
- },
1376
- &nbsp;
1377
- // Obtain the `aposUsersSafe` MongoDB collection as `self.safe`.
1378
- &nbsp;
1379
- async ensureSafeCollection() {
1380
- self.safe = await self.apos.db.collection('aposUsersSafe');
1381
- },
1382
- &nbsp;
1383
- // Index the safe.
1384
- &nbsp;
1385
- async ensureSafeIndexes() {
1386
- await self.safe.createIndex({ username: 1 }, { unique: true });
1387
- await self.safe.createIndex({ email: 1 }, {
1388
- unique: true,
1389
- sparse: true
1390
- });
1391
- },
1392
- &nbsp;
1393
- // After a user is updated, check to see if the `groups` option is configured for
1394
- // simplified user management. If it is, convert the single-select choice made
1395
- // via `piece.group` to an array stored in `groupIds`, so that all other code
1396
- // can find groups in a consistent way.
1397
- &nbsp;
1398
- <span class="fstat-no" title="function not covered" > as</span>ync afterConvert(req, piece) {
1399
- <span class="cstat-no" title="statement not covered" > if (self.options.groups) {</span>
1400
- <span class="cstat-no" title="statement not covered" > piece.groupIds = [];</span>
1401
- <span class="cstat-no" title="statement not covered" > piece.groupIds.push(piece.group);</span>
1402
- <span class="cstat-no" title="statement not covered" > delete piece.group;</span>
1403
- }
1404
- },
1405
- &nbsp;
1406
- // Insert or update a user's record in the safe, which stores the
1407
- // password hash completely outside of the `aposDocs` collection.
1408
- // First checks to be sure this is an `@apostrophecms/user` and returns
1409
- // immediately if not. Invoked on promise events.
1410
- async insertOrUpdateSafe(req, doc, action) {
1411
- // Store password hash exclusively in the safe so that it can never be
1412
- // accidentally exposed as part of a query on docs. Also store the
1413
- // username and, if present, the email address to take advantage of
1414
- // unique and sparse indexes which prevent duplication.
1415
- const safeUser = {
1416
- _id: doc._id,
1417
- username: doc.username,
1418
- updatedAt: new Date()
1419
- };
1420
- &nbsp;
1421
- <span class="missing-if-branch" title="else path not taken" >E</span>if (doc.email) {
1422
- safeUser.email = doc.email;
1423
- }
1424
- &nbsp;
1425
- await self.hashPassword(doc, safeUser);
1426
- await self.hashSecrets(doc, safeUser);
1427
- if (action === 'insert') {
1428
- await self.safe.insertOne(safeUser);
1429
- } else {
1430
- const changes = { $set: safeUser };
1431
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!safeUser.email) {
1432
- // Sparse indexes are only sparse on null/undefined, an empty string is not good enough
1433
- <span class="cstat-no" title="statement not covered" > changes.$unset = { email: 1 };</span>
1434
- }
1435
- await self.safe.updateOne({ _id: safeUser._id }, changes);
1436
- }
1437
- },
1438
- &nbsp;
1439
- // Hash the `password` property of `doc`, then delete that property
1440
- // and update the `passwordHash` property of `safeUser`. This method is
1441
- // called by the `docBeforeInsert` and `docBeforeSave handlers of this
1442
- // module. If `password` is falsy (i.e. the user left it blank,
1443
- // requesting no change), it is left alone and `safeUser` is
1444
- // not updated.
1445
- &nbsp;
1446
- async hashPassword(doc, safeUser) {
1447
- await self.hashSecret(doc, safeUser, 'password');
1448
- },
1449
- &nbsp;
1450
- // Similar to `hashPassword`, this method hashes all of the properties
1451
- // enumerated in `options.secrets` and via `addSecrets`, then deletes them
1452
- // and updates the corresponding properties of `safeUser`. If
1453
- // a secret is named `signup`, the corresponding property in
1454
- // `safeUser` will be named `signupHash`.
1455
- //
1456
- // This method is called by the `docBeforeInsert` and `docBeforeSave`
1457
- // handlers of this module.
1458
- &nbsp;
1459
- async hashSecrets(doc, safeUser) {
1460
- for (const secret of self.secrets) {
1461
- await self.hashSecret(doc, safeUser, secret);
1462
- }
1463
- },
1464
- &nbsp;
1465
- // Add the property specified by `name` to a list of
1466
- // secret properties. These are never stored directly
1467
- // to the user's doc in mongodb. Instead, if any of
1468
- // them have non-falsy values at the time a user is saved,
1469
- // those values are hashed and the hash is recorded
1470
- // in a separate mongodb collection used only for this purpose.
1471
- // You may then call `verifySecret` later to verify that
1472
- // a newly entered value matches the previously hashed
1473
- // value. This is useful to verify password reset codes,
1474
- // signup verification codes and the like with security
1475
- // just as good as that used for the password.
1476
- &nbsp;
1477
- addSecret(name) {
1478
- self.secrets.push(name);
1479
- },
1480
- &nbsp;
1481
- // Hashes a secret property of `doc`, deletes the property,
1482
- // and stores only the hash in `safeUser`. `secret` is
1483
- // the name of the property of `doc`, not the secret itself.
1484
- //
1485
- // If `secret` is the string `'password'`, then the `password`
1486
- // property will be deleted from `doc` and the `passwordHash`
1487
- // property of `safeUser` will be set.
1488
- //
1489
- // If the secret property is falsy (i.e. the user left the
1490
- // password field blank, requesting no change), it is left
1491
- // alone and `safeUser` is not updated.
1492
- //
1493
- // Called automatically by `hashSecrets`, above.
1494
- //
1495
- // The secret property itself is immediately deleted from doc
1496
- // to avoid any risk of accidentally storing it in cleartext.
1497
- // However there is a way to detect that it was updated:
1498
- // if `secret` is `password`, then the `_passwordUpdated` temporary
1499
- // property is set to true. This provides a way to take additional
1500
- // actions stemming from this change in a `beforeSave` handler, etc.
1501
- &nbsp;
1502
- async hashSecret(doc, safeUser, secret) {
1503
- if (!doc[secret]) {
1504
- return;
1505
- }
1506
- const hash = await require('util').promisify(self.pw.hash)(doc[secret]);
1507
- delete doc[secret];
1508
- safeUser[secret + 'Hash'] = hash;
1509
- doc[`_${secret}Updated`] = true;
1510
- },
1511
- &nbsp;
1512
- // Verify the given password by checking it against the
1513
- // hash in the safe. `user` is an `@apostrophecms/user` doc.
1514
- // Throws `'invalid'` as an exception if the password is incorrect.
1515
- &nbsp;
1516
- async verifyPassword(user, password) {
1517
- return self.verifySecret(user, 'password', password);
1518
- },
1519
- &nbsp;
1520
- // Check whether the provided value `attempt` matches
1521
- // the hash of the secret property `secret`. For security
1522
- // the user's password and other property names specified
1523
- // in `options.secrets` when configuring this module or via
1524
- // `addSecrets` are not stored as plaintext and are not kept in the
1525
- // aposDocs collection. Instead, they are hashed and salted using the
1526
- // `credential` module and the resulting hash is stored
1527
- // in a separate `aposUsersSafe` collection. This method
1528
- // can be used to verify that `attempt` matches the
1529
- // previously hashed value for the property named `secret`,
1530
- // without ever storing the actual value of the secret
1531
- //
1532
- // If the secret does not match, an `invalid` error is thrown.
1533
- // Otherwise the method returns normally.
1534
- &nbsp;
1535
- async verifySecret(user, secret, attempt) {
1536
- const verify = Promise.promisify(self.pw.verify);
1537
- const safeUser = await self.safe.findOne({ _id: user._id });
1538
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!safeUser) {
1539
- <span class="cstat-no" title="statement not covered" > throw new Error('No such user in the safe.');</span>
1540
- }
1541
- &nbsp;
1542
- const isVerified = await verify(safeUser[secret + 'Hash'], attempt);
1543
- &nbsp;
1544
- if (isVerified) {
1545
- return null;
1546
- } else {
1547
- throw self.apos.error('invalid', `Incorrect ${secret}`);
1548
- }
1549
- },
1550
- &nbsp;
1551
- // Forget the secret associated with the property name
1552
- // passed in `secret`. If `secret` is `'passwordReset'`,
1553
- // then the `passwordResetHash` property is deleted from
1554
- // the appropriate record in the `aposUsersSafe`
1555
- // collection. Note that the plaintext of the secret
1556
- // was never stored in the database in the first place.
1557
- &nbsp;
1558
- <span class="fstat-no" title="function not covered" > as</span>ync forgetSecret(user, secret) {
1559
- const changes = <span class="cstat-no" title="statement not covered" >{ $unset: {} };</span>
1560
- <span class="cstat-no" title="statement not covered" > changes.$unset[secret + 'Hash'] = 1;</span>
1561
- <span class="cstat-no" title="statement not covered" > await self.safe.updateOne({ _id: user._id }, changes);</span>
1562
- },
1563
- &nbsp;
1564
- // Initialize the [credential](https://npmjs.org/package/credential) module.
1565
- initializeCredential() {
1566
- self.pw = credential({
1567
- // For efficient unit tests only. Reducing the work factor
1568
- // for actual credentials increases the speed of brute force attacks
1569
- // if the database is ever compromised
1570
- work: self.options.insecurePasswords ? 0.01 : 1
1571
- });
1572
- },
1573
- &nbsp;
1574
- // Implement the `@apostrophecms/user:add` command line task.
1575
- &nbsp;
1576
- <span class="fstat-no" title="function not covered" > as</span>ync addFromTask() {
1577
- const argv = <span class="cstat-no" title="statement not covered" >self.apos.argv;</span>
1578
- // Support positional arguments for bc, but the named
1579
- // arguments make the intent clear
1580
- const username = <span class="cstat-no" title="statement not covered" >argv._[1] || argv.username;</span>
1581
- <span class="cstat-no" title="statement not covered" > if (!username) {</span>
1582
- <span class="cstat-no" title="statement not covered" > throw 'You must specify --username=usernamehere';</span>
1583
- }
1584
- const req = <span class="cstat-no" title="statement not covered" >self.apos.task.getReq();</span>
1585
- &nbsp;
1586
- const user = <span class="cstat-no" title="statement not covered" >{</span>
1587
- username,
1588
- title: username
1589
- };
1590
- &nbsp;
1591
- <span class="cstat-no" title="statement not covered" > await self.addPermissionsFromTask(argv, user);</span>
1592
- &nbsp;
1593
- <span class="cstat-no" title="statement not covered" > user.password = (await prompts(</span>
1594
- {
1595
- type: 'password',
1596
- name: 'password',
1597
- message: `Enter a password for ${username}:`,
1598
- <span class="fstat-no" title="function not covered" > va</span>lidate (input) {
1599
- <span class="cstat-no" title="statement not covered" > return input ? true : 'Password is required';</span>
1600
- }
1601
- }
1602
- )).password;
1603
- &nbsp;
1604
- <span class="cstat-no" title="statement not covered" > return self.apos.user.insert(req, user);</span>
1605
- },
1606
- &nbsp;
1607
- <span class="fstat-no" title="function not covered" > as</span>ync addPermissionsFromTask(argv, user) {
1608
- let role = <span class="cstat-no" title="statement not covered" >argv._[2] || argv.role;</span>
1609
- <span class="cstat-no" title="statement not covered" > if (!role) {</span>
1610
- <span class="cstat-no" title="statement not covered" > role = 'admin';</span>
1611
- <span class="cstat-no" title="statement not covered" > console.log('You did not pass a second argument or --role, assuming admin');</span>
1612
- }
1613
- <span class="cstat-no" title="statement not covered" > if (![ 'guest', 'contributor', 'editor', 'admin' ].includes(role)) {</span>
1614
- <span class="cstat-no" title="statement not covered" > throw 'Second argument or --role must be one of: guest, contributor, editor, admin';</span>
1615
- }
1616
- <span class="cstat-no" title="statement not covered" > user.role = role;</span>
1617
- },
1618
- &nbsp;
1619
- // Implement the `@apostrophecms/user:change-password` task.
1620
- &nbsp;
1621
- <span class="fstat-no" title="function not covered" > as</span>ync changePasswordFromTask() {
1622
- const argv = <span class="cstat-no" title="statement not covered" >self.apos.argv;</span>
1623
- <span class="cstat-no" title="statement not covered" > if (argv._.length !== 2) {</span>
1624
- <span class="cstat-no" title="statement not covered" > throw 'Incorrect number of arguments.';</span>
1625
- }
1626
- const username = <span class="cstat-no" title="statement not covered" >argv._[1];</span>
1627
- const req = <span class="cstat-no" title="statement not covered" >self.apos.task.getReq();</span>
1628
- &nbsp;
1629
- const user = <span class="cstat-no" title="statement not covered" >await self.apos.user.find(req, { username: username }).toObject();</span>
1630
- <span class="cstat-no" title="statement not covered" > if (!user) {</span>
1631
- <span class="cstat-no" title="statement not covered" > throw new Error('No such user.');</span>
1632
- }
1633
- &nbsp;
1634
- const { password } = <span class="cstat-no" title="statement not covered" >await prompts(</span>
1635
- {
1636
- type: 'password',
1637
- name: 'password',
1638
- message: `Change password for ${username} to:`,
1639
- <span class="fstat-no" title="function not covered" > va</span>lidate (input) {
1640
- <span class="cstat-no" title="statement not covered" > return input ? true : 'Password is required';</span>
1641
- }
1642
- }
1643
- );
1644
- &nbsp;
1645
- // This module's docBeforeUpdate handler does all the magic here
1646
- <span class="cstat-no" title="statement not covered" > user.password = password;</span>
1647
- <span class="cstat-no" title="statement not covered" > return self.update(req, user);</span>
1648
- },
1649
- ...require('./lib/legacy-migrations')(self)
1650
- };
1651
- },
1652
- tasks(self) {
1653
- return {
1654
- add: {
1655
- usage: 'Usage: node app @apostrophecms/user:add username groupname\n\nThis adds a new user and assigns them to a group.\nYou will be prompted for a password.',
1656
- task: self.addFromTask
1657
- },
1658
- 'change-password': {
1659
- usage: 'Usage: node app @apostrophecms/user:change-password username\n\nThis prompts you for a new password for the given user.',
1660
- task: self.changePasswordFromTask
1661
- }
1662
- };
1663
- }
1664
- };
1665
- &nbsp;</pre></td></tr></table></pre>
1666
-
1667
- <div class='push'></div><!-- for sticky footer -->
1668
- </div><!-- /wrapper -->
1669
- <div class='footer quiet pad2 space-top1 center small'>
1670
- Code coverage generated by
1671
- <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1672
- at Wed Jun 08 2022 11:06:49 GMT+0200 (Central European Summer Time)
1673
- </div>
1674
- <script src="../../../../prettify.js"></script>
1675
- <script>
1676
- window.onload = function () {
1677
- prettyPrint();
1678
- };
1679
- </script>
1680
- <script src="../../../../sorter.js"></script>
1681
- <script src="../../../../block-navigation.js"></script>
1682
- </body>
1683
- </html>
1684
-