@mapbox/cloudfriend 9.2.0 → 9.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +8 -0
- package/.idea/cloudfriend.iml +9 -0
- package/.idea/codeStyles/Project.xml +7 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/.nyc_output/6686e513-03b6-415d-9b8b-0fcde7a4e430.json +1 -0
- package/.nyc_output/f58a557c-a1c0-4dcc-83c5-bbca4d01baf9.json +1 -0
- package/.nyc_output/processinfo/6686e513-03b6-415d-9b8b-0fcde7a4e430.json +1 -0
- package/.nyc_output/processinfo/f58a557c-a1c0-4dcc-83c5-bbca4d01baf9.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -1
- package/cfniceberg_createtable.yaml +71 -0
- package/changelog.md +8 -0
- package/coverage/clover.xml +630 -0
- package/coverage/coverage-final.json +33 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/cloudfriend/bin/build-template.js.html +130 -0
- package/coverage/lcov-report/cloudfriend/bin/index.html +131 -0
- package/coverage/lcov-report/cloudfriend/bin/validate-template.js.html +142 -0
- package/coverage/lcov-report/cloudfriend/index.html +116 -0
- package/coverage/lcov-report/cloudfriend/index.js.html +307 -0
- package/coverage/lcov-report/cloudfriend/lib/build.js.html +217 -0
- package/coverage/lcov-report/cloudfriend/lib/conditions.js.html +430 -0
- package/coverage/lcov-report/cloudfriend/lib/index.html +206 -0
- package/coverage/lcov-report/cloudfriend/lib/intrinsic.js.html +979 -0
- package/coverage/lcov-report/cloudfriend/lib/merge.js.html +478 -0
- package/coverage/lcov-report/cloudfriend/lib/pseudo.js.html +370 -0
- package/coverage/lcov-report/cloudfriend/lib/rules.js.html +349 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/cross-account-role.js.html +244 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/event-lambda.js.html +367 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-database.js.html +286 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-iceberg-table.js.html +646 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-json-table.js.html +235 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-orc-table.js.html +226 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-parquet-table.js.html +268 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-presto-view.js.html +358 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-spark-view.js.html +241 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-table.js.html +481 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/hookshot.js.html +1504 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/index.html +431 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/index.js.html +157 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/kinesis-firehose-base.js.html +418 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/lambda.js.html +832 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/log-subscription-lambda.js.html +310 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/queue-lambda.js.html +364 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/queue.js.html +619 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/role.js.html +382 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/s3-kinesis-firehose.js.html +568 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/scheduled-lambda.js.html +490 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/service-role.js.html +307 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/stream-lambda.js.html +493 -0
- package/coverage/lcov-report/cloudfriend/lib/validate.js.html +154 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +161 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov.info +1319 -0
- package/jest.config.js +14 -0
- package/lib/shortcuts/api.md +37 -0
- package/lib/shortcuts/glue-iceberg-table.js +187 -0
- package/lib/shortcuts/index.js +1 -0
- package/package.json +15 -13
- package/readme.md +1 -1
- package/requirements.dev.txt +2 -2
- package/test/bin.test.js +18 -14
- package/test/fixtures/shortcuts/cross-account-role-defaults.json +1 -1
- package/test/fixtures/shortcuts/cross-account-role-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/event-lambda-defaults.json +1 -1
- package/test/fixtures/shortcuts/event-lambda-full.json +1 -1
- package/test/fixtures/shortcuts/firehose-defaults.json +1 -1
- package/test/fixtures/shortcuts/firehose-with-stream.json +1 -1
- package/test/fixtures/shortcuts/glue-database-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-database-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-iceberg-table-defaults.json +41 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-no-defaults.json +39 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-all-optimizers.json +101 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-both-optimizers.json +80 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-compaction-custom.json +68 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-compaction-defaults.json +57 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-optimizer-custom.json +75 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-optimizer-defaults.json +64 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-orphan-deletion-custom.json +74 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-orphan-deletion-defaults.json +62 -0
- package/test/fixtures/shortcuts/glue-json-table-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-json-table-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-orc-table-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-orc-table-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-parquet-table-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-parquet-table-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-table-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-table-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-view-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-view-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/hookshot-github-secret-ref.json +1 -1
- package/test/fixtures/shortcuts/hookshot-github-secret-string.json +1 -1
- package/test/fixtures/shortcuts/hookshot-github.json +1 -1
- package/test/fixtures/shortcuts/hookshot-passthrough-access-log-format.json +1 -1
- package/test/fixtures/shortcuts/hookshot-passthrough-alarms.json +1 -1
- package/test/fixtures/shortcuts/hookshot-passthrough-enhanced-logging.json +1 -1
- package/test/fixtures/shortcuts/hookshot-passthrough-full-blown-logging.json +1 -1
- package/test/fixtures/shortcuts/hookshot-passthrough-logging.json +1 -1
- package/test/fixtures/shortcuts/hookshot-passthrough.json +1 -1
- package/test/fixtures/shortcuts/lambda-defaults.json +1 -1
- package/test/fixtures/shortcuts/lambda-docker.json +1 -1
- package/test/fixtures/shortcuts/lambda-full.json +1 -1
- package/test/fixtures/shortcuts/lambda-provided-role.json +1 -1
- package/test/fixtures/shortcuts/lambda-zipfile.json +1 -1
- package/test/fixtures/shortcuts/log-subscription-lambda-defaults.json +1 -1
- package/test/fixtures/shortcuts/log-subscription-lambda-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/queue-defaults.json +1 -1
- package/test/fixtures/shortcuts/queue-external-topic-ref.json +1 -1
- package/test/fixtures/shortcuts/queue-external-topic.json +1 -1
- package/test/fixtures/shortcuts/queue-fifo-queuename.json +1 -1
- package/test/fixtures/shortcuts/queue-fifo.json +1 -1
- package/test/fixtures/shortcuts/queue-full.json +1 -1
- package/test/fixtures/shortcuts/queue-lambda-zero.json +1 -1
- package/test/fixtures/shortcuts/queue-lambda.json +1 -1
- package/test/fixtures/shortcuts/role-defaults.json +1 -1
- package/test/fixtures/shortcuts/role-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/scheduled-lambda-defaults.json +1 -1
- package/test/fixtures/shortcuts/scheduled-lambda-full.json +1 -1
- package/test/fixtures/shortcuts/service-role-defaults.json +1 -1
- package/test/fixtures/shortcuts/service-role-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/service-role-no-url-suffix.json +1 -1
- package/test/fixtures/shortcuts/service-role-url-suffix-with-replacement.json +1 -1
- package/test/fixtures/shortcuts/service-role-url-suffix.json +1 -1
- package/test/fixtures/shortcuts/stream-lambda-defaults.json +1 -1
- package/test/fixtures/shortcuts/stream-lambda-no-defaults.json +1 -1
- package/test/index.test.js +383 -235
- package/test/shortcuts.test.js +1523 -1483
- package/.nyc_output/2b544c0b-2830-4ad0-97cd-8e661710b0bb.json +0 -1
- package/.nyc_output/65e58b48-bf1c-412d-8dd4-d7b564b12d76.json +0 -1
- package/.nyc_output/processinfo/2b544c0b-2830-4ad0-97cd-8e661710b0bb.json +0 -1
- package/.nyc_output/processinfo/65e58b48-bf1c-412d-8dd4-d7b564b12d76.json +0 -1
|
@@ -0,0 +1,1504 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for cloudfriend/lib/shortcuts/hookshot.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">cloudfriend/lib/shortcuts</a> hookshot.js</h1>
|
|
23
|
+
<div class='clearfix'>
|
|
24
|
+
|
|
25
|
+
<div class='fl pad1y space-right2'>
|
|
26
|
+
<span class="strong">100% </span>
|
|
27
|
+
<span class="quiet">Statements</span>
|
|
28
|
+
<span class='fraction'>43/43</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">96.42% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>27/28</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">100% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>8/8</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<div class='fl pad1y space-right2'>
|
|
47
|
+
<span class="strong">100% </span>
|
|
48
|
+
<span class="quiet">Lines</span>
|
|
49
|
+
<span class='fraction'>39/39</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 type="search" id="fileSearch">
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
</div>
|
|
64
|
+
<div class='status-line high'></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></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
540
|
+
<span class="cline-any cline-neutral"> </span>
|
|
541
|
+
<span class="cline-any cline-yes">2x</span>
|
|
542
|
+
<span class="cline-any cline-yes">2x</span>
|
|
543
|
+
<span class="cline-any cline-yes">2x</span>
|
|
544
|
+
<span class="cline-any cline-yes">2x</span>
|
|
545
|
+
<span class="cline-any cline-neutral"> </span>
|
|
546
|
+
<span class="cline-any cline-yes">2x</span>
|
|
547
|
+
<span class="cline-any cline-neutral"> </span>
|
|
548
|
+
<span class="cline-any cline-neutral"> </span>
|
|
549
|
+
<span class="cline-any cline-yes">4x</span>
|
|
550
|
+
<span class="cline-any cline-yes">2x</span>
|
|
551
|
+
<span class="cline-any cline-yes">2x</span>
|
|
552
|
+
<span class="cline-any cline-yes">2x</span>
|
|
553
|
+
<span class="cline-any cline-neutral"> </span>
|
|
554
|
+
<span class="cline-any cline-yes">2x</span>
|
|
555
|
+
<span class="cline-any cline-neutral"> </span>
|
|
556
|
+
<span class="cline-any cline-neutral"> </span>
|
|
557
|
+
<span class="cline-any cline-neutral"> </span>
|
|
558
|
+
<span class="cline-any cline-neutral"> </span>
|
|
559
|
+
<span class="cline-any cline-neutral"> </span>
|
|
560
|
+
<span class="cline-any cline-neutral"> </span>
|
|
561
|
+
<span class="cline-any cline-neutral"> </span>
|
|
562
|
+
<span class="cline-any cline-neutral"> </span>
|
|
563
|
+
<span class="cline-any cline-neutral"> </span>
|
|
564
|
+
<span class="cline-any cline-neutral"> </span>
|
|
565
|
+
<span class="cline-any cline-neutral"> </span>
|
|
566
|
+
<span class="cline-any cline-neutral"> </span>
|
|
567
|
+
<span class="cline-any cline-neutral"> </span>
|
|
568
|
+
<span class="cline-any cline-neutral"> </span>
|
|
569
|
+
<span class="cline-any cline-neutral"> </span>
|
|
570
|
+
<span class="cline-any cline-neutral"> </span>
|
|
571
|
+
<span class="cline-any cline-neutral"> </span>
|
|
572
|
+
<span class="cline-any cline-neutral"> </span>
|
|
573
|
+
<span class="cline-any cline-neutral"> </span>
|
|
574
|
+
<span class="cline-any cline-neutral"> </span>
|
|
575
|
+
<span class="cline-any cline-neutral"> </span>
|
|
576
|
+
<span class="cline-any cline-neutral"> </span>
|
|
577
|
+
<span class="cline-any cline-neutral"> </span>
|
|
578
|
+
<span class="cline-any cline-neutral"> </span>
|
|
579
|
+
<span class="cline-any cline-neutral"> </span>
|
|
580
|
+
<span class="cline-any cline-neutral"> </span>
|
|
581
|
+
<span class="cline-any cline-neutral"> </span>
|
|
582
|
+
<span class="cline-any cline-neutral"> </span>
|
|
583
|
+
<span class="cline-any cline-neutral"> </span>
|
|
584
|
+
<span class="cline-any cline-neutral"> </span>
|
|
585
|
+
<span class="cline-any cline-neutral"> </span>
|
|
586
|
+
<span class="cline-any cline-neutral"> </span>
|
|
587
|
+
<span class="cline-any cline-neutral"> </span>
|
|
588
|
+
<span class="cline-any cline-neutral"> </span>
|
|
589
|
+
<span class="cline-any cline-neutral"> </span>
|
|
590
|
+
<span class="cline-any cline-neutral"> </span>
|
|
591
|
+
<span class="cline-any cline-neutral"> </span>
|
|
592
|
+
<span class="cline-any cline-neutral"> </span>
|
|
593
|
+
<span class="cline-any cline-neutral"> </span>
|
|
594
|
+
<span class="cline-any cline-neutral"> </span>
|
|
595
|
+
<span class="cline-any cline-neutral"> </span>
|
|
596
|
+
<span class="cline-any cline-neutral"> </span>
|
|
597
|
+
<span class="cline-any cline-neutral"> </span>
|
|
598
|
+
<span class="cline-any cline-neutral"> </span>
|
|
599
|
+
<span class="cline-any cline-neutral"> </span>
|
|
600
|
+
<span class="cline-any cline-neutral"> </span>
|
|
601
|
+
<span class="cline-any cline-neutral"> </span>
|
|
602
|
+
<span class="cline-any cline-neutral"> </span>
|
|
603
|
+
<span class="cline-any cline-neutral"> </span>
|
|
604
|
+
<span class="cline-any cline-neutral"> </span>
|
|
605
|
+
<span class="cline-any cline-neutral"> </span>
|
|
606
|
+
<span class="cline-any cline-neutral"> </span>
|
|
607
|
+
<span class="cline-any cline-neutral"> </span>
|
|
608
|
+
<span class="cline-any cline-neutral"> </span>
|
|
609
|
+
<span class="cline-any cline-neutral"> </span>
|
|
610
|
+
<span class="cline-any cline-neutral"> </span>
|
|
611
|
+
<span class="cline-any cline-neutral"> </span>
|
|
612
|
+
<span class="cline-any cline-neutral"> </span>
|
|
613
|
+
<span class="cline-any cline-neutral"> </span>
|
|
614
|
+
<span class="cline-any cline-neutral"> </span>
|
|
615
|
+
<span class="cline-any cline-neutral"> </span>
|
|
616
|
+
<span class="cline-any cline-neutral"> </span>
|
|
617
|
+
<span class="cline-any cline-neutral"> </span>
|
|
618
|
+
<span class="cline-any cline-neutral"> </span>
|
|
619
|
+
<span class="cline-any cline-neutral"> </span>
|
|
620
|
+
<span class="cline-any cline-neutral"> </span>
|
|
621
|
+
<span class="cline-any cline-neutral"> </span>
|
|
622
|
+
<span class="cline-any cline-neutral"> </span>
|
|
623
|
+
<span class="cline-any cline-neutral"> </span>
|
|
624
|
+
<span class="cline-any cline-neutral"> </span>
|
|
625
|
+
<span class="cline-any cline-neutral"> </span>
|
|
626
|
+
<span class="cline-any cline-neutral"> </span>
|
|
627
|
+
<span class="cline-any cline-yes">17x</span>
|
|
628
|
+
<span class="cline-any cline-neutral"> </span>
|
|
629
|
+
<span class="cline-any cline-neutral"> </span>
|
|
630
|
+
<span class="cline-any cline-neutral"> </span>
|
|
631
|
+
<span class="cline-any cline-neutral"> </span>
|
|
632
|
+
<span class="cline-any cline-neutral"> </span>
|
|
633
|
+
<span class="cline-any cline-neutral"> </span>
|
|
634
|
+
<span class="cline-any cline-neutral"> </span>
|
|
635
|
+
<span class="cline-any cline-yes">16x</span>
|
|
636
|
+
<span class="cline-any cline-neutral"> </span>
|
|
637
|
+
<span class="cline-any cline-yes">16x</span>
|
|
638
|
+
<span class="cline-any cline-neutral"> </span>
|
|
639
|
+
<span class="cline-any cline-neutral"> </span>
|
|
640
|
+
<span class="cline-any cline-neutral"> </span>
|
|
641
|
+
<span class="cline-any cline-yes">12x</span>
|
|
642
|
+
<span class="cline-any cline-neutral"> </span>
|
|
643
|
+
<span class="cline-any cline-yes">12x</span>
|
|
644
|
+
<span class="cline-any cline-yes">22x</span>
|
|
645
|
+
<span class="cline-any cline-yes">2x</span>
|
|
646
|
+
<span class="cline-any cline-neutral"> </span>
|
|
647
|
+
<span class="cline-any cline-yes">10x</span>
|
|
648
|
+
<span class="cline-any cline-yes">1x</span>
|
|
649
|
+
<span class="cline-any cline-neutral"> </span>
|
|
650
|
+
<span class="cline-any cline-yes">9x</span>
|
|
651
|
+
<span class="cline-any cline-yes">2x</span>
|
|
652
|
+
<span class="cline-any cline-neutral"> </span>
|
|
653
|
+
<span class="cline-any cline-yes">9x</span>
|
|
654
|
+
<span class="cline-any cline-yes">9x</span>
|
|
655
|
+
<span class="cline-any cline-yes">9x</span>
|
|
656
|
+
<span class="cline-any cline-neutral"> </span>
|
|
657
|
+
<span class="cline-any cline-yes">9x</span>
|
|
658
|
+
<span class="cline-any cline-neutral"> </span>
|
|
659
|
+
<span class="cline-any cline-neutral"> </span>
|
|
660
|
+
<span class="cline-any cline-neutral"> </span>
|
|
661
|
+
<span class="cline-any cline-neutral"> </span>
|
|
662
|
+
<span class="cline-any cline-neutral"> </span>
|
|
663
|
+
<span class="cline-any cline-neutral"> </span>
|
|
664
|
+
<span class="cline-any cline-neutral"> </span>
|
|
665
|
+
<span class="cline-any cline-neutral"> </span>
|
|
666
|
+
<span class="cline-any cline-neutral"> </span>
|
|
667
|
+
<span class="cline-any cline-neutral"> </span>
|
|
668
|
+
<span class="cline-any cline-neutral"> </span>
|
|
669
|
+
<span class="cline-any cline-neutral"> </span>
|
|
670
|
+
<span class="cline-any cline-neutral"> </span>
|
|
671
|
+
<span class="cline-any cline-neutral"> </span>
|
|
672
|
+
<span class="cline-any cline-neutral"> </span>
|
|
673
|
+
<span class="cline-any cline-neutral"> </span>
|
|
674
|
+
<span class="cline-any cline-neutral"> </span>
|
|
675
|
+
<span class="cline-any cline-neutral"> </span>
|
|
676
|
+
<span class="cline-any cline-neutral"> </span>
|
|
677
|
+
<span class="cline-any cline-neutral"> </span>
|
|
678
|
+
<span class="cline-any cline-neutral"> </span>
|
|
679
|
+
<span class="cline-any cline-neutral"> </span>
|
|
680
|
+
<span class="cline-any cline-neutral"> </span>
|
|
681
|
+
<span class="cline-any cline-neutral"> </span>
|
|
682
|
+
<span class="cline-any cline-neutral"> </span>
|
|
683
|
+
<span class="cline-any cline-neutral"> </span>
|
|
684
|
+
<span class="cline-any cline-neutral"> </span>
|
|
685
|
+
<span class="cline-any cline-neutral"> </span>
|
|
686
|
+
<span class="cline-any cline-neutral"> </span>
|
|
687
|
+
<span class="cline-any cline-neutral"> </span>
|
|
688
|
+
<span class="cline-any cline-neutral"> </span>
|
|
689
|
+
<span class="cline-any cline-neutral"> </span>
|
|
690
|
+
<span class="cline-any cline-neutral"> </span>
|
|
691
|
+
<span class="cline-any cline-neutral"> </span>
|
|
692
|
+
<span class="cline-any cline-neutral"> </span>
|
|
693
|
+
<span class="cline-any cline-neutral"> </span>
|
|
694
|
+
<span class="cline-any cline-neutral"> </span>
|
|
695
|
+
<span class="cline-any cline-neutral"> </span>
|
|
696
|
+
<span class="cline-any cline-neutral"> </span>
|
|
697
|
+
<span class="cline-any cline-neutral"> </span>
|
|
698
|
+
<span class="cline-any cline-neutral"> </span>
|
|
699
|
+
<span class="cline-any cline-neutral"> </span>
|
|
700
|
+
<span class="cline-any cline-neutral"> </span>
|
|
701
|
+
<span class="cline-any cline-neutral"> </span>
|
|
702
|
+
<span class="cline-any cline-neutral"> </span>
|
|
703
|
+
<span class="cline-any cline-neutral"> </span>
|
|
704
|
+
<span class="cline-any cline-neutral"> </span>
|
|
705
|
+
<span class="cline-any cline-neutral"> </span>
|
|
706
|
+
<span class="cline-any cline-neutral"> </span>
|
|
707
|
+
<span class="cline-any cline-neutral"> </span>
|
|
708
|
+
<span class="cline-any cline-neutral"> </span>
|
|
709
|
+
<span class="cline-any cline-neutral"> </span>
|
|
710
|
+
<span class="cline-any cline-neutral"> </span>
|
|
711
|
+
<span class="cline-any cline-neutral"> </span>
|
|
712
|
+
<span class="cline-any cline-neutral"> </span>
|
|
713
|
+
<span class="cline-any cline-neutral"> </span>
|
|
714
|
+
<span class="cline-any cline-neutral"> </span>
|
|
715
|
+
<span class="cline-any cline-neutral"> </span>
|
|
716
|
+
<span class="cline-any cline-neutral"> </span>
|
|
717
|
+
<span class="cline-any cline-neutral"> </span>
|
|
718
|
+
<span class="cline-any cline-neutral"> </span>
|
|
719
|
+
<span class="cline-any cline-neutral"> </span>
|
|
720
|
+
<span class="cline-any cline-neutral"> </span>
|
|
721
|
+
<span class="cline-any cline-neutral"> </span>
|
|
722
|
+
<span class="cline-any cline-neutral"> </span>
|
|
723
|
+
<span class="cline-any cline-neutral"> </span>
|
|
724
|
+
<span class="cline-any cline-neutral"> </span>
|
|
725
|
+
<span class="cline-any cline-neutral"> </span>
|
|
726
|
+
<span class="cline-any cline-neutral"> </span>
|
|
727
|
+
<span class="cline-any cline-neutral"> </span>
|
|
728
|
+
<span class="cline-any cline-neutral"> </span>
|
|
729
|
+
<span class="cline-any cline-neutral"> </span>
|
|
730
|
+
<span class="cline-any cline-neutral"> </span>
|
|
731
|
+
<span class="cline-any cline-neutral"> </span>
|
|
732
|
+
<span class="cline-any cline-neutral"> </span>
|
|
733
|
+
<span class="cline-any cline-neutral"> </span>
|
|
734
|
+
<span class="cline-any cline-neutral"> </span>
|
|
735
|
+
<span class="cline-any cline-neutral"> </span>
|
|
736
|
+
<span class="cline-any cline-yes">9x</span>
|
|
737
|
+
<span class="cline-any cline-neutral"> </span>
|
|
738
|
+
<span class="cline-any cline-neutral"> </span>
|
|
739
|
+
<span class="cline-any cline-neutral"> </span>
|
|
740
|
+
<span class="cline-any cline-neutral"> </span>
|
|
741
|
+
<span class="cline-any cline-neutral"> </span>
|
|
742
|
+
<span class="cline-any cline-neutral"> </span>
|
|
743
|
+
<span class="cline-any cline-yes">9x</span>
|
|
744
|
+
<span class="cline-any cline-yes">1x</span>
|
|
745
|
+
<span class="cline-any cline-neutral"> </span>
|
|
746
|
+
<span class="cline-any cline-neutral"> </span>
|
|
747
|
+
<span class="cline-any cline-neutral"> </span>
|
|
748
|
+
<span class="cline-any cline-neutral"> </span>
|
|
749
|
+
<span class="cline-any cline-neutral"> </span>
|
|
750
|
+
<span class="cline-any cline-neutral"> </span>
|
|
751
|
+
<span class="cline-any cline-neutral"> </span>
|
|
752
|
+
<span class="cline-any cline-yes">1x</span>
|
|
753
|
+
<span class="cline-any cline-neutral"> </span>
|
|
754
|
+
<span class="cline-any cline-neutral"> </span>
|
|
755
|
+
<span class="cline-any cline-neutral"> </span>
|
|
756
|
+
<span class="cline-any cline-neutral"> </span>
|
|
757
|
+
<span class="cline-any cline-neutral"> </span>
|
|
758
|
+
<span class="cline-any cline-yes">9x</span>
|
|
759
|
+
<span class="cline-any cline-neutral"> </span>
|
|
760
|
+
<span class="cline-any cline-neutral"> </span>
|
|
761
|
+
<span class="cline-any cline-neutral"> </span>
|
|
762
|
+
<span class="cline-any cline-neutral"> </span>
|
|
763
|
+
<span class="cline-any cline-neutral"> </span>
|
|
764
|
+
<span class="cline-any cline-neutral"> </span>
|
|
765
|
+
<span class="cline-any cline-neutral"> </span>
|
|
766
|
+
<span class="cline-any cline-neutral"> </span>
|
|
767
|
+
<span class="cline-any cline-neutral"> </span>
|
|
768
|
+
<span class="cline-any cline-neutral"> </span>
|
|
769
|
+
<span class="cline-any cline-neutral"> </span>
|
|
770
|
+
<span class="cline-any cline-neutral"> </span>
|
|
771
|
+
<span class="cline-any cline-neutral"> </span>
|
|
772
|
+
<span class="cline-any cline-neutral"> </span>
|
|
773
|
+
<span class="cline-any cline-neutral"> </span>
|
|
774
|
+
<span class="cline-any cline-neutral"> </span>
|
|
775
|
+
<span class="cline-any cline-neutral"> </span>
|
|
776
|
+
<span class="cline-any cline-neutral"> </span>
|
|
777
|
+
<span class="cline-any cline-yes">9x</span>
|
|
778
|
+
<span class="cline-any cline-neutral"> </span>
|
|
779
|
+
<span class="cline-any cline-yes">9x</span>
|
|
780
|
+
<span class="cline-any cline-neutral"> </span>
|
|
781
|
+
<span class="cline-any cline-neutral"> </span>
|
|
782
|
+
<span class="cline-any cline-neutral"> </span>
|
|
783
|
+
<span class="cline-any cline-neutral"> </span>
|
|
784
|
+
<span class="cline-any cline-neutral"> </span>
|
|
785
|
+
<span class="cline-any cline-neutral"> </span>
|
|
786
|
+
<span class="cline-any cline-neutral"> </span>
|
|
787
|
+
<span class="cline-any cline-neutral"> </span>
|
|
788
|
+
<span class="cline-any cline-neutral"> </span>
|
|
789
|
+
<span class="cline-any cline-neutral"> </span>
|
|
790
|
+
<span class="cline-any cline-neutral"> </span>
|
|
791
|
+
<span class="cline-any cline-neutral"> </span>
|
|
792
|
+
<span class="cline-any cline-neutral"> </span>
|
|
793
|
+
<span class="cline-any cline-yes">6x</span>
|
|
794
|
+
<span class="cline-any cline-neutral"> </span>
|
|
795
|
+
<span class="cline-any cline-neutral"> </span>
|
|
796
|
+
<span class="cline-any cline-neutral"> </span>
|
|
797
|
+
<span class="cline-any cline-neutral"> </span>
|
|
798
|
+
<span class="cline-any cline-neutral"> </span>
|
|
799
|
+
<span class="cline-any cline-neutral"> </span>
|
|
800
|
+
<span class="cline-any cline-neutral"> </span>
|
|
801
|
+
<span class="cline-any cline-neutral"> </span>
|
|
802
|
+
<span class="cline-any cline-neutral"> </span>
|
|
803
|
+
<span class="cline-any cline-neutral"> </span>
|
|
804
|
+
<span class="cline-any cline-neutral"> </span>
|
|
805
|
+
<span class="cline-any cline-neutral"> </span>
|
|
806
|
+
<span class="cline-any cline-neutral"> </span>
|
|
807
|
+
<span class="cline-any cline-neutral"> </span>
|
|
808
|
+
<span class="cline-any cline-neutral"> </span>
|
|
809
|
+
<span class="cline-any cline-neutral"> </span>
|
|
810
|
+
<span class="cline-any cline-neutral"> </span>
|
|
811
|
+
<span class="cline-any cline-yes">6x</span>
|
|
812
|
+
<span class="cline-any cline-neutral"> </span>
|
|
813
|
+
<span class="cline-any cline-neutral"> </span>
|
|
814
|
+
<span class="cline-any cline-neutral"> </span>
|
|
815
|
+
<span class="cline-any cline-neutral"> </span>
|
|
816
|
+
<span class="cline-any cline-neutral"> </span>
|
|
817
|
+
<span class="cline-any cline-neutral"> </span>
|
|
818
|
+
<span class="cline-any cline-neutral"> </span>
|
|
819
|
+
<span class="cline-any cline-neutral"> </span>
|
|
820
|
+
<span class="cline-any cline-neutral"> </span>
|
|
821
|
+
<span class="cline-any cline-neutral"> </span>
|
|
822
|
+
<span class="cline-any cline-neutral"> </span>
|
|
823
|
+
<span class="cline-any cline-neutral"> </span>
|
|
824
|
+
<span class="cline-any cline-neutral"> </span>
|
|
825
|
+
<span class="cline-any cline-neutral"> </span>
|
|
826
|
+
<span class="cline-any cline-neutral"> </span>
|
|
827
|
+
<span class="cline-any cline-neutral"> </span>
|
|
828
|
+
<span class="cline-any cline-neutral"> </span>
|
|
829
|
+
<span class="cline-any cline-neutral"> </span>
|
|
830
|
+
<span class="cline-any cline-neutral"> </span>
|
|
831
|
+
<span class="cline-any cline-neutral"> </span>
|
|
832
|
+
<span class="cline-any cline-neutral"> </span>
|
|
833
|
+
<span class="cline-any cline-neutral"> </span>
|
|
834
|
+
<span class="cline-any cline-neutral"> </span>
|
|
835
|
+
<span class="cline-any cline-neutral"> </span>
|
|
836
|
+
<span class="cline-any cline-neutral"> </span>
|
|
837
|
+
<span class="cline-any cline-neutral"> </span>
|
|
838
|
+
<span class="cline-any cline-neutral"> </span>
|
|
839
|
+
<span class="cline-any cline-neutral"> </span>
|
|
840
|
+
<span class="cline-any cline-neutral"> </span>
|
|
841
|
+
<span class="cline-any cline-neutral"> </span>
|
|
842
|
+
<span class="cline-any cline-neutral"> </span>
|
|
843
|
+
<span class="cline-any cline-neutral"> </span>
|
|
844
|
+
<span class="cline-any cline-neutral"> </span>
|
|
845
|
+
<span class="cline-any cline-neutral"> </span>
|
|
846
|
+
<span class="cline-any cline-neutral"> </span>
|
|
847
|
+
<span class="cline-any cline-neutral"> </span>
|
|
848
|
+
<span class="cline-any cline-neutral"> </span>
|
|
849
|
+
<span class="cline-any cline-neutral"> </span>
|
|
850
|
+
<span class="cline-any cline-neutral"> </span>
|
|
851
|
+
<span class="cline-any cline-neutral"> </span>
|
|
852
|
+
<span class="cline-any cline-neutral"> </span>
|
|
853
|
+
<span class="cline-any cline-neutral"> </span>
|
|
854
|
+
<span class="cline-any cline-neutral"> </span>
|
|
855
|
+
<span class="cline-any cline-neutral"> </span>
|
|
856
|
+
<span class="cline-any cline-neutral"> </span>
|
|
857
|
+
<span class="cline-any cline-neutral"> </span>
|
|
858
|
+
<span class="cline-any cline-neutral"> </span>
|
|
859
|
+
<span class="cline-any cline-neutral"> </span>
|
|
860
|
+
<span class="cline-any cline-neutral"> </span>
|
|
861
|
+
<span class="cline-any cline-neutral"> </span>
|
|
862
|
+
<span class="cline-any cline-neutral"> </span>
|
|
863
|
+
<span class="cline-any cline-neutral"> </span>
|
|
864
|
+
<span class="cline-any cline-neutral"> </span>
|
|
865
|
+
<span class="cline-any cline-neutral"> </span>
|
|
866
|
+
<span class="cline-any cline-neutral"> </span>
|
|
867
|
+
<span class="cline-any cline-neutral"> </span>
|
|
868
|
+
<span class="cline-any cline-neutral"> </span>
|
|
869
|
+
<span class="cline-any cline-neutral"> </span>
|
|
870
|
+
<span class="cline-any cline-neutral"> </span>
|
|
871
|
+
<span class="cline-any cline-neutral"> </span>
|
|
872
|
+
<span class="cline-any cline-neutral"> </span>
|
|
873
|
+
<span class="cline-any cline-neutral"> </span>
|
|
874
|
+
<span class="cline-any cline-neutral"> </span>
|
|
875
|
+
<span class="cline-any cline-neutral"> </span>
|
|
876
|
+
<span class="cline-any cline-neutral"> </span>
|
|
877
|
+
<span class="cline-any cline-neutral"> </span>
|
|
878
|
+
<span class="cline-any cline-neutral"> </span>
|
|
879
|
+
<span class="cline-any cline-neutral"> </span>
|
|
880
|
+
<span class="cline-any cline-neutral"> </span>
|
|
881
|
+
<span class="cline-any cline-neutral"> </span>
|
|
882
|
+
<span class="cline-any cline-neutral"> </span>
|
|
883
|
+
<span class="cline-any cline-neutral"> </span>
|
|
884
|
+
<span class="cline-any cline-neutral"> </span>
|
|
885
|
+
<span class="cline-any cline-neutral"> </span>
|
|
886
|
+
<span class="cline-any cline-neutral"> </span>
|
|
887
|
+
<span class="cline-any cline-neutral"> </span>
|
|
888
|
+
<span class="cline-any cline-neutral"> </span>
|
|
889
|
+
<span class="cline-any cline-neutral"> </span>
|
|
890
|
+
<span class="cline-any cline-neutral"> </span>
|
|
891
|
+
<span class="cline-any cline-neutral"> </span>
|
|
892
|
+
<span class="cline-any cline-neutral"> </span>
|
|
893
|
+
<span class="cline-any cline-neutral"> </span>
|
|
894
|
+
<span class="cline-any cline-neutral"> </span>
|
|
895
|
+
<span class="cline-any cline-neutral"> </span>
|
|
896
|
+
<span class="cline-any cline-neutral"> </span>
|
|
897
|
+
<span class="cline-any cline-neutral"> </span>
|
|
898
|
+
<span class="cline-any cline-neutral"> </span>
|
|
899
|
+
<span class="cline-any cline-neutral"> </span>
|
|
900
|
+
<span class="cline-any cline-neutral"> </span>
|
|
901
|
+
<span class="cline-any cline-neutral"> </span>
|
|
902
|
+
<span class="cline-any cline-neutral"> </span>
|
|
903
|
+
<span class="cline-any cline-neutral"> </span>
|
|
904
|
+
<span class="cline-any cline-neutral"> </span>
|
|
905
|
+
<span class="cline-any cline-neutral"> </span>
|
|
906
|
+
<span class="cline-any cline-neutral"> </span>
|
|
907
|
+
<span class="cline-any cline-neutral"> </span>
|
|
908
|
+
<span class="cline-any cline-yes">6x</span>
|
|
909
|
+
<span class="cline-any cline-yes">3x</span>
|
|
910
|
+
<span class="cline-any cline-neutral"> </span>
|
|
911
|
+
<span class="cline-any cline-neutral"> </span>
|
|
912
|
+
<span class="cline-any cline-neutral"> </span>
|
|
913
|
+
<span class="cline-any cline-yes">3x</span>
|
|
914
|
+
<span class="cline-any cline-neutral"> </span>
|
|
915
|
+
<span class="cline-any cline-neutral"> </span>
|
|
916
|
+
<span class="cline-any cline-neutral"> </span>
|
|
917
|
+
<span class="cline-any cline-neutral"> </span>
|
|
918
|
+
<span class="cline-any cline-neutral"> </span>
|
|
919
|
+
<span class="cline-any cline-neutral"> </span>
|
|
920
|
+
<span class="cline-any cline-neutral"> </span>
|
|
921
|
+
<span class="cline-any cline-neutral"> </span>
|
|
922
|
+
<span class="cline-any cline-neutral"> </span>
|
|
923
|
+
<span class="cline-any cline-neutral"> </span>
|
|
924
|
+
<span class="cline-any cline-neutral"> </span>
|
|
925
|
+
<span class="cline-any cline-neutral"> </span>
|
|
926
|
+
<span class="cline-any cline-neutral"> </span>
|
|
927
|
+
<span class="cline-any cline-neutral"> </span>
|
|
928
|
+
<span class="cline-any cline-neutral"> </span>
|
|
929
|
+
<span class="cline-any cline-neutral"> </span>
|
|
930
|
+
<span class="cline-any cline-neutral"> </span>
|
|
931
|
+
<span class="cline-any cline-neutral"> </span>
|
|
932
|
+
<span class="cline-any cline-neutral"> </span>
|
|
933
|
+
<span class="cline-any cline-neutral"> </span>
|
|
934
|
+
<span class="cline-any cline-neutral"> </span>
|
|
935
|
+
<span class="cline-any cline-neutral"> </span>
|
|
936
|
+
<span class="cline-any cline-neutral"> </span>
|
|
937
|
+
<span class="cline-any cline-neutral"> </span>
|
|
938
|
+
<span class="cline-any cline-neutral"> </span>
|
|
939
|
+
<span class="cline-any cline-neutral"> </span>
|
|
940
|
+
<span class="cline-any cline-neutral"> </span>
|
|
941
|
+
<span class="cline-any cline-neutral"> </span>
|
|
942
|
+
<span class="cline-any cline-neutral"> </span>
|
|
943
|
+
<span class="cline-any cline-neutral"> </span>
|
|
944
|
+
<span class="cline-any cline-neutral"> </span>
|
|
945
|
+
<span class="cline-any cline-neutral"> </span>
|
|
946
|
+
<span class="cline-any cline-neutral"> </span>
|
|
947
|
+
<span class="cline-any cline-neutral"> </span>
|
|
948
|
+
<span class="cline-any cline-neutral"> </span>
|
|
949
|
+
<span class="cline-any cline-neutral"> </span>
|
|
950
|
+
<span class="cline-any cline-neutral"> </span>
|
|
951
|
+
<span class="cline-any cline-neutral"> </span>
|
|
952
|
+
<span class="cline-any cline-neutral"> </span>
|
|
953
|
+
<span class="cline-any cline-neutral"> </span>
|
|
954
|
+
<span class="cline-any cline-neutral"> </span>
|
|
955
|
+
<span class="cline-any cline-neutral"> </span>
|
|
956
|
+
<span class="cline-any cline-neutral"> </span>
|
|
957
|
+
<span class="cline-any cline-neutral"> </span>
|
|
958
|
+
<span class="cline-any cline-neutral"> </span>
|
|
959
|
+
<span class="cline-any cline-neutral"> </span>
|
|
960
|
+
<span class="cline-any cline-neutral"> </span>
|
|
961
|
+
<span class="cline-any cline-neutral"> </span>
|
|
962
|
+
<span class="cline-any cline-neutral"> </span>
|
|
963
|
+
<span class="cline-any cline-neutral"> </span>
|
|
964
|
+
<span class="cline-any cline-neutral"> </span>
|
|
965
|
+
<span class="cline-any cline-neutral"> </span>
|
|
966
|
+
<span class="cline-any cline-neutral"> </span>
|
|
967
|
+
<span class="cline-any cline-yes">3x</span>
|
|
968
|
+
<span class="cline-any cline-neutral"> </span>
|
|
969
|
+
<span class="cline-any cline-neutral"> </span>
|
|
970
|
+
<span class="cline-any cline-neutral"> </span>
|
|
971
|
+
<span class="cline-any cline-neutral"> </span>
|
|
972
|
+
<span class="cline-any cline-neutral"> </span>
|
|
973
|
+
<span class="cline-any cline-neutral"> </span>
|
|
974
|
+
<span class="cline-any cline-neutral"> </span>
|
|
975
|
+
<span class="cline-any cline-neutral"> </span>
|
|
976
|
+
<span class="cline-any cline-neutral"> </span>
|
|
977
|
+
<span class="cline-any cline-neutral"> </span>
|
|
978
|
+
<span class="cline-any cline-neutral"> </span>
|
|
979
|
+
<span class="cline-any cline-neutral"> </span>
|
|
980
|
+
<span class="cline-any cline-neutral"> </span>
|
|
981
|
+
<span class="cline-any cline-neutral"> </span>
|
|
982
|
+
<span class="cline-any cline-neutral"> </span>
|
|
983
|
+
<span class="cline-any cline-neutral"> </span>
|
|
984
|
+
<span class="cline-any cline-neutral"> </span>
|
|
985
|
+
<span class="cline-any cline-neutral"> </span>
|
|
986
|
+
<span class="cline-any cline-neutral"> </span>
|
|
987
|
+
<span class="cline-any cline-neutral"> </span>
|
|
988
|
+
<span class="cline-any cline-neutral"> </span>
|
|
989
|
+
<span class="cline-any cline-neutral"> </span>
|
|
990
|
+
<span class="cline-any cline-neutral"> </span>
|
|
991
|
+
<span class="cline-any cline-neutral"> </span>
|
|
992
|
+
<span class="cline-any cline-neutral"> </span>
|
|
993
|
+
<span class="cline-any cline-neutral"> </span>
|
|
994
|
+
<span class="cline-any cline-neutral"> </span>
|
|
995
|
+
<span class="cline-any cline-neutral"> </span>
|
|
996
|
+
<span class="cline-any cline-neutral"> </span>
|
|
997
|
+
<span class="cline-any cline-neutral"> </span>
|
|
998
|
+
<span class="cline-any cline-neutral"> </span>
|
|
999
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1000
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1001
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1002
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1003
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1004
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1005
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1006
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1007
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1008
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1009
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1010
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1011
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1012
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">'use strict';
|
|
1013
|
+
|
|
1014
|
+
const crypto = require('crypto');
|
|
1015
|
+
const redent = require('redent');
|
|
1016
|
+
const Lambda = require('./lambda');
|
|
1017
|
+
const merge = require('../merge');
|
|
1018
|
+
|
|
1019
|
+
const random = crypto.randomBytes(4).toString('hex');
|
|
1020
|
+
|
|
1021
|
+
function assertNodeVersion(runtime) {
|
|
1022
|
+
if (runtime.match(/^nodejs[\d+]+.x$/)) {
|
|
1023
|
+
const version = runtime.match(/\d+/)[0];
|
|
1024
|
+
<span class="missing-if-branch" title="else path not taken" >E</span>if (Number(version) < 18)
|
|
1025
|
+
throw new Error(`Only nodejs runtimes >= 18 are supported for hookshot lambdas, received: '${runtime}'`);
|
|
1026
|
+
} else {
|
|
1027
|
+
throw new Error(`Only valid nodejs runtimes are supported for hookshot lambdas, received: '${runtime}'`);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* The hookshot.Passthrough class defines resources that set up a single API Gateway
|
|
1033
|
+
* endpoint that responds to `POST` and `OPTIONS` requests. You are expected to
|
|
1034
|
+
* provide a Lambda function that will receive the request, and return some
|
|
1035
|
+
* response to the caller.
|
|
1036
|
+
*
|
|
1037
|
+
* Note that in this case, your Lambda function will receive every HTTP `POST`
|
|
1038
|
+
* request that arrives at the API Gateway URL that hookshot helped you create.
|
|
1039
|
+
* You are responsible for any authentication that should be performed against
|
|
1040
|
+
* incoming requests.
|
|
1041
|
+
*
|
|
1042
|
+
* Your Lambda function will receive an event object which includes the request
|
|
1043
|
+
* method, headers, and body, as well as other data specific to the API Gateway
|
|
1044
|
+
* endpoint created by hookshot. See [AWS documentation here](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format)
|
|
1045
|
+
* for a full description of the incoming data.
|
|
1046
|
+
*
|
|
1047
|
+
* To work properly, **your lambda function must return a data object
|
|
1048
|
+
* matching in a specific JSON format**. Again, see [AWS documentation for a full description](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format).
|
|
1049
|
+
*
|
|
1050
|
+
* Your API Gateway endpoint will allow cross-origin resource
|
|
1051
|
+
* sharing (CORS) required by requests from any webpage. Preflight `OPTIONS`
|
|
1052
|
+
* requests will receive a `200` response with CORS headers. And the response
|
|
1053
|
+
* you return from your Lambda function will be modified to include CORS headers.
|
|
1054
|
+
*
|
|
1055
|
+
* The generated template's `Outputs` will include the URL for the API Gateway endpoint,
|
|
1056
|
+
* and a random string that can be used as a shared secret.
|
|
1057
|
+
*
|
|
1058
|
+
* @name hookshot.Passthrough
|
|
1059
|
+
*
|
|
1060
|
+
* @param {String} Prefix - This will be used to prefix the set of CloudFormation
|
|
1061
|
+
* resources created by this shortcut.
|
|
1062
|
+
* @param {String} PassthroughTo - The logical name of the Lambda function that you
|
|
1063
|
+
* have written which will receive a request and generate a response to provide
|
|
1064
|
+
* to the caller.
|
|
1065
|
+
* @param {String} [LoggingLevel='OFF'] - One of `OFF`, `INFO`, or `ERROR`. Logs are delivered
|
|
1066
|
+
* to a CloudWatch Log Group named `API-Gateway-Execution-Logs_{rest-api-id}/hookshot`.
|
|
1067
|
+
* @param {Boolean} [DataTraceEnabled=false] - Set to `true` to enable full request/response
|
|
1068
|
+
* logging in the API's logs.
|
|
1069
|
+
* @param {Boolean} [MetricsEnabled=false] - Set to `true` to enable additional metrics in CloudWatch.
|
|
1070
|
+
* @param {String} [AccessLogFormat] - A single line format of the access logs of
|
|
1071
|
+
* data, as specified by selected `$context` variables. The format must include at
|
|
1072
|
+
* least `$context.requestId`. [See AWS documentation for details](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-stage-accesslogsetting.html#cfn-apigateway-stage-accesslogsetting-format).
|
|
1073
|
+
* @param {String|Object} [WebhookSecret] - A secret string to be used to verify
|
|
1074
|
+
* payload signatures that are delivered to the endpoint. This is optional. If
|
|
1075
|
+
* not specified, a string will be generated for you. Implementation of
|
|
1076
|
+
* signature verification is up to the caller.
|
|
1077
|
+
*
|
|
1078
|
+
* @example
|
|
1079
|
+
* const cf = require('@mapbox/cloudfriend');
|
|
1080
|
+
*
|
|
1081
|
+
* const myTemplate = {
|
|
1082
|
+
* ...
|
|
1083
|
+
* Resources: {
|
|
1084
|
+
* MyLambdaFunction: {
|
|
1085
|
+
* Type: 'AWS::Lambda::Function',
|
|
1086
|
+
* Properties: { ... }
|
|
1087
|
+
* }
|
|
1088
|
+
* }
|
|
1089
|
+
* };
|
|
1090
|
+
*
|
|
1091
|
+
* const webhook = new cf.shortcuts.hookshot.Passthrough({
|
|
1092
|
+
* Prefix: 'Webhook',
|
|
1093
|
+
* PassthroughTo: 'MyLambdaFunction'
|
|
1094
|
+
* });
|
|
1095
|
+
*
|
|
1096
|
+
* module.exports = cf.merge(myTemplate, webhook);
|
|
1097
|
+
*/
|
|
1098
|
+
class Passthrough {
|
|
1099
|
+
constructor(options) {
|
|
1100
|
+
if (!options) throw new Error('Options required');
|
|
1101
|
+
const {
|
|
1102
|
+
Prefix,
|
|
1103
|
+
PassthroughTo,
|
|
1104
|
+
AccessLogFormat,
|
|
1105
|
+
DataTraceEnabled = false,
|
|
1106
|
+
MetricsEnabled = false,
|
|
1107
|
+
WebhookSecret
|
|
1108
|
+
} = options;
|
|
1109
|
+
|
|
1110
|
+
if (options.Runtime) assertNodeVersion(options.Runtime);
|
|
1111
|
+
|
|
1112
|
+
let {
|
|
1113
|
+
LoggingLevel = 'OFF'
|
|
1114
|
+
} = options;
|
|
1115
|
+
|
|
1116
|
+
const required = [Prefix, PassthroughTo];
|
|
1117
|
+
if (required.some((variable) => !variable))
|
|
1118
|
+
throw new Error('You must provide a Prefix, and PassthroughTo');
|
|
1119
|
+
|
|
1120
|
+
if (!['OFF', 'INFO', 'ERROR'].includes(LoggingLevel))
|
|
1121
|
+
throw new Error('LoggingLevel must be one of OFF, INFO, or ERROR');
|
|
1122
|
+
|
|
1123
|
+
if (DataTraceEnabled)
|
|
1124
|
+
LoggingLevel = LoggingLevel === 'OFF' ? 'ERROR' : LoggingLevel;
|
|
1125
|
+
|
|
1126
|
+
this.Prefix = Prefix;
|
|
1127
|
+
this.PassthroughTo = PassthroughTo;
|
|
1128
|
+
this.WebhookSecret = options.WebhookSecret;
|
|
1129
|
+
|
|
1130
|
+
const Resources = {
|
|
1131
|
+
[`${Prefix}Api`]: {
|
|
1132
|
+
Type: 'AWS::ApiGateway::RestApi',
|
|
1133
|
+
Properties: {
|
|
1134
|
+
Name: { 'Fn::Sub': '${AWS::StackName}-webhook' },
|
|
1135
|
+
FailOnWarnings: true,
|
|
1136
|
+
EndpointConfiguration: {
|
|
1137
|
+
Types: ['REGIONAL']
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
},
|
|
1141
|
+
|
|
1142
|
+
[`${Prefix}Stage`]: {
|
|
1143
|
+
Type: 'AWS::ApiGateway::Stage',
|
|
1144
|
+
Properties: {
|
|
1145
|
+
DeploymentId: { Ref: `${Prefix}Deployment${random}` },
|
|
1146
|
+
StageName: 'hookshot',
|
|
1147
|
+
RestApiId: { Ref: `${Prefix}Api` },
|
|
1148
|
+
MethodSettings: [
|
|
1149
|
+
{
|
|
1150
|
+
HttpMethod: '*',
|
|
1151
|
+
ResourcePath: '/*',
|
|
1152
|
+
ThrottlingBurstLimit: 20,
|
|
1153
|
+
ThrottlingRateLimit: 5,
|
|
1154
|
+
LoggingLevel,
|
|
1155
|
+
DataTraceEnabled,
|
|
1156
|
+
MetricsEnabled
|
|
1157
|
+
}
|
|
1158
|
+
]
|
|
1159
|
+
}
|
|
1160
|
+
},
|
|
1161
|
+
|
|
1162
|
+
[`${Prefix}Deployment${random}`]: {
|
|
1163
|
+
Type: 'AWS::ApiGateway::Deployment',
|
|
1164
|
+
DependsOn: `${Prefix}Method`,
|
|
1165
|
+
Properties: {
|
|
1166
|
+
RestApiId: { Ref: `${Prefix}Api` },
|
|
1167
|
+
StageName: 'unused'
|
|
1168
|
+
}
|
|
1169
|
+
},
|
|
1170
|
+
|
|
1171
|
+
[`${Prefix}Resource`]: {
|
|
1172
|
+
Type: 'AWS::ApiGateway::Resource',
|
|
1173
|
+
Properties: {
|
|
1174
|
+
ParentId: { 'Fn::GetAtt': [`${Prefix}Api`, 'RootResourceId'] },
|
|
1175
|
+
RestApiId: { Ref: `${Prefix}Api` },
|
|
1176
|
+
PathPart: 'webhook'
|
|
1177
|
+
}
|
|
1178
|
+
},
|
|
1179
|
+
|
|
1180
|
+
[`${Prefix}OptionsMethod`]: {
|
|
1181
|
+
Type: 'AWS::ApiGateway::Method',
|
|
1182
|
+
Properties: {
|
|
1183
|
+
RestApiId: { Ref: `${Prefix}Api` },
|
|
1184
|
+
ResourceId: { Ref: `${Prefix}Resource` },
|
|
1185
|
+
ApiKeyRequired: false,
|
|
1186
|
+
AuthorizationType: 'NONE',
|
|
1187
|
+
HttpMethod: 'OPTIONS',
|
|
1188
|
+
Integration: {
|
|
1189
|
+
Type: 'AWS_PROXY',
|
|
1190
|
+
IntegrationHttpMethod: 'POST',
|
|
1191
|
+
Uri: { 'Fn::Sub': `arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${Prefix}Function.Arn}/invocations` }
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
},
|
|
1195
|
+
|
|
1196
|
+
[`${Prefix}Method`]: this.method(),
|
|
1197
|
+
|
|
1198
|
+
[`${Prefix}Permission`]: {
|
|
1199
|
+
Type: 'AWS::Lambda::Permission',
|
|
1200
|
+
Properties: {
|
|
1201
|
+
FunctionName: { Ref: `${Prefix}Function` },
|
|
1202
|
+
Action: 'lambda:InvokeFunction',
|
|
1203
|
+
Principal: 'apigateway.amazonaws.com',
|
|
1204
|
+
SourceArn: { 'Fn::Sub': `arn:aws:execute-api:\${AWS::Region}:\${AWS::AccountId}:\${${Prefix}Api}/*` }
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
if (!WebhookSecret) Resources[`${Prefix}Secret`] = {
|
|
1210
|
+
Type: 'AWS::ApiGateway::ApiKey',
|
|
1211
|
+
Properties: {
|
|
1212
|
+
Enabled: false
|
|
1213
|
+
}
|
|
1214
|
+
};
|
|
1215
|
+
|
|
1216
|
+
if (AccessLogFormat) {
|
|
1217
|
+
Resources[`${Prefix}AccessLogs`] = {
|
|
1218
|
+
Type: 'AWS::Logs::LogGroup',
|
|
1219
|
+
Properties: {
|
|
1220
|
+
LogGroupName: { 'Fn::Sub': `\${AWS::StackName}-${Prefix}-access-logs` },
|
|
1221
|
+
RetentionInDays: 14
|
|
1222
|
+
}
|
|
1223
|
+
};
|
|
1224
|
+
|
|
1225
|
+
Resources[`${Prefix}Stage`].Properties.AccessLogSetting = {
|
|
1226
|
+
DestinationArn: { 'Fn::GetAtt': [`${Prefix}AccessLogs`, 'Arn'] },
|
|
1227
|
+
Format: AccessLogFormat
|
|
1228
|
+
};
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
const lambda = new Lambda(
|
|
1232
|
+
Object.assign({}, options, {
|
|
1233
|
+
LogicalName: `${Prefix}Function`,
|
|
1234
|
+
FunctionName: { 'Fn::Sub': `\${AWS::StackName}-${Prefix}` },
|
|
1235
|
+
Code: { ZipFile: this.code() },
|
|
1236
|
+
Description: { 'Fn::Sub': 'Passthrough function for ${AWS::StackName}' },
|
|
1237
|
+
Handler: 'index.lambda',
|
|
1238
|
+
Timeout: 30,
|
|
1239
|
+
MemorySize: 128,
|
|
1240
|
+
Statement: [
|
|
1241
|
+
{
|
|
1242
|
+
Effect: 'Allow',
|
|
1243
|
+
Action: 'lambda:InvokeFunction',
|
|
1244
|
+
Resource: { 'Fn::GetAtt': [PassthroughTo, 'Arn'] }
|
|
1245
|
+
}
|
|
1246
|
+
]
|
|
1247
|
+
})
|
|
1248
|
+
);
|
|
1249
|
+
|
|
1250
|
+
this.Resources = merge({ Resources }, lambda).Resources;
|
|
1251
|
+
|
|
1252
|
+
this.Outputs = {
|
|
1253
|
+
[`${Prefix}EndpointOutput`]: {
|
|
1254
|
+
Description: 'The HTTPS endpoint used to send github webhooks',
|
|
1255
|
+
Value: { 'Fn::Sub': `https://\${${Prefix}Api}.execute-api.\${AWS::Region}.amazonaws.com/hookshot/webhook` }
|
|
1256
|
+
},
|
|
1257
|
+
|
|
1258
|
+
[`${Prefix}SecretOutput`]: {
|
|
1259
|
+
Description: 'A secret key to give Github to use when signing webhook requests',
|
|
1260
|
+
Value: WebhookSecret ? WebhookSecret : { Ref: `${Prefix}Secret` }
|
|
1261
|
+
}
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
method() {
|
|
1266
|
+
return {
|
|
1267
|
+
Type: 'AWS::ApiGateway::Method',
|
|
1268
|
+
Properties: {
|
|
1269
|
+
RestApiId: { Ref: `${this.Prefix}Api` },
|
|
1270
|
+
ResourceId: { Ref: `${this.Prefix}Resource` },
|
|
1271
|
+
ApiKeyRequired: false,
|
|
1272
|
+
AuthorizationType: 'NONE',
|
|
1273
|
+
HttpMethod: 'POST',
|
|
1274
|
+
Integration: {
|
|
1275
|
+
Type: 'AWS_PROXY',
|
|
1276
|
+
IntegrationHttpMethod: 'POST',
|
|
1277
|
+
Uri: { 'Fn::Sub': `arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${this.Prefix}Function.Arn}/invocations` }
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
};
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
code() {
|
|
1284
|
+
return {
|
|
1285
|
+
'Fn::Sub': redent(`
|
|
1286
|
+
'use strict';
|
|
1287
|
+
|
|
1288
|
+
const { InvokeCommand, LambdaClient } = require('@aws-sdk/client-lambda');
|
|
1289
|
+
const client = new LambdaClient();
|
|
1290
|
+
|
|
1291
|
+
module.exports.lambda = (event, context, callback) => {
|
|
1292
|
+
if (event.httpMethod === 'OPTIONS') {
|
|
1293
|
+
const requestHeaders = event.headers['Access-Control-Request-Headers'] || event.headers['access-control-request-headers'];
|
|
1294
|
+
const response = {
|
|
1295
|
+
statusCode: 200,
|
|
1296
|
+
body: '',
|
|
1297
|
+
headers: {
|
|
1298
|
+
'Access-Control-Allow-Headers': requestHeaders,
|
|
1299
|
+
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
|
1300
|
+
'Access-Control-Allow-Origin': '*'
|
|
1301
|
+
}
|
|
1302
|
+
};
|
|
1303
|
+
return callback(null, response);
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
const command = new InvokeCommand({
|
|
1307
|
+
FunctionName: '\${${this.PassthroughTo}}',
|
|
1308
|
+
Payload: JSON.stringify(event)
|
|
1309
|
+
});
|
|
1310
|
+
|
|
1311
|
+
client.send(command)
|
|
1312
|
+
.then((response) => {
|
|
1313
|
+
if (!response || !response.Payload)
|
|
1314
|
+
return callback(new Error('Your Lambda function ${this.PassthroughTo} did not provide a payload'));
|
|
1315
|
+
|
|
1316
|
+
var payload = JSON.parse(Buffer.from(response.Payload).toString());
|
|
1317
|
+
payload.headers = payload.headers || {};
|
|
1318
|
+
payload.headers['Access-Control-Allow-Origin'] = '*';
|
|
1319
|
+
callback(null, payload);
|
|
1320
|
+
})
|
|
1321
|
+
.catch((err) => callback(err));
|
|
1322
|
+
};
|
|
1323
|
+
`).trim()
|
|
1324
|
+
};
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
/**
|
|
1329
|
+
* The hookshot.Github class defines resources that set up a single API Gateway
|
|
1330
|
+
* endpoint that is designed responds to POST requests sent from GitHub in
|
|
1331
|
+
* response to various GitHub events. The hookshot system will use a shared
|
|
1332
|
+
* secret to validate that the incoming payload did in fact originate from GitHub,
|
|
1333
|
+
* before sending the event payload to your Lambda function for further
|
|
1334
|
+
* processing. Any requests that did not come from GitHub or were not properly
|
|
1335
|
+
* signed using your secret key are rejected, and will never make it to your
|
|
1336
|
+
* Lambda function.
|
|
1337
|
+
*
|
|
1338
|
+
* @name hookshot.Github
|
|
1339
|
+
*
|
|
1340
|
+
* @property {Object} Resources - the CloudFormation resources created by this shortcut.
|
|
1341
|
+
* @property {Object} Outputs - the CloudFormation outputs created by this
|
|
1342
|
+
* shortcut. This includes the URL for the API Gateway endpoint, and a secret
|
|
1343
|
+
* string. Use these two values to configure GitHub to send webhooks to your
|
|
1344
|
+
* API Gateway endpoint.
|
|
1345
|
+
*
|
|
1346
|
+
* @param {String} Prefix this will be used to prefix the set of CloudFormation
|
|
1347
|
+
* resources created by this shortcut.
|
|
1348
|
+
* @param {String} PassthroughTo the logical name of the Lambda function that you
|
|
1349
|
+
* have written which will receive a request and generate a response to provide
|
|
1350
|
+
* to the caller.
|
|
1351
|
+
* @param {String} LoggingLevel one of `OFF`, `INFO`, or `ERROR`. Logs are delivered
|
|
1352
|
+
* to a CloudWatch LogGroup named `API-Gateway-Execution-Logs_{rest-api-id}/hookshot`
|
|
1353
|
+
* @param {String|Object} [WebhookSecret] A secret string to be used to verify
|
|
1354
|
+
* payload signatures that are delivered to the endpoint. This is optional. If
|
|
1355
|
+
* not specified, a string will be generated for you. You should provide this
|
|
1356
|
+
* value to GitHub, and signature verification will be performed before your
|
|
1357
|
+
* Lambda function being invoked to respond to the event.
|
|
1358
|
+
*
|
|
1359
|
+
* @example
|
|
1360
|
+
* const cf = require('@mapbox/cloudfriend');
|
|
1361
|
+
*
|
|
1362
|
+
* const myTemplate = {
|
|
1363
|
+
* ...
|
|
1364
|
+
* Resources: {
|
|
1365
|
+
* MyLambdaFunction: {
|
|
1366
|
+
* Type: 'AWS::Lambda::Function',
|
|
1367
|
+
* Properties: { ... }
|
|
1368
|
+
* }
|
|
1369
|
+
* }
|
|
1370
|
+
* };
|
|
1371
|
+
*
|
|
1372
|
+
* const webhook = new cf.shortcuts.hookshot.Github({
|
|
1373
|
+
* Prefix: 'Webhook',
|
|
1374
|
+
* PassthroughTo: 'MyLambdaFunction'
|
|
1375
|
+
* });
|
|
1376
|
+
*
|
|
1377
|
+
* module.exports = cf.merge(myTemplate, webhook);
|
|
1378
|
+
*/
|
|
1379
|
+
class Github extends Passthrough {
|
|
1380
|
+
constructor(options = {}) {
|
|
1381
|
+
super(options);
|
|
1382
|
+
delete this.Resources[`${this.Prefix}OptionsMethod`];
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
method() {
|
|
1386
|
+
return {
|
|
1387
|
+
Type: 'AWS::ApiGateway::Method',
|
|
1388
|
+
Properties: {
|
|
1389
|
+
RestApiId: { Ref: `${this.Prefix}Api` },
|
|
1390
|
+
ResourceId: { Ref: `${this.Prefix}Resource` },
|
|
1391
|
+
ApiKeyRequired: false,
|
|
1392
|
+
AuthorizationType: 'NONE',
|
|
1393
|
+
HttpMethod: 'POST',
|
|
1394
|
+
Integration: {
|
|
1395
|
+
Type: 'AWS',
|
|
1396
|
+
IntegrationHttpMethod: 'POST',
|
|
1397
|
+
IntegrationResponses: [
|
|
1398
|
+
{
|
|
1399
|
+
StatusCode: '200'
|
|
1400
|
+
},
|
|
1401
|
+
{
|
|
1402
|
+
StatusCode: '500',
|
|
1403
|
+
SelectionPattern: '^error.*'
|
|
1404
|
+
},
|
|
1405
|
+
{
|
|
1406
|
+
StatusCode: '403',
|
|
1407
|
+
SelectionPattern: '^invalid.*'
|
|
1408
|
+
}
|
|
1409
|
+
],
|
|
1410
|
+
Uri: { 'Fn::Sub': `arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${this.Prefix}Function.Arn}/invocations` },
|
|
1411
|
+
RequestTemplates: {
|
|
1412
|
+
'application/json': '{"signature":"$input.params(\'X-Hub-Signature\')","body":$input.json(\'$\')}'
|
|
1413
|
+
}
|
|
1414
|
+
},
|
|
1415
|
+
MethodResponses: [
|
|
1416
|
+
{
|
|
1417
|
+
StatusCode: '200',
|
|
1418
|
+
ResponseModels: {
|
|
1419
|
+
'application/json': 'Empty'
|
|
1420
|
+
}
|
|
1421
|
+
},
|
|
1422
|
+
{
|
|
1423
|
+
StatusCode: '500',
|
|
1424
|
+
ResponseModels: {
|
|
1425
|
+
'application/json': 'Empty'
|
|
1426
|
+
}
|
|
1427
|
+
},
|
|
1428
|
+
{
|
|
1429
|
+
StatusCode: '403',
|
|
1430
|
+
ResponseModels: {
|
|
1431
|
+
'application/json': 'Empty'
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
]
|
|
1435
|
+
}
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
code() {
|
|
1440
|
+
return {
|
|
1441
|
+
'Fn::Sub': [
|
|
1442
|
+
redent(`
|
|
1443
|
+
'use strict';
|
|
1444
|
+
|
|
1445
|
+
const crypto = require('crypto');
|
|
1446
|
+
const { InvokeCommand, LambdaClient } = require('@aws-sdk/client-lambda');
|
|
1447
|
+
const client = new LambdaClient();
|
|
1448
|
+
const secret = '\${WebhookSecret}';
|
|
1449
|
+
|
|
1450
|
+
module.exports.lambda = (event, context, callback) => {
|
|
1451
|
+
const body = event.body;
|
|
1452
|
+
const hash = 'sha1=' + crypto
|
|
1453
|
+
.createHmac('sha1', secret)
|
|
1454
|
+
.update(Buffer.from(JSON.stringify(body)))
|
|
1455
|
+
.digest('hex');
|
|
1456
|
+
|
|
1457
|
+
if (event.signature !== hash)
|
|
1458
|
+
return callback('invalid: signature does not match');
|
|
1459
|
+
|
|
1460
|
+
if (body.zen) return callback(null, 'ignored ping request');
|
|
1461
|
+
|
|
1462
|
+
const command = new InvokeCommand({
|
|
1463
|
+
FunctionName: '\${${this.PassthroughTo}}',
|
|
1464
|
+
Payload: JSON.stringify(event.body),
|
|
1465
|
+
InvocationType: 'Event'
|
|
1466
|
+
});
|
|
1467
|
+
|
|
1468
|
+
client.send(command)
|
|
1469
|
+
.then(() => callback(null, 'success'))
|
|
1470
|
+
.catch((err) => callback(err));
|
|
1471
|
+
};
|
|
1472
|
+
`).trim(),
|
|
1473
|
+
{
|
|
1474
|
+
WebhookSecret: this.WebhookSecret || { Ref: `${this.Prefix}Secret` }
|
|
1475
|
+
}
|
|
1476
|
+
]
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
module.exports = {
|
|
1482
|
+
Passthrough,
|
|
1483
|
+
Github
|
|
1484
|
+
};
|
|
1485
|
+
</pre></td></tr></table></pre>
|
|
1486
|
+
|
|
1487
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
1488
|
+
</div><!-- /wrapper -->
|
|
1489
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
1490
|
+
Code coverage generated by
|
|
1491
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1492
|
+
at 2026-02-09T18:26:12.950Z
|
|
1493
|
+
</div>
|
|
1494
|
+
<script src="../../../prettify.js"></script>
|
|
1495
|
+
<script>
|
|
1496
|
+
window.onload = function () {
|
|
1497
|
+
prettyPrint();
|
|
1498
|
+
};
|
|
1499
|
+
</script>
|
|
1500
|
+
<script src="../../../sorter.js"></script>
|
|
1501
|
+
<script src="../../../block-navigation.js"></script>
|
|
1502
|
+
</body>
|
|
1503
|
+
</html>
|
|
1504
|
+
|