shaapi 0.1.0__py3-none-any.whl

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 (141) hide show
  1. shaapi/__init__.py +3 -0
  2. shaapi/cli.py +97 -0
  3. shaapi/generator.py +114 -0
  4. shaapi/template/.dockerignore +37 -0
  5. shaapi/template/.env.template +59 -0
  6. shaapi/template/.gitattributes +12 -0
  7. shaapi/template/.gitignore +170 -0
  8. shaapi/template/.gitlab-ci.yml +89 -0
  9. shaapi/template/Dockerfile +59 -0
  10. shaapi/template/LICENSE +21 -0
  11. shaapi/template/README.md +206 -0
  12. shaapi/template/backend/.gitignore +164 -0
  13. shaapi/template/backend/__init__.py +0 -0
  14. shaapi/template/backend/alembic/README +1 -0
  15. shaapi/template/backend/alembic/env.py +102 -0
  16. shaapi/template/backend/alembic/script.py.mako +26 -0
  17. shaapi/template/backend/alembic/versions/2026_06_08_1024-64524c63b666_initial.py +143 -0
  18. shaapi/template/backend/alembic.ini +117 -0
  19. shaapi/template/backend/app/__init__.py +55 -0
  20. shaapi/template/backend/app/admin/__init__.py +1 -0
  21. shaapi/template/backend/app/admin/api/v1/__init__.py +0 -0
  22. shaapi/template/backend/app/admin/api/v1/auth.py +59 -0
  23. shaapi/template/backend/app/admin/api/v1/casbin.py +218 -0
  24. shaapi/template/backend/app/admin/api/v1/login_log.py +63 -0
  25. shaapi/template/backend/app/admin/api/v1/opera_log.py +61 -0
  26. shaapi/template/backend/app/admin/api/v1/role.py +108 -0
  27. shaapi/template/backend/app/admin/api/v1/user.py +47 -0
  28. shaapi/template/backend/app/admin/schema/casbin_rule.py +45 -0
  29. shaapi/template/backend/app/admin/schema/login_log.py +36 -0
  30. shaapi/template/backend/app/admin/schema/opera_log.py +43 -0
  31. shaapi/template/backend/app/admin/schema/role.py +36 -0
  32. shaapi/template/backend/app/admin/schema/sso.py +37 -0
  33. shaapi/template/backend/app/admin/schema/token.py +74 -0
  34. shaapi/template/backend/app/admin/schema/user.py +93 -0
  35. shaapi/template/backend/app/admin/service/auth_service.py +233 -0
  36. shaapi/template/backend/app/admin/service/casbin_service.py +135 -0
  37. shaapi/template/backend/app/admin/service/login_log_service.py +62 -0
  38. shaapi/template/backend/app/admin/service/opera_log_service.py +31 -0
  39. shaapi/template/backend/app/admin/service/role_service.py +79 -0
  40. shaapi/template/backend/app/admin/service/secure_token_service.py +60 -0
  41. shaapi/template/backend/app/admin/service/user_service.py +153 -0
  42. shaapi/template/backend/app/api.py +11 -0
  43. shaapi/template/backend/common/__init__.py +0 -0
  44. shaapi/template/backend/common/cloud_storage/__init__.py +11 -0
  45. shaapi/template/backend/common/cloud_storage/cloud_storage.py +180 -0
  46. shaapi/template/backend/common/dataclasses.py +52 -0
  47. shaapi/template/backend/common/email_conf/email.py +105 -0
  48. shaapi/template/backend/common/enums.py +144 -0
  49. shaapi/template/backend/common/exception/__init__.py +0 -0
  50. shaapi/template/backend/common/exception/errors.py +87 -0
  51. shaapi/template/backend/common/exception/exception_handler.py +280 -0
  52. shaapi/template/backend/common/log.py +123 -0
  53. shaapi/template/backend/common/model.py +68 -0
  54. shaapi/template/backend/common/pagination.py +83 -0
  55. shaapi/template/backend/common/response/__init__.py +0 -0
  56. shaapi/template/backend/common/response/response_code.py +158 -0
  57. shaapi/template/backend/common/response/response_schema.py +110 -0
  58. shaapi/template/backend/common/schema.py +144 -0
  59. shaapi/template/backend/common/security/jwt.py +203 -0
  60. shaapi/template/backend/common/security/rbac.py +98 -0
  61. shaapi/template/backend/common/security/sec_token.py +6 -0
  62. shaapi/template/backend/common/socketio/action.py +11 -0
  63. shaapi/template/backend/common/socketio/server.py +50 -0
  64. shaapi/template/backend/common/sso/base.py +69 -0
  65. shaapi/template/backend/common/sso/google.py +127 -0
  66. shaapi/template/backend/core/conf.py +208 -0
  67. shaapi/template/backend/core/path_conf.py +24 -0
  68. shaapi/template/backend/core/registrar.py +195 -0
  69. shaapi/template/backend/crud/__init__.py +1 -0
  70. shaapi/template/backend/crud/crud_base.py +35 -0
  71. shaapi/template/backend/crud/crud_casbin.py +46 -0
  72. shaapi/template/backend/crud/crud_login_log.py +58 -0
  73. shaapi/template/backend/crud/crud_opera_log.py +58 -0
  74. shaapi/template/backend/crud/crud_role.py +128 -0
  75. shaapi/template/backend/crud/crud_user.py +267 -0
  76. shaapi/template/backend/database/__init__.py +0 -0
  77. shaapi/template/backend/database/db_postgres.py +125 -0
  78. shaapi/template/backend/database/db_redis.py +62 -0
  79. shaapi/template/backend/entrypoint-api.sh +19 -0
  80. shaapi/template/backend/lang/en/app.py +18 -0
  81. shaapi/template/backend/lang/en/auth.py +10 -0
  82. shaapi/template/backend/lang/fr/app.py +18 -0
  83. shaapi/template/backend/lang/fr/auth.py +10 -0
  84. shaapi/template/backend/main.py +54 -0
  85. shaapi/template/backend/middleware/__init__.py +1 -0
  86. shaapi/template/backend/middleware/access_middleware.py +19 -0
  87. shaapi/template/backend/middleware/i18n_middleware.py +19 -0
  88. shaapi/template/backend/middleware/jwt_auth_middleware.py +73 -0
  89. shaapi/template/backend/middleware/opera_log_middleware.py +179 -0
  90. shaapi/template/backend/middleware/state_middleware.py +26 -0
  91. shaapi/template/backend/models/__init__.py +10 -0
  92. shaapi/template/backend/models/associations.py +20 -0
  93. shaapi/template/backend/models/casbin_rule.py +30 -0
  94. shaapi/template/backend/models/login_log.py +28 -0
  95. shaapi/template/backend/models/opera_log.py +36 -0
  96. shaapi/template/backend/models/role.py +27 -0
  97. shaapi/template/backend/models/user.py +30 -0
  98. shaapi/template/backend/seeder/json/admin.json +15 -0
  99. shaapi/template/backend/seeder/json/user.json +15 -0
  100. shaapi/template/backend/seeder/run.py +34 -0
  101. shaapi/template/backend/static/ip2region.xdb +0 -0
  102. shaapi/template/backend/templates/build/meet.html +169 -0
  103. shaapi/template/backend/templates/build/new_account.html +373 -0
  104. shaapi/template/backend/templates/build/reset-password.html +170 -0
  105. shaapi/template/backend/templates/build/test_email.html +25 -0
  106. shaapi/template/backend/templates/build/welcome-one-1.html +160 -0
  107. shaapi/template/backend/templates/build/welcome-one.html +178 -0
  108. shaapi/template/backend/templates/build/welcome-two.html +234 -0
  109. shaapi/template/backend/templates/index.html +0 -0
  110. shaapi/template/backend/templates/src/new_account.mjml +15 -0
  111. shaapi/template/backend/templates/src/reset_password.mjml +19 -0
  112. shaapi/template/backend/templates/src/test_email.mjml +11 -0
  113. shaapi/template/backend/templates/ws/ws.html +70 -0
  114. shaapi/template/backend/utils/demo_site.py +18 -0
  115. shaapi/template/backend/utils/encrypt.py +108 -0
  116. shaapi/template/backend/utils/health_check.py +34 -0
  117. shaapi/template/backend/utils/prometheus.py +135 -0
  118. shaapi/template/backend/utils/request_parse.py +110 -0
  119. shaapi/template/backend/utils/serializers.py +75 -0
  120. shaapi/template/backend/utils/timezone.py +51 -0
  121. shaapi/template/backend/utils/trace_id.py +7 -0
  122. shaapi/template/backend/utils/translator.py +28 -0
  123. shaapi/template/devops/scripts/deploy.sh +7 -0
  124. shaapi/template/devops/scripts/setup_env.sh +62 -0
  125. shaapi/template/docker-compose.monitoring.yml +63 -0
  126. shaapi/template/docker-compose.override.yml +12 -0
  127. shaapi/template/docker-compose.yml +90 -0
  128. shaapi/template/docker-run.sh +99 -0
  129. shaapi/template/etc/dashboards/fastapi-observability.json +1044 -0
  130. shaapi/template/etc/dashboards.yaml +10 -0
  131. shaapi/template/etc/grafana/datasource.yml +79 -0
  132. shaapi/template/etc/prometheus/prometheus.yml +52 -0
  133. shaapi/template/package-lock.json +2102 -0
  134. shaapi/template/package.json +16 -0
  135. shaapi/template/pyproject.toml +78 -0
  136. shaapi/template/uv.lock +2866 -0
  137. shaapi-0.1.0.dist-info/METADATA +92 -0
  138. shaapi-0.1.0.dist-info/RECORD +141 -0
  139. shaapi-0.1.0.dist-info/WHEEL +4 -0
  140. shaapi-0.1.0.dist-info/entry_points.txt +2 -0
  141. shaapi-0.1.0.dist-info/licenses/LICENCE +21 -0
