@sbc-connect/nuxt-base 0.0.0-test-ld-20260520212549
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/.env.example +11 -0
- package/CHANGELOG.md +338 -0
- package/LICENSE +28 -0
- package/README.md +55 -0
- package/app/app.config.ts +441 -0
- package/app/app.vue +18 -0
- package/app/assets/css/connect-base-layout.css +13 -0
- package/app/assets/css/connect-base-tw.css +303 -0
- package/app/components/Connect/Address/Display.vue +84 -0
- package/app/components/Connect/BCGovLogo.vue +42 -0
- package/app/components/Connect/Breadcrumb.vue +68 -0
- package/app/components/Connect/ButtonControl/Buttons.vue +28 -0
- package/app/components/Connect/ButtonControl/Index.vue +66 -0
- package/app/components/Connect/ButtonControl/Wrapper.vue +18 -0
- package/app/components/Connect/Contact/Display.vue +65 -0
- package/app/components/Connect/FloatingLabel.vue +67 -0
- package/app/components/Connect/Footer.vue +99 -0
- package/app/components/Connect/Header/LogoHomeLink.vue +20 -0
- package/app/components/Connect/Header/WhatsNew.vue +36 -0
- package/app/components/Connect/Header/Wrapper.vue +14 -0
- package/app/components/Connect/Header/index.vue +17 -0
- package/app/components/Connect/I18n/Helper.vue +40 -0
- package/app/components/Connect/Input.vue +69 -0
- package/app/components/Connect/InputDate.vue +104 -0
- package/app/components/Connect/Layout/Index.vue +25 -0
- package/app/components/Connect/Layout/Sidebar.vue +38 -0
- package/app/components/Connect/LocaleSelect.vue +37 -0
- package/app/components/Connect/Modal/Error.vue +76 -0
- package/app/components/Connect/Modal/index.vue +51 -0
- package/app/components/Connect/PageSection.vue +57 -0
- package/app/components/Connect/Select.vue +28 -0
- package/app/components/Connect/Slideover/WhatsNew.vue +61 -0
- package/app/components/Connect/Spinner.vue +91 -0
- package/app/components/Connect/SystemBanner.vue +53 -0
- package/app/components/Connect/Textarea.vue +27 -0
- package/app/components/Connect/Tombstone/Item.vue +51 -0
- package/app/components/Connect/Tombstone/index.vue +123 -0
- package/app/components/Connect/Transition/Collapse.vue +39 -0
- package/app/components/Connect/Transition/Fade.vue +31 -0
- package/app/components/HelloWorld/Index.vue +14 -0
- package/app/composables/useConnectButtonControl.ts +146 -0
- package/app/composables/useConnectLaunchDarkly.ts +173 -0
- package/app/composables/useConnectModal.ts +13 -0
- package/app/composables/useConnectTombstone.ts +25 -0
- package/app/coverage/app/app.config.ts.html +1408 -0
- package/app/coverage/app/app.vue.html +139 -0
- package/app/coverage/app/components/Connect/Address/Display.vue.html +337 -0
- package/app/coverage/app/components/Connect/Address/index.html +116 -0
- package/app/coverage/app/components/Connect/BCGovLogo.vue.html +211 -0
- package/app/coverage/app/components/Connect/Breadcrumb.vue.html +289 -0
- package/app/coverage/app/components/Connect/ButtonControl/Buttons.vue.html +166 -0
- package/app/coverage/app/components/Connect/ButtonControl/Index.vue.html +283 -0
- package/app/coverage/app/components/Connect/ButtonControl/Wrapper.vue.html +139 -0
- package/app/coverage/app/components/Connect/ButtonControl/index.html +146 -0
- package/app/coverage/app/components/Connect/Contact/Display.vue.html +280 -0
- package/app/coverage/app/components/Connect/Contact/index.html +116 -0
- package/app/coverage/app/components/Connect/FloatingLabel.vue.html +286 -0
- package/app/coverage/app/components/Connect/Footer.vue.html +382 -0
- package/app/coverage/app/components/Connect/Header/LogoHomeLink.vue.html +145 -0
- package/app/coverage/app/components/Connect/Header/WhatsNew.vue.html +193 -0
- package/app/coverage/app/components/Connect/Header/Wrapper.vue.html +127 -0
- package/app/coverage/app/components/Connect/Header/index.html +161 -0
- package/app/coverage/app/components/Connect/Header/index.vue.html +136 -0
- package/app/coverage/app/components/Connect/I18n/Helper.vue.html +205 -0
- package/app/coverage/app/components/Connect/I18n/index.html +116 -0
- package/app/coverage/app/components/Connect/Input.vue.html +262 -0
- package/app/coverage/app/components/Connect/InputDate.vue.html +406 -0
- package/app/coverage/app/components/Connect/Layout/Index.vue.html +160 -0
- package/app/coverage/app/components/Connect/Layout/Sidebar.vue.html +199 -0
- package/app/coverage/app/components/Connect/Layout/index.html +131 -0
- package/app/coverage/app/components/Connect/LocaleSelect.vue.html +196 -0
- package/app/coverage/app/components/Connect/Modal/Error.vue.html +313 -0
- package/app/coverage/app/components/Connect/Modal/index.html +131 -0
- package/app/coverage/app/components/Connect/Modal/index.vue.html +238 -0
- package/app/coverage/app/components/Connect/PageSection.vue.html +256 -0
- package/app/coverage/app/components/Connect/Select.vue.html +169 -0
- package/app/coverage/app/components/Connect/Slideover/WhatsNew.vue.html +268 -0
- package/app/coverage/app/components/Connect/Slideover/index.html +116 -0
- package/app/coverage/app/components/Connect/Spinner.vue.html +358 -0
- package/app/coverage/app/components/Connect/SystemBanner.vue.html +244 -0
- package/app/coverage/app/components/Connect/Textarea.vue.html +160 -0
- package/app/coverage/app/components/Connect/Tombstone/Item.vue.html +238 -0
- package/app/coverage/app/components/Connect/Tombstone/index.html +131 -0
- package/app/coverage/app/components/Connect/Tombstone/index.vue.html +454 -0
- package/app/coverage/app/components/Connect/Transition/Collapse.vue.html +202 -0
- package/app/coverage/app/components/Connect/Transition/Fade.vue.html +178 -0
- package/app/coverage/app/components/Connect/Transition/index.html +131 -0
- package/app/coverage/app/components/Connect/index.html +281 -0
- package/app/coverage/app/components/HelloWorld/Index.vue.html +127 -0
- package/app/coverage/app/components/HelloWorld/index.html +116 -0
- package/app/coverage/app/composables/index.html +161 -0
- package/app/coverage/app/composables/useConnectButtonControl.ts.html +523 -0
- package/app/coverage/app/composables/useConnectLaunchDarkly.ts.html +595 -0
- package/app/coverage/app/composables/useConnectModal.ts.html +124 -0
- package/app/coverage/app/composables/useConnectTombstone.ts.html +160 -0
- package/app/coverage/app/error.vue.html +247 -0
- package/app/coverage/app/index.html +146 -0
- package/app/coverage/app/interfaces/connect-address.ts.html +121 -0
- package/app/coverage/app/interfaces/connect-breadcrumb.ts.html +100 -0
- package/app/coverage/app/interfaces/connect-button-control.ts.html +151 -0
- package/app/coverage/app/interfaces/connect-contact-item.ts.html +103 -0
- package/app/coverage/app/interfaces/connect-modal.ts.html +100 -0
- package/app/coverage/app/interfaces/connect-tombstone.ts.html +208 -0
- package/app/coverage/app/interfaces/connect-whatsnew.ts.html +127 -0
- package/app/coverage/app/interfaces/index.html +206 -0
- package/app/coverage/app/layouts/ConnectBase.vue.html +100 -0
- package/app/coverage/app/layouts/index.html +116 -0
- package/app/coverage/app/plugins/index.html +146 -0
- package/app/coverage/app/plugins/maska.client.ts.html +115 -0
- package/app/coverage/app/plugins/sanitize.client.ts.html +151 -0
- package/app/coverage/app/plugins/whats-new.client.ts.html +220 -0
- package/app/coverage/app/types/dates.ts.html +136 -0
- package/app/coverage/app/types/index.html +116 -0
- package/app/coverage/app/utils/appendUrlParam.ts.html +97 -0
- package/app/coverage/app/utils/getErrorMessage.ts.html +211 -0
- package/app/coverage/app/utils/getErrorStatus.ts.html +196 -0
- package/app/coverage/app/utils/index.html +191 -0
- package/app/coverage/app/utils/logFetchError.ts.html +193 -0
- package/app/coverage/app/utils/parseSpecialCharacters.ts.html +160 -0
- package/app/coverage/app/utils/setBreadcrumbs.ts.html +100 -0
- package/app/coverage/base.css +224 -0
- package/app/coverage/block-navigation.js +87 -0
- package/app/coverage/clover.xml +2094 -0
- package/app/coverage/coverage-final.json +58 -0
- package/app/coverage/favicon.png +0 -0
- package/app/coverage/index.html +386 -0
- package/app/coverage/prettify.css +1 -0
- package/app/coverage/prettify.js +2 -0
- package/app/coverage/sort-arrow-sprite.png +0 -0
- package/app/coverage/sorter.js +210 -0
- package/app/error.vue +54 -0
- package/app/interfaces/connect-address.ts +12 -0
- package/app/interfaces/connect-breadcrumb.ts +5 -0
- package/app/interfaces/connect-button-control.ts +23 -0
- package/app/interfaces/connect-contact-item.ts +6 -0
- package/app/interfaces/connect-modal.ts +5 -0
- package/app/interfaces/connect-tombstone.ts +41 -0
- package/app/interfaces/connect-whatsnew.ts +14 -0
- package/app/layouts/ConnectBase.vue +5 -0
- package/app/plugins/maska.client.ts +10 -0
- package/app/plugins/sanitize.client.ts +22 -0
- package/app/plugins/whats-new.client.ts +45 -0
- package/app/spa-loading-template.html +61 -0
- package/app/types/base-app-config.d.ts +15 -0
- package/app/types/base-directives.d.ts +7 -0
- package/app/types/base-page-meta.d.ts +8 -0
- package/app/types/dates.ts +17 -0
- package/app/utils/appendUrlParam.ts +4 -0
- package/app/utils/getErrorMessage.ts +42 -0
- package/app/utils/getErrorStatus.ts +37 -0
- package/app/utils/logFetchError.ts +36 -0
- package/app/utils/parseSpecialCharacters.ts +25 -0
- package/app/utils/setBreadcrumbs.ts +7 -0
- package/firebase.json +34 -0
- package/i18n/locales/en-CA.ts +70 -0
- package/i18n/locales/fr-CA.ts +96 -0
- package/nuxt.config.ts +147 -0
- package/package.json +49 -0
- package/public/BCGovLogo/gov_bc_logo_horiz_en.png +0 -0
- package/public/BCGovLogo/gov_bc_logo_horiz_fr.png +0 -0
- package/public/BCGovLogo/gov_bc_logo_vert_en.png +0 -0
- package/public/BCGovLogo/gov_bc_logo_vert_fr.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/fonts/BCSans/BCSans-Bold.woff +0 -0
- package/public/fonts/BCSans/BCSans-Bold.woff2 +0 -0
- package/public/fonts/BCSans/BCSans-BoldItalic.woff +0 -0
- package/public/fonts/BCSans/BCSans-BoldItalic.woff2 +0 -0
- package/public/fonts/BCSans/BCSans-Italic.woff +0 -0
- package/public/fonts/BCSans/BCSans-Italic.woff2 +0 -0
- package/public/fonts/BCSans/BCSans-Regular.woff +0 -0
- package/public/fonts/BCSans/BCSans-Regular.woff2 +0 -0
- package/public/fonts/BCSans/LICENSE_OFL.txt +94 -0
- package/test-results/.last-run.json +7 -0
- package/test-results/error-page-404-Error-vue-D-1eb51-cted-visuals-with-404-error-Desktop-Chrome/error-context.md +135 -0
- package/test-results/error-page-404-Error-vue-D-1eb51-cted-visuals-with-404-error-Desktop-Chrome/test-failed-1.png +0 -0
- package/test-results/error-page-404-Error-vue-D-1eb51-cted-visuals-with-404-error-Desktop-Chrome/trace.zip +0 -0
- package/test-results/error-page-500-Error-vue-D-8c2cf-cted-visuals-with-500-error-Desktop-Chrome/error-context.md +135 -0
- package/test-results/error-page-500-Error-vue-D-8c2cf-cted-visuals-with-500-error-Desktop-Chrome/test-failed-1.png +0 -0
- package/test-results/error-page-500-Error-vue-D-8c2cf-cted-visuals-with-500-error-Desktop-Chrome/trace.zip +0 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@import "@nuxt/ui";
|
|
3
|
+
|
|
4
|
+
/* Customize Nuxt UI default tokens */
|
|
5
|
+
/* Follows https://sites.google.com/bcdevexchange.org/designsystem/foundation-styles/colours */
|
|
6
|
+
:root {
|
|
7
|
+
/* Nuxt UI Default Text Colours */
|
|
8
|
+
--ui-text-dimmed: var(--color-gray-400);
|
|
9
|
+
--ui-text-muted: var(--color-gray-500);
|
|
10
|
+
--ui-text-toned: var(--color-gray-600);
|
|
11
|
+
--ui-text: var(--ui-neutral);
|
|
12
|
+
--ui-text-highlighted: var(--ui-neutral-highlighted);
|
|
13
|
+
--ui-text-inverted: var(--color-white);
|
|
14
|
+
/* Variant Colours */
|
|
15
|
+
--ui-error: var(--color-red-600);
|
|
16
|
+
--ui-primary: var(--color-blue-500);
|
|
17
|
+
--ui-secondary: white;
|
|
18
|
+
--ui-success: var(--color-green-600);
|
|
19
|
+
--ui-warning: #F8661A;
|
|
20
|
+
/* Custom themes */
|
|
21
|
+
--ui-brand: var(--color-midnightBlue-900);
|
|
22
|
+
--ui-brand-inverted: var(--color-yellow-400);
|
|
23
|
+
--ui-line: #6F7780;
|
|
24
|
+
--ui-line-muted: var(--color-gray-300);
|
|
25
|
+
--ui-line-highlighted: #899EB2;
|
|
26
|
+
--ui-mark: #1A5A96;
|
|
27
|
+
--ui-mark-highlighted: #0000EE;
|
|
28
|
+
--ui-neutral: var(--color-gray-700);
|
|
29
|
+
--ui-neutral-highlighted: var(--color-gray-900);
|
|
30
|
+
--ui-neutral-toned: #757575;
|
|
31
|
+
--ui-shade-caution: #FFF7E3;
|
|
32
|
+
--ui-shade-inverted: white;
|
|
33
|
+
--ui-shade-new: #E8F5E9;
|
|
34
|
+
--ui-shade: var(--color-gray-100);
|
|
35
|
+
--ui-shade-secondary: #E2E8EE;
|
|
36
|
+
--ui-shade-highlighted: var(--color-blue-50);
|
|
37
|
+
--ui-shade-warning: #FAE9E9;
|
|
38
|
+
--ui-radius: 0.1667rem;
|
|
39
|
+
--ui-container: var(--container-bcGovLg);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* FUTURE: add dark themed colours (currently set to be the same) */
|
|
43
|
+
.dark {
|
|
44
|
+
/* Nuxt UI Default Text Colours */
|
|
45
|
+
--ui-text-dimmed: var(--ui-color-gray-400);
|
|
46
|
+
--ui-text-muted: var(--ui-color-gray-500);
|
|
47
|
+
--ui-text-toned: var(--ui-color-gray-600);
|
|
48
|
+
--ui-text: var(--ui-neutral);
|
|
49
|
+
--ui-text-highlighted: var(--ui-neutral-highlighted);
|
|
50
|
+
--ui-text-inverted: var(--color-white);
|
|
51
|
+
/* Variant Colours */
|
|
52
|
+
--ui-error: var(--color-red-600);
|
|
53
|
+
--ui-primary: var(--color-blue-500);
|
|
54
|
+
--ui-secondary: white;
|
|
55
|
+
--ui-success: var(--color-green-600);
|
|
56
|
+
--ui-warning: #F8661A;
|
|
57
|
+
/* Custom themes */
|
|
58
|
+
--ui-brand: var(--color-midnightBlue-900);
|
|
59
|
+
--ui-brand-inverted: var(--color-yellow-400);
|
|
60
|
+
--ui-line: #6F7780;
|
|
61
|
+
--ui-line-muted: var(--color-gray-300);
|
|
62
|
+
--ui-line-highlighted: #899EB2;
|
|
63
|
+
--ui-mark: #1A5A96;
|
|
64
|
+
--ui-mark-highlighted: #0000EE;
|
|
65
|
+
--ui-neutral: var(--color-gray-700);
|
|
66
|
+
--ui-neutral-highlighted: var(--color-gray-900);
|
|
67
|
+
--ui-neutral-toned: #757575;
|
|
68
|
+
--ui-shade-caution: #FFF7E3;
|
|
69
|
+
--ui-shade-inverted: white;
|
|
70
|
+
--ui-shade-new: #E8F5E9;
|
|
71
|
+
--ui-shade: var(--color-gray-100);
|
|
72
|
+
--ui-shade-secondary: #E2E8EE;
|
|
73
|
+
--ui-shade-highlighted: var(--color-blue-50);
|
|
74
|
+
--ui-shade-warning: #FAE9E9;
|
|
75
|
+
--ui-radius: 0.1667rem;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Main Theme */
|
|
79
|
+
@theme static {
|
|
80
|
+
/* font */
|
|
81
|
+
--font-sans: 'BCSans', 'Verdana', 'Arial', 'sans-serif';
|
|
82
|
+
|
|
83
|
+
/* widths */
|
|
84
|
+
--container-bcGovMd: 1020px;
|
|
85
|
+
--container-bcGovLg: 1360px;
|
|
86
|
+
--container-input: 600px;
|
|
87
|
+
|
|
88
|
+
/* list style types */
|
|
89
|
+
--marker-alpha: lower-alpha;
|
|
90
|
+
--marker-upper-alpha: upper-alpha;
|
|
91
|
+
|
|
92
|
+
/* box shadow */
|
|
93
|
+
/* bottom neutral/focused/error border for input elements */
|
|
94
|
+
--shadow-input: inset 0 -1px 0 0 var(--ui-neutral);
|
|
95
|
+
--shadow-input-focus: inset 0 -2px 0 0 var(--ui-primary);
|
|
96
|
+
--shadow-input-error: inset 0 -2px 0 0 var(--ui-error);
|
|
97
|
+
|
|
98
|
+
/* GRAY */
|
|
99
|
+
--color-gray-50: #f8f9fa;
|
|
100
|
+
--color-gray-100: #f1f3f5;
|
|
101
|
+
--color-gray-200: #e9ecef;
|
|
102
|
+
--color-gray-300: #dee2e6;
|
|
103
|
+
--color-gray-400: #ced4da;
|
|
104
|
+
--color-gray-500: #adb5bd;
|
|
105
|
+
--color-gray-600: #868e96;
|
|
106
|
+
--color-gray-700: #495057;
|
|
107
|
+
--color-gray-800: #343a40;
|
|
108
|
+
--color-gray-900: #212529;
|
|
109
|
+
--color-gray-950: #232529;
|
|
110
|
+
|
|
111
|
+
/* BLUE */
|
|
112
|
+
--color-blue-50: #e4edf7;
|
|
113
|
+
--color-blue-100: #e0e7ed;
|
|
114
|
+
--color-blue-150: #b3c2d1;
|
|
115
|
+
--color-blue-200: #8099b3;
|
|
116
|
+
--color-blue-300: #4d7094;
|
|
117
|
+
--color-blue-350: #38598a;
|
|
118
|
+
--color-blue-400: #26527d;
|
|
119
|
+
--color-blue-500: #1669bb;
|
|
120
|
+
--color-blue-600: #125192;
|
|
121
|
+
--color-blue-700: #002e5e;
|
|
122
|
+
--color-blue-800: #002753;
|
|
123
|
+
--color-blue-900: #002049;
|
|
124
|
+
--color-blue-950: #001438;
|
|
125
|
+
|
|
126
|
+
/* RED */
|
|
127
|
+
--color-red-50: #fef2f2;
|
|
128
|
+
--color-red-100: #fde3e4;
|
|
129
|
+
--color-red-200: #fdcbcc;
|
|
130
|
+
--color-red-300: #faa7a9;
|
|
131
|
+
--color-red-400: #f57478;
|
|
132
|
+
--color-red-500: #eb484d;
|
|
133
|
+
--color-red-600: #d3272c;
|
|
134
|
+
--color-red-700: #b52024;
|
|
135
|
+
--color-red-800: #961e21;
|
|
136
|
+
--color-red-900: #7d1f22;
|
|
137
|
+
--color-red-950: #440b0d;
|
|
138
|
+
|
|
139
|
+
/* YELLOW */
|
|
140
|
+
--color-yellow-50: #fffbeb;
|
|
141
|
+
--color-yellow-100: #fef2c7;
|
|
142
|
+
--color-yellow-200: #fee589;
|
|
143
|
+
--color-yellow-300: #fdd14c;
|
|
144
|
+
--color-yellow-400: #fcba19;
|
|
145
|
+
--color-yellow-500: #f69b0a;
|
|
146
|
+
--color-yellow-600: #da7505;
|
|
147
|
+
--color-yellow-700: #b55108;
|
|
148
|
+
--color-yellow-800: #933e0d;
|
|
149
|
+
--color-yellow-900: #79340e;
|
|
150
|
+
--color-yellow-950: #451903;
|
|
151
|
+
|
|
152
|
+
/* GREEN */
|
|
153
|
+
--color-green-50: #f2fbf4;
|
|
154
|
+
--color-green-100: #e2f6e6;
|
|
155
|
+
--color-green-200: #c6eccd;
|
|
156
|
+
--color-green-300: #99dca6;
|
|
157
|
+
--color-green-400: #65c378;
|
|
158
|
+
--color-green-500: #40a755;
|
|
159
|
+
--color-green-600: #2e8540;
|
|
160
|
+
--color-green-700: #286d37;
|
|
161
|
+
--color-green-800: #24572f;
|
|
162
|
+
--color-green-900: #1f4828;
|
|
163
|
+
--color-green-950: #0c2713;
|
|
164
|
+
|
|
165
|
+
/* MIDNIGHT BLUE */
|
|
166
|
+
--color-midnightBlue-50: #eef7ff;
|
|
167
|
+
--color-midnightBlue-100: #dceeff;
|
|
168
|
+
--color-midnightBlue-200: #b2dfff;
|
|
169
|
+
--color-midnightBlue-300: #6dc6ff;
|
|
170
|
+
--color-midnightBlue-400: #20a8ff;
|
|
171
|
+
--color-midnightBlue-500: #008dff;
|
|
172
|
+
--color-midnightBlue-600: #006edf;
|
|
173
|
+
--color-midnightBlue-700: #0057b4;
|
|
174
|
+
--color-midnightBlue-800: #004a94;
|
|
175
|
+
--color-midnightBlue-900: #003366;
|
|
176
|
+
--color-midnightBlue-950: #002651;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
@font-face {
|
|
180
|
+
font-family: "BCSans";
|
|
181
|
+
font-style: normal;
|
|
182
|
+
font-weight: 400;
|
|
183
|
+
src: url("BCGovFonts/BCSans-Regular.woff2") format("woff2"),
|
|
184
|
+
url("BCGovFonts/BCSans-Regular.woff") format("woff"); /* Optimized for very modern browsers */
|
|
185
|
+
font-display: swap;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
@font-face {
|
|
189
|
+
font-family: "BCSans";
|
|
190
|
+
font-style: italic;
|
|
191
|
+
font-weight: 400;
|
|
192
|
+
src: url("BCGovFonts/BCSans-Italic.woff2") format("woff2"),
|
|
193
|
+
url("BCGovFonts/BCSans-Italic.woff") format("woff"); /* Optimized for very modern browsers */
|
|
194
|
+
font-display: swap;
|
|
195
|
+
}
|
|
196
|
+
@font-face {
|
|
197
|
+
font-family: "BCSans";
|
|
198
|
+
font-weight: 700;
|
|
199
|
+
src: url("BCGovFonts/BCSans-Bold.woff2") format("woff2"),
|
|
200
|
+
url("BCGovFonts/BCSans-Bold.woff") format("woff"); /* Optimized for very modern browsers */
|
|
201
|
+
font-display: swap;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
@font-face {
|
|
205
|
+
font-family: "BCSans";
|
|
206
|
+
font-style: italic;
|
|
207
|
+
font-weight: 700;
|
|
208
|
+
src: url("BCGovFonts/BCSans-BoldItalic.woff2") format("woff2"),
|
|
209
|
+
url("BCGovFonts/BCSans-BoldItalic.woff") format("woff"); /* Optimized for very modern browsers */
|
|
210
|
+
font-display: swap;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
html,
|
|
214
|
+
body {
|
|
215
|
+
min-height: 100dvh; /* Modern browsers */
|
|
216
|
+
min-height: 100vh;
|
|
217
|
+
font-family: 'BCSans', Verdana, Arial, sans-serif;
|
|
218
|
+
font-size: 0.875rem;
|
|
219
|
+
text-rendering: optimizeLegibility;
|
|
220
|
+
-webkit-font-smoothing: antialiased;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
@media (min-width: 960px) {
|
|
224
|
+
html,
|
|
225
|
+
body {
|
|
226
|
+
font-size: 1rem;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
@layer base {
|
|
231
|
+
h1,
|
|
232
|
+
h2,
|
|
233
|
+
h3,
|
|
234
|
+
h4 {
|
|
235
|
+
@apply text-neutral-highlighted;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
h1,
|
|
239
|
+
h2,
|
|
240
|
+
h3 {
|
|
241
|
+
@apply font-bold;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
h1,
|
|
245
|
+
h2 {
|
|
246
|
+
@apply leading-9;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
h1 {
|
|
250
|
+
@apply text-3xl;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
h2 {
|
|
254
|
+
@apply text-lg;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
h3 {
|
|
258
|
+
@apply text-base;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
p {
|
|
262
|
+
@apply font-normal text-neutral;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
td,
|
|
266
|
+
th {
|
|
267
|
+
@apply text-neutral-highlighted text-sm;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/* floating labels */
|
|
271
|
+
.floating-label-input {
|
|
272
|
+
@apply pointer-events-none absolute left-0 top-3 text-neutral transition-all motion-reduce:transition-none duration-200 text-xs font-medium px-2.5 peer-focus:top-3 peer-focus:text-xs peer-placeholder-shown:text-sm peer-placeholder-shown:top-1/2 -translate-y-1/2 peer-focus:text-primary peer-aria-invalid:text-error;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.floating-label-textarea {
|
|
276
|
+
@apply pointer-events-none absolute left-0 top-1 text-neutral text-xs font-medium px-2.5 transition-all duration-200 peer-focus:top-1 peer-focus:text-xs peer-placeholder-shown:text-sm peer-placeholder-shown:top-2.5 peer-focus:translate-none peer-focus:text-primary peer-aria-invalid:text-error;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/* Standard container padding */
|
|
280
|
+
.padding-x-default {
|
|
281
|
+
@apply px-4 sm:px-7.5
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.padding-xy-default {
|
|
285
|
+
@apply py-6 px-4 sm:py-10 sm:px-7.5
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* left error border for section elements */
|
|
289
|
+
/* Psuedo element required to be visible so slot content does not cover it */
|
|
290
|
+
.shadow-section-error {
|
|
291
|
+
position: relative;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.shadow-section-error::before {
|
|
295
|
+
content: "";
|
|
296
|
+
position: absolute;
|
|
297
|
+
inset: 0 auto 0 0;
|
|
298
|
+
width: 3px;
|
|
299
|
+
background-color: var(--ui-error);
|
|
300
|
+
pointer-events: none;
|
|
301
|
+
z-index: 1;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const props = defineProps<{
|
|
3
|
+
address: Partial<ConnectAddress>
|
|
4
|
+
omitCountry?: boolean
|
|
5
|
+
separateCity?: boolean
|
|
6
|
+
textDecor?: boolean
|
|
7
|
+
}>()
|
|
8
|
+
|
|
9
|
+
const getAddressDisplayParts = (
|
|
10
|
+
address: Partial<ConnectAddress>,
|
|
11
|
+
separateCity = false,
|
|
12
|
+
addTextDecor = false,
|
|
13
|
+
omitCountry = false
|
|
14
|
+
): string[] => {
|
|
15
|
+
const regionNamesInEnglish = new Intl.DisplayNames(['en'], { type: 'region' })
|
|
16
|
+
const textDecor = addTextDecor ? ',' : ''
|
|
17
|
+
|
|
18
|
+
const getLine1 = () => {
|
|
19
|
+
return (
|
|
20
|
+
address.street || [
|
|
21
|
+
[address.unitNumber, address.streetNumber].filter(val => !!val).join('-'),
|
|
22
|
+
address.streetName
|
|
23
|
+
].filter(val => !!val).join(' ') || ''
|
|
24
|
+
) + textDecor
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const getLine2 = () => {
|
|
28
|
+
return (address.streetAdditional || '') + textDecor
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const getCity = () => {
|
|
32
|
+
return (address.city || '') + textDecor
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const getRegion = () => {
|
|
36
|
+
return address.region
|
|
37
|
+
? address.region + (addTextDecor ? '\u00A0' : '')
|
|
38
|
+
: ''
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const getCountry = () => {
|
|
42
|
+
try {
|
|
43
|
+
return address.country && !omitCountry ? (regionNamesInEnglish.of(address.country) || address.country) : ''
|
|
44
|
+
} catch {
|
|
45
|
+
return address.country || ''
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return [
|
|
49
|
+
getLine1(),
|
|
50
|
+
getLine2(),
|
|
51
|
+
separateCity ? getCity() : '',
|
|
52
|
+
[!separateCity ? getCity() : '', getRegion(), address.postalCode].filter(val => !!val).join(' ') || '',
|
|
53
|
+
getCountry()
|
|
54
|
+
].filter(val => !!val && val !== ',')
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const addressDisplay = computed<string[]>(() =>
|
|
58
|
+
getAddressDisplayParts(props.address, props.separateCity, props.textDecor, props.omitCountry)
|
|
59
|
+
)
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<template>
|
|
63
|
+
<div
|
|
64
|
+
data-testid="address-display"
|
|
65
|
+
class="flex flex-col gap-2"
|
|
66
|
+
>
|
|
67
|
+
<div>
|
|
68
|
+
<div
|
|
69
|
+
v-for="addressLine, i in addressDisplay"
|
|
70
|
+
:key="addressLine + i"
|
|
71
|
+
data-testid="address-line"
|
|
72
|
+
>
|
|
73
|
+
{{ addressLine }}
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
<span
|
|
77
|
+
v-if="address.locationDescription"
|
|
78
|
+
data-testid="location-description"
|
|
79
|
+
class="italic"
|
|
80
|
+
>
|
|
81
|
+
{{ address.locationDescription }}
|
|
82
|
+
</span>
|
|
83
|
+
</div>
|
|
84
|
+
</template>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// must explicitly import or will fail when publishing layer // TODO: find better way to handle image aliases
|
|
3
|
+
// @ts-expect-error - Cannot find module 'BCGovLogoLgFr' or its corresponding type declarations.ts(2307)
|
|
4
|
+
import frLargeLogo from 'BCGovLogoLgFr'
|
|
5
|
+
// @ts-expect-error - Cannot find module 'BCGovLogoSmFr' or its corresponding type declarations.ts(2307)
|
|
6
|
+
import frSmallLogo from 'BCGovLogoSmFr'
|
|
7
|
+
// @ts-expect-error - Cannot find module 'BCGovLogoLgEn' or its corresponding type declarations.ts(2307)
|
|
8
|
+
import enLargeLogo from 'BCGovLogoLgEn'
|
|
9
|
+
// @ts-expect-error - Cannot find module 'BCGovLogoSmEn' or its corresponding type declarations.ts(2307)
|
|
10
|
+
import enSmallLogo from 'BCGovLogoSmEn'
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<!-- use french logo for french locale, any other locale uses english logo -->
|
|
15
|
+
<div v-if="$i18n.locale === 'fr-CA'" class="shrink-0">
|
|
16
|
+
<!-- Using scale because it will increase the size of the image without affecting the container size -->
|
|
17
|
+
<!-- there is a lot of padding on the images, if only the height gets increased, -->
|
|
18
|
+
<!-- the padding makes the header too tall -->
|
|
19
|
+
<img
|
|
20
|
+
class="hidden h-[60px] scale-125 sm:block"
|
|
21
|
+
:src="frLargeLogo"
|
|
22
|
+
:alt="$t('connect.label.bcGovLogo')"
|
|
23
|
+
>
|
|
24
|
+
<img
|
|
25
|
+
class="block h-[64px] scale-125 sm:hidden"
|
|
26
|
+
:src="frSmallLogo"
|
|
27
|
+
:alt="$t('connect.label.bcGovLogo')"
|
|
28
|
+
>
|
|
29
|
+
</div>
|
|
30
|
+
<div v-else class="shrink-0">
|
|
31
|
+
<img
|
|
32
|
+
class="hidden h-[60px] scale-125 sm:block"
|
|
33
|
+
:src="enLargeLogo"
|
|
34
|
+
:alt="$t('connect.label.bcGovLogo')"
|
|
35
|
+
>
|
|
36
|
+
<img
|
|
37
|
+
class="block h-[64px] scale-150 sm:hidden"
|
|
38
|
+
:src="enSmallLogo"
|
|
39
|
+
:alt="$t('connect.label.bcGovLogo')"
|
|
40
|
+
>
|
|
41
|
+
</div>
|
|
42
|
+
</template>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const props = defineProps<{
|
|
3
|
+
accountId?: string
|
|
4
|
+
}>()
|
|
5
|
+
|
|
6
|
+
const { t } = useI18n()
|
|
7
|
+
|
|
8
|
+
const breadcrumbs = computed<ConnectBreadcrumb[]>(() => {
|
|
9
|
+
const metaCrumbs = useRoute().meta.breadcrumbs as ConnectBreadcrumb[] | undefined
|
|
10
|
+
|
|
11
|
+
if (metaCrumbs) {
|
|
12
|
+
return metaCrumbs.map((bc) => {
|
|
13
|
+
if (bc.appendAccountId && props.accountId) {
|
|
14
|
+
return {
|
|
15
|
+
...bc,
|
|
16
|
+
to: appendUrlParam(bc.to as string, 'accountid', props.accountId)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return bc
|
|
20
|
+
})
|
|
21
|
+
} else {
|
|
22
|
+
return [{ label: t('connect.breadcrumb.default') }]
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
function resolveBackHref() {
|
|
27
|
+
const bcLength = breadcrumbs.value.length
|
|
28
|
+
|
|
29
|
+
if (bcLength > 1) {
|
|
30
|
+
// return the second to last breadcrumb link
|
|
31
|
+
return breadcrumbs.value[bcLength - 2]?.to ?? breadcrumbs.value[bcLength - 2]?.href
|
|
32
|
+
} else {
|
|
33
|
+
return ''
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<div
|
|
40
|
+
v-if="$route.meta.hideBreadcrumbs !== true"
|
|
41
|
+
data-testid="connect-breadcrumb-wrapper"
|
|
42
|
+
class="bg-blue-350 p-2 sm:px-4 py-2"
|
|
43
|
+
>
|
|
44
|
+
<nav
|
|
45
|
+
:aria-label="$t('connect.breadcrumb.arialabel')"
|
|
46
|
+
class="app-inner-container flex items-center gap-3"
|
|
47
|
+
>
|
|
48
|
+
<UButton
|
|
49
|
+
class="size-[28px] rounded-full px-1 bg-secondary hover:bg-secondary/75"
|
|
50
|
+
:disabled="breadcrumbs.length < 2"
|
|
51
|
+
color="secondary"
|
|
52
|
+
icon="i-mdi-arrow-left"
|
|
53
|
+
:aria-label="$t('connect.label.goBack')"
|
|
54
|
+
:to="resolveBackHref()"
|
|
55
|
+
:ui="{
|
|
56
|
+
leadingIcon: 'text-primary',
|
|
57
|
+
}"
|
|
58
|
+
/>
|
|
59
|
+
<div class="w-[1px] bg-shade h-[24px]" />
|
|
60
|
+
<UBreadcrumb
|
|
61
|
+
as="div"
|
|
62
|
+
aria-label=""
|
|
63
|
+
:items="breadcrumbs"
|
|
64
|
+
separator-icon="i-mdi-chevron-right"
|
|
65
|
+
/>
|
|
66
|
+
</nav>
|
|
67
|
+
</div>
|
|
68
|
+
</template>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
defineProps<{ buttons: ConnectButton[], position: 'left' | 'right' }>()
|
|
3
|
+
|
|
4
|
+
// remove alertText and removeAlertSpacing from being added to button html attrs
|
|
5
|
+
const removeButtonAttrs = (button: ConnectButton) => {
|
|
6
|
+
const newButton = { ...button }
|
|
7
|
+
delete newButton['alertText']
|
|
8
|
+
delete newButton['removeAlertSpacing']
|
|
9
|
+
return newButton
|
|
10
|
+
}
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<div
|
|
15
|
+
v-for="(button, i) in buttons"
|
|
16
|
+
:key="`${position}-button-${i}`"
|
|
17
|
+
data-testid="button-wrapper"
|
|
18
|
+
class="flex flex-col grow"
|
|
19
|
+
>
|
|
20
|
+
<UButton
|
|
21
|
+
class="grow px-7 py-3 mb-1 justify-center"
|
|
22
|
+
v-bind="removeButtonAttrs(button)"
|
|
23
|
+
/>
|
|
24
|
+
<p :class="['text-center', !button.removeAlertSpacing ? 'h-[1.25rem]' : '']">
|
|
25
|
+
<span v-if="button.alertText" class="text-error">{{ button.alertText }}</span>
|
|
26
|
+
</p>
|
|
27
|
+
</div>
|
|
28
|
+
</template>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const {
|
|
3
|
+
stateKey = 'default-button-control'
|
|
4
|
+
} = defineProps<{
|
|
5
|
+
stateKey?: string
|
|
6
|
+
}>()
|
|
7
|
+
|
|
8
|
+
const { buttonControl: meta } = useConnectButtonControl(stateKey)
|
|
9
|
+
const buttonControl = computed(() => meta.value)
|
|
10
|
+
const leftGroup = computed(() => buttonControl.value?.leftGroup || [])
|
|
11
|
+
const rightGroup = computed(() => buttonControl.value?.rightGroup || [])
|
|
12
|
+
const leftAlertText = computed(() => buttonControl.value?.leftGroup.alertText || undefined)
|
|
13
|
+
const rightAlertText = computed(() => buttonControl.value?.rightGroup.alertText || undefined)
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<div
|
|
18
|
+
class="@container"
|
|
19
|
+
data-testid="connect-button-control"
|
|
20
|
+
>
|
|
21
|
+
<div class="grid grid-cols-1 gap-4 @4xl:grid-cols-2">
|
|
22
|
+
<div>
|
|
23
|
+
<div
|
|
24
|
+
class="flex justify-center @4xl:justify-start"
|
|
25
|
+
data-testid="left-buttons"
|
|
26
|
+
>
|
|
27
|
+
<div
|
|
28
|
+
class="relative grow flex flex-col flex-wrap gap-4 @4xl:grow-0"
|
|
29
|
+
:class="(leftGroup.class || '') + (leftGroup.stacked ? '' : ' flex-row')"
|
|
30
|
+
>
|
|
31
|
+
<div
|
|
32
|
+
v-if="leftAlertText"
|
|
33
|
+
class="absolute flex flex-wrap justify-start bottom-1/3 right-[-13rem] w-[12rem]"
|
|
34
|
+
>
|
|
35
|
+
<p class="text-error" role="alert">
|
|
36
|
+
{{ leftAlertText }}
|
|
37
|
+
</p>
|
|
38
|
+
</div>
|
|
39
|
+
<ConnectButtonControlButtons :buttons="leftGroup.buttons" position="left" />
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
<div>
|
|
44
|
+
<div
|
|
45
|
+
class="flex grow justify-center @4xl:justify-end"
|
|
46
|
+
data-testid="right-buttons"
|
|
47
|
+
>
|
|
48
|
+
<div
|
|
49
|
+
class="relative grow flex flex-col flex-wrap gap-4 @4xl:grow-0"
|
|
50
|
+
:class="(rightGroup.class || '') + (rightGroup.stacked ? '' : ' flex-row')"
|
|
51
|
+
>
|
|
52
|
+
<div
|
|
53
|
+
v-if="rightAlertText"
|
|
54
|
+
class="absolute flex flex-wrap justify-end bottom-1/3 left-[-13rem] w-[12rem]"
|
|
55
|
+
>
|
|
56
|
+
<p class="text-error" role="alert">
|
|
57
|
+
{{ rightAlertText }}
|
|
58
|
+
</p>
|
|
59
|
+
</div>
|
|
60
|
+
<ConnectButtonControlButtons :buttons="rightGroup.buttons" position="right" />
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</template>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const {
|
|
3
|
+
stateKey = 'default-button-control'
|
|
4
|
+
} = defineProps<{
|
|
5
|
+
stateKey?: string
|
|
6
|
+
}>()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<div
|
|
11
|
+
class="bg-shade-inverted pb-6 pt-10"
|
|
12
|
+
data-testid="connect-button-control-wrapper"
|
|
13
|
+
>
|
|
14
|
+
<div class="app-inner-container app-body">
|
|
15
|
+
<ConnectButtonControl :state-key="stateKey" />
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ConnectContactItem } from '#imports'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
contact: ConnectContactItem | ConnectContactItem[]
|
|
6
|
+
hours?: string
|
|
7
|
+
}>()
|
|
8
|
+
|
|
9
|
+
const iconMap = {
|
|
10
|
+
email: 'i-mdi-email',
|
|
11
|
+
phone: 'i-mdi-phone',
|
|
12
|
+
fax: 'i-mdi-fax'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const isMultipleContacts = computed(() => Array.isArray(props.contact))
|
|
16
|
+
const normalizedContact = computed(() => {
|
|
17
|
+
return isMultipleContacts.value ? props.contact as ConnectContactItem[] : [props.contact as ConnectContactItem]
|
|
18
|
+
})
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<div class="space-y-5">
|
|
23
|
+
<ul
|
|
24
|
+
v-if="isMultipleContacts"
|
|
25
|
+
class="space-y-1"
|
|
26
|
+
:aria-label="$t('connect.label.contactInformation')"
|
|
27
|
+
>
|
|
28
|
+
<li v-for="item in normalizedContact" :key="item.value">
|
|
29
|
+
<span class="inline-flex items-center gap-1">
|
|
30
|
+
<UIcon :name="iconMap[item.type]" class="mr-2 size-4 text-blue-350" />
|
|
31
|
+
{{ item.title }}
|
|
32
|
+
<span v-if="item.type === 'fax'">{{ item.value }}</span>
|
|
33
|
+
<a
|
|
34
|
+
v-else
|
|
35
|
+
class="text-primary underline"
|
|
36
|
+
:href="item.href"
|
|
37
|
+
:target="item.type === 'email' ? '_blank' : undefined"
|
|
38
|
+
>
|
|
39
|
+
{{ item.value }}
|
|
40
|
+
</a>
|
|
41
|
+
</span>
|
|
42
|
+
</li>
|
|
43
|
+
</ul>
|
|
44
|
+
|
|
45
|
+
<div v-else-if="normalizedContact[0]">
|
|
46
|
+
<span class="inline-flex items-center gap-1">
|
|
47
|
+
<UIcon :name="iconMap[normalizedContact[0].type]" class="mr-2 size-4 text-blue-350" />
|
|
48
|
+
{{ normalizedContact[0].title }}
|
|
49
|
+
<a
|
|
50
|
+
class="text-primary underline"
|
|
51
|
+
:href="normalizedContact[0].href"
|
|
52
|
+
:target="normalizedContact[0].type === 'email' ? '_blank' : undefined"
|
|
53
|
+
>
|
|
54
|
+
{{ normalizedContact[0].value }}
|
|
55
|
+
</a>
|
|
56
|
+
</span>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<p v-if="hours">
|
|
60
|
+
<strong class="text-neutral-highlighted">{{ $t('connect.label.hoursOfOperation') }}</strong>
|
|
61
|
+
<br>
|
|
62
|
+
{{ hours }}
|
|
63
|
+
</p>
|
|
64
|
+
</div>
|
|
65
|
+
</template>
|