@ministryofjustice/hmpps-connect-dps-components 1.0.0
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/README.md +108 -0
- package/dist/assets/_footer.scss +3 -0
- package/dist/assets/_header-bar.scss +121 -0
- package/dist/assets/dpsComponents/external-footer.njk +18 -0
- package/dist/assets/dpsComponents/external-header.njk +41 -0
- package/dist/assets/dpsComponents/footer.njk +5 -0
- package/dist/assets/dpsComponents/header-bar.njk +5 -0
- package/dist/assets/dpsComponents/prison-footer.njk +1 -0
- package/dist/assets/dpsComponents/prison-header.njk +49 -0
- package/dist/componentApiClient.d.ts +12 -0
- package/dist/componentApiClient.js +25 -0
- package/dist/componentApiClient.js.map +1 -0
- package/dist/componentsService.d.ts +3 -0
- package/dist/componentsService.js +47 -0
- package/dist/componentsService.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +22 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/types/AvailableComponent.d.ts +2 -0
- package/dist/types/AvailableComponent.js +3 -0
- package/dist/types/AvailableComponent.js.map +1 -0
- package/dist/types/CaseLoad.d.ts +7 -0
- package/dist/types/CaseLoad.js +3 -0
- package/dist/types/CaseLoad.js.map +1 -0
- package/dist/types/Component.d.ts +5 -0
- package/dist/types/Component.js +3 -0
- package/dist/types/Component.js.map +1 -0
- package/dist/types/HeaderFooterMeta.d.ts +11 -0
- package/dist/types/HeaderFooterMeta.js +3 -0
- package/dist/types/HeaderFooterMeta.js.map +1 -0
- package/dist/types/RequestOptions.d.ts +11 -0
- package/dist/types/RequestOptions.js +3 -0
- package/dist/types/RequestOptions.js.map +1 -0
- package/dist/types/Service.d.ts +7 -0
- package/dist/types/Service.js +3 -0
- package/dist/types/Service.js.map +1 -0
- package/dist/types/TimeoutOptions.d.ts +4 -0
- package/dist/types/TimeoutOptions.js +3 -0
- package/dist/types/TimeoutOptions.js.map +1 -0
- package/dist/types/User.d.ts +5 -0
- package/dist/types/User.js +3 -0
- package/dist/types/User.js.map +1 -0
- package/dist/utils/fallbacks.d.ts +4 -0
- package/dist/utils/fallbacks.js +32 -0
- package/dist/utils/fallbacks.js.map +1 -0
- package/dist/utils/updateCsp.d.ts +2 -0
- package/dist/utils/updateCsp.js +25 -0
- package/dist/utils/updateCsp.js.map +1 -0
- package/package.json +94 -0
package/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# hmpps-connect-dps-components
|
|
2
|
+
|
|
3
|
+
`hmpps-connect-dps-components` is a Node.js client library to simplify the process of incorporating global components within DPS applications.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
1. [Publishing to NPM](readme/publishing.md)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Implementation
|
|
11
|
+
|
|
12
|
+
## Prerequisites
|
|
13
|
+
|
|
14
|
+
The package assumes adherance to the standard [hmpps-template-typescript](https://github.com/ministryofjustice/hmpps-template-typescript) project.
|
|
15
|
+
It requires:
|
|
16
|
+
- a user object to be available on `res.locals` containing a token, displayName, and authSource.
|
|
17
|
+
- nunjucks to be setup
|
|
18
|
+
- an environment variable to be set for the micro frontend components api called `COMPONENT_API_URL`
|
|
19
|
+
- to be run after helmet middleware
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
To install the package, run the following command:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @ministryofjustice/hmpps-connect-dps-components
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
Currently, the package provides the header and the footer component.
|
|
32
|
+
|
|
33
|
+
To incorporate use as middleware for appropriate routes within your Express application:
|
|
34
|
+
|
|
35
|
+
```javascript
|
|
36
|
+
app.get('*', dpsComponents.get({
|
|
37
|
+
dpsUrl: config.serviceUrls.digitalPrison,
|
|
38
|
+
environmentName: 'DEV',
|
|
39
|
+
})
|
|
40
|
+
)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
There are a [number of options](./src/index.ts) available depending on your requirements.
|
|
44
|
+
|
|
45
|
+
Add the `hmpps-connect-dps-components` path to the nunjucksSetup.ts file to enable css to be loaded:
|
|
46
|
+
|
|
47
|
+
```javascript
|
|
48
|
+
const njkEnv = nunjucks.configure(
|
|
49
|
+
[
|
|
50
|
+
path.join(__dirname, '../../server/views'),
|
|
51
|
+
'node_modules/govuk-frontend/dist/',
|
|
52
|
+
'node_modules/govuk-frontend/dist/components/',
|
|
53
|
+
'node_modules/@ministryofjustice/frontend/',
|
|
54
|
+
'node_modules/@ministryofjustice/frontend/moj/components/',
|
|
55
|
+
'node_modules/@ministryofjustice/hmpps-connect-dps-components/dist/assets/',
|
|
56
|
+
],
|
|
57
|
+
{
|
|
58
|
+
autoescape: true,
|
|
59
|
+
express: app,
|
|
60
|
+
},
|
|
61
|
+
)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Include the package scss within the all.scss file
|
|
65
|
+
```scss
|
|
66
|
+
@import 'node_modules/@ministryofjustice/hmpps-connect-dps-components/dist/assets/footer';
|
|
67
|
+
@import 'node_modules/@ministryofjustice/hmpps-connect-dps-components/dist/assets/header-bar';
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Include reference to the components in your layout.njk file:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
{% for js in feComponents.jsIncludes %}
|
|
74
|
+
<script src="{{ js }}" nonce="{{ cspNonce }}"></script>
|
|
75
|
+
{% endfor %}
|
|
76
|
+
|
|
77
|
+
{% for css in feComponents.cssIncludes %}
|
|
78
|
+
<link href="{{ css }}" nonce="{{ cspNonce }}" rel="stylesheet" />
|
|
79
|
+
{% endfor %}
|
|
80
|
+
```
|
|
81
|
+
```typescript
|
|
82
|
+
{% block header %}
|
|
83
|
+
{{ feComponents.header | safe }}
|
|
84
|
+
{% endblock %}
|
|
85
|
+
```
|
|
86
|
+
```typescript
|
|
87
|
+
{% block footer %}
|
|
88
|
+
{{ feComponents.footer | safe }}
|
|
89
|
+
{% endblock %}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## CSP
|
|
93
|
+
|
|
94
|
+
The package updates the content-security-middleware to include references to the fe-components API. This package should be run after Helmet to prevent this being overwritten.
|
|
95
|
+
|
|
96
|
+
## Metadata
|
|
97
|
+
|
|
98
|
+
An optional parameter `includeMeta: true` can be passed into the `get` method. Setting this will result in a `feComponentsMeta` beind added to `res.locals` containing data the components have collected to render. This includes:
|
|
99
|
+
|
|
100
|
+
- activeCaseLoad (the active caseload of the user)
|
|
101
|
+
- caseLoads (all caseloads the user has access to)
|
|
102
|
+
- services (information on services the user has access to used for global navigation)
|
|
103
|
+
|
|
104
|
+
This can be useful e.g. for when your service needs access to activeCaseLoad information to prevent extra calls to the api and takes advantage of the caching that the micro frontend api does.
|
|
105
|
+
|
|
106
|
+
## Note
|
|
107
|
+
|
|
108
|
+
In the event of a failure to retrieve the components, the package will populate the html fields with fallback components. However, `feComponentsMeta` will not be populated. If you rely on the data from the micro frontend api, you should handle the data not being present within your application.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
.fallback-dps-header {
|
|
2
|
+
@include govuk-responsive-padding(3, 'top');
|
|
3
|
+
@include govuk-responsive-padding(3, 'bottom');
|
|
4
|
+
background-color: govuk-colour('black');
|
|
5
|
+
color: govuk-colour('white');
|
|
6
|
+
|
|
7
|
+
&__container {
|
|
8
|
+
@include govuk-width-container;
|
|
9
|
+
display: flex;
|
|
10
|
+
justify-content: space-between;
|
|
11
|
+
align-items: center;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
&__logo {
|
|
15
|
+
@include govuk-responsive-margin(2, 'right');
|
|
16
|
+
position: relative;
|
|
17
|
+
top: -2px;
|
|
18
|
+
fill: govuk-colour('white');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
&__title {
|
|
22
|
+
@include govuk-responsive-padding(3, 'right');
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
|
|
26
|
+
&__organisation-name {
|
|
27
|
+
@include govuk-responsive-margin(2, 'right');
|
|
28
|
+
@include govuk-font($size: 24, $weight: 'bold');
|
|
29
|
+
display: flex;
|
|
30
|
+
align-items: center;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&__service-name {
|
|
34
|
+
@include govuk-responsive-margin(2, 'right');
|
|
35
|
+
@include govuk-font(24);
|
|
36
|
+
display: none;
|
|
37
|
+
|
|
38
|
+
@include govuk-media-query($from: desktop) {
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
&__link {
|
|
46
|
+
@include govuk-link-common;
|
|
47
|
+
@include govuk-link-style-default;
|
|
48
|
+
|
|
49
|
+
text-underline-offset: 0.1em;
|
|
50
|
+
|
|
51
|
+
&:link,
|
|
52
|
+
&:visited,
|
|
53
|
+
&:active {
|
|
54
|
+
color: govuk-colour('white');
|
|
55
|
+
text-decoration: none;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&:hover {
|
|
59
|
+
text-decoration: underline;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&:focus {
|
|
63
|
+
color: govuk-colour('black');
|
|
64
|
+
|
|
65
|
+
svg {
|
|
66
|
+
fill: govuk-colour('black');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
&__sub-text {
|
|
71
|
+
@include govuk-font(16);
|
|
72
|
+
display: none;
|
|
73
|
+
|
|
74
|
+
@include govuk-media-query($from: tablet) {
|
|
75
|
+
display: block;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
&__navigation {
|
|
81
|
+
display: flex;
|
|
82
|
+
flex-direction: column;
|
|
83
|
+
align-items: flex-end;
|
|
84
|
+
list-style: none;
|
|
85
|
+
margin: 0;
|
|
86
|
+
padding: 0;
|
|
87
|
+
|
|
88
|
+
@include govuk-media-query($from: tablet) {
|
|
89
|
+
flex-direction: row;
|
|
90
|
+
align-items: center;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
&__item {
|
|
94
|
+
@include govuk-font(19);
|
|
95
|
+
margin-bottom: govuk-spacing(1);
|
|
96
|
+
text-align: right;
|
|
97
|
+
|
|
98
|
+
@include govuk-media-query($from: tablet) {
|
|
99
|
+
@include govuk-responsive-margin(4, 'right');
|
|
100
|
+
@include govuk-responsive-padding(4, 'right');
|
|
101
|
+
margin-bottom: 0;
|
|
102
|
+
border-right: 1px solid govuk-colour('white');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
a {
|
|
106
|
+
display: inline-block;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
&:last-child {
|
|
110
|
+
margin-right: 0;
|
|
111
|
+
border-right: 0;
|
|
112
|
+
padding-right: 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@media print {
|
|
119
|
+
display: none;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{% from "govuk/components/footer/macro.njk" import govukFooter -%}
|
|
2
|
+
{{
|
|
3
|
+
govukFooter({
|
|
4
|
+
meta: {
|
|
5
|
+
items: [
|
|
6
|
+
{
|
|
7
|
+
href: supportUrl,
|
|
8
|
+
text: "Feedback and support"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
href: authUrl + '/terms',
|
|
12
|
+
text: "Terms and conditions"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
classes: "govuk-!-display-none-print"
|
|
17
|
+
})
|
|
18
|
+
}}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{% from "govuk/components/tag/macro.njk" import govukTag %}
|
|
2
|
+
<header class="fallback-dps-header" role="banner">
|
|
3
|
+
<div class="fallback-dps-header__container">
|
|
4
|
+
<div class="fallback-dps-header__title">
|
|
5
|
+
<a class="fallback-dps-header__link fallback-dps-header__title__organisation-name" href="{{ authUrl }}">
|
|
6
|
+
<svg role="presentation" focusable="false" class="fallback-dps-header__logo" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 40 40" height="40" width="40">
|
|
7
|
+
<path fill-rule="evenodd" d="M38.1 16.9c.1 1.8 2.2 1.3 1.9 2.7 0-.9-3-.8-3-2.6 0-.3.1-.7.3-.9-.1-.1-.2-.1-.5-.1-.6 0-1.2.6-1.2 1.3 0 2.2 3 2.6 3 5.1 0 .6-.2 1-.6 1.2.2 0 .7-.1.8-.3-.2 1-1.2 1-1.6.6h-.3c.2.4.4.8.9.7-.9.7-2-.2-1.8-1.2-.2-.3-.4-.7-.6-.9-.1-.2-.2-.1-.2.1 0 .8-.6 1.6-.6 2.1 0 .6.6 1.1.8 1.1s.3-.2.4-.2c.1.1.1.2.1.7 0 .2 0 1 .1 1.7 0-.2.2-.3.3-.4.2-.1.4-.2.7-.1.1 0 .3.1.3.2.1.1.1.2.1.3 0 .2-.2.4-.3.6-.2.1-.3.2-.6.1-.2 0-.3-.1-.4-.2v-.1.7c0 .6-.1.8-.3.9 0-.1-.2-.2-.3-.2-.1 0-.3.1-.3.2 0 .2.3.2.3.6s-.8.8-1.3.8c.1-.2.2-.8.3-1.1-.1.1-.3.3-.4.7-.1.4-.3.4-.6.3.2-.2.6-1.1 1-1.3.4-.3.6-.4.7-1.1.1-.7 0-1.1 0-1.7 0-.8-.3-.7-.6-.7-.6 0-2.6-1.3-2.6-2.7v-.4c-.9 0-1.5.2-1.5 1.1 0 .3 0 .6.2.8.2.1.3.3 0 .4-.3.1-3.1 1.3-3.1 1.3-.3.1-.4 0-.6-.2-.1-.2-.3-.2-.4-.1-.2.1.1.2.1.4s-.1.7-1.3.6l.3-.6c.1-.2.1-.3.1-.3-.1 0-.1.1-.2.3l-.3.4h-.4l1-1c.2-.2.6-.4 1.1-.4.7-.1 2.9-.4 2.9-1.1 0-.8-.9-.8-.9-1.9 0-1 .4-2 3-1.9-.2-.7-.9-1.1-1.6-1.2-1.3-.3-1.7-1.2-1.8-2.1h-1c-.8 0-1.2-.3-1.5-.1-.1.1-.1.2 0 .3.1.2.3.7.6 1 .1 0 .4 0 .4.2s-.1.2-.1.3 0 .2.1.2.1-.1.1-.2c.1-.1.3-.1.7 0 .2.2.6.6.7 1-.3-.1-.8-.3-.9-.3s-.1.1 0 .1.4.2.6.3v.3c-.1-.1-.7-.4-1.1-.6-.3-.1-.6-.2-.8-.7-.2-.4-.8-1.6-1-1.9-.1-.2-.1-.3 0-.4.1-.1.1-.2.2-.3.1-.2.2-.2.4-.2s.8 0 1-.1c0 0 .1 0 .2-.1-.6-.6-1.2-1.4-1.2-1.6-.1-.1-.2-.2-.3-.2s-.2 0-.3.1l-.1.1c0-.1-.1-.1-.1-.2l-.3-.3c.2-.1.3-.3.4-.3.1-.1.2-.2.3-.2h.3c.2 0 .2 0 .3.1.2.2.6.4.8.7 0 0 .1 0 .1.1l.1-.1c.1-.1.2-.1.3-.1s.2.1.3.2.2.3.2.6v.2l.6.6c.1-.7.4-1.4.9-2h-.1v-.1c.1-.3.2-.9.3-1.1v-.3l.8.3.1-.1c.7-.7 2.3-1.1 2.3-2.1 0-.2-.1-.6-.3-.8.1.1.1.3.1.6 0 .2-.4.8-1.1.8-.3 0-.7-.3-.8-.3s-.2.1-.3.1c0 .4-.2.8-.3.8.1-.2 0-.6 0-.6-.1 0-.1.1-.1.4 0 .3-.2.7-.7.7.1-.1.2-.6.1-.7-.1-.1-.2.1-.3.1s-.2-.1-.2-.2-.2 0-.2-.1.2-.3.4-.3c.2-.1.6-.2.6-.4-.1-.2-.9.1-1.1.3-.4.3-.2-.1-.3-.2-.2-.4 0-.4.2-.7.2-.2.8-.7 1.5-1 0-.2.1-.3.3-.4.2-.1.6-.2.8-.3l-3.8-4c-.1-.1-.1-.1 0-.2 0 0 .1 0 .2.1l4 3.9c.3-.6.4-.9.3-1.3.4.2.9.7 1 1.2 1.2 0 1.6.8 1.9.4 0 .2-.1.3-.6.4 1.5.3 1 1.3 1.8 1.4-.1.1-.3.2-.6.1.9 1.3 0 2.1.7 2.8-.2.1-.7-.1-.9-.6.2 1.1-.1 1.7.1 2.1-.3.1-.6-.2-.7-.6-.1.2-.1.4-.2.7l.3.1-.1.1c-.6.6-.8.9-.9 1l-.1.1-.1-.1c-.3.4-.7.8-.7 1.2 0 .4.6 1.3 1.2 2.1v-.2c0-.1.1-.3.2-.4.1-.1.2-.1.4-.1s.4.1.6.3c.1.2.2.3.2.6 0 .1-.1.3-.2.4-.1.1-.2.1-.4.1-.1 0-.3-.1-.4-.1.4.6.9 1.2 1.1 1.7.4.9.9 1.4 1.3 1.4.6 0 1.1-.4 1.1-1.1 0-2.3-3-2.6-3-5.2 0-1.2 1-1.8 1.7-1.8.4 0 .7.1.9.3h.2c1.5 0 .6 1.9 1.7 2-.3.5-1 .2-1.3-.7zM30.3 10c.3-.2.8-.3 1.2-.3-.3-.1-.6-.3-.8-.3-.4-.1-.3.4-.4.6zm-2.7 5.5c0-.1 0-.3-.1-.3 0 0-.1-.1-.2-.1s-.1 0-.2.1-.1.2-.1.3c0 .2.1.4.3.4.1 0 .1 0 .2-.1 0 0 .1-.1.1-.3zm8.7 12.6v.2c.1.2.4.2.7 0 .1-.1.2-.2.2-.3v-.2c-.1-.1-.1-.1-.2-.1s-.3 0-.4.1c-.2.1-.3.2-.3.3zm-1.9-8.3c0 .1.1.3.2.4.1.1.2.2.4.2.1 0 .1 0 .2-.1s.1-.1.1-.2-.1-.3-.2-.4c-.1-.1-.2-.2-.4-.2-.1 0-.1 0-.2.1s-.1.1-.1.2zm-.8-3.2c.3-.3.9-1 .9-1l-.3-.3v.6c-.1-.1-.2-.2-.2-.3l-.2.3c.1 0 .3 0 .3.1-.2.2-.6.1-.7 0-.2-.2-.3-.3-.3-.4.1-.1.3-.1.4.1.2 0 .2-.2.2-.3-.1-.1-.2-.1-.3-.1.3-.2.6-.4.4-.9-.4.1-.6.3-.7.7 0-.1-.1-.3-.2-.3s-.3.1-.3.3c.2-.1.4.1.3.3-.1.1-.3.1-.6 0-.3-.4-.3-.6-.1-.9.1.1.1.2.1.4l.3-.6c-.1 0-.2.1-.3 0 .1-.1.2-.2.4-.3l-.7-.2c.1.2 0 .4 0 .6-.1-.1-.2-.2-.2-.3l-.3.6c.1-.1.3-.1.4-.1-.1.2-.4.3-.7.2-.2-.1-.3-.3-.3-.4.1-.1.3-.1.4.1.2-.1.2-.3.1-.4-.1-.1-.2-.1-.4 0 .3-.3.4-.6.3-1-.3.1-.6.4-.6.8 0-.1-.1-.2-.2-.2s-.3.1-.2.3c.2-.1.4.1.3.3-.1.1-.2.1-.6 0-.2-.1-.4-.2-.3-.6.1 0 .2.2.3.2l.1-.4h-.3c.1-.1.3-.2.4-.3l-.4-.2s-.2.9-.4 1.3l4.2 2.3zm0 7.9c.1-.2.1-.6 0-.7-.2-.1-.4 0-.7.2-.1.2-.1.6 0 .7.1.1.5 0 .7-.2zm1.1-1.9c.1-.2.1-.6 0-.7-.2-.1-.4 0-.7.2-.1.2-.1.6 0 .7.3.1.6 0 .7-.2zM27.4 18c.2-.1.4 0 .7 0 .2.1.3.3.4.4v.4l-.3.3c-.2.1-.4 0-.7 0-.5-.1-.6-.4-.5-.8.1-.2.2-.3.4-.3zm.2 1c.1.1.3.1.4 0 .1 0 .1-.1.2-.1v-.2c0-.1-.1-.2-.3-.3-.1-.1-.3-.1-.4 0-.1 0-.1.1-.2.1-.1.1.1.3.3.5zm4.8 7.2c.1-.1.2-.2.4-.2s.3.1.4.2c.1.1.2.3.2.6 0 .2-.1.4-.2.6-.1.1-.2.2-.4.2-.1 0-.3-.1-.4-.2-.1-.1-.2-.3-.2-.6 0-.2 0-.5.2-.6zm.3 1.1c.1 0 .2 0 .2-.1.1-.1.1-.2.2-.4 0-.3-.1-.6-.3-.6-.1 0-.2 0-.2.1-.1.1-.1.2-.2.4 0 .2 0 .3.1.4.1.1.1.2.2.2zm-4.8-13.8c.2-.1.3-.2.6-.2.1 0 .2.1.3.2s.1.2.1.4-.1.3-.3.6c-.3.2-.8.2-.9 0-.1-.3 0-.6.2-1zm0 .7v.2c.1.1.3.1.6 0 .1-.1.2-.2.2-.3v-.2c0-.1-.1-.1-.2-.1s-.2 0-.3.1c-.2 0-.3.2-.3.3zm5.7 13.7c.2-.1.4-.2.7-.1.4.1.8.4.7.8 0 .2-.1.3-.3.4-.1.1-.3.1-.6.1s-.3-.1-.6-.2c-.1-.1-.2-.3-.1-.6-.1-.2 0-.3.2-.4zm.4.9c.3 0 .6-.1.6-.3 0-.2-.2-.3-.4-.4-.2 0-.3 0-.4.1 0 0-.1.1-.1.2-.2.1 0 .3.3.4zm3.3-1.9c0-.6.4-1 1-1s1 .4 1 1-.4 1-1 1c-.5 0-1-.4-1-1zm.3 0c0 .4.3.8.8.8s.8-.3.8-.8c0-.4-.3-.8-.8-.8-.4.1-.8.5-.8.8zm-23.3-5.8c-.1.3.1.3.1.7 0 .3-.2.4-.6.6.2-.4 0-.7-.3-.8.1.8-.6.9-.8.8.2 0 .3-.4.2-.8-.1.2-.4.4-.7.4s-.4-.2-.6-.4c.3.2.6 0 .6-.2 0-.1-.3-.2-.3-.4 0-.6.6-.3.6-.8 0-.2-.1-.3-.2-.3s-.3.1-.3.3c-.3-.2 0-.9-.1-1.2 0 .7-.4.6-.6.9-.2-.2 0-.7-.2-1.2-.1.6-.3.4-.3.9-.6-.3-1.7-.2-2 .2 1 .8 2.2 1.2 2.2 2.4 0 .9-1.5 1.3-1.5 1.9 0 .6 1.5 2 2.2 2 .2 0 .3-.3.6-.3h.6c.2 0 .3.2.3.3.3 0 .8.6.3 1-.1-.2-.3-.6-.8-.3.2.4 0 .8-.4 1 .1-.2.2-.6-.1-.6s0 .2-.7.2c-.6 0-.6 0-.8-.3-.2-.3-.4-.4-.6-.4s-.2.3 0 .6c-1.2 0-.7-1.2-1.3-1.6v.9c-.4-.5-.8-.9-.8-1.3-.1-.3 0-.6-.3-.8-.1 0-.2-.1-.2-.3 0-.1.1-.1.3-.2.2-.1.6-.3.6-1 0-.4-.1-1.1-.9-1.7.1 1 0 1.9-.4 2.7-.6 1-1.7 1.7-2.2 1.9-.6.2-1.3.4-1.3 1.2 0 1.4.7 2.2 1.2 2.2.4 0 .3-.4.9-.4.2 0 .6.1.6.3.3-.1.7.1.7.4 0 .3-.1.4-.3.6.2-.4-.3-.4-.4-.4-.1.1 0 .2 0 .4s-.1.4-.4.6c.1-.1.1-.3-.2-.3-.2 0-.3.4-.7.4-.6 0-.7-.2-1.2-.1-.3.1-.3.3-.2.3-.7 0-.6-.8-.4-.9.1-.1.2-.2 0-.4-.2-.1-.6 0-.7.3-.6-1.1.2-1 0-2.2-.1.6-.4.9-.7 1 .1-.2-.1-.8-.1-1.2 0-.9.6-1.2.6-1.4 0-.2-.2-.4 0-.6.1-.1.3.1.6.1.7 0 1.2-.9 1.3-2 .1-1.2.7-2.1 1.1-3 0-.1 0-.3.1-.4-.6.7-1 1.6-1.7 2.1.1.8-1.5 1.7-2.3 1 .3 0 .8-.1 1-.6-.1 0-.2 0-.3-.1-.6.3-1.3-.1-1.3-.7.2.2.4.3.8.2.2-.1.1-.4.1-.8 0-2.3 3.6-3.9 3.6-5.8 0-.6-.3-.9-.8-.9-.2 0-.4.1-.7.2.2.1.3.3.3.6 0 2.1-3.5 1.9-3.7 3.3-.1-1.8 2-1.4 2.1-2.9-.4.7-1.2 1.1-1.7.9 1.1 0 .8-2.2 2-2.2.1 0 .2 0 .4.1.3-.3.8-.4 1.1-.4.6 0 1.3.3 1.3 1.3 0 2.2-3.6 3.7-3.6 5.8 0 .7.4 1 1 1 1.2 0 2.1-2.2 3.5-4.1.9-1.2 1.5-3.7 2-4.9-.7.4-.8 1.8-1.6 1.9.4-.3.1-1.4.4-2.3.1-.3.1-.6.1-.9-.4.6-.3 2.2-1.1 2.4.3-.3 0-.9 0-1.4 0-1 .6-1.1.6-2.1-.4.2-.3 1.4-1.2 1.4.7-.7 0-1.3.8-2.1-.4-.2-.8-.6-.8-.9.3-.2.7-.3 1-.3-.3-.2-.2-.4 0-.7.1.2.2.3.3.3.3-.1.8-.6 1.5-.8.5-.2 1.3-.5 1.6-.5.1 0 .1-.2.1-.3.2 0 .6 0 .7.3.2-.2.6-.3.9-.3.2.4.2.8 0 1.2.4 0 .7.4 1.1.3-.3.4-.8.3-1.2.2 1.2.3 1.5 1.6 2.1 1.7-1.2.7-1.7-.3-2.3-.3 1.7.9 1.7 1.9 2.1 1.9-.6.4-.9-.1-1.6-.3 1.3.9 1.3 1.6 1.2 2.1.3.2.2.6.2 1 .2-.1.6-.2.8-.2-.1.1-.2.2-.2.3-.7.8-1.1 1.4-1.5 2.4-.3-.2-.6-.6-.8-.7-.2-.2-.6-.2-.7-.2.4.4 1.8 2 2.2 2.4.4.4.3.8.4 1.2.4.4.8.7.7.9zM7.5 10.2c.4 0 .6-.6.4-.9-.4.2-1 .3-1.3.4.5.2.5.5.9.5zm2.3 2.5c.4-.2.4-.7.3-.9-.1-.2-.2-.4-.3-.4-.2 0-.4-.1-.4-.3-.1-.2.2-.3.4-.6-.2-.1-.4-.2-.2-.3.2-.1.4.1.4 0 .1-.1-.1-.2-.2-.3s-.2-.1-.3 0l-1.2.4c-.1 0-.3 0-.3.1s-.1.3 0 .3.1-.3.3-.3.2.1 0 .4c.4 0 .6-.1.7.2.1.2 0 .3-.1.6-.1.1 0 .3 0 .6.1.2.5.7.9.5zm.1-3.5c.2-.2 0-.4.3-.9-.3.2-.8.5-1.3.7.3.3.7.5 1 .2zm-.7-3.1c.1.1.1.2.1.3-.1 0-.1-.1-.3-.2v.6c.1-.1.2-.1.2-.2 0 .3-.1.6-.3.6l-.3-.3c0-.1.1-.2.2-.1 0-.3-.2-.3-.3-.2.1-.4.1-.6-.2-.7-.3.3-.1.4.1.6-.2-.1-.5.1-.2.4 0-.2.2-.1.2 0s-.1.3-.4.4c-.3.1-.4-.1-.5-.3.1 0 .2 0 .4.1l.1-.5c-.1.3-.2.3-.3.4 0-.1.1-.4.1-.4l-.7.2s.3.1.4.2c0 0-.1.1-.4 0l.2.4c0-.2.1-.3.2-.3.1.2.1.4-.2.6-.2.2-.4.1-.4 0-.1-.1 0-.3.2-.2 0-.3-.3-.3-.3-.1 0-.3-.1-.6-.4-.6-.1.3 0 .6.3.7-.2 0-.3.1-.1.3 0-.2.1-.2.2-.1s0 .2-.1.3c-.1.1-.3.1-.6-.2h.2L6 7.3v.3c-.1-.1-.1-.1-.1-.3l-.2.2c.2.2.6.5.9.9.3-.2 1-.6 1.5-.7.4-.2 1.1-.4 1.6-.4-.1-.6 0-1 0-1.2h-.5zm-2.7-.7l.2.4.1-.3v.6c0 .1.1.3.3.3.1 0 .3-.1.3-.3 0-.1-.1-.2-.1-.2 0-.1-.2-.3-.3-.4h.4v-.4l-.4.2v-.4l-.4.1.2.3-.3.1zm1.4.4c.1-.2.1-.3 0-.4-.1-.1-.2-.1-.3 0-.1.1-.1.2 0 .3.1.1.2.1.3.1zm.6-.5c.1-.1.1-.2 0-.3s-.2-.1-.3 0-.2.2 0 .3c.1.1.2.1.3 0zm.5.1c.1-.1.1-.2 0-.3s-.2-.1-.3 0c-.1.1-.1.2 0 .3.1.1.3.1.3 0zm.2.5c.1.1.2.1.3 0s.1-.2 0-.3h-.3c-.2 0-.2.3 0 .3zm-2.7.4c.1 0 .2-.1.2-.2s-.1-.2-.2-.2-.2.1-.2.2.1.2.2.2zm-.7.1c.1 0 .2-.1.2-.2S6 6 5.8 6c-.1 0-.2.1-.2.2s.1.2.2.2zm-.1.2c0-.1-.1-.2-.2-.2s-.2.1-.2.2.1.2.2.2.2 0 .2-.2zm.1.7c0-.1-.1-.2-.2-.2s-.2.1-.2.2.1.2.2.2.2-.1.2-.2zm15.7 16.9c-.1 0-.1.1-.1.1 0 .1 1-.1 1 .1 0 .1-.2.2-.6.2h-.1c0 .1.1.1.1.1v.1s0 .1 0 0h-.1s-.1 0 0 .1h-.1v-.1h-.1v-.1h.1l.1.1.1-.1-.1-.1h-.3c.1.1.1.2.1.3v.1h-.1s0 .1-.1.1H21c0-.1.1 0 .1-.1 0 0 0-.1.1-.1s.1.1.2.1h.1-.1v-.1c-.1 0-.1.1-.2.1 0 .1-.1.2-.1.2l-.1.1c-.1 0-.1 0-.1.1v-.1h-.1l-.1.1v-.1s0 .1-.1.1c0 0-.1 0-.1-.1v.2s-.1 0-.1-.1v-.1c-.1.1-.1 0-.1 0s0-.1.1-.1h.1c-.1 0-.1 0-.1-.1h.1v.1h.4v-.1c-.1 0-.1 0-.1-.1-.4-.2-.4-.3-.4-.3-.1 0-.2 0-.1-.1 0 .1.1.1.1 0 0 0-.1 0 0-.1v-.1h.1-.1.1l.1.1h.1v.1c0 .1 0 .1.1.1s.1.2.2.2v-.2s0-.1.1-.1l.1-.1v-.1h.2s.1 0 .1.1h.1s0 .1-.1.1c0 0 0 .1-.1.2.4-.1.8 0 .9 0 .2 0 .4-.1.4-.1 0-.1-1 .1-1-.1-.4-.4-.3-.4-.2-.4 0 0 0-.1 0 0 .2-.2.6 0 .7-.1 0 0-.2.1-.3.1.3.1.4-.1.8 0-.3-.1-.7.3-1.2 0 0 .1 0 0 0 0zm-.7 0c0 .1 0 .1 0 0 .1.1.1.1 0 0 .1.1.1.1 0 0zm0 0s-.1 0 0 0c-.1 0-.1 0 0 0-.1.1 0 0 0 0zm-.1.3s0 .1 0 0c0 .1.1.1 0 0 .1 0 .1 0 0 0 .1 0 .1 0 0 0 .1-.1.1-.1.1 0h-.1c0-.2 0-.2 0 0 0-.2.1-.2 0 0zm1.1-1.6c-.1 0-.3 0-.3.1s.7.1.9.1c.3 0 .3.1.3.1 0 .1-.3.1-.6.1h.3c.1 0 0 0 0 0h.1v.2h-.1c0 .1-.1 0-.1.1v.1h-.1v-.1s0 .1-.1.1 0-.1.1-.1H22s0-.1.1-.1h.1v-.1h-.5v.1s.1.1 0 .1h-.1s0 .1-.1.1h-.3c0-.1.1 0 .1-.1h-.1s0-.1.1-.1.1.1.2.1h.1-.1c-.1 0 0-.1 0-.2h-.1c-.4-.1-.2.1-.4.1 0 0 0 .1-.1.1 0 .1-.1.2-.2.1-.1 0-.2 0-.2.1v-.1h-.1c0 .1-.1.1-.1.1v-.2s0 .1-.1.1c0 0-.1 0-.1-.1v.2s-.1 0-.1-.1v-.1c-.1.1-.1 0-.1 0s0-.1.1-.1h.1c-.1 0-.1-.1-.1-.1h.1v.1c0 .1.2 0 .2 0h.2v-.1h-.1c-.1-.1-.1 0-.1 0-.1 0-.2 0-.1-.1 0 .1.1.1.1 0-.1 0-.1 0 0-.1v-.1s0-.1.1 0h-.1.1l.1.1h.1v.1c0 .1 0 .1.1.1h.1v-.1s0-.1.1-.1l.1-.1V23h.2s.1 0 .1.1h.1s0 .1-.1.1c0 0 0 .1-.1.2.3-.1 1 0 1.2 0 .1 0 .4 0 .4-.1 0 0 0-.1-.2-.1s-1 .2-1-.1c-.2-.3.1-.3.2-.2.1-.1.1-.1 0 0 .2-.2.6 0 .7-.1 0 0-.2.1-.3.1.3.1.4-.1.8 0-.3-.1-.8.1-1.2 0 .1 0 .1 0 0 0zm-.9 0s-.1-.1 0 0c-.1 0-.1 0 0 0zm.1.1s-.1 0 0 0l-.1-.1c-.1.1 0 .1.1.1h-.1v.1l.1-.1c-.1.1-.1.1 0 0-.1.1-.1.1 0 0-.1 0-.1 0 0 0-.1 0-.1 0 0 0-.1 0-.1 0 0 0zm0 0c0-.1 0-.1 0 0 0-.1 0 0 0 0zm2.2-.9s0 .1 0 0c0 .1 0 .1 0 0 0 .1 0 .1 0 0v.1c0 .1-.1 0-.1.1 0 0 .1 0 0 .1H23v-.1s0 .1-.1.1v-.1h-.2s0-.1.1-.1h.1v-.1h-.2c-.1 0-.1.1-.2.1h-.2v.1s.1.1 0 .1h-.1s0 .1-.1.1h-.3c0-.1.1 0 .1-.1h-.1s0-.1.1-.1.1.1.2.1h.1-.2c-.1 0-.1-.1 0-.2 0 0 0 .1-.1.1-.6-.1-.3.2-.8.1 0 0 0 .1-.1.1h-.1l-.1.1c-.1 0-.1 0-.2.1v-.1h-.1c0 .1-.1.1-.1.1v-.2s0 .1-.1.1c0 0-.1 0-.1-.1v.2s-.1 0-.1-.1v-.1c-.1.1-.1 0-.1 0s0-.1.1-.1h.1c-.1 0-.1-.1-.1-.1h.1v.1c0 .1.2 0 .2 0h.2s-.1-.1 0-.1v-.1h-.1l-.2-.2v-.1c-.1 0-.2 0-.1-.1 0 .1.1.1.1 0-.1 0-.1-.1 0-.1v-.1s0-.1.1 0c0 0-.1 0-.1-.1h.1s0 .1.1.1h.1v.1c0 .1 0 .1.1.1s.1.1.2.1v-.1s0-.1.1-.1l.1-.1v-.1h.3s.1 0 .1.1h.1s0 .1-.1.1c0 0 0 .1-.1.2.4-.1 1.5 0 1.7 0 .1 0 .4 0 .4-.1 0 0 0-.1-.3-.1-.2 0-1.3.2-1.3-.1 0-.2.3-.1.7-.1.1-.1.6 0 .7 0 0 0-.2.1-.3.1.3.1.4-.1.8 0-.2-.1-.7.2-1.1.1h-.1c-.2 0-.6 0-.6.1 0 .2.9.1 1.2.1.3 0 .4.1.4.1 0 .1-.3.1-.4.1h.3c-.4-.1-.4-.1-.3 0-.1 0 0-.1 0 0zm-2.2-.5s0 .1 0 0c.1.1.1.1.1 0H21zm-.1 0s0-.2 0 0c0 0-.1 0 0 0zm-.1.2c.1.1.1 0 0 0 .1 0 .1 0 0 0 .1 0 .1-.1 0 0l.1-.1h-.1c.1 0 .1 0 0 .1.1-.1.1-.1 0 0 .1-.1 0 0 0 0zm-1.9-2c0 .1-.3.1-.4.1h.5v.2c0 .1-.1 0-.1.1 0 0 .1 0 0 .1h-.1v-.1.1-.1h-.2s0-.1.1-.1h.1V20h-.2c-.1 0-.1.1-.2.1h-.2v.1s.1.1 0 .1H18s0 .1-.1.1h-.3c0-.1.1 0 .1-.1h-.1s0-.1.1-.1.1.1.2.1h.1-.1c-.1 0-.1-.1 0-.1h-.1c-.6-.1-.3.2-.8.1 0 0 0 .1-.1.1l-.1.1h-.1c-.1 0-.2 0-.2.1v-.2h-.1c0 .1-.1.1-.1.1v-.2s0 .1-.1.1c0 0-.1 0-.1-.1v.2s-.1 0-.1-.1v-.1c-.1.1-.1 0-.1 0s0-.1.1-.1h.1c-.1 0-.1-.1-.1-.1v.1c0 .1.2 0 .2 0h.2v-.1h-.1l-.2-.2v-.1c-.1 0-.2 0-.1-.1 0 .1.1.1.1 0-.1 0-.1-.1 0-.1v-.1s0-.1.1 0c0 0-.1 0-.1-.1h.1s0 .1.1.1h.1v.1c0 .1 0 .1.1.1s.1.1.1.1v-.1s0-.1.1-.1l.1-.1v-.1h.3s.1 0 .1.1h.1s0 .1-.1.1c0 .1 0 .1-.1.2.5-.1 1.5 0 1.8 0-.4.1-.1 0 0 0-.1-.1-.1-.1-.4-.1-.2 0-1.3.2-1.3-.1 0-.2.3-.1.7-.1.1-.1.6 0 .7 0 0 0-.2.1-.3.1.3.1.6-.1.8 0-.3-.1-.7.2-1.1.1h-.1c-.2 0-.6 0-.6.1 0 .2.9.1 1.2.1.3-.3.4-.2.4-.1zm-2.3-.2c.1.1.1.1.1 0h-.1zm-.1-.2s-.1 0 0 0c-.1 0-.1 0 0 0 0 .2 0 0 0 0zm-.1.3c0 .1 0 .1 0 0 0 .1.1.1 0 0 .1.1.1 0 0 0 .1 0 .1 0 0 0l.1-.1h-.1c.1 0 .1 0 0 .1.1 0 .1 0 0 0 .1 0 0 0 0 0zm2.6-1.4c0 .1-.3.2-.6.2h.6v.2h-.1c0 .1-.1 0-.1.1 0 0 .1 0 0 .1h-.1v-.1.2-.1h-.2s0-.1.1-.1h.1v-.1h-.2c-.1 0-.1.1-.2.1h-.2v.1c.1 0 .1.1 0 .1H18s0 .1-.1.1h-.1.1-.2c0-.1.1 0 .1-.1h-.1s0-.1.1-.1.1.2.2.1h.1-.1c-.1 0-.1-.1 0-.2h-.1c-.4-.1-.2.2-.6.2h-.1c0 .1-.2.2-.2.2-.1.1-.1 0-.2.1v-.2h-.1c0 .1-.1.1-.1.1V19s0 .1-.1.1c0 0-.1 0-.1-.1v.2s-.1 0-.1-.1V19c-.2 0-.2-.1-.2-.1s0-.1.1-.1h.1c-.1 0-.1-.1-.1-.1H16v.1c0 .1.2 0 .2 0h.2v-.1h-.1c-.1 0-.1-.1-.1-.1v-.1c-.1 0-.2 0-.1-.1 0 .1.1.1.1 0-.1 0-.1-.1 0-.1v-.1s0-.1.1 0c0 0-.1 0-.1-.1h.1s0 .1.1.1V18s.1 0 .1.1v.1c0 .1 0 .1.1.1s.1.1.1.1h.1v-.1s0-.1.1-.1l.1-.1V18h.3s.1 0 .1.1v.1h.1s0 .1-.1.1c0 0 0 .1-.1.2.4-.1 1.1 0 1.3 0 0-.1.3-.1.4-.2-.1-.1-.1-.1-.4-.1-.2 0-1.1.2-1.1-.1 0-.1.2-.1.4-.1.2-.1.4 0 .6-.1 0 0-.1.1-.2.1.3.1.6-.1.9.1-.2-.1-.8.1-1.1 0H18c-.2 0-.3 0-.3.1 0 .2.7.1 1 .1.2-.1.3-.1.3 0zm-2.5.3c-.1 0-.1 0 0 0zm.5-.5c.1.1.1.1.1 0H17zm-.1-.1s-.2 0 0 0c0 .1 0 .1 0 0zm-.2.3c.2.1.2 0 0 0 .2 0 .2 0 0 0 .2-.1.2-.1 0 0l.1-.1h-.1c.2 0 .2 0 0 .1.2-.1.2-.1 0 0 .2-.1 0-.1 0 0zm1.8-1.2c.1 0 .2.1.3.1h.2v.2c0 .1-.1 0-.1.1 0 0 .1 0 0 .1h-.1v-.2h-.2s0-.1.1-.1h.1v-.1h-.4v.2h-.1v.1h-.4c0-.1.1 0 .1-.1h-.1s0-.1.1-.1.1.1.2.1h.1-.1v-.2h-.1c-.3 0-.1.1-.2.1 0 0-.1.1-.2.1v-.1h-.1l-.1.1c-.1 0-.1 0-.1.1v-.1h-.1l-.1.1v-.1s0 .1-.1.1c0 0-.1 0-.1-.1v.2s-.1 0-.1-.1v-.1c-.1.1-.1 0-.1 0s0-.1.1-.1h.1c-.1 0-.1 0-.1-.1h.1v.1h.3s.1 0 .2-.1l-.1-.1c-.1 0-.2 0-.1-.1 0 .1.1.1.1 0-.1 0-.1 0 0-.1v-.1h.1-.1.1v.1h.1v.2l.1.1V17s0-.1.1-.1l.1-.1v-.1h.4s0 .1-.1.1c0 0-.1.1-.1.2.1-.1.2 0 .4.1.3-.1.5-.1.5-.2 0-.2-.9 0-.9-.3 0 0 0-.1.1-.1v-.1c.1-.1.2-.1.3-.2 0 0 0 .1-.1.2.2 0 .2-.3.7-.2-.3.1-.3.3-.8.4l-.1.1c0 .2.9 0 .9.3-.1 0-.2.1-.6.1zm-.7-.4c0 .1 0 .1 0 0 .1.1.1.1 0 0 .1.1 0 0 0 0zm0 0c-.2 0-.2 0 0 0-.2 0-.2 0 0 0-.2 0-.2 0 0 0zm-.2.2c-.1 0-.1 0 0 0 0 .1 0 0 0 0 .1-.1.1-.1.1 0h-.1c0-.1 0-.1 0 0 0-.1 0-.1 0 0zm1.3 5.1c.1 0 .1 0 .1.1s-.1.1-.2.1l-.1 2.4h.1v.2c0 .1-.1.1-.2.1 0 .3-.2.4-.4.4-.1 0-.3-.1-.3-.3 0-.1.1-.2.2-.2s.1 0 .1.1-.2 0-.2.1 0 .1.1.1.2-.1.2-.2c0-.2-.2-.2-.4-.2-1.3-.4-2.1-1.8-2.1-2.8h-.1l.1-.2-.1.1c-.1 0-.2-.1-.2-.2s.1-.2.2-.2.2.1.2.2l.1-.2c.2.1.6.2.9.2.7 0 1.2-.3 1.5-.3.2.1.4.4.5.7zm-2.6.2c-.1 1.2.8 2.1 1.7 2.4l-1.7-2.4zm1.8 2.3c0-.1 0-.3.1-.4l-1.3-1.8h-.3l1.5 2.2zm.1-.8c0-.1 0-.3.1-.4l-.8-1.1c-.1 0-.2.1-.3.1l1 1.4zm.2-1.7c0-.2 0-.3-.1-.3s-.4.1-.7.2l.7 1c0-.2.1-.4.1-.7v-.1c-.1 0-.1-.1-.1-.1h.1zm4.3-2.6c.1 0 .1-.1.1-.1h-.1s.1 0 0-.1c0-.1-.1-.1-.1 0s-.4 0-.4-.3l.1.1h.1c.1 0 .1-.1.1-.1 0-.1-.1-.2-.3-.3-.1 0-.1-.1-.1-.1 0-.1 0-.2-.1-.4v-.2c-.1.1-.1.3.1.6.1.1.4.3.4.4 0 0 0 .1-.1.1h-.1s-.1 0-.1-.1c-.1-.1-.2-.3-.3-.4-.1-.2-.1-.3-.1-.6.1-.1-.1-.4-.1-.6v-.1h-.1s0-.1-.1-.1-.1 0-.1-.1c0 0 0 .1-.1.1h-.4c-.1 0-.1 0 0 .1v.2-.1h.1v.1h-.1v.1h.3c0 .1-.2.1-.2.3l-.1-.1-.1-.1-.1-.1c-.1 0-.1-.1-.1-.1v-.1l-.1-.1v.2s0-.1-.1-.1c0 0 0-.1-.1 0 0 0 0 .1.1.1h-.1v.2h-.1c-.1.1 0 .2.1.1v.3c0 .1.1.2.3.3l-.2.2s-.1.1-.2.1l-.1-.1h-.2.2-.1s-.1.1 0 .1v-.1s.1.1.1 0v.1s.1.1.1 0l-.1-.1v-.1s0 .1.1 0v-.1h.2s0-.1.1-.1h.1s0-.1.1-.1c0 .3.3.2.4.4-.1 0-.2-.1-.3-.1s-.2.1-.2.2.1.2.1.3h-.2c-.1 0-.1-.1-.2-.1 0 0-.1 0-.1.1h.1s-.1 0-.1.1c0 0 0 .1.1 0 0 0 0 .1.1 0h.1s0-.1.1 0h.2v-.1c0-.1-.1-.1-.1-.1 0-.1.1-.2.2-.2 0 .1.1.3.3.4.1 0 .2-.1.2-.1v.1h-.1s-.1 0-.1.1h.1s.1.1.1 0c0 0-.1.1 0 .1s0-.1.1-.1v.1h.1v-.1s.1 0 .1-.1c1 .6 1 .6 1 .4 0 .2 0 .2 0 0 0 .2 0 0 0 0zm.7.6c.1 0 .2.1.2.2l-.1.1s.1.1.1.2c-.1 0-.1 0-.2-.1 0 .1 0 .1-.1.1s-.2 0-.2-.1c0 .1.2 0 .1 0h-1.5c0 .1 0 .2-.1.3-.1-.1-.1-.2-.1-.3h-1.3c0 .1.1.1.1 0 0 .1-.1.2-.2.2H20s-.1.1-.2.1c0-.1 0-.1.1-.2-.1 0-.1 0-.1-.1s0-.2.2-.2c-.1 0 0 .2 0 .1v-1.9c-.1 0-.2 0-.3-.1.1-.1.2-.1.3-.1v-1.8c-.1 0-.1.1 0 .1-.1 0-.2-.1-.1-.2l.1-.1s-.1-.1-.1-.2c.1 0 .1 0 .2.1 0-.1 0-.1.1-.1s.2 0 .2.2c0-.1-.1-.1-.1 0 .3.1.8.2 1.1.4.3.2.7.6 1 .9l.1.1c0-.1.1-.1.3-.1-.2.3-.3.3-.3.3.4.7.8 1.4.9 2.3V20zm-1.3-2.3c-.2-.3-.6-.6-.9-.8-.2-.2-.6-.3-.9-.4v.2c-.1 0-.1 0-.1-.1v1.2c.1 0 .1 0 .1.1v.1c.1 0 .1 0 .2.1-.1.1-.1.1-.2.1.1 0 .1.1 0 .1l-.1.1V20s.1-.1.2-.1c0 .1 0 .1-.1.2h1c0-.1 0-.1.1-.1h.1c0-.1 0-.1.1-.2.1.1.1.1.1.2 0-.1.1-.1.1 0l.1.1H23s-.1-.1-.1-.2h.1c-.1-.7-.3-1.2-.7-1.8h-.1s-.1-.1 0-.1c0 0-.1.1-.2 0 0-.1 0-.1.1-.2v-.1zm4.2 2.7v.4c0 1-.2 2.1-.6 3-.3.9-.9 1.8-1.5 2.4-.3.3-.7.7-1 .9-.1.1-.4.2-2-.2-.2 0-.3-.1-.6-.1 0-.2 0-.3.1-.4.1-.2.1-.3.2-.4.1 0 .1-.1.2-.1.6-.2 1-.7 1.5-1.2.4-.6.8-1.1 1-1.8.2-.7.3-1.3.3-2h-4.5v5c.3 0 1 .1 1 .1-.1.2-.2.4-.2.8-.6-.1-1-.3-1.6-.6.4-.2.6-.2.8-.2v-4.9h-4.7c0-.2-.1-.6-.2-.7-.2-.3-.3-.4-.3-.9 0-.2-.1-.6-.3-.8-.1-.1-.7-.8-.8-.9.3-.9.9-1.8 1.5-2.4.4-.4.9-.9 1.5-1.2-.2-.2-.6-.4-.6-.9 0-.2.1-.4.2-.6-.3-.9-.8-2-1.2-2.6l.9-.4c-.2.3-.2.8-.2 1 .2-.2.4-.4.6-.7 0 .3.2.8.3 1-.2 0-.4-.1-.8 0 .1.2.6.6 1.1.3.3-.1.7-.2.7-.6 0-.1-.1-.3-.3-.3s-.2.3-.1.4c-.2-.1-.6-.9-.1-1 .3-.1.7.3.8.7 0-.2.2-.7.6-.7.4 0 .3.8.1 1 0-.2-.2-.4-.3-.4s-.2.1-.2.3c0 .2.3.4.8.4.3 0 1.1-.1 1.1-.9-.2 0-.7.2-.8.4V9.4c.2.3.6.6.8.6-.1-.3-.3-.7-.7-.9h1.7c-.3.2-.6.6-.7.9.2 0 .6-.2.8-.4v1.2c-.2-.2-.6-.4-.8-.4.1.8.8.9 1.1.9.4 0 .8-.1.8-.4 0-.2-.1-.3-.2-.3s-.2.1-.3.4c0-.2-.2-1.1.2-1.1.3 0 .4.3.6.8.1-.3.4-.8.8-.7.3.1.1.9-.1 1 .1-.1 0-.4-.1-.4-.2 0-.3.1-.3.3 0 .2.3.4.7.6.6.1 1-.2 1.1-.4-.2-.1-.4-.1-.8.1.1-.2.3-.8.3-1 .1.3.2.6.6.7 0-.2 0-.7-.2-1l.9.4c-.4.4-1 1.6-1.2 2.6.2.1.3.3.3.7 0 .4-.2.7-.6.9.6.3 1 .8 1.5 1.2.3.3.6.8.9 1.2 0 0-.1.1-.1.2-.1.1-.2.2-.2.3-.1.1-.1.2-.1.3 0 .1 0 .2.1.4l1 2c-.6 0-.4.2-.2.3zm-7-5c-.6 0-1.2.1-1.8.4-.6.2-1.1.7-1.5 1.2-.4.6-.8 1.1-1 1.8-.2.7-.3 1.3-.3 2.1h4.6v-5.5zm.1-2.2c1.6 0 2.6.4 3.2.9.3-.2.6-.4.6-.7 0-.9-2.5-1-3.7-1-1.2 0-3.7.1-3.7 1 0 .2.1.4.6.7.5-.4 1.5-.9 3-.9zm4.7 7.7c0-.7-.1-1.4-.3-2.1-.2-.7-.6-1.2-1-1.8-.4-.6-.9-.9-1.5-1.2-.6-.2-1.1-.4-1.7-.4v5.5h4.5zm11 11.1c0-.1-.1-.1-.1-.1-1.5.4-3.2-.8-4.9-1.9-1.5-1-2.8-1.9-4-1.9-.4 0-.8.1-1.1.2-.4.2-.7.6-.9 1.1-.2.4-.4.8-.6 1.1-.2.3-.3.6-.3.8 0 .2.1.4.3.7.1.2.4.3.8.6.1 0 .1.1.2.1.3.1.4.2.4.4-.6.2-1.3.4-2.1.6-.9.1-2 .2-3.1.2s-2.1-.1-3.1-.2c-.9-.1-1.6-.3-2.1-.6 0-.2.2-.3.6-.4.1 0 .1-.1.2-.1.3-.1.6-.3.8-.4.2-.2.3-.3.3-.6s-.1-.6-.3-.8c-.1-.2-.3-.6-.6-1.1-.2-.4-.6-.9-.9-1.1-.3-.2-.7-.2-1.1-.2-1.2 0-2.6.9-4 1.9-1.8 1.1-3.6 2.3-4.9 1.9-.1 0-.1 0-.1.1s0 .1.1.1c.4.2.8.4 1.2.8.6.4 1 .8 1.6.8.6 0 1.1-.1 1.8-.6.6-.3 1.2-.7 1.8-1.1 1.1-.8 2.3-1.6 3.5-1.7l-.3.3c-.3.3-.7.6-.7 1.1 0 .4.1.7.3 1.1.1.1.1.2.2.4s.2.4.2.8c0 .1.1.3.1.4.1.2.2.8 1 1.2 1 .4 2.6.8 4.9.8 2.2 0 3.9-.2 4.9-.8.8-.4 1-.9 1-1.2 0-.2.1-.3.1-.4.1-.3.1-.6.2-.8.1-.2.2-.3.2-.6.2-.3.3-.6.3-.9 0-.6-.3-.8-.7-1.1l-.3-.3c1.1.1 2.3.9 3.5 1.7.6.4 1.2.8 1.8 1.1.7.3 1.2.6 1.8.6.6 0 1-.3 1.6-.8.3-.3.8-.6 1.2-.8-.9-.2-.7-.3-.7-.4zm-14.6-1.4c.4 0 .7.3.7.7 0 .3-.2.6-.3.8-.1-.2-.1-.3-.2-.3-.2 0-.1 1.1-.8 1.1v.2c0 .2-.2.4-.4.4s-.5-.3-.5-.5v-.2c-.7 0-.6-1.1-.8-1.1-.1 0-.2.1-.2.3-.1-.2-.3-.4-.3-.8 0-.3.2-.7.7-.7h.2V29c.7.1 1.2.2 1.8.2v1.2c0 .2 0 .2.1.2zm-1.1 2.6c.1 0 .2-.1.2-.2s-.1-.2-.2-.2-.2.1-.2.2.1.2.2.2zm1.5-1.5c.1-.1.1-.3.1-.4 0-.2-.1-.4-.4-.4-.6 0-.4.8-.7.8-.1 0-.2-.1-.2-.2 0-.2.3-.4.3-.8s-.3-.6-.6-.8c-.3.2-.6.6-.6.8 0 .3.3.6.3.8 0 .1-.1.2-.2.2-.2 0-.1-.8-.7-.8-.3 0-.4.3-.4.4 0 .1 0 .2.1.4l.2-.2c.4 0 .2 1.1.8 1.1.2 0 .3-.1.3-.3 0-.1-.1-.2-.1-.3 0-.1.1-.2.2-.2s.2 0 .2.2c0 .1-.1.2-.1.3s.1.3.3.3c.4 0 .3-1.1.8-1.1.3 0 .3.1.4.2zm.3-4.1c.7.1 1.5.3 1.9.2l-.1.1c-.2.2-.4.3-.7.6-.7.4-1.3.7-1.8.7-.6 0-1.3-.1-2.1-.3-.7-.2-1.3-.4-1.8-.7-.2.2-.6.2-.9.1-.3-.1-.6-.6-.6-.8v-.1l-.7-.7c-.7-.7-1.1-1.6-1.5-2.4-.1-.4-.3-.9-.3-1.3.6.2.8 0 1-.2.1 0 .1.2.1.2.7 0 1-.4 1.1-.8.1.4.1.8.3 1.1.2.7.6 1.2 1 1.8.1.2.3.3.4.4.1 0 .2-.1.3-.1.2 0 .4.1.7.3.2.2.2.4.2.7 1.3.4 2.5.8 3.5 1.2zM17.4 26c.1 0 .1.1.2.1 0-.1-.1-.2-.2-.4-.1-.1-.3-.2-.6-.2-.4 0-.8.4-1 .6-.1 0-.2 0-.3-.1 0 .1.1.2.1.3-.2.3-.3.7-.3.9 0 .1.2.4.4.7.2.1.3.1.6 0-.1-.1-.2-.1-.3-.2-.1 0-.2-.1-.2-.2v-.1c0-.1 0-.2.1-.3v-.3h.1c.1.1.3.1.4.1 0 0 .1 0 .1-.1.1-.1 0-.3-.2-.4l-.1-.4.1-.1c.1-.1.1-.2.2-.2.5.1.6.1.9.3zm.7 1.9c.2 0 .4-.2.4-.4s-.2-.4-.4-.4-.4.2-.4.4c-.1.3.2.4.4.4zm1.9.7c.2 0 .4-.2.4-.4s-.2-.4-.4-.4-.4.2-.4.4c0 .1.2.4.4.4zM20 5c-.2-.2-.4-.4-.4-.8.2 0 .6.2.8.4V3.5c-.3.3-.5.5-.9.5 0-.2.2-.6.4-.8h-1.1c.2.3.4.6.4.8-.2 0-.6-.2-.8-.4v1.1c.2-.2.4-.4.8-.4 0 .3-.2.6-.4.8H20zm-1.6 1.4c.1.4.6.8 1 .8s.9-.3 1-.8h-2zm1.2-.4h.8c-.1-.4-.4-.8-.8-.8V6zm-.4 0v-.8c-.4.1-.8.4-.8.8h.8zm.8 1.5c-.1 0-.2.1-.3.1V9h.3V7.5zm-1.1 1.6h.3V7.7c-.1 0-.2-.1-.3-.1v1.5zm1.2-1.8c0 .2.1.3.3.3s.3-.1.3-.3c0-.2-.1-.3-.3-.3s-.3.1-.3.3zm1-.1c.2 0 .3-.1.3-.3 0-.1-.1-.2-.3-.2s-.3.1-.3.3c0 .1.2.2.3.2zM22 7c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3s-.3.1-.3.3c0 .2.1.3.3.3zm2.2.8c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3s-.3.1-.3.3c0 .2.2.3.3.3zm-.5-.6c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3s-.3.1-.3.3c-.1.2 0 .3.3.3zm-.9-.2c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3s-.3.1-.3.3c-.1.1.2.3.3.3zm1.8 2.4c-.2 0-.3.1-.3.3 0 .2.1.3.3.3s.3-.1.3-.3c0-.2-.1-.3-.3-.3zm.1-.7c-.2 0-.3.1-.3.3 0 .2.1.3.3.3s.3-.1.3-.3c0-.2-.1-.3-.3-.3zm-.4-.5c0 .2.1.3.3.3s.4-.1.4-.3c0-.2-.1-.3-.3-.3s-.4.1-.4.3zm-5.9-.5c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3s-.3.1-.3.3c0 0 .2.3.3.3zm-.8-.5c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3s-.3.1-.3.3c.1.2.2.3.3.3zm-.7-.2c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3s-.3.1-.3.3c-.1.2.1.3.3.3zm-2.3.8c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3s-.3.1-.3.3c0 .2.1.3.3.3zm.6-.6c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3s-.3.1-.3.3c-.1.2.2.3.3.3zm.9-.2c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3s-.3.1-.3.3c-.1.1.1.3.3.3zm-1.5 2.8c0-.2-.1-.3-.3-.3s-.3 0-.3.3c0 .2.1.3.3.3.1 0 .3-.1.3-.3zm-.2-.8c0-.2-.1-.3-.3-.3-.2 0-.3.1-.3.3 0 .2.1.3.3.3.2 0 .3-.2.3-.3zm-.2-.5c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3s-.4.1-.4.3c0 .1.3.3.4.3zm7.7.3c-.1.1-.4.4-.4.8 0 .2.2.6.3.8.1-.3.4-.4.4-.8 0-.3-.2-.5-.3-.8zm-4.9 0c-.2.3-.3.6-.3.9 0 .3.3.4.4.8.1-.3.3-.6.3-.8 0-.5-.3-.8-.4-.9z"></path>
|
|
8
|
+
|
|
9
|
+
<image src="/assets/images/crest.svg" xlink:href="" width="40" height="40"></image>
|
|
10
|
+
</svg>
|
|
11
|
+
HMPPS
|
|
12
|
+
</a>
|
|
13
|
+
|
|
14
|
+
<a class="fallback-dps-header__link fallback-dps-header__title__service-name" href="{{ authUrl }}">Digital Services</a>
|
|
15
|
+
|
|
16
|
+
{% if environmentName !== 'PRODUCTION' %}
|
|
17
|
+
{{ govukTag({
|
|
18
|
+
text: environmentName,
|
|
19
|
+
classes: environmentNameColour
|
|
20
|
+
}) }}
|
|
21
|
+
{% endif %}
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<nav aria-label="Account navigation">
|
|
25
|
+
<ul class="fallback-dps-header__navigation">
|
|
26
|
+
{% if name %}
|
|
27
|
+
<li class="fallback-dps-header__navigation__item">
|
|
28
|
+
<a data-qa="manageDetails" class="fallback-dps-header__link" href="/account-details" data-test="manage-account-link">
|
|
29
|
+
<span data-qa=header-user-name>{{ name }}</span>
|
|
30
|
+
<span class="fallback-dps-header__link__sub-text">Manage your details</span>
|
|
31
|
+
</a>
|
|
32
|
+
</li>
|
|
33
|
+
{% endif %}
|
|
34
|
+
|
|
35
|
+
<li class="fallback-dps-header__navigation__item">
|
|
36
|
+
<a data-qa="signOut" class="fallback-dps-header__link" href="/sign-out">Sign out</a>
|
|
37
|
+
</li>
|
|
38
|
+
</ul>
|
|
39
|
+
</nav>
|
|
40
|
+
</div>
|
|
41
|
+
</header>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<footer class="govuk-footer govuk-!-display-none-print"></footer>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{% from "govuk/components/tag/macro.njk" import govukTag %}
|
|
2
|
+
<header class="fallback-dps-header" role="banner">
|
|
3
|
+
<div class="fallback-dps-header__container">
|
|
4
|
+
<div class="fallback-dps-header__title">
|
|
5
|
+
<a class="fallback-dps-header__link fallback-dps-header__link--no-underline fallback-dps-header__title__service-name" href="{{ dpsUrl }}">
|
|
6
|
+
<svg role="presentation" focusable="false" class="fallback-dps-header__logo" xmlns="http://www.w3.org/2000/svg" width="41" height="30" viewBox="0 0 41 30">
|
|
7
|
+
<path d="M22.6,10.4c-1,0.4-2-0.1-2.4-1s0.1-2,1-2.4s2,0.1,2.4,1S23.5,10,22.6,10.4 M16.7,17.1c-0.9,0.4-2-0.1-2.4-1
|
|
8
|
+
c-0.4-0.9,0.1-2,1-2.4s2,0.1,2.4,1S17.6,16.7,16.7,17.1 M27.5,13.4c-1,0.4-2-0.1-2.4-1s0.1-2,1-2.4c0.9-0.4,2,0.1,2.4,1
|
|
9
|
+
S28.5,13,27.5,13.4 M30.8,18.2c-1,0.4-2-0.1-2.4-1s0.1-2,1-2.4s2,0.1,2.4,1C32.2,16.7,31.7,17.8,30.8,18.2 M17,4.7l2.3,1.2V2.5
|
|
10
|
+
L17,3.2L16.8,3l0.9-3h-3.4l0.9,3L15,3.2c-0.1,0.1-2.3-0.7-2.3-0.7v3.4L15,4.7c0.1,0.1,0.1,0.2,0.2,0.2l-1.3,4
|
|
11
|
+
c-0.1,0.2-0.1,0.4-0.1,0.6c0,1.1,0.8,2,1.9,2.2h0.7c1-0.2,1.9-1.1,1.9-2.1c0-0.2,0-0.4-0.1-0.6l-1.3-4C16.8,4.8,16.9,4.8,17,4.7
|
|
12
|
+
M9.4,10.4c0.9,0.4,2-0.1,2.4-1s-0.1-2-1-2.4s-2,0.1-2.4,1S8.4,10,9.4,10.4 M4.4,13.4c0.9,0.4,2-0.1,2.4-1s-0.1-2-1-2.4
|
|
13
|
+
s-2,0.1-2.4,1S3.5,13,4.4,13.4 M1.2,18.2c0.9,0.4,2-0.1,2.4-1s-0.1-2-1-2.4s-2,0.1-2.4,1C-0.2,16.7,0.2,17.8,1.2,18.2 M16,29.2
|
|
14
|
+
c4.4,0,8.6,0.3,12.3,0.8c1.1-4.5,2.4-7,3.7-8.8l-2.5-0.9c0.2,1.3,0.3,1.9,0,2.7c-0.4-0.4-0.8-1.1-1.1-2.3l-1.2,4
|
|
15
|
+
c0.7-0.5,1.3-0.8,2-0.9c-1.1,2.5-2.6,3.1-3.5,3c-1.1-0.2-1.7-1.2-1.5-2.1c0.3-1.2,1.5-1.5,2.1-0.1c1.1-2.3-0.8-3-2-2.3
|
|
16
|
+
c1.9-1.9,2.1-3.5,0.6-5.6c-2.1,1.6-2.1,3.2-1.2,5.5c-1.2-1.4-3.2-0.6-2.5,1.6c0.9-1.4,2.1-0.5,1.9,0.8c-0.2,1.1-1.7,2.1-3.5,1.9
|
|
17
|
+
c-2.7-0.2-2.9-2.1-2.9-3.6c0.7-0.1,1.9,0.5,2.9,1.9l0.4-4.3c-1.1,1.1-2.1,1.4-3.2,1.4c0.4-1.2,2.1-3,2.1-3h-5.4c0,0,1.7,1.9,2.1,3
|
|
18
|
+
c-1.1,0-2.1-0.2-3.2-1.4l0.4,4.3c1-1.4,2.2-2,2.9-1.9c-0.1,1.5-0.2,3.4-2.9,3.6c-1.9,0.2-3.4-0.8-3.5-1.9c-0.2-1.3,1-2.2,1.9-0.8
|
|
19
|
+
c0.7-2.3-1.2-3-2.5-1.6c0.9-2.2,0.9-3.9-1.2-5.5c-1.5,2-1.3,3.7,0.6,5.6c-1.2-0.7-3.1,0-2,2.3c0.6-1.4,1.8-1.1,2.1,0.1
|
|
20
|
+
c0.2,0.9-0.3,1.9-1.5,2.1c-0.9,0.2-2.4-0.5-3.5-3c0.6,0,1.2,0.3,2,0.9l-1.2-4c-0.3,1.1-0.7,1.9-1.1,2.3c-0.3-0.8-0.2-1.4,0-2.7
|
|
21
|
+
L0,21.2C1.3,23,2.6,25.5,3.7,30C7.4,29.5,11.6,29.2,16,29.2"
|
|
22
|
+
/>
|
|
23
|
+
</svg>
|
|
24
|
+
Digital Prison Services
|
|
25
|
+
</a>
|
|
26
|
+
|
|
27
|
+
{% if environmentName !== 'PRODUCTION' %}
|
|
28
|
+
{{ govukTag({
|
|
29
|
+
text: environmentName,
|
|
30
|
+
classes: environmentNameColour
|
|
31
|
+
}) }}
|
|
32
|
+
{% endif %}
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<nav aria-label="Account navigation">
|
|
36
|
+
<ul class="fallback-dps-header__navigation">
|
|
37
|
+
{% if name %}
|
|
38
|
+
<li class="fallback-dps-header__navigation__item">
|
|
39
|
+
<span data-qa=header-user-name>{{ name }}</span>
|
|
40
|
+
</li>
|
|
41
|
+
{% endif %}
|
|
42
|
+
|
|
43
|
+
<li class="fallback-dps-header__navigation__item">
|
|
44
|
+
<a data-qa="signOut" class="fallback-dps-header__link fallback-dps-header__link--no-underline fallback-dps-header__sign-out" href="/sign-out">Sign out</a>
|
|
45
|
+
</li>
|
|
46
|
+
</ul>
|
|
47
|
+
</nav>
|
|
48
|
+
</div>
|
|
49
|
+
</header>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type bunyan from 'bunyan';
|
|
2
|
+
import AvailableComponent from './types/AvailableComponent';
|
|
3
|
+
import Component from './types/Component';
|
|
4
|
+
import TimeoutOptions from './types/TimeoutOptions';
|
|
5
|
+
import { ComponentsMeta } from './types/HeaderFooterMeta';
|
|
6
|
+
export type ComponentsApiResponse<T extends AvailableComponent[]> = Record<T[number], Component> & {
|
|
7
|
+
meta: ComponentsMeta[T[number]];
|
|
8
|
+
};
|
|
9
|
+
declare const _default: {
|
|
10
|
+
getComponents<T extends AvailableComponent[]>(userToken: string, timeoutOptions: TimeoutOptions, log: bunyan | typeof console): Promise<ComponentsApiResponse<T>>;
|
|
11
|
+
};
|
|
12
|
+
export default _default;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const superagent_1 = __importDefault(require("superagent"));
|
|
7
|
+
const config_1 = __importDefault(require("./config"));
|
|
8
|
+
exports.default = {
|
|
9
|
+
async getComponents(userToken, timeoutOptions, log) {
|
|
10
|
+
const result = await superagent_1.default
|
|
11
|
+
.get(`${config_1.default.apis.feComponents.url}/components`)
|
|
12
|
+
.agent(this.agent)
|
|
13
|
+
.retry(1, (err, _res) => {
|
|
14
|
+
if (err)
|
|
15
|
+
log.info(`Retry handler found API error with ${err.code} ${err.message}`);
|
|
16
|
+
return undefined; // retry handler only for logging retries, not to influence retry logic
|
|
17
|
+
})
|
|
18
|
+
.query('component=header&component=footer')
|
|
19
|
+
.auth(this.token, { type: 'bearer' })
|
|
20
|
+
.set({ 'x-user-token': userToken })
|
|
21
|
+
.timeout(timeoutOptions);
|
|
22
|
+
return result.body;
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=componentApiClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"componentApiClient.js","sourceRoot":"","sources":["../src/componentApiClient.ts"],"names":[],"mappings":";;;;;AAAA,4DAAmC;AAGnC,sDAA6B;AAS7B,kBAAe;IACb,KAAK,CAAC,aAAa,CACjB,SAAiB,EACjB,cAA8B,EAC9B,GAA4B;QAE5B,MAAM,MAAM,GAAG,MAAM,oBAAU;aAC5B,GAAG,CAAC,GAAG,gBAAM,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,aAAa,CAAC;aACjD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;aACjB,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;YACtB,IAAI,GAAG;gBAAE,GAAG,CAAC,IAAI,CAAC,sCAAsC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;YAClF,OAAO,SAAS,CAAA,CAAC,uEAAuE;QAC1F,CAAC,CAAC;aACD,KAAK,CAAC,mCAAmC,CAAC;aAC1C,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;aACpC,GAAG,CAAC,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC;aAClC,OAAO,CAAC,cAAc,CAAC,CAAA;QAE1B,OAAO,MAAM,CAAC,IAAI,CAAA;IACpB,CAAC;CACF,CAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const componentApiClient_1 = __importDefault(require("./componentApiClient"));
|
|
7
|
+
const fallbacks_1 = require("./utils/fallbacks");
|
|
8
|
+
const updateCsp_1 = __importDefault(require("./utils/updateCsp"));
|
|
9
|
+
const defaultOptions = {
|
|
10
|
+
logger: console,
|
|
11
|
+
timeoutOptions: { response: 2500, deadline: 2500 },
|
|
12
|
+
includeMeta: false,
|
|
13
|
+
};
|
|
14
|
+
function getFrontendComponents(requestOptions) {
|
|
15
|
+
const { logger, timeoutOptions, includeMeta } = {
|
|
16
|
+
...defaultOptions,
|
|
17
|
+
...requestOptions,
|
|
18
|
+
};
|
|
19
|
+
return async (_req, res, next) => {
|
|
20
|
+
try {
|
|
21
|
+
const { header, footer, meta } = await componentApiClient_1.default.getComponents(res.locals.user.token, timeoutOptions, logger);
|
|
22
|
+
res.locals.feComponents = {
|
|
23
|
+
header: header.html,
|
|
24
|
+
footer: footer.html,
|
|
25
|
+
cssIncludes: [...header.css, ...footer.css],
|
|
26
|
+
jsIncludes: [...header.javascript, ...footer.javascript],
|
|
27
|
+
};
|
|
28
|
+
if (includeMeta) {
|
|
29
|
+
res.locals.feComponentsMeta = meta;
|
|
30
|
+
}
|
|
31
|
+
(0, updateCsp_1.default)(res);
|
|
32
|
+
next();
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
logger.error('Failed to retrieve front end components, using fallbacks');
|
|
36
|
+
res.locals.feComponents = {
|
|
37
|
+
header: (0, fallbacks_1.getFallbackHeader)(res.locals.user, requestOptions),
|
|
38
|
+
footer: (0, fallbacks_1.getFallbackFooter)(res.locals.user, requestOptions),
|
|
39
|
+
cssIncludes: [],
|
|
40
|
+
jsIncludes: [],
|
|
41
|
+
};
|
|
42
|
+
next();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
exports.default = getFrontendComponents;
|
|
47
|
+
//# sourceMappingURL=componentsService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"componentsService.js","sourceRoot":"","sources":["../src/componentsService.ts"],"names":[],"mappings":";;;;;AACA,8EAAqD;AACrD,iDAAwE;AAExE,kEAAyC;AAEzC,MAAM,cAAc,GAA4B;IAC9C,MAAM,EAAE,OAAO;IACf,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAClD,WAAW,EAAE,KAAK;CACnB,CAAA;AAED,SAAwB,qBAAqB,CAAC,cAA+B;IAC3E,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,GAAG;QAC9C,GAAG,cAAc;QACjB,GAAG,cAAc;KAClB,CAAA;IAED,OAAO,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC/B,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,4BAAkB,CAAC,aAAa,CACrE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EACrB,cAAc,EACd,MAAM,CACP,CAAA;YAED,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG;gBACxB,MAAM,EAAE,MAAM,CAAC,IAAI;gBACnB,MAAM,EAAE,MAAM,CAAC,IAAI;gBACnB,WAAW,EAAE,CAAC,GAAG,MAAM,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC;gBAC3C,UAAU,EAAE,CAAC,GAAG,MAAM,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC;aACzD,CAAA;YAED,IAAI,WAAW,EAAE,CAAC;gBAChB,GAAG,CAAC,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAA;YACpC,CAAC;YAED,IAAA,mBAAS,EAAC,GAAG,CAAC,CAAA;YAEd,IAAI,EAAE,CAAA;QACR,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAA;YAExE,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG;gBACxB,MAAM,EAAE,IAAA,6BAAiB,EAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC;gBAC1D,MAAM,EAAE,IAAA,6BAAiB,EAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC;gBAC1D,WAAW,EAAE,EAAE;gBACf,UAAU,EAAE,EAAE;aACf,CAAA;YAED,IAAI,EAAE,CAAA;QACR,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAzCD,wCAyCC"}
|
package/dist/config.d.ts
ADDED
package/dist/config.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const production = process.env.NODE_ENV === 'production';
|
|
4
|
+
function get(name, fallback, options = { requireInProduction: false }) {
|
|
5
|
+
const envVarValue = process.env[name];
|
|
6
|
+
if (envVarValue !== undefined) {
|
|
7
|
+
return envVarValue;
|
|
8
|
+
}
|
|
9
|
+
if (fallback !== undefined && (!production || !options.requireInProduction)) {
|
|
10
|
+
return fallback;
|
|
11
|
+
}
|
|
12
|
+
throw new Error(`Missing env var ${name}`);
|
|
13
|
+
}
|
|
14
|
+
const requiredInProduction = { requireInProduction: true };
|
|
15
|
+
exports.default = {
|
|
16
|
+
apis: {
|
|
17
|
+
feComponents: {
|
|
18
|
+
url: get('COMPONENT_API_URL', 'http://fe-components', requiredInProduction),
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAAA,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAA;AAExD,SAAS,GAAG,CAAC,IAAY,EAAE,QAAgB,EAAE,OAAO,GAAG,EAAE,mBAAmB,EAAE,KAAK,EAAE;IACnF,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACrC,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,WAAW,CAAA;IACpB,CAAC;IACD,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC5E,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,oBAAoB,GAAG,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAA;AAE1D,kBAAe;IACb,IAAI,EAAE;QACJ,YAAY,EAAE;YACZ,GAAG,EAAE,GAAG,CAAC,mBAAmB,EAAE,sBAAsB,EAAE,oBAAoB,CAAC;SAC5E;KACF;CACF,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import getFrontendComponents from './componentsService';
|
|
2
|
+
declare const _default: {
|
|
3
|
+
/**
|
|
4
|
+
* Returns a request handler for adding header and footer frontend components to res.locals
|
|
5
|
+
*
|
|
6
|
+
* Adds stringified html for each component along with lists of css javascript links.
|
|
7
|
+
*
|
|
8
|
+
* Expects nunjucks and res.locals.user to be set up inline with the hmpps-template-typescript project
|
|
9
|
+
*
|
|
10
|
+
* @param requestOptions - config object for request
|
|
11
|
+
* @param requestOptions.dpsUrl - url to the dps homepage to be used in the header
|
|
12
|
+
* @param requestOptions.authUrl - if your service has users with non-nomis auth sources, pass in the url to the auth service for the home link
|
|
13
|
+
* @param requestOptions.supportUrl - if your service has users with non-nomis auth sources, pass in the support url for the support link
|
|
14
|
+
* @param requestOptions.environmentName - "DEV", "PRE-PRODUCTION" or "PRODUCTION" to be used in the header
|
|
15
|
+
* @param requestOptions.logger - pass in the bunyen logger if you want to use it. Falls back to console if not provided
|
|
16
|
+
* @param requestOptions.timeoutOptions - timeout object for superagent. Defaults to 2500ms
|
|
17
|
+
* @param requestOptions.includeMeta - adds feComponentsMeta to res.locals if true. Contains metadata for components including activeCaseLoad, caseLoads and available services for user
|
|
18
|
+
*/
|
|
19
|
+
getPageComponents: typeof getFrontendComponents;
|
|
20
|
+
};
|
|
21
|
+
export default _default;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const componentsService_1 = __importDefault(require("./componentsService"));
|
|
7
|
+
exports.default = {
|
|
8
|
+
/**
|
|
9
|
+
* Returns a request handler for adding header and footer frontend components to res.locals
|
|
10
|
+
*
|
|
11
|
+
* Adds stringified html for each component along with lists of css javascript links.
|
|
12
|
+
*
|
|
13
|
+
* Expects nunjucks and res.locals.user to be set up inline with the hmpps-template-typescript project
|
|
14
|
+
*
|
|
15
|
+
* @param requestOptions - config object for request
|
|
16
|
+
* @param requestOptions.dpsUrl - url to the dps homepage to be used in the header
|
|
17
|
+
* @param requestOptions.authUrl - if your service has users with non-nomis auth sources, pass in the url to the auth service for the home link
|
|
18
|
+
* @param requestOptions.supportUrl - if your service has users with non-nomis auth sources, pass in the support url for the support link
|
|
19
|
+
* @param requestOptions.environmentName - "DEV", "PRE-PRODUCTION" or "PRODUCTION" to be used in the header
|
|
20
|
+
* @param requestOptions.logger - pass in the bunyen logger if you want to use it. Falls back to console if not provided
|
|
21
|
+
* @param requestOptions.timeoutOptions - timeout object for superagent. Defaults to 2500ms
|
|
22
|
+
* @param requestOptions.includeMeta - adds feComponentsMeta to res.locals if true. Contains metadata for components including activeCaseLoad, caseLoads and available services for user
|
|
23
|
+
*/
|
|
24
|
+
getPageComponents: componentsService_1.default,
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,4EAAuD;AAEvD,kBAAe;IACb;;;;;;;;;;;;;;;OAeG;IACH,iBAAiB,EAAE,2BAAqB;CACzC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AvailableComponent.js","sourceRoot":"","sources":["../../src/types/AvailableComponent.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CaseLoad.js","sourceRoot":"","sources":["../../src/types/CaseLoad.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Component.js","sourceRoot":"","sources":["../../src/types/Component.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import CaseLoad from './CaseLoad';
|
|
2
|
+
import Service from './Service';
|
|
3
|
+
export default interface HeaderFooterMeta {
|
|
4
|
+
activeCaseLoad: CaseLoad;
|
|
5
|
+
caseLoads: CaseLoad[];
|
|
6
|
+
services: Service[];
|
|
7
|
+
}
|
|
8
|
+
export interface ComponentsMeta {
|
|
9
|
+
header: HeaderFooterMeta;
|
|
10
|
+
footer: HeaderFooterMeta;
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HeaderFooterMeta.js","sourceRoot":"","sources":["../../src/types/HeaderFooterMeta.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type bunyan from 'bunyan';
|
|
2
|
+
import TimeoutOptions from './TimeoutOptions';
|
|
3
|
+
export default interface RequestOptions {
|
|
4
|
+
dpsUrl: string;
|
|
5
|
+
authUrl?: string;
|
|
6
|
+
supportUrl?: string;
|
|
7
|
+
environmentName?: 'DEV' | 'PRE-PRODUCTION' | 'PRODUCTION';
|
|
8
|
+
logger?: bunyan | typeof console;
|
|
9
|
+
includeMeta?: boolean;
|
|
10
|
+
timeoutOptions?: TimeoutOptions;
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RequestOptions.js","sourceRoot":"","sources":["../../src/types/RequestOptions.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Service.js","sourceRoot":"","sources":["../../src/types/Service.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimeoutOptions.js","sourceRoot":"","sources":["../../src/types/TimeoutOptions.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"User.js","sourceRoot":"","sources":["../../src/types/User.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { User } from '../types/User';
|
|
2
|
+
import RequestOptions from '../types/RequestOptions';
|
|
3
|
+
export declare function getFallbackHeader(user: User, requestOptions: RequestOptions): string;
|
|
4
|
+
export declare function getFallbackFooter(user: User, requestOptions: RequestOptions): string;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getFallbackFooter = exports.getFallbackHeader = void 0;
|
|
7
|
+
const nunjucks_1 = __importDefault(require("nunjucks"));
|
|
8
|
+
function getFallbackHeader(user, requestOptions) {
|
|
9
|
+
const { dpsUrl, environmentName, authUrl, supportUrl } = requestOptions;
|
|
10
|
+
return nunjucks_1.default.render('dpsComponents/header-bar.njk', {
|
|
11
|
+
isPrisonUser: user.authSource === 'nomis',
|
|
12
|
+
user,
|
|
13
|
+
dpsUrl,
|
|
14
|
+
environmentName,
|
|
15
|
+
authUrl,
|
|
16
|
+
supportUrl,
|
|
17
|
+
name: initialiseName(user.displayName),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
exports.getFallbackHeader = getFallbackHeader;
|
|
21
|
+
function getFallbackFooter(user, requestOptions) {
|
|
22
|
+
const { supportUrl, authUrl } = requestOptions;
|
|
23
|
+
return nunjucks_1.default.render('dpsComponents/footer.njk', { isPrisonUser: user.authSource === 'nomis', supportUrl, authUrl });
|
|
24
|
+
}
|
|
25
|
+
exports.getFallbackFooter = getFallbackFooter;
|
|
26
|
+
function initialiseName(fullName) {
|
|
27
|
+
if (!fullName)
|
|
28
|
+
return null;
|
|
29
|
+
const array = fullName.split(' ');
|
|
30
|
+
return `${array[0][0]}. ${array.reverse()[0]}`;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=fallbacks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallbacks.js","sourceRoot":"","sources":["../../src/utils/fallbacks.ts"],"names":[],"mappings":";;;;;;AAAA,wDAA+B;AAI/B,SAAgB,iBAAiB,CAAC,IAAU,EAAE,cAA8B;IAC1E,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,cAAc,CAAA;IACvE,OAAO,kBAAQ,CAAC,MAAM,CAAC,8BAA8B,EAAE;QACrD,YAAY,EAAE,IAAI,CAAC,UAAU,KAAK,OAAO;QACzC,IAAI;QACJ,MAAM;QACN,eAAe;QACf,OAAO;QACP,UAAU;QACV,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC;KACvC,CAAC,CAAA;AACJ,CAAC;AAXD,8CAWC;AAED,SAAgB,iBAAiB,CAAC,IAAU,EAAE,cAA8B;IAC1E,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,cAAc,CAAA;IAC9C,OAAO,kBAAQ,CAAC,MAAM,CAAC,0BAA0B,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,UAAU,KAAK,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAA;AACxH,CAAC;AAHD,8CAGC;AAED,SAAS,cAAc,CAAC,QAAiB;IACvC,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAA;IAE1B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACjC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;AAChD,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const config_1 = __importDefault(require("../config"));
|
|
7
|
+
function updateCsp(res) {
|
|
8
|
+
var _a;
|
|
9
|
+
const csp = res.getHeaders()['content-security-policy'];
|
|
10
|
+
const allDirectives = (_a = csp === null || csp === void 0 ? void 0 : csp.split(';')) !== null && _a !== void 0 ? _a : [];
|
|
11
|
+
const directivesToUpdate = ['script-src', 'style-src', 'img-src', 'font-src'];
|
|
12
|
+
const updatedCspDirectives = allDirectives.map(directive => {
|
|
13
|
+
// if directive is not in cspToUpdate or includes fe components url already return as is
|
|
14
|
+
if (directive.includes(config_1.default.apis.feComponents.url) || !directivesToUpdate.some(p => directive.includes(`${p} `)))
|
|
15
|
+
return directive;
|
|
16
|
+
// if directive is in cspToUpdate and does not have fe components url, add in
|
|
17
|
+
return `${directive} ${config_1.default.apis.feComponents.url}`;
|
|
18
|
+
});
|
|
19
|
+
const requiredAndNotPresent = directivesToUpdate
|
|
20
|
+
.filter(p => !updatedCspDirectives.find(directive => directive.includes(`${p} `)))
|
|
21
|
+
.map(p => `${p} 'self' ${config_1.default.apis.feComponents.url}`);
|
|
22
|
+
res.set('content-security-policy', [...updatedCspDirectives, ...requiredAndNotPresent].join(';'));
|
|
23
|
+
}
|
|
24
|
+
exports.default = updateCsp;
|
|
25
|
+
//# sourceMappingURL=updateCsp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updateCsp.js","sourceRoot":"","sources":["../../src/utils/updateCsp.ts"],"names":[],"mappings":";;;;;AACA,uDAA8B;AAE9B,SAAwB,SAAS,CAAC,GAAa;;IAC7C,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC,yBAAyB,CAAC,CAAA;IACvD,MAAM,aAAa,GAAG,MAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,KAAK,CAAC,GAAG,CAAC,mCAAI,EAAE,CAAA;IAC3C,MAAM,kBAAkB,GAAG,CAAC,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;IAE7E,MAAM,oBAAoB,GAAG,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;QACzD,wFAAwF;QACxF,IAAI,SAAS,CAAC,QAAQ,CAAC,gBAAM,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChH,OAAO,SAAS,CAAA;QAElB,6EAA6E;QAC7E,OAAO,GAAG,SAAS,IAAI,gBAAM,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,CAAA;IACvD,CAAC,CAAC,CAAA;IAEF,MAAM,qBAAqB,GAAG,kBAAkB;SAC7C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;SACjF,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,gBAAM,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,CAAA;IAE1D,GAAG,CAAC,GAAG,CAAC,yBAAyB,EAAE,CAAC,GAAG,oBAAoB,EAAE,GAAG,qBAAqB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACnG,CAAC;AAnBD,4BAmBC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ministryofjustice/hmpps-connect-dps-components",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A package to allow the inclusion of connect dps micro frontend components within dps applications",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/**/*"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc && npm run copy:assets",
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"test:ci": "jest --runInBand --passWithNoTests",
|
|
14
|
+
"lint": "eslint . --cache --max-warnings 0",
|
|
15
|
+
"copy:assets": "rm -rf dist/assets && cp -r src/assets dist/assets",
|
|
16
|
+
"security_audit": "npx audit-ci --config audit-ci.json"
|
|
17
|
+
},
|
|
18
|
+
"jest": {
|
|
19
|
+
"transform": {
|
|
20
|
+
"^.+\\.tsx?$": [
|
|
21
|
+
"ts-jest",
|
|
22
|
+
{
|
|
23
|
+
"isolatedModules": true
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"testMatch": [
|
|
28
|
+
"<rootDir>/**/**/?(*.)(cy|test).{ts,js,jsx,mjs}"
|
|
29
|
+
],
|
|
30
|
+
"testEnvironment": "node",
|
|
31
|
+
"reporters": [
|
|
32
|
+
"default",
|
|
33
|
+
[
|
|
34
|
+
"jest-junit",
|
|
35
|
+
{
|
|
36
|
+
"outputDirectory": "test_results/jest/"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
[
|
|
40
|
+
"./node_modules/jest-html-reporter",
|
|
41
|
+
{
|
|
42
|
+
"outputPath": "test_results/unit-test-reports.html"
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
],
|
|
46
|
+
"moduleFileExtensions": [
|
|
47
|
+
"web.js",
|
|
48
|
+
"js",
|
|
49
|
+
"json",
|
|
50
|
+
"node",
|
|
51
|
+
"ts"
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"repository": {
|
|
55
|
+
"type": "git",
|
|
56
|
+
"url": "git+ssh://git@github.com/ministryofjustice/hmpps-connect-dps-components.git"
|
|
57
|
+
},
|
|
58
|
+
"author": "",
|
|
59
|
+
"license": "MIT",
|
|
60
|
+
"bugs": {
|
|
61
|
+
"url": "https://github.com/ministryofjustice/hmpps-connect-dps-components/issues"
|
|
62
|
+
},
|
|
63
|
+
"homepage": "https://github.com/ministryofjustice/hmpps-connect-dps-components#readme",
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@types/bunyan": "^1.8.11",
|
|
66
|
+
"@types/express": "^4.17.21",
|
|
67
|
+
"@types/jest": "^29.5.12",
|
|
68
|
+
"@types/superagent": "^8.1.7",
|
|
69
|
+
"@types/supertest": "^6.0.2",
|
|
70
|
+
"@typescript-eslint/eslint-plugin": "^6.13.2",
|
|
71
|
+
"cheerio": "^1.0.0-rc.12",
|
|
72
|
+
"eslint": "^8.51.0",
|
|
73
|
+
"eslint-config-airbnb-base": "^15.0.0",
|
|
74
|
+
"eslint-config-prettier": "^9.0.0",
|
|
75
|
+
"eslint-import-resolver-typescript": "^3.6.1",
|
|
76
|
+
"eslint-plugin-cypress": "^2.15.1",
|
|
77
|
+
"eslint-plugin-import": "^2.28.1",
|
|
78
|
+
"eslint-plugin-no-only-tests": "^3.1.0",
|
|
79
|
+
"eslint-plugin-prettier": "^5.0.1",
|
|
80
|
+
"express": "^4.19.2",
|
|
81
|
+
"govuk-frontend": "^5.4.0",
|
|
82
|
+
"jest": "^29.7.0",
|
|
83
|
+
"jest-html-reporter": "^3.10.2",
|
|
84
|
+
"jest-junit": "^16.0.0",
|
|
85
|
+
"nock": "^13.5.4",
|
|
86
|
+
"supertest": "^7.0.0",
|
|
87
|
+
"ts-jest": "^29.1.4"
|
|
88
|
+
},
|
|
89
|
+
"dependencies": {
|
|
90
|
+
"@types/nunjucks": "^3.2.6",
|
|
91
|
+
"nunjucks": "^3.2.4",
|
|
92
|
+
"superagent": "^9.0.2"
|
|
93
|
+
}
|
|
94
|
+
}
|