@@ -0,0 +1,169 @@
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Invitation</title>
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet" />
9
+ <style type="text/css">
10
+ body {
11
+ font-family: 'Inter', Arial, sans-serif;
12
+ margin: 0;
13
+ padding: 0;
14
+ color: #4f4d55;
15
+ background-color: #f4f4f4;
16
+ }
17
+
18
+ .container {
19
+ width: 100%;
20
+ max-width: 640px;
21
+ margin: 0 auto;
22
+ background-color: #ffffff;
23
+ padding: 32px;
24
+ text-align: left;
25
+ border-radius: 8px;
26
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
27
+ }
28
+
29
+ header {
30
+ padding: 24px;
31
+ }
32
+
33
+ header img {
34
+ max-width: 130px;
35
+ }
36
+
37
+ main {
38
+ padding: 32px 24px;
39
+ }
40
+
41
+ main p {
42
+ font-size: 16px;
43
+ line-height: 24px;
44
+ margin-bottom: 16px;
45
+ }
46
+
47
+ main div {
48
+ margin-top: 32px;
49
+ }
50
+
51
+ footer {
52
+ padding: 32px 24px;
53
+ font-size: 14px;
54
+ line-height: 20px;
55
+ }
56
+
57
+ footer p span {
58
+ color: #fc5933;
59
+ text-decoration: underline;
60
+ cursor: pointer;
61
+ }
62
+
63
+ footer div {
64
+ margin-top: 48px;
65
+ display: flex;
66
+ justify-content: space-between;
67
+ flex-direction: row;
68
+ align-items: center;
69
+ }
70
+
71
+ .footer-image {
72
+ max-width: 90px;
73
+ }
74
+
75
+ .social-icons {
76
+ display: flex;
77
+ flex-direction: row;
78
+ align-items: center;
79
+ gap: 16px;
80
+ }
81
+
82
+ .social-icons img {
83
+ width: 20px;
84
+ height: 20px;
85
+ }
86
+
87
+ @media (max-width: 600px) {
88
+ .container {
89
+ padding: 16px;
90
+ }
91
+
92
+ main {
93
+ padding: 16px;
94
+ }
95
+
96
+ footer {
97
+ padding: 16px;
98
+ }
99
+
100
+ footer div {
101
+ flex-direction: column;
102
+ gap: 16px;
103
+ }
104
+ }
105
+ </style>
106
+ </head>
107
+
108
+ <body>
109
+ <div class="container">
110
+ <header>
111
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718814671/test/Logo_nsmysd.png"
112
+ alt="Logo de Boilerplate" />
113
+ </header>
114
+ <main>
115
+ <p>Bonjour Samuel,</p>
116
+ <p>
117
+ Paul vous a invité à rejoindre le meet de Mise à niveau du parcours.
118
+ </p>
119
+
120
+ <div>
121
+ <a href="https://boilerplate.com/auth/login" style="
122
+ color: #ffffff;
123
+ font-weight: 500;
124
+ size: 16px;
125
+ line-height: 24px;
126
+ background-color: #fc5933;
127
+ text-decoration: none;
128
+ width: 185px;
129
+ height: 44px;
130
+ padding: 10px 16px;
131
+ border: 1.5px;
132
+ border-radius: 99px;
133
+ ">Accepter l'invitation</a>
134
+ </div>
135
+ </main>
136
+ <footer>
137
+ <p>
138
+ Ce courriel a été envoyé à <span>@boilerplate.com</span>. Si vous préférez
139
+ ne pas recevoir ce type d'e-mail, vous pouvez vous
140
+ <span>désabonner</span> ou
141
+ <span>gérer vos préférences en matière d'e-mail</span>.
142
+ </p>
143
+ <p>&copy; Boilerplate co., 38 Rue Legendre, 75017 Paris, France</p>
144
+ <div>
145
+ <div>
146
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718814671/test/Logo_nsmysd.png"
147
+ alt="Logo de Boilerplate" class="footer-image" />
148
+ </div>
149
+ <div class="social-icons">
150
+ <a href="https://www.twitter.com/nomdelentreprise" target="_blank">
151
+ <img src="https://upload.wikimedia.org/wikipedia/commons/5/53/X_logo_2023_original.svg" alt="X" />
152
+ </a>
153
+ <a href="https://www.facebook.com/nomdelentreprise" target="_blank">
154
+ <img src="https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg"
155
+ alt="Facebook" />
156
+ </a>
157
+ <a href="https://www.instagram.com/nomdelentreprise" target="_blank">
158
+ <img src="https://upload.wikimedia.org/wikipedia/commons/a/a5/Instagram_icon.png" alt="Instagram" />
159
+ </a>
160
+ <a href="https://www.linkedin.com/company/nomdelentreprise" target="_blank">
161
+ <img src="https://upload.wikimedia.org/wikipedia/commons/c/ca/LinkedIn_logo_initials.png" alt="LinkedIn" />
162
+ </a>
163
+ </div>
164
+ </div>
165
+ </footer>
166
+ </div>
167
+ </body>
168
+
169
+ </html>
@@ -0,0 +1,373 @@
1
+ <!DOCTYPE html>
2
+ <html
3
+ xmlns="http://www.w3.org/1999/xhtml"
4
+ xmlns:v="urn:schemas-microsoft-com:vml"
5
+ xmlns:o="urn:schemas-microsoft-com:office:office"
6
+ >
7
+ <head>
8
+ <title></title>
9
+ <!--[if !mso]><!-- -->
10
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
11
+ <!--<![endif]-->
12
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
13
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
14
+ <style type="text/css">
15
+ #outlook a {
16
+ padding: 0;
17
+ }
18
+ .ReadMsgBody {
19
+ width: 100%;
20
+ }
21
+ .ExternalClass {
22
+ width: 100%;
23
+ }
24
+ .ExternalClass * {
25
+ line-height: 100%;
26
+ }
27
+ body {
28
+ margin: 0;
29
+ padding: 0;
30
+ -webkit-text-size-adjust: 100%;
31
+ -ms-text-size-adjust: 100%;
32
+ }
33
+ table,
34
+ td {
35
+ border-collapse: collapse;
36
+ mso-table-lspace: 0pt;
37
+ mso-table-rspace: 0pt;
38
+ }
39
+ img {
40
+ border: 0;
41
+ height: auto;
42
+ line-height: 100%;
43
+ outline: none;
44
+ text-decoration: none;
45
+ -ms-interpolation-mode: bicubic;
46
+ }
47
+ p {
48
+ display: block;
49
+ margin: 13px 0;
50
+ }
51
+ </style>
52
+ <!--[if !mso]><!-->
53
+ <style type="text/css">
54
+ @media only screen and (max-width: 480px) {
55
+ @-ms-viewport {
56
+ width: 320px;
57
+ }
58
+ @viewport {
59
+ width: 320px;
60
+ }
61
+ }
62
+ </style>
63
+ <!--<![endif]-->
64
+ <!--[if mso]>
65
+ <xml>
66
+ <o:OfficeDocumentSettings>
67
+ <o:AllowPNG />
68
+ <o:PixelsPerInch>96</o:PixelsPerInch>
69
+ </o:OfficeDocumentSettings>
70
+ </xml>
71
+ <![endif]-->
72
+ <!--[if lte mso 11]>
73
+ <style type="text/css">
74
+ .outlook-group-fix {
75
+ width: 100% !important;
76
+ }
77
+ </style>
78
+ <![endif]-->
79
+ <!--[if !mso]><!-->
80
+ <link
81
+ href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700"
82
+ rel="stylesheet"
83
+ type="text/css"
84
+ />
85
+ <style type="text/css">
86
+ @import url(https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700);
87
+ </style>
88
+ <!--<![endif]-->
89
+ <style type="text/css">
90
+ @media only screen and (min-width: 480px) {
91
+ .mj-column-per-100 {
92
+ width: 100% !important;
93
+ max-width: 100%;
94
+ }
95
+ }
96
+ </style>
97
+ <style type="text/css"></style>
98
+ </head>
99
+ <body style="background-color: #ffffff">
100
+ <div style="background-color: #ffffff">
101
+ <!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
102
+ <div style="margin: 0px auto; max-width: 600px">
103
+ <table
104
+ align="center"
105
+ border="0"
106
+ cellpadding="0"
107
+ cellspacing="0"
108
+ role="presentation"
109
+ style="width: 100%"
110
+ >
111
+ <tbody>
112
+ <tr>
113
+ <td
114
+ style="
115
+ direction: ltr;
116
+ font-size: 0px;
117
+ padding: 20px 0;
118
+ text-align: center;
119
+ vertical-align: top;
120
+ "
121
+ >
122
+ <!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]-->
123
+ <div
124
+ class="mj-column-per-100 outlook-group-fix"
125
+ style="
126
+ font-size: 13px;
127
+ text-align: left;
128
+ direction: ltr;
129
+ display: inline-block;
130
+ vertical-align: top;
131
+ width: 100%;
132
+ "
133
+ >
134
+ <table
135
+ border="0"
136
+ cellpadding="0"
137
+ cellspacing="0"
138
+ role="presentation"
139
+ style="vertical-align: top"
140
+ width="100%"
141
+ >
142
+ <tr>
143
+ <td
144
+ style="
145
+ font-size: 0px;
146
+ padding: 10px 25px;
147
+ word-break: break-word;
148
+ "
149
+ >
150
+ <p
151
+ style="
152
+ border-top: solid 4px #555555;
153
+ font-size: 1;
154
+ margin: 0px auto;
155
+ width: 100%;
156
+ "
157
+ ></p>
158
+ <!--[if mso | IE
159
+ ]><table
160
+ align="center"
161
+ border="0"
162
+ cellpadding="0"
163
+ cellspacing="0"
164
+ style="
165
+ border-top: solid 4px #555555;
166
+ font-size: 1;
167
+ margin: 0px auto;
168
+ width: 550px;
169
+ "
170
+ role="presentation"
171
+ width="550px"
172
+ >
173
+ <tr>
174
+ <td style="height: 0; line-height: 0">&nbsp;</td>
175
+ </tr>
176
+ </table><!
177
+ [endif]-->
178
+ </td>
179
+ </tr>
180
+ <tr>
181
+ <td
182
+ align="left"
183
+ style="
184
+ font-size: 0px;
185
+ padding: 10px 25px;
186
+ word-break: break-word;
187
+ "
188
+ >
189
+ <div
190
+ style="
191
+ font-family: helvetica;
192
+ font-size: 20px;
193
+ line-height: 1;
194
+ text-align: left;
195
+ color: #555555;
196
+ "
197
+ >
198
+ {{ project_name }} - New Account
199
+ </div>
200
+ </td>
201
+ </tr>
202
+ <tr>
203
+ <td
204
+ align="left"
205
+ style="
206
+ font-size: 0px;
207
+ padding: 10px 25px;
208
+ word-break: break-word;
209
+ "
210
+ >
211
+ <div
212
+ style="
213
+ font-family: Ubuntu, Helvetica, Arial, sans-serif;
214
+ font-size: 16px;
215
+ line-height: 1;
216
+ text-align: left;
217
+ color: #555555;
218
+ "
219
+ >
220
+ You have a new account:
221
+ </div>
222
+ </td>
223
+ </tr>
224
+ <tr>
225
+ <td
226
+ align="left"
227
+ style="
228
+ font-size: 0px;
229
+ padding: 10px 25px;
230
+ word-break: break-word;
231
+ "
232
+ >
233
+ <div
234
+ style="
235
+ font-family: Ubuntu, Helvetica, Arial, sans-serif;
236
+ font-size: 16px;
237
+ line-height: 1;
238
+ text-align: left;
239
+ color: #555555;
240
+ "
241
+ >
242
+ Username: {{ first_name }}
243
+ </div>
244
+ </td>
245
+ </tr>
246
+ <tr>
247
+ <td
248
+ align="left"
249
+ style="
250
+ font-size: 0px;
251
+ padding: 10px 25px;
252
+ word-break: break-word;
253
+ "
254
+ >
255
+ <div
256
+ style="
257
+ font-family: Ubuntu, Helvetica, Arial, sans-serif;
258
+ font-size: 16px;
259
+ line-height: 1;
260
+ text-align: left;
261
+ color: #555555;
262
+ "
263
+ >
264
+ Url: {{ url }}
265
+ </div>
266
+ </td>
267
+ </tr>
268
+ <div>
269
+ subject: {{ subject }}
270
+ </div>
271
+ <tr>
272
+ <td
273
+ align="center"
274
+ vertical-align="middle"
275
+ style="
276
+ font-size: 0px;
277
+ padding: 50px 0px;
278
+ word-break: break-word;
279
+ "
280
+ >
281
+ <table
282
+ border="0"
283
+ cellpadding="0"
284
+ cellspacing="0"
285
+ role="presentation"
286
+ style="border-collapse: separate; line-height: 100%"
287
+ >
288
+ <tr>
289
+ <td
290
+ align="center"
291
+ bgcolor="#414141"
292
+ role="presentation"
293
+ style="
294
+ border: none;
295
+ border-radius: 3px;
296
+ cursor: auto;
297
+ padding: 10px 25px;
298
+ background: #414141;
299
+ "
300
+ valign="middle"
301
+ >
302
+ <a
303
+ href="{{ link }}"
304
+ style="
305
+ background: #414141;
306
+ color: #ffffff;
307
+ font-family: Ubuntu, Helvetica, Arial,
308
+ sans-serif;
309
+ font-size: 13px;
310
+ font-weight: normal;
311
+ line-height: 120%;
312
+ margin: 0;
313
+ text-decoration: none;
314
+ text-transform: none;
315
+ "
316
+ target="_blank"
317
+ >Go to Dashboard</a
318
+ >
319
+ </td>
320
+ </tr>
321
+ </table>
322
+ </td>
323
+ </tr>
324
+ <tr>
325
+ <td
326
+ style="
327
+ font-size: 0px;
328
+ padding: 10px 25px;
329
+ word-break: break-word;
330
+ "
331
+ >
332
+ <p
333
+ style="
334
+ border-top: solid 2px #555555;
335
+ font-size: 1;
336
+ margin: 0px auto;
337
+ width: 100%;
338
+ "
339
+ ></p>
340
+ <!--[if mso | IE
341
+ ]><table
342
+ align="center"
343
+ border="0"
344
+ cellpadding="0"
345
+ cellspacing="0"
346
+ style="
347
+ border-top: solid 2px #555555;
348
+ font-size: 1;
349
+ margin: 0px auto;
350
+ width: 550px;
351
+ "
352
+ role="presentation"
353
+ width="550px"
354
+ >
355
+ <tr>
356
+ <td style="height: 0; line-height: 0">&nbsp;</td>
357
+ </tr>
358
+ </table><!
359
+ [endif]-->
360
+ </td>
361
+ </tr>
362
+ </table>
363
+ </div>
364
+ <!--[if mso | IE]></td></tr></table><![endif]-->
365
+ </td>
366
+ </tr>
367
+ </tbody>
368
+ </table>
369
+ </div>
370
+ <!--[if mso | IE]></td></tr></table><![endif]-->
371
+ </div>
372
+ </body>
373
+ </html>