on master help sign in
.github/FUNDING.ymlnew file+1
since splitsnapshots
unifiedsplit
@@ -0,0 +1 @@
1+custom: ["https://iko.soy/donate"]
.github/workflows/build.yamlnew file+97
@@ -0,0 +1,97 @@
1+name: CI
2+
3+on:
4+ push:
5+ branches: ["master"]
6+ pull_request:
7+ branches: ["master"]
8+ release:
9+ types: [prereleased]
10+
11+jobs:
12+ build:
13+ runs-on: ubuntu-latest
14+
15+ steps:
16+ - uses: cachix/install-nix-action@v19
17+
18+ - name: Cachix
19+ uses: cachix/cachix-action@v12
20+ with:
21+ name: iko
22+ authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
23+
24+ - uses: actions/checkout@v3
25+ with:
26+ submodules: recursive
27+
28+ - name: Install clickable
29+ run: |
30+ docker --version
31+ sudo apt install adb git python3 python3-pip python3-setuptools
32+ pip3 install --user clickable-ut==7.10.0 --upgrade
33+ echo 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.bashrc
34+
35+ - name: Build artifacts
36+ run: ./dev/build.sh
37+
38+ - name: Build Warden
39+ run: clickable build --output click
40+
41+ - uses: actions/upload-artifact@v3
42+ with:
43+ name: click
44+ path: click/*
45+
46+ - uses: actions/upload-artifact@v3
47+ with:
48+ name: dist
49+ path: dist
50+
51+ # Tests
52+
53+ - uses: actions/setup-node@v3
54+ with:
55+ node-version: 16
56+
57+ - name: Install test dependencies
58+ working-directory: tests
59+ run: |
60+ npm ci
61+ npx playwright install --with-deps
62+
63+ - name: Run tests
64+ working-directory: tests
65+ run: npx playwright test
66+
67+ - uses: actions/upload-artifact@v3
68+ if: always()
69+ with:
70+ name: playwright-report
71+ path: tests/playwright-report/
72+
73+ # Upload release
74+
75+ - name: Zip Release Assets
76+ if: github.event_name == 'release'
77+ shell: bash
78+ run: |
79+ cd dist/
80+ zip -r ../../../../dist.zip .
81+
82+ - name: Upload dist to release
83+ if: github.event_name == 'release'
84+ uses: svenstaro/upload-release-action@2.4.1
85+ with:
86+ repo_token: ${{ secrets.GITHUB_TOKEN }}
87+ file: dist.zip
88+ tag: ${{ github.ref }}
89+
90+ - name: Upload click to release
91+ if: github.event_name == 'release'
92+ uses: svenstaro/upload-release-action@2.4.1
93+ with:
94+ repo_token: ${{ secrets.GITHUB_TOKEN }}
95+ file: build/all/app/*.click
96+ tag: ${{ github.ref }}
97+ file_glob: true
.gitignore+12−1
@@ -7,5 +7,16 @@ static/backend.js
7.spago
7.spago
8output
8output
9.psc-ide-port
9.psc-ide-port
10−backend.js
11elm.js
10elm.js
11+output-es
12+elm-stuff
13+node_modules/
14+/tests/test-results/
15+/tests/playwright-report/
16+/tests/playwright/.cache/
17+generated-docs
18+backend.js.map
19+.spago2nix
20+backend.js
21+vanilla
22+dist
.gitmodulesdeleted−6
@@ -1,6 +0,0 @@
1−[submodule "vanilla"]
2− path = vanilla
3− url = https://github.com/ilyakooo0/vanilla-compiled.git
4−[submodule "deps/bw"]
5− path = deps/bw
6− url = https://github.com/bitwarden/clients.git
.helix/languages.tomlnew file+3
@@ -0,0 +1,3 @@
1+[[language]]
2+name = "nix"
3+auto-format = true
.vscode/tasks.jsonnew file+31
@@ -0,0 +1,31 @@
1+{
2+ // See https://go.microsoft.com/fwlink/?LinkId=733558
3+ // for the documentation about the tasks.json format
4+ "version": "2.0.0",
5+ "tasks": [
6+ {
7+ "label": "Generate bridge",
8+ "type": "process",
9+ "command": "${workspaceFolder}/dev/generate-bridge.sh",
10+ "problemMatcher": []
11+ },
12+ {
13+ "label": "Build backend",
14+ "type": "process",
15+ "command": "${workspaceFolder}/dev/build-backend.sh",
16+ "problemMatcher": []
17+ },
18+ {
19+ "label": "Start Chrome",
20+ "type": "process",
21+ "command": "${workspaceFolder}/dev/start-chrome.sh",
22+ "problemMatcher": []
23+ },
24+ {
25+ "label": "Start Elm-live",
26+ "type": "process",
27+ "command": "${workspaceFolder}/dev/elm-live.sh",
28+ "problemMatcher": []
29+ }
30+ ]
31+}
README.md+32−8
@@ -1,14 +1,38 @@
1−# App Title
1+<p align="center">
2+ <img src="logo.png" style="width: 100px;" />
3+</p>
2
4
3−A short description of your app
5+<h1 align="center">Warden</h1>
4
6
5−## License
7+<p align="center">
8+ <a href="https://open-store.io/app/soy.iko.warden"><img src="https://open-store.io/badges/en_US.svg" alt="OpenStore" style="width: 150px;" /></a>
9+</p>
6
10
7−Copyright (C) 2022 Your FullName
8
11
9−This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published
12+<p align="center">
10−by the Free Software Foundation.
13+ <img src="screenshots/1.png" style="width: 150px;" />
14+ <img src="screenshots/2.png" style="width: 150px;" />
15+ <img src="screenshots/3.png" style="width: 150px;" />
16+ <img src="screenshots/4.png" style="width: 150px;" />
17+ <img src="screenshots/5.png" style="width: 150px;" />
18+</p>
11
19
12−This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20+Warden is a [Bitwarden](https://bitwarden.com)/[Vaultwarden](https://github.com/dani-garcia/vaultwarden) client for [Ubuntu Touch](https://ubuntu-touch.io).
13
21
14−You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
22+## Features
23+
24+1. View and edit: passwords, contact, secure notes and credit cards
25+2. Generate passwords
26+
27+## Support the project
28+
29+I fund the development of Warden out of my own pocket. If you find the project useful and don't want it to die, please consider donating what you think the app is worth to you.
30+
31+<p align="center">
32+ <a href="https://iko.soy/donate"><img src="img/donate.png" alt="Donate" style="width: 150px;" /></a>
33+</p>
34+
35+
36+## Porting
37+
38+Although Warden is intended for ubuntu touch it is written completely in web technologies. This means that, if there is demand, the app can be ported to virtually any platform. The biggest problem will be [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS).
backend-main.jsnew file+3
@@ -0,0 +1,3 @@
1+import * as Main from "./backend/Main/index.js"
2+
3+Main.main()
bw/src/BW.js → backend/BW.jsrenamed+83−65
@@ -1,21 +1,29 @@
1−import { StateFactory } from "../../deps/bw/libs/shared/dist/src/factories/stateFactory";
1+import { StateFactory } from "../../bw/factories/stateFactory";
2−import { GlobalState } from "../../deps/bw/libs/shared/dist/src/models/domain/globalState";
2+import { GlobalState } from "../../bw/models/domain/global-state";
3−import { ApiService } from "../../deps/bw/libs/shared/dist/src/services/api.service";
3+import { ApiService } from "../../bw/services/api.service";
4−import { AppIdService } from "../../deps/bw/libs/shared/dist/src/services/appId.service";
4+import { AppIdService } from "../../bw/services/appId.service";
5−import { ConsoleLogService } from "../../deps/bw/libs/shared/dist/src/services/consoleLog.service";
5+import { ConsoleLogService } from "../../bw/services/consoleLog.service";
6−import { EnvironmentService } from "../../deps/bw/libs/shared/dist/src/services/environment.service";
6+import { EnvironmentService } from "../../bw/services/environment.service";
7−import { StateMigrationService } from "../../deps/bw/libs/shared/dist/src/services/stateMigration.service";
7+import { StateMigrationService } from "../../bw/services/stateMigration.service";
8−import { TokenService } from "../../deps/bw/libs/shared/dist/src/services/token.service";
8+import { TokenService } from "../../bw/services/token.service";
9−import { WebCryptoFunctionService } from "../../deps/bw/libs/shared/dist/src/services/webCryptoFunction.service";
9+import { WebCryptoFunctionService } from "../../bw/services/webCryptoFunction.service";
10−import { Account, AccountProfile, AccountTokens } from "../../deps/bw/libs/shared/dist/src/models/domain/account";
10+import { Account, AccountProfile, AccountTokens } from "../../bw/models/domain/account";
11−
11+import {MemoryStorageService} from "../../bw/services/memoryStorage.service"
12+
12−// import BrowserStorageService from "../../deps/bw/libs/shared/dist/src/services/browserStorage.service";
13+// import BrowserStorageService from "../../../../bw/services/browserStorage.service";
13−import { CryptoService } from "../../deps/bw/libs/shared/dist/src/services/crypto.service";
14+import { CryptoService } from "../../bw/services/crypto.service";
14−
15+
15−import { I18nService } from "../../deps/bw/libs/shared/dist/src/services/i18n.service";
16+import { I18nService } from "../../bw/services/i18n.service";
16−import { StateService as BaseStateService } from "../../deps/bw/libs/shared/dist/src/services/state.service";
17+import { StateService as BaseStateService } from "../../bw/services/state.service";
17−import { PasswordTokenRequest } from "../../deps/bw/libs/shared/dist/src/models/request/identityToken/passwordTokenRequest";
18+import { PasswordTokenRequest } from "../../bw/models/request/identity-token/password-token.request";
18−import { TokenRequestTwoFactor } from "../../deps/bw/libs/common/src/models/request/identityToken/tokenRequestTwoFactor.ts";
19+import { TokenTwoFactorRequest} from "../../bw/models/request/identity-token/token-two-factor.request";
20+import { CipherRequest } from "../../bw/vault/models/request/cipher.request";
21+import { CipherCreateRequest } from "../../bw/vault/models/request/cipher-create.request";
22+import { Cipher } from "../../bw/vault/models/domain/cipher";
23+import { CipherData } from "../../bw/vault/models/data/cipher.data";
24+import { PasswordGenerationService } from "../../bw/services/passwordGeneration.service";
25+import { TotpService } from "../../bw/services/totp.service"
26+import { EncryptServiceImplementation } from "../../bw/services/cryptography/encrypt.service.implementation"
19
27
20function sanitize(obj) {
28function sanitize(obj) {
21 return JSON.parse(JSON.stringify(obj));
29 return JSON.parse(JSON.stringify(obj));
@@ -30,7 +38,7 @@ export function getServices() {
30
38
31 await bg.bootstrap()
39 await bg.bootstrap()
32
40
33− bg.environmentService.setUrls(urls)
41+ await bg.environmentService.setUrls(urls)
34
42
35 if (tokenResponse != null) {
43 if (tokenResponse != null) {
36 const accountInformation = await bg.tokenService.decodeToken(tokenResponse.accessToken);
44 const accountInformation = await bg.tokenService.decodeToken(tokenResponse.accessToken);
@@ -64,35 +72,54 @@ export function getServices() {
64 getProfile: (req) => api.getProfile(req),
72 getProfile: (req) => api.getProfile(req),
65 postIdentityToken: (req) => api.postIdentityToken(
73 postIdentityToken: (req) => api.postIdentityToken(
66 new PasswordTokenRequest(
74 new PasswordTokenRequest(
67− email = req.email,
75+ req.email,
68− masterPasswordHash = req.masterPasswordHash,
76+ req.masterPasswordHash,
69− captchaResponse = req.captchaResponse,
77+ req.captchaResponse,
70− twoFactor = new TokenRequestTwoFactor(req.twoFactor),
78+ new TokenTwoFactorRequest(
79+ req.twoFactor.provider,
80+ req.twoFactor.token,
81+ req.twoFactor.remember
82+ ),
71− device = req.device
83+ req.device
72 )
84 )
73 ),
85 ),
74 getSync: () => api.getSync().then(sanitize),
86 getSync: () => api.getSync().then(sanitize),
87+ postCipherCreate: (cipher) => api.postCipherCreate(makeCipherCreateRequest(cipher)),
88+ putCipher: (cipher) => api.putCipher(cipher.id, makeCipherRequest(cipher)),
89+ deleteCipher: (id) => api.deleteCipher(id),
90+ postTwoFactorEmail: (req) => api.postTwoFactorEmail(req),
75 }
91 }
76 },
92 },
77− crypto: bg.cryptoService
93+ crypto: bg.cryptoService,
94+ cryptoFunctions: bg.cryptoFunctionService,
95+ passwordGeneration: bg.passwordGenerationService,
96+ totpService: bg.totpService,
78 }
97 }
79}
98}
80
99
100+function makeCipherRequest(cipher) {
101+ return new CipherRequest(new Cipher(new CipherData(cipher)))
102+}
103+
104+function makeCipherCreateRequest(cipher) {
105+ return new CipherCreateRequest(new Cipher(new CipherData(cipher)))
106+}
107+
81class MainBackground {
108class MainBackground {
82− messagingService; //: MessagingServiceAbstraction;
109+ // messagingService; //: MessagingServiceAbstraction;
83− storageService; //: StorageServiceAbstraction;
110+ // storageService; //: StorageServiceAbstraction;
84− i18nService; //: I18nServiceAbstraction;
111+ // i18nService; //: I18nServiceAbstraction;
85− platformUtilsService; //: PlatformUtilsServiceAbstraction;
112+ // platformUtilsService; //: PlatformUtilsServiceAbstraction;
86− logService; //: LogServiceAbstraction;
113+ // logService; //: LogServiceAbstraction;
87− cryptoService; //: CryptoServiceAbstraction;
114+ // cryptoService; //: CryptoServiceAbstraction;
88− cryptoFunctionService; //: CryptoFunctionServiceAbstraction;
115+ // cryptoFunctionService; //: CryptoFunctionServiceAbstraction;
89− tokenService; //: TokenServiceAbstraction;
116+ // tokenService; //: TokenServiceAbstraction;
90− appIdService; //: AppIdServiceAbstraction;
117+ // appIdService; //: AppIdServiceAbstraction;
91− apiService; //: ApiServiceAbstraction;
118+ // apiService; //: ApiServiceAbstraction;
92− environmentService; //: EnvironmentServiceAbstraction;
119+ // environmentService; //: EnvironmentServiceAbstraction;
93− authService; //: AuthServiceAbstraction;
120+ // authService; //: AuthServiceAbstraction;
94− stateService; //: StateServiceAbstraction;
121+ // stateService; //: StateServiceAbstraction;
95− stateMigrationService; //: StateMigrationService;
122+ // stateMigrationService; //: StateMigrationService;
96
123
97
124
98 constructor() {
125 constructor() {
@@ -106,6 +133,7 @@ class MainBackground {
106 new StateFactory(GlobalState, Account)
133 new StateFactory(GlobalState, Account)
107 );
134 );
108 this.stateService = new StateService(
135 this.stateService = new StateService(
136+ this.storageService,
109 this.storageService,
137 this.storageService,
110 this.storageService,
138 this.storageService,
111 this.logService,
139 this.logService,
@@ -136,8 +164,13 @@ class MainBackground {
136 );
164 );
137 this.i18nService = new I18nService("en");
165 this.i18nService = new I18nService("en");
138 this.cryptoFunctionService = new WebCryptoFunctionService(window);
166 this.cryptoFunctionService = new WebCryptoFunctionService(window);
167+ this.encryptService = new EncryptServiceImplementation(
168+ this.cryptoFunctionService,
169+ this.logService
170+ );
139 this.cryptoService = new BrowserCryptoService(
171 this.cryptoService = new BrowserCryptoService(
140 this.cryptoFunctionService,
172 this.cryptoFunctionService,
173+ this.encryptService,
141 this.platformUtilsService,
174 this.platformUtilsService,
142 this.logService,
175 this.logService,
143 this.stateService
176 this.stateService
@@ -152,6 +185,16 @@ class MainBackground {
152 this.appIdService,
185 this.appIdService,
153 (expired) => this.logout(expired)
186 (expired) => this.logout(expired)
154 );
187 );
188+ this.passwordGenerationService = new PasswordGenerationService(
189+ this.cryptoService,
190+ this.policyService,
191+ this.stateService
192+ );
193+ this.totpService = new TotpService(
194+ this.cryptoFunctionService,
195+ this.logService,
196+ this.stateService
197+ );
155 }
198 }
156
199
157 async bootstrap() {
200 async bootstrap() {
@@ -171,31 +214,6 @@ class MainBackground {
171 }
214 }
172}
215}
173
216
174−class MemoryStorageService {
175− storage = {};
176−
177− async get(key) {
178− return this.storage[key]
179− }
180−
181− async has(key) {
182− return key in this.storage;
183− }
184−
185− async save(key, obj) {
186− if (obj == null) {
187− this.remove(key)
188− return
189− }
190−
191− this.storage[key] = obj
192− }
193−
194− async remove(key) {
195− delete this.storage[key]
196− }
197−}
198−
199class BrowserCryptoService extends CryptoService {
217class BrowserCryptoService extends CryptoService {
200 async retrieveKeyFromStorage(keySuffix) {
218 async retrieveKeyFromStorage(keySuffix) {
201 if (keySuffix === "biometric") {
219 if (keySuffix === "biometric") {
@@ -276,7 +294,7 @@ class BrowserPlatformUtilsService {
276 saveFile(win, blobData, blobOptions, fileName) {
294 saveFile(win, blobData, blobOptions, fileName) {
277 // BrowserApi.downloadFile(win, blobData, blobOptions, fileName);
295 // BrowserApi.downloadFile(win, blobData, blobOptions, fileName);
278 }
296 }
279− getApplicationVersion() {
297+ getApplicationVersionNumber() {
280 // return Promise.resolve(BrowserApi.getApplicationVersion());
298 // return Promise.resolve(BrowserApi.getApplicationVersion());
281 }
299 }
282 supportsWebAuthn(win) {
300 supportsWebAuthn(win) {
backend/BW.pursnew file+95
@@ -0,0 +1,95 @@
1+module BW where
2+
3+import BW.Types
4+import Bridge
5+import Prelude
6+
7+import Bridge as Bridge
8+import Control.Promise (Promise)
9+import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson)
10+import Data.ArrayBuffer.Typed as AB
11+import Data.ArrayBuffer.Types (ArrayBuffer, ArrayView, Int32)
12+import Data.EncString (EncString)
13+import Data.Function.Uncurried (Fn2, Fn3, Fn4)
14+import Data.JNullable (JNullable)
15+import Data.SymmetricCryptoKey (SymmetricCryptoKey)
16+import Effect (Effect)
17+import Effect.Unsafe (unsafePerformEffect)
18+import Untagged.Union (type (|+|))
19+
20+type TotpService =
21+ { getCode :: String -> Promise String
22+ , getTimeInterval :: String -> Int
23+ }
24+
25+type CryptoService =
26+ { makeKey :: Fn4 Password String KDF KdfConfig (Promise SymmetricCryptoKey)
27+ , hashPassword :: Fn3 Password SymmetricCryptoKey (JNullable HashPurpose) (Promise StringHash)
28+ , decryptToUtf8 :: Fn2 EncString SymmetricCryptoKey (Promise String)
29+ , decryptToBytes :: Fn2 EncString SymmetricCryptoKey (Promise ArrayBuffer)
30+ , encrypt :: Fn2 String SymmetricCryptoKey (Promise EncString)
31+ , stretchKey :: SymmetricCryptoKey -> Promise SymmetricCryptoKey
32+ }
33+
34+type ApiService =
35+ { postPrelogin :: PreloginRequest -> Promise PreloginResponse
36+ , getProfile :: Unit -> Promise ProfileResponse
37+ -- TODO: There can really be more request and response types. Maybe handle this later.
38+ , postIdentityToken :: PasswordTokenRequest -> Promise (IdentityCaptchaResponse |+| IdentityTwoFactorResponse |+| IdentityTokenResponse)
39+ , getSync :: Unit -> Promise SyncResponse
40+ , postCipherCreate :: CipherResponse -> Promise CipherResponse
41+ , putCipher :: CipherResponse -> Promise CipherResponse
42+ , deleteCipher :: String -> Promise Unit
43+ , postTwoFactorEmail :: TwoFactorEmailRequest -> Promise Unit
44+ }
45+
46+type PasswordGeneration =
47+ { generatePassword :: Bridge.PasswordGeneratorConfig -> Promise String
48+ }
49+
50+cryptoFunctionsTypeSha1 = "sha1" :: CryptoFunctionsType
51+
52+cryptoFunctionsTypeSha256 = "sha256" :: CryptoFunctionsType
53+
54+cryptoFunctionsTypeSha512 = "sha512" :: CryptoFunctionsType
55+
56+cryptoFunctionsTypeMd5 = "md5" :: CryptoFunctionsType
57+
58+type CryptoFunctionsType = String
59+
60+type CryptoFunctions =
61+ { hash :: Fn2 String CryptoFunctionsType (Promise Hash)
62+ }
63+
64+newtype Hash = Hash (ArrayBuffer)
65+
66+hashToArray :: Hash -> Array Int
67+hashToArray (Hash buf) =
68+ unsafePerformEffect do
69+ av :: ArrayView Int32 <- AB.whole buf
70+ AB.toArray av
71+
72+arrayToHash :: Array Int -> Hash
73+arrayToHash arr =
74+ unsafePerformEffect do
75+ av :: ArrayView Int32 <- AB.fromArray arr
76+ pure $ Hash $ AB.buffer av
77+
78+instance Eq Hash where
79+ eq a b = eq (hashToArray a) (hashToArray b)
80+
81+instance EncodeJson Hash where
82+ encodeJson = hashToArray >>> encodeJson
83+
84+instance DecodeJson Hash where
85+ decodeJson = decodeJson >>> map arrayToHash
86+
87+type Services =
88+ { crypto :: CryptoService
89+ , getApi :: Urls -> JNullable IdentityTokenResponse -> Promise ApiService
90+ , cryptoFunctions :: CryptoFunctions
91+ , passwordGeneration :: PasswordGeneration
92+ , totpService :: TotpService
93+ }
94+
95+foreign import getServices :: Effect Services
backend/BW/Logic.pursnew file+512
@@ -0,0 +1,512 @@
1+module BW.Logic where
2+
3+import BW
4+import BW.Types
5+import Prelude
6+
7+import Bridge as Bridge
8+import Control.Monad.Error.Class (throwError)
9+import Control.Promise (Promise)
10+import Control.Promise as Promise
11+import Data.EncString as EncString
12+import Data.Function.Uncurried (runFn2, runFn3, runFn4)
13+import Data.JNullable (JNullable, fromJNullable, jnull, nullify)
14+import Data.JNullable as JNullable
15+import Data.JOpt (JOpt(..), fromJOpt)
16+import Data.Maybe (Maybe(..), fromMaybe, maybe)
17+import Data.Newtype (class Newtype, unwrap, wrap)
18+import Data.Number.Format as Number
19+import Data.String as String
20+import Data.SymmetricCryptoKey (SymmetricCryptoKey)
21+import Data.SymmetricCryptoKey as SymmetricCryptoKey
22+import Data.Traversable (traverse)
23+import Data.Undefined.NoProblem (opt, undefined)
24+import Effect (Effect)
25+import Effect.Aff (Aff)
26+import Effect.Aff.Class (class MonadAff, liftAff)
27+import Effect.Class (liftEffect)
28+import Effect.Exception (error)
29+import Effect.Exception as Exc
30+import Effect.Random (random)
31+import Localstorage as Storage
32+import Run (Run)
33+import Run.Reader (Reader, askAt)
34+import Storage (DeviceIDKey(..))
35+import Type.Prelude (Proxy(..))
36+import Untagged.Union (type (|+|))
37+import Web.Storage.Storage (Storage)
38+
39+-- | Creates the master key
40+makePreloginKey
41+ :: forall r
42+ . PreloginResponse
43+ -> Email
44+ -> Password
45+ -> Run
46+ ( crypto :: Reader CryptoService
47+ , effect :: Effect
48+ , aff :: Aff
49+ | r
50+ )
51+ SymmetricCryptoKey
52+makePreloginKey { kdf, kdfIterations, kdfMemory, kdfParallelism } (Email email') password = do
53+ crypto <- askAt (Proxy :: _ "crypto")
54+ let
55+ email = (String.trim >>> String.toLower) email'
56+ liftPromise $ runFn4 crypto.makeKey password email kdf
57+ { iterations: kdfIterations
58+ , memory: kdfMemory
59+ , parallelism: kdfParallelism
60+ }
61+
62+makeDecryptionKey
63+ :: forall r
64+ .
65+ -- | Matser key (prelogin key)
66+ SymmetricCryptoKey
67+ -> EncryptedString
68+ -> Run
69+ ( crypto :: Reader CryptoService
70+ , effect :: Effect
71+ , aff :: Aff
72+ | r
73+ )
74+ SymmetricCryptoKey
75+makeDecryptionKey masterKey str = do
76+ crypto <- askAt (Proxy :: _ "crypto")
77+ let
78+ encryptedKeyString = EncString.fromString str
79+
80+ encType = EncString.encryptionType encryptedKeyString
81+ key <-
82+ if encType == EncString.encryptionTypeAesCbc256_B64 then
83+ liftPromise $ runFn2 crypto.decryptToBytes (EncString.fromString str) masterKey
84+ else if encType == EncString.encryptionTypeAesCbc256_HmacSha256_B64 then do
85+ stretchedMasterKey <- liftPromise $ crypto.stretchKey masterKey
86+ liftPromise $ runFn2 crypto.decryptToBytes (EncString.fromString str) stretchedMasterKey
87+ else
88+ liftEffect $ Exc.throw $ "Unsupported key encryption type: " <> show encType
89+ pure $ SymmetricCryptoKey.fromArrayBuffer key
90+
91+getLogInRequestToken
92+ :: forall r
93+ . { prelogin :: PreloginResponse
94+ , email :: Email
95+ , password :: Password
96+ , captchaResponse :: Maybe String
97+ , secondFactor :: Bridge.Cmd_Login_secondFactor_Maybe
98+ }
99+ -> Run
100+ ( api :: Reader ApiService
101+ , crypto :: Reader CryptoService
102+ , effect :: Effect
103+ , aff :: Aff
104+ , storage :: Reader Storage
105+ | r
106+ )
107+ (IdentityCaptchaResponse |+| IdentityTwoFactorResponse |+| IdentityTokenResponse)
108+getLogInRequestToken
109+ { prelogin
110+ , email
111+ , password
112+ , captchaResponse
113+ , secondFactor: Bridge.Cmd_Login_secondFactor_Maybe secondFactor
114+ } = do
115+ key <- makePreloginKey prelogin email password
116+ crypto <- askAt (Proxy :: _ "crypto")
117+ let
118+ twoFactor =
119+ maybe
120+ { provider: twoFactorProviderTypeEmail
121+ , token: ""
122+ , remember: false
123+ }
124+ ( \(Bridge.Cmd_Login_secondFactor x@{ provider }) ->
125+ x { provider = bridgeToSecondFactorType provider }
126+ )
127+ secondFactor
128+ _localHashedPassword <-
129+ liftPromise
130+ $ runFn3 crypto.hashPassword password key (nullify hashPurposeLocalAuthorization)
131+ StringHash hashedPassword <- liftPromise $ runFn3 crypto.hashPassword password key jnull
132+ deviceId <- getDeviceID
133+ api :: ApiService <- askAt (Proxy :: _ "api")
134+ liftPromise
135+ $ api.postIdentityToken
136+ { email: email
137+ , masterPasswordHash: hashedPassword
138+ , captchaResponse: fromMaybe "" captchaResponse
139+ , twoFactor
140+ , device:
141+ { type: deviceTypeUnknownBrowser
142+ , name: "Ubuntu Touch"
143+ , identifier: deviceId
144+ , pushToken: jnull
145+ }
146+ }
147+
148+bwPasswordStringHash
149+ :: forall r
150+ . PreloginResponse
151+ -> Email
152+ -> Password
153+ -> Run
154+ ( crypto :: Reader CryptoService
155+ , effect :: Effect
156+ , aff :: Aff
157+ | r
158+ )
159+ StringHash
160+bwPasswordStringHash prelogin email password = do
161+ key <- makePreloginKey prelogin email password
162+ crypto <- askAt (Proxy :: _ "crypto")
163+ _localHashedPassword <-
164+ liftPromise
165+ $ runFn3 crypto.hashPassword password key (nullify hashPurposeLocalAuthorization)
166+ liftPromise $ runFn3 crypto.hashPassword password key jnull
167+
168+hashPassword
169+ :: forall r
170+ . Password
171+ -> Run
172+ ( cryptoFunctions :: Reader CryptoFunctions
173+ , aff :: Aff
174+ , effect :: Effect
175+ | r
176+ )
177+ Hash
178+hashPassword (Password password) = do
179+ cryptoFunctions <- askAt (Proxy :: _ "cryptoFunctions")
180+ liftPromise $ runFn2 cryptoFunctions.hash password cryptoFunctionsTypeSha512
181+
182+decrypt
183+ :: forall r
184+ . EncryptedString
185+ -> Run
186+ ( key :: Reader SymmetricCryptoKey
187+ , crypto :: Reader CryptoService
188+ , aff :: Aff
189+ , effect :: Effect
190+ | r
191+ )
192+ String
193+decrypt input = do
194+ crypto <- askAt (Proxy :: _ "crypto")
195+ key <- askAt (Proxy :: _ "key")
196+ liftPromise $ runFn2 crypto.decryptToUtf8 (EncString.fromString input) key
197+
198+encrypt
199+ :: forall r
200+ . String
201+ -> Run
202+ ( key :: Reader SymmetricCryptoKey
203+ , crypto :: Reader CryptoService
204+ , aff :: Aff
205+ , effect :: Effect
206+ | r
207+ )
208+ EncryptedString
209+encrypt input = do
210+ crypto <- askAt (Proxy :: _ "crypto")
211+ key <- askAt (Proxy :: _ "key")
212+ map EncString.toString $ liftPromise $ runFn2 crypto.encrypt input key
213+
214+liftPromise :: forall m a. MonadAff m => Promise a -> m a
215+liftPromise = liftAff <<< Promise.toAff
216+
217+encodeCipher
218+ :: forall r
219+ . Bridge.FullCipher
220+ -> Run
221+ ( key :: Reader SymmetricCryptoKey
222+ , crypto :: Reader CryptoService
223+ , aff :: Aff
224+ , effect :: Effect
225+ | r
226+ )
227+ CipherResponse
228+encodeCipher
229+ (Bridge.FullCipher { name, cipher, id, favorite, reprompt, collectionIds }) = do
230+ let
231+ f :: CipherResponse -> Run _ CipherResponse
232+ f x = case cipher of
233+ Bridge.CardCipher (Bridge.Cipher_CardCipher c) -> do
234+ cardholderName <- encryptNullable c.cardholderName
235+ brand <- encryptNullable c.brand
236+ number <- encryptNullable c.number
237+ expMonth <- encryptNullable c.expMonth
238+ expYear <- encryptNullable c.expYear
239+ code <- encryptNullable c.code
240+ pure
241+ x
242+ { card =
243+ nullify
244+ { cardholderName
245+ , brand
246+ , number
247+ , expMonth
248+ , expYear
249+ , code
250+ }
251+ , type = cipherTypeCard
252+ }
253+ Bridge.IdentityCipher (Bridge.Cipher_IdentityCipher identity) -> do
254+ address1 <- encryptNullable identity.address1
255+ address2 <- encryptNullable identity.address2
256+ address3 <- encryptNullable identity.address3
257+ city <- encryptNullable identity.city
258+ company <- encryptNullable identity.company
259+ country <- encryptNullable identity.country
260+ email <- encryptNullable identity.email
261+ firstName <- encryptNullable identity.firstName
262+ lastName <- encryptNullable identity.lastName
263+ licenseNumber <- encryptNullable identity.licenseNumber
264+ middleName <- encryptNullable identity.middleName
265+ passportNumber <- encryptNullable identity.passportNumber
266+ phone <- encryptNullable identity.phone
267+ postalCode <- encryptNullable identity.postalCode
268+ ssn <- encryptNullable identity.ssn
269+ state <- encryptNullable identity.state
270+ title <- encryptNullable identity.title
271+ username <- encryptNullable identity.username
272+ pure
273+ x
274+ { identity =
275+ nullify
276+ { address1
277+ , address2
278+ , address3
279+ , city
280+ , company
281+ , country
282+ , email
283+ , firstName
284+ , lastName
285+ , licenseNumber
286+ , middleName
287+ , passportNumber
288+ , phone
289+ , postalCode
290+ , ssn
291+ , state
292+ , title
293+ , username
294+ }
295+ , type = cipherTypeIdentity
296+ }
297+ Bridge.LoginCipher (Bridge.Cipher_LoginCipher login) -> do
298+ password <- encryptNullable login.password
299+ uris <-
300+ traverse
301+ ( \uri -> do
302+ uriEnc <- nullify <$> encrypt uri
303+ pure { uri: uriEnc, match: jnull }
304+ )
305+ (unwrap login.uris)
306+ username <- encryptNullable login.username
307+ totp <- encryptNullable login.totp
308+ pure
309+ x
310+ { login =
311+ nullify
312+ { password
313+ , uris: JOpt $ opt uris
314+ , username
315+ , passwordRevisionDate: jnull
316+ , totp: totp
317+ , autofillOnPageLoad: JOpt undefined
318+ }
319+ , type = cipherTypeLogin
320+ }
321+ Bridge.NoteCipher note -> do
322+ encNote <- encrypt note
323+ pure
324+ x
325+ { notes = nullify encNote
326+ , type = cipherTypeSecureNote
327+ }
328+ encName <- encrypt name
329+ f
330+ { id
331+ , organizationId: jnull
332+ , folderId: jnull
333+ , type: 0
334+ , name: encName
335+ , notes: jnull
336+ , fields: jnull
337+ , login: jnull
338+ , card: jnull
339+ , identity: jnull
340+ , secureNote: jnull
341+ , favorite: favorite
342+ , edit: jnull
343+ , viewPassword: jnull
344+ , organizationUseTotp: jnull
345+ , revisionDate: jnull
346+ , attachments: jnull
347+ , passwordHistory: jnull
348+ , collectionIds: nullify $ unwrap collectionIds
349+ , deletedDate: jnull
350+ , reprompt
351+ }
352+
353+-- | Check if the cipher is supported by Warden.
354+supportedCipher :: CipherResponse -> Boolean
355+-- We do not support organizations since that requires managing a separate set of
356+-- encryption keys
357+supportedCipher { organizationId } | Just _ <- JNullable.toMaybe organizationId = false
358+supportedCipher _ = true
359+
360+decodeCipher
361+ :: forall r
362+ . CipherResponse
363+ -> Run
364+ ( key :: Reader SymmetricCryptoKey
365+ , crypto :: Reader CryptoService
366+ , aff :: Aff
367+ , effect :: Effect
368+ | r
369+ )
370+ (Maybe Bridge.FullCipher)
371+decodeCipher cipher | not (supportedCipher cipher) =
372+ pure $ Nothing
373+decodeCipher cipher = do
374+ name <- decrypt cipher.name
375+ cipherType <- case cipher.type of
376+ n
377+ | cipherTypeSecureNote == n -> do
378+ note <- fromJNullable "" <$> (traverse decrypt cipher.notes)
379+ pure $ Bridge.NoteCipher note
380+ n
381+ | cipherTypeLogin == n -> do
382+ case JNullable.toMaybe cipher.login of
383+ Nothing -> liftEffect $ throwError $ error "Login data is missing"
384+ Just login -> do
385+ username <- decryptNullable login.username
386+ password <- decryptNullable login.password
387+ totp <- decryptNullable login.totp
388+ uris <- fromJOpt [] <$>
389+ ((traverse >>> traverse) (_.uri >>> JNullable.toMaybe >>> maybe (pure "") decrypt) login.uris)
390+ pure $ Bridge.LoginCipher
391+ $ Bridge.Cipher_LoginCipher
392+ { username
393+ , password
394+ , uris: wrap uris
395+ , totp
396+ }
397+ n
398+ | cipherTypeCard == n -> do
399+ case JNullable.toMaybe cipher.card of
400+ Nothing -> liftEffect $ throwError $ error "Card data is missing"
401+ Just card -> do
402+ cardholderName <- decryptNullable card.cardholderName
403+ number <- decryptNullable card.number
404+ code <- decryptNullable card.code
405+ brand <- decryptNullable card.brand
406+ expMonth <- decryptNullable card.expMonth
407+ expYear <- decryptNullable card.expYear
408+ pure $ Bridge.CardCipher
409+ $ Bridge.Cipher_CardCipher
410+ { brand, cardholderName, code, expMonth, expYear, number }
411+ n
412+ | cipherTypeIdentity == n -> do
413+ case JNullable.toMaybe cipher.identity of
414+ Nothing -> liftEffect $ throwError $ error "Identity data is missing"
415+ Just identity -> do
416+ firstName <- decryptNullable identity.firstName
417+ middleName <- decryptNullable identity.middleName
418+ lastName <- decryptNullable identity.lastName
419+ address1 <- decryptNullable identity.address1
420+ address2 <- decryptNullable identity.address2
421+ address3 <- decryptNullable identity.address3
422+ city <- decryptNullable identity.city
423+ company <- decryptNullable identity.company
424+ country <- decryptNullable identity.country
425+ email <- decryptNullable identity.email
426+ licenseNumber <- decryptNullable identity.licenseNumber
427+ passportNumber <- decryptNullable identity.passportNumber
428+ phone <- decryptNullable identity.phone
429+ postalCode <- decryptNullable identity.postalCode
430+ ssn <- decryptNullable identity.ssn
431+ state <- decryptNullable identity.state
432+ title <- decryptNullable identity.title
433+ username <- decryptNullable identity.username
434+ pure $ Bridge.IdentityCipher
435+ $ wrap
436+ { firstName
437+ , middleName
438+ , lastName
439+ , address1
440+ , address2
441+ , address3
442+ , city
443+ , company
444+ , country
445+ , email
446+ , licenseNumber
447+ , passportNumber
448+ , phone
449+ , postalCode
450+ , ssn
451+ , state
452+ , title
453+ , username
454+ }
455+ n -> liftEffect $ throwError $ error $ "Unsupported cipher type: " <> show n
456+ pure $ Just
457+ $ wrap
458+ { cipher: cipherType
459+ , name
460+ , id: cipher.id
461+ , favorite: cipher.favorite
462+ , reprompt: cipher.reprompt
463+ , collectionIds: wrap <<< fromJNullable [] $ cipher.collectionIds
464+ }
465+
466+decryptNullable
467+ :: forall x r
468+ . Newtype x (Maybe String)
469+ => JNullable EncryptedString
470+ -> Run
471+ ( key :: Reader SymmetricCryptoKey
472+ , crypto :: Reader CryptoService
473+ , aff :: Aff
474+ , effect :: Effect
475+ | r
476+ )
477+ x
478+decryptNullable x = wrap <<< fromJNullable Nothing <<< map Just <$> (traverse decrypt x)
479+
480+encryptNullable
481+ :: forall x r
482+ . Newtype x (Maybe String)
483+ => x
484+ -> Run
485+ ( key :: Reader SymmetricCryptoKey
486+ , crypto :: Reader CryptoService
487+ , aff :: Aff
488+ , effect :: Effect
489+ | r
490+ )
491+ (JNullable EncryptedString)
492+encryptNullable x = case unwrap x of
493+ Nothing -> pure jnull
494+ Just y -> nullify <$> encrypt y
495+
496+getDeviceID ::
497+ forall r.
498+ Run
499+ ( effect :: Effect
500+ , storage :: Reader Storage
501+ | r
502+ )
503+ String
504+getDeviceID = do
505+ storage <- askAt (Proxy :: _ "storage")
506+ maybeId <- liftEffect $ Storage.get storage DeviceIDKey
507+ case maybeId of
508+ Just id -> pure id
509+ Nothing -> do
510+ id <- map Number.toString $ liftEffect $ random
511+ liftEffect $ Storage.store storage DeviceIDKey id
512+ pure id
backend/BW/Types.pursnew file+726
@@ -0,0 +1,726 @@
1+module BW.Types where
2+
3+import Prelude
4+
5+import Bridge as Bridge
6+import Data.Argonaut (class DecodeJson, class EncodeJson)
7+import Data.Either (Either)
8+import Data.Either as Either
9+import Data.Int as Int
10+import Data.JNullable (JNullable)
11+import Data.JOpt (JOpt)
12+import Data.Maybe (Maybe(..))
13+import Data.Nullable (Nullable)
14+import Data.ShowableJson (ShowableJson)
15+import Data.Timestamp (Timestamp)
16+import Data.Traversable (for)
17+import Data.Tuple.Nested ((/\))
18+import Foreign as Foreign
19+import Literals.Undefined (Undefined)
20+import Type.Prelude (Proxy(..))
21+import Untagged.TypeCheck (class HasRuntimeType)
22+import Untagged.Union (type (|+|))
23+import Untagged.Union as Union
24+
25+newtype EncryptedString = EncryptedString String
26+
27+derive newtype instance Show EncryptedString
28+derive newtype instance Ord EncryptedString
29+derive newtype instance Eq EncryptedString
30+derive newtype instance EncodeJson EncryptedString
31+derive newtype instance DecodeJson EncryptedString
32+
33+kdfPBKDF2_SHA256 = 0 :: KDF
34+kdfArgon2id = 1 :: KDF
35+
36+type KDF = Int
37+
38+type PreloginResponse =
39+ { kdf :: KDF
40+ , kdfIterations :: Int
41+ , kdfMemory :: JNullable Int
42+ , kdfParallelism :: JNullable Int
43+ }
44+
45+type KdfConfig =
46+ { iterations :: Int
47+ , memory :: JNullable Int
48+ , parallelism :: JNullable Int
49+ }
50+
51+type PreloginRequest =
52+ { email :: Email
53+ }
54+
55+type ProfileResponse =
56+ { id :: String
57+ , name :: JNullable String
58+ , email :: String
59+ , emailVerified :: Boolean
60+ , masterPasswordHint :: JNullable String
61+ -- , premiumPersonally :: Boolean
62+ -- , premiumFromOrganization :: Boolean
63+ , culture :: JNullable String
64+ , twoFactorEnabled :: Boolean
65+ , key :: EncryptedString
66+ , privateKey :: EncryptedString
67+ , securityStamp :: JNullable String
68+ , forcePasswordReset :: Boolean
69+ , usesKeyConnector :: Boolean
70+ -- , organizations :: Array ProfileOrganizationResponse
71+ , providers :: Array ProfileProviderResponse
72+ , providerOrganizations :: Array ProfileProviderOrganizationResponse
73+ }
74+
75+type ProfileOrganizationResponse =
76+ { id :: String
77+ , name :: JNullable String
78+ , usePolicies :: JNullable Boolean
79+ , useGroups :: JNullable Boolean
80+ , useDirectory :: JNullable Boolean
81+ , useEvents :: JNullable Boolean
82+ , useTotp :: JNullable Boolean
83+ , use2fa :: JNullable Boolean
84+ , useApi :: JNullable Boolean
85+ , useSso :: JNullable Boolean
86+ , useKeyConnector :: JNullable Boolean
87+ , useResetPassword :: JNullable Boolean
88+ , selfHost :: JNullable Boolean
89+ , usersGetPremium :: JNullable Boolean
90+ , seats :: JNullable Int
91+ , maxCollections :: JNullable Int
92+ , maxStorageGb :: JNullable Int
93+ , key :: JNullable String
94+ , hasPublicAndPrivateKeys :: JNullable Boolean
95+ , status :: JNullable OrganizationUserStatusType
96+ , type :: JNullable OrganizationUserType
97+ , enabled :: JNullable Boolean
98+ , ssoBound :: JNullable Boolean
99+ , identifier :: JNullable String
100+ , permissions :: JNullable PermissionsApi
101+ , resetPasswordEnrolled :: JNullable Boolean
102+ , userId :: JNullable String
103+ , providerId :: JNullable String
104+ , providerName :: JNullable String
105+ , familySponsorshipFriendlyName :: JNullable String
106+ , familySponsorshipAvailable :: JNullable Boolean
107+ , planProductType :: JNullable ProductType
108+ , keyConnectorEnabled :: JNullable Boolean
109+ , keyConnectorUrl :: JNullable String
110+ , familySponsorshipLastSyncDate :: JNullable Timestamp
111+ , familySponsorshipValidUntil :: JNullable Timestamp
112+ , familySponsorshipToDelete :: JNullable Boolean
113+ }
114+
115+organizationUserStatusTypeInvited = 0 :: OrganizationUserStatusType
116+
117+organizationUserStatusTypeAccepted = 0 :: OrganizationUserStatusType
118+
119+organizationUserStatusTypeConfirmed = 0 :: OrganizationUserStatusType
120+
121+type OrganizationUserStatusType = Int
122+
123+organizationUserTypeOwner = 0 :: OrganizationUserType
124+
125+organizationUserTypeAdmin = 1 :: OrganizationUserType
126+
127+organizationUserTypeUser = 2 :: OrganizationUserType
128+
129+organizationUserTypeManager = 3 :: OrganizationUserType
130+
131+organizationUserTypeCustom = 4 :: OrganizationUserType
132+
133+type OrganizationUserType = Int
134+
135+type PermissionsApi =
136+ { accessEventLogs :: Boolean
137+ , accessImportExport :: Boolean
138+ , accessReports :: Boolean
139+ , manageAllCollections :: Boolean
140+ , createNewCollections :: Boolean
141+ , editAnyCollection :: Boolean
142+ , deleteAnyCollection :: Boolean
143+ , manageAssignedCollections :: Boolean
144+ , editAssignedCollections :: Boolean
145+ , deleteAssignedCollections :: Boolean
146+ , manageCiphers :: Boolean
147+ , manageGroups :: Boolean
148+ , manageSso :: Boolean
149+ , managePolicies :: Boolean
150+ , manageUsers :: Boolean
151+ , manageResetPassword :: Boolean
152+ }
153+
154+productTypeFree = 0 :: ProductType
155+
156+productTypeFamilies = 1 :: ProductType
157+
158+productTypeTeams = 2 :: ProductType
159+
160+productTypeEnterprise = 3 :: ProductType
161+
162+type ProductType = Int
163+
164+type ProfileProviderResponse =
165+ { id :: String
166+ , name :: JNullable String
167+ , key :: JNullable String
168+ , status :: JNullable ProviderUserStatusType
169+ , type :: JNullable ProviderUserType
170+ , enabled :: Boolean
171+ , permissions :: PermissionsApi
172+ , userId :: JNullable String
173+ , useEvents :: Boolean
174+ }
175+
176+providerUserStatusTypeInvited = 0 :: ProviderUserStatusType
177+
178+providerUserStatusTypeAccepted = 1 :: ProviderUserStatusType
179+
180+providerUserStatusTypeConfirmed = 2 :: ProviderUserStatusType
181+
182+type ProviderUserStatusType = Int
183+
184+providerUserTypeProviderAdmin = 0 :: ProviderUserType
185+
186+providerUserTypeServiceUser = 1 :: ProviderUserType
187+
188+type ProviderUserType = Int
189+
190+type ProfileProviderOrganizationResponse =
191+ { id :: String
192+ , name :: JNullable String
193+ , usePolicies :: Boolean
194+ , useGroups :: Boolean
195+ , useDirectory :: Boolean
196+ , useEvents :: Boolean
197+ , useTotp :: Boolean
198+ , use2fa :: Boolean
199+ , useApi :: Boolean
200+ , useSso :: Boolean
201+ , useKeyConnector :: Boolean
202+ , useResetPassword :: Boolean
203+ , selfHost :: Boolean
204+ , usersGetPremium :: Boolean
205+ , seats :: Int
206+ , maxCollections :: Int
207+ , maxStorageGb :: JNullable Int
208+ , key :: JNullable String
209+ , hasPublicAndPrivateKeys :: Boolean
210+ , status :: OrganizationUserStatusType
211+ , type :: OrganizationUserType
212+ , enabled :: Boolean
213+ , ssoBound :: Boolean
214+ , identifier :: JNullable String
215+ , permissions :: PermissionsApi
216+ , resetPasswordEnrolled :: Boolean
217+ , userId :: JNullable String
218+ , providerId :: JNullable String
219+ , providerName :: JNullable String
220+ , familySponsorshipFriendlyName :: JNullable String
221+ , familySponsorshipAvailable :: Boolean
222+ , planProductType :: ProductType
223+ , keyConnectorEnabled :: Boolean
224+ , keyConnectorUrl :: JNullable String
225+ , familySponsorshipLastSyncDate :: JNullable Timestamp
226+ , familySponsorshipValidUntil :: JNullable Timestamp
227+ , familySponsorshipToDelete :: JNullable Boolean
228+ }
229+
230+type Urls =
231+ { base :: JNullable String
232+ , webVault :: JNullable String
233+ , api :: JNullable String
234+ , identity :: JNullable String
235+ , icons :: JNullable String
236+ , notifications :: JNullable String
237+ , events :: JNullable String
238+ , keyConnector :: JNullable String
239+ }
240+
241+type PasswordTokenRequest =
242+ { email :: Email
243+ , masterPasswordHash :: String
244+ , captchaResponse :: String
245+ , twoFactor :: TokenRequestTwoFactor
246+ , device :: DeviceRequest
247+ }
248+
249+type DeviceRequest =
250+ { type :: DeviceType
251+ , name :: String
252+ , identifier :: String
253+ , pushToken :: JNullable String
254+ }
255+
256+deviceTypeAndroid = 0 :: DeviceType
257+
258+deviceTypeiOS = 1 :: DeviceType
259+
260+deviceTypeChromeExtension = 2 :: DeviceType
261+
262+deviceTypeFirefoxExtension = 3 :: DeviceType
263+
264+deviceTypeOperaExtension = 4 :: DeviceType
265+
266+deviceTypeEdgeExtension = 5 :: DeviceType
267+
268+deviceTypeWindowsDesktop = 6 :: DeviceType
269+
270+deviceTypeMacOsDesktop = 7 :: DeviceType
271+
272+deviceTypeLinuxDesktop = 8 :: DeviceType
273+
274+deviceTypeChromeBrowser = 9 :: DeviceType
275+
276+deviceTypeFirefoxBrowser = 10 :: DeviceType
277+
278+deviceTypeOperaBrowser = 11 :: DeviceType
279+
280+deviceTypeEdgeBrowser = 12 :: DeviceType
281+
282+deviceTypeIEBrowser = 13 :: DeviceType
283+
284+deviceTypeUnknownBrowser = 14 :: DeviceType
285+
286+deviceTypeAndroidAmazon = 15 :: DeviceType
287+
288+deviceTypeUWP = 16 :: DeviceType
289+
290+deviceTypeSafariBrowser = 17 :: DeviceType
291+
292+deviceTypeVivaldiBrowser = 18 :: DeviceType
293+
294+deviceTypeVivaldiExtension = 19 :: DeviceType
295+
296+deviceTypeSafariExtension = 20 :: DeviceType
297+
298+type DeviceType = Int
299+
300+type TokenRequestTwoFactor =
301+ { provider :: TwoFactorProviderType
302+ , token :: String
303+ , remember :: Boolean
304+ }
305+
306+twoFactorProviderTypeAuthenticator = 0 :: TwoFactorProviderType
307+
308+twoFactorProviderTypeEmail = 1 :: TwoFactorProviderType
309+
310+twoFactorProviderTypeDuo = 2 :: TwoFactorProviderType
311+
312+twoFactorProviderTypeYubikey = 3 :: TwoFactorProviderType
313+
314+twoFactorProviderTypeU2f = 4 :: TwoFactorProviderType
315+
316+twoFactorProviderTypeRemember = 5 :: TwoFactorProviderType
317+
318+twoFactorProviderTypeOrganizationDuo = 6 :: TwoFactorProviderType
319+
320+twoFactorProviderTypeWebAuthn = 7 :: TwoFactorProviderType
321+
322+type TwoFactorProviderType = Int
323+
324+secondFactorTypeToBridge
325+ :: TwoFactorProviderType
326+ -> Maybe Bridge.TwoFactorProviderType
327+secondFactorTypeToBridge x = case x of
328+ n
329+ | n == twoFactorProviderTypeAuthenticator -> Just Bridge.Authenticator
330+ n
331+ | n == twoFactorProviderTypeEmail -> Just Bridge.Email
332+ n
333+ | n == twoFactorProviderTypeDuo -> Just Bridge.Duo
334+ n
335+ | n == twoFactorProviderTypeYubikey -> Just Bridge.Yubikey
336+ n
337+ | n == twoFactorProviderTypeU2f -> Just Bridge.U2f
338+ n
339+ | n == twoFactorProviderTypeRemember -> Just Bridge.Remember
340+ n
341+ | n == twoFactorProviderTypeOrganizationDuo -> Just Bridge.OrganizationDuo
342+ n
343+ | n == twoFactorProviderTypeWebAuthn -> Just Bridge.WebAuthn
344+ _ -> Nothing
345+
346+bridgeToSecondFactorType :: Bridge.TwoFactorProviderType -> TwoFactorProviderType
347+bridgeToSecondFactorType Bridge.Authenticator = twoFactorProviderTypeAuthenticator
348+bridgeToSecondFactorType Bridge.Email = twoFactorProviderTypeEmail
349+bridgeToSecondFactorType Bridge.Duo = twoFactorProviderTypeDuo
350+bridgeToSecondFactorType Bridge.Yubikey = twoFactorProviderTypeYubikey
351+bridgeToSecondFactorType Bridge.U2f = twoFactorProviderTypeU2f
352+bridgeToSecondFactorType Bridge.Remember = twoFactorProviderTypeRemember
353+bridgeToSecondFactorType Bridge.OrganizationDuo = twoFactorProviderTypeOrganizationDuo
354+bridgeToSecondFactorType Bridge.WebAuthn = twoFactorProviderTypeWebAuthn
355+
356+newtype Password = Password String
357+
358+hashPurposeServerAuthorization = 1 :: HashPurpose
359+
360+hashPurposeLocalAuthorization = 2 :: HashPurpose
361+
362+type HashPurpose = Int
363+
364+newtype StringHash = StringHash String
365+
366+newtype AccessToken = AccessToken String
367+
368+derive newtype instance Show AccessToken
369+derive newtype instance Eq AccessToken
370+derive newtype instance Ord AccessToken
371+derive newtype instance EncodeJson AccessToken
372+derive newtype instance DecodeJson AccessToken
373+
374+newtype RefreshToken = RefreshToken String
375+
376+derive newtype instance Show RefreshToken
377+derive newtype instance Eq RefreshToken
378+derive newtype instance Ord RefreshToken
379+derive newtype instance EncodeJson RefreshToken
380+derive newtype instance DecodeJson RefreshToken
381+
382+type IdentityCaptchaResponse =
383+ { siteKey :: String
384+ }
385+
386+type IdentityTokenResponse =
387+ { accessToken :: AccessToken
388+ , expiresIn :: Int
389+ , refreshToken :: RefreshToken
390+ , tokenType :: String
391+ , resetMasterPassword :: Boolean
392+ , privateKey :: EncryptedString
393+ , key :: EncryptedString
394+ , twoFactorToken :: JNullable String
395+ , kdf :: KDF
396+ , kdfIterations :: Int
397+ , forcePasswordReset :: JNullable Boolean
398+ , apiUseKeyConnector :: JNullable Boolean
399+ , keyConnectorUrl :: JNullable String
400+ }
401+
402+newtype TwoFactorProviderTypes = TwoFactorProviderTypes (Array (Int |+| String))
403+
404+instance HasRuntimeType TwoFactorProviderTypes where
405+ hasRuntimeType Proxy = Foreign.isArray
406+
407+fromTwoFactorProviderType :: TwoFactorProviderTypes -> Either String (Array Bridge.TwoFactorProviderType)
408+fromTwoFactorProviderType (TwoFactorProviderTypes xs) =
409+ for xs $ \rawProvider -> do
410+ providerInt <- Union.reduce (Either.Right /\ (\x -> Either.note x $ Int.fromString x)) rawProvider
411+ Either.note (show providerInt) $ secondFactorTypeToBridge providerInt
412+
413+type IdentityTwoFactorResponse =
414+ { twoFactorProviders :: TwoFactorProviderTypes
415+ -- it is a Map type and untaged unions gets confused
416+ -- , twoFactorProviders2 :: Object (Object String)
417+ , captchaToken :: String |+| Undefined
418+ }
419+
420+newtype Email = Email String
421+
422+type SyncResponse =
423+ { profile :: ProfileResponse
424+ , folders :: Array FolderResponse
425+ , collections :: Array CollectionDetailsResponse
426+ , ciphers :: Array CipherResponse
427+ , domains :: JNullable DomainsResponse
428+ , policies :: JNullable (Array PolicyResponse)
429+ , sends :: Array SendResponse
430+ }
431+
432+type FolderResponse =
433+ { id :: String
434+ , name :: JNullable String
435+ , revisionDate :: JNullable String
436+ }
437+
438+type CollectionDetailsResponse =
439+ { id :: String
440+ , organizationId :: JNullable String
441+ , name :: JNullable String
442+ , externalId :: JNullable String
443+ , readOnly :: Boolean
444+ }
445+
446+type CipherId = String
447+
448+type CipherResponse =
449+ { id :: CipherId
450+ , organizationId :: JNullable String
451+ , folderId :: JNullable String
452+ , type :: CipherType
453+ , name :: EncryptedString
454+ , notes :: JNullable EncryptedString
455+ , fields :: JNullable (Array FieldApi)
456+ , login :: JNullable LoginApi
457+ , card :: JNullable CardApi
458+ , identity :: JNullable IdentityApi
459+ , secureNote :: JNullable SecureNoteApi
460+ , favorite :: Boolean
461+ , edit :: JNullable Boolean
462+ , viewPassword :: JNullable Boolean
463+ , organizationUseTotp :: JNullable Boolean
464+ , revisionDate :: JNullable Timestamp
465+ , attachments :: JNullable (Array AttachmentResponse)
466+ , passwordHistory :: JNullable (Array PasswordHistoryResponse)
467+ , collectionIds :: JNullable (Array String)
468+ , deletedDate :: JNullable String
469+ , reprompt :: CipherRepromptType
470+ }
471+
472+cipherTypeLogin = 1 :: CipherType
473+
474+cipherTypeSecureNote = 2 :: CipherType
475+
476+cipherTypeCard = 3 :: CipherType
477+
478+cipherTypeIdentity = 4 :: CipherType
479+
480+type CipherType = Int
481+
482+type FieldApi =
483+ { name :: JNullable String
484+ , value :: JNullable String
485+ , type :: FieldType
486+ , linkedId :: JNullable LinkedIdType
487+ }
488+
489+fieldTypeText = 0 :: FieldType
490+
491+fieldTypeHidden = 1 :: FieldType
492+
493+fieldTypeBoolean = 2 :: FieldType
494+
495+fieldTypeLinked = 3 :: FieldType
496+
497+type FieldType = Int
498+
499+linkedIdTypeLoginLinkedIdUsername = 100 :: LinkedIdType
500+
501+linkedIdTypeLoginLinkedIdPassword = 101 :: LinkedIdType
502+
503+linkedIdTypeCardLinkedIdCardholderName = 300 :: LinkedIdType
504+
505+linkedIdTypeCardLinkedIdExpMonth = 301 :: LinkedIdType
506+
507+linkedIdTypeCardLinkedIdExpYear = 302 :: LinkedIdType
508+
509+linkedIdTypeCardLinkedIdCode = 303 :: LinkedIdType
510+
511+linkedIdTypeCardLinkedIdBrand = 304 :: LinkedIdType
512+
513+linkedIdTypeCardLinkedIdNumber = 305 :: LinkedIdType
514+
515+linkedIdTypeIdentityLinkedIdTitle = 400 :: LinkedIdType
516+
517+linkedIdTypeIdentityLinkedIdMiddleName = 401 :: LinkedIdType
518+
519+linkedIdTypeIdentityLinkedIdAddress1 = 402 :: LinkedIdType
520+
521+linkedIdTypeIdentityLinkedIdAddress2 = 403 :: LinkedIdType
522+
523+linkedIdTypeIdentityLinkedIdAddress3 = 404 :: LinkedIdType
524+
525+linkedIdTypeIdentityLinkedIdCity = 405 :: LinkedIdType
526+
527+linkedIdTypeIdentityLinkedIdState = 406 :: LinkedIdType
528+
529+linkedIdTypeIdentityLinkedIdPostalCode = 407 :: LinkedIdType
530+
531+linkedIdTypeIdentityLinkedIdCountry = 408 :: LinkedIdType
532+
533+linkedIdTypeIdentityLinkedIdCompany = 409 :: LinkedIdType
534+
535+linkedIdTypeIdentityLinkedIdEmail = 410 :: LinkedIdType
536+
537+linkedIdTypeIdentityLinkedIdPhone = 411 :: LinkedIdType
538+
539+linkedIdTypeIdentityLinkedIdSsn = 412 :: LinkedIdType
540+
541+linkedIdTypeIdentityLinkedIdUsername = 413 :: LinkedIdType
542+
543+linkedIdTypeIdentityLinkedIdPassportNumber = 414 :: LinkedIdType
544+
545+linkedIdTypeIdentityLinkedIdLicenseNumber = 415 :: LinkedIdType
546+
547+linkedIdTypeIdentityLinkedIdFirstName = 416 :: LinkedIdType
548+
549+linkedIdTypeIdentityLinkedIdLastName = 417 :: LinkedIdType
550+
551+linkedIdTypeIdentityLinkedIdFullName = 418 :: LinkedIdType
552+
553+type LinkedIdType = Int
554+
555+type LoginApi =
556+ { uris :: JOpt (Array LoginUriApi)
557+ , username :: JNullable EncryptedString
558+ , password :: JNullable EncryptedString
559+ , passwordRevisionDate :: JNullable String
560+ , totp :: JNullable EncryptedString
561+ -- This thing is undefined in some cases for some reson. Just ignoring it
562+ , autofillOnPageLoad :: JOpt (JNullable Boolean)
563+ }
564+
565+type LoginUriApi =
566+ { uri :: JNullable EncryptedString
567+ , match :: JNullable UriMatchType
568+ }
569+
570+uriMatchTypeDomain = 0 :: UriMatchType
571+
572+uriMatchTypeHost = 1 :: UriMatchType
573+
574+uriMatchTypeStartsWith = 2 :: UriMatchType
575+
576+uriMatchTypeExact = 3 :: UriMatchType
577+
578+uriMatchTypeRegularExpression = 4 :: UriMatchType
579+
580+uriMatchTypeNever = 5 :: UriMatchType
581+
582+type UriMatchType = Int
583+
584+type CardApi =
585+ { cardholderName :: JNullable EncryptedString
586+ , brand :: JNullable EncryptedString
587+ , number :: JNullable EncryptedString
588+ , expMonth :: JNullable EncryptedString
589+ , expYear :: JNullable EncryptedString
590+ , code :: JNullable EncryptedString
591+ }
592+
593+type IdentityApi =
594+ { title :: JNullable EncryptedString
595+ , firstName :: JNullable EncryptedString
596+ , middleName :: JNullable EncryptedString
597+ , lastName :: JNullable EncryptedString
598+ , address1 :: JNullable EncryptedString
599+ , address2 :: JNullable EncryptedString
600+ , address3 :: JNullable EncryptedString
601+ , city :: JNullable EncryptedString
602+ , state :: JNullable EncryptedString
603+ , postalCode :: JNullable EncryptedString
604+ , country :: JNullable EncryptedString
605+ , company :: JNullable EncryptedString
606+ , email :: JNullable EncryptedString
607+ , phone :: JNullable EncryptedString
608+ , ssn :: JNullable EncryptedString
609+ , username :: JNullable EncryptedString
610+ , passportNumber :: JNullable EncryptedString
611+ , licenseNumber :: JNullable EncryptedString
612+ }
613+
614+secureNoteTypeGeneric = 0 :: SecureNoteType
615+
616+type SecureNoteType = Int
617+
618+type SecureNoteApi =
619+ {
620+ -- type :: SecureNoteType
621+ }
622+
623+type AttachmentResponse =
624+ { id :: String
625+ , url :: JNullable String
626+ , fileName :: JNullable String
627+ , key :: JNullable String
628+ , size :: JNullable String
629+ , sizeName :: JNullable String
630+ }
631+
632+type PasswordHistoryResponse =
633+ { password :: String
634+ , lastUsedDate :: JNullable String
635+ }
636+
637+cipherRepromptTypeNone = 0 :: CipherRepromptType
638+
639+cipherRepromptTypePassword = 1 :: CipherRepromptType
640+
641+type CipherRepromptType = Int
642+
643+type DomainsResponse =
644+ { equivalentDomains :: Array (Array String)
645+ , globalEquivalentDomains :: Array GlobalDomainResponse
646+ }
647+
648+type GlobalDomainResponse =
649+ { type :: Int
650+ , domains :: Array String
651+ , excluded :: Boolean
652+ }
653+
654+type PolicyResponse =
655+ { id :: String
656+ , organizationId :: JNullable String
657+ , type :: PolicyType
658+ , data :: ShowableJson
659+ , enabled :: Boolean
660+ }
661+
662+policyTypeTwoFactorAuthentication = 0 :: PolicyType -- Requires users to have 2fa enabled
663+
664+policyTypeMasterPassword = 1 :: PolicyType -- Sets minimum requirements for master password complexity
665+
666+policyTypePasswordGenerator = 2 :: PolicyType -- Sets minimum requirements/default type for generated passwords/passphrases
667+
668+policyTypeSingleOrg = 3 :: PolicyType -- Allows users to only be apart of one organization
669+
670+policyTypeRequireSso = 4 :: PolicyType -- Requires users to authenticate with SSO
671+
672+policyTypePersonalOwnership = 5 :: PolicyType -- Disables personal vault ownership for adding/cloning items
673+
674+policyTypeDisableSend = 6 :: PolicyType -- Disables the ability to create and edit Bitwarden Sends
675+
676+policyTypeSendOptions = 7 :: PolicyType -- Sets restrictions or defaults for Bitwarden Sends
677+
678+policyTypeResetPassword = 8 :: PolicyType -- Allows orgs to use reset password : also can enable auto-enrollment during invite flow
679+
680+policyTypeMaximumVaultTimeout = 9 :: PolicyType -- Sets the maximum allowed vault timeout
681+
682+policyTypeDisablePersonalVaultExport = 10 :: PolicyType -- Disable personal vault export
683+
684+type PolicyType = Int
685+
686+type SendResponse =
687+ { id :: String
688+ , accessId :: JNullable String
689+ , type :: SendType
690+ , name :: JNullable String
691+ , notes :: JNullable String
692+ , file :: JNullable SendFileApi
693+ , text :: JNullable SendTextApi
694+ , key :: JNullable String
695+ , maxAccessCount :: JNullable Int
696+ , accessCount :: JNullable Int
697+ , revisionDate :: JNullable String
698+ , expirationDate :: JNullable String
699+ , deletionDate :: JNullable String
700+ , password :: JNullable String
701+ , disable :: Boolean
702+ , hideEmail :: Boolean
703+ }
704+
705+sendTypeText = 0 :: SendType
706+
707+sendTypeFile = 1 :: SendType
708+
709+type SendType = Int
710+
711+type SendFileApi =
712+ { id :: String
713+ , fileName :: JNullable String
714+ , size :: JNullable String
715+ , sizeName :: JNullable String
716+ }
717+
718+type SendTextApi =
719+ { text :: JNullable String
720+ , hidden :: Boolean
721+ }
722+
723+type TwoFactorEmailRequest =
724+ { email :: Email
725+ , masterPasswordHash :: StringHash
726+ }
backend/Bridge.purs+632−3
@@ -12,13 +12,492 @@ import Data.Newtype (class Newtype)
12
12
13import Prelude
13import Prelude
14
14
15+newtype Cipher_CardCipher_brand_Maybe =
16+ Cipher_CardCipher_brand_Maybe (Maybe String)
17+
18+derive instance newtypeCipher_CardCipher_brand_Maybe :: Newtype Cipher_CardCipher_brand_Maybe _
19+instance encodeJsonCipher_CardCipher_brand_Maybe :: EncodeJson Cipher_CardCipher_brand_Maybe where
20+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
21+instance decodeJsonCipher_CardCipher_brand_Maybe :: DecodeJson Cipher_CardCipher_brand_Maybe where
22+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
23+derive instance genericCipher_CardCipher_brand_Maybe :: Generic Cipher_CardCipher_brand_Maybe _
24+derive instance eqCipher_CardCipher_brand_Maybe :: Eq Cipher_CardCipher_brand_Maybe
25+derive instance ordCipher_CardCipher_brand_Maybe :: Ord Cipher_CardCipher_brand_Maybe
26+
27+newtype Cipher_CardCipher_cardholderName_Maybe =
28+ Cipher_CardCipher_cardholderName_Maybe (Maybe String)
29+
30+derive instance newtypeCipher_CardCipher_cardholderName_Maybe :: Newtype Cipher_CardCipher_cardholderName_Maybe _
31+instance encodeJsonCipher_CardCipher_cardholderName_Maybe :: EncodeJson Cipher_CardCipher_cardholderName_Maybe where
32+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
33+instance decodeJsonCipher_CardCipher_cardholderName_Maybe :: DecodeJson Cipher_CardCipher_cardholderName_Maybe where
34+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
35+derive instance genericCipher_CardCipher_cardholderName_Maybe :: Generic Cipher_CardCipher_cardholderName_Maybe _
36+derive instance eqCipher_CardCipher_cardholderName_Maybe :: Eq Cipher_CardCipher_cardholderName_Maybe
37+derive instance ordCipher_CardCipher_cardholderName_Maybe :: Ord Cipher_CardCipher_cardholderName_Maybe
38+
39+newtype Cipher_CardCipher_code_Maybe =
40+ Cipher_CardCipher_code_Maybe (Maybe String)
41+
42+derive instance newtypeCipher_CardCipher_code_Maybe :: Newtype Cipher_CardCipher_code_Maybe _
43+instance encodeJsonCipher_CardCipher_code_Maybe :: EncodeJson Cipher_CardCipher_code_Maybe where
44+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
45+instance decodeJsonCipher_CardCipher_code_Maybe :: DecodeJson Cipher_CardCipher_code_Maybe where
46+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
47+derive instance genericCipher_CardCipher_code_Maybe :: Generic Cipher_CardCipher_code_Maybe _
48+derive instance eqCipher_CardCipher_code_Maybe :: Eq Cipher_CardCipher_code_Maybe
49+derive instance ordCipher_CardCipher_code_Maybe :: Ord Cipher_CardCipher_code_Maybe
50+
51+newtype Cipher_CardCipher_expMonth_Maybe =
52+ Cipher_CardCipher_expMonth_Maybe (Maybe String)
53+
54+derive instance newtypeCipher_CardCipher_expMonth_Maybe :: Newtype Cipher_CardCipher_expMonth_Maybe _
55+instance encodeJsonCipher_CardCipher_expMonth_Maybe :: EncodeJson Cipher_CardCipher_expMonth_Maybe where
56+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
57+instance decodeJsonCipher_CardCipher_expMonth_Maybe :: DecodeJson Cipher_CardCipher_expMonth_Maybe where
58+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
59+derive instance genericCipher_CardCipher_expMonth_Maybe :: Generic Cipher_CardCipher_expMonth_Maybe _
60+derive instance eqCipher_CardCipher_expMonth_Maybe :: Eq Cipher_CardCipher_expMonth_Maybe
61+derive instance ordCipher_CardCipher_expMonth_Maybe :: Ord Cipher_CardCipher_expMonth_Maybe
62+
63+newtype Cipher_CardCipher_expYear_Maybe =
64+ Cipher_CardCipher_expYear_Maybe (Maybe String)
65+
66+derive instance newtypeCipher_CardCipher_expYear_Maybe :: Newtype Cipher_CardCipher_expYear_Maybe _
67+instance encodeJsonCipher_CardCipher_expYear_Maybe :: EncodeJson Cipher_CardCipher_expYear_Maybe where
68+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
69+instance decodeJsonCipher_CardCipher_expYear_Maybe :: DecodeJson Cipher_CardCipher_expYear_Maybe where
70+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
71+derive instance genericCipher_CardCipher_expYear_Maybe :: Generic Cipher_CardCipher_expYear_Maybe _
72+derive instance eqCipher_CardCipher_expYear_Maybe :: Eq Cipher_CardCipher_expYear_Maybe
73+derive instance ordCipher_CardCipher_expYear_Maybe :: Ord Cipher_CardCipher_expYear_Maybe
74+
75+newtype Cipher_CardCipher_number_Maybe =
76+ Cipher_CardCipher_number_Maybe (Maybe String)
77+
78+derive instance newtypeCipher_CardCipher_number_Maybe :: Newtype Cipher_CardCipher_number_Maybe _
79+instance encodeJsonCipher_CardCipher_number_Maybe :: EncodeJson Cipher_CardCipher_number_Maybe where
80+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
81+instance decodeJsonCipher_CardCipher_number_Maybe :: DecodeJson Cipher_CardCipher_number_Maybe where
82+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
83+derive instance genericCipher_CardCipher_number_Maybe :: Generic Cipher_CardCipher_number_Maybe _
84+derive instance eqCipher_CardCipher_number_Maybe :: Eq Cipher_CardCipher_number_Maybe
85+derive instance ordCipher_CardCipher_number_Maybe :: Ord Cipher_CardCipher_number_Maybe
86+
87+newtype Cipher_CardCipher =
88+ Cipher_CardCipher {
89+ brand :: Cipher_CardCipher_brand_Maybe
90+ , cardholderName :: Cipher_CardCipher_cardholderName_Maybe
91+ , code :: Cipher_CardCipher_code_Maybe
92+ , expMonth :: Cipher_CardCipher_expMonth_Maybe
93+ , expYear :: Cipher_CardCipher_expYear_Maybe
94+ , number :: Cipher_CardCipher_number_Maybe
95+ }
96+
97+derive instance newtypeCipher_CardCipher :: Newtype Cipher_CardCipher _
98+instance encodeJsonCipher_CardCipher :: EncodeJson Cipher_CardCipher where
99+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
100+instance decodeJsonCipher_CardCipher :: DecodeJson Cipher_CardCipher where
101+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
102+derive instance genericCipher_CardCipher :: Generic Cipher_CardCipher _
103+derive instance eqCipher_CardCipher :: Eq Cipher_CardCipher
104+derive instance ordCipher_CardCipher :: Ord Cipher_CardCipher
105+
106+newtype Cipher_IdentityCipher_address1_Maybe =
107+ Cipher_IdentityCipher_address1_Maybe (Maybe String)
108+
109+derive instance newtypeCipher_IdentityCipher_address1_Maybe :: Newtype Cipher_IdentityCipher_address1_Maybe _
110+instance encodeJsonCipher_IdentityCipher_address1_Maybe :: EncodeJson Cipher_IdentityCipher_address1_Maybe where
111+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
112+instance decodeJsonCipher_IdentityCipher_address1_Maybe :: DecodeJson Cipher_IdentityCipher_address1_Maybe where
113+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
114+derive instance genericCipher_IdentityCipher_address1_Maybe :: Generic Cipher_IdentityCipher_address1_Maybe _
115+derive instance eqCipher_IdentityCipher_address1_Maybe :: Eq Cipher_IdentityCipher_address1_Maybe
116+derive instance ordCipher_IdentityCipher_address1_Maybe :: Ord Cipher_IdentityCipher_address1_Maybe
117+
118+newtype Cipher_IdentityCipher_address2_Maybe =
119+ Cipher_IdentityCipher_address2_Maybe (Maybe String)
120+
121+derive instance newtypeCipher_IdentityCipher_address2_Maybe :: Newtype Cipher_IdentityCipher_address2_Maybe _
122+instance encodeJsonCipher_IdentityCipher_address2_Maybe :: EncodeJson Cipher_IdentityCipher_address2_Maybe where
123+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
124+instance decodeJsonCipher_IdentityCipher_address2_Maybe :: DecodeJson Cipher_IdentityCipher_address2_Maybe where
125+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
126+derive instance genericCipher_IdentityCipher_address2_Maybe :: Generic Cipher_IdentityCipher_address2_Maybe _
127+derive instance eqCipher_IdentityCipher_address2_Maybe :: Eq Cipher_IdentityCipher_address2_Maybe
128+derive instance ordCipher_IdentityCipher_address2_Maybe :: Ord Cipher_IdentityCipher_address2_Maybe
129+
130+newtype Cipher_IdentityCipher_address3_Maybe =
131+ Cipher_IdentityCipher_address3_Maybe (Maybe String)
132+
133+derive instance newtypeCipher_IdentityCipher_address3_Maybe :: Newtype Cipher_IdentityCipher_address3_Maybe _
134+instance encodeJsonCipher_IdentityCipher_address3_Maybe :: EncodeJson Cipher_IdentityCipher_address3_Maybe where
135+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
136+instance decodeJsonCipher_IdentityCipher_address3_Maybe :: DecodeJson Cipher_IdentityCipher_address3_Maybe where
137+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
138+derive instance genericCipher_IdentityCipher_address3_Maybe :: Generic Cipher_IdentityCipher_address3_Maybe _
139+derive instance eqCipher_IdentityCipher_address3_Maybe :: Eq Cipher_IdentityCipher_address3_Maybe
140+derive instance ordCipher_IdentityCipher_address3_Maybe :: Ord Cipher_IdentityCipher_address3_Maybe
141+
142+newtype Cipher_IdentityCipher_city_Maybe =
143+ Cipher_IdentityCipher_city_Maybe (Maybe String)
144+
145+derive instance newtypeCipher_IdentityCipher_city_Maybe :: Newtype Cipher_IdentityCipher_city_Maybe _
146+instance encodeJsonCipher_IdentityCipher_city_Maybe :: EncodeJson Cipher_IdentityCipher_city_Maybe where
147+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
148+instance decodeJsonCipher_IdentityCipher_city_Maybe :: DecodeJson Cipher_IdentityCipher_city_Maybe where
149+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
150+derive instance genericCipher_IdentityCipher_city_Maybe :: Generic Cipher_IdentityCipher_city_Maybe _
151+derive instance eqCipher_IdentityCipher_city_Maybe :: Eq Cipher_IdentityCipher_city_Maybe
152+derive instance ordCipher_IdentityCipher_city_Maybe :: Ord Cipher_IdentityCipher_city_Maybe
153+
154+newtype Cipher_IdentityCipher_company_Maybe =
155+ Cipher_IdentityCipher_company_Maybe (Maybe String)
156+
157+derive instance newtypeCipher_IdentityCipher_company_Maybe :: Newtype Cipher_IdentityCipher_company_Maybe _
158+instance encodeJsonCipher_IdentityCipher_company_Maybe :: EncodeJson Cipher_IdentityCipher_company_Maybe where
159+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
160+instance decodeJsonCipher_IdentityCipher_company_Maybe :: DecodeJson Cipher_IdentityCipher_company_Maybe where
161+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
162+derive instance genericCipher_IdentityCipher_company_Maybe :: Generic Cipher_IdentityCipher_company_Maybe _
163+derive instance eqCipher_IdentityCipher_company_Maybe :: Eq Cipher_IdentityCipher_company_Maybe
164+derive instance ordCipher_IdentityCipher_company_Maybe :: Ord Cipher_IdentityCipher_company_Maybe
165+
166+newtype Cipher_IdentityCipher_country_Maybe =
167+ Cipher_IdentityCipher_country_Maybe (Maybe String)
168+
169+derive instance newtypeCipher_IdentityCipher_country_Maybe :: Newtype Cipher_IdentityCipher_country_Maybe _
170+instance encodeJsonCipher_IdentityCipher_country_Maybe :: EncodeJson Cipher_IdentityCipher_country_Maybe where
171+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
172+instance decodeJsonCipher_IdentityCipher_country_Maybe :: DecodeJson Cipher_IdentityCipher_country_Maybe where
173+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
174+derive instance genericCipher_IdentityCipher_country_Maybe :: Generic Cipher_IdentityCipher_country_Maybe _
175+derive instance eqCipher_IdentityCipher_country_Maybe :: Eq Cipher_IdentityCipher_country_Maybe
176+derive instance ordCipher_IdentityCipher_country_Maybe :: Ord Cipher_IdentityCipher_country_Maybe
177+
178+newtype Cipher_IdentityCipher_email_Maybe =
179+ Cipher_IdentityCipher_email_Maybe (Maybe String)
180+
181+derive instance newtypeCipher_IdentityCipher_email_Maybe :: Newtype Cipher_IdentityCipher_email_Maybe _
182+instance encodeJsonCipher_IdentityCipher_email_Maybe :: EncodeJson Cipher_IdentityCipher_email_Maybe where
183+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
184+instance decodeJsonCipher_IdentityCipher_email_Maybe :: DecodeJson Cipher_IdentityCipher_email_Maybe where
185+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
186+derive instance genericCipher_IdentityCipher_email_Maybe :: Generic Cipher_IdentityCipher_email_Maybe _
187+derive instance eqCipher_IdentityCipher_email_Maybe :: Eq Cipher_IdentityCipher_email_Maybe
188+derive instance ordCipher_IdentityCipher_email_Maybe :: Ord Cipher_IdentityCipher_email_Maybe
189+
190+newtype Cipher_IdentityCipher_firstName_Maybe =
191+ Cipher_IdentityCipher_firstName_Maybe (Maybe String)
192+
193+derive instance newtypeCipher_IdentityCipher_firstName_Maybe :: Newtype Cipher_IdentityCipher_firstName_Maybe _
194+instance encodeJsonCipher_IdentityCipher_firstName_Maybe :: EncodeJson Cipher_IdentityCipher_firstName_Maybe where
195+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
196+instance decodeJsonCipher_IdentityCipher_firstName_Maybe :: DecodeJson Cipher_IdentityCipher_firstName_Maybe where
197+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
198+derive instance genericCipher_IdentityCipher_firstName_Maybe :: Generic Cipher_IdentityCipher_firstName_Maybe _
199+derive instance eqCipher_IdentityCipher_firstName_Maybe :: Eq Cipher_IdentityCipher_firstName_Maybe
200+derive instance ordCipher_IdentityCipher_firstName_Maybe :: Ord Cipher_IdentityCipher_firstName_Maybe
201+
202+newtype Cipher_IdentityCipher_lastName_Maybe =
203+ Cipher_IdentityCipher_lastName_Maybe (Maybe String)
204+
205+derive instance newtypeCipher_IdentityCipher_lastName_Maybe :: Newtype Cipher_IdentityCipher_lastName_Maybe _
206+instance encodeJsonCipher_IdentityCipher_lastName_Maybe :: EncodeJson Cipher_IdentityCipher_lastName_Maybe where
207+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
208+instance decodeJsonCipher_IdentityCipher_lastName_Maybe :: DecodeJson Cipher_IdentityCipher_lastName_Maybe where
209+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
210+derive instance genericCipher_IdentityCipher_lastName_Maybe :: Generic Cipher_IdentityCipher_lastName_Maybe _
211+derive instance eqCipher_IdentityCipher_lastName_Maybe :: Eq Cipher_IdentityCipher_lastName_Maybe
212+derive instance ordCipher_IdentityCipher_lastName_Maybe :: Ord Cipher_IdentityCipher_lastName_Maybe
213+
214+newtype Cipher_IdentityCipher_licenseNumber_Maybe =
215+ Cipher_IdentityCipher_licenseNumber_Maybe (Maybe String)
216+
217+derive instance newtypeCipher_IdentityCipher_licenseNumber_Maybe :: Newtype Cipher_IdentityCipher_licenseNumber_Maybe _
218+instance encodeJsonCipher_IdentityCipher_licenseNumber_Maybe :: EncodeJson Cipher_IdentityCipher_licenseNumber_Maybe where
219+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
220+instance decodeJsonCipher_IdentityCipher_licenseNumber_Maybe :: DecodeJson Cipher_IdentityCipher_licenseNumber_Maybe where
221+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
222+derive instance genericCipher_IdentityCipher_licenseNumber_Maybe :: Generic Cipher_IdentityCipher_licenseNumber_Maybe _
223+derive instance eqCipher_IdentityCipher_licenseNumber_Maybe :: Eq Cipher_IdentityCipher_licenseNumber_Maybe
224+derive instance ordCipher_IdentityCipher_licenseNumber_Maybe :: Ord Cipher_IdentityCipher_licenseNumber_Maybe
225+
226+newtype Cipher_IdentityCipher_middleName_Maybe =
227+ Cipher_IdentityCipher_middleName_Maybe (Maybe String)
228+
229+derive instance newtypeCipher_IdentityCipher_middleName_Maybe :: Newtype Cipher_IdentityCipher_middleName_Maybe _
230+instance encodeJsonCipher_IdentityCipher_middleName_Maybe :: EncodeJson Cipher_IdentityCipher_middleName_Maybe where
231+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
232+instance decodeJsonCipher_IdentityCipher_middleName_Maybe :: DecodeJson Cipher_IdentityCipher_middleName_Maybe where
233+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
234+derive instance genericCipher_IdentityCipher_middleName_Maybe :: Generic Cipher_IdentityCipher_middleName_Maybe _
235+derive instance eqCipher_IdentityCipher_middleName_Maybe :: Eq Cipher_IdentityCipher_middleName_Maybe
236+derive instance ordCipher_IdentityCipher_middleName_Maybe :: Ord Cipher_IdentityCipher_middleName_Maybe
237+
238+newtype Cipher_IdentityCipher_passportNumber_Maybe =
239+ Cipher_IdentityCipher_passportNumber_Maybe (Maybe String)
240+
241+derive instance newtypeCipher_IdentityCipher_passportNumber_Maybe :: Newtype Cipher_IdentityCipher_passportNumber_Maybe _
242+instance encodeJsonCipher_IdentityCipher_passportNumber_Maybe :: EncodeJson Cipher_IdentityCipher_passportNumber_Maybe where
243+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
244+instance decodeJsonCipher_IdentityCipher_passportNumber_Maybe :: DecodeJson Cipher_IdentityCipher_passportNumber_Maybe where
245+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
246+derive instance genericCipher_IdentityCipher_passportNumber_Maybe :: Generic Cipher_IdentityCipher_passportNumber_Maybe _
247+derive instance eqCipher_IdentityCipher_passportNumber_Maybe :: Eq Cipher_IdentityCipher_passportNumber_Maybe
248+derive instance ordCipher_IdentityCipher_passportNumber_Maybe :: Ord Cipher_IdentityCipher_passportNumber_Maybe
249+
250+newtype Cipher_IdentityCipher_phone_Maybe =
251+ Cipher_IdentityCipher_phone_Maybe (Maybe String)
252+
253+derive instance newtypeCipher_IdentityCipher_phone_Maybe :: Newtype Cipher_IdentityCipher_phone_Maybe _
254+instance encodeJsonCipher_IdentityCipher_phone_Maybe :: EncodeJson Cipher_IdentityCipher_phone_Maybe where
255+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
256+instance decodeJsonCipher_IdentityCipher_phone_Maybe :: DecodeJson Cipher_IdentityCipher_phone_Maybe where
257+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
258+derive instance genericCipher_IdentityCipher_phone_Maybe :: Generic Cipher_IdentityCipher_phone_Maybe _
259+derive instance eqCipher_IdentityCipher_phone_Maybe :: Eq Cipher_IdentityCipher_phone_Maybe
260+derive instance ordCipher_IdentityCipher_phone_Maybe :: Ord Cipher_IdentityCipher_phone_Maybe
261+
262+newtype Cipher_IdentityCipher_postalCode_Maybe =
263+ Cipher_IdentityCipher_postalCode_Maybe (Maybe String)
264+
265+derive instance newtypeCipher_IdentityCipher_postalCode_Maybe :: Newtype Cipher_IdentityCipher_postalCode_Maybe _
266+instance encodeJsonCipher_IdentityCipher_postalCode_Maybe :: EncodeJson Cipher_IdentityCipher_postalCode_Maybe where
267+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
268+instance decodeJsonCipher_IdentityCipher_postalCode_Maybe :: DecodeJson Cipher_IdentityCipher_postalCode_Maybe where
269+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
270+derive instance genericCipher_IdentityCipher_postalCode_Maybe :: Generic Cipher_IdentityCipher_postalCode_Maybe _
271+derive instance eqCipher_IdentityCipher_postalCode_Maybe :: Eq Cipher_IdentityCipher_postalCode_Maybe
272+derive instance ordCipher_IdentityCipher_postalCode_Maybe :: Ord Cipher_IdentityCipher_postalCode_Maybe
273+
274+newtype Cipher_IdentityCipher_ssn_Maybe =
275+ Cipher_IdentityCipher_ssn_Maybe (Maybe String)
276+
277+derive instance newtypeCipher_IdentityCipher_ssn_Maybe :: Newtype Cipher_IdentityCipher_ssn_Maybe _
278+instance encodeJsonCipher_IdentityCipher_ssn_Maybe :: EncodeJson Cipher_IdentityCipher_ssn_Maybe where
279+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
280+instance decodeJsonCipher_IdentityCipher_ssn_Maybe :: DecodeJson Cipher_IdentityCipher_ssn_Maybe where
281+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
282+derive instance genericCipher_IdentityCipher_ssn_Maybe :: Generic Cipher_IdentityCipher_ssn_Maybe _
283+derive instance eqCipher_IdentityCipher_ssn_Maybe :: Eq Cipher_IdentityCipher_ssn_Maybe
284+derive instance ordCipher_IdentityCipher_ssn_Maybe :: Ord Cipher_IdentityCipher_ssn_Maybe
285+
286+newtype Cipher_IdentityCipher_state_Maybe =
287+ Cipher_IdentityCipher_state_Maybe (Maybe String)
288+
289+derive instance newtypeCipher_IdentityCipher_state_Maybe :: Newtype Cipher_IdentityCipher_state_Maybe _
290+instance encodeJsonCipher_IdentityCipher_state_Maybe :: EncodeJson Cipher_IdentityCipher_state_Maybe where
291+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
292+instance decodeJsonCipher_IdentityCipher_state_Maybe :: DecodeJson Cipher_IdentityCipher_state_Maybe where
293+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
294+derive instance genericCipher_IdentityCipher_state_Maybe :: Generic Cipher_IdentityCipher_state_Maybe _
295+derive instance eqCipher_IdentityCipher_state_Maybe :: Eq Cipher_IdentityCipher_state_Maybe
296+derive instance ordCipher_IdentityCipher_state_Maybe :: Ord Cipher_IdentityCipher_state_Maybe
297+
298+newtype Cipher_IdentityCipher_title_Maybe =
299+ Cipher_IdentityCipher_title_Maybe (Maybe String)
300+
301+derive instance newtypeCipher_IdentityCipher_title_Maybe :: Newtype Cipher_IdentityCipher_title_Maybe _
302+instance encodeJsonCipher_IdentityCipher_title_Maybe :: EncodeJson Cipher_IdentityCipher_title_Maybe where
303+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
304+instance decodeJsonCipher_IdentityCipher_title_Maybe :: DecodeJson Cipher_IdentityCipher_title_Maybe where
305+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
306+derive instance genericCipher_IdentityCipher_title_Maybe :: Generic Cipher_IdentityCipher_title_Maybe _
307+derive instance eqCipher_IdentityCipher_title_Maybe :: Eq Cipher_IdentityCipher_title_Maybe
308+derive instance ordCipher_IdentityCipher_title_Maybe :: Ord Cipher_IdentityCipher_title_Maybe
309+
310+newtype Cipher_IdentityCipher_username_Maybe =
311+ Cipher_IdentityCipher_username_Maybe (Maybe String)
312+
313+derive instance newtypeCipher_IdentityCipher_username_Maybe :: Newtype Cipher_IdentityCipher_username_Maybe _
314+instance encodeJsonCipher_IdentityCipher_username_Maybe :: EncodeJson Cipher_IdentityCipher_username_Maybe where
315+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
316+instance decodeJsonCipher_IdentityCipher_username_Maybe :: DecodeJson Cipher_IdentityCipher_username_Maybe where
317+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
318+derive instance genericCipher_IdentityCipher_username_Maybe :: Generic Cipher_IdentityCipher_username_Maybe _
319+derive instance eqCipher_IdentityCipher_username_Maybe :: Eq Cipher_IdentityCipher_username_Maybe
320+derive instance ordCipher_IdentityCipher_username_Maybe :: Ord Cipher_IdentityCipher_username_Maybe
321+
322+newtype Cipher_IdentityCipher =
323+ Cipher_IdentityCipher {
324+ address1 :: Cipher_IdentityCipher_address1_Maybe
325+ , address2 :: Cipher_IdentityCipher_address2_Maybe
326+ , address3 :: Cipher_IdentityCipher_address3_Maybe
327+ , city :: Cipher_IdentityCipher_city_Maybe
328+ , company :: Cipher_IdentityCipher_company_Maybe
329+ , country :: Cipher_IdentityCipher_country_Maybe
330+ , email :: Cipher_IdentityCipher_email_Maybe
331+ , firstName :: Cipher_IdentityCipher_firstName_Maybe
332+ , lastName :: Cipher_IdentityCipher_lastName_Maybe
333+ , licenseNumber :: Cipher_IdentityCipher_licenseNumber_Maybe
334+ , middleName :: Cipher_IdentityCipher_middleName_Maybe
335+ , passportNumber :: Cipher_IdentityCipher_passportNumber_Maybe
336+ , phone :: Cipher_IdentityCipher_phone_Maybe
337+ , postalCode :: Cipher_IdentityCipher_postalCode_Maybe
338+ , ssn :: Cipher_IdentityCipher_ssn_Maybe
339+ , state :: Cipher_IdentityCipher_state_Maybe
340+ , title :: Cipher_IdentityCipher_title_Maybe
341+ , username :: Cipher_IdentityCipher_username_Maybe
342+ }
343+
344+derive instance newtypeCipher_IdentityCipher :: Newtype Cipher_IdentityCipher _
345+instance encodeJsonCipher_IdentityCipher :: EncodeJson Cipher_IdentityCipher where
346+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
347+instance decodeJsonCipher_IdentityCipher :: DecodeJson Cipher_IdentityCipher where
348+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
349+derive instance genericCipher_IdentityCipher :: Generic Cipher_IdentityCipher _
350+derive instance eqCipher_IdentityCipher :: Eq Cipher_IdentityCipher
351+derive instance ordCipher_IdentityCipher :: Ord Cipher_IdentityCipher
352+
353+newtype Cipher_LoginCipher_password_Maybe =
354+ Cipher_LoginCipher_password_Maybe (Maybe String)
355+
356+derive instance newtypeCipher_LoginCipher_password_Maybe :: Newtype Cipher_LoginCipher_password_Maybe _
357+instance encodeJsonCipher_LoginCipher_password_Maybe :: EncodeJson Cipher_LoginCipher_password_Maybe where
358+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
359+instance decodeJsonCipher_LoginCipher_password_Maybe :: DecodeJson Cipher_LoginCipher_password_Maybe where
360+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
361+derive instance genericCipher_LoginCipher_password_Maybe :: Generic Cipher_LoginCipher_password_Maybe _
362+derive instance eqCipher_LoginCipher_password_Maybe :: Eq Cipher_LoginCipher_password_Maybe
363+derive instance ordCipher_LoginCipher_password_Maybe :: Ord Cipher_LoginCipher_password_Maybe
364+
365+newtype Cipher_LoginCipher_totp_Maybe =
366+ Cipher_LoginCipher_totp_Maybe (Maybe String)
367+
368+derive instance newtypeCipher_LoginCipher_totp_Maybe :: Newtype Cipher_LoginCipher_totp_Maybe _
369+instance encodeJsonCipher_LoginCipher_totp_Maybe :: EncodeJson Cipher_LoginCipher_totp_Maybe where
370+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
371+instance decodeJsonCipher_LoginCipher_totp_Maybe :: DecodeJson Cipher_LoginCipher_totp_Maybe where
372+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
373+derive instance genericCipher_LoginCipher_totp_Maybe :: Generic Cipher_LoginCipher_totp_Maybe _
374+derive instance eqCipher_LoginCipher_totp_Maybe :: Eq Cipher_LoginCipher_totp_Maybe
375+derive instance ordCipher_LoginCipher_totp_Maybe :: Ord Cipher_LoginCipher_totp_Maybe
376+
377+newtype Cipher_LoginCipher_uris_List =
378+ Cipher_LoginCipher_uris_List (Array String)
379+
380+derive instance newtypeCipher_LoginCipher_uris_List :: Newtype Cipher_LoginCipher_uris_List _
381+instance encodeJsonCipher_LoginCipher_uris_List :: EncodeJson Cipher_LoginCipher_uris_List where
382+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
383+instance decodeJsonCipher_LoginCipher_uris_List :: DecodeJson Cipher_LoginCipher_uris_List where
384+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
385+derive instance genericCipher_LoginCipher_uris_List :: Generic Cipher_LoginCipher_uris_List _
386+derive instance eqCipher_LoginCipher_uris_List :: Eq Cipher_LoginCipher_uris_List
387+derive instance ordCipher_LoginCipher_uris_List :: Ord Cipher_LoginCipher_uris_List
388+
389+newtype Cipher_LoginCipher_username_Maybe =
390+ Cipher_LoginCipher_username_Maybe (Maybe String)
391+
392+derive instance newtypeCipher_LoginCipher_username_Maybe :: Newtype Cipher_LoginCipher_username_Maybe _
393+instance encodeJsonCipher_LoginCipher_username_Maybe :: EncodeJson Cipher_LoginCipher_username_Maybe where
394+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
395+instance decodeJsonCipher_LoginCipher_username_Maybe :: DecodeJson Cipher_LoginCipher_username_Maybe where
396+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
397+derive instance genericCipher_LoginCipher_username_Maybe :: Generic Cipher_LoginCipher_username_Maybe _
398+derive instance eqCipher_LoginCipher_username_Maybe :: Eq Cipher_LoginCipher_username_Maybe
399+derive instance ordCipher_LoginCipher_username_Maybe :: Ord Cipher_LoginCipher_username_Maybe
400+
401+newtype Cipher_LoginCipher =
402+ Cipher_LoginCipher {
403+ password :: Cipher_LoginCipher_password_Maybe
404+ , totp :: Cipher_LoginCipher_totp_Maybe
405+ , uris :: Cipher_LoginCipher_uris_List
406+ , username :: Cipher_LoginCipher_username_Maybe
407+ }
408+
409+derive instance newtypeCipher_LoginCipher :: Newtype Cipher_LoginCipher _
410+instance encodeJsonCipher_LoginCipher :: EncodeJson Cipher_LoginCipher where
411+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
412+instance decodeJsonCipher_LoginCipher :: DecodeJson Cipher_LoginCipher where
413+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
414+derive instance genericCipher_LoginCipher :: Generic Cipher_LoginCipher _
415+derive instance eqCipher_LoginCipher :: Eq Cipher_LoginCipher
416+derive instance ordCipher_LoginCipher :: Ord Cipher_LoginCipher
417+
418+data Cipher =
419+ CardCipher Cipher_CardCipher
420+ | IdentityCipher Cipher_IdentityCipher
421+ | LoginCipher Cipher_LoginCipher
422+ | NoteCipher String
423+
424+instance encodeJsonCipher :: EncodeJson Cipher where
425+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
426+instance decodeJsonCipher :: DecodeJson Cipher where
427+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
428+derive instance genericCipher :: Generic Cipher _
429+derive instance eqCipher :: Eq Cipher
430+derive instance ordCipher :: Ord Cipher
431+
432+data CipherType =
433+ CardType
434+ | IdentityType
435+ | LoginType
436+ | NoteType
437+
438+instance encodeJsonCipherType :: EncodeJson CipherType where
439+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
440+instance decodeJsonCipherType :: DecodeJson CipherType where
441+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
442+derive instance genericCipherType :: Generic CipherType _
443+derive instance eqCipherType :: Eq CipherType
444+derive instance ordCipherType :: Ord CipherType
445+
446+newtype Cmd_ChooseSecondFactor =
447+ Cmd_ChooseSecondFactor {
448+ email :: String
449+ , factor :: TwoFactorProviderType
450+ , password :: String
451+ , requestFromServer :: Boolean
452+ , server :: String
453+ }
454+
455+derive instance newtypeCmd_ChooseSecondFactor :: Newtype Cmd_ChooseSecondFactor _
456+instance encodeJsonCmd_ChooseSecondFactor :: EncodeJson Cmd_ChooseSecondFactor where
457+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
458+instance decodeJsonCmd_ChooseSecondFactor :: DecodeJson Cmd_ChooseSecondFactor where
459+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
460+derive instance genericCmd_ChooseSecondFactor :: Generic Cmd_ChooseSecondFactor _
461+derive instance eqCmd_ChooseSecondFactor :: Eq Cmd_ChooseSecondFactor
462+derive instance ordCmd_ChooseSecondFactor :: Ord Cmd_ChooseSecondFactor
463+
464+newtype Cmd_Login_secondFactor =
465+ Cmd_Login_secondFactor {
466+ provider :: TwoFactorProviderType
467+ , remember :: Boolean
468+ , token :: String
469+ }
470+
471+derive instance newtypeCmd_Login_secondFactor :: Newtype Cmd_Login_secondFactor _
472+instance encodeJsonCmd_Login_secondFactor :: EncodeJson Cmd_Login_secondFactor where
473+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
474+instance decodeJsonCmd_Login_secondFactor :: DecodeJson Cmd_Login_secondFactor where
475+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
476+derive instance genericCmd_Login_secondFactor :: Generic Cmd_Login_secondFactor _
477+derive instance eqCmd_Login_secondFactor :: Eq Cmd_Login_secondFactor
478+derive instance ordCmd_Login_secondFactor :: Ord Cmd_Login_secondFactor
479+
480+newtype Cmd_Login_secondFactor_Maybe =
481+ Cmd_Login_secondFactor_Maybe (Maybe Cmd_Login_secondFactor)
482+
483+derive instance newtypeCmd_Login_secondFactor_Maybe :: Newtype Cmd_Login_secondFactor_Maybe _
484+instance encodeJsonCmd_Login_secondFactor_Maybe :: EncodeJson Cmd_Login_secondFactor_Maybe where
485+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
486+instance decodeJsonCmd_Login_secondFactor_Maybe :: DecodeJson Cmd_Login_secondFactor_Maybe where
487+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
488+derive instance genericCmd_Login_secondFactor_Maybe :: Generic Cmd_Login_secondFactor_Maybe _
489+derive instance eqCmd_Login_secondFactor_Maybe :: Eq Cmd_Login_secondFactor_Maybe
490+derive instance ordCmd_Login_secondFactor_Maybe :: Ord Cmd_Login_secondFactor_Maybe
491+
15newtype Cmd_Login =
492newtype Cmd_Login =
16 Cmd_Login {
493 Cmd_Login {
17 email :: String
494 email :: String
18 , password :: String
495 , password :: String
496+ , secondFactor :: Cmd_Login_secondFactor_Maybe
19 , server :: String
497 , server :: String
20 }
498 }
21
499
500+derive instance newtypeCmd_Login :: Newtype Cmd_Login _
22instance encodeJsonCmd_Login :: EncodeJson Cmd_Login where
501instance encodeJsonCmd_Login :: EncodeJson Cmd_Login where
23 encodeJson = genericEncodeAeson Argonaut.defaultOptions
502 encodeJson = genericEncodeAeson Argonaut.defaultOptions
24instance decodeJsonCmd_Login :: DecodeJson Cmd_Login where
503instance decodeJsonCmd_Login :: DecodeJson Cmd_Login where
@@ -28,8 +507,21 @@ derive instance eqCmd_Login :: Eq Cmd_Login
28derive instance ordCmd_Login :: Ord Cmd_Login
507derive instance ordCmd_Login :: Ord Cmd_Login
29
508
30data Cmd =
509data Cmd =
510+ ChooseSecondFactor Cmd_ChooseSecondFactor
511+ | Copy String
512+ | CreateCipher FullCipher
513+ | DeleteCipher FullCipher
514+ | GeneratePassword PasswordGeneratorConfig
31− Init
515+ | Init
32 | Login Cmd_Login
516 | Login Cmd_Login
517+ | NeedCiphersList
518+ | NeedEmail
519+ | NeedsReset
520+ | Open String
521+ | RequestCipher String
522+ | RequestTotp String
523+ | SendMasterPassword String
524+ | UpdateCipher FullCipher
33
525
34instance encodeJsonCmd :: EncodeJson Cmd where
526instance encodeJsonCmd :: EncodeJson Cmd where
35 encodeJson = genericEncodeAeson Argonaut.defaultOptions
527 encodeJson = genericEncodeAeson Argonaut.defaultOptions
@@ -39,12 +531,74 @@ derive instance genericCmd :: Generic Cmd _
39derive instance eqCmd :: Eq Cmd
531derive instance eqCmd :: Eq Cmd
40derive instance ordCmd :: Ord Cmd
532derive instance ordCmd :: Ord Cmd
41
533
534+newtype FullCipher_collectionIds_List =
535+ FullCipher_collectionIds_List (Array String)
536+
537+derive instance newtypeFullCipher_collectionIds_List :: Newtype FullCipher_collectionIds_List _
538+instance encodeJsonFullCipher_collectionIds_List :: EncodeJson FullCipher_collectionIds_List where
539+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
540+instance decodeJsonFullCipher_collectionIds_List :: DecodeJson FullCipher_collectionIds_List where
541+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
542+derive instance genericFullCipher_collectionIds_List :: Generic FullCipher_collectionIds_List _
543+derive instance eqFullCipher_collectionIds_List :: Eq FullCipher_collectionIds_List
544+derive instance ordFullCipher_collectionIds_List :: Ord FullCipher_collectionIds_List
545+
546+newtype FullCipher =
547+ FullCipher {
548+ cipher :: Cipher
549+ , collectionIds :: FullCipher_collectionIds_List
550+ , favorite :: Boolean
551+ , id :: String
552+ , name :: String
553+ , reprompt :: Int
554+ }
555+
556+derive instance newtypeFullCipher :: Newtype FullCipher _
557+instance encodeJsonFullCipher :: EncodeJson FullCipher where
558+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
559+instance decodeJsonFullCipher :: DecodeJson FullCipher where
560+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
561+derive instance genericFullCipher :: Generic FullCipher _
562+derive instance eqFullCipher :: Eq FullCipher
563+derive instance ordFullCipher :: Ord FullCipher
564+
565+newtype PasswordGeneratorConfig =
566+ PasswordGeneratorConfig {
567+ ambiguous :: Boolean
568+ , capitalize :: Boolean
569+ , includeNumber :: Boolean
570+ , length :: Int
571+ , lowercase :: Boolean
572+ , minLowercase :: Int
573+ , minNumber :: Int
574+ , minSpecial :: Int
575+ , minUppercase :: Int
576+ , numWords :: Int
577+ , number :: Boolean
578+ , special :: Boolean
579+ , type :: String
580+ , uppercase :: Boolean
581+ , wordSeparator :: String
582+ }
583+
584+derive instance newtypePasswordGeneratorConfig :: Newtype PasswordGeneratorConfig _
585+instance encodeJsonPasswordGeneratorConfig :: EncodeJson PasswordGeneratorConfig where
586+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
587+instance decodeJsonPasswordGeneratorConfig :: DecodeJson PasswordGeneratorConfig where
588+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
589+derive instance genericPasswordGeneratorConfig :: Generic PasswordGeneratorConfig _
590+derive instance eqPasswordGeneratorConfig :: Eq PasswordGeneratorConfig
591+derive instance ordPasswordGeneratorConfig :: Ord PasswordGeneratorConfig
592+
42newtype Sub_LoadCiphers =
593newtype Sub_LoadCiphers =
43 Sub_LoadCiphers {
594 Sub_LoadCiphers {
595+ cipherType :: CipherType
44− date :: String
596+ , date :: String
597+ , id :: String
45 , name :: String
598 , name :: String
46 }
599 }
47
600
601+derive instance newtypeSub_LoadCiphers :: Newtype Sub_LoadCiphers _
48instance encodeJsonSub_LoadCiphers :: EncodeJson Sub_LoadCiphers where
602instance encodeJsonSub_LoadCiphers :: EncodeJson Sub_LoadCiphers where
49 encodeJson = genericEncodeAeson Argonaut.defaultOptions
603 encodeJson = genericEncodeAeson Argonaut.defaultOptions
50instance decodeJsonSub_LoadCiphers :: DecodeJson Sub_LoadCiphers where
604instance decodeJsonSub_LoadCiphers :: DecodeJson Sub_LoadCiphers where
@@ -56,6 +610,7 @@ derive instance ordSub_LoadCiphers :: Ord Sub_LoadCiphers
56newtype Sub_LoadCiphers_List =
610newtype Sub_LoadCiphers_List =
57 Sub_LoadCiphers_List (Array Sub_LoadCiphers)
611 Sub_LoadCiphers_List (Array Sub_LoadCiphers)
58
612
613+derive instance newtypeSub_LoadCiphers_List :: Newtype Sub_LoadCiphers_List _
59instance encodeJsonSub_LoadCiphers_List :: EncodeJson Sub_LoadCiphers_List where
614instance encodeJsonSub_LoadCiphers_List :: EncodeJson Sub_LoadCiphers_List where
60 encodeJson = genericEncodeAeson Argonaut.defaultOptions
615 encodeJson = genericEncodeAeson Argonaut.defaultOptions
61instance decodeJsonSub_LoadCiphers_List :: DecodeJson Sub_LoadCiphers_List where
616instance decodeJsonSub_LoadCiphers_List :: DecodeJson Sub_LoadCiphers_List where
@@ -64,10 +619,66 @@ derive instance genericSub_LoadCiphers_List :: Generic Sub_LoadCiphers_List _
64derive instance eqSub_LoadCiphers_List :: Eq Sub_LoadCiphers_List
619derive instance eqSub_LoadCiphers_List :: Eq Sub_LoadCiphers_List
65derive instance ordSub_LoadCiphers_List :: Ord Sub_LoadCiphers_List
620derive instance ordSub_LoadCiphers_List :: Ord Sub_LoadCiphers_List
66
621
622+newtype Sub_NeedsMasterPassword =
623+ Sub_NeedsMasterPassword {
624+ login :: String
625+ , server :: String
626+ }
627+
628+derive instance newtypeSub_NeedsMasterPassword :: Newtype Sub_NeedsMasterPassword _
629+instance encodeJsonSub_NeedsMasterPassword :: EncodeJson Sub_NeedsMasterPassword where
630+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
631+instance decodeJsonSub_NeedsMasterPassword :: DecodeJson Sub_NeedsMasterPassword where
632+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
633+derive instance genericSub_NeedsMasterPassword :: Generic Sub_NeedsMasterPassword _
634+derive instance eqSub_NeedsMasterPassword :: Eq Sub_NeedsMasterPassword
635+derive instance ordSub_NeedsMasterPassword :: Ord Sub_NeedsMasterPassword
636+
637+newtype Sub_NeedsSecondFactor_List =
638+ Sub_NeedsSecondFactor_List (Array TwoFactorProviderType)
639+
640+derive instance newtypeSub_NeedsSecondFactor_List :: Newtype Sub_NeedsSecondFactor_List _
641+instance encodeJsonSub_NeedsSecondFactor_List :: EncodeJson Sub_NeedsSecondFactor_List where
642+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
643+instance decodeJsonSub_NeedsSecondFactor_List :: DecodeJson Sub_NeedsSecondFactor_List where
644+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
645+derive instance genericSub_NeedsSecondFactor_List :: Generic Sub_NeedsSecondFactor_List _
646+derive instance eqSub_NeedsSecondFactor_List :: Eq Sub_NeedsSecondFactor_List
647+derive instance ordSub_NeedsSecondFactor_List :: Ord Sub_NeedsSecondFactor_List
648+
649+newtype Sub_Totp =
650+ Sub_Totp {
651+ code :: String
652+ , interval :: Int
653+ , source :: String
654+ }
655+
656+derive instance newtypeSub_Totp :: Newtype Sub_Totp _
657+instance encodeJsonSub_Totp :: EncodeJson Sub_Totp where
658+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
659+instance decodeJsonSub_Totp :: DecodeJson Sub_Totp where
660+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
661+derive instance genericSub_Totp :: Generic Sub_Totp _
662+derive instance eqSub_Totp :: Eq Sub_Totp
663+derive instance ordSub_Totp :: Ord Sub_Totp
664+
67data Sub =
665data Sub =
666+ CaptchaDone
667+ | CipherChanged FullCipher
668+ | CipherDeleted FullCipher
68− Error String
669+ | Error String
670+ | GeneratedPassword String
671+ | LoadCipher FullCipher
69 | LoadCiphers Sub_LoadCiphers_List
672 | LoadCiphers Sub_LoadCiphers_List
673+ | LoginSuccessful
674+ | NeedsCaptcha String
70 | NeedsLogin
675 | NeedsLogin
676+ | NeedsMasterPassword Sub_NeedsMasterPassword
677+ | NeedsSecondFactor Sub_NeedsSecondFactor_List
678+ | RecieveEmail String
679+ | Reset
680+ | Totp Sub_Totp
681+ | WrongPassword
71
682
72instance encodeJsonSub :: EncodeJson Sub where
683instance encodeJsonSub :: EncodeJson Sub where
73 encodeJson = genericEncodeAeson Argonaut.defaultOptions
684 encodeJson = genericEncodeAeson Argonaut.defaultOptions
@@ -77,3 +688,21 @@ derive instance genericSub :: Generic Sub _
77derive instance eqSub :: Eq Sub
688derive instance eqSub :: Eq Sub
78derive instance ordSub :: Ord Sub
689derive instance ordSub :: Ord Sub
79
690
691+data TwoFactorProviderType =
692+ Authenticator
693+ | Duo
694+ | Email
695+ | OrganizationDuo
696+ | Remember
697+ | U2f
698+ | WebAuthn
699+ | Yubikey
700+
701+instance encodeJsonTwoFactorProviderType :: EncodeJson TwoFactorProviderType where
702+ encodeJson = genericEncodeAeson Argonaut.defaultOptions
703+instance decodeJsonTwoFactorProviderType :: DecodeJson TwoFactorProviderType where
704+ decodeJson = genericDecodeAeson Argonaut.defaultOptions
705+derive instance genericTwoFactorProviderType :: Generic TwoFactorProviderType _
706+derive instance eqTwoFactorProviderType :: Eq TwoFactorProviderType
707+derive instance ordTwoFactorProviderType :: Ord TwoFactorProviderType
708+
backend/Data/Clipboard.jsnew file+4
@@ -0,0 +1,4 @@
1+
2+export function clipboard(text) {
3+ return navigator.clipboard.writeText(text)
4+}
backend/Data/Clipboard.pursnew file+6
@@ -0,0 +1,6 @@
1+module Data.Clipboard where
2+
3+import Prelude
4+import Control.Promise (Promise)
5+
6+foreign import clipboard :: String -> Promise Unit
bw/src/Data/EncString.js → backend/Data/EncString.jsrenamed+5−2
@@ -1,11 +1,14 @@
1−import { EncString } from "../../deps/bw/libs/shared/dist/src/models/domain/encString"
1+import { EncString } from "../../bw/models/domain/enc-string"
2
2
3export function fromString(str) {
3export function fromString(str) {
4− console.log("fromString " + str)
5 const x = new EncString(str)
4 const x = new EncString(str)
6 return x
5 return x
7}
6}
8
7
8+export function toString(encStr) {
9+ return encStr.encryptedString
10+}
11+
9export function encryptionType(encStr) {
12export function encryptionType(encStr) {
10 return encStr.encryptionType
13 return encStr.encryptionType
11}
14}
bw/src/Data/EncString.purs → backend/Data/EncString.pursrenamed+2
@@ -25,3 +25,5 @@ type EncryptionType
25 = Int
25 = Int
26
26
27foreign import fromString :: EncryptedString -> EncString
27foreign import fromString :: EncryptedString -> EncString
28+
29+foreign import toString :: EncString -> EncryptedString
backend/Data/HCaptcha.jsnew file+9
@@ -0,0 +1,9 @@
1+export function bindHCaptchToken(callback) {
2+ return () => {
3+ window.addEventListener("message", (e) => {
4+ if (typeof e.data === 'object' && "hCaptchaToken" in e.data) {
5+ callback(e.data.hCaptchaToken)();
6+ }
7+ })
8+ }
9+}
backend/Data/HCaptcha.pursnew file+6
@@ -0,0 +1,6 @@
1+module Data.HCaptcha where
2+
3+import Prelude
4+import Effect (Effect)
5+
6+foreign import bindHCaptchToken :: (String -> Effect Unit) -> Effect Unit
backend/Data/JNullable.pursnew file+73
@@ -0,0 +1,73 @@
1+module Data.JNullable where
2+
3+import Prelude
4+
5+import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson)
6+import Data.Foldable (class Foldable, foldlDefault, foldrDefault)
7+import Data.Maybe (Maybe(..))
8+import Data.Nullable (Nullable, null, toNullable)
9+import Data.Nullable as Nullable
10+import Data.Traversable (class Traversable)
11+import Data.Tuple.Nested ((/\))
12+
13+newtype JNullable a
14+ = JNullable (Nullable a)
15+
16+derive newtype instance Eq a => Eq (JNullable a)
17+derive newtype instance Ord a => Ord (JNullable a)
18+derive newtype instance Show a => Show (JNullable a)
19+
20+instance Functor JNullable where
21+ map f (JNullable n) = case Nullable.toMaybe n of
22+ Nothing -> jnull
23+ Just a -> nullify (f a)
24+
25+instance Foldable JNullable where
26+ foldMap f (JNullable n) = case Nullable.toMaybe n of
27+ Nothing -> mempty
28+ Just a -> f a
29+ foldr f def (JNullable n) = case Nullable.toMaybe n of
30+ Nothing -> def
31+ Just a -> f a def
32+ foldl f def (JNullable n) = case Nullable.toMaybe n of
33+ Nothing -> def
34+ Just a -> f def a
35+
36+instance Apply JNullable where
37+ apply (JNullable n) (JNullable m) = case (Nullable.toMaybe n /\ Nullable.toMaybe m) of
38+ (Nothing /\ _) -> jnull
39+ (_ /\ Nothing) -> jnull
40+ (Just f /\ Just a) -> nullify (f a)
41+
42+
43+instance Applicative JNullable where
44+ pure = nullify
45+
46+instance Traversable JNullable where
47+ traverse f (JNullable n) = case Nullable.toMaybe n of
48+ Nothing -> pure jnull
49+ Just a -> nullify <$> f a
50+
51+ sequence (JNullable n) = case Nullable.toMaybe n of
52+ Nothing -> pure jnull
53+ Just a -> nullify <$> a
54+
55+instance EncodeJson a => EncodeJson (JNullable a) where
56+ encodeJson (JNullable a) = encodeJson $ Nullable.toMaybe a
57+
58+instance DecodeJson a => DecodeJson (JNullable a) where
59+ decodeJson json = JNullable <<< Nullable.toNullable <$> decodeJson json
60+
61+jnull :: forall a. JNullable a
62+jnull = JNullable null
63+
64+nullify :: forall a. a -> JNullable a
65+nullify = Just >>> toNullable >>> JNullable
66+
67+fromJNullable :: forall a. a -> JNullable a -> a
68+fromJNullable def (JNullable a) = case Nullable.toMaybe a of
69+ Nothing -> def
70+ Just a' -> a'
71+
72+toMaybe :: forall a. JNullable a -> Maybe a
73+toMaybe (JNullable a) = Nullable.toMaybe a
backend/Data/JOpt.pursnew file+62
@@ -0,0 +1,62 @@
1+module Data.JOpt where
2+
3+import Prelude
4+
5+import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson)
6+import Data.Foldable (class Foldable)
7+import Data.Maybe (Maybe(..))
8+import Data.Traversable (class Traversable)
9+import Data.Undefined.NoProblem (Opt)
10+import Data.Undefined.NoProblem as Opt
11+
12+newtype JOpt a
13+ = JOpt (Opt a)
14+
15+derive newtype instance Eq a => Eq (JOpt a)
16+derive newtype instance Ord a => Ord (JOpt a)
17+derive newtype instance Show a => Show (JOpt a)
18+
19+instance Functor JOpt where
20+ map f (JOpt a) = case Opt.toMaybe a of
21+ Nothing -> JOpt (Opt.fromMaybe Nothing)
22+ Just x -> JOpt (Opt.fromMaybe (Just $ f x))
23+
24+instance Apply JOpt where
25+ apply (JOpt f) (JOpt a) = case Opt.toMaybe f of
26+ Nothing -> JOpt (Opt.fromMaybe Nothing)
27+ Just f' -> case Opt.toMaybe a of
28+ Nothing -> JOpt (Opt.fromMaybe Nothing)
29+ Just a' -> JOpt (Opt.fromMaybe (Just $ f' a'))
30+
31+instance Applicative JOpt where
32+ pure = JOpt <<< Opt.fromMaybe <<< Just
33+
34+instance Foldable JOpt where
35+ foldMap f (JOpt a) = case Opt.toMaybe a of
36+ Nothing -> mempty
37+ Just x -> f x
38+ foldl f z (JOpt a) = case Opt.toMaybe a of
39+ Nothing -> z
40+ Just x -> f z x
41+ foldr f z (JOpt a) = case Opt.toMaybe a of
42+ Nothing -> z
43+ Just x -> f x z
44+
45+instance Traversable JOpt where
46+ traverse f (JOpt a) = case Opt.toMaybe a of
47+ Nothing -> pure (JOpt (Opt.fromMaybe Nothing))
48+ Just x -> map pure (f x)
49+ sequence (JOpt a) = case Opt.toMaybe a of
50+ Nothing -> pure (JOpt (Opt.fromMaybe Nothing))
51+ Just x -> map pure x
52+
53+fromJOpt :: forall a. a -> JOpt a -> a
54+fromJOpt def (JOpt a) = case Opt.toMaybe a of
55+ Nothing -> def
56+ Just x -> x
57+
58+instance EncodeJson a => EncodeJson (JOpt a) where
59+ encodeJson (JOpt a) = encodeJson $ Opt.toMaybe a
60+
61+instance DecodeJson a => DecodeJson (JOpt a) where
62+ decodeJson json = JOpt <<< Opt.fromMaybe <$> decodeJson json
backend/Data/OpenURL.jsnew file+3
@@ -0,0 +1,3 @@
1+export function openURL(url) {
2+ return () => window.open(url, '_blank')
3+}
backend/Data/OpenURL.pursnew file+6
@@ -0,0 +1,6 @@
1+module Data.OpenURL where
2+
3+import Prelude
4+import Effect (Effect)
5+
6+foreign import openURL :: String -> Effect Unit
backend/Data/ShowableJson.pursnew file+19
@@ -0,0 +1,19 @@
1+module Data.ShowableJson
2+ ( ShowableJson(..)
3+ )
4+ where
5+
6+import Prelude
7+
8+import Data.Argonaut (class DecodeJson, class EncodeJson, Json)
9+import Data.Argonaut as Json
10+
11+newtype ShowableJson = ShowableJson Json
12+
13+instance Show ShowableJson where
14+ show (ShowableJson x) = Json.stringify x
15+
16+derive newtype instance Eq ShowableJson
17+derive newtype instance Ord ShowableJson
18+derive newtype instance EncodeJson ShowableJson
19+derive newtype instance DecodeJson ShowableJson
backend/Data/SymmetricCryptoKey.jsnew file+5
@@ -0,0 +1,5 @@
1+import { SymmetricCryptoKey } from '../../bw/models/domain/symmetric-crypto-key.js'
2+
3+export function fromArrayBuffer(arr) {
4+ return new SymmetricCryptoKey(arr)
5+}
bw/src/Data/SymmetricCryptoKey.purs → backend/Data/SymmetricCryptoKey.pursrenamed+3−3
@@ -2,12 +2,12 @@ module Data.SymmetricCryptoKey where
2
2
3import Prelude
3import Prelude
4import Data.ArrayBuffer.Types (ArrayBuffer)
4import Data.ArrayBuffer.Types (ArrayBuffer)
5−import Data.Nullable (Nullable)
5+import Data.JNullable (JNullable)
6
6
7type SymmetricCryptoKey
7type SymmetricCryptoKey
8 = { key :: ArrayBuffer
8 = { key :: ArrayBuffer
9− , encKey :: Nullable ArrayBuffer
9+ , encKey :: JNullable ArrayBuffer
10− , macKey :: Nullable ArrayBuffer
10+ , macKey :: JNullable ArrayBuffer
11 , encType :: EncryptionType
11 , encType :: EncryptionType
12 , keyB64 :: String
12 , keyB64 :: String
13 , encKeyB64 :: String
13 , encKeyB64 :: String
bw/src/Data/Timestamp.js → backend/Data/Timestamp.jsrenamed

The content is the same.

bw/src/Data/Timestamp.purs → backend/Data/Timestamp.pursrenamed+8
@@ -1,6 +1,8 @@
1module Data.Timestamp where
1module Data.Timestamp where
2
2
3import Prelude
3import Prelude
4+
5+import Data.Argonaut (class DecodeJson, class EncodeJson)
4import Data.Bifunctor (lmap)
6import Data.Bifunctor (lmap)
5import Data.DateTime (DateTime)
7import Data.DateTime (DateTime)
6import Data.DateTime.Parsing as DateTime
8import Data.DateTime.Parsing as DateTime
@@ -12,6 +14,12 @@ import Effect.Exception (throw)
12newtype Timestamp
14newtype Timestamp
13 = Timestamp String
15 = Timestamp String
14
16
17+derive newtype instance Show Timestamp
18+derive newtype instance Ord Timestamp
19+derive newtype instance Eq Timestamp
20+derive newtype instance EncodeJson Timestamp
21+derive newtype instance DecodeJson Timestamp
22+
15toDateTime :: Timestamp -> Effect DateTime
23toDateTime :: Timestamp -> Effect DateTime
16toDateTime (Timestamp ts) =
24toDateTime (Timestamp ts) =
17 either throw pure
25 either throw pure
backend/FFI.js+16−1
@@ -1,6 +1,21 @@
1+function searchForInit(obj) {
2+ if (obj.init) {
3+ return obj.init
4+ } else {
5+ for (let key in obj) {
6+ if (obj.hasOwnProperty(key)) {
7+ const result = searchForInit(obj[key])
8+ if (result) {
9+ return result
10+ }
11+ }
12+ }
13+ }
14+}
15+
1export function startElm(element) {
16export function startElm(element) {
2 return function () {
17 return function () {
3− return Elm.Main.init({
18+ return searchForInit(Elm)({
4 node: document.getElementById(element)
19 node: document.getElementById(element)
5 })
20 })
6 }
21 }
backend/Localstorage.pursnew file+33
@@ -0,0 +1,33 @@
1+module Localstorage where
2+
3+import Prelude
4+import Data.Argonaut (class DecodeJson, class EncodeJson)
5+import Data.Argonaut as Json
6+import Data.Either (Either(..))
7+import Data.Maybe (Maybe(..))
8+import Effect (Effect)
9+import Effect.Exception as Exc
10+import Type.Prelude (Proxy)
11+import Web.Storage.Storage (Storage)
12+import Web.Storage.Storage as Storage
13+
14+class TypeId a where
15+ typeId :: Proxy a -> String
16+
17+class StorageKey k t | k -> t where
18+ storageKey :: k -> String
19+
20+store :: forall k t. StorageKey k t => EncodeJson t => Storage -> k -> t -> Effect Unit
21+store storage key t = Storage.setItem (storageKey key) (Json.stringify $ Json.encodeJson $ t) storage
22+
23+get :: forall k t. StorageKey k t => DecodeJson t => Storage -> k -> Effect (Maybe t)
24+get storage key =
25+ Storage.getItem (storageKey key) storage
26+ >>= \x -> case x of
27+ Nothing -> pure Nothing
28+ Just y -> case Json.parseJson y >>= Json.decodeJson of
29+ Left err -> Exc.throw $ Json.printJsonDecodeError err
30+ Right y -> pure $ Just y
31+
32+delete :: forall k t. StorageKey k t => Storage -> k -> Effect Unit
33+delete storage key = Storage.removeItem (storageKey key) storage
backend/Main.purs+403−58
@@ -2,103 +2,448 @@ module Main
2 ( main
2 ( main
3 ) where
3 ) where
4
4
5−import Bridge
6import Prelude
5import Prelude
6+
7−import BW (CryptoService)
7+import BW (ApiService, CryptoFunctions, Services, CryptoService)
8import BW as WB
8import BW as WB
9−import BW.Logic (decrypt, liftPromise)
9+import BW.Logic (bwPasswordStringHash, decodeCipher, decrypt, encodeCipher, hashPassword, liftPromise, supportedCipher)
10import BW.Logic as Logic
10import BW.Logic as Logic
11−import BW.Types (Email(..), EncryptedString(..), Password(..), Urls, CipherResponse)
11+import BW.Types (CipherResponse, Email(..), Password(..), Urls, cipherTypeCard, cipherTypeIdentity, cipherTypeLogin, cipherTypeSecureNote, fromTwoFactorProviderType)
12import Bridge as Bridge
12import Bridge as Bridge
13−import Control.El (class HasL, Al, L(..), l)
13+import Control.Monad.Error.Class (catchError)
14−import Control.Monad.Reader (runReaderT)
15−import Control.Promise (Promise)
16−import Control.Promise as Promise
17−import Data.Argonaut (class EncodeJson, encodeJson)
14+import Data.Argonaut (class DecodeJson)
18−import Data.Argonaut as Json
15+import Data.Array as Array
19−import Data.Array as A
16+import Data.Clipboard as Clipboard
17+import Data.DateTime (DateTime)
20import Data.Either (Either(..))
18import Data.Either (Either(..))
21−import Data.Maybe (Maybe(..))
19+import Data.Foldable (for_)
22−import Data.Nullable (Nullable, null, toNullable)
20+import Data.HCaptcha (bindHCaptchToken)
21+import Data.JNullable (jnull, nullify)
23−import Data.Nullable as Nullable
22+import Data.JNullable as JNullable
23+import Data.Maybe (Maybe(..), maybe)
24+import Data.OpenURL (openURL)
25+import Data.Ord.Down (Down(..))
24import Data.SymmetricCryptoKey (SymmetricCryptoKey)
26import Data.SymmetricCryptoKey (SymmetricCryptoKey)
25import Data.Timestamp as Timestamp
27import Data.Timestamp as Timestamp
26import Data.Traversable (traverse)
28import Data.Traversable (traverse)
27import Effect (Effect)
29import Effect (Effect)
28import Effect.Aff (Aff, runAff_, try)
30import Effect.Aff (Aff, runAff_, try)
29−import Effect.Aff as Aff
30−import Effect.Aff.Class (class MonadAff, liftAff)
31−import Effect.Aff.Class as Aff
32import Effect.Class (liftEffect)
31import Effect.Class (liftEffect)
33import Effect.Class.Console (log)
32import Effect.Class.Console (log)
33+import Effect.Exception (throw)
34import Effect.Exception as Exc
34import Effect.Exception as Exc
35+import Effect.Ref as Ref
35import Elm as Elm
36import Elm as Elm
37+import FFI (Elm)
36import FFI as FFI
38import FFI as FFI
37−import Prelude as Array
39+import Localstorage (class StorageKey)
38−import Unsafe.Coerce (unsafeCoerce)
40+import Localstorage as Storage
41+import Run (AFF, EFFECT, Run, liftAff, runBaseAff')
42+import Run.Reader (Reader, askAt, runReaderAt)
43+import Storage (MasterPasswordHashKey(..), PreloginResponseKey(..), SyncKey(..), TokenKey(..), UrlsKey(..))
44+import Type.Prelude (Proxy(..))
45+import Type.Row (type (+))
46+import Untagged.Union (toEither1)
47+import Web.HTML as Html
48+import Web.HTML.Window as Window
49+import Web.Storage.Storage (Storage)
50+import Web.Storage.Storage as WebStorage
39
51
40main :: Effect Unit
52main :: Effect Unit
41main = do
53main = do
42 app <- FFI.startElm "elm"
54 app <- FFI.startElm "elm"
55+ storage <- Html.window >>= Window.localStorage
43 services <- WB.getServices
56 services <- WB.getServices
57+ masterKeyRef <- Ref.new Nothing
58+ hCaptchaTokenRef <- Ref.new Nothing
59+ bindHCaptchToken \captchaToken -> do
60+ Ref.write (Just captchaToken) hCaptchaTokenRef
61+ Elm.send app Bridge.CaptchaDone
62+ let
63+ runAff act = runElmAff app $ run $ act
64+
65+ run
66+ :: forall a
67+ . Run
68+ ( app :: Reader Elm
69+ , aff :: Aff
70+ , effect :: Effect
71+ , crypto :: Reader CryptoService
72+ , storage :: Reader Storage
73+ , services :: Reader Services
74+ , cryptoFunctions :: Reader CryptoFunctions
75+ )
76+ a
77+ -> Run (EFFECT + AFF + ()) a
78+ run act =
79+ runReaderAt (Proxy :: _ "app") app
80+ $ runReaderAt (Proxy :: _ "crypto") services.crypto
81+ $ runReaderAt (Proxy :: _ "storage") storage
82+ $ runReaderAt (Proxy :: _ "services") services
83+ $ runReaderAt (Proxy :: _ "cryptoFunctions") services.cryptoFunctions
84+ $ act
85+
86+ runWithDecryptionKey
87+ :: Run
88+ ( app :: Reader Elm
89+ , aff :: Aff
90+ , effect :: Effect
91+ , key :: Reader SymmetricCryptoKey
92+ , crypto :: Reader CryptoService
93+ , storage :: Reader Storage
94+ , services :: Reader Services
95+ , cryptoFunctions :: Reader CryptoFunctions
96+ )
97+ Unit
98+ -> Effect Unit
99+ runWithDecryptionKey act = do
100+ maybeKey <- Ref.read masterKeyRef
101+ runAff
102+ $ case maybeKey of
103+ Just masterKey -> do
104+ token <- getOrReset TokenKey
105+ key <- Logic.makeDecryptionKey masterKey token.key
106+ runReaderAt (Proxy :: _ "key") key $ act
107+ Nothing -> requestMasterPassword
44 Elm.subscribe app \cmd -> case cmd of
108 Elm.subscribe app \cmd -> case cmd of
45− Bridge.Login (Bridge.Cmd_Login { email, server, password }) -> do
109+ Bridge.Login (Bridge.Cmd_Login { email: email', server, password, secondFactor }) -> do
110+ let
111+ email = Email email'
112+ captchaResponse <- Ref.read hCaptchaTokenRef
113+ Ref.write Nothing hCaptchaTokenRef
46 let
114 let
47 urls = baseUrl server
115 urls = baseUrl server
48− runElmAff app do
116+ runAff do
49− unauthedApi <- liftPromise $ services.getApi urls null
117+ unauthedApi <- liftPromise $ services.getApi urls jnull
50− { masterKey, token, key } <-
118+ prelogin <- liftPromise $ unauthedApi.postPrelogin { email }
51− flip runReaderT { api: unauthedApi, crypto: services.crypto } do
119+ runReaderAt (Proxy :: _ "api") unauthedApi do
52− token <-
120+ loginResponse <-
121+ liftAff
122+ $ catchError
123+ ( do
124+ resp <-
125+ runBaseAff' $ run $ runReaderAt (Proxy :: _ "api") unauthedApi
53− try (Logic.getLogInRequestToken (Email email) (Password password))
126+ $ Logic.getLogInRequestToken
54− >>= \et -> case et of
127+ { prelogin
55− Left _ -> liftEffect $ Exc.throw "Could not log in. Please check your data and try again."
128+ , email
56− Right t -> pure t
129+ , password: Password password
57− masterKey <- Logic.makePreloginKey (Email email) (Password password)
130+ , captchaResponse
58− key <- Logic.makeDecryptionKey masterKey token.key
131+ , secondFactor
59− pure { token, masterKey, key }
132+ }
60− api <- liftPromise $ services.getApi urls (nullify token)
133+ pure $ Right resp
61− _ <-
134+ )
62− flip runReaderT { api: api, crypto: services.crypto, key: key } do
135+ ( \err -> do
63− sync <- liftPromise $ api.getSync unit
136+ log $ show err
64− processedCiphers <- traverse processCipher sync.ciphers
137+ pure $ Left unit
65− liftEffect $ Elm.send app $ LoadCiphers $ Bridge.Sub_LoadCiphers_List (A.take 3 processedCiphers)
138+ )
139+ case map (toEither1 >>> map toEither1) $ loginResponse of
140+ Left _ -> send Bridge.WrongPassword
141+ Right (Left { siteKey }) -> send $ Bridge.NeedsCaptcha siteKey
142+ Right (Right (Right token)) -> do
143+ masterKey <- Logic.makePreloginKey prelogin email (Password password)
144+ api <- liftPromise $ services.getApi urls (nullify token)
145+ sync <- liftPromise $ api.getSync unit
146+ hash <- hashPassword (Password password)
147+ log $ show sync
148+ liftEffect do
149+ Ref.write (Just masterKey) masterKeyRef
150+ Storage.store storage UrlsKey server
151+ Storage.store storage MasterPasswordHashKey hash
152+ Storage.store storage PreloginResponseKey prelogin
153+ Storage.store storage SyncKey sync
154+ Storage.store storage TokenKey token
155+ send Bridge.LoginSuccessful
156+ Right (Right (Left { twoFactorProviders, captchaToken })) -> do
157+ case toEither1 captchaToken of
158+ Left captchaTokenString ->
159+ liftEffect
160+ $ Ref.write (Just captchaTokenString) hCaptchaTokenRef
161+ Right _ -> pure unit
162+ providers <- case fromTwoFactorProviderType twoFactorProviders of
163+ Left x -> liftEffect $ throw $ "Unknown second factor provider: " <> x
164+ Right x -> pure x
165+ send $ Bridge.NeedsSecondFactor $ Bridge.Sub_NeedsSecondFactor_List providers
166+ Bridge.NeedCiphersList ->
167+ runWithDecryptionKey do
168+ sendCiphers
169+ performSync
170+ Bridge.NeedsReset -> do
171+ WebStorage.clear storage
172+ Elm.send app Bridge.Reset
173+ Bridge.SendMasterPassword masterPassword ->
174+ runAff do
175+ hash <- getOrReset MasterPasswordHashKey
176+ newHash <- hashPassword (Password masterPassword)
177+ if hash == newHash then do
178+ sync <- getOrReset SyncKey
179+ prelogin <- getOrReset PreloginResponseKey
180+ masterKey <- Logic.makePreloginKey prelogin (Email sync.profile.email) (Password masterPassword)
181+ liftEffect $ Ref.write (Just masterKey) masterKeyRef
182+ send Bridge.LoginSuccessful
183+ else do
184+ send $ Bridge.Error "The password is wrong. Please try again."
185+ requestMasterPassword
186+ Bridge.Init -> do
187+ Storage.get storage TokenKey
188+ >>= \x ->
189+ Elm.send app case x of
190+ Just _ -> Bridge.LoginSuccessful
191+ Nothing -> Bridge.NeedsLogin
192+ Bridge.RequestCipher id ->
193+ runWithDecryptionKey do
194+ sync <- getOrReset SyncKey
195+ case Array.find (\c -> c.id == id) sync.ciphers of
196+ Nothing -> pure unit
197+ Just cipherResponse -> do
198+ cipher <- decodeCipher cipherResponse
199+ for_ cipher $ send <<< Bridge.LoadCipher
200+ pure unit
201+ Bridge.NeedEmail ->
202+ runWithDecryptionKey do
203+ sync <- getOrReset SyncKey
204+ send $ Bridge.RecieveEmail sync.profile.email
205+ pure unit
206+ Bridge.Copy text ->
207+ runWithDecryptionKey do
208+ liftPromise $ Clipboard.clipboard text
209+ Bridge.Open uri -> openURL uri
210+ Bridge.UpdateCipher fullCipher ->
211+ runWithDecryptionKey do
212+ api <- getAuthedApi
213+ cipher <- encodeCipher fullCipher
214+ newCipher <- liftPromise (api.putCipher cipher) >>= decodeCipher
215+ for_ newCipher $ send <<< Bridge.CipherChanged
216+ performSync
217+ pure unit
218+ Bridge.GeneratePassword cfg ->
219+ runWithDecryptionKey do
220+ password <- liftPromise $ services.passwordGeneration.generatePassword cfg
221+ send $ Bridge.GeneratedPassword password
66− pure unit
222+ pure unit
223+ Bridge.CreateCipher fullCipher ->
224+ runWithDecryptionKey do
225+ api <- getAuthedApi
226+ cipher <- encodeCipher fullCipher
227+ newCipher <- liftPromise (api.postCipherCreate cipher) >>= decodeCipher
228+ for_ newCipher $ send <<< Bridge.CipherChanged
229+ performSync
67 pure unit
230 pure unit
68− Bridge.Init -> Elm.send app (Bridge.NeedsLogin)
231+ Bridge.DeleteCipher c@(Bridge.FullCipher { id }) ->
232+ runWithDecryptionKey do
233+ api <- getAuthedApi
234+ liftPromise $ api.deleteCipher id
235+ send $ Bridge.CipherDeleted c
236+ performSync
237+ pure unit
238+ Bridge.RequestTotp totp ->
239+ runWithDecryptionKey do
240+ { totpService } <- askAt (Proxy :: _ "services")
241+ code <- liftPromise $ totpService.getCode totp
242+ let
243+ interval = totpService.getTimeInterval totp
244+ send $ Bridge.Totp
245+ $ Bridge.Sub_Totp
246+ { interval
247+ , code
248+ , source: totp
249+ }
250+ pure unit
251+ Bridge.ChooseSecondFactor
252+ ( Bridge.Cmd_ChooseSecondFactor
253+ { email: email'
254+ , factor
255+ , server
256+ , password
257+ , requestFromServer
258+ }
259+ ) ->
260+ when requestFromServer
261+ let
262+ email = Email email'
263+ in
264+ case factor of
265+ Bridge.Email ->
266+ runAff do
267+ let
268+ urls = baseUrl server
269+ unauthedApi <- liftPromise $ services.getApi urls jnull
270+ prelogin <- liftPromise $ unauthedApi.postPrelogin { email }
271+ masterPasswordHash <- bwPasswordStringHash prelogin email (Password password)
272+ liftPromise $ unauthedApi.postTwoFactorEmail { email, masterPasswordHash }
273+ pure unit
274+ _ -> pure unit
69
275
70−processCipher ::
276+processCipher
71− forall r.
277+ :: forall r
278+ . CipherResponse
279+ -> Run
72− HasL "crypto" CryptoService r =>
280+ ( crypto :: Reader CryptoService
73− HasL "key" SymmetricCryptoKey r =>
281+ , key :: Reader SymmetricCryptoKey
282+ , aff :: Aff
283+ , effect :: Effect
284+ | r
285+ )
74− CipherResponse -> Al r Bridge.Sub_LoadCiphers
286+ (Maybe { cipher :: Bridge.Sub_LoadCiphers, date :: DateTime })
287+processCipher cipher | not (supportedCipher cipher) = pure Nothing
75processCipher cipher = do
288processCipher cipher = do
76 name <- decrypt cipher.name
289 name <- decrypt cipher.name
290+ cipherType <- case cipher.type of
291+ n
292+ | n == cipherTypeLogin -> pure Bridge.LoginType
293+ n
294+ | n == cipherTypeSecureNote -> pure Bridge.NoteType
295+ n
296+ | n == cipherTypeCard -> pure Bridge.CardType
297+ n
298+ | n == cipherTypeIdentity -> pure Bridge.IdentityType
299+ n -> liftEffect $ throw $ "Unsupported cipher type: " <> show n
300+ date <- liftEffect $ maybe (pure bottom) (Timestamp.toDateTime) $ JNullable.toMaybe cipher.revisionDate
77 pure
301 pure
302+ $ Just
303+ $
304+ { cipher:
78− $ Bridge.Sub_LoadCiphers
305+ Bridge.Sub_LoadCiphers
306+ { name: name
79− { name: name, date: Timestamp.toLocalDateTimeString cipher.revisionDate }
307+ , date: maybe "" Timestamp.toLocalDateTimeString $ JNullable.toMaybe cipher.revisionDate
308+ , id: cipher.id
309+ , cipherType
310+ }
311+ , date
312+ }
80
313
81−runElmAff :: FFI.Elm -> Aff Unit -> Effect Unit
314+runElmAff :: FFI.Elm -> Run (AFF + EFFECT + ()) Unit -> Effect Unit
82runElmAff app =
315runElmAff app =
83 runAff_
316 runAff_
84− $ \res -> do
317+ ( \res -> do
85 case res of
318 case res of
86 Left e -> do
319 Left e -> do
87 log $ show e
320 log $ show e
88 Elm.send app (Bridge.Error $ Exc.message e)
321 Elm.send app (Bridge.Error $ Exc.message e)
89 Right unit -> pure unit
322 Right unit -> pure unit
323+ )
324+ <<< runBaseAff'
90
325
91baseUrl :: String -> Urls
326baseUrl :: String -> Urls
92baseUrl server =
327baseUrl server =
93 { base: nullify server
328 { base: nullify server
94− , webVault: null
329+ , webVault: jnull
95− , api: null
330+ , api: jnull
96− , identity: null
331+ , identity: jnull
97− , icons: null
332+ , icons: jnull
98− , notifications: null
333+ , notifications: jnull
99− , events: null
334+ , events: jnull
100− , keyConnector: null
335+ , keyConnector: jnull
101 }
336 }
102
337
103−nullify :: forall a. a -> Nullable a
338+getOrReset
104−nullify = Just >>> toNullable
339+ :: forall k t r
340+ . StorageKey k t
341+ => DecodeJson t
342+ => k
343+ -> Run
344+ ( storage :: Reader Storage
345+ , app :: Reader Elm
346+ , effect :: Effect
347+ | r
348+ )
349+ t
350+getOrReset key = do
351+ storage <- askAt (Proxy :: _ "storage")
352+ app <- askAt (Proxy :: _ "app")
353+ let
354+ handleError = do
355+ WebStorage.clear storage
356+ Elm.send app Bridge.Reset
357+ Exc.throw "Encountered an internal error. Resetting the app."
358+ liftEffect $ try (Storage.get storage key)
359+ >>= \x -> case x of
360+ Left err -> do
361+ log $ show err
362+ handleError
363+ Right Nothing -> handleError
364+ Right (Just y) -> pure y
365+
366+getAuthedApi
367+ :: forall r
368+ . Run
369+ ( storage :: Reader Storage
370+ , app :: Reader Elm
371+ , aff :: Aff
372+ , effect :: Effect
373+ , services :: Reader Services
374+ | r
375+ )
376+ ApiService
377+getAuthedApi = do
378+ services <- askAt (Proxy :: _ "services")
379+ token <- getOrReset TokenKey
380+ url <- getOrReset UrlsKey
381+ liftPromise $ services.getApi (baseUrl url) (nullify token)
382+
383+requestMasterPassword
384+ :: forall r
385+ . Run
386+ ( storage :: Reader Storage
387+ , app :: Reader Elm
388+ , effect :: Effect
389+ | r
390+ )
391+ Unit
392+requestMasterPassword = do
393+ url <- getOrReset UrlsKey
394+ sync <- getOrReset SyncKey
395+ send $ Bridge.NeedsMasterPassword $ Bridge.Sub_NeedsMasterPassword { server: url, login: sync.profile.email }
396+
397+send
398+ :: forall r
399+ . Bridge.Sub
400+ -> Run
401+ ( app :: Reader Elm
402+ , effect :: Effect
403+ | r
404+ )
405+ Unit
406+send sub = do
407+ app <- askAt (Proxy :: _ "app")
408+ liftEffect $ Elm.send app sub
409+
410+performSync
411+ :: forall r
412+ . Run
413+ ( storage :: Reader Storage
414+ , app :: Reader Elm
415+ , aff :: Aff
416+ , effect :: Effect
417+ , services :: Reader Services
418+ , crypto :: Reader CryptoService
419+ , key :: Reader SymmetricCryptoKey
420+ | r
421+ )
422+ Unit
423+performSync = do
424+ api <- getAuthedApi
425+ storage <- askAt (Proxy :: _ "storage")
426+ newSync <- liftPromise $ api.getSync unit
427+ liftEffect $ Storage.store storage SyncKey newSync
428+ sendCiphers
429+
430+sendCiphers
431+ :: forall r
432+ . Run
433+ ( storage :: Reader Storage
434+ , app :: Reader Elm
435+ , aff :: Aff
436+ , effect :: Effect
437+ , services :: Reader Services
438+ , crypto :: Reader CryptoService
439+ , key :: Reader SymmetricCryptoKey
440+ | r
441+ )
442+ Unit
443+sendCiphers = do
444+ sync <- getOrReset SyncKey
445+ ciphers <- Array.catMaybes <$> traverse processCipher sync.ciphers
446+ let
447+ sortedCiphers = Array.sortWith (_.date >>> Down) ciphers
448+ send $ Bridge.LoadCiphers $ Bridge.Sub_LoadCiphers_List $ map _.cipher sortedCiphers
449+ pure unit
backend/Storage.pursnew file+43
@@ -0,0 +1,43 @@
1+module Storage where
2+
3+import Prelude
4+
5+import BW (Hash)
6+import BW.Types (IdentityTokenResponse, SyncResponse, PreloginResponse)
7+import Localstorage (class StorageKey)
8+
9+data SyncKey
10+ = SyncKey
11+
12+instance StorageKey SyncKey SyncResponse where
13+ storageKey SyncKey = "sync"
14+
15+data TokenKey
16+ = TokenKey
17+
18+instance StorageKey TokenKey IdentityTokenResponse where
19+ storageKey TokenKey = "token"
20+
21+data UrlsKey
22+ = UrlsKey
23+
24+instance StorageKey UrlsKey String where
25+ storageKey UrlsKey = "urls"
26+
27+data PreloginResponseKey
28+ = PreloginResponseKey
29+
30+instance StorageKey PreloginResponseKey PreloginResponse where
31+ storageKey PreloginResponseKey = "prelogin-reponse"
32+
33+data MasterPasswordHashKey
34+ = MasterPasswordHashKey
35+
36+instance StorageKey MasterPasswordHashKey Hash where
37+ storageKey MasterPasswordHashKey = "master-password-hash"
38+
39+data DeviceIDKey
40+ = DeviceIDKey
41+
42+instance StorageKey DeviceIDKey String where
43+ storageKey DeviceIDKey = "device-uuid"
bridge.yaml+154−9
@@ -1,14 +1,159 @@
1Sub:
1Sub:
2−- NeedsLogin
2+ - NeedsLogin
3+ - NeedsCaptcha: String
4+ - NeedsSecondFactor: { List: TwoFactorProviderType }
5+ - CaptchaDone
3−- Error: String
6+ - Error: String
4−- LoadCiphers:
7+ - LoadCiphers:
5− List:
8+ List:
6 name: String
9 name: String
7 date: String
10 date: String
11+ id: String
12+ cipherType: CipherType
13+ - LoginSuccessful
14+ - WrongPassword
15+ - NeedsMasterPassword:
16+ server: String
17+ login: String
18+ - Reset
19+ - LoadCipher: FullCipher
20+ - RecieveEmail: String
21+ - CipherChanged: FullCipher
22+ - GeneratedPassword: String
23+ - CipherDeleted: FullCipher
24+ - Totp:
25+ source: String
26+ code: String
27+ interval: Int
8
28
9Cmd:
29Cmd:
10−- Init
30+ - Init
11−- Login:
31+ - Login:
12− email: String
32+ email: String
13− server: String
33+ server: String
14− password: String
34+ password: String
35+ secondFactor:
36+ Maybe:
37+ provider: TwoFactorProviderType
38+ token: String
39+ remember: Bool
40+ - ChooseSecondFactor:
41+ factor: TwoFactorProviderType
42+ email: String
43+ server: String
44+ password: String
45+ requestFromServer: Bool
46+ - NeedCiphersList
47+ - SendMasterPassword: String
48+ - NeedsReset
49+ - RequestCipher: String
50+ - NeedEmail
51+ - Copy: String
52+ - Open: String
53+ - UpdateCipher: FullCipher
54+ - CreateCipher: FullCipher
55+ - GeneratePassword: PasswordGeneratorConfig
56+ - DeleteCipher: FullCipher
57+ - RequestTotp: String
58+
59+FullCipher:
60+ reprompt: Int
61+ favorite: Bool
62+ id: String
63+ name: String
64+ cipher: Cipher
65+ collectionIds: { List: String }
66+
67+Cipher:
68+ - LoginCipher:
69+ uris: { List: String }
70+ username:
71+ Maybe: String
72+ password:
73+ Maybe: String
74+ totp:
75+ Maybe: String
76+ - NoteCipher: String
77+ - CardCipher:
78+ cardholderName:
79+ Maybe: String
80+ brand:
81+ Maybe: String
82+ number:
83+ Maybe: String
84+ expMonth:
85+ Maybe: String
86+ expYear:
87+ Maybe: String
88+ code:
89+ Maybe: String
90+ - IdentityCipher:
91+ title:
92+ Maybe: String
93+ firstName:
94+ Maybe: String
95+ middleName:
96+ Maybe: String
97+ lastName:
98+ Maybe: String
99+ address1:
100+ Maybe: String
101+ address2:
102+ Maybe: String
103+ address3:
104+ Maybe: String
105+ city:
106+ Maybe: String
107+ state:
108+ Maybe: String
109+ postalCode:
110+ Maybe: String
111+ country:
112+ Maybe: String
113+ company:
114+ Maybe: String
115+ email:
116+ Maybe: String
117+ phone:
118+ Maybe: String
119+ ssn:
120+ Maybe: String
121+ username:
122+ Maybe: String
123+ passportNumber:
124+ Maybe: String
125+ licenseNumber:
126+ Maybe: String
127+
128+CipherType:
129+ - LoginType
130+ - CardType
131+ - NoteType
132+ - IdentityType
133+
134+PasswordGeneratorConfig:
135+ length: Int
136+ ambiguous: Bool
137+ number: Bool
138+ minNumber: Int
139+ uppercase: Bool
140+ minUppercase: Int
141+ lowercase: Bool
142+ minLowercase: Int
143+ special: Bool
144+ minSpecial: Int
145+ type: String
146+ numWords: Int
147+ wordSeparator: String
148+ capitalize: Bool
149+ includeNumber: Bool
150+
151+TwoFactorProviderType:
152+ - Authenticator
153+ - Email
154+ - Duo
155+ - Yubikey
156+ - U2f
157+ - Remember
158+ - OrganizationDuo
159+ - WebAuthn
build.sh+2−6
@@ -1,9 +1,5 @@
1−#!/bin/bash
1+#!/bin/sh
2
2
3set -e
3set -e
4
4
5−cp -r "$SRC_DIR"/{appname.apparmor,appname.desktop,vanilla,index.html,style.css,manifest.json,logo.svg} "$INSTALL_DIR"
5+cp -r "$SRC_DIR/dist"/* "$INSTALL_DIR"
6−
7−elm make --debug "$SRC_DIR/frontend/Main.elm" --output="$INSTALL_DIR/elm.js"
8−
9−(cd "$SRC_DIR" && spago bundle-app --to "$INSTALL_DIR/backend.js")
bw/spago.dhalldeleted−20
@@ -1,20 +0,0 @@
1−{ name = "bw"
2−, dependencies =
3− [ "aff"
4− , "aff-promise"
5− , "argonaut"
6− , "argonaut-generic"
7− , "arraybuffer-types"
8− , "console"
9− , "datetime-parsing"
10− , "effect"
11− , "el"
12− , "foreign"
13− , "maybe"
14− , "newtype"
15− , "prelude"
16− , "undefined-is-not-a-problem"
17− ]
18−, packages = ../packages.dhall
19−, sources = [ "src/**/*.purs" ]
20−}
bw/src/BW.pursdeleted−34
@@ -1,34 +0,0 @@
1−module BW where
2−
3−import BW.Types
4−import Prelude
5−import Control.Promise (Promise)
6−import Data.ArrayBuffer.Types (ArrayBuffer)
7−import Data.EncString (EncString)
8−import Data.Function.Uncurried (Fn2, Fn3, Fn4)
9−import Data.Nullable (Nullable)
10−import Data.SymmetricCryptoKey (SymmetricCryptoKey)
11−import Effect (Effect)
12−
13−type CryptoService
14− = { makeKey :: Fn4 Password String KDF Int (Promise SymmetricCryptoKey)
15− , hashPassword :: Fn3 Password SymmetricCryptoKey (Nullable HashPurpose) (Promise Hash)
16− , decryptToUtf8 :: Fn2 EncString SymmetricCryptoKey (Promise String)
17− , decryptToBytes :: Fn2 EncString SymmetricCryptoKey (Promise ArrayBuffer)
18− , stretchKey :: SymmetricCryptoKey -> Promise SymmetricCryptoKey
19− }
20−
21−type ApiService
22− = { postPrelogin :: PreloginRequest -> Promise PreloginResponse
23− , getProfile :: Unit -> Promise ProfileResponse
24− -- TODO: There can really be more request and response types. Maybe handle this later.
25− , postIdentityToken :: PasswordTokenRequest -> Promise IdentityTokenResponse
26− , getSync :: Unit -> Promise SyncResponse
27− }
28−
29−type Services
30− = { crypto :: CryptoService
31− , getApi :: Urls -> Nullable IdentityTokenResponse -> Promise ApiService
32− }
33−
34−foreign import getServices :: Effect Services
bw/src/BW/Logic.pursdeleted−100
@@ -1,100 +0,0 @@
1−module BW.Logic where
2−
3−import BW
4−import BW.Types
5−import Control.El
6−import Prelude
7−import Control.Monad.Error.Class (throwError)
8−import Control.Promise (Promise)
9−import Control.Promise as Promise
10−import Data.EncString as EncString
11−import Data.Function.Uncurried (runFn2, runFn3, runFn4)
12−import Data.Maybe (Maybe(..))
13−import Data.Nullable (null, toNullable)
14−import Data.String as String
15−import Data.SymmetricCryptoKey (SymmetricCryptoKey)
16−import Data.SymmetricCryptoKey as SymmetricCryptoKey
17−import Effect.Aff.Class (class MonadAff, liftAff)
18−import Effect.Class (liftEffect)
19−import Effect.Class.Console (log)
20−import Effect.Exception (error)
21−import Effect.Exception as Exc
22−
23−makePreloginKey ::
24− forall r.
25− HasL "api" ApiService r =>
26− HasL "crypto" CryptoService r =>
27− Email -> Password -> Al r SymmetricCryptoKey
28−makePreloginKey (Email email') (Password password) = do
29− api :: ApiService <- l (L :: L "api")
30− crypto <- l (L :: L "crypto")
31− let
32− email = (String.trim >>> String.toLower) email'
33− { kdf, kdfIterations } <- liftPromise $ api.postPrelogin { email }
34− liftPromise $ runFn4 crypto.makeKey (Password password) email kdf kdfIterations
35−
36−makeDecryptionKey ::
37− forall r.
38− HasL "crypto" CryptoService r =>
39− -- | Matser key (prelogin key)
40− SymmetricCryptoKey -> EncryptedString -> Al r SymmetricCryptoKey
41−makeDecryptionKey masterKey str = do
42− crypto <- l (L :: L "crypto")
43− let
44− encryptedKeyString = EncString.fromString str
45−
46− encType = EncString.encryptionType encryptedKeyString
47− key <-
48− if encType == EncString.encryptionTypeAesCbc256_B64 then
49− liftPromise $ runFn2 crypto.decryptToBytes (EncString.fromString str) masterKey
50− else if encType == EncString.encryptionTypeAesCbc256_HmacSha256_B64 then do
51− stretchedMasterKey <- liftPromise $ crypto.stretchKey masterKey
52− liftPromise $ runFn2 crypto.decryptToBytes (EncString.fromString str) stretchedMasterKey
53− else
54− liftEffect $ Exc.throw $ "Unsupported key encryption type: " <> show encType
55− pure $ SymmetricCryptoKey.fromArrayBuffer key
56−
57−getLogInRequestToken ::
58− forall r.
59− HasL "api" ApiService r =>
60− HasL "crypto" CryptoService r =>
61− Email -> Password -> Al r IdentityTokenResponse
62−getLogInRequestToken email password = do
63− key <- makePreloginKey email password
64− crypto <- l (L :: L "crypto")
65− api :: ApiService <- l (L :: L "api")
66− _localHashedPassword <-
67− liftPromise
68− $ runFn3 crypto.hashPassword password key (toNullable $ Just hashPurposeLocalAuthorization)
69− Hash hashedPassword <- liftPromise $ runFn3 crypto.hashPassword password key null
70− liftPromise
71− $ api.postIdentityToken
72− { email: email
73− , masterPasswordHash: hashedPassword
74− , captchaResponse: ""
75− , twoFactor:
76− { provider: twoFactorProviderTypeEmail
77− , token: ""
78− , remember: false
79− }
80− , device:
81− { type: deviceTypeUnknownBrowser
82− , name: "Temporary device name"
83− , identifier: "42"
84− , pushToken: null
85− }
86− }
87−
88−decrypt ::
89− forall r.
90− HasL "crypto" CryptoService r =>
91− HasL "key" SymmetricCryptoKey r =>
92− EncryptedString ->
93− Al r String
94−decrypt input = do
95− crypto <- l (L :: L "crypto")
96− key <- l (L :: L "key")
97− liftPromise $ runFn2 crypto.decryptToUtf8 (EncString.fromString input) key
98−
99−liftPromise ∷ forall m a. MonadAff m ⇒ Promise a → m a
100−liftPromise = liftAff <<< Promise.toAff
bw/src/BW/Types.pursdeleted−650
@@ -1,650 +0,0 @@
1−module BW.Types where
2−
3−import Prelude
4−
5−import Data.ArrayBuffer.Types (ArrayBuffer)
6−import Data.Date (Date)
7−import Data.Nullable (Nullable)
8−import Data.ShowableJson (ShowableJson)
9−import Data.Timestamp (Timestamp(..))
10−import Data.Undefined.NoProblem (Opt)
11−
12−newtype EncryptedString
13− = EncryptedString String
14−
15−derive newtype instance Show EncryptedString
16−
17−kdfPBKDF2_SHA256 = 0 :: KDF
18−
19−type KDF
20− = Int
21−
22−type PreloginResponse
23− = { kdf :: KDF
24− , kdfIterations :: Int
25− }
26−
27−type PreloginRequest
28− = { email :: String
29− }
30−
31−type ProfileResponse
32− = { id :: String
33− , name :: String
34− , email :: String
35− , emailVerified :: Boolean
36− , masterPasswordHint :: String
37− , premiumPersonally :: Boolean
38− , premiumFromOrganization :: Boolean
39− , culture :: String
40− , twoFactorEnabled :: Boolean
41− , key :: EncryptedString
42− , privateKey :: EncryptedString
43− , securityStamp :: String
44− , forcePasswordReset :: Boolean
45− , usesKeyConnector :: Boolean
46− , organizations :: Array ProfileOrganizationResponse
47− , providers :: Array ProfileProviderResponse
48− , providerOrganizations :: Array ProfileProviderOrganizationResponse
49− }
50−
51−type ProfileOrganizationResponse
52− = { id :: String
53− , name :: String
54− , usePolicies :: Boolean
55− , useGroups :: Boolean
56− , useDirectory :: Boolean
57− , useEvents :: Boolean
58− , useTotp :: Boolean
59− , use2fa :: Boolean
60− , useApi :: Boolean
61− , useSso :: Boolean
62− , useKeyConnector :: Boolean
63− , useResetPassword :: Boolean
64− , selfHost :: Boolean
65− , usersGetPremium :: Boolean
66− , seats :: Int
67− , maxCollections :: Int
68− , maxStorageGb :: Nullable Int
69− , key :: String
70− , hasPublicAndPrivateKeys :: Boolean
71− , status :: OrganizationUserStatusType
72− , type :: OrganizationUserType
73− , enabled :: Boolean
74− , ssoBound :: Boolean
75− , identifier :: String
76− , permissions :: PermissionsApi
77− , resetPasswordEnrolled :: Boolean
78− , userId :: String
79− , providerId :: String
80− , providerName :: String
81− , familySponsorshipFriendlyName :: String
82− , familySponsorshipAvailable :: Boolean
83− , planProductType :: ProductType
84− , keyConnectorEnabled :: Boolean
85− , keyConnectorUrl :: String
86− , familySponsorshipLastSyncDate :: Nullable Date
87− , familySponsorshipValidUntil :: Nullable Date
88− , familySponsorshipToDelete :: Nullable Boolean
89− }
90−
91−organizationUserStatusTypeInvited = 0 :: OrganizationUserStatusType
92−
93−organizationUserStatusTypeAccepted = 0 :: OrganizationUserStatusType
94−
95−organizationUserStatusTypeConfirmed = 0 :: OrganizationUserStatusType
96−
97−type OrganizationUserStatusType
98− = Int
99−
100−organizationUserTypeOwner = 0 :: OrganizationUserType
101−
102−organizationUserTypeAdmin = 1 :: OrganizationUserType
103−
104−organizationUserTypeUser = 2 :: OrganizationUserType
105−
106−organizationUserTypeManager = 3 :: OrganizationUserType
107−
108−organizationUserTypeCustom = 4 :: OrganizationUserType
109−
110−type OrganizationUserType
111− = Int
112−
113−type PermissionsApi
114− = { accessEventLogs :: Boolean
115− , accessImportExport :: Boolean
116− , accessReports :: Boolean
117− , manageAllCollections :: Boolean
118− , createNewCollections :: Boolean
119− , editAnyCollection :: Boolean
120− , deleteAnyCollection :: Boolean
121− , manageAssignedCollections :: Boolean
122− , editAssignedCollections :: Boolean
123− , deleteAssignedCollections :: Boolean
124− , manageCiphers :: Boolean
125− , manageGroups :: Boolean
126− , manageSso :: Boolean
127− , managePolicies :: Boolean
128− , manageUsers :: Boolean
129− , manageResetPassword :: Boolean
130− }
131−
132−productTypeFree = 0 :: ProductType
133−
134−productTypeFamilies = 1 :: ProductType
135−
136−productTypeTeams = 2 :: ProductType
137−
138−productTypeEnterprise = 3 :: ProductType
139−
140−type ProductType
141− = Int
142−
143−type ProfileProviderResponse
144− = { id :: String
145− , name :: String
146− , key :: String
147− , status :: ProviderUserStatusType
148− , type :: ProviderUserType
149− , enabled :: Boolean
150− , permissions :: PermissionsApi
151− , userId :: String
152− , useEvents :: Boolean
153− }
154−
155−providerUserStatusTypeInvited = 0 :: ProviderUserStatusType
156−
157−providerUserStatusTypeAccepted = 1 :: ProviderUserStatusType
158−
159−providerUserStatusTypeConfirmed = 2 :: ProviderUserStatusType
160−
161−type ProviderUserStatusType
162− = Int
163−
164−providerUserTypeProviderAdmin = 0 :: ProviderUserType
165−
166−providerUserTypeServiceUser = 1 :: ProviderUserType
167−
168−type ProviderUserType
169− = Int
170−
171−type ProfileProviderOrganizationResponse
172− = { id :: String
173− , name :: String
174− , usePolicies :: Boolean
175− , useGroups :: Boolean
176− , useDirectory :: Boolean
177− , useEvents :: Boolean
178− , useTotp :: Boolean
179− , use2fa :: Boolean
180− , useApi :: Boolean
181− , useSso :: Boolean
182− , useKeyConnector :: Boolean
183− , useResetPassword :: Boolean
184− , selfHost :: Boolean
185− , usersGetPremium :: Boolean
186− , seats :: Int
187− , maxCollections :: Int
188− , maxStorageGb :: Nullable Int
189− , key :: String
190− , hasPublicAndPrivateKeys :: Boolean
191− , status :: OrganizationUserStatusType
192− , type :: OrganizationUserType
193− , enabled :: Boolean
194− , ssoBound :: Boolean
195− , identifier :: String
196− , permissions :: PermissionsApi
197− , resetPasswordEnrolled :: Boolean
198− , userId :: String
199− , providerId :: String
200− , providerName :: String
201− , familySponsorshipFriendlyName :: String
202− , familySponsorshipAvailable :: Boolean
203− , planProductType :: ProductType
204− , keyConnectorEnabled :: Boolean
205− , keyConnectorUrl :: String
206− , familySponsorshipLastSyncDate :: Nullable Date
207− , familySponsorshipValidUntil :: Nullable Date
208− , familySponsorshipToDelete :: Nullable Boolean
209− }
210−
211−type Urls
212− = { base :: Nullable String
213− , webVault :: Nullable String
214− , api :: Nullable String
215− , identity :: Nullable String
216− , icons :: Nullable String
217− , notifications :: Nullable String
218− , events :: Nullable String
219− , keyConnector :: Nullable String
220− }
221−
222−type PasswordTokenRequest
223− = { email :: Email
224− , masterPasswordHash :: String
225− , captchaResponse :: String
226− , twoFactor :: TokenRequestTwoFactor
227− , device :: DeviceRequest
228− }
229−
230−type DeviceRequest
231− = { type :: DeviceType
232− , name :: String
233− , identifier :: String
234− , pushToken :: Nullable String
235− }
236−
237−deviceTypeAndroid = 0 :: DeviceType
238−
239−deviceTypeiOS = 1 :: DeviceType
240−
241−deviceTypeChromeExtension = 2 :: DeviceType
242−
243−deviceTypeFirefoxExtension = 3 :: DeviceType
244−
245−deviceTypeOperaExtension = 4 :: DeviceType
246−
247−deviceTypeEdgeExtension = 5 :: DeviceType
248−
249−deviceTypeWindowsDesktop = 6 :: DeviceType
250−
251−deviceTypeMacOsDesktop = 7 :: DeviceType
252−
253−deviceTypeLinuxDesktop = 8 :: DeviceType
254−
255−deviceTypeChromeBrowser = 9 :: DeviceType
256−
257−deviceTypeFirefoxBrowser = 10 :: DeviceType
258−
259−deviceTypeOperaBrowser = 11 :: DeviceType
260−
261−deviceTypeEdgeBrowser = 12 :: DeviceType
262−
263−deviceTypeIEBrowser = 13 :: DeviceType
264−
265−deviceTypeUnknownBrowser = 14 :: DeviceType
266−
267−deviceTypeAndroidAmazon = 15 :: DeviceType
268−
269−deviceTypeUWP = 16 :: DeviceType
270−
271−deviceTypeSafariBrowser = 17 :: DeviceType
272−
273−deviceTypeVivaldiBrowser = 18 :: DeviceType
274−
275−deviceTypeVivaldiExtension = 19 :: DeviceType
276−
277−deviceTypeSafariExtension = 20 :: DeviceType
278−
279−type DeviceType
280− = Int
281−
282−type TokenRequestTwoFactor
283− = { provider :: TwoFactorProviderType
284− , token :: String
285− , remember :: Boolean
286− }
287−
288−twoFactorProviderTypeAuthenticator = 0 :: TwoFactorProviderType
289−
290−twoFactorProviderTypeEmail = 1 :: TwoFactorProviderType
291−
292−twoFactorProviderTypeDuo = 2 :: TwoFactorProviderType
293−
294−twoFactorProviderTypeYubikey = 3 :: TwoFactorProviderType
295−
296−twoFactorProviderTypeU2f = 4 :: TwoFactorProviderType
297−
298−twoFactorProviderTypeRemember = 5 :: TwoFactorProviderType
299−
300−twoFactorProviderTypeOrganizationDuo = 6 :: TwoFactorProviderType
301−
302−twoFactorProviderTypeWebAuthn = 7 :: TwoFactorProviderType
303−
304−type TwoFactorProviderType
305− = Int
306−
307−newtype Password
308− = Password String
309−
310−hashPurposeServerAuthorization = 1 :: HashPurpose
311−
312−hashPurposeLocalAuthorization = 2 :: HashPurpose
313−
314−type HashPurpose
315− = Int
316−
317−newtype Hash
318− = Hash String
319−
320−newtype AccessToken
321− = AccessToken String
322−
323−derive newtype instance Show AccessToken
324−
325−newtype RefreshToken
326− = RefreshToken String
327−
328−derive newtype instance Show RefreshToken
329−
330−
331−type IdentityTokenResponse
332− = { accessToken :: AccessToken
333− , expiresIn :: Int
334− , refreshToken :: RefreshToken
335− , tokenType :: String
336− , resetMasterPassword :: Boolean
337− , privateKey :: EncryptedString
338− , key :: EncryptedString
339− , twoFactorToken :: Nullable String
340− , kdf :: KDF
341− , kdfIterations :: Int
342− , forcePasswordReset :: Nullable Boolean
343− , apiUseKeyConnector :: Nullable Boolean
344− , keyConnectorUrl :: Nullable String
345− }
346−
347−newtype Email
348− = Email String
349−
350−type SyncResponse
351− = { profile :: ProfileResponse
352− , folders :: Array FolderResponse
353− , collections :: Array CollectionDetailsResponse
354− , ciphers :: Array CipherResponse
355− , domains :: Nullable DomainsResponse
356− , policies :: Nullable (Array PolicyResponse)
357− , sends :: Array SendResponse
358− }
359−
360−type FolderResponse
361− = { id :: String
362− , name :: String
363− , revisionDate :: String
364− }
365−
366−type CollectionDetailsResponse
367− = { id :: String
368− , organizationId :: Nullable String
369− , name :: String
370− , externalId :: Nullable String
371− , readOnly :: Boolean
372− }
373−
374−type CipherResponse
375− = { id :: String
376− , organizationId :: Nullable String
377− , folderId :: Nullable String
378− , type :: CipherType
379− , name :: EncryptedString
380− , notes :: Nullable EncryptedString
381− , fields :: Nullable (Array FieldApi)
382− , login :: Nullable LoginApi
383− , card :: Nullable CardApi
384− , identity :: Nullable IdentityApi
385− , secureNote :: Nullable SecureNoteApi
386− , favorite :: Boolean
387− , edit :: Boolean
388− , viewPassword :: Boolean
389− , organizationUseTotp :: Boolean
390− , revisionDate :: Timestamp
391− , attachments :: Nullable (Array AttachmentResponse)
392− , passwordHistory :: Nullable (Array PasswordHistoryResponse)
393− , collectionIds :: Nullable (Array String)
394− , deletedDate :: Nullable String
395− , reprompt :: CipherRepromptType
396− }
397−
398−cipherTypeLogin = 1 :: CipherType
399−
400−cipherTypeSecureNote = 2 :: CipherType
401−
402−cipherTypeCard = 3 :: CipherType
403−
404−cipherTypeIdentity = 4 :: CipherType
405−
406−type CipherType
407− = Int
408−
409−type FieldApi
410− = { name :: String
411− , value :: String
412− , type :: FieldType
413− , linkedId :: Nullable LinkedIdType
414− }
415−
416−fieldTypeText = 0 :: FieldType
417−
418−fieldTypeHidden = 1 :: FieldType
419−
420−fieldTypeBoolean = 2 :: FieldType
421−
422−fieldTypeLinked = 3 :: FieldType
423−
424−type FieldType
425− = Int
426−
427−linkedIdTypeLoginLinkedIdUsername = 100 :: LinkedIdType
428−
429−linkedIdTypeLoginLinkedIdPassword = 101 :: LinkedIdType
430−
431−linkedIdTypeCardLinkedIdCardholderName = 300 :: LinkedIdType
432−
433−linkedIdTypeCardLinkedIdExpMonth = 301 :: LinkedIdType
434−
435−linkedIdTypeCardLinkedIdExpYear = 302 :: LinkedIdType
436−
437−linkedIdTypeCardLinkedIdCode = 303 :: LinkedIdType
438−
439−linkedIdTypeCardLinkedIdBrand = 304 :: LinkedIdType
440−
441−linkedIdTypeCardLinkedIdNumber = 305 :: LinkedIdType
442−
443−linkedIdTypeIdentityLinkedIdTitle = 400 :: LinkedIdType
444−
445−linkedIdTypeIdentityLinkedIdMiddleName = 401 :: LinkedIdType
446−
447−linkedIdTypeIdentityLinkedIdAddress1 = 402 :: LinkedIdType
448−
449−linkedIdTypeIdentityLinkedIdAddress2 = 403 :: LinkedIdType
450−
451−linkedIdTypeIdentityLinkedIdAddress3 = 404 :: LinkedIdType
452−
453−linkedIdTypeIdentityLinkedIdCity = 405 :: LinkedIdType
454−
455−linkedIdTypeIdentityLinkedIdState = 406 :: LinkedIdType
456−
457−linkedIdTypeIdentityLinkedIdPostalCode = 407 :: LinkedIdType
458−
459−linkedIdTypeIdentityLinkedIdCountry = 408 :: LinkedIdType
460−
461−linkedIdTypeIdentityLinkedIdCompany = 409 :: LinkedIdType
462−
463−linkedIdTypeIdentityLinkedIdEmail = 410 :: LinkedIdType
464−
465−linkedIdTypeIdentityLinkedIdPhone = 411 :: LinkedIdType
466−
467−linkedIdTypeIdentityLinkedIdSsn = 412 :: LinkedIdType
468−
469−linkedIdTypeIdentityLinkedIdUsername = 413 :: LinkedIdType
470−
471−linkedIdTypeIdentityLinkedIdPassportNumber = 414 :: LinkedIdType
472−
473−linkedIdTypeIdentityLinkedIdLicenseNumber = 415 :: LinkedIdType
474−
475−linkedIdTypeIdentityLinkedIdFirstName = 416 :: LinkedIdType
476−
477−linkedIdTypeIdentityLinkedIdLastName = 417 :: LinkedIdType
478−
479−linkedIdTypeIdentityLinkedIdFullName = 418 :: LinkedIdType
480−
481−type LinkedIdType
482− = Int
483−
484−type LoginApi
485− = { uris :: Opt (Array LoginUriApi)
486− , username :: Nullable EncryptedString
487− , password :: Nullable EncryptedString
488− , passwordRevisionDate :: Nullable String
489− , totp :: Nullable EncryptedString
490− -- This thing is undefined in some cases for some reson. Just ignoring it
491− , autofillOnPageLoad :: Opt (Nullable Boolean)
492− }
493−
494−type LoginUriApi
495− = { uri :: String
496− , match :: Nullable UriMatchType
497− }
498−
499−uriMatchTypeDomain = 0 :: UriMatchType
500−
501−uriMatchTypeHost = 1 :: UriMatchType
502−
503−uriMatchTypeStartsWith = 2 :: UriMatchType
504−
505−uriMatchTypeExact = 3 :: UriMatchType
506−
507−uriMatchTypeRegularExpression = 4 :: UriMatchType
508−
509−uriMatchTypeNever = 5 :: UriMatchType
510−
511−type UriMatchType
512− = Int
513−
514−type CardApi
515− = { cardholderName :: Nullable String
516− , brand :: Nullable String
517− , number :: Nullable String
518− , expMonth :: Nullable String
519− , expYear :: Nullable String
520− , code :: Nullable String
521− }
522−
523−type IdentityApi
524− = { title :: String
525− , firstName :: String
526− , middleName :: String
527− , lastName :: String
528− , address1 :: String
529− , address2 :: String
530− , address3 :: String
531− , city :: String
532− , state :: String
533− , postalCode :: String
534− , country :: String
535− , company :: String
536− , email :: String
537− , phone :: String
538− , ssn :: String
539− , username :: String
540− , passportNumber :: String
541− , licenseNumber :: String
542− }
543−
544−secureNoteApiGeneric = 0 :: SecureNoteApi
545−
546−type SecureNoteApi
547− = Int
548−
549−type AttachmentResponse
550− = { id :: String
551− , url :: String
552− , fileName :: String
553− , key :: String
554− , size :: String
555− , sizeName :: String
556− }
557−
558−type PasswordHistoryResponse
559− = { password :: String
560− , lastUsedDate :: String
561− }
562−
563−cipherRepromptTypeNone = 0 :: CipherRepromptType
564−
565−cipherRepromptTypePassword = 1 :: CipherRepromptType
566−
567−type CipherRepromptType
568− = Int
569−
570−type DomainsResponse
571− = { equivalentDomains :: Array (Array String)
572− , globalEquivalentDomains :: Array GlobalDomainResponse
573− }
574−
575−type GlobalDomainResponse
576− = { type :: Int
577− , domains :: Array String
578− , excluded :: Boolean
579− }
580−
581−type PolicyResponse
582− = { id :: String
583− , organizationId :: Nullable String
584− , type :: PolicyType
585− , data :: ShowableJson
586− , enabled :: Boolean
587− }
588−
589−policyTypeTwoFactorAuthentication = 0 :: PolicyType -- Requires users to have 2fa enabled
590−
591−policyTypeMasterPassword = 1 :: PolicyType -- Sets minimum requirements for master password complexity
592−
593−policyTypePasswordGenerator = 2 :: PolicyType -- Sets minimum requirements/default type for generated passwords/passphrases
594−
595−policyTypeSingleOrg = 3 :: PolicyType -- Allows users to only be apart of one organization
596−
597−policyTypeRequireSso = 4 :: PolicyType -- Requires users to authenticate with SSO
598−
599−policyTypePersonalOwnership = 5 :: PolicyType -- Disables personal vault ownership for adding/cloning items
600−
601−policyTypeDisableSend = 6 :: PolicyType -- Disables the ability to create and edit Bitwarden Sends
602−
603−policyTypeSendOptions = 7 :: PolicyType -- Sets restrictions or defaults for Bitwarden Sends
604−
605−policyTypeResetPassword = 8 :: PolicyType -- Allows orgs to use reset password : also can enable auto-enrollment during invite flow
606−
607−policyTypeMaximumVaultTimeout = 9 :: PolicyType -- Sets the maximum allowed vault timeout
608−
609−policyTypeDisablePersonalVaultExport = 10 :: PolicyType -- Disable personal vault export
610−
611−type PolicyType
612− = Int
613−
614−type SendResponse
615− = { id :: String
616− , accessId :: String
617− , type :: SendType
618− , name :: String
619− , notes :: Nullable String
620− , file :: Nullable SendFileApi
621− , text :: Nullable SendTextApi
622− , key :: String
623− , maxAccessCount :: Nullable Int
624− , accessCount :: Int
625− , revisionDate :: String
626− , expirationDate :: String
627− , deletionDate :: Nullable String
628− , password :: String
629− , disable :: Boolean
630− , hideEmail :: Boolean
631− }
632−
633−sendTypeText = 0 :: SendType
634−
635−sendTypeFile = 1 :: SendType
636−
637−type SendType
638− = Int
639−
640−type SendFileApi
641− = { id :: String
642− , fileName :: String
643− , size :: String
644− , sizeName :: String
645− }
646−
647−type SendTextApi
648− = { text :: String
649− , hidden :: Boolean
650− }
bw/src/Data/ShowableJson.pursdeleted−14
@@ -1,14 +0,0 @@
1−module Data.ShowableJson
2− ( ShowableJson(..)
3− )
4− where
5−
6−import Prelude
7−
8−import Data.Argonaut (Json)
9−import Data.Argonaut as Json
10−
11−newtype ShowableJson = ShowableJson Json
12−
13−instance Show ShowableJson where
14− show (ShowableJson x) = Json.stringify x
bw/src/Data/SymmetricCryptoKey.jsdeleted−6
@@ -1,6 +0,0 @@
1−import { SymmetricCryptoKey } from '../../deps/bw/libs/shared/dist/src/models/domain/symmetricCryptoKey.js';
2−
3−export function fromArrayBuffer(arr) {
4− console.log("fromArrayBuffer " + arr)
5− return new SymmetricCryptoKey(arr)
6−}
clickable.yaml+2−11
@@ -1,17 +1,8 @@
1clickable_minimum_required: 7.1.2
1clickable_minimum_required: 7.1.2
2+framework: ubuntu-sdk-20.04
2builder: custom
3builder: custom
3build: $SRC_DIR/build.sh
4build: $SRC_DIR/build.sh
4kill: webapp-container*
5kill: webapp-container*
5−image_setup:
6+docker_image: clickable/amd64-20.04-amd64
6− env: {}
7− # DEB_URL: http://archive.ubuntu.com/ubuntu
8− # HOST_ARCH: amd64
9−
10− # PATH: /opt/someprogram/bin:$PATH
11− run:
12−
13− - (cd /tmp && curl -L -o elm.gz https://github.com/elm/compiler/releases/download/0.19.1/binary-for-linux-64-bit.gz && gunzip elm.gz && chmod +x elm && mv elm /usr/local/bin/)
14− - npm install -g spago esbuild purescript --unsafe-perm=true
15− - (cd / && curl https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.37.1.tar.xz >git.tar.gz && tar -xvf git.tar.gz && cd git-2.37.1 && ./configure --without-curl && make)
16
7
17restrict_arch: all
8restrict_arch: all
deps/bwdeleted−1

Submodule changed.

dev/build-backend.sh+7−1
@@ -1,3 +1,9 @@
1#!/bin/sh
1#!/bin/sh
2
2
3−spago bundle-app --to backend.js
3+set -e
4+
5+spago build
6+
7+export out="$(pwd)/backend.js"
8+
9+$(nix build .#backendBuildScript --print-out-paths) "$(pwd)/output"
dev/build-bw.sh+2
@@ -1,5 +1,7 @@
1#!/bin/sh
1#!/bin/sh
2
2
3+set -e
4+
3(cd deps/bw && npm install)
5(cd deps/bw && npm install)
4
6
5(cd deps/bw/libs/common/ && npm run clean && npm exec -c "tsc -m es2020 -t es2018")
7(cd deps/bw/libs/common/ && npm run clean && npm exec -c "tsc -m es2020 -t es2018")
dev/build.shnew file+10
@@ -0,0 +1,10 @@
1+#!/bin/sh
2+
3+
4+rm -r dist
5+
6+mkdir -p dist
7+
8+cp -r "$(nix build ".#warden-click-src" --print-out-paths)"/* dist
9+
10+chmod -R 777 dist
dev/elm-live.sh+5−1
@@ -1,3 +1,7 @@
1#!/bin/sh
1#!/bin/sh
2
2
3+set -e
4+
5+nix build .#vanilla -o vanilla
6+
3−elm-live frontend/Main.elm --start-page=index.html --proxy-prefix=/api --proxy-host=http://localhost:6009 --pushstate -- --debug --output=elm.js
7+nix run github:NixOS/nixpkgs?rev=d9a1414346059619d9e13ab93e749bbb82e5252a#elmPackages.elm-live -- $1 --start-page=index.html --proxy-prefix=/api --proxy-host=http://localhost:6009 -- --debug --output=elm.js
dev/elm2nix.shnew file+8
@@ -0,0 +1,8 @@
1+#!/bin/sh
2+
3+set -e
4+
5+cd "$(dirname "$0")/.."
6+
7+nix run github:NixOS/nixpkgs#elm2nix -- snapshot
8+nix run github:NixOS/nixpkgs#elm2nix -- convert > elm-srcs.nix
dev/generate-bridge.sh+1−1
@@ -1,3 +1,3 @@
1#!/bin/sh
1#!/bin/sh
2
2
3−elm-ps-bridge --input bridge.yaml --elmOutput=Frontend/Bridge.elm --psOutput=backend/Bridge.purs
3+nix run github:ilyakooo0/elm-ps-bridge -- --input bridge.yaml --elmOutput=frontend/Bridge.elm --psOutput=backend/Bridge.purs
dev/record-test.shnew file+11
@@ -0,0 +1,11 @@
1+#!/bin/sh
2+
3+set -e
4+
5+cd tests
6+
7+npm install
8+
9+export RECORD_TEST=true
10+
11+npx playwright test
dev/spago2nix.shnew file+3
@@ -0,0 +1,3 @@
1+#!/bin/sh
2+
3+nix run "github:justinwoo/spago2nix#spago2nix" -- generate
dev/start-chrome.sh+7−1
@@ -1,3 +1,9 @@
1#!/bin/sh
1#!/bin/sh
2
2
3+if test -x "$(which chromium)"; then
4+ chromium --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
3−/Applications/Chromium.app/Contents/MacOS/Chromium --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
5+elif test -x /Applications/Chromium.app/Contents/MacOS/Chromium; then
6+ /Applications/Chromium.app/Contents/MacOS/Chromium --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
7+else
8+ flatpak run com.github.Eloston.UngoogledChromium --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
9+fi
dev/test.shnew file+9
@@ -0,0 +1,9 @@
1+#!/bin/sh
2+
3+set -e
4+
5+cd tests
6+
7+npm install
8+
9+npx playwright test
dev/update-tests.shnew file+9
@@ -0,0 +1,9 @@
1+#!/bin/sh
2+
3+set -e
4+
5+cd tests
6+
7+npm install
8+
9+npx playwright test --update-snapshots
el/spago.dhalldeleted−14
@@ -1,14 +0,0 @@
1−{ name = "bw"
2−, dependencies =
3− [ "aff"
4− , "effect"
5− , "newtype"
6− , "prelude"
7− , "record"
8− , "test-unit"
9− , "transformers"
10− , "unsafe-coerce"
11− ]
12−, packages = ../packages.dhall
13−, sources = [ "src/**/*.purs", "test/**/*.purs" ]
14−}
el/src/Control/El.pursdeleted−23
@@ -1,23 +0,0 @@
1−module Control.El (El, Al, l, class HasL, L(..)) where
2−
3−
4−import Control.Monad.Reader (class MonadAsk, ReaderT, asks)
5−import Data.Symbol (class IsSymbol, reflectSymbol)
6−import Effect (Effect)
7−import Effect.Aff (Aff)
8−import Prim.Row (class Cons, class Nub)
9−import Record.Unsafe (unsafeGet)
10−import Type.Proxy (Proxy(..))
11−
12−data L :: forall k. k -> Type
13−data L t = L
14−
15−type El r = ReaderT (Record r) Effect
16−type Al r = ReaderT (Record r) Aff
17−
18−l :: forall res r field m. MonadAsk (Record r) m => HasL field res r => IsSymbol field => L field -> m res
19−l L = asks (unsafeGet (reflectSymbol (Proxy :: Proxy field)))
20−
21−class HasL :: forall k1 k2 k3. k1 -> k2 -> k3 -> Constraint
22−class HasL field t r | field r -> t
23−instance (Cons field t r r', Nub r' r) => HasL field t r
el/test/Main.pursdeleted−27
@@ -1,27 +0,0 @@
1−module Test.Main
2− ( main
3− )
4− where
5−
6−import Prelude
7−import Test.Unit
8−
9−import Control.El
10−import Control.Monad.Reader (runReaderT)
11−import Effect (Effect)
12−import Effect.Aff (launchAff_)
13−import Test.Unit.Assert as Assert
14−import Test.Unit.Output.Fancy (runTest)
15−import Type.Proxy (Proxy(..))
16−
17−main ∷ Effect Unit
18−main = launchAff_ $ void $ runTest do
19− suite "sync code" do
20− test "arithmetic" do
21− x <- runReaderT singleHandler {handle: 2, ignore: "Hello"}
22− Assert.equal x 2
23−
24−
25−singleHandler :: forall r. HasL "handle" Int r => Al r Int
26−singleHandler = do
27− l (L :: L "handle")
elm-srcs.nixnew file+62
@@ -0,0 +1,62 @@
1+{
2+
3+ "FabienHenon/elm-infinite-scroll" = {
4+ sha256 = "0vhh7j3lna05l5hwjazag52lbkjv11s80jj62m9wb53qxkarw948";
5+ version = "3.0.3";
6+ };
7+
8+ "bartavelle/json-helpers" = {
9+ sha256 = "0k96qra2nq1j4j4ahfl98dkpkc6f2831mq5d5xxg27mp31qwq5nn";
10+ version = "2.0.2";
11+ };
12+
13+ "elm/browser" = {
14+ sha256 = "0nagb9ajacxbbg985r4k9h0jadqpp0gp84nm94kcgbr5sf8i9x13";
15+ version = "1.0.2";
16+ };
17+
18+ "elm/core" = {
19+ sha256 = "19w0iisdd66ywjayyga4kv2p1v9rxzqjaxhckp8ni6n8i0fb2dvf";
20+ version = "1.0.5";
21+ };
22+
23+ "elm/html" = {
24+ sha256 = "1n3gpzmpqqdsldys4ipgyl1zacn0kbpc3g4v3hdpiyfjlgh8bf3k";
25+ version = "1.0.0";
26+ };
27+
28+ "elm/json" = {
29+ sha256 = "0kjwrz195z84kwywaxhhlnpl3p251qlbm5iz6byd6jky2crmyqyh";
30+ version = "1.1.3";
31+ };
32+
33+ "elm/time" = {
34+ sha256 = "0vch7i86vn0x8b850w1p69vplll1bnbkp8s383z7pinyg94cm2z1";
35+ version = "1.0.0";
36+ };
37+
38+ "mdgriffith/elm-ui" = {
39+ sha256 = "0ffcqv4a4ad400hwp824m3qq4jy82cqp5ghmhp1m0q7n004z6kgv";
40+ version = "1.1.8";
41+ };
42+
43+ "mgold/elm-nonempty-list" = {
44+ sha256 = "02d3xgasgy5knh02rgl403z9hwlbyrsnp9wavc2lhkxxa2misrgl";
45+ version = "4.2.0";
46+ };
47+
48+ "elm/random" = {
49+ sha256 = "138n2455wdjwa657w6sjq18wx2r0k60ibpc4frhbqr50sncxrfdl";
50+ version = "1.0.0";
51+ };
52+
53+ "elm/url" = {
54+ sha256 = "0av8x5syid40sgpl5vd7pry2rq0q4pga28b4yykn9gd9v12rs3l4";
55+ version = "1.0.0";
56+ };
57+
58+ "elm/virtual-dom" = {
59+ sha256 = "1yvb8px2z62xd578ag2q0r5hd1vkz9y7dfkx05355iiy1d7jwq4v";
60+ version = "1.0.3";
61+ };
62+}
elm.json+5−1
@@ -6,14 +6,18 @@
6 "elm-version": "0.19.1",
6 "elm-version": "0.19.1",
7 "dependencies": {
7 "dependencies": {
8 "direct": {
8 "direct": {
9+ "FabienHenon/elm-infinite-scroll": "3.0.3",
9 "bartavelle/json-helpers": "2.0.2",
10 "bartavelle/json-helpers": "2.0.2",
10 "elm/browser": "1.0.2",
11 "elm/browser": "1.0.2",
11 "elm/core": "1.0.5",
12 "elm/core": "1.0.5",
12 "elm/html": "1.0.0",
13 "elm/html": "1.0.0",
13 "elm/json": "1.1.3",
14 "elm/json": "1.1.3",
14− "elm/time": "1.0.0"
15+ "elm/time": "1.0.0",
16+ "mdgriffith/elm-ui": "1.1.8",
17+ "mgold/elm-nonempty-list": "4.2.0"
15 },
18 },
16 "indirect": {
19 "indirect": {
20+ "elm/random": "1.0.0",
17 "elm/url": "1.0.0",
21 "elm/url": "1.0.0",
18 "elm/virtual-dom": "1.0.3"
22 "elm/virtual-dom": "1.0.3"
19 }
23 }
flake.locknew file+177
@@ -0,0 +1,177 @@
1+{
2+ "nodes": {
3+ "bw": {
4+ "flake": false,
5+ "locked": {
6+ "lastModified": 1675446731,
7+ "narHash": "sha256-IbFjYNYZep6W9c+dztJ9CXrwQ0cep3EKb6qnEvv4pj4=",
8+ "owner": "bitwarden",
9+ "repo": "clients",
10+ "rev": "ff143760d4f527f2349333ee4b3004eeda68fac5",
11+ "type": "github"
12+ },
13+ "original": {
14+ "owner": "bitwarden",
15+ "repo": "clients",
16+ "rev": "ff143760d4f527f2349333ee4b3004eeda68fac5",
17+ "type": "github"
18+ }
19+ },
20+ "easy-ps": {
21+ "flake": false,
22+ "locked": {
23+ "lastModified": 1671011575,
24+ "narHash": "sha256-tESal32bcqqdZO+aKnBzc1GoL2mtnaDtj2y7ociCRGA=",
25+ "owner": "justinwoo",
26+ "repo": "easy-purescript-nix",
27+ "rev": "11d3bd58ce6e32703bf69cec04dc7c38eabe14ba",
28+ "type": "github"
29+ },
30+ "original": {
31+ "owner": "justinwoo",
32+ "repo": "easy-purescript-nix",
33+ "type": "github"
34+ }
35+ },
36+ "easy-purescript-nix": {
37+ "flake": false,
38+ "locked": {
39+ "lastModified": 1670198178,
40+ "narHash": "sha256-5KkyNpPakv4xIP2ba0S5GX+dcmd3AcO9kPhwa482BbA=",
41+ "owner": "justinwoo",
42+ "repo": "easy-purescript-nix",
43+ "rev": "7a4cb3cd6ca53566ea1675692eab0aa13907ff09",
44+ "type": "github"
45+ },
46+ "original": {
47+ "owner": "justinwoo",
48+ "repo": "easy-purescript-nix",
49+ "type": "github"
50+ }
51+ },
52+ "flake-utils": {
53+ "locked": {
54+ "lastModified": 1676283394,
55+ "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=",
56+ "owner": "numtide",
57+ "repo": "flake-utils",
58+ "rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073",
59+ "type": "github"
60+ },
61+ "original": {
62+ "owner": "numtide",
63+ "repo": "flake-utils",
64+ "type": "github"
65+ }
66+ },
67+ "flake-utils_2": {
68+ "locked": {
69+ "lastModified": 1667395993,
70+ "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
71+ "owner": "numtide",
72+ "repo": "flake-utils",
73+ "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
74+ "type": "github"
75+ },
76+ "original": {
77+ "owner": "numtide",
78+ "repo": "flake-utils",
79+ "type": "github"
80+ }
81+ },
82+ "nix-filter": {
83+ "locked": {
84+ "lastModified": 1676294984,
85+ "narHash": "sha256-hdLUa/3RH1VJ+gMUysQE0JGM4F2Q/tIIFbtoxAOurJQ=",
86+ "owner": "numtide",
87+ "repo": "nix-filter",
88+ "rev": "fc282c5478e4141842f9644c239a41cfe9586732",
89+ "type": "github"
90+ },
91+ "original": {
92+ "owner": "numtide",
93+ "repo": "nix-filter",
94+ "type": "github"
95+ }
96+ },
97+ "nixpkgs": {
98+ "locked": {
99+ "lastModified": 1677080879,
100+ "narHash": "sha256-0SjW4/d3Rkw6C7hHZ5lxT4r6Pw9vzQb6Il6zYWwe2Bo=",
101+ "owner": "NixOS",
102+ "repo": "nixpkgs",
103+ "rev": "f5dad40450d272a1ea2413f4a67ac08760649e89",
104+ "type": "github"
105+ },
106+ "original": {
107+ "id": "nixpkgs",
108+ "type": "indirect"
109+ }
110+ },
111+ "nixpkgs_2": {
112+ "locked": {
113+ "lastModified": 1670507980,
114+ "narHash": "sha256-riNZa0xzM1it3pzxciwALeMs+0CsBMWIW2FqulzK8vM=",
115+ "owner": "NixOS",
116+ "repo": "nixpkgs",
117+ "rev": "2787fc7d1e51404678614bf0fe92fc296746eec0",
118+ "type": "github"
119+ },
120+ "original": {
121+ "owner": "NixOS",
122+ "ref": "nixos-unstable",
123+ "repo": "nixpkgs",
124+ "type": "github"
125+ }
126+ },
127+ "root": {
128+ "inputs": {
129+ "bw": "bw",
130+ "easy-ps": "easy-ps",
131+ "flake-utils": "flake-utils",
132+ "nix-filter": "nix-filter",
133+ "nixpkgs": "nixpkgs",
134+ "spago2nix": "spago2nix",
135+ "vanilla": "vanilla"
136+ }
137+ },
138+ "spago2nix": {
139+ "inputs": {
140+ "easy-purescript-nix": "easy-purescript-nix",
141+ "flake-utils": "flake-utils_2",
142+ "nixpkgs": "nixpkgs_2"
143+ },
144+ "locked": {
145+ "lastModified": 1671225584,
146+ "narHash": "sha256-h9r67pmvDuA3TV9299L4CN60XSm8RRtX1EwUoKu9Pyw=",
147+ "owner": "justinwoo",
148+ "repo": "spago2nix",
149+ "rev": "1b8ec352bc7eac077b934d6b9f6efa0129926e59",
150+ "type": "github"
151+ },
152+ "original": {
153+ "owner": "justinwoo",
154+ "repo": "spago2nix",
155+ "type": "github"
156+ }
157+ },
158+ "vanilla": {
159+ "flake": false,
160+ "locked": {
161+ "lastModified": 1663430347,
162+ "narHash": "sha256-J+KyCcCMdC8SYINKAtUsNfM0/lnbwOnsY8TKOP+yY0s=",
163+ "owner": "ilyakooo0",
164+ "repo": "vanilla-compiled",
165+ "rev": "7a0ee46ce9b958b51c57b37c46e86a0a1868bfa9",
166+ "type": "github"
167+ },
168+ "original": {
169+ "owner": "ilyakooo0",
170+ "repo": "vanilla-compiled",
171+ "type": "github"
172+ }
173+ }
174+ },
175+ "root": "root",
176+ "version": 7
177+}
flake.nixnew file+133
@@ -0,0 +1,133 @@
1+{
2+ inputs = {
3+ flake-utils.url = "github:numtide/flake-utils";
4+ bw = {
5+ url =
6+ # Afer this commit they started requiring path at the top level and I can't deal with this right now
7+ "github:bitwarden/clients?rev=ff143760d4f527f2349333ee4b3004eeda68fac5";
8+ flake = false;
9+ };
10+ spago2nix.url = "github:justinwoo/spago2nix";
11+ easy-ps = {
12+ url = "github:justinwoo/easy-purescript-nix";
13+ flake = false;
14+ };
15+ vanilla = {
16+ url = "github:ilyakooo0/vanilla-compiled";
17+ flake = false;
18+ };
19+ nix-filter.url = "github:numtide/nix-filter";
20+ };
21+
22+ outputs = inputs@{ self, nixpkgs, flake-utils, spago2nix, ... }:
23+ flake-utils.lib.eachDefaultSystem (system:
24+ let
25+ pkgs = import nixpkgs { inherit system; };
26+ spagoPkgs = pkgs.callPackage ./spago-packages.nix { };
27+ easy-ps = pkgs.callPackage inputs.easy-ps { };
28+ nix-filter = import inputs.nix-filter;
29+
30+ bw = pkgs.buildNpmPackage {
31+ pname = "bw";
32+ version = "latest";
33+ npmDepsHash = "sha256-jQvL7/SzXqVk03ncU6Mxq8lqFFy+lIrF2QheheXrQ0w=";
34+ makeCacheWritable = true;
35+ src = inputs.bw;
36+ nativeBuildInputs = [ pkgs.python3 ];
37+ buildPhase = ''
38+ (cd libs/common/ && rm -r spec && find . -name "*.spec.ts" -exec rm {} \; && npm exec -c "tsc -m es2020 -t es2018") '';
39+ installPhase = ''
40+ mkdir -p $out
41+ cp -r libs/shared/dist/* $out
42+ cp -r node_modules $out/node_modules
43+ cp package.json $out/package.json
44+ '';
45+ ELECTRON_SKIP_BINARY_DOWNLOAD = 1;
46+ };
47+
48+ backendBuildScript = pkgs.writeScript "build-backend.sh" ''
49+ workdir=$(mktemp -d)
50+ (
51+ cd $workdir
52+ cp -r $1 ./backend
53+ cp -r ${bw} ./bw
54+ cp ${./backend-main.js} backend.js
55+ ${pkgs.esbuild}/bin/esbuild backend.js --bundle --define:ENVIRONMENT_IS_WEB=true --define:ENVIRONMENT_IS_WORKER=false --define:ENVIRONMENT_IS_NODE=false --define:ENVIRONMENT_IS_SHELL=false --external:fs --external:path --loader:.wasm=base64 --outfile=$out
56+ )
57+
58+ '';
59+ backend-js = pkgs.stdenv.mkDerivation {
60+ name = "backend-js";
61+ buildInputs =
62+ [ spagoPkgs.installSpagoStyle spagoPkgs.buildSpagoStyle ];
63+ nativeBuildInputs = [ easy-ps.purs-0_15_7 easy-ps.spago ];
64+ src = nix-filter {
65+ root = ./.;
66+ include = [
67+ ./spago.dhall
68+ ./packages.dhall
69+ (nix-filter.inDirectory ./backend)
70+ ];
71+ };
72+ unpackPhase = ''
73+ cp $src/spago.dhall .
74+ cp $src/packages.dhall .
75+ cp -r $src/backend .
76+ install-spago-style
77+ '';
78+ buildPhase = ''
79+ build-spago-style "./backend/**/*.purs"
80+ '';
81+ installPhase = ''
82+ mkdir $out
83+ cp -r output/* $out/
84+ '';
85+ };
86+
87+ backend =
88+ pkgs.runCommand "backend.js" { buildInputs = [ pkgs.esbuild ]; } ''
89+ ${backendBuildScript} ${backend-js}
90+ '';
91+
92+ frontend = pkgs.callPackage ./frontend.nix { inherit nix-filter; };
93+
94+ warden-src = pkgs.runCommand "warden-src" { } ''
95+ mkdir -p $out
96+
97+ cp ${backend} $out/backend.js
98+ cp -r ${frontend}/Main.min.js $out/elm.js
99+ cp ${./index.html} $out/index.html
100+ cp ${./style.css} $out/style.css
101+ cp -r ${inputs.vanilla} $out/vanilla
102+ '';
103+
104+ warden-click-src = pkgs.runCommand "warden-click-src" { } ''
105+ mkdir -p $out
106+
107+ cp ${./warden.apparmor} $out/warden.apparmor
108+ cp ${./warden.desktop} $out/warden.desktop
109+ cp ${./manifest.json} $out/manifest.json
110+ cp ${./logo.png} $out/logo.png
111+ cp -r ${warden-src}/* $out/
112+ '';
113+
114+ warden = pkgs.writeScript "warden" ''
115+ ${pkgs.electron}/bin/electron ${warden-src}/index.html
116+ '';
117+
118+ in {
119+ packages = {
120+ inherit bw frontend warden-src backendBuildScript warden-click-src;
121+ vanilla = inputs.vanilla.outPath;
122+ };
123+ apps = {
124+ inherit (spago2nix.apps.${system}) spago2nix;
125+ warden = {
126+ type = "app";
127+ program = warden.outPath;
128+ };
129+ };
130+
131+ devShells.default = import ./shell.nix { inherit pkgs; };
132+ });
133+}
frontend.nixnew file+49
@@ -0,0 +1,49 @@
1+{ pkgs, nix-filter }:
2+with pkgs;
3+
4+let
5+ mkDerivation = { srcs ? ./elm-srcs.nix, src, name, srcdir ? "./frontend"
6+ , targets ? [ ], registryDat ? ./registry.dat, outputJavaScript ? true }:
7+ stdenv.mkDerivation {
8+ inherit name src;
9+
10+ buildInputs = [ elmPackages.elm ]
11+ ++ lib.optional outputJavaScript nodePackages.uglify-js;
12+
13+ buildPhase = pkgs.elmPackages.fetchElmDeps {
14+ elmPackages = import srcs;
15+ elmVersion = "0.19.1";
16+ inherit registryDat;
17+ };
18+
19+ installPhase = let
20+ elmfile = module:
21+ "${srcdir}/${builtins.replaceStrings [ "." ] [ "/" ] module}.elm";
22+ extension = if outputJavaScript then "js" else "html";
23+ in ''
24+ mkdir -p $out/share/doc
25+ ${lib.concatStrings (map (module: ''
26+ echo "compiling ${elmfile module}"
27+ elm make ${
28+ elmfile module
29+ } --output $out/${module}.${extension} --docs $out/share/doc/${module}.json
30+ ${lib.optionalString outputJavaScript ''
31+ echo "minifying ${elmfile module}"
32+ uglifyjs $out/${module}.${extension} --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' \
33+ | uglifyjs --mangle --output $out/${module}.min.${extension}
34+ ''}
35+ '') targets)}
36+ '';
37+ };
38+in mkDerivation {
39+ name = "frontend";
40+ srcs = ./elm-srcs.nix;
41+ src = nix-filter {
42+ root = ./.;
43+ include = [ (nix-filter.inDirectory ./frontend) ./elm.json ];
44+ };
45+ targets = [ "Main" ];
46+ srcdir = "./frontend";
47+ outputJavaScript = true;
48+}
49+
frontend/Bridge.elm+826−8
@@ -8,17 +8,565 @@ import Dict exposing (Dict)
8import Set exposing (Set)
8import Set exposing (Set)
9
9
10
10
11+type alias Cipher_CardCipher_brand_Maybe = (Maybe String)
12+
13+jsonDecCipher_CardCipher_brand_Maybe : Json.Decode.Decoder ( Cipher_CardCipher_brand_Maybe )
14+jsonDecCipher_CardCipher_brand_Maybe =
15+ Json.Decode.maybe (Json.Decode.string)
16+
17+jsonEncCipher_CardCipher_brand_Maybe : Cipher_CardCipher_brand_Maybe -> Value
18+jsonEncCipher_CardCipher_brand_Maybe val = (maybeEncode (Json.Encode.string)) val
19+
20+
21+
22+type alias Cipher_CardCipher_cardholderName_Maybe = (Maybe String)
23+
24+jsonDecCipher_CardCipher_cardholderName_Maybe : Json.Decode.Decoder ( Cipher_CardCipher_cardholderName_Maybe )
25+jsonDecCipher_CardCipher_cardholderName_Maybe =
26+ Json.Decode.maybe (Json.Decode.string)
27+
28+jsonEncCipher_CardCipher_cardholderName_Maybe : Cipher_CardCipher_cardholderName_Maybe -> Value
29+jsonEncCipher_CardCipher_cardholderName_Maybe val = (maybeEncode (Json.Encode.string)) val
30+
31+
32+
33+type alias Cipher_CardCipher_code_Maybe = (Maybe String)
34+
35+jsonDecCipher_CardCipher_code_Maybe : Json.Decode.Decoder ( Cipher_CardCipher_code_Maybe )
36+jsonDecCipher_CardCipher_code_Maybe =
37+ Json.Decode.maybe (Json.Decode.string)
38+
39+jsonEncCipher_CardCipher_code_Maybe : Cipher_CardCipher_code_Maybe -> Value
40+jsonEncCipher_CardCipher_code_Maybe val = (maybeEncode (Json.Encode.string)) val
41+
42+
43+
44+type alias Cipher_CardCipher_expMonth_Maybe = (Maybe String)
45+
46+jsonDecCipher_CardCipher_expMonth_Maybe : Json.Decode.Decoder ( Cipher_CardCipher_expMonth_Maybe )
47+jsonDecCipher_CardCipher_expMonth_Maybe =
48+ Json.Decode.maybe (Json.Decode.string)
49+
50+jsonEncCipher_CardCipher_expMonth_Maybe : Cipher_CardCipher_expMonth_Maybe -> Value
51+jsonEncCipher_CardCipher_expMonth_Maybe val = (maybeEncode (Json.Encode.string)) val
52+
53+
54+
55+type alias Cipher_CardCipher_expYear_Maybe = (Maybe String)
56+
57+jsonDecCipher_CardCipher_expYear_Maybe : Json.Decode.Decoder ( Cipher_CardCipher_expYear_Maybe )
58+jsonDecCipher_CardCipher_expYear_Maybe =
59+ Json.Decode.maybe (Json.Decode.string)
60+
61+jsonEncCipher_CardCipher_expYear_Maybe : Cipher_CardCipher_expYear_Maybe -> Value
62+jsonEncCipher_CardCipher_expYear_Maybe val = (maybeEncode (Json.Encode.string)) val
63+
64+
65+
66+type alias Cipher_CardCipher_number_Maybe = (Maybe String)
67+
68+jsonDecCipher_CardCipher_number_Maybe : Json.Decode.Decoder ( Cipher_CardCipher_number_Maybe )
69+jsonDecCipher_CardCipher_number_Maybe =
70+ Json.Decode.maybe (Json.Decode.string)
71+
72+jsonEncCipher_CardCipher_number_Maybe : Cipher_CardCipher_number_Maybe -> Value
73+jsonEncCipher_CardCipher_number_Maybe val = (maybeEncode (Json.Encode.string)) val
74+
75+
76+
77+type alias Cipher_CardCipher =
78+ { brand: Cipher_CardCipher_brand_Maybe
79+ , cardholderName: Cipher_CardCipher_cardholderName_Maybe
80+ , code: Cipher_CardCipher_code_Maybe
81+ , expMonth: Cipher_CardCipher_expMonth_Maybe
82+ , expYear: Cipher_CardCipher_expYear_Maybe
83+ , number: Cipher_CardCipher_number_Maybe
84+ }
85+
86+jsonDecCipher_CardCipher : Json.Decode.Decoder ( Cipher_CardCipher )
87+jsonDecCipher_CardCipher =
88+ Json.Decode.succeed (\pbrand pcardholderName pcode pexpMonth pexpYear pnumber -> {brand = pbrand, cardholderName = pcardholderName, code = pcode, expMonth = pexpMonth, expYear = pexpYear, number = pnumber})
89+ |> required "brand" (jsonDecCipher_CardCipher_brand_Maybe)
90+ |> required "cardholderName" (jsonDecCipher_CardCipher_cardholderName_Maybe)
91+ |> required "code" (jsonDecCipher_CardCipher_code_Maybe)
92+ |> required "expMonth" (jsonDecCipher_CardCipher_expMonth_Maybe)
93+ |> required "expYear" (jsonDecCipher_CardCipher_expYear_Maybe)
94+ |> required "number" (jsonDecCipher_CardCipher_number_Maybe)
95+
96+jsonEncCipher_CardCipher : Cipher_CardCipher -> Value
97+jsonEncCipher_CardCipher val =
98+ Json.Encode.object
99+ [ ("brand", jsonEncCipher_CardCipher_brand_Maybe val.brand)
100+ , ("cardholderName", jsonEncCipher_CardCipher_cardholderName_Maybe val.cardholderName)
101+ , ("code", jsonEncCipher_CardCipher_code_Maybe val.code)
102+ , ("expMonth", jsonEncCipher_CardCipher_expMonth_Maybe val.expMonth)
103+ , ("expYear", jsonEncCipher_CardCipher_expYear_Maybe val.expYear)
104+ , ("number", jsonEncCipher_CardCipher_number_Maybe val.number)
105+ ]
106+
107+
108+
109+type alias Cipher_IdentityCipher_address1_Maybe = (Maybe String)
110+
111+jsonDecCipher_IdentityCipher_address1_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_address1_Maybe )
112+jsonDecCipher_IdentityCipher_address1_Maybe =
113+ Json.Decode.maybe (Json.Decode.string)
114+
115+jsonEncCipher_IdentityCipher_address1_Maybe : Cipher_IdentityCipher_address1_Maybe -> Value
116+jsonEncCipher_IdentityCipher_address1_Maybe val = (maybeEncode (Json.Encode.string)) val
117+
118+
119+
120+type alias Cipher_IdentityCipher_address2_Maybe = (Maybe String)
121+
122+jsonDecCipher_IdentityCipher_address2_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_address2_Maybe )
123+jsonDecCipher_IdentityCipher_address2_Maybe =
124+ Json.Decode.maybe (Json.Decode.string)
125+
126+jsonEncCipher_IdentityCipher_address2_Maybe : Cipher_IdentityCipher_address2_Maybe -> Value
127+jsonEncCipher_IdentityCipher_address2_Maybe val = (maybeEncode (Json.Encode.string)) val
128+
129+
130+
131+type alias Cipher_IdentityCipher_address3_Maybe = (Maybe String)
132+
133+jsonDecCipher_IdentityCipher_address3_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_address3_Maybe )
134+jsonDecCipher_IdentityCipher_address3_Maybe =
135+ Json.Decode.maybe (Json.Decode.string)
136+
137+jsonEncCipher_IdentityCipher_address3_Maybe : Cipher_IdentityCipher_address3_Maybe -> Value
138+jsonEncCipher_IdentityCipher_address3_Maybe val = (maybeEncode (Json.Encode.string)) val
139+
140+
141+
142+type alias Cipher_IdentityCipher_city_Maybe = (Maybe String)
143+
144+jsonDecCipher_IdentityCipher_city_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_city_Maybe )
145+jsonDecCipher_IdentityCipher_city_Maybe =
146+ Json.Decode.maybe (Json.Decode.string)
147+
148+jsonEncCipher_IdentityCipher_city_Maybe : Cipher_IdentityCipher_city_Maybe -> Value
149+jsonEncCipher_IdentityCipher_city_Maybe val = (maybeEncode (Json.Encode.string)) val
150+
151+
152+
153+type alias Cipher_IdentityCipher_company_Maybe = (Maybe String)
154+
155+jsonDecCipher_IdentityCipher_company_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_company_Maybe )
156+jsonDecCipher_IdentityCipher_company_Maybe =
157+ Json.Decode.maybe (Json.Decode.string)
158+
159+jsonEncCipher_IdentityCipher_company_Maybe : Cipher_IdentityCipher_company_Maybe -> Value
160+jsonEncCipher_IdentityCipher_company_Maybe val = (maybeEncode (Json.Encode.string)) val
161+
162+
163+
164+type alias Cipher_IdentityCipher_country_Maybe = (Maybe String)
165+
166+jsonDecCipher_IdentityCipher_country_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_country_Maybe )
167+jsonDecCipher_IdentityCipher_country_Maybe =
168+ Json.Decode.maybe (Json.Decode.string)
169+
170+jsonEncCipher_IdentityCipher_country_Maybe : Cipher_IdentityCipher_country_Maybe -> Value
171+jsonEncCipher_IdentityCipher_country_Maybe val = (maybeEncode (Json.Encode.string)) val
172+
173+
174+
175+type alias Cipher_IdentityCipher_email_Maybe = (Maybe String)
176+
177+jsonDecCipher_IdentityCipher_email_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_email_Maybe )
178+jsonDecCipher_IdentityCipher_email_Maybe =
179+ Json.Decode.maybe (Json.Decode.string)
180+
181+jsonEncCipher_IdentityCipher_email_Maybe : Cipher_IdentityCipher_email_Maybe -> Value
182+jsonEncCipher_IdentityCipher_email_Maybe val = (maybeEncode (Json.Encode.string)) val
183+
184+
185+
186+type alias Cipher_IdentityCipher_firstName_Maybe = (Maybe String)
187+
188+jsonDecCipher_IdentityCipher_firstName_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_firstName_Maybe )
189+jsonDecCipher_IdentityCipher_firstName_Maybe =
190+ Json.Decode.maybe (Json.Decode.string)
191+
192+jsonEncCipher_IdentityCipher_firstName_Maybe : Cipher_IdentityCipher_firstName_Maybe -> Value
193+jsonEncCipher_IdentityCipher_firstName_Maybe val = (maybeEncode (Json.Encode.string)) val
194+
195+
196+
197+type alias Cipher_IdentityCipher_lastName_Maybe = (Maybe String)
198+
199+jsonDecCipher_IdentityCipher_lastName_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_lastName_Maybe )
200+jsonDecCipher_IdentityCipher_lastName_Maybe =
201+ Json.Decode.maybe (Json.Decode.string)
202+
203+jsonEncCipher_IdentityCipher_lastName_Maybe : Cipher_IdentityCipher_lastName_Maybe -> Value
204+jsonEncCipher_IdentityCipher_lastName_Maybe val = (maybeEncode (Json.Encode.string)) val
205+
206+
207+
208+type alias Cipher_IdentityCipher_licenseNumber_Maybe = (Maybe String)
209+
210+jsonDecCipher_IdentityCipher_licenseNumber_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_licenseNumber_Maybe )
211+jsonDecCipher_IdentityCipher_licenseNumber_Maybe =
212+ Json.Decode.maybe (Json.Decode.string)
213+
214+jsonEncCipher_IdentityCipher_licenseNumber_Maybe : Cipher_IdentityCipher_licenseNumber_Maybe -> Value
215+jsonEncCipher_IdentityCipher_licenseNumber_Maybe val = (maybeEncode (Json.Encode.string)) val
216+
217+
218+
219+type alias Cipher_IdentityCipher_middleName_Maybe = (Maybe String)
220+
221+jsonDecCipher_IdentityCipher_middleName_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_middleName_Maybe )
222+jsonDecCipher_IdentityCipher_middleName_Maybe =
223+ Json.Decode.maybe (Json.Decode.string)
224+
225+jsonEncCipher_IdentityCipher_middleName_Maybe : Cipher_IdentityCipher_middleName_Maybe -> Value
226+jsonEncCipher_IdentityCipher_middleName_Maybe val = (maybeEncode (Json.Encode.string)) val
227+
228+
229+
230+type alias Cipher_IdentityCipher_passportNumber_Maybe = (Maybe String)
231+
232+jsonDecCipher_IdentityCipher_passportNumber_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_passportNumber_Maybe )
233+jsonDecCipher_IdentityCipher_passportNumber_Maybe =
234+ Json.Decode.maybe (Json.Decode.string)
235+
236+jsonEncCipher_IdentityCipher_passportNumber_Maybe : Cipher_IdentityCipher_passportNumber_Maybe -> Value
237+jsonEncCipher_IdentityCipher_passportNumber_Maybe val = (maybeEncode (Json.Encode.string)) val
238+
239+
240+
241+type alias Cipher_IdentityCipher_phone_Maybe = (Maybe String)
242+
243+jsonDecCipher_IdentityCipher_phone_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_phone_Maybe )
244+jsonDecCipher_IdentityCipher_phone_Maybe =
245+ Json.Decode.maybe (Json.Decode.string)
246+
247+jsonEncCipher_IdentityCipher_phone_Maybe : Cipher_IdentityCipher_phone_Maybe -> Value
248+jsonEncCipher_IdentityCipher_phone_Maybe val = (maybeEncode (Json.Encode.string)) val
249+
250+
251+
252+type alias Cipher_IdentityCipher_postalCode_Maybe = (Maybe String)
253+
254+jsonDecCipher_IdentityCipher_postalCode_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_postalCode_Maybe )
255+jsonDecCipher_IdentityCipher_postalCode_Maybe =
256+ Json.Decode.maybe (Json.Decode.string)
257+
258+jsonEncCipher_IdentityCipher_postalCode_Maybe : Cipher_IdentityCipher_postalCode_Maybe -> Value
259+jsonEncCipher_IdentityCipher_postalCode_Maybe val = (maybeEncode (Json.Encode.string)) val
260+
261+
262+
263+type alias Cipher_IdentityCipher_ssn_Maybe = (Maybe String)
264+
265+jsonDecCipher_IdentityCipher_ssn_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_ssn_Maybe )
266+jsonDecCipher_IdentityCipher_ssn_Maybe =
267+ Json.Decode.maybe (Json.Decode.string)
268+
269+jsonEncCipher_IdentityCipher_ssn_Maybe : Cipher_IdentityCipher_ssn_Maybe -> Value
270+jsonEncCipher_IdentityCipher_ssn_Maybe val = (maybeEncode (Json.Encode.string)) val
271+
272+
273+
274+type alias Cipher_IdentityCipher_state_Maybe = (Maybe String)
275+
276+jsonDecCipher_IdentityCipher_state_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_state_Maybe )
277+jsonDecCipher_IdentityCipher_state_Maybe =
278+ Json.Decode.maybe (Json.Decode.string)
279+
280+jsonEncCipher_IdentityCipher_state_Maybe : Cipher_IdentityCipher_state_Maybe -> Value
281+jsonEncCipher_IdentityCipher_state_Maybe val = (maybeEncode (Json.Encode.string)) val
282+
283+
284+
285+type alias Cipher_IdentityCipher_title_Maybe = (Maybe String)
286+
287+jsonDecCipher_IdentityCipher_title_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_title_Maybe )
288+jsonDecCipher_IdentityCipher_title_Maybe =
289+ Json.Decode.maybe (Json.Decode.string)
290+
291+jsonEncCipher_IdentityCipher_title_Maybe : Cipher_IdentityCipher_title_Maybe -> Value
292+jsonEncCipher_IdentityCipher_title_Maybe val = (maybeEncode (Json.Encode.string)) val
293+
294+
295+
296+type alias Cipher_IdentityCipher_username_Maybe = (Maybe String)
297+
298+jsonDecCipher_IdentityCipher_username_Maybe : Json.Decode.Decoder ( Cipher_IdentityCipher_username_Maybe )
299+jsonDecCipher_IdentityCipher_username_Maybe =
300+ Json.Decode.maybe (Json.Decode.string)
301+
302+jsonEncCipher_IdentityCipher_username_Maybe : Cipher_IdentityCipher_username_Maybe -> Value
303+jsonEncCipher_IdentityCipher_username_Maybe val = (maybeEncode (Json.Encode.string)) val
304+
305+
306+
307+type alias Cipher_IdentityCipher =
308+ { address1: Cipher_IdentityCipher_address1_Maybe
309+ , address2: Cipher_IdentityCipher_address2_Maybe
310+ , address3: Cipher_IdentityCipher_address3_Maybe
311+ , city: Cipher_IdentityCipher_city_Maybe
312+ , company: Cipher_IdentityCipher_company_Maybe
313+ , country: Cipher_IdentityCipher_country_Maybe
314+ , email: Cipher_IdentityCipher_email_Maybe
315+ , firstName: Cipher_IdentityCipher_firstName_Maybe
316+ , lastName: Cipher_IdentityCipher_lastName_Maybe
317+ , licenseNumber: Cipher_IdentityCipher_licenseNumber_Maybe
318+ , middleName: Cipher_IdentityCipher_middleName_Maybe
319+ , passportNumber: Cipher_IdentityCipher_passportNumber_Maybe
320+ , phone: Cipher_IdentityCipher_phone_Maybe
321+ , postalCode: Cipher_IdentityCipher_postalCode_Maybe
322+ , ssn: Cipher_IdentityCipher_ssn_Maybe
323+ , state: Cipher_IdentityCipher_state_Maybe
324+ , title: Cipher_IdentityCipher_title_Maybe
325+ , username: Cipher_IdentityCipher_username_Maybe
326+ }
327+
328+jsonDecCipher_IdentityCipher : Json.Decode.Decoder ( Cipher_IdentityCipher )
329+jsonDecCipher_IdentityCipher =
330+ Json.Decode.succeed (\paddress1 paddress2 paddress3 pcity pcompany pcountry pemail pfirstName plastName plicenseNumber pmiddleName ppassportNumber pphone ppostalCode pssn pstate ptitle pusername -> {address1 = paddress1, address2 = paddress2, address3 = paddress3, city = pcity, company = pcompany, country = pcountry, email = pemail, firstName = pfirstName, lastName = plastName, licenseNumber = plicenseNumber, middleName = pmiddleName, passportNumber = ppassportNumber, phone = pphone, postalCode = ppostalCode, ssn = pssn, state = pstate, title = ptitle, username = pusername})
331+ |> required "address1" (jsonDecCipher_IdentityCipher_address1_Maybe)
332+ |> required "address2" (jsonDecCipher_IdentityCipher_address2_Maybe)
333+ |> required "address3" (jsonDecCipher_IdentityCipher_address3_Maybe)
334+ |> required "city" (jsonDecCipher_IdentityCipher_city_Maybe)
335+ |> required "company" (jsonDecCipher_IdentityCipher_company_Maybe)
336+ |> required "country" (jsonDecCipher_IdentityCipher_country_Maybe)
337+ |> required "email" (jsonDecCipher_IdentityCipher_email_Maybe)
338+ |> required "firstName" (jsonDecCipher_IdentityCipher_firstName_Maybe)
339+ |> required "lastName" (jsonDecCipher_IdentityCipher_lastName_Maybe)
340+ |> required "licenseNumber" (jsonDecCipher_IdentityCipher_licenseNumber_Maybe)
341+ |> required "middleName" (jsonDecCipher_IdentityCipher_middleName_Maybe)
342+ |> required "passportNumber" (jsonDecCipher_IdentityCipher_passportNumber_Maybe)
343+ |> required "phone" (jsonDecCipher_IdentityCipher_phone_Maybe)
344+ |> required "postalCode" (jsonDecCipher_IdentityCipher_postalCode_Maybe)
345+ |> required "ssn" (jsonDecCipher_IdentityCipher_ssn_Maybe)
346+ |> required "state" (jsonDecCipher_IdentityCipher_state_Maybe)
347+ |> required "title" (jsonDecCipher_IdentityCipher_title_Maybe)
348+ |> required "username" (jsonDecCipher_IdentityCipher_username_Maybe)
349+
350+jsonEncCipher_IdentityCipher : Cipher_IdentityCipher -> Value
351+jsonEncCipher_IdentityCipher val =
352+ Json.Encode.object
353+ [ ("address1", jsonEncCipher_IdentityCipher_address1_Maybe val.address1)
354+ , ("address2", jsonEncCipher_IdentityCipher_address2_Maybe val.address2)
355+ , ("address3", jsonEncCipher_IdentityCipher_address3_Maybe val.address3)
356+ , ("city", jsonEncCipher_IdentityCipher_city_Maybe val.city)
357+ , ("company", jsonEncCipher_IdentityCipher_company_Maybe val.company)
358+ , ("country", jsonEncCipher_IdentityCipher_country_Maybe val.country)
359+ , ("email", jsonEncCipher_IdentityCipher_email_Maybe val.email)
360+ , ("firstName", jsonEncCipher_IdentityCipher_firstName_Maybe val.firstName)
361+ , ("lastName", jsonEncCipher_IdentityCipher_lastName_Maybe val.lastName)
362+ , ("licenseNumber", jsonEncCipher_IdentityCipher_licenseNumber_Maybe val.licenseNumber)
363+ , ("middleName", jsonEncCipher_IdentityCipher_middleName_Maybe val.middleName)
364+ , ("passportNumber", jsonEncCipher_IdentityCipher_passportNumber_Maybe val.passportNumber)
365+ , ("phone", jsonEncCipher_IdentityCipher_phone_Maybe val.phone)
366+ , ("postalCode", jsonEncCipher_IdentityCipher_postalCode_Maybe val.postalCode)
367+ , ("ssn", jsonEncCipher_IdentityCipher_ssn_Maybe val.ssn)
368+ , ("state", jsonEncCipher_IdentityCipher_state_Maybe val.state)
369+ , ("title", jsonEncCipher_IdentityCipher_title_Maybe val.title)
370+ , ("username", jsonEncCipher_IdentityCipher_username_Maybe val.username)
371+ ]
372+
373+
374+
375+type alias Cipher_LoginCipher_password_Maybe = (Maybe String)
376+
377+jsonDecCipher_LoginCipher_password_Maybe : Json.Decode.Decoder ( Cipher_LoginCipher_password_Maybe )
378+jsonDecCipher_LoginCipher_password_Maybe =
379+ Json.Decode.maybe (Json.Decode.string)
380+
381+jsonEncCipher_LoginCipher_password_Maybe : Cipher_LoginCipher_password_Maybe -> Value
382+jsonEncCipher_LoginCipher_password_Maybe val = (maybeEncode (Json.Encode.string)) val
383+
384+
385+
386+type alias Cipher_LoginCipher_totp_Maybe = (Maybe String)
387+
388+jsonDecCipher_LoginCipher_totp_Maybe : Json.Decode.Decoder ( Cipher_LoginCipher_totp_Maybe )
389+jsonDecCipher_LoginCipher_totp_Maybe =
390+ Json.Decode.maybe (Json.Decode.string)
391+
392+jsonEncCipher_LoginCipher_totp_Maybe : Cipher_LoginCipher_totp_Maybe -> Value
393+jsonEncCipher_LoginCipher_totp_Maybe val = (maybeEncode (Json.Encode.string)) val
394+
395+
396+
397+type alias Cipher_LoginCipher_uris_List = (List String)
398+
399+jsonDecCipher_LoginCipher_uris_List : Json.Decode.Decoder ( Cipher_LoginCipher_uris_List )
400+jsonDecCipher_LoginCipher_uris_List =
401+ Json.Decode.list (Json.Decode.string)
402+
403+jsonEncCipher_LoginCipher_uris_List : Cipher_LoginCipher_uris_List -> Value
404+jsonEncCipher_LoginCipher_uris_List val = (Json.Encode.list Json.Encode.string) val
405+
406+
407+
408+type alias Cipher_LoginCipher_username_Maybe = (Maybe String)
409+
410+jsonDecCipher_LoginCipher_username_Maybe : Json.Decode.Decoder ( Cipher_LoginCipher_username_Maybe )
411+jsonDecCipher_LoginCipher_username_Maybe =
412+ Json.Decode.maybe (Json.Decode.string)
413+
414+jsonEncCipher_LoginCipher_username_Maybe : Cipher_LoginCipher_username_Maybe -> Value
415+jsonEncCipher_LoginCipher_username_Maybe val = (maybeEncode (Json.Encode.string)) val
416+
417+
418+
419+type alias Cipher_LoginCipher =
420+ { password: Cipher_LoginCipher_password_Maybe
421+ , totp: Cipher_LoginCipher_totp_Maybe
422+ , uris: Cipher_LoginCipher_uris_List
423+ , username: Cipher_LoginCipher_username_Maybe
424+ }
425+
426+jsonDecCipher_LoginCipher : Json.Decode.Decoder ( Cipher_LoginCipher )
427+jsonDecCipher_LoginCipher =
428+ Json.Decode.succeed (\ppassword ptotp puris pusername -> {password = ppassword, totp = ptotp, uris = puris, username = pusername})
429+ |> required "password" (jsonDecCipher_LoginCipher_password_Maybe)
430+ |> required "totp" (jsonDecCipher_LoginCipher_totp_Maybe)
431+ |> required "uris" (jsonDecCipher_LoginCipher_uris_List)
432+ |> required "username" (jsonDecCipher_LoginCipher_username_Maybe)
433+
434+jsonEncCipher_LoginCipher : Cipher_LoginCipher -> Value
435+jsonEncCipher_LoginCipher val =
436+ Json.Encode.object
437+ [ ("password", jsonEncCipher_LoginCipher_password_Maybe val.password)
438+ , ("totp", jsonEncCipher_LoginCipher_totp_Maybe val.totp)
439+ , ("uris", jsonEncCipher_LoginCipher_uris_List val.uris)
440+ , ("username", jsonEncCipher_LoginCipher_username_Maybe val.username)
441+ ]
442+
443+
444+
445+type Cipher =
446+ CardCipher Cipher_CardCipher
447+ | IdentityCipher Cipher_IdentityCipher
448+ | LoginCipher Cipher_LoginCipher
449+ | NoteCipher String
450+
451+jsonDecCipher : Json.Decode.Decoder ( Cipher )
452+jsonDecCipher =
453+ let jsonDecDictCipher = Dict.fromList
454+ [ ("CardCipher", Json.Decode.lazy (\_ -> Json.Decode.map CardCipher (jsonDecCipher_CardCipher)))
455+ , ("IdentityCipher", Json.Decode.lazy (\_ -> Json.Decode.map IdentityCipher (jsonDecCipher_IdentityCipher)))
456+ , ("LoginCipher", Json.Decode.lazy (\_ -> Json.Decode.map LoginCipher (jsonDecCipher_LoginCipher)))
457+ , ("NoteCipher", Json.Decode.lazy (\_ -> Json.Decode.map NoteCipher (Json.Decode.string)))
458+ ]
459+ jsonDecObjectSetCipher = Set.fromList []
460+ in decodeSumTaggedObject "Cipher" "tag" "contents" jsonDecDictCipher jsonDecObjectSetCipher
461+
462+jsonEncCipher : Cipher -> Value
463+jsonEncCipher val =
464+ let keyval v = case v of
465+ CardCipher v1 -> ("CardCipher", encodeValue (jsonEncCipher_CardCipher v1))
466+ IdentityCipher v1 -> ("IdentityCipher", encodeValue (jsonEncCipher_IdentityCipher v1))
467+ LoginCipher v1 -> ("LoginCipher", encodeValue (jsonEncCipher_LoginCipher v1))
468+ NoteCipher v1 -> ("NoteCipher", encodeValue (Json.Encode.string v1))
469+ in encodeSumTaggedObject "tag" "contents" keyval val
470+
471+
472+
473+type CipherType =
474+ CardType
475+ | IdentityType
476+ | LoginType
477+ | NoteType
478+
479+jsonDecCipherType : Json.Decode.Decoder ( CipherType )
480+jsonDecCipherType =
481+ let jsonDecDictCipherType = Dict.fromList [("CardType", CardType), ("IdentityType", IdentityType), ("LoginType", LoginType), ("NoteType", NoteType)]
482+ in decodeSumUnaries "CipherType" jsonDecDictCipherType
483+
484+jsonEncCipherType : CipherType -> Value
485+jsonEncCipherType val =
486+ case val of
487+ CardType -> Json.Encode.string "CardType"
488+ IdentityType -> Json.Encode.string "IdentityType"
489+ LoginType -> Json.Encode.string "LoginType"
490+ NoteType -> Json.Encode.string "NoteType"
491+
492+
493+
494+type alias Cmd_ChooseSecondFactor =
495+ { email: String
496+ , factor: TwoFactorProviderType
497+ , password: String
498+ , requestFromServer: Bool
499+ , server: String
500+ }
501+
502+jsonDecCmd_ChooseSecondFactor : Json.Decode.Decoder ( Cmd_ChooseSecondFactor )
503+jsonDecCmd_ChooseSecondFactor =
504+ Json.Decode.succeed (\pemail pfactor ppassword prequestFromServer pserver -> {email = pemail, factor = pfactor, password = ppassword, requestFromServer = prequestFromServer, server = pserver})
505+ |> required "email" (Json.Decode.string)
506+ |> required "factor" (jsonDecTwoFactorProviderType)
507+ |> required "password" (Json.Decode.string)
508+ |> required "requestFromServer" (Json.Decode.bool)
509+ |> required "server" (Json.Decode.string)
510+
511+jsonEncCmd_ChooseSecondFactor : Cmd_ChooseSecondFactor -> Value
512+jsonEncCmd_ChooseSecondFactor val =
513+ Json.Encode.object
514+ [ ("email", Json.Encode.string val.email)
515+ , ("factor", jsonEncTwoFactorProviderType val.factor)
516+ , ("password", Json.Encode.string val.password)
517+ , ("requestFromServer", Json.Encode.bool val.requestFromServer)
518+ , ("server", Json.Encode.string val.server)
519+ ]
520+
521+
522+
523+type alias Cmd_Login_secondFactor =
524+ { provider: TwoFactorProviderType
525+ , remember: Bool
526+ , token: String
527+ }
528+
529+jsonDecCmd_Login_secondFactor : Json.Decode.Decoder ( Cmd_Login_secondFactor )
530+jsonDecCmd_Login_secondFactor =
531+ Json.Decode.succeed (\pprovider premember ptoken -> {provider = pprovider, remember = premember, token = ptoken})
532+ |> required "provider" (jsonDecTwoFactorProviderType)
533+ |> required "remember" (Json.Decode.bool)
534+ |> required "token" (Json.Decode.string)
535+
536+jsonEncCmd_Login_secondFactor : Cmd_Login_secondFactor -> Value
537+jsonEncCmd_Login_secondFactor val =
538+ Json.Encode.object
539+ [ ("provider", jsonEncTwoFactorProviderType val.provider)
540+ , ("remember", Json.Encode.bool val.remember)
541+ , ("token", Json.Encode.string val.token)
542+ ]
543+
544+
545+
546+type alias Cmd_Login_secondFactor_Maybe = (Maybe Cmd_Login_secondFactor)
547+
548+jsonDecCmd_Login_secondFactor_Maybe : Json.Decode.Decoder ( Cmd_Login_secondFactor_Maybe )
549+jsonDecCmd_Login_secondFactor_Maybe =
550+ Json.Decode.maybe (jsonDecCmd_Login_secondFactor)
551+
552+jsonEncCmd_Login_secondFactor_Maybe : Cmd_Login_secondFactor_Maybe -> Value
553+jsonEncCmd_Login_secondFactor_Maybe val = (maybeEncode (jsonEncCmd_Login_secondFactor)) val
554+
555+
556+
11type alias Cmd_Login =
557type alias Cmd_Login =
12 { email: String
558 { email: String
13 , password: String
559 , password: String
560+ , secondFactor: Cmd_Login_secondFactor_Maybe
14 , server: String
561 , server: String
15 }
562 }
16
563
17jsonDecCmd_Login : Json.Decode.Decoder ( Cmd_Login )
564jsonDecCmd_Login : Json.Decode.Decoder ( Cmd_Login )
18jsonDecCmd_Login =
565jsonDecCmd_Login =
19− Json.Decode.succeed (\pemail ppassword pserver -> {email = pemail, password = ppassword, server = pserver})
566+ Json.Decode.succeed (\pemail ppassword psecondFactor pserver -> {email = pemail, password = ppassword, secondFactor = psecondFactor, server = pserver})
20 |> required "email" (Json.Decode.string)
567 |> required "email" (Json.Decode.string)
21 |> required "password" (Json.Decode.string)
568 |> required "password" (Json.Decode.string)
569+ |> required "secondFactor" (jsonDecCmd_Login_secondFactor_Maybe)
22 |> required "server" (Json.Decode.string)
570 |> required "server" (Json.Decode.string)
23
571
24jsonEncCmd_Login : Cmd_Login -> Value
572jsonEncCmd_Login : Cmd_Login -> Value
@@ -26,20 +574,47 @@ jsonEncCmd_Login val =
26 Json.Encode.object
574 Json.Encode.object
27 [ ("email", Json.Encode.string val.email)
575 [ ("email", Json.Encode.string val.email)
28 , ("password", Json.Encode.string val.password)
576 , ("password", Json.Encode.string val.password)
577+ , ("secondFactor", jsonEncCmd_Login_secondFactor_Maybe val.secondFactor)
29 , ("server", Json.Encode.string val.server)
578 , ("server", Json.Encode.string val.server)
30 ]
579 ]
31
580
32
581
33
582
34type Cmd =
583type Cmd =
584+ ChooseSecondFactor Cmd_ChooseSecondFactor
585+ | Copy String
586+ | CreateCipher FullCipher
587+ | DeleteCipher FullCipher
588+ | GeneratePassword PasswordGeneratorConfig
35− Init
589+ | Init
36 | Login Cmd_Login
590 | Login Cmd_Login
591+ | NeedCiphersList
592+ | NeedEmail
593+ | NeedsReset
594+ | Open String
595+ | RequestCipher String
596+ | RequestTotp String
597+ | SendMasterPassword String
598+ | UpdateCipher FullCipher
37
599
38jsonDecCmd : Json.Decode.Decoder ( Cmd )
600jsonDecCmd : Json.Decode.Decoder ( Cmd )
39jsonDecCmd =
601jsonDecCmd =
40 let jsonDecDictCmd = Dict.fromList
602 let jsonDecDictCmd = Dict.fromList
603+ [ ("ChooseSecondFactor", Json.Decode.lazy (\_ -> Json.Decode.map ChooseSecondFactor (jsonDecCmd_ChooseSecondFactor)))
604+ , ("Copy", Json.Decode.lazy (\_ -> Json.Decode.map Copy (Json.Decode.string)))
605+ , ("CreateCipher", Json.Decode.lazy (\_ -> Json.Decode.map CreateCipher (jsonDecFullCipher)))
606+ , ("DeleteCipher", Json.Decode.lazy (\_ -> Json.Decode.map DeleteCipher (jsonDecFullCipher)))
607+ , ("GeneratePassword", Json.Decode.lazy (\_ -> Json.Decode.map GeneratePassword (jsonDecPasswordGeneratorConfig)))
41− [ ("Init", Json.Decode.lazy (\_ -> Json.Decode.succeed Init))
608+ , ("Init", Json.Decode.lazy (\_ -> Json.Decode.succeed Init))
42 , ("Login", Json.Decode.lazy (\_ -> Json.Decode.map Login (jsonDecCmd_Login)))
609 , ("Login", Json.Decode.lazy (\_ -> Json.Decode.map Login (jsonDecCmd_Login)))
610+ , ("NeedCiphersList", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedCiphersList))
611+ , ("NeedEmail", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedEmail))
612+ , ("NeedsReset", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedsReset))
613+ , ("Open", Json.Decode.lazy (\_ -> Json.Decode.map Open (Json.Decode.string)))
614+ , ("RequestCipher", Json.Decode.lazy (\_ -> Json.Decode.map RequestCipher (Json.Decode.string)))
615+ , ("RequestTotp", Json.Decode.lazy (\_ -> Json.Decode.map RequestTotp (Json.Decode.string)))
616+ , ("SendMasterPassword", Json.Decode.lazy (\_ -> Json.Decode.map SendMasterPassword (Json.Decode.string)))
617+ , ("UpdateCipher", Json.Decode.lazy (\_ -> Json.Decode.map UpdateCipher (jsonDecFullCipher)))
43 ]
618 ]
44 jsonDecObjectSetCmd = Set.fromList []
619 jsonDecObjectSetCmd = Set.fromList []
45 in decodeSumTaggedObject "Cmd" "tag" "contents" jsonDecDictCmd jsonDecObjectSetCmd
620 in decodeSumTaggedObject "Cmd" "tag" "contents" jsonDecDictCmd jsonDecObjectSetCmd
@@ -47,27 +622,148 @@ jsonDecCmd =
47jsonEncCmd : Cmd -> Value
622jsonEncCmd : Cmd -> Value
48jsonEncCmd val =
623jsonEncCmd val =
49 let keyval v = case v of
624 let keyval v = case v of
625+ ChooseSecondFactor v1 -> ("ChooseSecondFactor", encodeValue (jsonEncCmd_ChooseSecondFactor v1))
626+ Copy v1 -> ("Copy", encodeValue (Json.Encode.string v1))
627+ CreateCipher v1 -> ("CreateCipher", encodeValue (jsonEncFullCipher v1))
628+ DeleteCipher v1 -> ("DeleteCipher", encodeValue (jsonEncFullCipher v1))
629+ GeneratePassword v1 -> ("GeneratePassword", encodeValue (jsonEncPasswordGeneratorConfig v1))
50 Init -> ("Init", encodeValue (Json.Encode.list identity []))
630 Init -> ("Init", encodeValue (Json.Encode.list identity []))
51 Login v1 -> ("Login", encodeValue (jsonEncCmd_Login v1))
631 Login v1 -> ("Login", encodeValue (jsonEncCmd_Login v1))
632+ NeedCiphersList -> ("NeedCiphersList", encodeValue (Json.Encode.list identity []))
633+ NeedEmail -> ("NeedEmail", encodeValue (Json.Encode.list identity []))
634+ NeedsReset -> ("NeedsReset", encodeValue (Json.Encode.list identity []))
635+ Open v1 -> ("Open", encodeValue (Json.Encode.string v1))
636+ RequestCipher v1 -> ("RequestCipher", encodeValue (Json.Encode.string v1))
637+ RequestTotp v1 -> ("RequestTotp", encodeValue (Json.Encode.string v1))
638+ SendMasterPassword v1 -> ("SendMasterPassword", encodeValue (Json.Encode.string v1))
639+ UpdateCipher v1 -> ("UpdateCipher", encodeValue (jsonEncFullCipher v1))
52 in encodeSumTaggedObject "tag" "contents" keyval val
640 in encodeSumTaggedObject "tag" "contents" keyval val
53
641
54
642
55
643
644+type alias FullCipher_collectionIds_List = (List String)
645+
646+jsonDecFullCipher_collectionIds_List : Json.Decode.Decoder ( FullCipher_collectionIds_List )
647+jsonDecFullCipher_collectionIds_List =
648+ Json.Decode.list (Json.Decode.string)
649+
650+jsonEncFullCipher_collectionIds_List : FullCipher_collectionIds_List -> Value
651+jsonEncFullCipher_collectionIds_List val = (Json.Encode.list Json.Encode.string) val
652+
653+
654+
655+type alias FullCipher =
656+ { cipher: Cipher
657+ , collectionIds: FullCipher_collectionIds_List
658+ , favorite: Bool
659+ , id: String
660+ , name: String
661+ , reprompt: Int
662+ }
663+
664+jsonDecFullCipher : Json.Decode.Decoder ( FullCipher )
665+jsonDecFullCipher =
666+ Json.Decode.succeed (\pcipher pcollectionIds pfavorite pid pname preprompt -> {cipher = pcipher, collectionIds = pcollectionIds, favorite = pfavorite, id = pid, name = pname, reprompt = preprompt})
667+ |> required "cipher" (jsonDecCipher)
668+ |> required "collectionIds" (jsonDecFullCipher_collectionIds_List)
669+ |> required "favorite" (Json.Decode.bool)
670+ |> required "id" (Json.Decode.string)
671+ |> required "name" (Json.Decode.string)
672+ |> required "reprompt" (Json.Decode.int)
673+
674+jsonEncFullCipher : FullCipher -> Value
675+jsonEncFullCipher val =
676+ Json.Encode.object
677+ [ ("cipher", jsonEncCipher val.cipher)
678+ , ("collectionIds", jsonEncFullCipher_collectionIds_List val.collectionIds)
679+ , ("favorite", Json.Encode.bool val.favorite)
680+ , ("id", Json.Encode.string val.id)
681+ , ("name", Json.Encode.string val.name)
682+ , ("reprompt", Json.Encode.int val.reprompt)
683+ ]
684+
685+
686+
687+type alias PasswordGeneratorConfig =
688+ { ambiguous: Bool
689+ , capitalize: Bool
690+ , includeNumber: Bool
691+ , length: Int
692+ , lowercase: Bool
693+ , minLowercase: Int
694+ , minNumber: Int
695+ , minSpecial: Int
696+ , minUppercase: Int
697+ , numWords: Int
698+ , number: Bool
699+ , special: Bool
700+ , type_: String
701+ , uppercase: Bool
702+ , wordSeparator: String
703+ }
704+
705+jsonDecPasswordGeneratorConfig : Json.Decode.Decoder ( PasswordGeneratorConfig )
706+jsonDecPasswordGeneratorConfig =
707+ Json.Decode.succeed (\pambiguous pcapitalize pincludeNumber plength plowercase pminLowercase pminNumber pminSpecial pminUppercase pnumWords pnumber pspecial ptype puppercase pwordSeparator -> {ambiguous = pambiguous, capitalize = pcapitalize, includeNumber = pincludeNumber, length = plength, lowercase = plowercase, minLowercase = pminLowercase, minNumber = pminNumber, minSpecial = pminSpecial, minUppercase = pminUppercase, numWords = pnumWords, number = pnumber, special = pspecial, type_ = ptype, uppercase = puppercase, wordSeparator = pwordSeparator})
708+ |> required "ambiguous" (Json.Decode.bool)
709+ |> required "capitalize" (Json.Decode.bool)
710+ |> required "includeNumber" (Json.Decode.bool)
711+ |> required "length" (Json.Decode.int)
712+ |> required "lowercase" (Json.Decode.bool)
713+ |> required "minLowercase" (Json.Decode.int)
714+ |> required "minNumber" (Json.Decode.int)
715+ |> required "minSpecial" (Json.Decode.int)
716+ |> required "minUppercase" (Json.Decode.int)
717+ |> required "numWords" (Json.Decode.int)
718+ |> required "number" (Json.Decode.bool)
719+ |> required "special" (Json.Decode.bool)
720+ |> required "type" (Json.Decode.string)
721+ |> required "uppercase" (Json.Decode.bool)
722+ |> required "wordSeparator" (Json.Decode.string)
723+
724+jsonEncPasswordGeneratorConfig : PasswordGeneratorConfig -> Value
725+jsonEncPasswordGeneratorConfig val =
726+ Json.Encode.object
727+ [ ("ambiguous", Json.Encode.bool val.ambiguous)
728+ , ("capitalize", Json.Encode.bool val.capitalize)
729+ , ("includeNumber", Json.Encode.bool val.includeNumber)
730+ , ("length", Json.Encode.int val.length)
731+ , ("lowercase", Json.Encode.bool val.lowercase)
732+ , ("minLowercase", Json.Encode.int val.minLowercase)
733+ , ("minNumber", Json.Encode.int val.minNumber)
734+ , ("minSpecial", Json.Encode.int val.minSpecial)
735+ , ("minUppercase", Json.Encode.int val.minUppercase)
736+ , ("numWords", Json.Encode.int val.numWords)
737+ , ("number", Json.Encode.bool val.number)
738+ , ("special", Json.Encode.bool val.special)
739+ , ("type", Json.Encode.string val.type_)
740+ , ("uppercase", Json.Encode.bool val.uppercase)
741+ , ("wordSeparator", Json.Encode.string val.wordSeparator)
742+ ]
743+
744+
745+
56type alias Sub_LoadCiphers =
746type alias Sub_LoadCiphers =
747+ { cipherType: CipherType
57− { date: String
748+ , date: String
749+ , id: String
58 , name: String
750 , name: String
59 }
751 }
60
752
61jsonDecSub_LoadCiphers : Json.Decode.Decoder ( Sub_LoadCiphers )
753jsonDecSub_LoadCiphers : Json.Decode.Decoder ( Sub_LoadCiphers )
62jsonDecSub_LoadCiphers =
754jsonDecSub_LoadCiphers =
63− Json.Decode.succeed (\pdate pname -> {date = pdate, name = pname})
755+ Json.Decode.succeed (\pcipherType pdate pid pname -> {cipherType = pcipherType, date = pdate, id = pid, name = pname})
756+ |> required "cipherType" (jsonDecCipherType)
64 |> required "date" (Json.Decode.string)
757 |> required "date" (Json.Decode.string)
758+ |> required "id" (Json.Decode.string)
65 |> required "name" (Json.Decode.string)
759 |> required "name" (Json.Decode.string)
66
760
67jsonEncSub_LoadCiphers : Sub_LoadCiphers -> Value
761jsonEncSub_LoadCiphers : Sub_LoadCiphers -> Value
68jsonEncSub_LoadCiphers val =
762jsonEncSub_LoadCiphers val =
69 Json.Encode.object
763 Json.Encode.object
764+ [ ("cipherType", jsonEncCipherType val.cipherType)
70− [ ("date", Json.Encode.string val.date)
765+ , ("date", Json.Encode.string val.date)
766+ , ("id", Json.Encode.string val.id)
71 , ("name", Json.Encode.string val.name)
767 , ("name", Json.Encode.string val.name)
72 ]
768 ]
73
769
@@ -84,17 +780,97 @@ jsonEncSub_LoadCiphers_List val = (Json.Encode.list jsonEncSub_LoadCiphers) val
84
780
85
781
86
782
783+type alias Sub_NeedsMasterPassword =
784+ { login: String
785+ , server: String
786+ }
787+
788+jsonDecSub_NeedsMasterPassword : Json.Decode.Decoder ( Sub_NeedsMasterPassword )
789+jsonDecSub_NeedsMasterPassword =
790+ Json.Decode.succeed (\plogin pserver -> {login = plogin, server = pserver})
791+ |> required "login" (Json.Decode.string)
792+ |> required "server" (Json.Decode.string)
793+
794+jsonEncSub_NeedsMasterPassword : Sub_NeedsMasterPassword -> Value
795+jsonEncSub_NeedsMasterPassword val =
796+ Json.Encode.object
797+ [ ("login", Json.Encode.string val.login)
798+ , ("server", Json.Encode.string val.server)
799+ ]
800+
801+
802+
803+type alias Sub_NeedsSecondFactor_List = (List TwoFactorProviderType)
804+
805+jsonDecSub_NeedsSecondFactor_List : Json.Decode.Decoder ( Sub_NeedsSecondFactor_List )
806+jsonDecSub_NeedsSecondFactor_List =
807+ Json.Decode.list (jsonDecTwoFactorProviderType)
808+
809+jsonEncSub_NeedsSecondFactor_List : Sub_NeedsSecondFactor_List -> Value
810+jsonEncSub_NeedsSecondFactor_List val = (Json.Encode.list jsonEncTwoFactorProviderType) val
811+
812+
813+
814+type alias Sub_Totp =
815+ { code: String
816+ , interval: Int
817+ , source: String
818+ }
819+
820+jsonDecSub_Totp : Json.Decode.Decoder ( Sub_Totp )
821+jsonDecSub_Totp =
822+ Json.Decode.succeed (\pcode pinterval psource -> {code = pcode, interval = pinterval, source = psource})
823+ |> required "code" (Json.Decode.string)
824+ |> required "interval" (Json.Decode.int)
825+ |> required "source" (Json.Decode.string)
826+
827+jsonEncSub_Totp : Sub_Totp -> Value
828+jsonEncSub_Totp val =
829+ Json.Encode.object
830+ [ ("code", Json.Encode.string val.code)
831+ , ("interval", Json.Encode.int val.interval)
832+ , ("source", Json.Encode.string val.source)
833+ ]
834+
835+
836+
87type Sub =
837type Sub =
838+ CaptchaDone
839+ | CipherChanged FullCipher
840+ | CipherDeleted FullCipher
88− Error String
841+ | Error String
842+ | GeneratedPassword String
843+ | LoadCipher FullCipher
89 | LoadCiphers Sub_LoadCiphers_List
844 | LoadCiphers Sub_LoadCiphers_List
845+ | LoginSuccessful
846+ | NeedsCaptcha String
90 | NeedsLogin
847 | NeedsLogin
848+ | NeedsMasterPassword Sub_NeedsMasterPassword
849+ | NeedsSecondFactor Sub_NeedsSecondFactor_List
850+ | RecieveEmail String
851+ | Reset
852+ | Totp Sub_Totp
853+ | WrongPassword
91
854
92jsonDecSub : Json.Decode.Decoder ( Sub )
855jsonDecSub : Json.Decode.Decoder ( Sub )
93jsonDecSub =
856jsonDecSub =
94 let jsonDecDictSub = Dict.fromList
857 let jsonDecDictSub = Dict.fromList
858+ [ ("CaptchaDone", Json.Decode.lazy (\_ -> Json.Decode.succeed CaptchaDone))
859+ , ("CipherChanged", Json.Decode.lazy (\_ -> Json.Decode.map CipherChanged (jsonDecFullCipher)))
860+ , ("CipherDeleted", Json.Decode.lazy (\_ -> Json.Decode.map CipherDeleted (jsonDecFullCipher)))
95− [ ("Error", Json.Decode.lazy (\_ -> Json.Decode.map Error (Json.Decode.string)))
861+ , ("Error", Json.Decode.lazy (\_ -> Json.Decode.map Error (Json.Decode.string)))
862+ , ("GeneratedPassword", Json.Decode.lazy (\_ -> Json.Decode.map GeneratedPassword (Json.Decode.string)))
863+ , ("LoadCipher", Json.Decode.lazy (\_ -> Json.Decode.map LoadCipher (jsonDecFullCipher)))
96 , ("LoadCiphers", Json.Decode.lazy (\_ -> Json.Decode.map LoadCiphers (jsonDecSub_LoadCiphers_List)))
864 , ("LoadCiphers", Json.Decode.lazy (\_ -> Json.Decode.map LoadCiphers (jsonDecSub_LoadCiphers_List)))
865+ , ("LoginSuccessful", Json.Decode.lazy (\_ -> Json.Decode.succeed LoginSuccessful))
866+ , ("NeedsCaptcha", Json.Decode.lazy (\_ -> Json.Decode.map NeedsCaptcha (Json.Decode.string)))
97 , ("NeedsLogin", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedsLogin))
867 , ("NeedsLogin", Json.Decode.lazy (\_ -> Json.Decode.succeed NeedsLogin))
868+ , ("NeedsMasterPassword", Json.Decode.lazy (\_ -> Json.Decode.map NeedsMasterPassword (jsonDecSub_NeedsMasterPassword)))
869+ , ("NeedsSecondFactor", Json.Decode.lazy (\_ -> Json.Decode.map NeedsSecondFactor (jsonDecSub_NeedsSecondFactor_List)))
870+ , ("RecieveEmail", Json.Decode.lazy (\_ -> Json.Decode.map RecieveEmail (Json.Decode.string)))
871+ , ("Reset", Json.Decode.lazy (\_ -> Json.Decode.succeed Reset))
872+ , ("Totp", Json.Decode.lazy (\_ -> Json.Decode.map Totp (jsonDecSub_Totp)))
873+ , ("WrongPassword", Json.Decode.lazy (\_ -> Json.Decode.succeed WrongPassword))
98 ]
874 ]
99 jsonDecObjectSetSub = Set.fromList []
875 jsonDecObjectSetSub = Set.fromList []
100 in decodeSumTaggedObject "Sub" "tag" "contents" jsonDecDictSub jsonDecObjectSetSub
876 in decodeSumTaggedObject "Sub" "tag" "contents" jsonDecDictSub jsonDecObjectSetSub
@@ -102,8 +878,50 @@ jsonDecSub =
102jsonEncSub : Sub -> Value
878jsonEncSub : Sub -> Value
103jsonEncSub val =
879jsonEncSub val =
104 let keyval v = case v of
880 let keyval v = case v of
881+ CaptchaDone -> ("CaptchaDone", encodeValue (Json.Encode.list identity []))
882+ CipherChanged v1 -> ("CipherChanged", encodeValue (jsonEncFullCipher v1))
883+ CipherDeleted v1 -> ("CipherDeleted", encodeValue (jsonEncFullCipher v1))
105 Error v1 -> ("Error", encodeValue (Json.Encode.string v1))
884 Error v1 -> ("Error", encodeValue (Json.Encode.string v1))
885+ GeneratedPassword v1 -> ("GeneratedPassword", encodeValue (Json.Encode.string v1))
886+ LoadCipher v1 -> ("LoadCipher", encodeValue (jsonEncFullCipher v1))
106 LoadCiphers v1 -> ("LoadCiphers", encodeValue (jsonEncSub_LoadCiphers_List v1))
887 LoadCiphers v1 -> ("LoadCiphers", encodeValue (jsonEncSub_LoadCiphers_List v1))
888+ LoginSuccessful -> ("LoginSuccessful", encodeValue (Json.Encode.list identity []))
889+ NeedsCaptcha v1 -> ("NeedsCaptcha", encodeValue (Json.Encode.string v1))
107 NeedsLogin -> ("NeedsLogin", encodeValue (Json.Encode.list identity []))
890 NeedsLogin -> ("NeedsLogin", encodeValue (Json.Encode.list identity []))
891+ NeedsMasterPassword v1 -> ("NeedsMasterPassword", encodeValue (jsonEncSub_NeedsMasterPassword v1))
892+ NeedsSecondFactor v1 -> ("NeedsSecondFactor", encodeValue (jsonEncSub_NeedsSecondFactor_List v1))
893+ RecieveEmail v1 -> ("RecieveEmail", encodeValue (Json.Encode.string v1))
894+ Reset -> ("Reset", encodeValue (Json.Encode.list identity []))
895+ Totp v1 -> ("Totp", encodeValue (jsonEncSub_Totp v1))
896+ WrongPassword -> ("WrongPassword", encodeValue (Json.Encode.list identity []))
108 in encodeSumTaggedObject "tag" "contents" keyval val
897 in encodeSumTaggedObject "tag" "contents" keyval val
109
898
899+
900+
901+type TwoFactorProviderType =
902+ Authenticator
903+ | Duo
904+ | Email
905+ | OrganizationDuo
906+ | Remember
907+ | U2f
908+ | WebAuthn
909+ | Yubikey
910+
911+jsonDecTwoFactorProviderType : Json.Decode.Decoder ( TwoFactorProviderType )
912+jsonDecTwoFactorProviderType =
913+ let jsonDecDictTwoFactorProviderType = Dict.fromList [("Authenticator", Authenticator), ("Duo", Duo), ("Email", Email), ("OrganizationDuo", OrganizationDuo), ("Remember", Remember), ("U2f", U2f), ("WebAuthn", WebAuthn), ("Yubikey", Yubikey)]
914+ in decodeSumUnaries "TwoFactorProviderType" jsonDecDictTwoFactorProviderType
915+
916+jsonEncTwoFactorProviderType : TwoFactorProviderType -> Value
917+jsonEncTwoFactorProviderType val =
918+ case val of
919+ Authenticator -> Json.Encode.string "Authenticator"
920+ Duo -> Json.Encode.string "Duo"
921+ Email -> Json.Encode.string "Email"
922+ OrganizationDuo -> Json.Encode.string "OrganizationDuo"
923+ Remember -> Json.Encode.string "Remember"
924+ U2f -> Json.Encode.string "U2f"
925+ WebAuthn -> Json.Encode.string "WebAuthn"
926+ Yubikey -> Json.Encode.string "Yubikey"
927+
frontend/FFI.elm+1−3
@@ -2,7 +2,6 @@ port module FFI exposing (getBridge, sendBridge)
2
2
3import Bridge
3import Bridge
4import Json.Decode as D
4import Json.Decode as D
5−import Json.Encode as E
6
5
7
6
8port bridgeSub : (D.Value -> msg) -> Sub msg
7port bridgeSub : (D.Value -> msg) -> Sub msg
@@ -14,8 +13,7 @@ port bridgeCmd : D.Value -> Cmd msg
14getBridge : (String -> msg) -> (Bridge.Sub -> msg) -> Sub msg
13getBridge : (String -> msg) -> (Bridge.Sub -> msg) -> Sub msg
15getBridge err f =
14getBridge err f =
16 bridgeSub
15 bridgeSub
17− ((\v -> Debug.log (E.encode 1 v) v)
18− >> D.decodeValue Bridge.jsonDecSub
16+ (D.decodeValue Bridge.jsonDecSub
19 >> (\res ->
17 >> (\res ->
20 case res of
18 case res of
21 Ok a ->
19 Ok a ->
frontend/GlobalEvents.elmnew file+9
@@ -0,0 +1,9 @@
1+module GlobalEvents exposing (..)
2+
3+import Bridge
4+
5+
6+type Event
7+ = UpdateCipher Bridge.FullCipher
8+ | GeneratedPassword String
9+ | DecodedTotp Bridge.Sub_Totp
frontend/Logic/Cipher.elmnew file+78
@@ -0,0 +1,78 @@
1+module Logic.Cipher exposing (normalizeCipher)
2+
3+import Bridge
4+
5+
6+normalizeCipher : Bridge.Cipher -> Bridge.Cipher
7+normalizeCipher x =
8+ case x of
9+ Bridge.CardCipher c ->
10+ Bridge.CardCipher (normalizeCardCipher c)
11+
12+ Bridge.IdentityCipher c ->
13+ Bridge.IdentityCipher (normalizeIdentityCipher c)
14+
15+ Bridge.LoginCipher c ->
16+ Bridge.LoginCipher (normalizeLoginCipher c)
17+
18+ Bridge.NoteCipher c ->
19+ Bridge.NoteCipher c
20+
21+
22+normalizeCardCipher : Bridge.Cipher_CardCipher -> Bridge.Cipher_CardCipher
23+normalizeCardCipher { brand, cardholderName, code, expMonth, expYear, number } =
24+ { brand = normalizeStringMaybe brand
25+ , cardholderName = normalizeStringMaybe cardholderName
26+ , code = normalizeStringMaybe code
27+ , expMonth = normalizeStringMaybe expMonth
28+ , expYear = normalizeStringMaybe expYear
29+ , number = normalizeStringMaybe number
30+ }
31+
32+
33+normalizeIdentityCipher : Bridge.Cipher_IdentityCipher -> Bridge.Cipher_IdentityCipher
34+normalizeIdentityCipher { address1, address2, address3, city, company, country, email, firstName, lastName, licenseNumber, middleName, passportNumber, phone, postalCode, ssn, state, title, username } =
35+ { address1 = normalizeStringMaybe address1
36+ , address2 = normalizeStringMaybe address2
37+ , address3 = normalizeStringMaybe address3
38+ , city = normalizeStringMaybe city
39+ , company = normalizeStringMaybe company
40+ , country = normalizeStringMaybe country
41+ , email = normalizeStringMaybe email
42+ , firstName = normalizeStringMaybe firstName
43+ , lastName = normalizeStringMaybe lastName
44+ , licenseNumber = normalizeStringMaybe licenseNumber
45+ , middleName = normalizeStringMaybe middleName
46+ , passportNumber = normalizeStringMaybe passportNumber
47+ , phone = normalizeStringMaybe phone
48+ , postalCode = normalizeStringMaybe postalCode
49+ , ssn = normalizeStringMaybe ssn
50+ , state = normalizeStringMaybe state
51+ , title = normalizeStringMaybe title
52+ , username = normalizeStringMaybe username
53+ }
54+
55+
56+normalizeLoginCipher : Bridge.Cipher_LoginCipher -> Bridge.Cipher_LoginCipher
57+normalizeLoginCipher { password, totp, uris, username } =
58+ { password = password
59+ , uris = uris |> List.map String.trim |> List.filter String.isEmpty
60+ , totp = normalizeStringMaybe totp
61+ , username = username
62+ }
63+
64+
65+normalizeStringMaybe : Maybe String -> Maybe String
66+normalizeStringMaybe =
67+ Maybe.andThen
68+ (\x ->
69+ let
70+ y =
71+ String.trim x
72+ in
73+ if String.isEmpty y then
74+ Nothing
75+
76+ else
77+ Just y
78+ )
frontend/Logic/SecondFactor.elmnew file+31
@@ -0,0 +1,31 @@
1+module Logic.SecondFactor exposing (secondFactorName)
2+
3+import Bridge
4+
5+
6+secondFactorName : Bridge.TwoFactorProviderType -> String
7+secondFactorName factor =
8+ case factor of
9+ Bridge.Authenticator ->
10+ "Authenticator"
11+
12+ Bridge.Duo ->
13+ "Duo"
14+
15+ Bridge.Email ->
16+ "Email"
17+
18+ Bridge.OrganizationDuo ->
19+ "Organization Duo"
20+
21+ Bridge.Remember ->
22+ "Remember (IDK what this is)"
23+
24+ Bridge.U2f ->
25+ "U2f"
26+
27+ Bridge.WebAuthn ->
28+ "WebAuthn"
29+
30+ Bridge.Yubikey ->
31+ "Yubikey"
frontend/Main.elm+690−123
@@ -1,65 +1,227 @@
1−module Main exposing (..)
1+module Main exposing (main)
2
2
3import Bridge
3import Bridge
4import Browser
4import Browser
5−import FFI exposing (getBridge)
5+import FFI exposing (getBridge, sendBridge)
6+import GlobalEvents exposing (Event)
6import Html exposing (..)
7import Html exposing (..)
7−import Html.Attributes as Attr
8+import Html.Lazy as Lazy
9+import List.Nonempty as Nonempty exposing (Nonempty(..))
8import Notification
10import Notification
11+import Pages.Captcha as Captcha
12+import Pages.Cipher as Cipher
9import Pages.Ciphers as Ciphers
13import Pages.Ciphers as Ciphers
14+import Pages.EditCipher as EditCipher exposing (Msg(..))
10import Pages.Loader exposing (loader)
15import Pages.Loader exposing (loader)
11import Pages.Login as Login
16import Pages.Login as Login
17+import Pages.MasterPassword as MasterPassword
12−import Pages.Navigation as Navigation
18+import Pages.Navigation as Navigation exposing (TopButton(..))
19+import Pages.SecondFactor as SecondFactor
20+import Pages.SecondFactorSelect as SecondFactorSelect
21+import Task
22+import Time
23+import Types exposing (CipherId)
13import Utils exposing (..)
24import Utils exposing (..)
14
25
15
26
27+notificationLingerSeconds : Int
28+notificationLingerSeconds =
29+ 15
30+
31+
16type Msg
32type Msg
17− = RecieveMessage String
18− | ShowLoginPage
33+ = ShowLoginPage
19− | ShowError String
34+ | ShowError String String
35+ | ShowInfo String String
20 | CloseNotification
36 | CloseNotification
21− | SubmitLogin { email : String, password : String, server : String }
37+ | SubmitLogin Bridge.Cmd_Login
22− | LoginMsg Login.Msg
23− | CiphersMsg Ciphers.Msg
24 | LoadCiphers Bridge.Sub_LoadCiphers_List
38 | LoadCiphers Bridge.Sub_LoadCiphers_List
39+ | LoginSuccessful
40+ | Reset
41+ | NeedsReset
42+ | SendMasterPassword { password : String }
43+ | ShowMasterPasswordPage { server : String, login : String }
44+ | ShowCipherPage Bridge.FullCipher
45+ | RequestCipher CipherId
46+ | PopView
47+ | RecieveEmail String
48+ | Copy String
49+ | Open String
50+ | ShowCaptcha Captcha.HCaptchSiteKey
51+ | ClearNotification { currentTime : Time.Posix }
52+ | UpdateLastNotificatioTime Time.Posix
53+ | EditCipher Bridge.FullCipher
54+ | UpdateCipher Bridge.FullCipher
55+ | CreateCipher Bridge.FullCipher
56+ | FireGlobalEvent Event
57+ | GeneratePassword Bridge.PasswordGeneratorConfig
58+ | OpenNewCipherEditPage Bridge.CipherType
59+ | WrongPassword
60+ | DeleteCipher Bridge.FullCipher
61+ | RequestTotp String
62+ | ShowSecondFactorSelect (List Bridge.TwoFactorProviderType)
63+ | SelectSecondFactor
64+ { provider : Bridge.TwoFactorProviderType
65+ , requestFromServer : Bool
66+ }
67+ | PageMsg PageMsg
68+
69+
70+type PageMsg
71+ = LoginMsg Login.Msg
72+ | CiphersMsg Ciphers.Msg
73+ | MasterPasswordMsg MasterPassword.Msg
74+ | CipherMsg Cipher.Msg
75+ | EditCipherMsg EditCipher.Msg
76+ | SecondFactorSelectMsg SecondFactorSelect.Msg
77+ | SecondFactorMsg SecondFactor.Msg
25
78
26
79
27type alias Model =
80type alias Model =
28 { notifications : List Notification.Config
81 { notifications : List Notification.Config
29− , page : PageModel
82+ , pageStack : Navigation.PageStack PageModel
83+ , userEmail : Maybe String
84+ , lastNotificationTime : Time.Posix
30 }
85 }
31
86
32
87
88+findLoginDetails :
89+ List PageModel
90+ ->
91+ Maybe
92+ { server : String
93+ , email : String
94+ , password : String
95+ }
96+findLoginDetails xs =
97+ case xs of
98+ (LoginModel { server, email, password }) :: _ ->
99+ Just
100+ { server = server
101+ , email = email
102+ , password = password
103+ }
104+
105+ _ :: rest ->
106+ findLoginDetails rest
107+
108+ [] ->
109+ Nothing
110+
111+
33−appendNotification : Notification.Config -> Model -> Model
112+appendNotification : Notification.Config -> Model -> ( Model, Cmd Msg )
34appendNotification cfg model =
113appendNotification cfg model =
35− { model | notifications = cfg :: model.notifications }
114+ ( { model | notifications = cfg :: model.notifications }, Task.perform UpdateLastNotificatioTime Time.now )
36
115
37
116
38type PageModel
117type PageModel
39− = LoginModel Login.Model
118+ = LoginModel (Login.Model Msg)
40 | LoadingPage
119 | LoadingPage
41− | CiphersModel Ciphers.Model
120+ | CiphersModel (Ciphers.Model Msg)
42−
121+ | EditCipherModel (EditCipher.Model Msg)
43−
122+ | MasterPasswordModel (MasterPassword.Model Msg)
123+ | CipherModel (Cipher.Model Msg)
124+ | CaptchaModel Captcha.Model
125+ | SecondFactorSelectModel (SecondFactorSelect.Model Msg)
126+ | SecondFactorModel (SecondFactor.Model Msg)
127+
128+
129+showPage :
130+ String
131+ -> PageModel
132+ ->
133+ { title : List (Html Msg)
44−showPage : PageModel -> ( String, List (Html Msg) )
134+ , body : List (Html Msg)
135+ , topButton : Maybe (Navigation.TopButton Msg)
136+ }
45−showPage page =
137+showPage email page =
138+ let
139+ simpleBackButton =
140+ BackButton { action = PopView, icon = Nothing }
141+
142+ liftPageWith :
143+ (pageMsg -> PageMsg)
144+ ->
145+ { title : List (Html pageMsg)
146+ , body : List (Html pageMsg)
147+ , topButton : Maybe (Navigation.TopButton Msg)
148+ }
149+ ->
150+ { title : List (Html Msg)
151+ , body : List (Html Msg)
152+ , topButton : Maybe (Navigation.TopButton Msg)
153+ }
154+ liftPageWith lift { title, body, topButton } =
155+ { title = title |> List.map (Html.map (lift >> PageMsg))
156+ , body = body |> List.map (Html.map (lift >> PageMsg))
157+ , topButton = topButton
158+ }
159+ in
46 case page of
160 case page of
47 LoginModel model ->
161 LoginModel model ->
48− let
162+ liftPageWith LoginMsg
49− p =
163+ { title = [ text Login.title ]
50− Login.page loginCallbacks LoginMsg
51− in
52− ( p.title model, p.view model )
164+ , body = Login.view model
165+ , topButton = Nothing
166+ }
53
167
54 CiphersModel model ->
168 CiphersModel model ->
55− let
169+ liftPageWith CiphersMsg
56− p =
170+ { title = Ciphers.title model
57− Ciphers.page {} CiphersMsg
171+ , body = Ciphers.view model
58− in
172+ , topButton =
59− ( p.title model, p.view model )
173+ Ciphers.menuConfig email model
174+ |> Navigation.mapMenuConfig (CiphersMsg >> PageMsg)
175+ |> Navigation.MenuButton
176+ |> Just
177+ }
60
178
61 LoadingPage ->
179 LoadingPage ->
62− ( "", [ loader ] )
180+ { title = []
181+ , body = [ loader ]
182+ , topButton = Just simpleBackButton
183+ }
184+
185+ MasterPasswordModel model ->
186+ liftPageWith MasterPasswordMsg
187+ { title = [ text MasterPassword.title ]
188+ , body = MasterPassword.view model
189+ , topButton = Nothing
190+ }
191+
192+ CipherModel model ->
193+ liftPageWith CipherMsg
194+ { title = Cipher.title model
195+ , body = Cipher.view model
196+ , topButton = Just simpleBackButton
197+ }
198+
199+ CaptchaModel model ->
200+ { title = [ text Captcha.title ]
201+ , body = Captcha.view model
202+ , topButton = Just simpleBackButton
203+ }
204+
205+ EditCipherModel model ->
206+ liftPageWith EditCipherMsg
207+ { title = EditCipher.title model
208+ , body = EditCipher.view model
209+ , topButton = Just (BackButton { action = PopView, icon = Just "close" })
210+ }
211+
212+ SecondFactorSelectModel model ->
213+ liftPageWith SecondFactorSelectMsg
214+ { title = [ text SecondFactorSelect.title ]
215+ , body = SecondFactorSelect.view model
216+ , topButton = Just simpleBackButton
217+ }
218+
219+ SecondFactorModel model ->
220+ liftPageWith SecondFactorMsg
221+ { title = [ SecondFactor.title model |> text ]
222+ , body = [ SecondFactor.view model ]
223+ , topButton = Just simpleBackButton
224+ }
63
225
64
226
65main : Program () Model Msg
227main : Program () Model Msg
@@ -68,27 +230,116 @@ main =
68 { init = \_ -> init
230 { init = \_ -> init
69 , view = view
231 , view = view
70 , update = update
232 , update = update
71− , subscriptions =
233+ , subscriptions = subscriptions
72− \_ ->
73− getBridge ShowError
74− (\msg ->
75− case msg of
76− Bridge.NeedsLogin ->
77− ShowLoginPage
78−
79− Bridge.Error err ->
80− ShowError err
81−
82− Bridge.LoadCiphers ciphers ->
83− LoadCiphers ciphers
84− )
85 }
234 }
86
235
87
236
237+subscriptions : Model -> Sub Msg
238+subscriptions model =
239+ Sub.batch
240+ ([ getBridge (ShowError "Something went wrong!")
241+ (\msg ->
242+ case msg of
243+ Bridge.NeedsLogin ->
244+ ShowLoginPage
245+
246+ Bridge.Error err ->
247+ ShowError "Something went wrong!" err
248+
249+ Bridge.LoadCiphers ciphers ->
250+ LoadCiphers ciphers
251+
252+ Bridge.LoginSuccessful ->
253+ LoginSuccessful
254+
255+ Bridge.Reset ->
256+ Reset
257+
258+ Bridge.NeedsMasterPassword { server, login } ->
259+ ShowMasterPasswordPage { server = server, login = login }
260+
261+ Bridge.LoadCipher cipher ->
262+ ShowCipherPage cipher
263+
264+ Bridge.RecieveEmail email ->
265+ RecieveEmail email
266+
267+ Bridge.NeedsCaptcha uri ->
268+ ShowCaptcha uri
269+
270+ Bridge.CaptchaDone ->
271+ PopView
272+
273+ Bridge.CipherChanged c ->
274+ ShowInfo "Entry updated" ("The entry “" ++ c.name ++ "” has been successfully updated.")
275+
276+ Bridge.GeneratedPassword password ->
277+ GlobalEvents.GeneratedPassword password |> FireGlobalEvent
278+
279+ Bridge.WrongPassword ->
280+ WrongPassword
281+
282+ Bridge.CipherDeleted c ->
283+ ShowInfo "Entry deleted" ("The entry “" ++ c.name ++ "” has been successfully deleted.")
284+
285+ Bridge.Totp totp ->
286+ GlobalEvents.DecodedTotp totp |> FireGlobalEvent
287+
288+ Bridge.NeedsSecondFactor secondFactors ->
289+ case secondFactors of
290+ [ provider ] ->
291+ SelectSecondFactor
292+ { provider = provider
293+ , requestFromServer = False
294+ }
295+
296+ _ ->
297+ ShowSecondFactorSelect secondFactors
298+ )
299+ ]
300+ ++ optional (List.isEmpty model.notifications |> not) (Time.every 1000 (\t -> ClearNotification { currentTime = t }))
301+ ++ (model.pageStack
302+ |> Nonempty.toList
303+ |> List.map
304+ (\x ->
305+ case x of
306+ LoginModel _ ->
307+ Sub.none
308+
309+ LoadingPage ->
310+ Sub.none
311+
312+ CiphersModel _ ->
313+ Sub.none
314+
315+ EditCipherModel _ ->
316+ Sub.none
317+
318+ MasterPasswordModel _ ->
319+ Sub.none
320+
321+ CipherModel m ->
322+ Cipher.subscriptions m
323+
324+ CaptchaModel _ ->
325+ Sub.none
326+
327+ SecondFactorSelectModel _ ->
328+ Sub.none
329+
330+ SecondFactorModel _ ->
331+ Sub.none
332+ )
333+ )
334+ )
335+
336+
88init : ( Model, Cmd Msg )
337init : ( Model, Cmd Msg )
89init =
338init =
90 ( { notifications = []
339 ( { notifications = []
91− , page = LoadingPage
340+ , pageStack = Nonempty.singleton LoadingPage
341+ , userEmail = Nothing
342+ , lastNotificationTime = Time.millisToPosix 0
92 }
343 }
93 , FFI.sendBridge Bridge.Init
344 , FFI.sendBridge Bridge.Init
94 )
345 )
@@ -96,118 +347,434 @@ init =
96
347
97view : Model -> Html Msg
348view : Model -> Html Msg
98view model =
349view model =
99− let
100− ( title, body ) =
101− showPage model.page
102− in
103 div []
350 div []
104− [ Navigation.navigation { back = False, title = title }
105− , main_ []
106− (maybeList (List.head model.notifications) (Notification.notification CloseNotification)
351+ (maybeList (List.head model.notifications) (Lazy.lazy2 Notification.notification CloseNotification)
107− ++ [ div [ Attr.class "p-side-navigation--icons is-drawer-expanded" ]
352+ ++ [ Lazy.lazy2 Navigation.showNavigationView
108− [ div [ Attr.class "p-side-navigation__overlay" ] []
353+ model.pageStack
109− , nav [ Attr.class "p-side-navigation__drawer" ]
354+ (showPage (Maybe.withDefault "" model.userEmail))
110− [ div [ Attr.class "p-side-navigation__drawer-header" ]
355+ ]
111− [ a [ Attr.class "p-side-navigation__toggle--in-drawer" ] [ text "mail@iko.soy" ]
356+ )
112− ]
357+
113− , ul [ Attr.class "p-side-navigation__list" ]
358+
114− (List.repeat 6
359+mapHead : (a -> a) -> Nonempty a -> Nonempty a
115− (li [ Attr.class "p-side-navigation__item" ]
360+mapHead f (Nonempty x xx) =
116− [ a [ Attr.class "p-side-navigation__link" ]
361+ Nonempty (f x) xx
117− [ i [ Attr.class "p-icon--help p-side-navigation__icon" ] []
362+
118− , text "Users"
363+
119− ]
364+doNotStoreInHistory : PageModel -> Bool
120− ]
365+doNotStoreInHistory page =
121− )
366+ case page of
122− )
367+ LoadingPage ->
123− ]
368+ True
124− ]
369+
125− ]
370+ _ ->
126− ++ body
371+ False
127− )
128− ]
129
372
130
373
131update : Msg -> Model -> ( Model, Cmd Msg )
374update : Msg -> Model -> ( Model, Cmd Msg )
132update msg model =
375update msg model =
133 let
376 let
134− processPage : (pageModel -> PageModel) -> ( Result String pageModel, Cmd Msg ) -> ( Model, Cmd Msg )
377+ updatePageStackHead : PageModel -> Model
135− processPage liftModel ( resultModel, cmd ) =
378+ updatePageStackHead mdl =
136− case resultModel of
379+ { model | pageStack = mapHead (always mdl) model.pageStack }
137− Ok mdl ->
380+
138− ( { model | page = liftModel mdl }, cmd )
381+ appendPageStack : PageModel -> Model
139−
382+ appendPageStack mdl =
140− Err err ->
383+ { model | pageStack = model.pageStack |> Nonempty.toList |> List.filter (doNotStoreInHistory >> not) |> Nonempty mdl }
141− ( appendNotification
384+
142− { title = "An error had occured"
385+ keepStackWith : PageModel -> Model
143− , message = err
386+ keepStackWith mdl =
144− , severity = Notification.Error
387+ { model | pageStack = Nonempty.cons mdl model.pageStack }
145− }
146− model
147− , cmd
148− )
149 in
388 in
150 case msg of
389 case msg of
151− RecieveMessage x ->
390+ ShowError title err ->
152− ( appendNotification
391+ appendNotification
153− { title = "Got a message!"
392+ { title = title
393+ , message = err
394+ , severity = Notification.Error
395+ }
396+ model
397+
398+ ShowInfo title inf ->
399+ appendNotification
400+ { title = title
154− , message = x
401+ , message = inf
155 , severity = Notification.Info
402 , severity = Notification.Info
156 }
403 }
157 model
404 model
405+
406+ CloseNotification ->
407+ ( { model | notifications = tailEmpty model.notifications }
158 , Cmd.none
408 , Cmd.none
159 )
409 )
160
410
161− ShowError err ->
411+ SubmitLogin data ->
162− ( appendNotification
412+ ( keepStackWith <| LoadingPage
163− { title = "Something went wrong"
413+ , FFI.sendBridge (Bridge.Login data)
164− , message = err
414+ )
165− , severity = Notification.Error
415+
416+ ShowLoginPage ->
417+ ( Login.init loginCallbacks |> LoginModel |> appendPageStack
418+ , Cmd.none
419+ )
420+
421+ LoadCiphers ciphers ->
422+ let
423+ ciphersShown =
424+ model.pageStack
425+ |> Nonempty.toList
426+ |> List.any
427+ (\x ->
428+ case x of
429+ CiphersModel _ ->
430+ True
431+
432+ _ ->
433+ False
434+ )
435+ in
436+ ( if ciphersShown then
437+ { model
438+ | pageStack =
439+ model.pageStack
440+ |> Nonempty.map
441+ (\x ->
442+ case x of
443+ CiphersModel pageModel ->
444+ CiphersModel (Ciphers.updateCiphers ciphers pageModel)
445+
446+ other ->
447+ other
448+ )
166 }
449 }
167− model
450+
451+ else
452+ appendPageStack <| CiphersModel (Ciphers.init ciphersCallbacks ciphers)
168 , Cmd.none
453 , Cmd.none
169 )
454 )
170
455
171− CloseNotification ->
456+ LoginSuccessful ->
172− ( { model | notifications = tailEmpty model.notifications }
457+ ( { model | pageStack = Nonempty.singleton LoadingPage }
458+ , Cmd.batch [ sendBridge Bridge.NeedCiphersList, sendBridge Bridge.NeedEmail ]
459+ )
460+
461+ Reset ->
462+ init
463+
464+ ShowMasterPasswordPage { server, login } ->
465+ ( MasterPassword.init masterPasswordCallbacks { server = server, login = login }
466+ |> MasterPasswordModel
467+ |> appendPageStack
173 , Cmd.none
468 , Cmd.none
174 )
469 )
175
470
176− SubmitLogin data ->
471+ NeedsReset ->
472+ ( appendPageStack <| LoadingPage, sendBridge Bridge.NeedsReset )
473+
474+ SendMasterPassword { password } ->
475+ ( appendPageStack <| LoadingPage, sendBridge (Bridge.SendMasterPassword password) )
476+
477+ ShowCipherPage cipher ->
478+ Cipher.init cipherCallbacks cipher
479+ |> Tuple.mapFirst (\pageModel -> appendPageStack <| CipherModel pageModel)
480+
481+ RequestCipher id ->
482+ ( appendPageStack <| LoadingPage, sendBridge (Bridge.RequestCipher id) )
483+
484+ PopView ->
485+ ( { model | pageStack = Navigation.popView model.pageStack }
486+ , Cmd.none
487+ )
488+
489+ RecieveEmail email ->
490+ ( { model | userEmail = Just email }, Cmd.none )
491+
492+ Copy text ->
493+ ( model, FFI.sendBridge (Bridge.Copy text) )
494+
495+ Open uri ->
496+ ( model, FFI.sendBridge (Bridge.Open uri) )
497+
498+ ShowCaptcha uri ->
499+ ( Captcha.init uri |> CaptchaModel |> appendPageStack, Cmd.none )
500+
501+ ClearNotification { currentTime } ->
502+ if Time.posixToMillis model.lastNotificationTime + notificationLingerSeconds * 1000 > Time.posixToMillis currentTime then
503+ ( model, Cmd.none )
504+
505+ else
506+ ( { model | notifications = List.tail model.notifications |> Maybe.withDefault [] }
507+ , Task.perform UpdateLastNotificatioTime Time.now
508+ )
509+
510+ UpdateLastNotificatioTime time ->
511+ ( { model | lastNotificationTime = time }, Cmd.none )
512+
513+ EditCipher cipher ->
514+ EditCipher.init { fullCipher = cipher, callbacks = editCipherCallbacks }
515+ |> Tuple.mapFirst (\pageModel -> keepStackWith <| EditCipherModel pageModel)
516+
517+ UpdateCipher cipher ->
177 ( model
518 ( model
178− , FFI.sendBridge (Bridge.Login data)
519+ , Cmd.batch
520+ [ Bridge.UpdateCipher cipher |> sendBridge
521+ , cipher |> GlobalEvents.UpdateCipher |> FireGlobalEvent |> pureCmd
522+ , PopView |> pureCmd
523+ ]
179 )
524 )
180
525
181− LoginMsg imsg ->
526+ CreateCipher cipher ->
182− case model.page of
527+ ( model
183− LoginModel page ->
528+ , Cmd.batch
184− (Login.page loginCallbacks LoginMsg).update imsg page |> processPage LoginModel
529+ [ Bridge.CreateCipher cipher |> sendBridge
530+ , PopView |> pureCmd
531+ ]
532+ )
185
533
186− _ ->
534+ FireGlobalEvent ev ->
187− ( model, Cmd.none )
535+ ( { model
536+ | pageStack =
537+ model.pageStack
538+ |> Nonempty.map
539+ (\page ->
540+ case page of
541+ LoadingPage ->
542+ LoadingPage
188
543
189− CiphersMsg imsg ->
544+ LoginModel m ->
190− case model.page of
545+ LoginModel m
191− CiphersModel page ->
192− (Ciphers.page ciphersCallbacks CiphersMsg).update imsg page |> processPage CiphersModel
193
546
194− _ ->
547+ CiphersModel m ->
548+ Ciphers.event m ev |> CiphersModel
549+
550+ MasterPasswordModel m ->
551+ MasterPasswordModel m
552+
553+ CipherModel m ->
554+ Cipher.event m ev |> CipherModel
555+
556+ EditCipherModel m ->
557+ EditCipher.event m ev |> EditCipherModel
558+
559+ CaptchaModel m ->
560+ CaptchaModel m
561+
562+ SecondFactorSelectModel m ->
563+ SecondFactorSelectModel m
564+
565+ SecondFactorModel m ->
566+ SecondFactorModel m
567+ )
568+ }
569+ , Cmd.none
570+ )
571+
572+ GeneratePassword cfg ->
573+ ( model, FFI.sendBridge (Bridge.GeneratePassword cfg) )
574+
575+ OpenNewCipherEditPage t ->
576+ EditCipher.init
577+ { callbacks = createCipherCallbacks
578+ , fullCipher =
579+ { reprompt = 0
580+ , favorite = False
581+ , id = ""
582+ , name = ""
583+ , collectionIds = []
584+ , cipher =
585+ case t of
586+ Bridge.LoginType ->
587+ Bridge.LoginCipher
588+ { uris = []
589+ , username = Nothing
590+ , password = Nothing
591+ , totp = Nothing
592+ }
593+
594+ Bridge.NoteType ->
595+ Bridge.NoteCipher ""
596+
597+ Bridge.CardType ->
598+ Bridge.CardCipher
599+ { cardholderName = Nothing
600+ , brand = Nothing
601+ , number = Nothing
602+ , expMonth = Nothing
603+ , expYear = Nothing
604+ , code = Nothing
605+ }
606+
607+ Bridge.IdentityType ->
608+ Bridge.IdentityCipher
609+ { title = Nothing
610+ , firstName = Nothing
611+ , middleName = Nothing
612+ , lastName = Nothing
613+ , address1 = Nothing
614+ , address2 = Nothing
615+ , address3 = Nothing
616+ , city = Nothing
617+ , state = Nothing
618+ , postalCode = Nothing
619+ , country = Nothing
620+ , company = Nothing
621+ , email = Nothing
622+ , phone = Nothing
623+ , ssn = Nothing
624+ , username = Nothing
625+ , passportNumber = Nothing
626+ , licenseNumber = Nothing
627+ }
628+ }
629+ }
630+ |> Tuple.mapFirst (\pageModel -> keepStackWith <| EditCipherModel pageModel)
631+
632+ WrongPassword ->
633+ ( model
634+ , Cmd.batch
635+ [ pureCmd PopView
636+ , pureCmd (ShowError "Login failed" "The login details you provided are not valid. Please try again.")
637+ ]
638+ )
639+
640+ DeleteCipher cipher ->
641+ ( model
642+ , Cmd.batch
643+ [ pureCmd PopView
644+ , pureCmd PopView
645+ , FFI.sendBridge (Bridge.DeleteCipher cipher)
646+ ]
647+ )
648+
649+ RequestTotp totp ->
650+ ( model, FFI.sendBridge (Bridge.RequestTotp totp) )
651+
652+ ShowSecondFactorSelect secondFactors ->
653+ ( SecondFactorSelect.init secondFactorSelectCallbacks secondFactors
654+ |> SecondFactorSelectModel
655+ |> appendPageStack
656+ , Cmd.none
657+ )
658+
659+ SelectSecondFactor { provider, requestFromServer } ->
660+ case Nonempty.toList model.pageStack |> findLoginDetails of
661+ Just { email, password, server } ->
662+ ( SecondFactor.init
663+ { provider = provider
664+ , callbacks =
665+ { submit =
666+ \{ token, remember } ->
667+ SubmitLogin
668+ { email = email
669+ , password = password
670+ , server = server
671+ , secondFactor =
672+ Just
673+ { provider = provider
674+ , token = token
675+ , remember = remember
676+ }
677+ }
678+ }
679+ }
680+ |> SecondFactorModel
681+ |> appendPageStack
682+ , Bridge.ChooseSecondFactor
683+ { factor = provider
684+ , email = email
685+ , password = password
686+ , server = server
687+ , requestFromServer = requestFromServer
688+ }
689+ |> FFI.sendBridge
690+ )
691+
692+ Nothing ->
195 ( model, Cmd.none )
693 ( model, Cmd.none )
196
694
197− ShowLoginPage ->
695+ PageMsg pageMsg ->
198− (Login.page loginCallbacks LoginMsg).init ()
696+ case ( pageMsg, model.pageStack |> Nonempty.head ) of
199− |> Tuple.mapFirst (\pageModel -> { model | page = LoginModel pageModel })
697+ ( SecondFactorMsg imsg, SecondFactorModel m ) ->
698+ SecondFactor.update m imsg
699+ |> Tuple.mapBoth
700+ (SecondFactorModel >> updatePageStackHead)
701+ (Maybe.map pureCmd >> Maybe.withDefault Cmd.none)
200
702
201− LoadCiphers ciphers ->
703+ ( LoginMsg imsg, LoginModel page ) ->
202− (Ciphers.page ciphersCallbacks CiphersMsg).init ciphers
704+ Login.update imsg page
203− |> Tuple.mapFirst (\pageModel -> { model | page = CiphersModel pageModel })
705+ |> Tuple.mapFirst (LoginModel >> updatePageStackHead)
706+
707+ ( CiphersMsg imsg, CiphersModel page ) ->
708+ Ciphers.update imsg page
709+ |> Tuple.mapFirst (CiphersModel >> updatePageStackHead)
710+
711+ ( MasterPasswordMsg imsg, MasterPasswordModel page ) ->
712+ MasterPassword.update imsg page
713+ |> Tuple.mapFirst (MasterPasswordModel >> updatePageStackHead)
714+
715+ ( CipherMsg imsg, CipherModel page ) ->
716+ Cipher.update imsg page
717+ |> Tuple.mapFirst (CipherModel >> updatePageStackHead)
718+
719+ ( EditCipherMsg imsg, EditCipherModel page ) ->
720+ EditCipher.update imsg page
721+ |> Tuple.mapFirst (EditCipherModel >> updatePageStackHead)
722+
723+ ( SecondFactorSelectMsg imsg, SecondFactorSelectModel m ) ->
724+ SecondFactorSelect.update imsg m
725+ |> Tuple.mapFirst (SecondFactorSelectModel >> updatePageStackHead)
726+
727+ _ ->
728+ ( model, Cmd.none )
204
729
205
730
206loginCallbacks : Login.Callbacks Msg
731loginCallbacks : Login.Callbacks Msg
207loginCallbacks =
732loginCallbacks =
208− { submit = SubmitLogin }
733+ { submit =
734+ \{ email, server, password } ->
735+ SubmitLogin
736+ { email = email
737+ , password = password
738+ , server = server
739+ , secondFactor = Nothing
740+ }
741+ }
209
742
210
743
211−ciphersCallbacks : Ciphers.Callbacks
744+ciphersCallbacks : Ciphers.Callbacks Msg
212ciphersCallbacks =
745ciphersCallbacks =
213− {}
746+ { selected = RequestCipher
747+ , logOut = NeedsReset
748+ , createNewCipher = OpenNewCipherEditPage
749+ , lift = CiphersMsg >> PageMsg
750+ }
751+
752+
753+cipherCallbacks : Cipher.Callbacks Msg
754+cipherCallbacks =
755+ { copy = Copy, open = Open, edit = EditCipher, needTotp = RequestTotp }
756+
757+
758+editCipherCallbacks : EditCipher.Callbacks Msg
759+editCipherCallbacks =
760+ { save = UpdateCipher, generatePassword = GeneratePassword, delete = Just DeleteCipher }
761+
762+
763+createCipherCallbacks : EditCipher.Callbacks Msg
764+createCipherCallbacks =
765+ { save = CreateCipher, generatePassword = GeneratePassword, delete = Nothing }
766+
767+
768+masterPasswordCallbacks : MasterPassword.Callbacks Msg
769+masterPasswordCallbacks =
770+ { submit = SendMasterPassword
771+ , reset = NeedsReset
772+ }
773+
774+
775+secondFactorSelectCallbacks : SecondFactorSelect.Callbacks Msg
776+secondFactorSelectCallbacks =
777+ { selectFactor =
778+ \provider ->
779+ SelectSecondFactor { provider = provider, requestFromServer = True }
780+ }
frontend/Modal.elmnew file+33
@@ -0,0 +1,33 @@
1+module Modal exposing (..)
2+
3+import Html exposing (..)
4+import Html.Attributes as Attr
5+import Html.Events as Ev
6+
7+
8+type alias ModelConfig msg =
9+ { title : String
10+ , body : List (Html msg)
11+ , close : msg
12+ , footer : List (Html msg)
13+ }
14+
15+
16+modal : ModelConfig msg -> Html msg
17+modal cfg =
18+ div
19+ [ Attr.class "p-modal" ]
20+ [ section
21+ [ Attr.class "p-modal__dialog"
22+ ]
23+ (header
24+ [ Attr.class "p-modal__header"
25+ ]
26+ [ h2 [ Attr.class "p-modal__title" ] [ text cfg.title ]
27+ , button [ Attr.class "p-modal__close", Ev.onClick cfg.close ] [ text "Close" ]
28+ ]
29+ :: cfg.body
30+ ++ [ footer [ Attr.class "p-modal__footer" ] cfg.footer
31+ ]
32+ )
33+ ]
frontend/Page.elm+23−13
@@ -1,22 +1,32 @@
1module Page exposing (..)
1module Page exposing (..)
2
2
3+import Browser
3import Html exposing (..)
4import Html exposing (..)
4import Html.Events exposing (..)
5import Html.Events exposing (..)
5
6
6
7
7−type alias Env =
8+page :
8− {}
9+ { init : model
9−
10+ , view : model -> List (Html msg)
11+ , update : msg -> model -> ( model, Cmd (Maybe msg) )
12+ }
13+ -> Program () model (Maybe msg)
14+page { init, view, update } =
15+ Browser.element
16+ { subscriptions = always Sub.none
17+ , init = \_ -> ( init, Cmd.none )
18+ , view = view >> Html.div [] >> Html.map Just
19+ , update =
20+ \mmsg model ->
21+ case mmsg of
22+ Nothing ->
23+ ( model, Cmd.none )
10
24
11−type alias Page init model imsg emsg =
25+ Just msg ->
12− (imsg -> emsg)
26+ update msg model
13− -> InitializedPage init model imsg emsg
27+ }
14
28
15
29
16−type alias InitializedPage init model imsg emsg =
30+noUpdate : a -> model -> ( model, Cmd msg )
17− { init : init -> ( model, Cmd emsg )
31+noUpdate _ model =
18− , view : model -> List (Html emsg)
32+ ( model, Cmd.none )
19− , update : imsg -> model -> ( Result String model, Cmd emsg )
20− , subscriptions : model -> Sub emsg
21− , title : model -> String
22− }
frontend/Pages/Captcha.elmnew file+45
@@ -0,0 +1,45 @@
1+module Pages.Captcha exposing (HCaptchSiteKey, Model, init, main, title, view)
2+
3+import Html exposing (..)
4+import Html.Attributes as Attr
5+import Page exposing (..)
6+import Utils exposing (..)
7+
8+
9+main : Program () Model (Maybe (Maybe ()))
10+main =
11+ page
12+ { init = init "10000000-ffff-ffff-ffff-000000000001"
13+ , view = view
14+ , update = noUpdate
15+ }
16+
17+
18+type alias HCaptchSiteKey =
19+ String
20+
21+
22+type alias Model =
23+ { siteKey : HCaptchSiteKey
24+ }
25+
26+
27+title : String
28+title =
29+ "Captcha"
30+
31+
32+init : HCaptchSiteKey -> Model
33+init siteKey =
34+ { siteKey = siteKey }
35+
36+
37+view : Model -> List (Html msg)
38+view { siteKey } =
39+ [ iframe
40+ [ Attr.src ("https://iko.soy/warden/hcaptcha.html?" ++ siteKey)
41+ , Attr.style "width" "100%"
42+ , Attr.style "height" "80vh"
43+ ]
44+ []
45+ ]
frontend/Pages/Cipher.elmnew file+358
@@ -0,0 +1,358 @@
1+module Pages.Cipher exposing
2+ ( Callbacks
3+ , Model
4+ , Msg
5+ , event
6+ , init
7+ , subscriptions
8+ , title
9+ , update
10+ , view
11+ )
12+
13+import Bridge
14+import GlobalEvents
15+import Html exposing (..)
16+import Html.Attributes as Attr
17+import Html.Events as Ev
18+import Page exposing (..)
19+import Time
20+import Utils exposing (..)
21+
22+
23+type alias Model emsg =
24+ { cipher : Bridge.FullCipher
25+ , passwordHidden : Bool
26+ , cvvHidden : Bool
27+ , decodedTotp : Maybe { code : String, interval : Int }
28+ , callbacks : Callbacks emsg
29+ }
30+
31+
32+type Msg
33+ = TogglePasswordVisiblity
34+ | ToggleCVVVisiblity
35+ | Copy String
36+ | Open String
37+ | Edit Bridge.FullCipher
38+
39+
40+type alias Callbacks msg =
41+ { copy : String -> msg
42+ , open : String -> msg
43+ , edit : Bridge.FullCipher -> msg
44+ , needTotp : String -> msg
45+ }
46+
47+
48+event : Model emsg -> GlobalEvents.Event -> Model emsg
49+event model ev =
50+ case ev of
51+ GlobalEvents.UpdateCipher c ->
52+ { model
53+ | cipher =
54+ if c.id == model.cipher.id then
55+ c
56+
57+ else
58+ model.cipher
59+ }
60+
61+ GlobalEvents.DecodedTotp { source, code, interval } ->
62+ case model.cipher.cipher of
63+ Bridge.LoginCipher { totp } ->
64+ if totp == Just source then
65+ { model | decodedTotp = Just { code = code, interval = interval } }
66+
67+ else
68+ model
69+
70+ _ ->
71+ model
72+
73+ _ ->
74+ model
75+
76+
77+title : Model emsg -> List (Html Msg)
78+title { cipher } =
79+ [ text cipher.name
80+ , span [ Attr.class "u-float-right" ] [ iconButton "edit" (Edit cipher) ]
81+ ]
82+
83+
84+init : Callbacks emsg -> Bridge.FullCipher -> ( Model emsg, Cmd emsg )
85+init callbacks cipher =
86+ ( { cipher = cipher
87+ , passwordHidden = True
88+ , cvvHidden = True
89+ , decodedTotp = Nothing
90+ , callbacks = callbacks
91+ }
92+ , case cipher.cipher of
93+ Bridge.LoginCipher { totp } ->
94+ case totp of
95+ Just x ->
96+ callbacks.needTotp x |> pureCmd
97+
98+ Nothing ->
99+ Cmd.none
100+
101+ _ ->
102+ Cmd.none
103+ )
104+
105+
106+update : Msg -> Model emsg -> ( Model emsg, Cmd emsg )
107+update msg model =
108+ case msg of
109+ TogglePasswordVisiblity ->
110+ ( { model | passwordHidden = not model.passwordHidden }, Cmd.none )
111+
112+ ToggleCVVVisiblity ->
113+ ( { model | cvvHidden = not model.cvvHidden }, Cmd.none )
114+
115+ Copy text ->
116+ ( model, model.callbacks.copy text |> pureCmd )
117+
118+ Open uri ->
119+ ( model, model.callbacks.open uri |> pureCmd )
120+
121+ Edit cipher ->
122+ ( model, model.callbacks.edit cipher |> pureCmd )
123+
124+
125+subscriptions : Model msg -> Sub msg
126+subscriptions { cipher, callbacks } =
127+ case cipher.cipher of
128+ Bridge.LoginCipher { totp } ->
129+ case totp of
130+ Just x ->
131+ Time.every 1000 (always (callbacks.needTotp x))
132+
133+ Nothing ->
134+ Sub.none
135+
136+ _ ->
137+ Sub.none
138+
139+
140+row : { name : String, value : String, nameIcon : String, icons : List ( String, msg ) } -> Html msg
141+row { name, value, nameIcon, icons } =
142+ p []
143+ [ span [ Attr.class "u-text--muted" ] [ i [ Attr.class ("p-icon--" ++ nameIcon) ] [], text (" " ++ name) ]
144+ , br [] []
145+ , text value
146+ , span [ Attr.class "u-float-right" ] (icons |> List.map (uncurry iconButton))
147+ ]
148+
149+
150+view : Model emsg -> List (Html Msg)
151+view { passwordHidden, cipher, cvvHidden, decodedTotp } =
152+ (case cipher.cipher of
153+ Bridge.LoginCipher { username, password, uris, totp } ->
154+ maybeList username
155+ (\x ->
156+ row
157+ { name = "Username", value = x, nameIcon = "user", icons = [ ( "copy", Copy x ) ] }
158+ )
159+ ++ maybeList password
160+ (\x ->
161+ row
162+ { name = "Password"
163+ , value =
164+ if passwordHidden then
165+ hiddenPassword
166+
167+ else
168+ x
169+ , nameIcon = "security"
170+ , icons = [ ( hiddenButtonIcon passwordHidden, TogglePasswordVisiblity ), ( "copy", Copy x ) ]
171+ }
172+ )
173+ ++ maybeList totp
174+ (\_ ->
175+ row
176+ { name = "One-time password"
177+ , value =
178+ case decodedTotp of
179+ Nothing ->
180+ "Loading..."
181+
182+ Just { code } ->
183+ code
184+ , nameIcon = "revisions"
185+ , icons =
186+ case decodedTotp of
187+ Nothing ->
188+ []
189+
190+ Just { code } ->
191+ [ ( "copy", Copy code ) ]
192+ }
193+ )
194+ ++ (uris
195+ |> List.map
196+ (\uri ->
197+ row
198+ { name = "URL"
199+ , value = uri
200+ , nameIcon = "get-link"
201+ , icons = [ ( "external-link", Open uri ), ( "copy", Copy uri ) ]
202+ }
203+ )
204+ )
205+
206+ Bridge.NoteCipher contents ->
207+ [ row { name = "Note", value = contents, nameIcon = "switcher-environments", icons = [] }
208+ ]
209+
210+ Bridge.CardCipher { number, code, cardholderName, expMonth, expYear } ->
211+ maybeList number (\x -> row { name = "Card number", value = x, nameIcon = "containers", icons = [ ( "copy", Copy x ) ] })
212+ ++ optional (expMonth /= Nothing || expYear /= Nothing)
213+ (row
214+ (let
215+ x =
216+ [ expMonth, expYear ] |> List.concatMap (flip maybeList identity) |> String.join "/"
217+ in
218+ { name = "Expiration date"
219+ , value = x
220+ , nameIcon = "timed-out"
221+ , icons = [ ( "copy", Copy x ) ]
222+ }
223+ )
224+ )
225+ ++ maybeList code
226+ (\x ->
227+ row
228+ { name = "CVV"
229+ , value =
230+ if cvvHidden then
231+ hiddenCvv
232+
233+ else
234+ x
235+ , nameIcon = "security"
236+ , icons = [ ( hiddenButtonIcon cvvHidden, ToggleCVVVisiblity ), ( "copy", Copy x ) ]
237+ }
238+ )
239+ ++ maybeList cardholderName
240+ (\x -> row { name = "Cardholder name", value = x, nameIcon = "user", icons = [ ( "copy", Copy x ) ] })
241+
242+ Bridge.IdentityCipher { address1, address2, address3, company, email, firstName, lastName, licenseNumber, middleName, passportNumber, phone, ssn, username } ->
243+ optional (firstName /= Nothing || middleName /= Nothing || lastName /= Nothing)
244+ (row
245+ (let
246+ x =
247+ [ firstName, middleName, lastName ] |> List.concatMap (flip maybeList identity) |> unwords
248+ in
249+ { name = "Name"
250+ , value = x
251+ , nameIcon = ""
252+ , icons = [ ( "copy", Copy x ) ]
253+ }
254+ )
255+ )
256+ ++ maybeList username
257+ (\x ->
258+ row
259+ { name = "Username"
260+ , value = x
261+ , nameIcon = ""
262+ , icons = [ ( "copy", Copy x ) ]
263+ }
264+ )
265+ ++ maybeList company
266+ (\x ->
267+ row
268+ { name = "Company"
269+ , value = x
270+ , nameIcon = ""
271+ , icons = [ ( "copy", Copy x ) ]
272+ }
273+ )
274+ ++ maybeList ssn
275+ (\x ->
276+ row
277+ { name = "Social security number"
278+ , value = x
279+ , nameIcon = ""
280+ , icons = [ ( "copy", Copy x ) ]
281+ }
282+ )
283+ ++ maybeList passportNumber
284+ (\x ->
285+ row
286+ { name = "Passport number"
287+ , value = x
288+ , nameIcon = ""
289+ , icons = [ ( "copy", Copy x ) ]
290+ }
291+ )
292+ ++ maybeList licenseNumber
293+ (\x ->
294+ row
295+ { name = "License Number"
296+ , value = x
297+ , nameIcon = ""
298+ , icons = [ ( "copy", Copy x ) ]
299+ }
300+ )
301+ ++ maybeList email
302+ (\x ->
303+ row
304+ { name = "Email"
305+ , value = x
306+ , nameIcon = ""
307+ , icons = [ ( "copy", Copy x ) ]
308+ }
309+ )
310+ ++ maybeList phone
311+ (\x ->
312+ row
313+ { name = "Phone number"
314+ , value = x
315+ , nameIcon = ""
316+ , icons = [ ( "copy", Copy x ) ]
317+ }
318+ )
319+ ++ optional (address1 /= Nothing || address2 /= Nothing || address3 /= Nothing)
320+ (row
321+ (let
322+ x =
323+ [ address1, address2, address3 ] |> List.concatMap (flip maybeList identity) |> unwords
324+ in
325+ { name = "Address"
326+ , value = x
327+ , nameIcon = ""
328+ , icons = [ ( "copy", Copy x ) ]
329+ }
330+ )
331+ )
332+ )
333+ |> List.intersperse (hr [] [])
334+
335+
336+hiddenPassword : String
337+hiddenPassword =
338+ String.repeat 12 "●"
339+
340+
341+hiddenCvv : String
342+hiddenCvv =
343+ String.repeat 3 "●"
344+
345+
346+iconButton : String -> msg -> Html msg
347+iconButton name msg =
348+ button [ Attr.class "p-button is-inline is-dense has-icon", Ev.onClick msg ]
349+ [ i [ Attr.class ("p-icon--" ++ name) ] [] ]
350+
351+
352+hiddenButtonIcon : Bool -> String
353+hiddenButtonIcon hidden =
354+ if hidden then
355+ "show"
356+
357+ else
358+ "hide"
frontend/Pages/Ciphers.elm+267−36
@@ -1,67 +1,298 @@
1−module Pages.Ciphers exposing (Callbacks, Model, Msg, page)
1+module Pages.Ciphers exposing
2+ ( Callbacks
3+ , Model
4+ , Msg
5+ , event
6+ , init
7+ , menuConfig
8+ , title
9+ , update
10+ , updateCiphers
11+ , view
12+ )
2
13
3import Bridge
14import Bridge
15+import GlobalEvents
4import Html exposing (..)
16import Html exposing (..)
5import Html.Attributes as Attr
17import Html.Attributes as Attr
6import Html.Events as Ev
18import Html.Events as Ev
19+import Html.Keyed as Keyed
20+import Html.Lazy as Lazy
21+import InfiniteScroll
7import Page exposing (..)
22import Page exposing (..)
23+import Pages.Navigation as Navigation
24+import Search
8import Utils exposing (..)
25import Utils exposing (..)
9
26
10
27
11−type alias Model =
28+type alias Model emsg =
12 { ciphers : Bridge.Sub_LoadCiphers_List
29 { ciphers : Bridge.Sub_LoadCiphers_List
30+ , search : String
31+ , menuVisible : Bool
32+ , ciphersListFilter : CiphersFilter
33+ , scroll : InfiniteScroll.Model Msg
34+ , sublist : { end : Int }
35+ , cipherSelectDropdownVisivble : Bool
36+ , callbacks : Callbacks emsg
37+ }
38+
39+
40+updateCiphers : Bridge.Sub_LoadCiphers_List -> Model emsg -> Model emsg
41+updateCiphers ciphers model =
42+ { model | ciphers = ciphers }
43+
44+
45+type CiphersFilter
46+ = AllCiphers
47+ | SpecificCiphers Bridge.CipherType
48+
49+
50+applyCipherFilter : CiphersFilter -> Bridge.Sub_LoadCiphers_List -> Bridge.Sub_LoadCiphers_List
51+applyCipherFilter filter list =
52+ case filter of
53+ AllCiphers ->
54+ list
55+
56+ SpecificCiphers t ->
57+ list |> List.filter (.cipherType >> (==) t)
58+
59+
60+menuConfig : String -> Model emsg -> Navigation.MenuConfig Msg
61+menuConfig email { ciphersListFilter, menuVisible } =
62+ { title = email
63+ , items =
64+ [ { icon = "units"
65+ , name = "All items"
66+ , trigger = UpdateFilter AllCiphers
67+ , current = ciphersListFilter == AllCiphers
68+ }
69+ , { icon = "security"
70+ , name = "Passwords"
71+ , trigger = UpdateFilter (SpecificCiphers Bridge.LoginType)
72+ , current = ciphersListFilter == SpecificCiphers Bridge.LoginType
73+ }
74+ , { icon = "edit"
75+ , name = "Notes"
76+ , trigger = UpdateFilter (SpecificCiphers Bridge.NoteType)
77+ , current = ciphersListFilter == SpecificCiphers Bridge.NoteType
78+ }
79+ , { icon = "containers"
80+ , name = "Cards"
81+ , trigger = UpdateFilter (SpecificCiphers Bridge.CardType)
82+ , current = ciphersListFilter == SpecificCiphers Bridge.CardType
83+ }
84+ , { icon = "user"
85+ , name = "Contacts"
86+ , trigger = UpdateFilter (SpecificCiphers Bridge.IdentityType)
87+ , current = ciphersListFilter == SpecificCiphers Bridge.IdentityType
88+ }
89+ ]
90+ , toggle = ToggleMenu
91+ , visible = menuVisible
92+ , logOut = LogOut
13 }
93 }
14
94
15
95
16type Msg
96type Msg
17 = Noop
97 = Noop
98+ | UpdateSearch String
99+ | ToggleMenu
100+ | UpdateFilter CiphersFilter
101+ | LogOut
102+ | LoadMore InfiniteScroll.Direction
103+ | InfiniteScrollMsg InfiniteScroll.Msg
104+ | CreateNewCipher Bridge.CipherType
105+ | ToggleSelectCipherTypeVisible
106+ | SelectCipher String
18
107
19
108
20−type alias Callbacks =
109+type alias Callbacks msg =
21− {}
110+ { selected : String -> msg
111+ , logOut : msg
112+ , createNewCipher : Bridge.CipherType -> msg
113+ , lift : Msg -> msg
114+ }
22
115
23
116
24−page : Callbacks -> Page Bridge.Sub_LoadCiphers_List Model Msg emsg
117+event : Model emsg -> GlobalEvents.Event -> Model emsg
25−page callbacks liftMsg =
118+event model ev =
26− { init = \ciphers -> Tuple.mapSecond (Cmd.map liftMsg) (init ciphers)
119+ case ev of
27− , view = \model -> view model |> List.map (Html.map liftMsg)
120+ GlobalEvents.UpdateCipher c ->
28− , update = \msg model -> update callbacks liftMsg msg model
121+ { model
29− , subscriptions = \model -> subscriptions model |> Sub.map liftMsg
122+ | ciphers =
30− , title = always "Passwords"
123+ model.ciphers
31− }
124+ |> List.map
125+ (\cipher ->
126+ if cipher.id == c.id then
127+ { cipher | name = c.name }
32
128
129+ else
130+ cipher
131+ )
132+ }
33
133
34−init : Bridge.Sub_LoadCiphers_List -> ( Model, Cmd Msg )
134+ _ ->
35−init ciphers =
135+ model
36− ( { ciphers = ciphers }
37− , Cmd.none
38− )
39
136
40
137
41−update : Callbacks -> (Msg -> emsg) -> Msg -> Model -> ( Result String Model, Cmd emsg )
138+title : Model emsg -> List (Html Msg)
42−update {} liftMsg msg model =
139+title { ciphersListFilter, cipherSelectDropdownVisivble } =
43− case msg of
140+ [ text
44− Noop ->
141+ (case ciphersListFilter of
45− ( Ok model, Cmd.none )
142+ AllCiphers ->
143+ "All items"
46
144
145+ SpecificCiphers cipherType ->
146+ case cipherType of
147+ Bridge.CardType ->
148+ "Cards"
47
149
48−subscriptions : Model -> Sub Msg
150+ Bridge.IdentityType ->
49−subscriptions model =
151+ "Contacts"
50− Sub.none
51
152
153+ Bridge.LoginType ->
154+ "Passwords"
52
155
53−view : Model -> List (Html Msg)
156+ Bridge.NoteType ->
54−view { ciphers } =
157+ "Notes"
55− [ ul [ Attr.class "p-list--divided" ]
158+ )
56− (List.map
159+ , span [ Attr.class "u-float-right" ]
57− (\{ name, date } ->
160+ [ span [ Attr.class "p-contextual-menu" ]
58− li [ Attr.class "p-list__item cipher-row" ]
161+ ([ span [] [ iconButton "plus" ToggleSelectCipherTypeVisible ]
59− [ div [ Attr.class "cipher-row-container" ]
162+ ]
60− [ p [] [ text name ]
163+ ++ optionals cipherSelectDropdownVisivble
61− , p [ Attr.class "p-text--small u-align-text--right u-text--muted" ] [ text date ]
164+ [ div
165+ [ Attr.class "overlay"
166+ , Ev.onClick ToggleSelectCipherTypeVisible
62 ]
167 ]
168+ []
169+ , span
170+ [ Attr.class "p-contextual-menu__dropdown"
171+ , Attr.attribute "aria-hidden" "false"
172+ ]
173+ (let
174+ create t =
175+ CreateNewCipher t
176+ in
177+ [ button
178+ [ Attr.class "p-contextual-menu__link"
179+ , Ev.onClick (create Bridge.LoginType)
180+ ]
181+ [ text "Login" ]
182+ , button
183+ [ Attr.class "p-contextual-menu__link"
184+ , Ev.onClick (create Bridge.CardType)
185+ ]
186+ [ text "Card" ]
187+ , button
188+ [ Attr.class "p-contextual-menu__link"
189+ , Ev.onClick (create Bridge.NoteType)
190+ ]
191+ [ text "Note" ]
192+ , button
193+ [ Attr.class "p-contextual-menu__link"
194+ , Ev.onClick (create Bridge.IdentityType)
195+ ]
196+ [ text "Contact" ]
197+ ]
198+ )
63 ]
199 ]
64 )
200 )
65− ciphers
201+ ]
66− )
202+ ]
203+
204+
205+init : Callbacks emsg -> Bridge.Sub_LoadCiphers_List -> Model emsg
206+init callbacks ciphers =
207+ { ciphers = ciphers
208+ , search = ""
209+ , menuVisible = False
210+ , ciphersListFilter = AllCiphers
211+ , scroll = InfiniteScroll.init (LoadMore >> pureCmd)
212+ , sublist = { end = 20 }
213+ , cipherSelectDropdownVisivble = False
214+ , callbacks = callbacks
215+ }
216+
217+
218+update : Msg -> Model emsg -> ( Model emsg, Cmd emsg )
219+update msg model =
220+ case msg of
221+ Noop ->
222+ ( model, Cmd.none )
223+
224+ UpdateSearch s ->
225+ ( { model | search = s }, Cmd.none )
226+
227+ ToggleMenu ->
228+ ( { model | menuVisible = not model.menuVisible }, Cmd.none )
229+
230+ UpdateFilter filter ->
231+ ( { model | ciphersListFilter = filter, menuVisible = False }, Cmd.none )
232+
233+ LogOut ->
234+ ( model, pureCmd model.callbacks.logOut )
235+
236+ LoadMore direction ->
237+ let
238+ newSublist =
239+ case direction of
240+ InfiniteScroll.Top ->
241+ { end = model.sublist.end }
242+
243+ InfiniteScroll.Bottom ->
244+ { end = min (model.sublist.end + 10) (List.length model.ciphers) }
245+ in
246+ ( { model | sublist = newSublist, scroll = InfiniteScroll.stopLoading model.scroll }, Cmd.none )
247+
248+ InfiniteScrollMsg msg_ ->
249+ let
250+ ( scroll, cmd ) =
251+ InfiniteScroll.update InfiniteScrollMsg msg_ model.scroll
252+ in
253+ ( { model | scroll = scroll }, Cmd.map model.callbacks.lift cmd )
254+
255+ CreateNewCipher t ->
256+ ( { model | cipherSelectDropdownVisivble = False }, pureCmd (model.callbacks.createNewCipher t) )
257+
258+ ToggleSelectCipherTypeVisible ->
259+ ( { model | cipherSelectDropdownVisivble = not model.cipherSelectDropdownVisivble }
260+ , Cmd.none
261+ )
262+
263+ SelectCipher id ->
264+ ( model, model.callbacks.selected id |> pureCmd )
265+
266+
267+view : Model emsg -> List (Html Msg)
268+view { ciphers, search, ciphersListFilter, sublist } =
269+ [ input
270+ [ Attr.type_ "search"
271+ , Attr.value search
272+ , Ev.onInput UpdateSearch
273+ , Attr.placeholder "Search"
274+ , Attr.attribute "autocomplete" "off"
275+ ]
276+ []
277+ , ciphers
278+ |> applyCipherFilter ciphersListFilter
279+ |> Search.searchList search .name (List.take sublist.end >> Lazy.lazy showCiphers)
67 ]
280 ]
281+
282+
283+showCiphers : Bridge.Sub_LoadCiphers_List -> Html Msg
284+showCiphers ciphers =
285+ Keyed.ul [ Attr.class "p-list--divided", InfiniteScroll.infiniteScroll InfiniteScrollMsg, Attr.class "ciphers-list no-scroll-bar" ]
286+ (ciphers
287+ |> List.map
288+ (\{ name, date, id } ->
289+ ( id
290+ , li [ Attr.class "p-list__item cipher-row", Ev.onClick (SelectCipher id) ]
291+ [ div [ Attr.class "cipher-row-container" ]
292+ [ p [] [ text name ]
293+ , p [ Attr.class "p-text--small u-align-text--right u-text--muted hide-in-test" ] [ text date ]
294+ ]
295+ ]
296+ )
297+ )
298+ )
frontend/Pages/EditCipher.elmnew file+475
@@ -0,0 +1,475 @@
1+module Pages.EditCipher exposing (Callbacks, Model, Msg, event, init, title, update, view)
2+
3+import Bridge
4+import GlobalEvents
5+import Html exposing (..)
6+import Html.Attributes as Attr
7+import Html.Events as Ev
8+import Logic.Cipher exposing (normalizeCipher)
9+import Modal exposing (modal)
10+import Page exposing (..)
11+import Pages.MasterPassword exposing (Msg)
12+import Pages.PasswordGenerator as PasswordGenerator
13+import Utils exposing (..)
14+
15+
16+type alias Model msg =
17+ { fullCipher : Bridge.FullCipher
18+ , passwordGenerator : Maybe PasswordGenerator.Model
19+ , callbacks : Callbacks msg
20+ }
21+
22+
23+type Msg
24+ = EditCipher Bridge.FullCipher
25+ | PasswordGeneratorMsg PasswordGenerator.Msg
26+ | OpenGeneratePasword
27+ | CloseGeneratePassword
28+ | GeneratePassword Bridge.PasswordGeneratorConfig
29+ | Delete
30+ | Save
31+
32+
33+type alias Callbacks msg =
34+ { save : Bridge.FullCipher -> msg
35+ , generatePassword : Bridge.PasswordGeneratorConfig -> msg
36+ , delete : Maybe (Bridge.FullCipher -> msg)
37+ }
38+
39+
40+title : Model msg -> List (Html Msg)
41+title { fullCipher } =
42+ [ text fullCipher.name
43+ , span [ Attr.class "u-float-right" ]
44+ [ iconButton "task-outstanding" Save
45+ ]
46+ ]
47+
48+
49+event : Model msg -> GlobalEvents.Event -> Model msg
50+event model ev =
51+ case ev of
52+ GlobalEvents.UpdateCipher c ->
53+ { model
54+ | fullCipher =
55+ if c.id == model.fullCipher.id then
56+ c
57+
58+ else
59+ model.fullCipher
60+ }
61+
62+ GlobalEvents.GeneratedPassword password ->
63+ let
64+ fullCipher =
65+ model.fullCipher
66+ in
67+ { model
68+ | passwordGenerator = Nothing
69+ , fullCipher =
70+ { fullCipher
71+ | cipher =
72+ case fullCipher.cipher of
73+ Bridge.LoginCipher c ->
74+ Bridge.LoginCipher
75+ { c | password = Just password }
76+
77+ c ->
78+ c
79+ }
80+ }
81+
82+ _ ->
83+ model
84+
85+
86+init : { fullCipher : Bridge.FullCipher, callbacks : Callbacks emsg } -> ( Model emsg, Cmd emsg )
87+init { fullCipher, callbacks } =
88+ ( { fullCipher = fullCipher
89+ , passwordGenerator = Nothing
90+ , callbacks = callbacks
91+ }
92+ , Cmd.none
93+ )
94+
95+
96+update : Msg -> Model emsg -> ( Model emsg, Cmd emsg )
97+update msg model =
98+ case msg of
99+ EditCipher fullCipher ->
100+ ( { model | fullCipher = fullCipher }, Cmd.none )
101+
102+ PasswordGeneratorMsg m ->
103+ ( { model | passwordGenerator = Maybe.map (PasswordGenerator.update m) model.passwordGenerator }
104+ , Cmd.none
105+ )
106+
107+ OpenGeneratePasword ->
108+ ( { model | passwordGenerator = Just PasswordGenerator.init }
109+ , Cmd.none
110+ )
111+
112+ CloseGeneratePassword ->
113+ ( { model | passwordGenerator = Nothing }, Cmd.none )
114+
115+ GeneratePassword cfg ->
116+ ( model, pureCmd (model.callbacks.generatePassword cfg) )
117+
118+ Delete ->
119+ ( model
120+ , Maybe.withDefault Cmd.none
121+ (Maybe.map (\f -> f model.fullCipher |> pureCmd) model.callbacks.delete)
122+ )
123+
124+ Save ->
125+ let
126+ { fullCipher } =
127+ model
128+ in
129+ ( model
130+ , model.callbacks.save { fullCipher | cipher = normalizeCipher fullCipher.cipher } |> pureCmd
131+ )
132+
133+
134+heading : String -> String -> Html msg
135+heading icons name =
136+ span [ Attr.class "u-text--muted" ] [ i [ Attr.class ("p-icon--" ++ icons) ] [], text (" " ++ name) ]
137+
138+
139+row : { name : String, nameIcon : String, attrs : List (Html.Attribute msg) } -> Html msg
140+row { name, nameIcon, attrs } =
141+ p []
142+ [ heading nameIcon name
143+ , br [] []
144+ , input attrs []
145+ ]
146+
147+
148+view : Model emsg -> List (Html Msg)
149+view { fullCipher, passwordGenerator, callbacks } =
150+ maybeList passwordGenerator
151+ (\x ->
152+ modal
153+ { title = "Password generator"
154+ , close = CloseGeneratePassword
155+ , footer =
156+ [ button
157+ [ Attr.class "p-button--positive u-no-margin"
158+ , Ev.onClick <| GeneratePassword x.passwordConfig
159+ ]
160+ [ text "Generate password" ]
161+ ]
162+ , body =
163+ PasswordGenerator.view x |> List.map (Html.map PasswordGeneratorMsg)
164+ }
165+ )
166+ ++ [ row
167+ { name = "Entry name"
168+ , nameIcon = ""
169+ , attrs =
170+ [ Attr.type_ "text"
171+ , Attr.value fullCipher.name
172+ , Ev.onInput (\x -> { fullCipher | name = x } |> EditCipher)
173+ , Attr.attribute "autocomplete" "off"
174+ ]
175+ }
176+ ]
177+ ++ (case fullCipher.cipher of
178+ Bridge.LoginCipher cipher ->
179+ let
180+ { username, password, uris, totp } =
181+ cipher
182+
183+ edit c =
184+ { fullCipher | cipher = Bridge.LoginCipher c } |> EditCipher
185+ in
186+ [ row
187+ { name = "Username"
188+ , nameIcon = "user"
189+ , attrs =
190+ [ Attr.type_ "text"
191+ , Attr.value (Maybe.withDefault "" username)
192+ , Ev.onInput (\x -> edit { cipher | username = Just x })
193+ , Attr.attribute "autocomplete" "username"
194+ ]
195+ }
196+ , p []
197+ [ heading "security" "Password"
198+ , br [] []
199+ , input
200+ [ Attr.type_ "text"
201+ , Attr.value (Maybe.withDefault "" password)
202+ , Ev.onInput (\x -> edit { cipher | password = Just x })
203+ , Attr.attribute "autocomplete" "new-password"
204+ , Attr.style "width" "calc(100% - 3.5rem)"
205+ ]
206+ []
207+ , iconButton "restart" OpenGeneratePasword
208+ ]
209+ , row
210+ { name = "One-time password"
211+ , nameIcon = "revisions"
212+ , attrs =
213+ [ Attr.type_ "text"
214+ , Attr.value (Maybe.withDefault "" totp)
215+ , Ev.onInput (\x -> edit { cipher | totp = Just x })
216+ , Attr.attribute "autocomplete" "off"
217+ ]
218+ }
219+ ]
220+ ++ (uris
221+ |> List.indexedMap
222+ (\i uri ->
223+ row
224+ { name = "URL"
225+ , nameIcon = "get-link"
226+ , attrs =
227+ [ Attr.type_ "url"
228+ , Attr.value uri
229+ , Ev.onInput (\x -> edit { cipher | uris = replace i x uris })
230+ ]
231+ }
232+ )
233+ )
234+ ++ [ row
235+ { name = "URL"
236+ , nameIcon = "get-link"
237+ , attrs =
238+ [ Attr.type_ "url"
239+ , Ev.onInput (\x -> edit { cipher | uris = uris ++ [ x ] })
240+ ]
241+ }
242+ ]
243+
244+ Bridge.NoteCipher contents ->
245+ [ p []
246+ [ heading "switcher-environments" "Note"
247+ , br [] []
248+ , textarea
249+ [ Attr.spellcheck True
250+ , Attr.style "height" "65vh"
251+ , Attr.value contents
252+ , Ev.onInput (\x -> EditCipher { fullCipher | cipher = Bridge.NoteCipher x })
253+ ]
254+ []
255+ ]
256+ ]
257+
258+ Bridge.CardCipher cipher ->
259+ let
260+ { number, code, cardholderName, expMonth, expYear } =
261+ cipher
262+
263+ edit c =
264+ { fullCipher | cipher = Bridge.CardCipher c } |> EditCipher
265+ in
266+ [ row
267+ { name = "Card number"
268+ , nameIcon = "containers"
269+ , attrs =
270+ [ Attr.attribute "autocomplete" "cc-number"
271+ , Attr.type_ "text"
272+ , Attr.value (Maybe.withDefault "" number)
273+ , Ev.onInput (\x -> edit { cipher | number = Just x })
274+ ]
275+ }
276+ , p []
277+ [ heading "timed-out" "Expiration date"
278+ , br [] []
279+ , input
280+ [ Attr.attribute "autocomplete" "cc-exp-month"
281+ , Attr.type_ "text"
282+ , Attr.value (Maybe.withDefault "" expMonth)
283+ , Ev.onInput (\x -> edit { cipher | expMonth = Just x })
284+ , Attr.style "width" "30%"
285+ , Attr.style "min-width" "initial"
286+ , Attr.class "u-align--right"
287+ ]
288+ []
289+ , text " / "
290+ , input
291+ [ Attr.attribute "autocomplete" "cc-exp-year"
292+ , Attr.type_ "text"
293+ , Attr.value (Maybe.withDefault "" expYear)
294+ , Ev.onInput (\x -> edit { cipher | expYear = Just x })
295+ , Attr.style "width" "30%"
296+ , Attr.style "min-width" "initial"
297+ ]
298+ []
299+ ]
300+ , row
301+ { name = "CVV"
302+ , nameIcon = "security"
303+ , attrs =
304+ [ Attr.attribute "autocomplete" "cc-csc"
305+ , Attr.type_ "text"
306+ , Attr.value (Maybe.withDefault "" code)
307+ , Ev.onInput (\x -> edit { cipher | code = Just x })
308+ ]
309+ }
310+ , row
311+ { name = "Cardholder name"
312+ , nameIcon = "user"
313+ , attrs =
314+ [ Attr.attribute "autocomplete" "cc-name"
315+ , Attr.type_ "text"
316+ , Attr.value (Maybe.withDefault "" cardholderName)
317+ , Ev.onInput (\x -> edit { cipher | cardholderName = Just x })
318+ ]
319+ }
320+ ]
321+
322+ Bridge.IdentityCipher cipher ->
323+ let
324+ { address1, address2, address3, company, email, firstName, lastName, licenseNumber, middleName, passportNumber, phone, ssn, username } =
325+ cipher
326+
327+ edit c =
328+ { fullCipher | cipher = Bridge.IdentityCipher c } |> EditCipher
329+ in
330+ [ row
331+ { name = "First name"
332+ , nameIcon = ""
333+ , attrs =
334+ [ Attr.attribute "autocomplete" "given-name"
335+ , Attr.type_ "text"
336+ , Attr.value (Maybe.withDefault "" firstName)
337+ , Ev.onInput (\x -> edit { cipher | firstName = Just x })
338+ ]
339+ }
340+ , row
341+ { name = "Middle name"
342+ , nameIcon = ""
343+ , attrs =
344+ [ Attr.attribute "autocomplete" "additional-name"
345+ , Attr.type_ "text"
346+ , Attr.value (Maybe.withDefault "" middleName)
347+ , Ev.onInput (\x -> edit { cipher | middleName = Just x })
348+ ]
349+ }
350+ , row
351+ { name = "Last name"
352+ , nameIcon = ""
353+ , attrs =
354+ [ Attr.attribute "autocomplete" "family-name"
355+ , Attr.type_ "text"
356+ , Attr.value (Maybe.withDefault "" lastName)
357+ , Ev.onInput (\x -> edit { cipher | lastName = Just x })
358+ ]
359+ }
360+ , row
361+ { name = "Username"
362+ , nameIcon = ""
363+ , attrs =
364+ [ Attr.attribute "autocomplete" "username"
365+ , Attr.type_ "text"
366+ , Attr.value (Maybe.withDefault "" username)
367+ , Ev.onInput (\x -> edit { cipher | username = Just x })
368+ ]
369+ }
370+ , row
371+ { name = "Company"
372+ , nameIcon = ""
373+ , attrs =
374+ [ Attr.attribute "autocomplete" "organization"
375+ , Attr.type_ "text"
376+ , Attr.value (Maybe.withDefault "" company)
377+ , Ev.onInput (\x -> edit { cipher | company = Just x })
378+ ]
379+ }
380+ , row
381+ { name = "Social security number"
382+ , nameIcon = ""
383+ , attrs =
384+ [ Attr.attribute "autocomplete" "off"
385+ , Attr.type_ "number"
386+ , Attr.value (Maybe.withDefault "" ssn)
387+ , Ev.onInput (\x -> edit { cipher | ssn = Just x })
388+ ]
389+ }
390+ , row
391+ { name = "Passport number"
392+ , nameIcon = ""
393+ , attrs =
394+ [ Attr.attribute "autocomplete" "off"
395+ , Attr.type_ "number"
396+ , Attr.value (Maybe.withDefault "" passportNumber)
397+ , Ev.onInput (\x -> edit { cipher | passportNumber = Just x })
398+ ]
399+ }
400+ , row
401+ { name = "License Number"
402+ , nameIcon = ""
403+ , attrs =
404+ [ Attr.attribute "autocomplete" "off"
405+ , Attr.type_ "number"
406+ , Attr.value (Maybe.withDefault "" licenseNumber)
407+ , Ev.onInput (\x -> edit { cipher | licenseNumber = Just x })
408+ ]
409+ }
410+ , row
411+ { name = "Email"
412+ , nameIcon = ""
413+ , attrs =
414+ [ Attr.attribute "autocomplete" "email"
415+ , Attr.type_ "email"
416+ , Attr.value (Maybe.withDefault "" email)
417+ , Ev.onInput (\x -> edit { cipher | email = Just x })
418+ ]
419+ }
420+ , row
421+ { name = "Phone number"
422+ , nameIcon = ""
423+ , attrs =
424+ [ Attr.attribute "autocomplete" "tel"
425+ , Attr.type_ "tel"
426+ , Attr.value (Maybe.withDefault "" phone)
427+ , Ev.onInput (\x -> edit { cipher | phone = Just x })
428+ ]
429+ }
430+ , row
431+ { name = "Address line 1"
432+ , nameIcon = ""
433+ , attrs =
434+ [ Attr.attribute "autocomplete" "address-line1"
435+ , Attr.type_ "text"
436+ , Attr.value (Maybe.withDefault "" address1)
437+ , Ev.onInput (\x -> edit { cipher | address1 = Just x })
438+ ]
439+ }
440+ , row
441+ { name = "Address line 2"
442+ , nameIcon = ""
443+ , attrs =
444+ [ Attr.attribute "autocomplete" "address-line2"
445+ , Attr.type_ "text"
446+ , Attr.value (Maybe.withDefault "" address2)
447+ , Ev.onInput (\x -> edit { cipher | address2 = Just x })
448+ ]
449+ }
450+ , row
451+ { name = "Address line 3"
452+ , nameIcon = ""
453+ , attrs =
454+ [ Attr.attribute "autocomplete" "address-line3"
455+ , Attr.type_ "text"
456+ , Attr.value (Maybe.withDefault "" address3)
457+ , Ev.onInput (\x -> edit { cipher | address3 = Just x })
458+ ]
459+ }
460+ ]
461+ )
462+ ++ optional (callbacks.delete /= Nothing)
463+ (button
464+ [ Attr.style "width" "100%"
465+ , Attr.class "p-button--negative"
466+ , Ev.onClick Delete
467+ ]
468+ [ text "Delete" ]
469+ )
470+
471+
472+iconButton : String -> msg -> Html msg
473+iconButton name msg =
474+ button [ Attr.class "p-button is-inline is-dense has-icon", Ev.onClick msg ]
475+ [ i [ Attr.class ("p-icon--" ++ name) ] [] ]
frontend/Pages/Login.elm+56−37
@@ -1,4 +1,4 @@
1−module Pages.Login exposing (Callbacks, Model, Msg, page)
1+module Pages.Login exposing (Callbacks, Model, Msg, init, title, update, view)
2
2
3import Html exposing (..)
3import Html exposing (..)
4import Html.Attributes as Attr
4import Html.Attributes as Attr
@@ -7,10 +7,11 @@ import Page exposing (..)
7import Utils exposing (..)
7import Utils exposing (..)
8
8
9
9
10−type alias Model =
10+type alias Model emsg =
11 { server : String
11 { server : String
12 , email : String
12 , email : String
13 , password : String
13 , password : String
14+ , callbacks : Callbacks emsg
14 }
15 }
15
16
16
17
@@ -26,56 +27,74 @@ type alias Callbacks emsg =
26 }
27 }
27
28
28
29
29−page : Callbacks emsg -> Page () Model Msg emsg
30+title : String
30−page callbacks liftMsg =
31+title =
31− { init = \() -> Tuple.mapSecond (Cmd.map liftMsg) init
32+ "Log into bitwarden"
32− , view = \model -> view model |> List.map (Html.map liftMsg)
33− , update = \msg model -> update callbacks liftMsg msg model
34− , subscriptions = \model -> subscriptions model |> Sub.map liftMsg
35− , title = always "Log into bitwarden"
36− }
37
33
38
34
39−init : ( Model, Cmd Msg )
35+init : Callbacks emsg -> Model emsg
40−init =
36+init callbacks =
41− ( { server = "https://bitwarden.iko.soy"
37+ { server = "https://vault.bitwarden.com"
42− , email = "mail@iko.soy"
38+ , email = ""
43− , password = ""
39+ , password = ""
44− }
40+ , callbacks = callbacks
45− , Cmd.none
41+ }
46− )
47
42
48
43
49−update : Callbacks emsg -> (Msg -> emsg) -> Msg -> Model -> ( Result String Model, Cmd emsg )
44+update : Msg -> Model emsg -> ( Model emsg, Cmd emsg )
50−update { submit } liftMsg msg model =
45+update msg model =
51 case msg of
46 case msg of
52 UpdateEmail email ->
47 UpdateEmail email ->
53− ( Ok { model | email = email }, Cmd.none )
48+ ( { model | email = email }, Cmd.none )
54
49
55 UpdateServer server ->
50 UpdateServer server ->
56− ( Ok { model | server = server }, Cmd.none )
51+ ( { model | server = server }, Cmd.none )
57
52
58 UpdatePassword password ->
53 UpdatePassword password ->
59− ( Ok { model | password = password }, Cmd.none )
54+ ( { model | password = password }, Cmd.none )
60
55
61 Submit ->
56 Submit ->
62− ( Ok model, pureCmd (submit model) )
57+ ( model
63−
58+ , pureCmd
64−
59+ (model.callbacks.submit
65−subscriptions : Model -> Sub Msg
60+ { email = model.email
66−subscriptions model =
61+ , password = model.password
67− Sub.none
62+ , server = model.server
68−
63+ }
69−
64+ )
70−view : Model -> List (Html Msg)
65+ )
66+
67+
68+view : Model emsg -> List (Html Msg)
71view model =
69view model =
72− [ form []
70+ [ form [ Ev.onSubmit Submit ]
73 [ label [] [ text "Server" ]
71 [ label [] [ text "Server" ]
74− , input [ Attr.type_ "url", Attr.value model.server, Ev.onInput UpdateServer ] []
72+ , input
73+ [ Attr.type_ "url"
74+ , Attr.value model.server
75+ , Ev.onInput UpdateServer
76+ , Attr.attribute "autocomplete" "url"
77+ , Attr.required True
78+ ]
79+ []
75 , label [] [ text "Email" ]
80 , label [] [ text "Email" ]
76− , input [ Attr.type_ "email", Attr.value model.email, Ev.onInput UpdateEmail ] []
81+ , input
82+ [ Attr.type_ "email"
83+ , Attr.value model.email
84+ , Ev.onInput UpdateEmail
85+ , Attr.attribute "autocomplete" "email"
86+ , Attr.required True
87+ ]
88+ []
77 , label [] [ text "Password" ]
89 , label [] [ text "Password" ]
78− , input [ Attr.type_ "password", Attr.value model.password, Ev.onInput UpdatePassword ] []
90+ , input
91+ [ Attr.type_ "password"
92+ , Attr.value model.password
93+ , Ev.onInput UpdatePassword
94+ , Attr.attribute "autocomplete" "current-password"
95+ , Attr.required True
96+ ]
97+ []
98+ , alignRight [ button [ Attr.type_ "submit" ] [ text "Log in" ] ]
79 ]
99 ]
80− , alignRight [ button [ Ev.onClick Submit ] [ text "Log in" ] ]
81 ]
100 ]
frontend/Pages/MasterPassword.elmnew file+82
@@ -0,0 +1,82 @@
1+module Pages.MasterPassword exposing (Callbacks, Model, Msg, init, title, update, view)
2+
3+import Html exposing (..)
4+import Html.Attributes as Attr
5+import Html.Events as Ev
6+import Page exposing (..)
7+import Utils exposing (..)
8+
9+
10+type alias Model emsg =
11+ { server : String
12+ , email : String
13+ , password : String
14+ , callbacks : Callbacks emsg
15+ }
16+
17+
18+type Msg
19+ = UpdatePassword String
20+ | Submit
21+ | Reset
22+
23+
24+type alias Callbacks emsg =
25+ { submit : { password : String } -> emsg
26+ , reset : emsg
27+ }
28+
29+
30+title : String
31+title =
32+ "Enter master password"
33+
34+
35+init : Callbacks emsg -> { server : String, login : String } -> Model emsg
36+init callbacks { server, login } =
37+ { server = server
38+ , email = login
39+ , password = ""
40+ , callbacks = callbacks
41+ }
42+
43+
44+update : Msg -> Model emsg -> ( Model emsg, Cmd emsg )
45+update msg model =
46+ case msg of
47+ UpdatePassword password ->
48+ ( { model | password = password }, Cmd.none )
49+
50+ Submit ->
51+ ( model, pureCmd (model.callbacks.submit { password = model.password }) )
52+
53+ Reset ->
54+ ( model, pureCmd model.callbacks.reset )
55+
56+
57+view : Model emsg -> List (Html Msg)
58+view model =
59+ [ alignRight [ button [ Attr.class "p-button--negative", Ev.onClick Reset ] [ text "Log out" ] ]
60+ , table [ Attr.class "p-table--mobile-card u-no-margin" ]
61+ [ thead [] [ tr [] [ th [] [ text "Server" ], th [] [ text "Email" ] ] ]
62+ , tbody
63+ []
64+ [ tr []
65+ [ td [ Attr.attribute "data-heading" "Server" ] [ text model.server ]
66+ , td [ Attr.attribute "data-heading" "Email" ] [ text model.email ]
67+ ]
68+ ]
69+ ]
70+ , form [ Ev.onSubmit Submit ]
71+ [ label [] [ text "Password" ]
72+ , input
73+ [ Attr.type_ "password"
74+ , Attr.value model.password
75+ , Ev.onInput UpdatePassword
76+ , Attr.attribute "autocomplete" "new-password"
77+ , Attr.required True
78+ ]
79+ []
80+ , alignRight [ button [ Attr.type_ "submit" ] [ text "Log in" ] ]
81+ ]
82+ ]
frontend/Pages/Navigation.elm+141−23
@@ -1,51 +1,127 @@
1−module Pages.Navigation exposing (Config, navigation)
1+module Pages.Navigation exposing
2+ ( Config
3+ , MenuConfig
4+ , PageStack
5+ , TopButton(..)
6+ , mapMenuConfig
7+ , popView
8+ , pushView
9+ , showNavigationView
10+ )
2
11
3import Html exposing (..)
12import Html exposing (..)
4import Html.Attributes as Attr
13import Html.Attributes as Attr
14+import Html.Events as Ev
15+import Html.Lazy as Lazy
16+import List.Nonempty as Nonempty exposing (Nonempty)
5import Utils exposing (..)
17import Utils exposing (..)
6
18
7
19
8−type alias Config =
20+type TopButton msg
9− { back : Bool
21+ = BackButton { action : msg, icon : Maybe String }
10− , title : String
22+ | MenuButton (MenuConfig msg)
23+
24+
25+type alias Config msg =
26+ { topButton : Maybe (TopButton msg)
27+ , title : List (Html msg)
11 }
28 }
12
29
13
30
14−navigation : Config -> Html msg
31+navigation : Config msg -> Html msg
15−navigation { back, title } =
32+navigation { topButton, title } =
16− nav [ Attr.class "p-tabs p-tabs__list" ]
33+ div []
17− [ h3 [ Attr.class "u-no-margin u-no-padding" ]
34+ ((case topButton of
18− [ button
35+ Just (MenuButton cfg) ->
19− (Attr.class "p-button--base is-inline u-no-margin" :: optional (not back) (Attr.style "visibility" "hidden"))
36+ [ Lazy.lazy menu cfg ]
20− [ i [ Attr.class "p-icon--chevron-up ninety-counter" ] []
37+
21− ]
38+ _ ->
22− , text title
39+ []
23− ]
40+ )
24− ]
41+ ++ [ nav [ Attr.class "p-tabs p-tabs__list no-scroll-bar" ]
42+ [ h3 []
43+ ([ case topButton of
44+ Nothing ->
45+ button
46+ [ Attr.class "p-button--base is-inline u-no-margin", Attr.style "visibility" "hidden" ]
47+ []
48+
49+ Just (BackButton { action, icon }) ->
50+ button
51+ [ Attr.class "p-button--base is-inline u-no-margin", Ev.onClick action ]
52+ [ case icon of
53+ Nothing ->
54+ i [ Attr.class "p-icon--chevron-up ninety-counter" ] []
55+
56+ Just iconName ->
57+ i [ Attr.class ("p-icon--" ++ iconName) ] []
58+ ]
59+
60+ Just (MenuButton cfg) ->
61+ button
62+ [ Attr.class "p-button--base is-inline u-no-margin", Ev.onClick cfg.toggle ]
63+ [ i [ Attr.class "p-icon--menu" ] [] ]
64+ ]
65+ ++ title
66+ )
67+ ]
68+ ]
69+ )
25
70
26
71
27type alias MenuConfig msg =
72type alias MenuConfig msg =
28 { title : String
73 { title : String
29− , items : List { icon : String, name : String, trigger : msg }
74+ , items : List { icon : String, name : String, trigger : msg, current : Bool }
30− , close : msg
75+ , toggle : msg
76+ , visible : Bool
77+ , logOut : msg
78+ }
79+
80+
81+mapMenuConfig : (a -> b) -> MenuConfig a -> MenuConfig b
82+mapMenuConfig f { title, items, toggle, visible, logOut } =
83+ { items =
84+ List.map
85+ (\{ icon, name, trigger, current } ->
86+ { icon = icon, name = name, trigger = f trigger, current = current }
87+ )
88+ items
89+ , title = title
90+ , toggle = f toggle
91+ , visible = visible
92+ , logOut = f logOut
31 }
93 }
32
94
33
95
34menu : MenuConfig msg -> Html msg
96menu : MenuConfig msg -> Html msg
35−menu { title, items, close } =
97+menu { title, items, toggle, visible, logOut } =
36− div [ Attr.class "p-side-navigation--icons is-drawer-expanded" ]
98+ div [ Attr.class "p-side-navigation--icons", Attr.classList [ ( "is-drawer-expanded", visible ) ] ]
37 [ div [ Attr.class "p-side-navigation__overlay" ] []
99 [ div [ Attr.class "p-side-navigation__overlay" ] []
38 , nav [ Attr.class "p-side-navigation__drawer" ]
100 , nav [ Attr.class "p-side-navigation__drawer" ]
39 [ div [ Attr.class "p-side-navigation__drawer-header" ]
101 [ div [ Attr.class "p-side-navigation__drawer-header" ]
40− [ a [ Attr.class "p-side-navigation__toggle--in-drawer" ] [ text title ]
102+ [ a [ Attr.class "p-side-navigation__toggle--in-drawer", Ev.onClick toggle ] [ text title ]
103+ , button
104+ [ Attr.class "p-button--negative is-inline u-float-right"
105+ , Attr.style "margin-right" "1rem"
106+ , Ev.onClick logOut
107+ ]
108+ [ text "Log out" ]
41 ]
109 ]
42 , ul [ Attr.class "p-side-navigation__list" ]
110 , ul [ Attr.class "p-side-navigation__list" ]
43 (items
111 (items
44 |> List.map
112 |> List.map
45− (\{ icon, name, trigger } ->
113+ (\{ icon, name, trigger, current } ->
46 li [ Attr.class "p-side-navigation__item" ]
114 li [ Attr.class "p-side-navigation__item" ]
47− [ a [ Attr.class "p-side-navigation__link" ]
115+ [ a
48− [ i [ Attr.class "p-side-navigation__icon", Attr.class ("p-icon--" ++ icon) ] []
116+ [ Attr.class "p-side-navigation__link"
117+ , Attr.classList [ ( "is-active", current ) ]
118+ , Ev.onClick trigger
119+ ]
120+ [ i
121+ [ Attr.class "p-side-navigation__icon"
122+ , Attr.class ("p-icon--" ++ icon)
123+ ]
124+ []
49 , text name
125 , text name
50 ]
126 ]
51 ]
127 ]
@@ -53,3 +129,45 @@ menu { title, items, close } =
53 )
129 )
54 ]
130 ]
55 ]
131 ]
132+
133+
134+type alias PageStack model =
135+ Nonempty model
136+
137+
138+pushView : model -> PageStack model -> PageStack model
139+pushView model stack =
140+ Nonempty.cons model stack
141+
142+
143+popView : PageStack model -> PageStack model
144+popView stack =
145+ stack
146+ |> Nonempty.tail
147+ |> Nonempty.fromList
148+ |> Maybe.withDefault stack
149+
150+
151+showNavigationView :
152+ PageStack model
153+ ->
154+ (model
155+ ->
156+ { title : List (Html msg)
157+ , body : List (Html msg)
158+ , topButton : Maybe (TopButton msg)
159+ }
160+ )
161+ -> Html msg
162+showNavigationView stack render =
163+ let
164+ { title, body, topButton } =
165+ render (Nonempty.head stack)
166+ in
167+ div []
168+ [ Lazy.lazy navigation
169+ { topButton = topButton
170+ , title = title
171+ }
172+ , main_ [] body
173+ ]
frontend/Pages/PasswordGenerator.elmnew file+158
@@ -0,0 +1,158 @@
1+module Pages.PasswordGenerator exposing (Model, Msg, init, update, view)
2+
3+import Bridge
4+import Html exposing (..)
5+import Html.Attributes as Attr
6+import Html.Events as Ev
7+import Switch exposing (switch)
8+
9+
10+type Msg
11+ = Noop
12+ | UpdateNumberCount Int
13+ | ToggleNumber Bool
14+ | ToggleAmbiguousCharacters Bool
15+ | ToggleCapitals Bool
16+ | UpdateNumberOfCapitals Int
17+ | UpdateLength Int
18+ | ToggleSpecialCharacters Bool
19+ | UpdateSpecialCharactersCount Int
20+
21+
22+type alias Model =
23+ { passwordConfig : Bridge.PasswordGeneratorConfig
24+ }
25+
26+
27+update : Msg -> Model -> Model
28+update msg { passwordConfig } =
29+ case msg of
30+ Noop ->
31+ { passwordConfig = passwordConfig }
32+
33+ UpdateNumberCount count ->
34+ { passwordConfig = { passwordConfig | minNumber = count } }
35+
36+ ToggleNumber enabled ->
37+ { passwordConfig = { passwordConfig | includeNumber = enabled } }
38+
39+ ToggleAmbiguousCharacters enabled ->
40+ { passwordConfig = { passwordConfig | ambiguous = enabled } }
41+
42+ ToggleCapitals enabled ->
43+ { passwordConfig = { passwordConfig | capitalize = enabled } }
44+
45+ UpdateNumberOfCapitals count ->
46+ { passwordConfig = { passwordConfig | minUppercase = count } }
47+
48+ UpdateLength count ->
49+ { passwordConfig = { passwordConfig | length = count } }
50+
51+ ToggleSpecialCharacters enabled ->
52+ { passwordConfig = { passwordConfig | special = enabled } }
53+
54+ UpdateSpecialCharactersCount count ->
55+ { passwordConfig = { passwordConfig | minSpecial = count } }
56+
57+
58+init : Model
59+init =
60+ { passwordConfig =
61+ { ambiguous = True
62+ , capitalize = True
63+ , includeNumber = True
64+ , length = 16
65+ , lowercase = True
66+ , minLowercase = 1
67+ , minNumber = 1
68+ , minSpecial = 1
69+ , minUppercase = 1
70+ , numWords = 1
71+ , number = True
72+ , special = True
73+ , type_ = "password"
74+ , uppercase = True
75+ , wordSeparator = "-"
76+ }
77+ }
78+
79+
80+view : Model -> List (Html Msg)
81+view { passwordConfig } =
82+ [ passwordGeneratorGroup
83+ [ switch
84+ { trigger = always Noop
85+ , label = "Length"
86+ , value = True
87+ , hidden = True
88+ }
89+ , input
90+ [ Attr.type_ "number"
91+ , Attr.class "is-dense"
92+ , Attr.value (String.fromInt passwordConfig.length)
93+ , Ev.onInput (String.toInt >> Maybe.withDefault 1 >> UpdateLength)
94+ , Attr.min "6"
95+ ]
96+ []
97+ ]
98+ , switchRow
99+ { label = "Numbers"
100+ , enabled = passwordConfig.includeNumber
101+ , toggle = ToggleNumber
102+ , trigger = UpdateNumberCount
103+ , value = passwordConfig.minNumber
104+ }
105+ , switchRow
106+ { label = "Uppercase Characters"
107+ , enabled = passwordConfig.capitalize
108+ , toggle = ToggleCapitals
109+ , trigger = UpdateNumberOfCapitals
110+ , value = passwordConfig.minUppercase
111+ }
112+ , switchRow
113+ { label = "Special Characters"
114+ , enabled = passwordConfig.special
115+ , toggle = ToggleSpecialCharacters
116+ , trigger = UpdateSpecialCharactersCount
117+ , value = passwordConfig.minSpecial
118+ }
119+ , switch
120+ { trigger = ToggleAmbiguousCharacters
121+ , label = "Ambiguous Characters"
122+ , value = passwordConfig.ambiguous
123+ , hidden = False
124+ }
125+ ]
126+
127+
128+switchRow :
129+ { toggle : Bool -> Msg
130+ , label : String
131+ , enabled : Bool
132+ , value : Int
133+ , trigger : Int -> Msg
134+ }
135+ -> Html Msg
136+switchRow { toggle, label, enabled, value, trigger } =
137+ passwordGeneratorGroup
138+ [ switch
139+ { trigger = toggle
140+ , label = label
141+ , value = enabled
142+ , hidden = False
143+ }
144+ , input
145+ [ Attr.type_ "number"
146+ , Attr.class "is-dense"
147+ , Attr.value (String.fromInt value)
148+ , Ev.onInput (String.toInt >> Maybe.withDefault 1 >> trigger)
149+ , Attr.min "1"
150+ , Attr.disabled (not enabled)
151+ ]
152+ []
153+ ]
154+
155+
156+passwordGeneratorGroup : List (Html msg) -> Html msg
157+passwordGeneratorGroup =
158+ div [ Attr.class "password-generator-group" ]
frontend/Pages/SecondFactor.elmnew file+91
@@ -0,0 +1,91 @@
1+module Pages.SecondFactor exposing
2+ ( Callbacks
3+ , Model
4+ , Msg
5+ , init
6+ , title
7+ , update
8+ , view
9+ )
10+
11+import Bridge
12+import Html exposing (..)
13+import Html.Attributes as Attr
14+import Html.Events as Ev
15+import Logic.SecondFactor exposing (secondFactorName)
16+import Utils exposing (..)
17+
18+
19+type alias Callbacks msg =
20+ { submit : { token : String, remember : Bool } -> msg
21+ }
22+
23+
24+type Msg
25+ = Submit
26+ | UpdateValue String
27+ | UpdateRemember Bool
28+
29+
30+type alias Model msg =
31+ { token : String
32+ , remember : Bool
33+ , factorType : Bridge.TwoFactorProviderType
34+ , callbacks : Callbacks msg
35+ }
36+
37+
38+init :
39+ { provider : Bridge.TwoFactorProviderType
40+ , callbacks : Callbacks msg
41+ }
42+ -> Model msg
43+init { provider, callbacks } =
44+ { token = ""
45+ , remember = True
46+ , factorType = provider
47+ , callbacks = callbacks
48+ }
49+
50+
51+title : Model msg -> String
52+title { factorType } =
53+ secondFactorName factorType
54+
55+
56+update : Model emsg -> Msg -> ( Model emsg, Maybe emsg )
57+update model msg =
58+ case msg of
59+ Submit ->
60+ ( model, model.callbacks.submit { token = model.token, remember = model.remember } |> Just )
61+
62+ UpdateValue token ->
63+ ( { model | token = token }, Nothing )
64+
65+ UpdateRemember remember ->
66+ ( { model | remember = remember }, Nothing )
67+
68+
69+view : Model emsg -> Html Msg
70+view { factorType, token, remember } =
71+ form [ Ev.onSubmit Submit ]
72+ [ label [] [ secondFactorName factorType ++ " code" |> text ]
73+ , input
74+ [ Attr.type_ "number"
75+ , Attr.value token
76+ , Attr.required True
77+ , Ev.onInput UpdateValue
78+ , Attr.attribute "autocomplete" "one-time-code"
79+ ]
80+ []
81+ , label []
82+ [ input
83+ [ Attr.type_ "checkbox"
84+ , Attr.checked remember
85+ , Ev.onCheck UpdateRemember
86+ ]
87+ []
88+ , text "Remember this device"
89+ ]
90+ , alignRight [ button [ Attr.type_ "submit" ] [ text "Submit" ] ]
91+ ]
frontend/Pages/SecondFactorSelect.elmnew file+164
@@ -0,0 +1,164 @@
1+module Pages.SecondFactorSelect exposing
2+ ( Callbacks
3+ , Model
4+ , Msg
5+ , init
6+ , main
7+ , title
8+ , update
9+ , view
10+ )
11+
12+import Bridge
13+import Element as El
14+import Element.Font as Font
15+import Element.Input as Input
16+import Html
17+import Html.Attributes as Attr
18+import Logic.SecondFactor exposing (secondFactorName)
19+import Page exposing (..)
20+import Utils exposing (..)
21+
22+
23+main : Program () (Model (Maybe Msg)) (Maybe Msg)
24+main =
25+ Page.page
26+ { init =
27+ init { selectFactor = always Nothing }
28+ [ Bridge.Duo
29+ , Bridge.Email
30+ ]
31+ , view = view
32+ , update = update
33+ }
34+
35+
36+type alias Model emsg =
37+ { availableFactors : List Bridge.TwoFactorProviderType
38+ , callbacks : Callbacks emsg
39+ }
40+
41+
42+type Msg
43+ = SelectFactor Bridge.TwoFactorProviderType
44+
45+
46+type alias Callbacks emsg =
47+ { selectFactor : Bridge.TwoFactorProviderType -> emsg
48+ }
49+
50+
51+title : String
52+title =
53+ "Second factor"
54+
55+
56+init : Callbacks emsg -> List Bridge.TwoFactorProviderType -> Model emsg
57+init callbacks providers =
58+ { availableFactors = providers
59+ , callbacks = callbacks
60+ }
61+
62+
63+update : Msg -> Model emsg -> ( Model emsg, Cmd emsg )
64+update msg model =
65+ case msg of
66+ SelectFactor factor ->
67+ ( model, model.callbacks.selectFactor factor |> pureCmd )
68+
69+
70+view : Model emsg -> List (Html.Html Msg)
71+view { availableFactors } =
72+ let
73+ ( supportedProviders, unsupportedProviders ) =
74+ List.partition providerIsSupported availableFactors
75+ in
76+ [ El.layout [ El.padding 8 ]
77+ (El.column
78+ [ El.width El.fill
79+ , El.spacing 8
80+ ]
81+ ([ if List.isEmpty supportedProviders then
82+ El.column []
83+ [ El.paragraph []
84+ [ El.text "Unfortunately, your account has no compatible 2FA providers."
85+ ]
86+ , El.el
87+ [ El.height (El.px 16)
88+ ]
89+ El.none
90+ ]
91+
92+ else
93+ El.column [ El.centerX ]
94+ (supportedProviders
95+ |> List.map
96+ (\factor ->
97+ Input.button [ El.centerX ]
98+ { label =
99+ Html.button [ Attr.class "p-button" ] [ secondFactorName factor |> Html.text ]
100+ |> El.html
101+ , onPress = SelectFactor factor |> Just
102+ }
103+ )
104+ )
105+ ]
106+ ++ (if List.isEmpty unsupportedProviders |> not then
107+ [ Html.div
108+ [ Attr.class "p-notification--information"
109+ ]
110+ [ Html.div [ Attr.class "p-notification__content" ]
111+ [ Html.h5 [ Attr.class "p-notification__title" ]
112+ [ Html.text "The following 2FA providers are not supported"
113+ ]
114+ , Html.p [ Attr.class "notification__message" ]
115+ [ Html.ul []
116+ (List.map
117+ (secondFactorName >> Html.text >> List.singleton >> Html.li [])
118+ unsupportedProviders
119+ )
120+ ]
121+ ]
122+ ]
123+ |> El.html
124+ |> List.singleton
125+ |> El.paragraph
126+ [ Font.size 16
127+ , El.width El.fill
128+ ]
129+ ]
130+
131+ else
132+ []
133+ )
134+ )
135+ )
136+ ]
137+
138+
139+providerIsSupported : Bridge.TwoFactorProviderType -> Bool
140+providerIsSupported provider =
141+ case provider of
142+ Bridge.Authenticator ->
143+ True
144+
145+ Bridge.Duo ->
146+ False
147+
148+ Bridge.Email ->
149+ True
150+
151+ Bridge.OrganizationDuo ->
152+ False
153+
154+ Bridge.Remember ->
155+ False
156+
157+ Bridge.U2f ->
158+ False
159+
160+ Bridge.WebAuthn ->
161+ False
162+
163+ Bridge.Yubikey ->
164+ False
frontend/Search.elmnew file+40
@@ -0,0 +1,40 @@
1+module Search exposing (searchList)
2+
3+import Html exposing (..)
4+import Html.Lazy as Lazy
5+
6+
7+type alias Needle =
8+ String
9+
10+
11+type alias Haystack =
12+ String
13+
14+
15+search : List Needle -> Haystack -> Bool
16+search needles haystack =
17+ let
18+ haystack_ =
19+ haystack |> String.toLower
20+ in
21+ List.all (\needle -> String.contains needle haystack_) needles
22+
23+
24+prepareNeedles : String -> List Needle
25+prepareNeedles =
26+ String.toLower
27+ >> String.words
28+ >> List.map String.trim
29+ >> List.filter (String.isEmpty >> not)
30+ >> List.filter (String.length >> (<) 1)
31+
32+
33+searchList : Needle -> (a -> Haystack) -> (List a -> Html msg) -> List a -> Html msg
34+searchList needle getHaystack show aa =
35+ case prepareNeedles needle of
36+ [] ->
37+ Lazy.lazy show aa
38+
39+ needles ->
40+ aa |> List.filter (\a -> search needles (getHaystack a)) |> show
frontend/Switch.elmnew file+35
@@ -0,0 +1,35 @@
1+module Switch exposing (..)
2+
3+import Html exposing (..)
4+import Html.Attributes as Attr
5+import Html.Events as Ev
6+import Utils exposing (..)
7+
8+
9+type alias SwitchConfig msg =
10+ { trigger : Bool -> msg
11+ , label : String
12+ , value : Bool
13+ , hidden : Bool
14+ }
15+
16+
17+switch : SwitchConfig msg -> Html msg
18+switch cfg =
19+ label
20+ [ Attr.class "p-switch"
21+ ]
22+ [ input
23+ [ Attr.type_ "checkbox"
24+ , Attr.class "p-switch__input"
25+ , Ev.onCheck cfg.trigger
26+ , Attr.checked cfg.value
27+ ]
28+ []
29+ , span
30+ (Attr.class "p-switch__slider"
31+ :: optional cfg.hidden (Attr.style "visibility" "hidden")
32+ )
33+ []
34+ , span [ Attr.class "p-switch__label" ] [ text cfg.label ]
35+ ]
frontend/Types.elmnew file+5
@@ -0,0 +1,5 @@
1+module Types exposing (..)
2+
3+
4+type alias CipherId =
5+ String
frontend/Utils.elm+70
@@ -2,6 +2,7 @@ module Utils exposing (..)
2
2
3import Html exposing (..)
3import Html exposing (..)
4import Html.Attributes as Attr
4import Html.Attributes as Attr
5+import Html.Events as Ev
5import Task
6import Task
6
7
7
8
@@ -81,3 +82,72 @@ tailEmpty x =
81
82
82 _ :: xs ->
83 _ :: xs ->
83 xs
84 xs
85+
86+
87+unwords : List String -> String
88+unwords =
89+ String.join " "
90+
91+
92+zip : List a -> List b -> List ( a, b )
93+zip =
94+ List.map2 (\a b -> ( a, b ))
95+
96+
97+mapIndex : (a -> a) -> Int -> List a -> List a
98+mapIndex f i xs =
99+ case ( i, xs ) of
100+ ( _, [] ) ->
101+ []
102+
103+ ( 0, x :: xx ) ->
104+ f x :: xx
105+
106+ ( j, x :: xx ) ->
107+ x :: mapIndex f (j - 1) xx
108+
109+
110+replace : Int -> a -> List a -> List a
111+replace i a xs =
112+ case ( i, xs ) of
113+ ( 0, _ :: xx ) ->
114+ a :: xx
115+
116+ ( j, x :: xx ) ->
117+ x :: replace (j - 1) a xx
118+
119+ ( _, [] ) ->
120+ []
121+
122+
123+index : Int -> List a -> Maybe a
124+index i xs =
125+ case ( i, xs ) of
126+ ( 0, x :: _ ) ->
127+ Just x
128+
129+ ( j, _ :: xx ) ->
130+ index (j - 1) xx
131+
132+ ( _, [] ) ->
133+ Nothing
134+
135+
136+spanList : (a -> Bool) -> List a -> ( List a, List a )
137+spanList f aa =
138+ case aa of
139+ [] ->
140+ ( aa, aa )
141+
142+ a :: rest ->
143+ if f a then
144+ spanList f rest |> Tuple.mapFirst ((::) a)
145+
146+ else
147+ ( [], aa )
148+
149+
150+iconButton : String -> msg -> Html msg
151+iconButton name msg =
152+ button [ Attr.class "p-button is-inline is-dense has-icon", Ev.onClick msg ]
153+ [ i [ Attr.class ("p-icon--" ++ name) ] [] ]
hcaptcha.htmlnew file+33
@@ -0,0 +1,33 @@
1+<!DOCTYPE html>
2+<html lang="en">
3+
4+<head>
5+ <meta charset="UTF-8">
6+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
7+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8+ <title>hCaptcha</title>
9+ <script src="https://js.hcaptcha.com/1/api.js" async defer></script>
10+</head>
11+
12+<body>
13+
14+ <script>
15+ function processSuccess(token) {
16+ console.log(token);
17+ window.parent.postMessage({ "hCaptchaToken": token }, "*");
18+ }
19+
20+ const sitekey = location.search.replace("?", "")
21+ console.log(sitekey)
22+
23+ const div = document.createElement("div");
24+ div.setAttribute("class", "h-captcha");
25+ div.setAttribute("data-sitekey", sitekey);
26+ div.setAttribute("data-callback", "processSuccess");
27+
28+ document.body.append(div)
29+
30+ </script>
31+</body>
32+
33+</html>
img/donate.pngnew file

Binary file not shown.

index.html+2−2
@@ -5,9 +5,9 @@
5 <meta charset="UTF-8">
5 <meta charset="UTF-8">
6 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 <meta http-equiv="X-UA-Compatible" content="IE=edge">
7 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
7 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
8− <link rel="stylesheet" href="vanilla/style.css">
8+ <link rel="stylesheet" href="vanilla/dist/style.css">
9 <link rel="stylesheet" href="style.css">
9 <link rel="stylesheet" href="style.css">
10− <title>Test.</title>
10+ <title>Warden</title>
11 <script src="elm.js"></script>
11 <script src="elm.js"></script>
12</head>
12</head>
13
13
logo.pngnew file

Binary file not shown.

logo.svgdeleted−24
@@ -1,24 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2−<svg style="enable-background:new" xmlns="http://www.w3.org/2000/svg" height="512" viewBox="0 0 512.40002 512" width="512.4" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
3− <defs>
4− <linearGradient id="a" y2="494" gradientUnits="userSpaceOnUse" x2="256" gradientTransform="matrix(1 0 0 1.076 0 -19.36)" y1="18" x1="256">
5− <stop style="stop-color:#eaeaea" offset="0"/>
6− <stop style="stop-color:#f4f4f4" offset="1"/>
7− </linearGradient>
8− </defs>
9− <rect style="color:#000000;enable-background:accumulate;fill:url(#a)" height="512" width="512" y="0" x="0"/>
10− <path style="opacity:.1" d="m256 112c-79.5 0-144 64.5-144 144s64.5 144 144 144 144-64.5 144-144-64.5-144-144-144zm49.47 39.98c3.098 0.0797 6.222 0.9104 9.096 2.568 9.197 5.312 12.34 17.07 7.029 26.26-5.305 9.196-17.06 12.34-26.25 7.029-9.19-5.305-12.34-17.06-7.039-26.25 3.653-6.322 10.35-9.787 17.17-9.611zm-49.48 20.5c7.731 0 15.21 1.074 22.31 3.035 1.253 7.726 5.837 14.84 13.15 19.06 7.298 4.207 15.74 4.629 23.05 1.867 14.22 13.98 23.47 32.99 24.81 54.17l-27.39 0.4043c-2.5-28.7-26.6-51.2-55.9-51.2-8.451 0-16.47 1.88-23.65 5.225l-13.4-23.9c11.16-5.522 23.72-8.645 37.01-8.645zm-46.33 14.03 14.06 23.54c-14.44 10.16-23.88 26.95-23.88 45.95s9.437 35.78 23.88 45.94l-14.06 23.55c-16.83-11.24-29.34-28.43-34.54-48.55 6.069-4.952 9.953-12.49 9.953-20.94 0-8.451-3.884-15.99-9.953-20.94 5.201-20.12 17.72-37.3 34.54-48.55zm-51.58 50.26c10.62 0 19.22 8.608 19.22 19.23s-8.605 19.22-19.22 19.22-19.23-8.605-19.23-19.22 8.607-19.23 19.23-19.23zm153.8 24.21 27.4 0.4023c-1.348 21.18-10.6 40.19-24.81 54.17-7.31-2.762-15.75-2.347-23.05 1.867-7.309 4.227-11.89 11.34-13.15 19.06-7.104 1.967-14.58 3.041-22.31 3.041-13.29 0-25.86-3.124-37.01-8.652l13.36-23.94c7.186 3.344 15.2 5.225 23.65 5.225 29.34 0 53.41-22.49 55.93-51.18zm-7.482 60.6c6.816-0.1758 13.51 3.289 17.16 9.607 5.311 9.197 2.16 20.95-7.035 26.25-9.196 5.311-20.95 2.159-26.25-7.037-5.312-9.191-2.159-20.94 7.037-26.25 2.872-1.658 5.994-2.49 9.092-2.57z"/>
11− <g transform="translate(0,18)">
12− <path style="opacity:.3;color:#000000;enable-background:accumulate;fill:#fff" d="m256 256l-147.8 256h403.8v-256h-122.7-133.3z" transform="translate(0,-18)"/>
13− <path style="opacity:.15;color:#000000;enable-background:accumulate;fill:#fff" d="m0 0v512h108.2l76.4-132.3 71.4-123.7-68.9-120-0.2 0.3-78.7-136.3h-108.2z" transform="translate(0,-18)"/>
14− </g>
15− <path d="m-208.3 605.6c-7.842 0-14.55 5.029-17.32 12.19-0.0612-0.00067-0.1208 0-0.1823 0-7.088 0-12.83 6.002-12.83 13.41 0 7.404 5.746 13.41 12.83 13.41h17.5 16.33c5.155 0 9.333-4.365 9.333-9.75 0-4.543-2.974-8.363-7-9.445 0.001-0.1029 0-0.2015 0-0.3047 0-10.77-8.357-19.5-18.67-19.5z" style="stroke-width:4;color:#000000;stroke:#ccc;enable-background:accumulate;display:none;fill:#fff"/>
16− <path style="stroke-width:4;color:#000000;stroke:#ccc;enable-background:accumulate;display:none;fill:none" d="m288.9 828.1c-6.349 0-11.78 4.072-14.02 9.867-0.0496-0.00055-0.0978 0-0.1476 0-5.738 0-10.39 4.86-10.39 10.85 0 5.995 4.652 10.85 10.39 10.85h14.17 13.22c4.173 0 7.557-3.534 7.557-7.894 0-3.678-2.408-6.771-5.667-7.647 0.001-0.0833 0-0.1632 0-0.2467 0-8.719-6.766-15.79-15.11-15.79z"/>
17− <g style="display:none" transform="translate(0 -558.4)">
18− <path d="m166.1 576.4h179.9c145.3 0 166.1 20.74 166.1 165.9v144.2c0 145.2-20.76 165.9-166.1 165.9h-179.9c-145.3 0-166.1-20-166.1-165.5v-144.2c0-145.2 20.76-165.9 166.1-165.9z" style="stroke:#00f;fill:#00f;display:inline;fill-opacity:.08118"/>
19− <circle style="stroke-width:.8333;fill-opacity:.08118;color:#000000;stroke:#00f;enable-background:accumulate;display:inline;fill:#00f" cx="256" transform="matrix(1.2 0 0 1.2 -51.2 528.8)" cy="238" r="120"/>
20− <rect style="stroke-linejoin:round;fill-opacity:.08118;color:#000000;stroke:#00f;stroke-linecap:round;enable-background:accumulate;display:inline;fill:#00f" height="272" width="272" y="678.4" x="120"/>
21− <rect style="stroke-linejoin:round;fill-opacity:.08118;color:#000000;stroke:#00f;stroke-linecap:round;enable-background:accumulate;display:inline;fill:#00f" height="240" width="304" y="694.4" x="104"/>
22− <rect style="stroke-linejoin:round;fill-opacity:.08118;color:#000000;stroke:#00f;stroke-linecap:round;enable-background:accumulate;display:inline;fill:#00f" height="304" width="240" y="662.4" x="136"/>
23− </g>
24−</svg>
logo.xcfnew file

Binary file not shown.

manifest.json+8−8
@@ -1,15 +1,15 @@
1{
1{
2− "name": "appname.iko",
2+ "name": "soy.iko.warden",
3− "description": "A short description of your app",
3+ "description": "A simple Bitwarden client",
4 "architecture": "@CLICK_ARCH@",
4 "architecture": "@CLICK_ARCH@",
5− "title": "App Title",
5+ "title": "Warden",
6 "hooks": {
6 "hooks": {
7− "appname": {
7+ "warden": {
8− "apparmor": "appname.apparmor",
8+ "apparmor": "warden.apparmor",
9− "desktop": "appname.desktop"
9+ "desktop": "warden.desktop"
10 }
10 }
11 },
11 },
12− "version": "1.0.0",
12+ "version": "1.2.4",
13− "maintainer": "Your FullName <email@domain.org>",
13+ "maintainer": "Ilia Kostiuchenko <mail@iko.soy>",
14 "framework": "@CLICK_FRAMEWORK@"
14 "framework": "@CLICK_FRAMEWORK@"
15}
15}
package-lock.jsonnew file+959
@@ -0,0 +1,959 @@
1+{
2+ "name": "warden",
3+ "lockfileVersion": 3,
4+ "requires": true,
5+ "packages": {
6+ "": {
7+ "devDependencies": {
8+ "cssnano": "^5.1.15"
9+ }
10+ },
11+ "node_modules/@trysound/sax": {
12+ "version": "0.2.0",
13+ "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
14+ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
15+ "dev": true,
16+ "engines": {
17+ "node": ">=10.13.0"
18+ }
19+ },
20+ "node_modules/boolbase": {
21+ "version": "1.0.0",
22+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
23+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
24+ "dev": true
25+ },
26+ "node_modules/browserslist": {
27+ "version": "4.21.5",
28+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
29+ "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
30+ "dev": true,
31+ "funding": [
32+ {
33+ "type": "opencollective",
34+ "url": "https://opencollective.com/browserslist"
35+ },
36+ {
37+ "type": "tidelift",
38+ "url": "https://tidelift.com/funding/github/npm/browserslist"
39+ }
40+ ],
41+ "dependencies": {
42+ "caniuse-lite": "^1.0.30001449",
43+ "electron-to-chromium": "^1.4.284",
44+ "node-releases": "^2.0.8",
45+ "update-browserslist-db": "^1.0.10"
46+ },
47+ "bin": {
48+ "browserslist": "cli.js"
49+ },
50+ "engines": {
51+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
52+ }
53+ },
54+ "node_modules/caniuse-api": {
55+ "version": "3.0.0",
56+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
57+ "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
58+ "dev": true,
59+ "dependencies": {
60+ "browserslist": "^4.0.0",
61+ "caniuse-lite": "^1.0.0",
62+ "lodash.memoize": "^4.1.2",
63+ "lodash.uniq": "^4.5.0"
64+ }
65+ },
66+ "node_modules/caniuse-lite": {
67+ "version": "1.0.30001457",
68+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz",
69+ "integrity": "sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA==",
70+ "dev": true,
71+ "funding": [
72+ {
73+ "type": "opencollective",
74+ "url": "https://opencollective.com/browserslist"
75+ },
76+ {
77+ "type": "tidelift",
78+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
79+ }
80+ ]
81+ },
82+ "node_modules/colord": {
83+ "version": "2.9.3",
84+ "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
85+ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
86+ "dev": true
87+ },
88+ "node_modules/commander": {
89+ "version": "7.2.0",
90+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
91+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
92+ "dev": true,
93+ "engines": {
94+ "node": ">= 10"
95+ }
96+ },
97+ "node_modules/css-declaration-sorter": {
98+ "version": "6.3.1",
99+ "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz",
100+ "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==",
101+ "dev": true,
102+ "engines": {
103+ "node": "^10 || ^12 || >=14"
104+ },
105+ "peerDependencies": {
106+ "postcss": "^8.0.9"
107+ }
108+ },
109+ "node_modules/css-select": {
110+ "version": "4.3.0",
111+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
112+ "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
113+ "dev": true,
114+ "dependencies": {
115+ "boolbase": "^1.0.0",
116+ "css-what": "^6.0.1",
117+ "domhandler": "^4.3.1",
118+ "domutils": "^2.8.0",
119+ "nth-check": "^2.0.1"
120+ },
121+ "funding": {
122+ "url": "https://github.com/sponsors/fb55"
123+ }
124+ },
125+ "node_modules/css-tree": {
126+ "version": "1.1.3",
127+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
128+ "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
129+ "dev": true,
130+ "dependencies": {
131+ "mdn-data": "2.0.14",
132+ "source-map": "^0.6.1"
133+ },
134+ "engines": {
135+ "node": ">=8.0.0"
136+ }
137+ },
138+ "node_modules/css-what": {
139+ "version": "6.1.0",
140+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
141+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
142+ "dev": true,
143+ "engines": {
144+ "node": ">= 6"
145+ },
146+ "funding": {
147+ "url": "https://github.com/sponsors/fb55"
148+ }
149+ },
150+ "node_modules/cssesc": {
151+ "version": "3.0.0",
152+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
153+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
154+ "dev": true,
155+ "bin": {
156+ "cssesc": "bin/cssesc"
157+ },
158+ "engines": {
159+ "node": ">=4"
160+ }
161+ },
162+ "node_modules/cssnano": {
163+ "version": "5.1.15",
164+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz",
165+ "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==",
166+ "dev": true,
167+ "dependencies": {
168+ "cssnano-preset-default": "^5.2.14",
169+ "lilconfig": "^2.0.3",
170+ "yaml": "^1.10.2"
171+ },
172+ "engines": {
173+ "node": "^10 || ^12 || >=14.0"
174+ },
175+ "funding": {
176+ "type": "opencollective",
177+ "url": "https://opencollective.com/cssnano"
178+ },
179+ "peerDependencies": {
180+ "postcss": "^8.2.15"
181+ }
182+ },
183+ "node_modules/cssnano-preset-default": {
184+ "version": "5.2.14",
185+ "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz",
186+ "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==",
187+ "dev": true,
188+ "dependencies": {
189+ "css-declaration-sorter": "^6.3.1",
190+ "cssnano-utils": "^3.1.0",
191+ "postcss-calc": "^8.2.3",
192+ "postcss-colormin": "^5.3.1",
193+ "postcss-convert-values": "^5.1.3",
194+ "postcss-discard-comments": "^5.1.2",
195+ "postcss-discard-duplicates": "^5.1.0",
196+ "postcss-discard-empty": "^5.1.1",
197+ "postcss-discard-overridden": "^5.1.0",
198+ "postcss-merge-longhand": "^5.1.7",
199+ "postcss-merge-rules": "^5.1.4",
200+ "postcss-minify-font-values": "^5.1.0",
201+ "postcss-minify-gradients": "^5.1.1",
202+ "postcss-minify-params": "^5.1.4",
203+ "postcss-minify-selectors": "^5.2.1",
204+ "postcss-normalize-charset": "^5.1.0",
205+ "postcss-normalize-display-values": "^5.1.0",
206+ "postcss-normalize-positions": "^5.1.1",
207+ "postcss-normalize-repeat-style": "^5.1.1",
208+ "postcss-normalize-string": "^5.1.0",
209+ "postcss-normalize-timing-functions": "^5.1.0",
210+ "postcss-normalize-unicode": "^5.1.1",
211+ "postcss-normalize-url": "^5.1.0",
212+ "postcss-normalize-whitespace": "^5.1.1",
213+ "postcss-ordered-values": "^5.1.3",
214+ "postcss-reduce-initial": "^5.1.2",
215+ "postcss-reduce-transforms": "^5.1.0",
216+ "postcss-svgo": "^5.1.0",
217+ "postcss-unique-selectors": "^5.1.1"
218+ },
219+ "engines": {
220+ "node": "^10 || ^12 || >=14.0"
221+ },
222+ "peerDependencies": {
223+ "postcss": "^8.2.15"
224+ }
225+ },
226+ "node_modules/cssnano-utils": {
227+ "version": "3.1.0",
228+ "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
229+ "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
230+ "dev": true,
231+ "engines": {
232+ "node": "^10 || ^12 || >=14.0"
233+ },
234+ "peerDependencies": {
235+ "postcss": "^8.2.15"
236+ }
237+ },
238+ "node_modules/csso": {
239+ "version": "4.2.0",
240+ "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz",
241+ "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==",
242+ "dev": true,
243+ "dependencies": {
244+ "css-tree": "^1.1.2"
245+ },
246+ "engines": {
247+ "node": ">=8.0.0"
248+ }
249+ },
250+ "node_modules/dom-serializer": {
251+ "version": "1.4.1",
252+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
253+ "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
254+ "dev": true,
255+ "dependencies": {
256+ "domelementtype": "^2.0.1",
257+ "domhandler": "^4.2.0",
258+ "entities": "^2.0.0"
259+ },
260+ "funding": {
261+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
262+ }
263+ },
264+ "node_modules/domelementtype": {
265+ "version": "2.3.0",
266+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
267+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
268+ "dev": true,
269+ "funding": [
270+ {
271+ "type": "github",
272+ "url": "https://github.com/sponsors/fb55"
273+ }
274+ ]
275+ },
276+ "node_modules/domhandler": {
277+ "version": "4.3.1",
278+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
279+ "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
280+ "dev": true,
281+ "dependencies": {
282+ "domelementtype": "^2.2.0"
283+ },
284+ "engines": {
285+ "node": ">= 4"
286+ },
287+ "funding": {
288+ "url": "https://github.com/fb55/domhandler?sponsor=1"
289+ }
290+ },
291+ "node_modules/domutils": {
292+ "version": "2.8.0",
293+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
294+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
295+ "dev": true,
296+ "dependencies": {
297+ "dom-serializer": "^1.0.1",
298+ "domelementtype": "^2.2.0",
299+ "domhandler": "^4.2.0"
300+ },
301+ "funding": {
302+ "url": "https://github.com/fb55/domutils?sponsor=1"
303+ }
304+ },
305+ "node_modules/electron-to-chromium": {
306+ "version": "1.4.302",
307+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.302.tgz",
308+ "integrity": "sha512-Uk7C+7aPBryUR1Fwvk9VmipBcN9fVsqBO57jV2ZjTm+IZ6BMNqu7EDVEg2HxCNufk6QcWlFsBkhQyQroB2VWKw==",
309+ "dev": true
310+ },
311+ "node_modules/entities": {
312+ "version": "2.2.0",
313+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
314+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
315+ "dev": true,
316+ "funding": {
317+ "url": "https://github.com/fb55/entities?sponsor=1"
318+ }
319+ },
320+ "node_modules/escalade": {
321+ "version": "3.1.1",
322+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
323+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
324+ "dev": true,
325+ "engines": {
326+ "node": ">=6"
327+ }
328+ },
329+ "node_modules/lilconfig": {
330+ "version": "2.0.6",
331+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz",
332+ "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==",
333+ "dev": true,
334+ "engines": {
335+ "node": ">=10"
336+ }
337+ },
338+ "node_modules/lodash.memoize": {
339+ "version": "4.1.2",
340+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
341+ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
342+ "dev": true
343+ },
344+ "node_modules/lodash.uniq": {
345+ "version": "4.5.0",
346+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
347+ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
348+ "dev": true
349+ },
350+ "node_modules/mdn-data": {
351+ "version": "2.0.14",
352+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
353+ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
354+ "dev": true
355+ },
356+ "node_modules/nanoid": {
357+ "version": "3.3.4",
358+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
359+ "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
360+ "dev": true,
361+ "peer": true,
362+ "bin": {
363+ "nanoid": "bin/nanoid.cjs"
364+ },
365+ "engines": {
366+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
367+ }
368+ },
369+ "node_modules/node-releases": {
370+ "version": "2.0.10",
371+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
372+ "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==",
373+ "dev": true
374+ },
375+ "node_modules/normalize-url": {
376+ "version": "6.1.0",
377+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
378+ "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
379+ "dev": true,
380+ "engines": {
381+ "node": ">=10"
382+ },
383+ "funding": {
384+ "url": "https://github.com/sponsors/sindresorhus"
385+ }
386+ },
387+ "node_modules/nth-check": {
388+ "version": "2.1.1",
389+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
390+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
391+ "dev": true,
392+ "dependencies": {
393+ "boolbase": "^1.0.0"
394+ },
395+ "funding": {
396+ "url": "https://github.com/fb55/nth-check?sponsor=1"
397+ }
398+ },
399+ "node_modules/picocolors": {
400+ "version": "1.0.0",
401+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
402+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
403+ "dev": true
404+ },
405+ "node_modules/postcss": {
406+ "version": "8.4.21",
407+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
408+ "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
409+ "dev": true,
410+ "funding": [
411+ {
412+ "type": "opencollective",
413+ "url": "https://opencollective.com/postcss/"
414+ },
415+ {
416+ "type": "tidelift",
417+ "url": "https://tidelift.com/funding/github/npm/postcss"
418+ }
419+ ],
420+ "peer": true,
421+ "dependencies": {
422+ "nanoid": "^3.3.4",
423+ "picocolors": "^1.0.0",
424+ "source-map-js": "^1.0.2"
425+ },
426+ "engines": {
427+ "node": "^10 || ^12 || >=14"
428+ }
429+ },
430+ "node_modules/postcss-calc": {
431+ "version": "8.2.4",
432+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz",
433+ "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==",
434+ "dev": true,
435+ "dependencies": {
436+ "postcss-selector-parser": "^6.0.9",
437+ "postcss-value-parser": "^4.2.0"
438+ },
439+ "peerDependencies": {
440+ "postcss": "^8.2.2"
441+ }
442+ },
443+ "node_modules/postcss-colormin": {
444+ "version": "5.3.1",
445+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz",
446+ "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==",
447+ "dev": true,
448+ "dependencies": {
449+ "browserslist": "^4.21.4",
450+ "caniuse-api": "^3.0.0",
451+ "colord": "^2.9.1",
452+ "postcss-value-parser": "^4.2.0"
453+ },
454+ "engines": {
455+ "node": "^10 || ^12 || >=14.0"
456+ },
457+ "peerDependencies": {
458+ "postcss": "^8.2.15"
459+ }
460+ },
461+ "node_modules/postcss-convert-values": {
462+ "version": "5.1.3",
463+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz",
464+ "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==",
465+ "dev": true,
466+ "dependencies": {
467+ "browserslist": "^4.21.4",
468+ "postcss-value-parser": "^4.2.0"
469+ },
470+ "engines": {
471+ "node": "^10 || ^12 || >=14.0"
472+ },
473+ "peerDependencies": {
474+ "postcss": "^8.2.15"
475+ }
476+ },
477+ "node_modules/postcss-discard-comments": {
478+ "version": "5.1.2",
479+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz",
480+ "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==",
481+ "dev": true,
482+ "engines": {
483+ "node": "^10 || ^12 || >=14.0"
484+ },
485+ "peerDependencies": {
486+ "postcss": "^8.2.15"
487+ }
488+ },
489+ "node_modules/postcss-discard-duplicates": {
490+ "version": "5.1.0",
491+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz",
492+ "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==",
493+ "dev": true,
494+ "engines": {
495+ "node": "^10 || ^12 || >=14.0"
496+ },
497+ "peerDependencies": {
498+ "postcss": "^8.2.15"
499+ }
500+ },
501+ "node_modules/postcss-discard-empty": {
502+ "version": "5.1.1",
503+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz",
504+ "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==",
505+ "dev": true,
506+ "engines": {
507+ "node": "^10 || ^12 || >=14.0"
508+ },
509+ "peerDependencies": {
510+ "postcss": "^8.2.15"
511+ }
512+ },
513+ "node_modules/postcss-discard-overridden": {
514+ "version": "5.1.0",
515+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz",
516+ "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==",
517+ "dev": true,
518+ "engines": {
519+ "node": "^10 || ^12 || >=14.0"
520+ },
521+ "peerDependencies": {
522+ "postcss": "^8.2.15"
523+ }
524+ },
525+ "node_modules/postcss-merge-longhand": {
526+ "version": "5.1.7",
527+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz",
528+ "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==",
529+ "dev": true,
530+ "dependencies": {
531+ "postcss-value-parser": "^4.2.0",
532+ "stylehacks": "^5.1.1"
533+ },
534+ "engines": {
535+ "node": "^10 || ^12 || >=14.0"
536+ },
537+ "peerDependencies": {
538+ "postcss": "^8.2.15"
539+ }
540+ },
541+ "node_modules/postcss-merge-rules": {
542+ "version": "5.1.4",
543+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz",
544+ "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==",
545+ "dev": true,
546+ "dependencies": {
547+ "browserslist": "^4.21.4",
548+ "caniuse-api": "^3.0.0",
549+ "cssnano-utils": "^3.1.0",
550+ "postcss-selector-parser": "^6.0.5"
551+ },
552+ "engines": {
553+ "node": "^10 || ^12 || >=14.0"
554+ },
555+ "peerDependencies": {
556+ "postcss": "^8.2.15"
557+ }
558+ },
559+ "node_modules/postcss-minify-font-values": {
560+ "version": "5.1.0",
561+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz",
562+ "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==",
563+ "dev": true,
564+ "dependencies": {
565+ "postcss-value-parser": "^4.2.0"
566+ },
567+ "engines": {
568+ "node": "^10 || ^12 || >=14.0"
569+ },
570+ "peerDependencies": {
571+ "postcss": "^8.2.15"
572+ }
573+ },
574+ "node_modules/postcss-minify-gradients": {
575+ "version": "5.1.1",
576+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz",
577+ "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==",
578+ "dev": true,
579+ "dependencies": {
580+ "colord": "^2.9.1",
581+ "cssnano-utils": "^3.1.0",
582+ "postcss-value-parser": "^4.2.0"
583+ },
584+ "engines": {
585+ "node": "^10 || ^12 || >=14.0"
586+ },
587+ "peerDependencies": {
588+ "postcss": "^8.2.15"
589+ }
590+ },
591+ "node_modules/postcss-minify-params": {
592+ "version": "5.1.4",
593+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz",
594+ "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==",
595+ "dev": true,
596+ "dependencies": {
597+ "browserslist": "^4.21.4",
598+ "cssnano-utils": "^3.1.0",
599+ "postcss-value-parser": "^4.2.0"
600+ },
601+ "engines": {
602+ "node": "^10 || ^12 || >=14.0"
603+ },
604+ "peerDependencies": {
605+ "postcss": "^8.2.15"
606+ }
607+ },
608+ "node_modules/postcss-minify-selectors": {
609+ "version": "5.2.1",
610+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz",
611+ "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==",
612+ "dev": true,
613+ "dependencies": {
614+ "postcss-selector-parser": "^6.0.5"
615+ },
616+ "engines": {
617+ "node": "^10 || ^12 || >=14.0"
618+ },
619+ "peerDependencies": {
620+ "postcss": "^8.2.15"
621+ }
622+ },
623+ "node_modules/postcss-normalize-charset": {
624+ "version": "5.1.0",
625+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
626+ "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==",
627+ "dev": true,
628+ "engines": {
629+ "node": "^10 || ^12 || >=14.0"
630+ },
631+ "peerDependencies": {
632+ "postcss": "^8.2.15"
633+ }
634+ },
635+ "node_modules/postcss-normalize-display-values": {
636+ "version": "5.1.0",
637+ "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz",
638+ "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==",
639+ "dev": true,
640+ "dependencies": {
641+ "postcss-value-parser": "^4.2.0"
642+ },
643+ "engines": {
644+ "node": "^10 || ^12 || >=14.0"
645+ },
646+ "peerDependencies": {
647+ "postcss": "^8.2.15"
648+ }
649+ },
650+ "node_modules/postcss-normalize-positions": {
651+ "version": "5.1.1",
652+ "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz",
653+ "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==",
654+ "dev": true,
655+ "dependencies": {
656+ "postcss-value-parser": "^4.2.0"
657+ },
658+ "engines": {
659+ "node": "^10 || ^12 || >=14.0"
660+ },
661+ "peerDependencies": {
662+ "postcss": "^8.2.15"
663+ }
664+ },
665+ "node_modules/postcss-normalize-repeat-style": {
666+ "version": "5.1.1",
667+ "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz",
668+ "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==",
669+ "dev": true,
670+ "dependencies": {
671+ "postcss-value-parser": "^4.2.0"
672+ },
673+ "engines": {
674+ "node": "^10 || ^12 || >=14.0"
675+ },
676+ "peerDependencies": {
677+ "postcss": "^8.2.15"
678+ }
679+ },
680+ "node_modules/postcss-normalize-string": {
681+ "version": "5.1.0",
682+ "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz",
683+ "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==",
684+ "dev": true,
685+ "dependencies": {
686+ "postcss-value-parser": "^4.2.0"
687+ },
688+ "engines": {
689+ "node": "^10 || ^12 || >=14.0"
690+ },
691+ "peerDependencies": {
692+ "postcss": "^8.2.15"
693+ }
694+ },
695+ "node_modules/postcss-normalize-timing-functions": {
696+ "version": "5.1.0",
697+ "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz",
698+ "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==",
699+ "dev": true,
700+ "dependencies": {
701+ "postcss-value-parser": "^4.2.0"
702+ },
703+ "engines": {
704+ "node": "^10 || ^12 || >=14.0"
705+ },
706+ "peerDependencies": {
707+ "postcss": "^8.2.15"
708+ }
709+ },
710+ "node_modules/postcss-normalize-unicode": {
711+ "version": "5.1.1",
712+ "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz",
713+ "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==",
714+ "dev": true,
715+ "dependencies": {
716+ "browserslist": "^4.21.4",
717+ "postcss-value-parser": "^4.2.0"
718+ },
719+ "engines": {
720+ "node": "^10 || ^12 || >=14.0"
721+ },
722+ "peerDependencies": {
723+ "postcss": "^8.2.15"
724+ }
725+ },
726+ "node_modules/postcss-normalize-url": {
727+ "version": "5.1.0",
728+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz",
729+ "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==",
730+ "dev": true,
731+ "dependencies": {
732+ "normalize-url": "^6.0.1",
733+ "postcss-value-parser": "^4.2.0"
734+ },
735+ "engines": {
736+ "node": "^10 || ^12 || >=14.0"
737+ },
738+ "peerDependencies": {
739+ "postcss": "^8.2.15"
740+ }
741+ },
742+ "node_modules/postcss-normalize-whitespace": {
743+ "version": "5.1.1",
744+ "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz",
745+ "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==",
746+ "dev": true,
747+ "dependencies": {
748+ "postcss-value-parser": "^4.2.0"
749+ },
750+ "engines": {
751+ "node": "^10 || ^12 || >=14.0"
752+ },
753+ "peerDependencies": {
754+ "postcss": "^8.2.15"
755+ }
756+ },
757+ "node_modules/postcss-ordered-values": {
758+ "version": "5.1.3",
759+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz",
760+ "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==",
761+ "dev": true,
762+ "dependencies": {
763+ "cssnano-utils": "^3.1.0",
764+ "postcss-value-parser": "^4.2.0"
765+ },
766+ "engines": {
767+ "node": "^10 || ^12 || >=14.0"
768+ },
769+ "peerDependencies": {
770+ "postcss": "^8.2.15"
771+ }
772+ },
773+ "node_modules/postcss-reduce-initial": {
774+ "version": "5.1.2",
775+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz",
776+ "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==",
777+ "dev": true,
778+ "dependencies": {
779+ "browserslist": "^4.21.4",
780+ "caniuse-api": "^3.0.0"
781+ },
782+ "engines": {
783+ "node": "^10 || ^12 || >=14.0"
784+ },
785+ "peerDependencies": {
786+ "postcss": "^8.2.15"
787+ }
788+ },
789+ "node_modules/postcss-reduce-transforms": {
790+ "version": "5.1.0",
791+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz",
792+ "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==",
793+ "dev": true,
794+ "dependencies": {
795+ "postcss-value-parser": "^4.2.0"
796+ },
797+ "engines": {
798+ "node": "^10 || ^12 || >=14.0"
799+ },
800+ "peerDependencies": {
801+ "postcss": "^8.2.15"
802+ }
803+ },
804+ "node_modules/postcss-selector-parser": {
805+ "version": "6.0.11",
806+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz",
807+ "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==",
808+ "dev": true,
809+ "dependencies": {
810+ "cssesc": "^3.0.0",
811+ "util-deprecate": "^1.0.2"
812+ },
813+ "engines": {
814+ "node": ">=4"
815+ }
816+ },
817+ "node_modules/postcss-svgo": {
818+ "version": "5.1.0",
819+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz",
820+ "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==",
821+ "dev": true,
822+ "dependencies": {
823+ "postcss-value-parser": "^4.2.0",
824+ "svgo": "^2.7.0"
825+ },
826+ "engines": {
827+ "node": "^10 || ^12 || >=14.0"
828+ },
829+ "peerDependencies": {
830+ "postcss": "^8.2.15"
831+ }
832+ },
833+ "node_modules/postcss-unique-selectors": {
834+ "version": "5.1.1",
835+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz",
836+ "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==",
837+ "dev": true,
838+ "dependencies": {
839+ "postcss-selector-parser": "^6.0.5"
840+ },
841+ "engines": {
842+ "node": "^10 || ^12 || >=14.0"
843+ },
844+ "peerDependencies": {
845+ "postcss": "^8.2.15"
846+ }
847+ },
848+ "node_modules/postcss-value-parser": {
849+ "version": "4.2.0",
850+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
851+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
852+ "dev": true
853+ },
854+ "node_modules/source-map": {
855+ "version": "0.6.1",
856+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
857+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
858+ "dev": true,
859+ "engines": {
860+ "node": ">=0.10.0"
861+ }
862+ },
863+ "node_modules/source-map-js": {
864+ "version": "1.0.2",
865+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
866+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
867+ "dev": true,
868+ "peer": true,
869+ "engines": {
870+ "node": ">=0.10.0"
871+ }
872+ },
873+ "node_modules/stable": {
874+ "version": "0.1.8",
875+ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
876+ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
877+ "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility",
878+ "dev": true
879+ },
880+ "node_modules/stylehacks": {
881+ "version": "5.1.1",
882+ "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz",
883+ "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==",
884+ "dev": true,
885+ "dependencies": {
886+ "browserslist": "^4.21.4",
887+ "postcss-selector-parser": "^6.0.4"
888+ },
889+ "engines": {
890+ "node": "^10 || ^12 || >=14.0"
891+ },
892+ "peerDependencies": {
893+ "postcss": "^8.2.15"
894+ }
895+ },
896+ "node_modules/svgo": {
897+ "version": "2.8.0",
898+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
899+ "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==",
900+ "dev": true,
901+ "dependencies": {
902+ "@trysound/sax": "0.2.0",
903+ "commander": "^7.2.0",
904+ "css-select": "^4.1.3",
905+ "css-tree": "^1.1.3",
906+ "csso": "^4.2.0",
907+ "picocolors": "^1.0.0",
908+ "stable": "^0.1.8"
909+ },
910+ "bin": {
911+ "svgo": "bin/svgo"
912+ },
913+ "engines": {
914+ "node": ">=10.13.0"
915+ }
916+ },
917+ "node_modules/update-browserslist-db": {
918+ "version": "1.0.10",
919+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
920+ "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
921+ "dev": true,
922+ "funding": [
923+ {
924+ "type": "opencollective",
925+ "url": "https://opencollective.com/browserslist"
926+ },
927+ {
928+ "type": "tidelift",
929+ "url": "https://tidelift.com/funding/github/npm/browserslist"
930+ }
931+ ],
932+ "dependencies": {
933+ "escalade": "^3.1.1",
934+ "picocolors": "^1.0.0"
935+ },
936+ "bin": {
937+ "browserslist-lint": "cli.js"
938+ },
939+ "peerDependencies": {
940+ "browserslist": ">= 4.21.0"
941+ }
942+ },
943+ "node_modules/util-deprecate": {
944+ "version": "1.0.2",
945+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
946+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
947+ "dev": true
948+ },
949+ "node_modules/yaml": {
950+ "version": "1.10.2",
951+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
952+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
953+ "dev": true,
954+ "engines": {
955+ "node": ">= 6"
956+ }
957+ }
958+ }
959+}
packages.dhall+36−5
@@ -99,12 +99,10 @@ in upstream
99-------------------------------
99-------------------------------
100-}
100-}
101let upstream =
101let upstream =
102− https://github.com/purescript/package-sets/releases/download/psc-0.15.2-20220706/packages.dhall
102+ https://github.com/purescript/package-sets/releases/download/psc-0.15.4-20220808/packages.dhall
103− sha256:7a24ebdbacb2bfa27b2fc6ce3da96f048093d64e54369965a2a7b5d9892b6031
103+ sha256:60eee64b04ca0013fae3e02a69fc3b176105c6baa2f31865c67cd5f881a412fd
104
104
105in upstream
105in upstream
106− with bw = ./bw/spago.dhall as Location
107− with el = ./el/spago.dhall as Location
108 with argonaut-aeson-generic =
106 with argonaut-aeson-generic =
109 { dependencies =
107 { dependencies =
110 [ "argonaut-codecs"
108 [ "argonaut-codecs"
@@ -127,5 +125,38 @@ in upstream
127 ]
125 ]
128 , repo =
126 , repo =
129 "https://github.com/ilyakooo0/purescript-argonaut-aeson-generic.git"
127 "https://github.com/ilyakooo0/purescript-argonaut-aeson-generic.git"
130− , version = "purescript-0.14"
128+ , version = "3e388500811ef4b6718fc776789f3be050ad7b57"
129+ }
130+ with untagged-union =
131+ { dependencies =
132+ [ "assert"
133+ , "console"
134+ , "effect"
135+ , "either"
136+ , "foreign"
137+ , "foreign-object"
138+ , "literals"
139+ , "maybe"
140+ , "newtype"
141+ , "prelude"
142+ , "tuples"
143+ , "unsafe-coerce"
144+ ]
145+ , repo = "https://github.com/rowtype-yoga/purescript-untagged-union.git"
146+ , version = "6c5bccef38696a16e86ba9a65cf778b4462c4a66"
147+ }
148+ with literals =
149+ { repo = "https://github.com/ilyakooo0/purescript-literals.git"
150+ , version = "6875fb28026595cfb780318305a77e79b098bb01"
151+ , dependencies =
152+ [ "assert"
153+ , "effect"
154+ , "integers"
155+ , "maybe"
156+ , "numbers"
157+ , "partial"
158+ , "prelude"
159+ , "typelevel-prelude"
160+ , "unsafe-coerce"
161+ ]
131 }
162 }
registry.datnew file

Binary file not shown.

scratchpad/password_generator.htmlnew file+74
@@ -0,0 +1,74 @@
1+<!DOCTYPE html>
2+<html lang="en">
3+
4+<head>
5+ <meta charset="UTF-8">
6+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
7+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8+ <link rel="stylesheet" href="../vanilla/dist/style.css">
9+ <link rel="stylesheet" href="../style.css">
10+ <title>Password generator</title>
11+
12+ <style>
13+ body {
14+ margin: 10px;
15+ }
16+
17+ </style>
18+
19+</head>
20+
21+<body>
22+
23+ <div class="select-second-factor-container">
24+ <button class="p-button">Hello</button>
25+ <button class="p-button">Bar</button>
26+ <button class="p-button">Bar</button>
27+ <button class="p-button">Bardi</button>
28+ <button class="p-button">Wolrd</button>
29+ </div>
30+
31+ <div class="password-generator-group">
32+ <p>Password length</p>
33+ <input type="number" class="p-slider__input">
34+ </div>
35+
36+
37+ <div class="password-generator-group">
38+ <label class="p-switch">
39+ <input type="checkbox" class="p-switch__input">
40+ <span class="p-switch__slider"></span>
41+ <span class="p-switch__label">Numbers</span>
42+ </label>
43+ <input type="number" class="p-slider__input">
44+ </div>
45+
46+ <form action="">
47+ <label><input type="checkbox" name="" id="">Hahahah</label>
48+ <input type="checkbox">
49+
50+ </form>
51+
52+
53+
54+ <input type="range" min="0" max="100" value="50" step="1">
55+ <input type="range" min="0" max="100" value="50" step="1"
56+ style="background-image: -webkit-gradient(linear, 0% 0%, 100% 0%, color-stop(0.5, rgb(0, 102, 204)), color-stop(0.5, rgb(217, 217, 217)));">
57+ <h1>h</h1>
58+ <div class="p-slider__wrapper">
59+ <input type="range" min="0" max="100" value="50" step="1" id="slider4" disabled=""
60+ aria-label="Example of a disabled slider, range 0 to 100">
61+ <input class="p-slider__input" type="text" maxlength="3" id="slider4-input" disabled="" tabindex="0">
62+ </div>
63+ <div class="p-slider__wrapper">
64+ <input type="range" min="0" max="100" value="50" step="1" id="slider3" aria-label="Example slider, range 0 to 100">
65+ <input class="p-slider__input" type="number" maxlength="3" id="slider3-input" tabindex="0">
66+ </div>
67+
68+ <form>
69+ <input type="range" min="0" max="100" value="50" step="1">
70+ </form>
71+
72+</body>
73+
74+</html>
screenshots/1.pngnew file

Binary file not shown.

screenshots/2.pngnew file

Binary file not shown.

screenshots/3.pngnew file

Binary file not shown.

screenshots/4.pngnew file

Binary file not shown.

screenshots/5.pngnew file

Binary file not shown.

spago-packages.nixnew file+1102
@@ -0,0 +1,1102 @@
1+# This file was generated by Spago2Nix
2+
3+{ pkgs ? import <nixpkgs> {} }:
4+
5+let
6+ inputs = {
7+
8+ "aff" = pkgs.stdenv.mkDerivation {
9+ name = "aff";
10+ version = "v7.0.0";
11+ src = pkgs.fetchgit {
12+ url = "https://github.com/purescript-contrib/purescript-aff.git";
13+ rev = "2d44d9f9d0d6a416a4103fba2fb39e5160f80e36";
14+ sha256 = "1d38l16s8hvfqq5w40w21j5089svdiggkraw3rwrl6ml7lijjqx4";
15+ };
16+ phases = "installPhase";
17+ installPhase = "ln -s $src $out";
18+ };
19+
20+ "aff-promise" = pkgs.stdenv.mkDerivation {
21+ name = "aff-promise";
22+ version = "v4.0.0";
23+ src = pkgs.fetchgit {
24+ url = "https://github.com/nwolverson/purescript-aff-promise.git";
25+ rev = "3aa74e68e3e4c3e38d821375703e0b2f49d831eb";
26+ sha256 = "10gv3b05dxnlmr9zmigqs1hz4xqrx7da30aqh12kqg3zrg49k9cc";
27+ };
28+ phases = "installPhase";
29+ installPhase = "ln -s $src $out";
30+ };
31+
32+ "argonaut" = pkgs.stdenv.mkDerivation {
33+ name = "argonaut";
34+ version = "v9.0.0";
35+ src = pkgs.fetchgit {
36+ url = "https://github.com/purescript-contrib/purescript-argonaut.git";
37+ rev = "7505a47f2edb0c9cacaac4f11dcedf4723a3e9c8";
38+ sha256 = "18yxhlrwri6q858krz1klyq29fx8nvfm16c04wm2rn91mgyasn6x";
39+ };
40+ phases = "installPhase";
41+ installPhase = "ln -s $src $out";
42+ };
43+
44+ "argonaut-aeson-generic" = pkgs.stdenv.mkDerivation {
45+ name = "argonaut-aeson-generic";
46+ version = "3e388500811ef4b6718fc776789f3be050ad7b57";
47+ src = pkgs.fetchgit {
48+ url = "https://github.com/ilyakooo0/purescript-argonaut-aeson-generic.git";
49+ rev = "3e388500811ef4b6718fc776789f3be050ad7b57";
50+ sha256 = "0yhcxxz5lpgwxxsx93kmr884rk5nrvgy7lmpaixazqps2a2q0fhc";
51+ };
52+ phases = "installPhase";
53+ installPhase = "ln -s $src $out";
54+ };
55+
56+ "argonaut-codecs" = pkgs.stdenv.mkDerivation {
57+ name = "argonaut-codecs";
58+ version = "v9.0.0";
59+ src = pkgs.fetchgit {
60+ url = "https://github.com/purescript-contrib/purescript-argonaut-codecs.git";
61+ rev = "176a5dddae28fda9a2ff31ed4bf1efcc148513a4";
62+ sha256 = "08ys445222syysxh24la8bc8l20lwwqi4vdfa3ph2a60l1lx3kp8";
63+ };
64+ phases = "installPhase";
65+ installPhase = "ln -s $src $out";
66+ };
67+
68+ "argonaut-core" = pkgs.stdenv.mkDerivation {
69+ name = "argonaut-core";
70+ version = "v7.0.0";
71+ src = pkgs.fetchgit {
72+ url = "https://github.com/purescript-contrib/purescript-argonaut-core.git";
73+ rev = "68da81dd80ec36d3b013eff46dc067a972c22e5d";
74+ sha256 = "0hxl17ddbflkk0hchjgk5xj6j9fwp3b182w4g073p0dwscdl4f08";
75+ };
76+ phases = "installPhase";
77+ installPhase = "ln -s $src $out";
78+ };
79+
80+ "argonaut-generic" = pkgs.stdenv.mkDerivation {
81+ name = "argonaut-generic";
82+ version = "v8.0.0";
83+ src = pkgs.fetchgit {
84+ url = "https://github.com/purescript-contrib/purescript-argonaut-generic.git";
85+ rev = "2df4080f036762df91a24b22842e389395ef0bdd";
86+ sha256 = "0f3bkmv37nk89vscvivdr971sjydqiw7lwk9hfdfms05id8jdjkw";
87+ };
88+ phases = "installPhase";
89+ installPhase = "ln -s $src $out";
90+ };
91+
92+ "argonaut-traversals" = pkgs.stdenv.mkDerivation {
93+ name = "argonaut-traversals";
94+ version = "v10.0.0";
95+ src = pkgs.fetchgit {
96+ url = "https://github.com/purescript-contrib/purescript-argonaut-traversals.git";
97+ rev = "8d2403d8d57afb568933dbb36063d5670ce770a0";
98+ sha256 = "0v965bcl1hdp1hacbzxcm35kxxclixj0kpsdm816gs7m548z6l43";
99+ };
100+ phases = "installPhase";
101+ installPhase = "ln -s $src $out";
102+ };
103+
104+ "arraybuffer" = pkgs.stdenv.mkDerivation {
105+ name = "arraybuffer";
106+ version = "v13.0.0";
107+ src = pkgs.fetchgit {
108+ url = "https://github.com/purescript-contrib/purescript-arraybuffer.git";
109+ rev = "3b5ba3040f060057e864805546a50f319853517d";
110+ sha256 = "0cfi15r95zd7ikvs8v3pf2i3rzxjqxk7209j96d8qs6jzqlypbwd";
111+ };
112+ phases = "installPhase";
113+ installPhase = "ln -s $src $out";
114+ };
115+
116+ "arraybuffer-types" = pkgs.stdenv.mkDerivation {
117+ name = "arraybuffer-types";
118+ version = "v3.0.2";
119+ src = pkgs.fetchgit {
120+ url = "https://github.com/purescript-contrib/purescript-arraybuffer-types.git";
121+ rev = "9b0b7a0f9ee034e039f3d3a2a9c3f74eb7c9264a";
122+ sha256 = "1q3111jk6jj64bxy86lc7ik6q5mgdz87bc086wj5rm57dmlivlxx";
123+ };
124+ phases = "installPhase";
125+ installPhase = "ln -s $src $out";
126+ };
127+
128+ "arrays" = pkgs.stdenv.mkDerivation {
129+ name = "arrays";
130+ version = "v7.0.0";
131+ src = pkgs.fetchgit {
132+ url = "https://github.com/purescript/purescript-arrays.git";
133+ rev = "d20bae2f76db6cf29b7b75e26e82b8a54c32295e";
134+ sha256 = "1ciz796yrdfnqiskjjhh6r3bn9mks1dm5zin7kwzh1nfy1i4w9pz";
135+ };
136+ phases = "installPhase";
137+ installPhase = "ln -s $src $out";
138+ };
139+
140+ "assert" = pkgs.stdenv.mkDerivation {
141+ name = "assert";
142+ version = "v6.0.0";
143+ src = pkgs.fetchgit {
144+ url = "https://github.com/purescript/purescript-assert.git";
145+ rev = "27c0edb57d2ee497eb5fab664f5601c35b613eda";
146+ sha256 = "02qpcsijil64qq4kcikv2ynxl85zkryvv0vmzjm6752956ymzi0j";
147+ };
148+ phases = "installPhase";
149+ installPhase = "ln -s $src $out";
150+ };
151+
152+ "avar" = pkgs.stdenv.mkDerivation {
153+ name = "avar";
154+ version = "v5.0.0";
155+ src = pkgs.fetchgit {
156+ url = "https://github.com/purescript-contrib/purescript-avar.git";
157+ rev = "d00f5784d9cc8f079babd62740f5c52b87e5caa5";
158+ sha256 = "132g0ccmjr8328xpaycww8b5wmx1vi3li4irxxqcjk5wi47i8c9h";
159+ };
160+ phases = "installPhase";
161+ installPhase = "ln -s $src $out";
162+ };
163+
164+ "bifunctors" = pkgs.stdenv.mkDerivation {
165+ name = "bifunctors";
166+ version = "v6.0.0";
167+ src = pkgs.fetchgit {
168+ url = "https://github.com/purescript/purescript-bifunctors.git";
169+ rev = "16ba2fb6dd7f05528ebd9e2f9ca3a068b325e5b3";
170+ sha256 = "1qz5aaiq5w4g1rhjb63z47h6nqhw8hw23x1zw5alam047pq4vfkg";
171+ };
172+ phases = "installPhase";
173+ installPhase = "ln -s $src $out";
174+ };
175+
176+ "catenable-lists" = pkgs.stdenv.mkDerivation {
177+ name = "catenable-lists";
178+ version = "v7.0.0";
179+ src = pkgs.fetchgit {
180+ url = "https://github.com/purescript/purescript-catenable-lists.git";
181+ rev = "09abe1f4888bc00841ad2b59e56a9e7ce7ebd4ab";
182+ sha256 = "0fn6caspdnb0nrlj31sy7d5hxrhndfz7a2b9wfkxf5bv5vpjyawb";
183+ };
184+ phases = "installPhase";
185+ installPhase = "ln -s $src $out";
186+ };
187+
188+ "console" = pkgs.stdenv.mkDerivation {
189+ name = "console";
190+ version = "v6.0.0";
191+ src = pkgs.fetchgit {
192+ url = "https://github.com/purescript/purescript-console.git";
193+ rev = "3b83d7b792d03872afeea5e62b4f686ab0f09842";
194+ sha256 = "0fr5l1myhscp910mybp04cg6g8f2hy3ikjfc8fkqlb2dm2cqzdfs";
195+ };
196+ phases = "installPhase";
197+ installPhase = "ln -s $src $out";
198+ };
199+
200+ "const" = pkgs.stdenv.mkDerivation {
201+ name = "const";
202+ version = "v6.0.0";
203+ src = pkgs.fetchgit {
204+ url = "https://github.com/purescript/purescript-const.git";
205+ rev = "ab9570cf2b6e67f7e441178211db1231cfd75c37";
206+ sha256 = "0mcpwqqf5bcwxlzk53smvsjjz1ymlnq0ypphg6sc83ibw70g64f6";
207+ };
208+ phases = "installPhase";
209+ installPhase = "ln -s $src $out";
210+ };
211+
212+ "contravariant" = pkgs.stdenv.mkDerivation {
213+ name = "contravariant";
214+ version = "v6.0.0";
215+ src = pkgs.fetchgit {
216+ url = "https://github.com/purescript/purescript-contravariant.git";
217+ rev = "9ad3e105b8855bcc25f4e0893c784789d05a58de";
218+ sha256 = "1xkd3rfs8v20w7mj6sj6dmhfb2vb1zpmjv245xj1rahk3g16qm7m";
219+ };
220+ phases = "installPhase";
221+ installPhase = "ln -s $src $out";
222+ };
223+
224+ "control" = pkgs.stdenv.mkDerivation {
225+ name = "control";
226+ version = "v6.0.0";
227+ src = pkgs.fetchgit {
228+ url = "https://github.com/purescript/purescript-control.git";
229+ rev = "a6033808790879a17b2729e73747a9ed3fb2264e";
230+ sha256 = "05sdgywprwpav62d2bvlb80yd39brxhnmhhl1f116mm9hw5clqia";
231+ };
232+ phases = "installPhase";
233+ installPhase = "ln -s $src $out";
234+ };
235+
236+ "datetime" = pkgs.stdenv.mkDerivation {
237+ name = "datetime";
238+ version = "v6.0.0";
239+ src = pkgs.fetchgit {
240+ url = "https://github.com/purescript/purescript-datetime.git";
241+ rev = "a6a0cf1b0324964ad1854bc3377ed8766ba90e6f";
242+ sha256 = "1idjljxy8rjlw3wiypk1c9cc1fc4g9kf7drzdy6a0yjdg7504gad";
243+ };
244+ phases = "installPhase";
245+ installPhase = "ln -s $src $out";
246+ };
247+
248+ "datetime-parsing" = pkgs.stdenv.mkDerivation {
249+ name = "datetime-parsing";
250+ version = "v0.2.0";
251+ src = pkgs.fetchgit {
252+ url = "https://github.com/flounders/purescript-datetime-parsing.git";
253+ rev = "aa7d336c2681501dbe343adcbbf8f2ee51b23932";
254+ sha256 = "1w0lfs64qz1hs7zijyzpvqlp2z06wmbz4jp8cjsnw9yj46jsy8nh";
255+ };
256+ phases = "installPhase";
257+ installPhase = "ln -s $src $out";
258+ };
259+
260+ "distributive" = pkgs.stdenv.mkDerivation {
261+ name = "distributive";
262+ version = "v6.0.0";
263+ src = pkgs.fetchgit {
264+ url = "https://github.com/purescript/purescript-distributive.git";
265+ rev = "6005e513642e855ebf6f884d24a35c2803ca252a";
266+ sha256 = "0x6cfsx9ff66kvw9l10pxd5vv16r91mmfxrfc68w1xfdfi81lhdx";
267+ };
268+ phases = "installPhase";
269+ installPhase = "ln -s $src $out";
270+ };
271+
272+ "effect" = pkgs.stdenv.mkDerivation {
273+ name = "effect";
274+ version = "v4.0.0";
275+ src = pkgs.fetchgit {
276+ url = "https://github.com/purescript/purescript-effect.git";
277+ rev = "a192ddb923027d426d6ea3d8deb030c9aa7c7dda";
278+ sha256 = "0aa10lc6h9mlf4xf3g3ziig7v6kxdqvbh20kma8ay59w0b1bhmj1";
279+ };
280+ phases = "installPhase";
281+ installPhase = "ln -s $src $out";
282+ };
283+
284+ "either" = pkgs.stdenv.mkDerivation {
285+ name = "either";
286+ version = "v6.1.0";
287+ src = pkgs.fetchgit {
288+ url = "https://github.com/purescript/purescript-either.git";
289+ rev = "af655a04ed2fd694b6688af39ee20d7907ad0763";
290+ sha256 = "05zps4klvgmvlm06f4hrycssm8q0pysbqnjsrk26lfvmid6mmg63";
291+ };
292+ phases = "installPhase";
293+ installPhase = "ln -s $src $out";
294+ };
295+
296+ "enums" = pkgs.stdenv.mkDerivation {
297+ name = "enums";
298+ version = "v6.0.0";
299+ src = pkgs.fetchgit {
300+ url = "https://github.com/purescript/purescript-enums.git";
301+ rev = "bae47961d401f9acf88da38f32e87403e5f0cf2f";
302+ sha256 = "08sl5q07hv6v2008dcpg4mxiqwk9z0fhq67k0bgkxvlbsmar7khg";
303+ };
304+ phases = "installPhase";
305+ installPhase = "ln -s $src $out";
306+ };
307+
308+ "exceptions" = pkgs.stdenv.mkDerivation {
309+ name = "exceptions";
310+ version = "v6.0.0";
311+ src = pkgs.fetchgit {
312+ url = "https://github.com/purescript/purescript-exceptions.git";
313+ rev = "afab3c07c820bb49b6c5be50049db46a964a6161";
314+ sha256 = "04xrbrcjwsv8gj465ygrlqhv1majxmr6m242iazg6apxlr89hgvg";
315+ };
316+ phases = "installPhase";
317+ installPhase = "ln -s $src $out";
318+ };
319+
320+ "exists" = pkgs.stdenv.mkDerivation {
321+ name = "exists";
322+ version = "v6.0.0";
323+ src = pkgs.fetchgit {
324+ url = "https://github.com/purescript/purescript-exists.git";
325+ rev = "f765b4ace7869c27b9c05949e18c843881f9173b";
326+ sha256 = "0xnxi8fsmi15wrpq5d99gg94glk8a45hpx7pf4pmxg5r6rn1vjvx";
327+ };
328+ phases = "installPhase";
329+ installPhase = "ln -s $src $out";
330+ };
331+
332+ "float32" = pkgs.stdenv.mkDerivation {
333+ name = "float32";
334+ version = "v2.0.0";
335+ src = pkgs.fetchgit {
336+ url = "https://github.com/purescript-contrib/purescript-float32.git";
337+ rev = "3b70984d823c12c1b84a45a9b3d45199a4fcc67d";
338+ sha256 = "0a1lvga6bbhbb8g3crp3fr0kmpkzjmffhfq71ig6flin13xijgys";
339+ };
340+ phases = "installPhase";
341+ installPhase = "ln -s $src $out";
342+ };
343+
344+ "foldable-traversable" = pkgs.stdenv.mkDerivation {
345+ name = "foldable-traversable";
346+ version = "v6.0.0";
347+ src = pkgs.fetchgit {
348+ url = "https://github.com/purescript/purescript-foldable-traversable.git";
349+ rev = "b3926f870532d287ea59e2d5cd3873b81ef2a93a";
350+ sha256 = "0xg8qvyc6r9wqgy7wnw1rjqljl4wpgdrkxsm5x9rsagj2k5brxip";
351+ };
352+ phases = "installPhase";
353+ installPhase = "ln -s $src $out";
354+ };
355+
356+ "foreign" = pkgs.stdenv.mkDerivation {
357+ name = "foreign";
358+ version = "v7.0.0";
359+ src = pkgs.fetchgit {
360+ url = "https://github.com/purescript/purescript-foreign.git";
361+ rev = "2dd222d1ec7363fa0a0a7adb0d8eaf81bb7006dd";
362+ sha256 = "0ycjaal8b2rsg3zl3b7acv166vjfdvziiza3fs8nhfw0rx0xmm1m";
363+ };
364+ phases = "installPhase";
365+ installPhase = "ln -s $src $out";
366+ };
367+
368+ "foreign-object" = pkgs.stdenv.mkDerivation {
369+ name = "foreign-object";
370+ version = "v4.0.0";
371+ src = pkgs.fetchgit {
372+ url = "https://github.com/purescript/purescript-foreign-object.git";
373+ rev = "28a635827a9a6c251df73f68874070d51fe9f756";
374+ sha256 = "0ql0vgndcb5dqaqz81mvrqkrl5c2rlgxpydgdiiaxmmfxvxwi439";
375+ };
376+ phases = "installPhase";
377+ installPhase = "ln -s $src $out";
378+ };
379+
380+ "free" = pkgs.stdenv.mkDerivation {
381+ name = "free";
382+ version = "v7.0.0";
383+ src = pkgs.fetchgit {
384+ url = "https://github.com/purescript/purescript-free.git";
385+ rev = "e2d8fa8023a864363857834e11393483bced5e38";
386+ sha256 = "0gyy0k297m26gw76w7kx8k1zjczlqbqb3nmh2h4gb3r84gl05g6r";
387+ };
388+ phases = "installPhase";
389+ installPhase = "ln -s $src $out";
390+ };
391+
392+ "functions" = pkgs.stdenv.mkDerivation {
393+ name = "functions";
394+ version = "v6.0.0";
395+ src = pkgs.fetchgit {
396+ url = "https://github.com/purescript/purescript-functions.git";
397+ rev = "f626f20580483977c5b27a01aac6471e28aff367";
398+ sha256 = "1bsf2y8hx103a92yrc6m05q2dv51ckag1srd7q5n9vaf2k9byrj9";
399+ };
400+ phases = "installPhase";
401+ installPhase = "ln -s $src $out";
402+ };
403+
404+ "functors" = pkgs.stdenv.mkDerivation {
405+ name = "functors";
406+ version = "v5.0.0";
407+ src = pkgs.fetchgit {
408+ url = "https://github.com/purescript/purescript-functors.git";
409+ rev = "022ffd7a2a7ec12080314f3d217b400674a247b4";
410+ sha256 = "1pnw3r1nk0rx8mrw3ajjml40zvx9v26qrqwj77pz7hpwxigxfbff";
411+ };
412+ phases = "installPhase";
413+ installPhase = "ln -s $src $out";
414+ };
415+
416+ "gen" = pkgs.stdenv.mkDerivation {
417+ name = "gen";
418+ version = "v4.0.0";
419+ src = pkgs.fetchgit {
420+ url = "https://github.com/purescript/purescript-gen.git";
421+ rev = "9fbcc2a1261c32e30d79c5418edef4d96fe76931";
422+ sha256 = "0kajzcp9a8dmqvb3ga27hlf18m2smbp98a0bmzzb9vv156ckw0b4";
423+ };
424+ phases = "installPhase";
425+ installPhase = "ln -s $src $out";
426+ };
427+
428+ "identity" = pkgs.stdenv.mkDerivation {
429+ name = "identity";
430+ version = "v6.0.0";
431+ src = pkgs.fetchgit {
432+ url = "https://github.com/purescript/purescript-identity.git";
433+ rev = "ef6768f8a52ab0bc943a85f5761ba07c257f639f";
434+ sha256 = "1lh0pkwwdyd8q9bgf4l1m96gdnardki4r2s359cnhrwp94b43fyr";
435+ };
436+ phases = "installPhase";
437+ installPhase = "ln -s $src $out";
438+ };
439+
440+ "integers" = pkgs.stdenv.mkDerivation {
441+ name = "integers";
442+ version = "v6.0.0";
443+ src = pkgs.fetchgit {
444+ url = "https://github.com/purescript/purescript-integers.git";
445+ rev = "54d712b25c594833083d15dc9ff2418eb9c52822";
446+ sha256 = "04j9sqvkgyxxvbm8jfc2118wzmgswn8jva9fysgbsnmsg9vcxfm6";
447+ };
448+ phases = "installPhase";
449+ installPhase = "ln -s $src $out";
450+ };
451+
452+ "invariant" = pkgs.stdenv.mkDerivation {
453+ name = "invariant";
454+ version = "v6.0.0";
455+ src = pkgs.fetchgit {
456+ url = "https://github.com/purescript/purescript-invariant.git";
457+ rev = "1d2a196d51e90623adb88496c2cfd759c6736894";
458+ sha256 = "07rqag47ykdiqc5yfbc1a64ijaqliljhcw1vgbv81m7ljzzd2xna";
459+ };
460+ phases = "installPhase";
461+ installPhase = "ln -s $src $out";
462+ };
463+
464+ "js-date" = pkgs.stdenv.mkDerivation {
465+ name = "js-date";
466+ version = "v8.0.0";
467+ src = pkgs.fetchgit {
468+ url = "https://github.com/purescript-contrib/purescript-js-date.git";
469+ rev = "1ea020316946cc4b87195bca9c54d0c16abaa490";
470+ sha256 = "03535g8hc4bzyzig25hf75dls9ypsgrdk2nc45h8zw4xyy4ha0gz";
471+ };
472+ phases = "installPhase";
473+ installPhase = "ln -s $src $out";
474+ };
475+
476+ "js-timers" = pkgs.stdenv.mkDerivation {
477+ name = "js-timers";
478+ version = "v6.1.0";
479+ src = pkgs.fetchgit {
480+ url = "https://github.com/purescript-contrib/purescript-js-timers.git";
481+ rev = "7cb728b3e6dc29f355143617e6e9ac770ecd9273";
482+ sha256 = "0dm933kqhwgmpkylgrlpjplidn8biic8jlzs4l4nny4a1z20mr61";
483+ };
484+ phases = "installPhase";
485+ installPhase = "ln -s $src $out";
486+ };
487+
488+ "lazy" = pkgs.stdenv.mkDerivation {
489+ name = "lazy";
490+ version = "v6.0.0";
491+ src = pkgs.fetchgit {
492+ url = "https://github.com/purescript/purescript-lazy.git";
493+ rev = "48347841226b27af5205a1a8ec71e27a93ce86fd";
494+ sha256 = "0dxlc3b2bdqsri45i7a9bvwvv0gg43cc1gq61zi41f290a29ny2q";
495+ };
496+ phases = "installPhase";
497+ installPhase = "ln -s $src $out";
498+ };
499+
500+ "lcg" = pkgs.stdenv.mkDerivation {
501+ name = "lcg";
502+ version = "v4.0.0";
503+ src = pkgs.fetchgit {
504+ url = "https://github.com/purescript/purescript-lcg.git";
505+ rev = "67c6c6483a563a59ae036d9dca0f1be2835326a5";
506+ sha256 = "1shzn6zvc1cxd7v0bvfsk7x3xf59vxby8c5lfjvd746r6396zn65";
507+ };
508+ phases = "installPhase";
509+ installPhase = "ln -s $src $out";
510+ };
511+
512+ "lists" = pkgs.stdenv.mkDerivation {
513+ name = "lists";
514+ version = "v7.0.0";
515+ src = pkgs.fetchgit {
516+ url = "https://github.com/purescript/purescript-lists.git";
517+ rev = "b113451e5b41cad87d669a3165f955c71cd863e2";
518+ sha256 = "1mg7vy44k8jlqkri7x4ikciixx92b17wi35887x09dwdsicjf0sx";
519+ };
520+ phases = "installPhase";
521+ installPhase = "ln -s $src $out";
522+ };
523+
524+ "literals" = pkgs.stdenv.mkDerivation {
525+ name = "literals";
526+ version = "6875fb28026595cfb780318305a77e79b098bb01";
527+ src = pkgs.fetchgit {
528+ url = "https://github.com/ilyakooo0/purescript-literals.git";
529+ rev = "6875fb28026595cfb780318305a77e79b098bb01";
530+ sha256 = "0s45cdgpdhni3rj7irr8pch46yxwmdcmj2nrg1vpkvygydkikdmb";
531+ };
532+ phases = "installPhase";
533+ installPhase = "ln -s $src $out";
534+ };
535+
536+ "maybe" = pkgs.stdenv.mkDerivation {
537+ name = "maybe";
538+ version = "v6.0.0";
539+ src = pkgs.fetchgit {
540+ url = "https://github.com/purescript/purescript-maybe.git";
541+ rev = "c6f98ac1088766287106c5d9c8e30e7648d36786";
542+ sha256 = "0n33g8c579vcs06ii0r7f14jjdwzjw7p583w4nmrv9h442q2cvlz";
543+ };
544+ phases = "installPhase";
545+ installPhase = "ln -s $src $out";
546+ };
547+
548+ "media-types" = pkgs.stdenv.mkDerivation {
549+ name = "media-types";
550+ version = "v6.0.0";
551+ src = pkgs.fetchgit {
552+ url = "https://github.com/purescript-contrib/purescript-media-types.git";
553+ rev = "af853de226592f319a953637069a943dd261cba3";
554+ sha256 = "0bxpsd2yw3zg58ay649v3xld7n17n7j7n9y8l841cjih9bc7ccxx";
555+ };
556+ phases = "installPhase";
557+ installPhase = "ln -s $src $out";
558+ };
559+
560+ "newtype" = pkgs.stdenv.mkDerivation {
561+ name = "newtype";
562+ version = "v5.0.0";
563+ src = pkgs.fetchgit {
564+ url = "https://github.com/purescript/purescript-newtype.git";
565+ rev = "29d8e6dd77aec2c975c948364ec3faf26e14ee7b";
566+ sha256 = "0kfc644zn2f9rpx8fy4gjvmz04k9mv1c2xrqis8m3s0ydnhbffd7";
567+ };
568+ phases = "installPhase";
569+ installPhase = "ln -s $src $out";
570+ };
571+
572+ "nonempty" = pkgs.stdenv.mkDerivation {
573+ name = "nonempty";
574+ version = "v7.0.0";
575+ src = pkgs.fetchgit {
576+ url = "https://github.com/purescript/purescript-nonempty.git";
577+ rev = "28150ecc7419238b187abd609a92a645273348bb";
578+ sha256 = "1mwdc2sny2ygp67kyk7h2493vq7syf7j18s3d9a5gwf1y7jlf7gh";
579+ };
580+ phases = "installPhase";
581+ installPhase = "ln -s $src $out";
582+ };
583+
584+ "now" = pkgs.stdenv.mkDerivation {
585+ name = "now";
586+ version = "v6.0.0";
587+ src = pkgs.fetchgit {
588+ url = "https://github.com/purescript-contrib/purescript-now.git";
589+ rev = "b5ffed2381e5fefc063f484e607e8499e79eaf32";
590+ sha256 = "01khmqs4iz7dhlvd43zxj19q0c0vvqf1m128vgvgxz5mv430zfgr";
591+ };
592+ phases = "installPhase";
593+ installPhase = "ln -s $src $out";
594+ };
595+
596+ "nullable" = pkgs.stdenv.mkDerivation {
597+ name = "nullable";
598+ version = "v6.0.0";
599+ src = pkgs.fetchgit {
600+ url = "https://github.com/purescript-contrib/purescript-nullable.git";
601+ rev = "3202744c6c65e8d1fbba7f4256a1c482078e7fb5";
602+ sha256 = "10s3b54pjmr2rxlyzvc8yc99k1dpn0qrijnc4y65yj5z6bxf2791";
603+ };
604+ phases = "installPhase";
605+ installPhase = "ln -s $src $out";
606+ };
607+
608+ "numbers" = pkgs.stdenv.mkDerivation {
609+ name = "numbers";
610+ version = "v9.0.0";
611+ src = pkgs.fetchgit {
612+ url = "https://github.com/purescript/purescript-numbers.git";
613+ rev = "2a53528f18f9415334bae28e7bb3cf3be86342c2";
614+ sha256 = "1h4v6ir1hq6gvkk0kla38vlcd6bv73xkc8pv71jygwqxrdwfxxgw";
615+ };
616+ phases = "installPhase";
617+ installPhase = "ln -s $src $out";
618+ };
619+
620+ "ordered-collections" = pkgs.stdenv.mkDerivation {
621+ name = "ordered-collections";
622+ version = "v3.0.0";
623+ src = pkgs.fetchgit {
624+ url = "https://github.com/purescript/purescript-ordered-collections.git";
625+ rev = "9826b7632d0d0a691173bde308a634195f42a419";
626+ sha256 = "1wk8mcn1zsxi0yk9ybas2v7m0drb492806gld1xxxic8x1i19ws0";
627+ };
628+ phases = "installPhase";
629+ installPhase = "ln -s $src $out";
630+ };
631+
632+ "orders" = pkgs.stdenv.mkDerivation {
633+ name = "orders";
634+ version = "v6.0.0";
635+ src = pkgs.fetchgit {
636+ url = "https://github.com/purescript/purescript-orders.git";
637+ rev = "f86db621ec5eef1274145f8b1fd8ebbfe0ed4a2c";
638+ sha256 = "14fjls3v14ia6fr2w4p0i5dqv10zk343wg28m4c77a17jmvbs9r4";
639+ };
640+ phases = "installPhase";
641+ installPhase = "ln -s $src $out";
642+ };
643+
644+ "parallel" = pkgs.stdenv.mkDerivation {
645+ name = "parallel";
646+ version = "v6.0.0";
647+ src = pkgs.fetchgit {
648+ url = "https://github.com/purescript/purescript-parallel.git";
649+ rev = "85290dca837771ac4870071008c933d315ef678f";
650+ sha256 = "0bpwvzq4dn7vx5mfj12w1zvvnamc6w2c45c2v54b9yw36snnwpcf";
651+ };
652+ phases = "installPhase";
653+ installPhase = "ln -s $src $out";
654+ };
655+
656+ "parsing" = pkgs.stdenv.mkDerivation {
657+ name = "parsing";
658+ version = "v9.1.0";
659+ src = pkgs.fetchgit {
660+ url = "https://github.com/purescript-contrib/purescript-parsing.git";
661+ rev = "44ef16b7cfb7cedc3d518c00ef10c6cb73ff4fc8";
662+ sha256 = "1wkk3p1w2k1cvby4airyxgavk1djfzvzc2ch6b8951b592rj8lkr";
663+ };
664+ phases = "installPhase";
665+ installPhase = "ln -s $src $out";
666+ };
667+
668+ "partial" = pkgs.stdenv.mkDerivation {
669+ name = "partial";
670+ version = "v4.0.0";
671+ src = pkgs.fetchgit {
672+ url = "https://github.com/purescript/purescript-partial.git";
673+ rev = "0fa0646f5ea1ec5f0c46dcbd770c705a6c9ad3ec";
674+ sha256 = "04s1h0r3slyd8kcamhqqrr6piksl9y76nmf2418j0ifhp16qwxmm";
675+ };
676+ phases = "installPhase";
677+ installPhase = "ln -s $src $out";
678+ };
679+
680+ "prelude" = pkgs.stdenv.mkDerivation {
681+ name = "prelude";
682+ version = "v6.0.0";
683+ src = pkgs.fetchgit {
684+ url = "https://github.com/purescript/purescript-prelude.git";
685+ rev = "32787f4399c92459c41602131a5858559eb868c5";
686+ sha256 = "0jkbckxw2640gmfi2f8bpf2zwnay2dxy8n24rvxl3w3dihcgd9qc";
687+ };
688+ phases = "installPhase";
689+ installPhase = "ln -s $src $out";
690+ };
691+
692+ "profunctor" = pkgs.stdenv.mkDerivation {
693+ name = "profunctor";
694+ version = "v6.0.0";
695+ src = pkgs.fetchgit {
696+ url = "https://github.com/purescript/purescript-profunctor.git";
697+ rev = "0a966a14e7b0c827d44657dc1710cdc712d2e034";
698+ sha256 = "07rhk8micbc74my6s53xbj2smvvwah2w1drqrcmcnncxdks3lqg3";
699+ };
700+ phases = "installPhase";
701+ installPhase = "ln -s $src $out";
702+ };
703+
704+ "profunctor-lenses" = pkgs.stdenv.mkDerivation {
705+ name = "profunctor-lenses";
706+ version = "v8.0.0";
707+ src = pkgs.fetchgit {
708+ url = "https://github.com/purescript-contrib/purescript-profunctor-lenses.git";
709+ rev = "973d567afe458fd802cf4f0d9725b6dc35ad9297";
710+ sha256 = "0axz7nznn12iqh6sn9qjg6i8qglpdsqgkp30ndwdj98czcnbnybv";
711+ };
712+ phases = "installPhase";
713+ installPhase = "ln -s $src $out";
714+ };
715+
716+ "psci-support" = pkgs.stdenv.mkDerivation {
717+ name = "psci-support";
718+ version = "v6.0.0";
719+ src = pkgs.fetchgit {
720+ url = "https://github.com/purescript/purescript-psci-support.git";
721+ rev = "897cdb543548cb6078d69b6413b54841404eda72";
722+ sha256 = "1ix53r8avkn3fw72mngwzw7v6c6mv7j4miw5mrgjrh9hb8p2ydl1";
723+ };
724+ phases = "installPhase";
725+ installPhase = "ln -s $src $out";
726+ };
727+
728+ "quickcheck" = pkgs.stdenv.mkDerivation {
729+ name = "quickcheck";
730+ version = "v8.0.1";
731+ src = pkgs.fetchgit {
732+ url = "https://github.com/purescript/purescript-quickcheck.git";
733+ rev = "bf5029f97e6c0d7552d3a08d2ab793a19e2c5e3d";
734+ sha256 = "142dvh57fl8b6i7mm37a38v7vkc1znbqz6l6wqa704m53hkikvyd";
735+ };
736+ phases = "installPhase";
737+ installPhase = "ln -s $src $out";
738+ };
739+
740+ "random" = pkgs.stdenv.mkDerivation {
741+ name = "random";
742+ version = "v6.0.0";
743+ src = pkgs.fetchgit {
744+ url = "https://github.com/purescript/purescript-random.git";
745+ rev = "9540bc965a9596da02fefd9949418bb19c92533a";
746+ sha256 = "0qz14qviz5053j9h1jwpk0gnn692hcdx6fp90wckzrnw31d53174";
747+ };
748+ phases = "installPhase";
749+ installPhase = "ln -s $src $out";
750+ };
751+
752+ "record" = pkgs.stdenv.mkDerivation {
753+ name = "record";
754+ version = "v4.0.0";
755+ src = pkgs.fetchgit {
756+ url = "https://github.com/purescript/purescript-record.git";
757+ rev = "c89cd1ada6b636692571fc374196b1c39c4c9f70";
758+ sha256 = "1g7s2h1as5cz824wpm0jhjprrh66shha5i4gq37q73yw0s5p2ahm";
759+ };
760+ phases = "installPhase";
761+ installPhase = "ln -s $src $out";
762+ };
763+
764+ "refs" = pkgs.stdenv.mkDerivation {
765+ name = "refs";
766+ version = "v6.0.0";
767+ src = pkgs.fetchgit {
768+ url = "https://github.com/purescript/purescript-refs.git";
769+ rev = "f8e6216da4cb9309fde1f20cd6f69ac3a3b7f9e8";
770+ sha256 = "09bvfxhjfwfwv55py45s71maazwrr68k0rk4v8ynfqv91h34319h";
771+ };
772+ phases = "installPhase";
773+ installPhase = "ln -s $src $out";
774+ };
775+
776+ "run" = pkgs.stdenv.mkDerivation {
777+ name = "run";
778+ version = "v5.0.0";
779+ src = pkgs.fetchgit {
780+ url = "https://github.com/natefaubion/purescript-run.git";
781+ rev = "abec7c343e92154d44b9dafd52b91ee82d32a870";
782+ sha256 = "059xhjxjfs1w2hmgld53kciyfws3pmjyz75w836ph99rqr4aczny";
783+ };
784+ phases = "installPhase";
785+ installPhase = "ln -s $src $out";
786+ };
787+
788+ "safe-coerce" = pkgs.stdenv.mkDerivation {
789+ name = "safe-coerce";
790+ version = "v2.0.0";
791+ src = pkgs.fetchgit {
792+ url = "https://github.com/purescript/purescript-safe-coerce.git";
793+ rev = "7fa799ae80a38b8d948efcb52608e58e198b3da7";
794+ sha256 = "00m4l733gpl0153cbl6n5kly7jr8ids399apza2rbczif40brp9g";
795+ };
796+ phases = "installPhase";
797+ installPhase = "ln -s $src $out";
798+ };
799+
800+ "st" = pkgs.stdenv.mkDerivation {
801+ name = "st";
802+ version = "v6.0.0";
803+ src = pkgs.fetchgit {
804+ url = "https://github.com/purescript/purescript-st.git";
805+ rev = "2cc7ae1c3318a303378c4a9f3fa0f10ee7cc3589";
806+ sha256 = "1ykk27zn03svfsv2s1mf88d6x3q6qhb9bwjzgals79krw8w0aiyl";
807+ };
808+ phases = "installPhase";
809+ installPhase = "ln -s $src $out";
810+ };
811+
812+ "strings" = pkgs.stdenv.mkDerivation {
813+ name = "strings";
814+ version = "v6.0.0";
815+ src = pkgs.fetchgit {
816+ url = "https://github.com/purescript/purescript-strings.git";
817+ rev = "4bc6954448d056f8aa7a659695a6ad60ad4fdf19";
818+ sha256 = "101va3rawcn5inp20krfg192bbjbvm27xfzwwc1inb2ya0m98amg";
819+ };
820+ phases = "installPhase";
821+ installPhase = "ln -s $src $out";
822+ };
823+
824+ "tailrec" = pkgs.stdenv.mkDerivation {
825+ name = "tailrec";
826+ version = "v6.0.0";
827+ src = pkgs.fetchgit {
828+ url = "https://github.com/purescript/purescript-tailrec.git";
829+ rev = "5e2104aa734b31a17074cc805bf087d72b65afd1";
830+ sha256 = "0vc3dpsd2xxz694zlm75nx1cn6c6f29nzkb8xlxkk6ydw3wpsk3w";
831+ };
832+ phases = "installPhase";
833+ installPhase = "ln -s $src $out";
834+ };
835+
836+ "test-unit" = pkgs.stdenv.mkDerivation {
837+ name = "test-unit";
838+ version = "v17.0.0";
839+ src = pkgs.fetchgit {
840+ url = "https://github.com/bodil/purescript-test-unit.git";
841+ rev = "3112d7ebe06d467238058a6384dc75ffd960d335";
842+ sha256 = "02gfb4dqbj5v7dwifm8jhr0lh7lfp5hari5795w1z48wy3apnvvx";
843+ };
844+ phases = "installPhase";
845+ installPhase = "ln -s $src $out";
846+ };
847+
848+ "transformers" = pkgs.stdenv.mkDerivation {
849+ name = "transformers";
850+ version = "v6.0.0";
851+ src = pkgs.fetchgit {
852+ url = "https://github.com/purescript/purescript-transformers.git";
853+ rev = "be72ab52357d9a665cbf93d73ba1c07c4b0957ee";
854+ sha256 = "0ijrdsppl8vx0rlbwc9p0vjbmvwlcy4ia7xymvk6y34zbxzjlzm6";
855+ };
856+ phases = "installPhase";
857+ installPhase = "ln -s $src $out";
858+ };
859+
860+ "tuples" = pkgs.stdenv.mkDerivation {
861+ name = "tuples";
862+ version = "v7.0.0";
863+ src = pkgs.fetchgit {
864+ url = "https://github.com/purescript/purescript-tuples.git";
865+ rev = "4f52da2729b448c8564369378f1232d8d2dc1d8b";
866+ sha256 = "1m1ng0xxicb73945jymcl1hn2y2hmynlnmhb2k0kkn1jrjwgcc3d";
867+ };
868+ phases = "installPhase";
869+ installPhase = "ln -s $src $out";
870+ };
871+
872+ "type-equality" = pkgs.stdenv.mkDerivation {
873+ name = "type-equality";
874+ version = "v4.0.1";
875+ src = pkgs.fetchgit {
876+ url = "https://github.com/purescript/purescript-type-equality.git";
877+ rev = "0525b7d39e0fbd81b4209518139fb8ab02695774";
878+ sha256 = "1ass38jdycsjisdimdc4drg2w8vkkwp6lkvz3kvy7q0h98vdmlbr";
879+ };
880+ phases = "installPhase";
881+ installPhase = "ln -s $src $out";
882+ };
883+
884+ "typelevel-prelude" = pkgs.stdenv.mkDerivation {
885+ name = "typelevel-prelude";
886+ version = "v7.0.0";
887+ src = pkgs.fetchgit {
888+ url = "https://github.com/purescript/purescript-typelevel-prelude.git";
889+ rev = "dca2fe3c8cfd5527d4fe70c4bedfda30148405bf";
890+ sha256 = "0x86mrg33kpnrnsfp4p3c92j5lpyqzy87bxdynwf7smk3inqr2jc";
891+ };
892+ phases = "installPhase";
893+ installPhase = "ln -s $src $out";
894+ };
895+
896+ "uint" = pkgs.stdenv.mkDerivation {
897+ name = "uint";
898+ version = "v7.0.0";
899+ src = pkgs.fetchgit {
900+ url = "https://github.com/purescript-contrib/purescript-uint.git";
901+ rev = "9e4f76ffd5192472f75583844172fe8ab3c0cb9f";
902+ sha256 = "173bhrd006q53s7agwyasxhfbr89x9jpz5b47vm2fr74l3jcw3lq";
903+ };
904+ phases = "installPhase";
905+ installPhase = "ln -s $src $out";
906+ };
907+
908+ "undefined-is-not-a-problem" = pkgs.stdenv.mkDerivation {
909+ name = "undefined-is-not-a-problem";
910+ version = "v1.1.0";
911+ src = pkgs.fetchgit {
912+ url = "https://github.com/paluh/purescript-undefined-is-not-a-problem.git";
913+ rev = "8ac77ac8525343f7319cd48bf2ceb736286f3b27";
914+ sha256 = "1qv7gdyslfj86ga0a7gxkbpvykm3s1x4kzcm8zi75lhlvkpyjh3w";
915+ };
916+ phases = "installPhase";
917+ installPhase = "ln -s $src $out";
918+ };
919+
920+ "unfoldable" = pkgs.stdenv.mkDerivation {
921+ name = "unfoldable";
922+ version = "v6.0.0";
923+ src = pkgs.fetchgit {
924+ url = "https://github.com/purescript/purescript-unfoldable.git";
925+ rev = "493dfe04ed590e20d8f69079df2f58486882748d";
926+ sha256 = "15z2k639ph8wdkrc2y838m5am1z7szw2vqymmv021skzisyn7zwf";
927+ };
928+ phases = "installPhase";
929+ installPhase = "ln -s $src $out";
930+ };
931+
932+ "unicode" = pkgs.stdenv.mkDerivation {
933+ name = "unicode";
934+ version = "v6.0.0";
935+ src = pkgs.fetchgit {
936+ url = "https://github.com/purescript-contrib/purescript-unicode.git";
937+ rev = "6454d59d9e1fd1bc5a72e80e985d8282022a567a";
938+ sha256 = "0w2gsmqcy7pj5vd22qzpig20bdgzmbagyqxrg9mm1njjfsmcm8cv";
939+ };
940+ phases = "installPhase";
941+ installPhase = "ln -s $src $out";
942+ };
943+
944+ "unsafe-coerce" = pkgs.stdenv.mkDerivation {
945+ name = "unsafe-coerce";
946+ version = "v6.0.0";
947+ src = pkgs.fetchgit {
948+ url = "https://github.com/purescript/purescript-unsafe-coerce.git";
949+ rev = "ab956f82e66e633f647fb3098e8ddd3ec58d689f";
950+ sha256 = "0r6d3dx8jalfzvrvkagz9v05yxwkkhgbzlpswg4w1cyl03zjcla4";
951+ };
952+ phases = "installPhase";
953+ installPhase = "ln -s $src $out";
954+ };
955+
956+ "untagged-union" = pkgs.stdenv.mkDerivation {
957+ name = "untagged-union";
958+ version = "6c5bccef38696a16e86ba9a65cf778b4462c4a66";
959+ src = pkgs.fetchgit {
960+ url = "https://github.com/rowtype-yoga/purescript-untagged-union.git";
961+ rev = "6c5bccef38696a16e86ba9a65cf778b4462c4a66";
962+ sha256 = "0s4pik6xcr7zqhlrjxjqgzp8hfg09kgd58zq3xjj0inw9ly35ywn";
963+ };
964+ phases = "installPhase";
965+ installPhase = "ln -s $src $out";
966+ };
967+
968+ "variant" = pkgs.stdenv.mkDerivation {
969+ name = "variant";
970+ version = "v8.0.0";
971+ src = pkgs.fetchgit {
972+ url = "https://github.com/natefaubion/purescript-variant.git";
973+ rev = "8b2bd73a4202257d80a955c4dd36f6055f149823";
974+ sha256 = "18nyxnaqqg1zzydwd2hh9hbzr31j509g5yb1lnd0m60bma4l9h5g";
975+ };
976+ phases = "installPhase";
977+ installPhase = "ln -s $src $out";
978+ };
979+
980+ "web-dom" = pkgs.stdenv.mkDerivation {
981+ name = "web-dom";
982+ version = "v6.0.0";
983+ src = pkgs.fetchgit {
984+ url = "https://github.com/purescript-web/purescript-web-dom.git";
985+ rev = "568a1ee158b29e6e739e7a9aaed3e35ca4c4305a";
986+ sha256 = "0angs86ld0h3ld889ag55lh62101dfn3fknyqrfv0imgn40vwm44";
987+ };
988+ phases = "installPhase";
989+ installPhase = "ln -s $src $out";
990+ };
991+
992+ "web-events" = pkgs.stdenv.mkDerivation {
993+ name = "web-events";
994+ version = "v4.0.0";
995+ src = pkgs.fetchgit {
996+ url = "https://github.com/purescript-web/purescript-web-events.git";
997+ rev = "2124356117be7b764a2f3948032255ac4dab7051";
998+ sha256 = "0l47gsgj71x0gjbhjqwsar2y44ljhq3xa0nkgr1qvqxmcm00llqf";
999+ };
1000+ phases = "installPhase";
1001+ installPhase = "ln -s $src $out";
1002+ };
1003+
1004+ "web-file" = pkgs.stdenv.mkDerivation {
1005+ name = "web-file";
1006+ version = "v4.0.0";
1007+ src = pkgs.fetchgit {
1008+ url = "https://github.com/purescript-web/purescript-web-file.git";
1009+ rev = "023786ae62bbb8bf58156dd7f02011fa38221ef1";
1010+ sha256 = "1wjf1m5y2qsba83is297icv9zyl7jilxdga0192mm1rp0j16jjln";
1011+ };
1012+ phases = "installPhase";
1013+ installPhase = "ln -s $src $out";
1014+ };
1015+
1016+ "web-html" = pkgs.stdenv.mkDerivation {
1017+ name = "web-html";
1018+ version = "v4.0.0";
1019+ src = pkgs.fetchgit {
1020+ url = "https://github.com/purescript-web/purescript-web-html.git";
1021+ rev = "be189cf91b9a19cf493637423522e2fe4a0088cc";
1022+ sha256 = "0yspv6sci3mkflvqwf5jvz3a8nclmhbvazx9n34acyj3aai7k6bs";
1023+ };
1024+ phases = "installPhase";
1025+ installPhase = "ln -s $src $out";
1026+ };
1027+
1028+ "web-storage" = pkgs.stdenv.mkDerivation {
1029+ name = "web-storage";
1030+ version = "v5.0.0";
1031+ src = pkgs.fetchgit {
1032+ url = "https://github.com/purescript-web/purescript-web-storage.git";
1033+ rev = "6b74461e136755db70c271dc898d51776363d7e2";
1034+ sha256 = "0q1grh8cp6h1szsqg3xmwlzrc1bbz8yzlwxlcl1iym5mjiyzgkcs";
1035+ };
1036+ phases = "installPhase";
1037+ installPhase = "ln -s $src $out";
1038+ };
1039+
1040+ };
1041+
1042+ cpPackage = pkg:
1043+ let
1044+ target = ".spago/${pkg.name}/${pkg.version}";
1045+ in ''
1046+ if [ ! -e ${target} ]; then
1047+ echo "Installing ${target}."
1048+ mkdir -p ${target}
1049+ cp --no-preserve=mode,ownership,timestamp -r ${toString pkg.outPath}/* ${target}
1050+ else
1051+ echo "${target} already exists. Skipping."
1052+ fi
1053+ '';
1054+
1055+ getGlob = pkg: ''".spago/${pkg.name}/${pkg.version}/src/**/*.purs"'';
1056+
1057+ getStoreGlob = pkg: ''"${pkg.outPath}/src/**/*.purs"'';
1058+
1059+in {
1060+ inherit inputs;
1061+
1062+ installSpagoStyle = pkgs.writeShellScriptBin "install-spago-style" ''
1063+ set -e
1064+ echo installing dependencies...
1065+ ${builtins.toString (builtins.map cpPackage (builtins.attrValues inputs))}
1066+ echo "echo done."
1067+ '';
1068+
1069+ buildSpagoStyle = pkgs.writeShellScriptBin "build-spago-style" ''
1070+ set -e
1071+ echo building project...
1072+ purs compile ${builtins.toString (builtins.map getGlob (builtins.attrValues inputs))} "$@"
1073+ echo done.
1074+ '';
1075+
1076+ buildFromNixStore = pkgs.writeShellScriptBin "build-from-store" ''
1077+ set -e
1078+ echo building project using sources from nix store...
1079+ purs compile ${builtins.toString (
1080+ builtins.map getStoreGlob (builtins.attrValues inputs))} "$@"
1081+ echo done.
1082+ '';
1083+
1084+ mkBuildProjectOutput =
1085+ { src, purs }:
1086+
1087+ pkgs.stdenv.mkDerivation {
1088+ name = "build-project-output";
1089+ src = src;
1090+
1091+ buildInputs = [ purs ];
1092+
1093+ installPhase = ''
1094+ mkdir -p $out
1095+ purs compile "$src/**/*.purs" ${builtins.toString
1096+ (builtins.map
1097+ (x: ''"${x.outPath}/src/**/*.purs"'')
1098+ (builtins.attrValues inputs))}
1099+ mv output $out
1100+ '';
1101+ };
1102+}
spago.dhall+18−4
@@ -17,24 +17,38 @@ to generate this file without the comments in this block.
17 , "argonaut"
17 , "argonaut"
18 , "argonaut-aeson-generic"
18 , "argonaut-aeson-generic"
19 , "argonaut-codecs"
19 , "argonaut-codecs"
20+ , "arraybuffer"
21+ , "arraybuffer-types"
20 , "arrays"
22 , "arrays"
21− , "bw"
23+ , "bifunctors"
22 , "console"
24 , "console"
23 , "datetime"
25 , "datetime"
24 , "datetime-parsing"
26 , "datetime-parsing"
25 , "effect"
27 , "effect"
26 , "either"
28 , "either"
27− , "el"
28 , "exceptions"
29 , "exceptions"
29 , "foldable-traversable"
30 , "foldable-traversable"
30 , "foreign"
31 , "foreign"
31− , "lists"
32+ , "functions"
33+ , "integers"
34+ , "literals"
32 , "maybe"
35 , "maybe"
33 , "newtype"
36 , "newtype"
34 , "nullable"
37 , "nullable"
38+ , "numbers"
39+ , "orders"
35 , "prelude"
40 , "prelude"
41+ , "random"
42+ , "refs"
43+ , "run"
44+ , "strings"
36 , "transformers"
45 , "transformers"
37− , "unsafe-coerce"
46+ , "tuples"
47+ , "typelevel-prelude"
48+ , "undefined-is-not-a-problem"
49+ , "untagged-union"
50+ , "web-html"
51+ , "web-storage"
38 ]
52 ]
39, packages = ./packages.dhall
53, packages = ./packages.dhall
40, sources = [ "backend/**/*.purs" ]
54, sources = [ "backend/**/*.purs" ]
style.css+101−10
@@ -1,32 +1,49 @@
1−
2:root {
1:root {
3− --color-light: #F7F7F7;
2+ --color-light: #f7f7f7;
4}
3}
5
4
6main {
5main {
7 margin: 1rem;
6 margin: 1rem;
8}
7}
9
8
10−
11nav.p-tabs__list {
9nav.p-tabs__list {
12 top: 0;
10 top: 0;
13 position: sticky;
11 position: sticky;
14 background-color: white;
12 background-color: white;
15 padding-bottom: 1rem;
13 padding-bottom: 1rem;
14+ padding-right: 1rem;
16 padding-bottom: 0;
15 padding-bottom: 0;
17 z-index: 10;
16 z-index: 10;
18}
17}
19
18
19+nav h3 {
20+ width: 100%;
21+}
22+
20.ninety-counter {
23.ninety-counter {
21 transform: rotate(90deg);
24 transform: rotate(90deg);
22}
25}
23
26
27+@keyframes floating-notification-animation {
28+ from {
29+ transform: translateY(-60px);
30+ opacity: 0;
31+ }
32+
33+ to {
34+ transform: none;
35+ opacity: 1;
36+ }
37+}
38+
24.floating-notifications {
39.floating-notifications {
25 position: fixed;
40 position: fixed;
26 top: 1rem;
41 top: 1rem;
27 right: 1rem;
42 right: 1rem;
28 left: 1rem;
43 left: 1rem;
29 z-index: 9999;
44 z-index: 9999;
45+ animation-duration: 0.5s;
46+ animation-name: floating-notification-animation;
30}
47}
31
48
32.simple-flex-center {
49.simple-flex-center {
@@ -38,17 +55,17 @@ nav.p-tabs__list {
38 align-content: center;
55 align-content: center;
39}
56}
40
57
41−.spinner{
58+.spinner {
42 padding: 1rem;
59 padding: 1rem;
43}
60}
44
61
45.cipher-row-container {
62.cipher-row-container {
46− display: flex;
63+ display: flex;
47− width: 100%;
64+ width: 100%;
48− align-items: baseline;
65+ align-items: baseline;
49− justify-content: space-between;
66+ justify-content: space-between;
50− flex-direction: row;
67+ flex-direction: row;
51− flex-wrap: wrap;
68+ flex-wrap: wrap;
52}
69}
53
70
54.cipher-row p {
71.cipher-row p {
@@ -58,3 +75,77 @@ nav.p-tabs__list {
58.cipher-row .p-text--small {
75.cipher-row .p-text--small {
59 margin-bottom: 0.5rem;
76 margin-bottom: 0.5rem;
60}
77}
78+
79+.ciphers-list {
80+ height: calc(100vh - 9.5rem);
81+ overflow: auto;
82+ margin: 0;
83+}
84+
85+p {
86+ word-break: break-word;
87+}
88+
89+.no-scroll-bar::-webkit-scrollbar {
90+ display: none;
91+}
92+
93+textarea {
94+ resize: none;
95+}
96+
97+.password-generator-group {
98+ display: flex;
99+ flex-direction: row;
100+ align-items: baseline;
101+ justify-content: space-between;
102+}
103+
104+.password-generator-group > input[type="number"] {
105+ width: 5%;
106+ margin-bottom: 0px;
107+ min-width: 5rem;
108+ text-align: center;
109+}
110+
111+.p-side-navigation__drawer {
112+ max-width: initial;
113+}
114+
115+.select-cipher-type-container {
116+ display: flex;
117+ flex-direction: column;
118+ align-items: center;
119+ justify-content: center;
120+}
121+
122+.select-cipher-type-container > * {
123+ margin: 0px;
124+ margin-bottom: 1.5rem;
125+}
126+
127+.overlay {
128+ position: fixed;
129+ top: 0;
130+ left: 0;
131+ right: 0;
132+ bottom: 0;
133+}
134+
135+.select-second-factor-container {
136+ display: flex;
137+ flex-direction: column;
138+ align-items: center;
139+ justify-content: center;
140+}
141+
142+.p-tabs__list {
143+ overflow: initial;
144+}
145+
146+.p-modal {
147+ top: 0;
148+ left: 0;
149+ right: 0;
150+ bottom: 0;
151+}
tests/package-lock.jsonnew file+73
@@ -0,0 +1,73 @@
1+{
2+ "name": "warden-tests",
3+ "version": "1.0.0",
4+ "lockfileVersion": 2,
5+ "requires": true,
6+ "packages": {
7+ "": {
8+ "name": "warden-tests",
9+ "version": "1.0.0",
10+ "devDependencies": {
11+ "@playwright/test": "^1.27.1"
12+ }
13+ },
14+ "node_modules/@playwright/test": {
15+ "version": "1.27.1",
16+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.27.1.tgz",
17+ "integrity": "sha512-mrL2q0an/7tVqniQQF6RBL2saskjljXzqNcCOVMUjRIgE6Y38nCNaP+Dc2FBW06bcpD3tqIws/HT9qiMHbNU0A==",
18+ "dev": true,
19+ "dependencies": {
20+ "@types/node": "*",
21+ "playwright-core": "1.27.1"
22+ },
23+ "bin": {
24+ "playwright": "cli.js"
25+ },
26+ "engines": {
27+ "node": ">=14"
28+ }
29+ },
30+ "node_modules/@types/node": {
31+ "version": "18.11.9",
32+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
33+ "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
34+ "dev": true
35+ },
36+ "node_modules/playwright-core": {
37+ "version": "1.27.1",
38+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.27.1.tgz",
39+ "integrity": "sha512-9EmeXDncC2Pmp/z+teoVYlvmPWUC6ejSSYZUln7YaP89Z6lpAaiaAnqroUt/BoLo8tn7WYShcfaCh+xofZa44Q==",
40+ "dev": true,
41+ "bin": {
42+ "playwright": "cli.js"
43+ },
44+ "engines": {
45+ "node": ">=14"
46+ }
47+ }
48+ },
49+ "dependencies": {
50+ "@playwright/test": {
51+ "version": "1.27.1",
52+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.27.1.tgz",
53+ "integrity": "sha512-mrL2q0an/7tVqniQQF6RBL2saskjljXzqNcCOVMUjRIgE6Y38nCNaP+Dc2FBW06bcpD3tqIws/HT9qiMHbNU0A==",
54+ "dev": true,
55+ "requires": {
56+ "@types/node": "*",
57+ "playwright-core": "1.27.1"
58+ }
59+ },
60+ "@types/node": {
61+ "version": "18.11.9",
62+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
63+ "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
64+ "dev": true
65+ },
66+ "playwright-core": {
67+ "version": "1.27.1",
68+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.27.1.tgz",
69+ "integrity": "sha512-9EmeXDncC2Pmp/z+teoVYlvmPWUC6ejSSYZUln7YaP89Z6lpAaiaAnqroUt/BoLo8tn7WYShcfaCh+xofZa44Q==",
70+ "dev": true
71+ }
72+ }
73+}
tests/package.jsonnew file+9
@@ -0,0 +1,9 @@
1+{
2+ "name": "warden-tests",
3+ "version": "1.0.0",
4+ "scripts": {},
5+ "keywords": [],
6+ "devDependencies": {
7+ "@playwright/test": "^1.27.1"
8+ }
9+}
tests/playwright.config.tsnew file+65
@@ -0,0 +1,65 @@
1+import type { PlaywrightTestConfig } from '@playwright/test';
2+import { devices } from '@playwright/test';
3+
4+/**
5+ * See https://playwright.dev/docs/test-configuration.
6+ */
7+const config: PlaywrightTestConfig = {
8+ testDir: './src',
9+ /* Maximum time one test can run for. */
10+ timeout: 30 * 1000,
11+ expect: {
12+ /**
13+ * Maximum time expect() should wait for the condition to be met.
14+ * For example in `await expect(locator).toHaveText();`
15+ */
16+ timeout: 5000
17+ },
18+ /* Run tests in files in parallel */
19+ fullyParallel: false,
20+ /* Fail the build on CI if you accidentally left test.only in the source code. */
21+ forbidOnly: !!process.env.CI,
22+ /* Retry on CI only */
23+ retries: 0,
24+ /* Opt out of parallel tests on CI. */
25+ workers: 1,
26+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
27+ reporter: 'html',
28+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
29+ use: {
30+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
31+ actionTimeout: 0,
32+ /* Base URL to use in actions like `await page.goto('/')`. */
33+ // baseURL: 'http://localhost:3000',
34+
35+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
36+ trace: 'on-first-retry',
37+ },
38+
39+ /* Configure projects for major browsers */
40+ projects: [
41+ {
42+ name: 'Pixel 3',
43+ use: {
44+ ...devices['Pixel 3'],
45+ launchOptions: {
46+ args: ["--disable-web-security"],
47+ },
48+ headless: process.env.RECORD_TEST !== "true",
49+ }
50+ },
51+
52+ ],
53+
54+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
55+ outputDir: 'test-results/',
56+
57+ /* Run your local dev server before starting the tests */
58+ webServer: {
59+ command: './vaultwarden/run.sh',
60+ port: 8000,
61+ },
62+
63+};
64+
65+export default config;
tests/src/test.spec.tsnew file+257
@@ -0,0 +1,257 @@
1+import { test, expect, Page } from '@playwright/test';
2+
3+async function logIn(page: Page) {
4+ await page.locator('input[type="url"]').tap();
5+ await page.locator('input[type="url"]').press('Control+a');
6+ await page.locator('input[type="url"]').fill('http://localhost:8000');
7+ await page.locator('input[type="email"]').tap();
8+ await page.locator('input[type="email"]').fill('test@example.com');
9+ await page.locator('input[type="password"]').tap();
10+ await page.locator('input[type="password"]').fill('Password123');
11+ await page.getByRole('button', { name: 'Log in' }).tap();
12+ await page.locator('.p-icon--spinner.u-animation--spin.spinner').waitFor({ state: "visible" })
13+ await page.locator('.p-icon--spinner.u-animation--spin.spinner').waitFor({ state: "hidden" })
14+}
15+
16+async function fillInLoginCipher(page: Page) {
17+ await page.locator('p:has-text("Entry name") input[type="text"]').tap();
18+ await page.locator('p:has-text("Entry name") input[type="text"]').fill('Test login entry');
19+ await page.locator('p:has-text("Username") input[type="text"]').tap();
20+ await page.locator('p:has-text("Username") input[type="text"]').fill('login_entry_username');
21+ await page.locator('input[type="text"]').nth(2).tap();
22+ await page.locator('input[type="text"]').nth(2).fill('Password123');
23+ await page.locator('input[type="url"]').tap();
24+ await page.locator('input[type="url"]').fill('https://example.com');
25+}
26+
27+async function fillInCardCipher(page: Page) {
28+ await page.locator('p:has-text("Entry name") input[type="text"]').tap();
29+ await page.locator('p:has-text("Entry name") input[type="text"]').fill('Test card');
30+ await page.locator('p:has-text("Card number") input[type="text"]').tap();
31+ await page.locator('p:has-text("Card number") input[type="text"]').fill('1234567890123456');
32+ await page.locator('p:has-text("Expiration date /") input[type="text"]').first().tap();
33+ await page.locator('p:has-text("Expiration date /") input[type="text"]').first().fill('01');
34+ await page.locator('p:has-text("Expiration date /") input[type="text"]').nth(1).tap();
35+ await page.locator('p:has-text("Expiration date /") input[type="text"]').nth(1).fill('01');
36+ await page.locator('p:has-text("CVV") input[type="text"]').tap();
37+ await page.locator('p:has-text("CVV") input[type="text"]').fill('123');
38+ await page.locator('p:has-text("Cardholder name") input[type="text"]').tap();
39+ await page.locator('p:has-text("Cardholder name") input[type="text"]').fill('Sampel Palnet');
40+}
41+
42+async function fillInNoteCipher(page: Page) {
43+ await page.locator('input[type="text"]').tap();
44+ await page.locator('input[type="text"]').fill('Secret note');
45+ await page.locator('textarea').tap();
46+ await page.locator('textarea').fill('This is a very secret note');
47+}
48+
49+async function fillInContractCipher(page: Page) {
50+ await page.locator('p:has-text("Entry name") input[type="text"]').tap();
51+ await page.locator('p:has-text("Entry name") input[type="text"]').fill('John Appleseed');
52+ await page.locator('p:has-text("First name") input[type="text"]').tap();
53+ await page.locator('p:has-text("First name") input[type="text"]').fill('John');
54+ await page.locator('p:has-text("Middle name") input[type="text"]').tap();
55+ await page.locator('p:has-text("Middle name") input[type="text"]').fill('Mathews');
56+ await page.locator('p:has-text("Last name") input[type="text"]').tap();
57+ await page.locator('p:has-text("Last name") input[type="text"]').fill('Appleseed');
58+ await page.locator('p:has-text("Username") input[type="text"]').tap();
59+ await page.locator('p:has-text("Username") input[type="text"]').fill('jappleseed');
60+ await page.locator('p:has-text("Company") input[type="text"]').tap();
61+ await page.locator('p:has-text("Company") input[type="text"]').fill('Very good building company');
62+ await page.locator('p:has-text("Social security number") input[type="number"]').tap();
63+ await page.locator('p:has-text("Social security number") input[type="number"]').fill('123456789');
64+ await page.locator('p:has-text("Passport number") input[type="number"]').tap();
65+ await page.locator('p:has-text("Passport number") input[type="number"]').fill('123456798');
66+ await page.locator('p:has-text("License Number") input[type="number"]').tap();
67+ await page.locator('p:has-text("License Number") input[type="number"]').fill('12345');
68+ await page.locator('input[type="email"]').tap();
69+ await page.locator('input[type="email"]').fill('john@example.com');
70+ await page.locator('input[type="tel"]').tap();
71+ await page.locator('input[type="tel"]').fill('123456789');
72+ await page.locator('p:has-text("Address line 1") input[type="text"]').tap();
73+ await page.locator('p:has-text("Address line 1") input[type="text"]').fill('Abc def');
74+ await page.locator('p:has-text("Address line 2") input[type="text"]').tap();
75+ await page.locator('p:has-text("Address line 2") input[type="text"]').fill('Ghijk Lmn');
76+}
77+
78+async function screenshot(page: Page) {
79+ await page.waitForLoadState("networkidle")
80+
81+ if (await page.locator('div.floating-notifications').isVisible()) {
82+ await page.locator("button.p-notification__close").tap()
83+ await screenshot(page)
84+ } else if (await page.locator('.p-icon--spinner.u-animation--spin.spinner').isVisible()) {
85+ await page.locator('.p-icon--spinner.u-animation--spin.spinner').waitFor({ state: "hidden" })
86+ await screenshot(page)
87+ } else {
88+ await expect.soft(page).toHaveScreenshot({ animations: "disabled", fullPage: true, maxDiffPixelRatio: 0.01 })
89+ }
90+}
91+
92+async function waitForNotification(page: Page) {
93+ await page.locator('div.floating-notifications').waitFor({ state: "visible" })
94+}
95+
96+
97+/**
98+ * Screenshots the very first (last edited) entry.
99+ */
100+function cipherPage(name: string) {
101+ test(name + " cipher page", async ({ page }) => {
102+ await logIn(page)
103+
104+ await page.locator('.cipher-row').first().tap()
105+
106+ await screenshot(page)
107+ })
108+}
109+
110+test.beforeEach(async ({ page }) => {
111+ await page.goto(`file://${__dirname}/../../dist/index.html`);
112+ await page.addStyleTag({ content: '.hide-in-test {opacity: 0;}' })
113+})
114+
115+if (process.env.RECORD_TEST === "true") {
116+
117+ test('record', async ({ page }) => {
118+ await logIn(page)
119+ await page.pause()
120+ })
121+
122+} else {
123+ test('Login page', async ({ page }) => {
124+ await screenshot(page)
125+ });
126+
127+ test('Empty ciphers page', async ({ page }) => {
128+ await logIn(page)
129+
130+ await screenshot(page)
131+ })
132+
133+ test('Login entry page', async ({ page }) => {
134+ await logIn(page)
135+
136+ await page.getByRole('button').nth(2).tap();
137+ await page.getByRole('button', { name: 'Login' }).tap();
138+
139+ await screenshot(page)
140+
141+ await fillInLoginCipher(page)
142+
143+ await screenshot(page)
144+
145+ await page.getByRole('heading').locator('span').getByRole('button').tap();
146+
147+ await waitForNotification(page)
148+ });
149+
150+ cipherPage("Login")
151+
152+ test('Create Card entry page', async ({ page }) => {
153+ await logIn(page)
154+
155+ await page.getByRole('button').nth(2).tap();
156+ await page.getByRole('button', { name: 'Card' }).tap();
157+
158+ await screenshot(page)
159+
160+ await fillInCardCipher(page)
161+
162+ await screenshot(page)
163+
164+ await page.getByRole('heading').locator('span').getByRole('button').tap();
165+
166+ await waitForNotification(page)
167+ })
168+
169+ cipherPage("Card")
170+
171+ test('Create Note entry page', async ({ page }) => {
172+ await logIn(page)
173+
174+ await page.getByRole('button').nth(2).tap();
175+ await page.getByRole('button', { name: 'Note' }).tap();
176+
177+ await screenshot(page)
178+
179+ await fillInNoteCipher(page)
180+
181+ await screenshot(page)
182+
183+ await page.getByRole('heading').locator('span').getByRole('button').tap();
184+
185+ await waitForNotification(page)
186+ })
187+
188+ cipherPage("Note")
189+
190+ test('Create Contact entry page', async ({ page }) => {
191+ await logIn(page)
192+
193+ await page.getByRole('button').nth(2).tap();
194+ await page.getByRole('button', { name: 'Contact' }).tap();
195+
196+ await screenshot(page)
197+
198+ await fillInContractCipher(page)
199+
200+ await screenshot(page)
201+
202+ await page.getByRole('heading').locator('span').getByRole('button').tap();
203+
204+ await waitForNotification(page)
205+ })
206+
207+ cipherPage("Contact")
208+
209+ test('Filled ciphers page', async ({ page }) => {
210+ await logIn(page)
211+ await screenshot(page)
212+ })
213+
214+ test('Side bar', async ({ page }) => {
215+ await logIn(page)
216+
217+ await page.getByRole('button').nth(1).tap();
218+
219+ await screenshot(page)
220+ })
221+
222+ test('Passwords view', async ({ page }) => {
223+ await logIn(page)
224+
225+ await page.getByRole('button').nth(1).click();
226+ await page.getByText('Passwords').click();
227+
228+ await screenshot(page)
229+ })
230+
231+ test('Notes view', async ({ page }) => {
232+ await logIn(page)
233+
234+ await page.getByRole('button').nth(1).click();
235+ await page.getByText('Notes').click();
236+
237+ await screenshot(page)
238+ })
239+
240+ test('Cards view', async ({ page }) => {
241+ await logIn(page)
242+
243+ await page.getByRole('button').nth(1).click();
244+ await page.getByText('Cards').click();
245+
246+ await screenshot(page)
247+ })
248+
249+ test('Contacts view', async ({ page }) => {
250+ await logIn(page)
251+
252+ await page.getByRole('button').nth(1).click();
253+ await page.getByText('Contacts').click();
254+
255+ await screenshot(page)
256+ })
257+}
tests/src/test.spec.ts-snapshots/Card-cipher-page-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Cards-view-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Contact-cipher-page-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Contacts-view-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Create-Card-entry-page-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Create-Card-entry-page-2-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Create-Contact-entry-page-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Create-Contact-entry-page-2-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Create-Note-entry-page-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Create-Note-entry-page-2-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Empty-ciphers-page-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Filled-ciphers-page-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Login-cipher-page-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Login-entry-page-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Login-entry-page-2-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Login-page-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Note-cipher-page-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Notes-view-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Passwords-view-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/src/test.spec.ts-snapshots/Side-bar-1-Pixel-3-linux.pngnew file

Binary file not shown.

tests/vaultwarden/.envnew file+3
@@ -0,0 +1,3 @@
1+WEB_VAULT_ENABLED=false
2+LOGIN_RATELIMIT_SECONDS=1
3+LOGIN_RATELIMIT_MAX_BURST=100000000
tests/vaultwarden/README.mdnew file+4
@@ -0,0 +1,4 @@
1+# Test vaultwarden setup
2+
3+login: `test@example.com`
4+password: `Password123`
tests/vaultwarden/data/db.sqlite3new file

Binary file not shown.

tests/vaultwarden/data/db.sqlite3-shmnew file

Binary file not shown.

tests/vaultwarden/data/db.sqlite3-walnew file

No changes to the content.

tests/vaultwarden/data/rsa_key.pemnew file+27
@@ -0,0 +1,27 @@
1+-----BEGIN RSA PRIVATE KEY-----
2+MIIEowIBAAKCAQEArVVTdkrmMbDxyGxGY73Fse9Du7DplgSBPQ5uyOnAsqf6pa1U
3+jjWwTV7Xqzp0z7k32WC64P0eGdacTQGZiFUQxTVm6bJ4TZ8bh4fz51tB4npCAzpr
4+8EcgGRzZT+cA1GQOG7jDqv8w9edWWGdPr6mx1ENvnpXtv60tvnwfsioAUSnx3SC6
5+0oTVCxj1InyneUDXCk/UqBE1wmwl8aF5U3aOc42qcELAgr6i0aCsK1LQjH+SOREh
6+tRQgpDF17IdYAxdYUTyinqrYJnoo5kQXeC/4QoZIsDi1empas7pXwrDlVYtjNK2T
7+Oht6dWUnffc2oTUCNY+ATZ6Nsu4zItEM7yQo/QIDAQABAoIBABUX/q21JLlkXrA0
8+2QYXWKE0TGphd7O9fZrYEExcAgrb3WlfJBygVQG9aoKYfRGwaScHmgZ6VzjuwJuw
9+d6Y7L+zH+Gu1P+W2WKvQNDLyDJ0KotDwwaT+it3zgFC0fIncWUkvXYSIRMWQLxZY
10+ED8A6Da8NC+48DN02E3HnjXY3awCusn9fQkPLeparsdyrvz5s8lnYYQZ6u7FQeD9
11+gM5SUP8WVLtPl4KBidJvHl4qPDAxnu98cZEoffbWIAsg3wvKNZL9yE21ZGWdExxA
12+/czWYO4ckuGY7Tb0Y+MiRI5kBM4VbCzwVfZTLRPXnKddiL7QpLMNmYpHzEcMZut4
13+z3vcdnMCgYEA5ZIzaltIEfL8zmX76pIPlyBs5n98RaagCIxQyURNRSU4H6Sr6yW2
14+CNAszcn6iAxiteXkPUkWmPXE4BFt0ifKgecPQIDk0spaVu2khRPMwUMyR0PfwXfY
15+2fqT0zMZX0MB3VPxnDTY9sAvTi2FsskL9j+Pil7U8bYaixzdc2H+LcsCgYEAwUm2
16+5A1eyX8ojZM5xUaQ/ZAiW+9u0fI5UxJ9Q0SFUWn11LJyIoIvkw6puE10508e7UT1
17+rnYZc5v/Mr6E1oO2NGBHkOZdlfJMD346r2YAtm2Nt/HZuLZU38wyIZzg0FxS6lmZ
18+m1vTEoM6Ko5GVtjvLEst27ZZDgWRW7rJNyYEq1cCgYBm6ZJY9FCrkzUXRYqXziBl
19+DCklbzMDej21d0lj4FWPUK8HKGfVQxOGgeQD4K6JvJunlUYq3w/dRBecptOHaUUT
20+1MP2k5GAmSvEWkXtTkH0xS3N2rR84z/3/6ey/u450S0Nzeq6rsowW1kZf7i2u/+7
21+xSSQ0BA/xvXBNRBlACHU3wKBgQDAuYF0zqgOfY2v7HaT75KuYUMBLDHxgHYMEMl5
22+gx7zWJXXqL4JDonlNZ+gtwqzgL6zkijt9a/XCFpi/HhzdAz/GGkDX888rcWNRS26
23+qhhXzdCa8rlGZfcm1vG9djDrUMMUDJcOw3YoZVRgDlCwU8nW/ncRNjaBtqeDMTFk
24+nbHWLQKBgH0Xatwy6DVHDbU+GYcZBjyQP5zCz0JEjDE8hEhv/ioCfUK1rfjY58zU
25+oXDdn3GpFm6eFxcVxv9Ki4jViQDYAvAErBl0kMkVU6hvITPlMEyqBh89h65xUEnw
26+ttaX+Q2lKGwHsZT4RzA45XjO8kvBymY9siL2JQUMLB8wpu9RyTRj
27+-----END RSA PRIVATE KEY-----
tests/vaultwarden/data/rsa_key.pub.pemnew file+9
@@ -0,0 +1,9 @@
1+-----BEGIN PUBLIC KEY-----
2+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArVVTdkrmMbDxyGxGY73F
3+se9Du7DplgSBPQ5uyOnAsqf6pa1UjjWwTV7Xqzp0z7k32WC64P0eGdacTQGZiFUQ
4+xTVm6bJ4TZ8bh4fz51tB4npCAzpr8EcgGRzZT+cA1GQOG7jDqv8w9edWWGdPr6mx
5+1ENvnpXtv60tvnwfsioAUSnx3SC60oTVCxj1InyneUDXCk/UqBE1wmwl8aF5U3aO
6+c42qcELAgr6i0aCsK1LQjH+SOREhtRQgpDF17IdYAxdYUTyinqrYJnoo5kQXeC/4
7+QoZIsDi1empas7pXwrDlVYtjNK2TOht6dWUnffc2oTUCNY+ATZ6Nsu4zItEM7yQo
8+/QIDAQAB
9+-----END PUBLIC KEY-----
tests/vaultwarden/run.shnew file+13
@@ -0,0 +1,13 @@
1+#!/bin/sh
2+
3+set -e
4+
5+cd "$(dirname "$0")"
6+
7+tmp="$(mktemp -d)"
8+
9+cp -r data .env "$tmp"
10+
11+cd "$tmp"
12+
13+nix run github:NixOS/nixpkgs?rev=d9a1414346059619d9e13ab93e749bbb82e5252a#vaultwarden
vanilla/Ubuntu-L.533f8963.ttfdeleted

Binary file not shown.

vanilla/Ubuntu-LI.b9256a21.ttfdeleted

Binary file not shown.

vanilla/Ubuntu-R.744f36ed.ttfdeleted

Binary file not shown.

vanilla/Ubuntu-RI.33fd878c.ttfdeleted

Binary file not shown.

vanilla/Ubuntu-Th.04a5f703.ttfdeleted

Binary file not shown.

vanilla/UbuntuMono-B.1f21d913.ttfdeleted

Binary file not shown.

vanilla/UbuntuMono-R.54fdcd79.ttfdeleted

Binary file not shown.

vanilla/style.cssdeleted−2
@@ -1,2 +0,0 @@
1−html{-webkit-text-size-adjust:100%;line-height:1.15}body{margin:0}h1{margin:.67em 0;font-size:2em}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:#0000}abbr[title]{border-bottom:none;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;max-width:100%;white-space:normal;padding:0;display:table}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template,[hidden]{display:none}.p-media-object--large .p-media-object__title,.p-heading--1,h1{max-width:40em;margin-top:0;margin-bottom:.835rem;padding-top:.166rem;font-size:2.22819rem;font-style:normal;font-weight:100;line-height:3rem}@media (min-width:1036px){.p-media-object--large .p-media-object__title,.p-heading--1,h1{margin-bottom:.8rem;padding-top:.201rem;font-size:2.91029rem;line-height:3.5rem}}@media (min-width:1681px){.p-media-object--large .p-media-object__title,.p-heading--1,h1{margin-bottom:.85rem;padding-top:.151rem}}.p-heading--2,h2{max-width:40em;margin-top:0;margin-bottom:.9rem;padding-top:.101rem;font-size:1.83274rem;font-style:normal;font-weight:100;line-height:2.5rem}@media (min-width:1036px){.p-heading--2,h2{margin-bottom:.8rem;padding-top:.201rem;font-size:2.22819rem;line-height:3rem}}.p-pull-quote--large .p-pull-quote__quote,.p-heading--3,h3{max-width:40em;margin-top:0;margin-bottom:.5rem;padding-top:.5rem;font-size:1.49271rem;font-style:normal;font-weight:100;line-height:2rem}@media (min-width:1036px){.p-pull-quote--large .p-pull-quote__quote,.p-heading--3,h3{margin-bottom:.9rem;padding-top:.101rem;font-size:1.70596rem;line-height:2.5rem}}.p-panel__title,.p-pull-quote .p-pull-quote__quote,.p-navigation__tagged-logo .p-navigation__logo-title,.p-modal__title,.p-media-object__title,.p-matrix__title,.p-heading--4,h4{max-width:40em;margin-top:0;margin-bottom:.7rem;padding-top:.301rem;font-size:1.22176rem;font-style:normal;font-weight:300;line-height:1.5rem}@media (min-width:1036px){.p-panel__title,.p-pull-quote .p-pull-quote__quote,.p-navigation__tagged-logo .p-navigation__logo-title,.p-modal__title,.p-media-object__title,.p-matrix__title,.p-heading--4,h4{margin-bottom:.95rem;padding-top:.051rem;font-size:1.30612rem;line-height:2rem}}@media (min-width:1681px){.p-panel__title,.p-pull-quote .p-pull-quote__quote,.p-navigation__tagged-logo .p-navigation__logo-title,.p-modal__title,.p-media-object__title,.p-matrix__title,.p-heading--4,h4{margin-bottom:1rem;padding-top:.001rem}}.p-heading--5,.p-code-snippet .p-code-snippet__title,h5{max-width:40em;margin-top:0;margin-bottom:1.1rem;padding-top:.401rem;font-size:1rem;font-style:normal;font-weight:400;line-height:1.5rem}.p-pull-quote .p-pull-quote__citation,.p-pull-quote--small .p-pull-quote__citation,.p-pull-quote--large .p-pull-quote__citation,.p-heading--6,h6{max-width:40em;margin-top:0;margin-bottom:1.1rem;padding-top:.338rem;font-size:1rem;font-style:italic;font-weight:300;line-height:1.5rem}@media (min-width:1681px){.p-pull-quote .p-pull-quote__citation,.p-pull-quote--small .p-pull-quote__citation,.p-pull-quote--large .p-pull-quote__citation,.p-heading--6,h6{padding-top:.345rem}}.p-side-navigation--raw-html h2,.p-side-navigation--raw-html h3,.p-side-navigation--raw-html h4,.p-side-navigation--raw-html h5,.p-side-navigation--raw-html h6,.p-side-navigation__heading,.p-side-navigation__heading--linked,.p-notification--information .p-notification__content,.p-notification--negative .p-notification__content,.p-notification--caution .p-notification__content,.p-notification--positive .p-notification__content,.p-notification .p-notification__content,summary,p,.p-pull-quote--small .p-pull-quote__quote,.p-notification--information .p-notification__action,.p-notification--negative .p-notification__action,.p-notification--caution .p-notification__action,.p-notification--positive .p-notification__action,.p-notification .p-notification__action,.p-notification--information .p-notification__timestamp,.p-notification--negative .p-notification__timestamp,.p-notification--caution .p-notification__timestamp,.p-notification--positive .p-notification__timestamp,.p-notification .p-notification__timestamp,.p-breadcrumbs__item,dt,dd,cite,.p-text--default{margin-top:0;padding-top:.4005rem;line-height:1.5rem}.p-pull-quote--small .p-pull-quote__quote,.p-notification--information .p-notification__action,.p-notification--negative .p-notification__action,.p-notification--caution .p-notification__action,.p-notification--positive .p-notification__action,.p-notification .p-notification__action,.p-notification--information .p-notification__timestamp,.p-notification--negative .p-notification__timestamp,.p-notification--caution .p-notification__timestamp,.p-notification--positive .p-notification__timestamp,.p-notification .p-notification__timestamp,.p-breadcrumbs__item,dt,dd,cite,.p-text--default{margin-bottom:.1rem}p{margin-bottom:1.1rem}p:not([class*=p-heading--]):not([class*=p-muted-heading])+p{margin-top:-.5rem}.p-tooltip__message,.p-media-object__meta-list-item,.p-media-object__meta-list-item--venue,.p-media-object__meta-list-item--location,.p-media-object__meta-list-item--date,.p-form-validation__message,.p-form-help-text,.p-chip .p-chip__value,.p-chip--positive .p-chip__value,.p-chip--caution .p-chip__value,.p-chip--negative .p-chip__value,.p-chip--information .p-chip__value,.p-chip,.p-chip--positive,.p-chip--caution,.p-chip--negative,.p-chip--information,small,.p-text--small{margin-bottom:.95rem;padding-top:.0505rem;font-size:.875rem;line-height:1.25rem}@media (min-width:1681px){.p-tooltip__message,.p-media-object__meta-list-item,.p-media-object__meta-list-item--venue,.p-media-object__meta-list-item--location,.p-media-object__meta-list-item--date,.p-form-validation__message,.p-form-help-text,.p-chip .p-chip__value,.p-chip--positive .p-chip__value,.p-chip--caution .p-chip__value,.p-chip--negative .p-chip__value,.p-chip--information .p-chip__value,.p-chip,.p-chip--positive,.p-chip--caution,.p-chip--negative,.p-chip--information,small,.p-text--small{padding-top:.0506rem}}.p-status-label--negative,.p-label--negative,.p-status-label--information,.p-label--information,.p-status-label--caution,.p-label--caution,.p-status-label--positive,.p-label--positive,.p-status-label,.p-label,.p-logo-section__title,.p-badge,.p-badge--negative,.p-chip .p-chip__lead+.p-chip__value:before,.p-chip--positive .p-chip__lead+.p-chip__value:before,.p-chip--caution .p-chip__lead+.p-chip__value:before,.p-chip--negative .p-chip__lead+.p-chip__value:before,.p-chip--information .p-chip__lead+.p-chip__value:before,.p-chip .p-chip__lead,.p-chip--positive .p-chip__lead,.p-chip--caution .p-chip__lead,.p-chip--negative .p-chip__lead,.p-chip--information .p-chip__lead,.p-text--x-small-capitalised,.p-text--x-small,.p-table--mobile-card td:before,.p-table--mobile-card tbody th:before,thead th,.p-muted-heading{margin-bottom:.75rem;padding-top:.2505rem;font-size:.765625rem;font-weight:400;line-height:1rem}@media (min-width:1681px){.p-status-label--negative,.p-label--negative,.p-status-label--information,.p-label--information,.p-status-label--caution,.p-label--caution,.p-status-label--positive,.p-label--positive,.p-status-label,.p-label,.p-logo-section__title,.p-badge,.p-badge--negative,.p-chip .p-chip__lead+.p-chip__value:before,.p-chip--positive .p-chip__lead+.p-chip__value:before,.p-chip--caution .p-chip__lead+.p-chip__value:before,.p-chip--negative .p-chip__lead+.p-chip__value:before,.p-chip--information .p-chip__lead+.p-chip__value:before,.p-chip .p-chip__lead,.p-chip--positive .p-chip__lead,.p-chip--caution .p-chip__lead,.p-chip--negative .p-chip__lead,.p-chip--information .p-chip__lead,.p-text--x-small-capitalised,.p-text--x-small,.p-table--mobile-card td:before,.p-table--mobile-card tbody th:before,thead th,.p-muted-heading{padding-top:.2506rem}}.u-text--muted,.p-notification--information .p-notification__timestamp,.p-notification--negative .p-notification__timestamp,.p-notification--caution .p-notification__timestamp,.p-notification--positive .p-notification__timestamp,.p-notification .p-notification__timestamp,.p-muted-heading{color:#0009}.p-table--mobile-card td:before,.p-table--mobile-card tbody th:before,thead th,.p-muted-heading{text-transform:uppercase}.p-side-navigation--raw-html h2,.p-side-navigation--raw-html h3,.p-side-navigation--raw-html h4,.p-side-navigation--raw-html h5,.p-side-navigation--raw-html h6,.p-side-navigation__heading,.p-side-navigation__heading--linked,.p-search-and-filter .p-search-and-filter__search-query,dt,b,strong{font-weight:400}p:not([class*=p-heading--]):not([class*=p-muted-heading])+h1,p:not([class*=p-heading--]):not([class*=p-muted-heading])+.p-heading--1{padding-top:1.665rem}@media (min-width:1036px){p:not([class*=p-heading--]):not([class*=p-muted-heading])+h1,p:not([class*=p-heading--]):not([class*=p-muted-heading])+.p-heading--1{padding-top:1.7rem}}p:not([class*=p-heading--]):not([class*=p-muted-heading])+h2,p:not([class*=p-heading--]):not([class*=p-muted-heading])+.p-heading--2{padding-top:1.6rem}@media (min-width:1036px){p:not([class*=p-heading--]):not([class*=p-muted-heading])+h2,p:not([class*=p-heading--]):not([class*=p-muted-heading])+.p-heading--2{padding-top:1.7rem}}p:not([class*=p-heading--]):not([class*=p-muted-heading])+h3,p:not([class*=p-heading--]):not([class*=p-muted-heading])+.p-heading--3{padding-top:2rem}@media (min-width:1036px){p:not([class*=p-heading--]):not([class*=p-muted-heading])+h3,p:not([class*=p-heading--]):not([class*=p-muted-heading])+.p-heading--3{padding-top:1.6rem}}p:not([class*=p-heading--]):not([class*=p-muted-heading])+h4,p:not([class*=p-heading--]):not([class*=p-muted-heading])+.p-heading--4{padding-top:1.8rem}@media (min-width:1036px){p:not([class*=p-heading--]):not([class*=p-muted-heading])+h4,p:not([class*=p-heading--]):not([class*=p-muted-heading])+.p-heading--4{padding-top:1.55rem}}p:not([class*=p-heading--]):not([class*=p-muted-heading])+h5,p:not([class*=p-heading--]):not([class*=p-muted-heading])+.p-heading--5,p:not([class*=p-heading--]):not([class*=p-muted-heading])+h6,p:not([class*=p-heading--]):not([class*=p-muted-heading])+.p-heading--6{padding-top:1.9rem}p:not([class*=p-heading--]):not([class*=p-muted-heading])+.p-muted-heading{padding-top:1.55rem}.p-switch__slider:before,.p-navigation__dropdown,.p-navigation__dropdown--right,.p-modal__dialog,.p-contextual-menu__dropdown,.p-card--muted,.p-card--highlighted,.p-card,fieldset{border-radius:.125rem}.p-switch__slider:before,.p-side-navigation:target .p-side-navigation__drawer,[class*=p-side-navigation--]:target .p-side-navigation__drawer,.p-side-navigation.is-expanded .p-side-navigation__drawer,.p-side-navigation.is-drawer-expanded .p-side-navigation__drawer,[class*=p-side-navigation--].is-expanded .p-side-navigation__drawer,[class*=p-side-navigation--].is-drawer-expanded .p-side-navigation__drawer,.p-navigation__dropdown,.p-navigation__dropdown--right,.p-modal__dialog,.p-contextual-menu__dropdown,.p-card--muted,.p-card--highlighted{box-shadow:0 1px 1px #00000026,0 2px 2px -1px #00000026,0 0 3px #0003}.p-notification--information,.p-notification--negative,.p-notification--caution,.p-notification--positive,.p-notification,.p-card,fieldset{border:1px solid #d9d9d9}.p-card--muted{color:#111;background-color:#f7f7f7}.p-notification--information,.p-notification--negative,.p-notification--caution,.p-notification--positive,.p-notification,.p-modal__dialog,.p-card--highlighted,.p-card,fieldset{color:#111;background-color:#fff}.p-card__inner,.p-modal__dialog,.p-card--highlighted,.p-card,fieldset{padding:1rem;overflow:auto}.p-modal__dialog,.p-card--highlighted,.p-card,fieldset{margin-bottom:1.5rem;padding:1rem;overflow:auto}.p-accordion__tab,td,th{padding-top:calc(.5rem - 1px);padding-bottom:.5rem}.p-side-navigation--raw-html ul,.p-side-navigation__list,.p-list--divided,.p-list,.is-crossed,.is-ticked{margin-left:0;padding-left:0;list-style:none}.p-tabs__link:before,.p-notification--information .p-notification__meta:after,.p-notification--negative .p-notification__meta:after,.p-notification--caution .p-notification__meta:after,.p-notification--positive .p-notification__meta:after,.p-notification .p-notification__meta:after,.p-modal__footer:after,.p-accordion__group+.p-accordion__group:after,.p-tabs__list:after,[class*=p-strip].is-bordered:after,.p-side-navigation--raw-html ul:after,.p-side-navigation__list:after,.p-modal__header:after{content:"";height:1px;background-color:#d9d9d9;position:absolute;left:0;right:0}.p-tabs__list,[class*=p-strip].is-bordered,.p-side-navigation--raw-html ul,.p-side-navigation__list,.p-modal__header{position:relative}.p-tabs__list:after,[class*=p-strip].is-bordered:after,.p-side-navigation--raw-html ul:after,.p-side-navigation__list:after,.p-modal__header:after{bottom:0}.p-notification--information .p-notification__meta,.p-notification--negative .p-notification__meta,.p-notification--caution .p-notification__meta,.p-notification--positive .p-notification__meta,.p-notification .p-notification__meta,.p-modal__footer,.p-accordion__group+.p-accordion__group{position:relative}.p-notification--information .p-notification__meta:after,.p-notification--negative .p-notification__meta:after,.p-notification--caution .p-notification__meta:after,.p-notification--positive .p-notification__meta:after,.p-notification .p-notification__meta:after,.p-modal__footer:after,.p-accordion__group+.p-accordion__group:after{top:0}hr{height:1px;width:100%;border:0;margin-top:0;position:relative}.p-panel__content,[class*=p-strip].is-shallow{padding-top:.75rem;padding-bottom:.75rem}@media (min-width:1036px){.p-panel__content,[class*=p-strip].is-shallow{padding-top:1.5rem;padding-bottom:1.5rem}}.p-strip--suru-topped,.p-strip--suru,.p-strip--image,.p-strip--accent,.p-strip--dark,.p-strip--light,.p-strip{padding-top:2rem;padding-bottom:2rem}@media (min-width:1036px){.p-strip--suru-topped,.p-strip--suru,.p-strip--image,.p-strip--accent,.p-strip--dark,.p-strip--light,.p-strip{padding-top:4rem;padding-bottom:4rem}}[class*=p-strip].is-deep{padding:3rem 0}@media (min-width:1036px){[class*=p-strip].is-deep{padding:6rem 0}}.u-hide-text,.p-notification--information .p-notification__close,.p-notification--negative .p-notification__close,.p-notification--caution .p-notification__close,.p-notification--positive .p-notification__close,.p-notification .p-notification__close,.p-icon--email,.p-icon--rss,.p-icon--youtube,.p-icon--linkedin,.p-icon--instagram,.p-icon--twitter,.p-icon--github,.p-icon--facebook,.p-side-navigation__toggle:before,.p-side-navigation__toggle--in-drawer:before,.p-top:after,.p-icon--hide,.p-icon--show,.p-icon--spinner,.p-icon--user,.p-icon--share,.p-icon--success,.p-icon--search,.p-icon--copy,.p-icon--menu,.p-icon--code,.p-icon--drag,.p-icon--external-link,.p-icon--warning,.p-icon--error,.p-icon--delete,.p-icon--information,.p-icon--help,.p-icon--question,.p-icon--close,.p-icon--chevron-down,.p-icon--chevron-up,.p-icon--collapse,.p-icon--expand,.p-icon--minus,.p-icon--plus,.p-icon--anchor,.p-chip .p-chip__dismiss,.p-chip--positive .p-chip__dismiss,.p-chip--caution .p-chip__dismiss,.p-chip--negative .p-chip__dismiss,.p-chip--information .p-chip__dismiss,.p-accordion__tab:before,.p-code-snippet .p-code-snippet__block--icon:before{text-indent:110vw;white-space:nowrap;overflow:hidden}.u-clearfix:after,.p-stepped-list:after,.p-list:after{clear:both;content:"";display:block}.u-no-margin--bottom:not(hr):not(h1):not(h2):not(h3):not(h4):not(h5):not(h6):not(p):not(small):not([class*=p-heading]):not([class*=p-button--link]){margin-bottom:0!important}.p-media-object--large .u-no-margin--bottom.p-media-object__title,.u-no-margin--bottom.p-heading--1,h1.u-no-margin--bottom{margin-bottom:-.165rem!important}@media (min-width:1036px){.p-media-object--large .u-no-margin--bottom.p-media-object__title,.u-no-margin--bottom.p-heading--1,h1.u-no-margin--bottom{margin-bottom:-.2rem!important}}@media (min-width:1681px){.p-media-object--large .u-no-margin--bottom.p-media-object__title,.u-no-margin--bottom.p-heading--1,h1.u-no-margin--bottom{margin-bottom:-.15rem!important}}.u-no-margin--bottom.p-heading--2,h2.u-no-margin--bottom{margin-bottom:-.1rem!important}@media (min-width:1036px){.u-no-margin--bottom.p-heading--2,h2.u-no-margin--bottom{margin-bottom:-.2rem!important}}.p-pull-quote--large .u-no-margin--bottom.p-pull-quote__quote,.u-no-margin--bottom.p-heading--3,h3.u-no-margin--bottom{margin-bottom:0!important}@media (min-width:1036px){.p-pull-quote--large .u-no-margin--bottom.p-pull-quote__quote,.u-no-margin--bottom.p-heading--3,h3.u-no-margin--bottom{margin-bottom:-.1rem!important}}.p-media-object__title,.u-no-margin--bottom.p-panel__title,.p-pull-quote .u-no-margin--bottom.p-pull-quote__quote,.p-navigation__tagged-logo .u-no-margin--bottom.p-navigation__logo-title,.u-no-margin--bottom.p-modal__title,.u-no-margin--bottom.p-media-object__title,.u-no-margin--bottom.p-matrix__title,.u-no-margin--bottom.p-heading--4,h4.u-no-margin--bottom{margin-bottom:.2rem!important}@media (min-width:1036px){.p-media-object__title,.u-no-margin--bottom.p-panel__title,.p-pull-quote .u-no-margin--bottom.p-pull-quote__quote,.p-navigation__tagged-logo .u-no-margin--bottom.p-navigation__logo-title,.u-no-margin--bottom.p-modal__title,.u-no-margin--bottom.p-media-object__title,.u-no-margin--bottom.p-matrix__title,.u-no-margin--bottom.p-heading--4,h4.u-no-margin--bottom{margin-bottom:-.05rem!important}}@media (min-width:1681px){.p-media-object__title,.u-no-margin--bottom.p-panel__title,.p-pull-quote .u-no-margin--bottom.p-pull-quote__quote,.p-navigation__tagged-logo .u-no-margin--bottom.p-navigation__logo-title,.u-no-margin--bottom.p-modal__title,.u-no-margin--bottom.p-media-object__title,.u-no-margin--bottom.p-matrix__title,.u-no-margin--bottom.p-heading--4,h4.u-no-margin--bottom{margin-bottom:0!important}}.p-card__content,.p-button--link.u-no-margin--bottom,.u-no-margin--bottom.p-heading--5,.p-code-snippet .u-no-margin--bottom.p-code-snippet__title,h5.u-no-margin--bottom,.p-pull-quote .u-no-margin--bottom.p-pull-quote__citation,.p-pull-quote--small .u-no-margin--bottom.p-pull-quote__citation,.p-pull-quote--large .u-no-margin--bottom.p-pull-quote__citation,.u-no-margin--bottom.p-heading--6,h6.u-no-margin--bottom,p.u-no-margin--bottom{margin-bottom:.1rem!important}.p-status-label--negative,.p-label--negative,.p-status-label--information,.p-label--information,.p-status-label--caution,.p-label--caution,.p-status-label--positive,.p-label--positive,.p-status-label,.p-label,.u-no-margin--bottom.p-tooltip__message,.u-no-margin--bottom.p-media-object__meta-list-item,.u-no-margin--bottom.p-media-object__meta-list-item--venue,.u-no-margin--bottom.p-media-object__meta-list-item--location,.u-no-margin--bottom.p-media-object__meta-list-item--date,.u-no-margin--bottom.p-form-validation__message,.u-no-margin--bottom.p-form-help-text,.p-chip .u-no-margin--bottom.p-chip__value,.p-chip--positive .u-no-margin--bottom.p-chip__value,.p-chip--caution .u-no-margin--bottom.p-chip__value,.p-chip--negative .u-no-margin--bottom.p-chip__value,.p-chip--information .u-no-margin--bottom.p-chip__value,.u-no-margin--bottom.p-chip,.u-no-margin--bottom.p-chip--positive,.u-no-margin--bottom.p-chip--caution,.u-no-margin--bottom.p-chip--negative,.u-no-margin--bottom.p-chip--information,small.u-no-margin--bottom,.u-no-margin--bottom.p-text--small,.u-no-margin--bottom.p-status-label--negative,.u-no-margin--bottom.p-label--negative,.u-no-margin--bottom.p-status-label--information,.u-no-margin--bottom.p-label--information,.u-no-margin--bottom.p-status-label--caution,.u-no-margin--bottom.p-label--caution,.u-no-margin--bottom.p-status-label--positive,.u-no-margin--bottom.p-label--positive,.u-no-margin--bottom.p-status-label,.u-no-margin--bottom.p-label,.u-no-margin--bottom.p-logo-section__title,.u-no-margin--bottom.p-badge,.u-no-margin--bottom.p-badge--negative,.p-chip .p-chip__lead+.u-no-margin--bottom.p-chip__value:before,.p-chip--positive .p-chip__lead+.u-no-margin--bottom.p-chip__value:before,.p-chip--caution .p-chip__lead+.u-no-margin--bottom.p-chip__value:before,.p-chip--negative .p-chip__lead+.u-no-margin--bottom.p-chip__value:before,.p-chip--information .p-chip__lead+.u-no-margin--bottom.p-chip__value:before,.p-chip .u-no-margin--bottom.p-chip__lead,.p-chip--positive .u-no-margin--bottom.p-chip__lead,.p-chip--caution .u-no-margin--bottom.p-chip__lead,.p-chip--negative .u-no-margin--bottom.p-chip__lead,.p-chip--information .u-no-margin--bottom.p-chip__lead,.u-no-margin--bottom.p-text--x-small-capitalised,.u-no-margin--bottom.p-text--x-small,.p-table--mobile-card td.u-no-margin--bottom:before,.p-table--mobile-card tbody th.u-no-margin--bottom:before,thead th.u-no-margin--bottom,.u-no-margin--bottom.p-muted-heading{margin-bottom:-.05rem!important}hr.u-no-margin--bottom{z-index:2;margin-bottom:-1px!important}.p-side-navigation__toggle:before,.p-side-navigation__toggle--in-drawer:before,.p-top:after,.p-icon--hide,.p-icon--show,.p-icon--spinner,.p-icon--user,.p-icon--share,.p-icon--success,.p-icon--search,.p-icon--copy,.p-icon--menu,.p-icon--code,.p-icon--drag,.p-icon--external-link,.p-icon--warning,.p-icon--error,.p-icon--delete,.p-icon--information,.p-icon--help,.p-icon--question,.p-icon--close,.p-icon--chevron-down,.p-icon--chevron-up,.p-icon--collapse,.p-icon--expand,.p-icon--minus,.p-icon--plus,.p-icon--anchor,.p-chip .p-chip__dismiss,.p-chip--positive .p-chip__dismiss,.p-chip--caution .p-chip__dismiss,.p-chip--negative .p-chip__dismiss,.p-chip--information .p-chip__dismiss,.p-accordion__tab:before,.p-code-snippet .p-code-snippet__block--icon:before{height:1rem;width:1rem;font-size:inherit;vertical-align:calc(.5px + .3465em - .5rem);background-position:50%;background-repeat:no-repeat;background-size:contain;margin:0;padding:0;display:inline-block;position:relative}.p-icon--email,.p-icon--rss,.p-icon--youtube,.p-icon--linkedin,.p-icon--instagram,.p-icon--twitter,.p-icon--github,.p-icon--facebook{height:2rem;width:2rem;background-repeat:no-repeat;background-size:contain;display:inline-block}html{background:#fff}@font-face{font-display:fallback;font-family:Ubuntu;font-style:normal;font-weight:300;src:url(Ubuntu-L.533f8963.ttf)}@font-face{font-display:fallback;font-family:Ubuntu;font-style:normal;font-weight:400;src:url(Ubuntu-R.744f36ed.ttf)}@font-face{font-display:fallback;font-family:Ubuntu;font-style:italic;font-weight:300;src:url(Ubuntu-LI.b9256a21.ttf)}@font-face{font-display:fallback;font-family:Ubuntu;font-style:italic;font-weight:400;src:url(Ubuntu-RI.33fd878c.ttf)}@font-face{font-display:fallback;font-family:Ubuntu;font-style:normal;font-weight:100;src:url(Ubuntu-Th.04a5f703.ttf)}@font-face{font-display:fallback;font-family:Ubuntu Mono;font-style:normal;font-weight:300;src:url(UbuntuMono-R.54fdcd79.ttf)}@font-face{font-display:fallback;font-family:Ubuntu Mono;font-style:normal;font-weight:400;src:url(UbuntuMono-B.1f21d913.ttf)}html{color:#111;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:Ubuntu,-apple-system,Segoe UI,Roboto,Oxygen,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:1rem;font-weight:300;line-height:1.5rem}@media (min-width:1681px){html{font-size:1.125rem;line-height:1.6875rem}}p{max-width:40em}small.dense,.p-text--small.dense{margin-bottom:1.2rem}.p-text--x-small-capitalised{text-transform:uppercase;font-weight:400}p:not([class*=p-heading--]):not([class*=p-muted-heading]):empty{margin:0;padding:0;line-height:0}sub,sup{vertical-align:baseline;line-height:0;position:relative}abbr[title]{cursor:help;border-bottom:.1em dotted;text-decoration:none}blockquote{border-left:2px solid #666;margin-top:0;margin-bottom:1.5rem;margin-left:0;padding-bottom:.5rem;padding-left:1.5rem;overflow:auto}blockquote>:last-child{margin-bottom:.1rem}blockquote>cite{font-style:normal;display:block}html{box-sizing:border-box}*,:before,:after{box-sizing:inherit}button{color:#111;background-color:#fff;border-color:#0000008f}button:visited{color:#111}button:hover{background-color:#f2f2f2;border-color:#0000008f}button:active,button[aria-pressed=true],button[aria-selected=true],button[aria-expanded=true]{background-color:#e6e6e6;border-color:#0000008f;transition-duration:0s}button:disabled:active,button:disabled[aria-pressed=true],button:disabled[aria-selected=true],button:disabled[aria-expanded=true],button:disabled:hover,button.is-disabled:active,button.is-disabled[aria-pressed=true],button.is-disabled[aria-selected=true],button.is-disabled[aria-expanded=true],button.is-disabled:hover{background-color:#0000;border-color:#0000008f}.p-segmented-control.is-dense .p-segmented-control__button,.p-segmented-control.is-dense .p-tab-buttons__button,.p-tab-buttons.is-dense .p-segmented-control__button,.p-tab-buttons.is-dense .p-tab-buttons__button,.is-dense.p-tabs__link,.is-dense.p-side-navigation__toggle,.is-dense.p-side-navigation__toggle--in-drawer,.is-dense.p-pagination__link--previous,.is-dense.p-pagination__link--next,.is-dense.p-pagination__link,.is-dense.p-button--base,.is-dense.p-button--negative,.is-dense.p-button--positive,.is-dense.p-button--brand,.is-dense.p-button,.is-dense.p-article-pagination__link--next,.is-dense.p-article-pagination__link--previous,button.is-dense{padding-top:calc(.15rem - 1px);padding-bottom:calc(.15rem - 1px)}.p-tabs__link,.p-side-navigation__toggle,.p-side-navigation__toggle--in-drawer,.p-pagination__link--previous,.p-pagination__link--next,.p-pagination__link,.p-button--base,.p-button--negative,.p-button--positive,.p-button--brand,.p-button,.p-article-pagination__link--next,.p-article-pagination__link--previous,button{cursor:pointer;text-align:center;border-style:solid;border-width:1px;border-radius:.125rem;justify-content:center;margin:0 1rem 1.2rem 0;padding:calc(.4rem - 1px) 1rem;font-size:1rem;font-weight:300;line-height:1.5rem;text-decoration:none;transition-property:background-color,border-color;transition-duration:.1s;transition-timing-function:cubic-bezier(.55,.055,.675,.19);display:inline-block}.p-tabs__link:focus,.p-side-navigation__toggle:focus,.p-side-navigation__toggle--in-drawer:focus,.p-pagination__link--previous:focus,.p-pagination__link--next:focus,.p-pagination__link:focus,.p-button--base:focus,.p-button--negative:focus,.p-button--positive:focus,.p-button--brand:focus,.p-button:focus,.p-article-pagination__link--next:focus,.p-article-pagination__link--previous:focus,button:focus,.p-tabs__link:focus-visible,.p-side-navigation__toggle:focus-visible,.p-side-navigation__toggle--in-drawer:focus-visible,.p-pagination__link--previous:focus-visible,.p-pagination__link--next:focus-visible,.p-pagination__link:focus-visible,.p-button--base:focus-visible,.p-button--negative:focus-visible,.p-button--positive:focus-visible,.p-button--brand:focus-visible,.p-button:focus-visible,.p-article-pagination__link--next:focus-visible,.p-article-pagination__link--previous:focus-visible,button:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}.p-tabs__link:focus:not(:focus-visible),.p-side-navigation__toggle:focus:not(:focus-visible),.p-side-navigation__toggle--in-drawer:focus:not(:focus-visible),.p-pagination__link--previous:focus:not(:focus-visible),.p-pagination__link--next:focus:not(:focus-visible),.p-pagination__link:focus:not(:focus-visible),.p-button--base:focus:not(:focus-visible),.p-button--negative:focus:not(:focus-visible),.p-button--positive:focus:not(:focus-visible),.p-button--brand:focus:not(:focus-visible),.p-button:focus:not(:focus-visible),.p-article-pagination__link--next:focus:not(:focus-visible),.p-article-pagination__link--previous:focus:not(:focus-visible),button:focus:not(:focus-visible){outline-offset:0;outline:0}.p-tabs__link:active,.p-side-navigation__toggle:active,.p-side-navigation__toggle--in-drawer:active,.p-pagination__link--previous:active,.p-pagination__link--next:active,.p-pagination__link:active,.p-button--base:active,.p-button--negative:active,.p-button--positive:active,.p-button--brand:active,.p-button:active,.p-article-pagination__link--next:active,.p-article-pagination__link--previous:active,button:active,.p-tabs__link:focus,.p-side-navigation__toggle:focus,.p-side-navigation__toggle--in-drawer:focus,.p-pagination__link--previous:focus,.p-pagination__link--next:focus,.p-pagination__link:focus,.p-button--base:focus,.p-button--negative:focus,.p-button--positive:focus,.p-button--brand:focus,.p-button:focus,.p-article-pagination__link--next:focus,.p-article-pagination__link--previous:focus,button:focus,.p-tabs__link:hover,.p-side-navigation__toggle:hover,.p-side-navigation__toggle--in-drawer:hover,.p-pagination__link--previous:hover,.p-pagination__link--next:hover,.p-pagination__link:hover,.p-button--base:hover,.p-button--negative:hover,.p-button--positive:hover,.p-button--brand:hover,.p-button:hover,.p-article-pagination__link--next:hover,.p-article-pagination__link--previous:hover,button:hover{text-decoration:none}.p-tabs__link:disabled,.p-side-navigation__toggle:disabled,.p-side-navigation__toggle--in-drawer:disabled,.p-pagination__link--previous:disabled,.p-pagination__link--next:disabled,.p-pagination__link:disabled,.p-button--base:disabled,.p-button--negative:disabled,.p-button--positive:disabled,.p-button--brand:disabled,.p-button:disabled,.p-article-pagination__link--next:disabled,.p-article-pagination__link--previous:disabled,button:disabled,.is-disabled.p-tabs__link,.is-disabled.p-side-navigation__toggle,.is-disabled.p-side-navigation__toggle--in-drawer,.is-disabled.p-pagination__link--previous,.is-disabled.p-pagination__link--next,.is-disabled.p-pagination__link,.is-disabled.p-button--base,.is-disabled.p-button--negative,.is-disabled.p-button--positive,.is-disabled.p-button--brand,.is-disabled.p-button,.is-disabled.p-article-pagination__link--next,.is-disabled.p-article-pagination__link--previous,button.is-disabled{cursor:not-allowed;opacity:.33}.p-tabs__link:last-child,.p-side-navigation__toggle:last-child,.p-side-navigation__toggle--in-drawer:last-child,.p-pagination__link--previous:last-child,.p-pagination__link--next:last-child,.p-pagination__link:last-child,.p-button--base:last-child,.p-button--negative:last-child,.p-button--positive:last-child,.p-button--brand:last-child,.p-button:last-child,.p-article-pagination__link--next:last-child,.p-article-pagination__link--previous:last-child,button:last-child{margin-right:0}.is-dense.p-tabs__link,.is-dense.p-side-navigation__toggle,.is-dense.p-side-navigation__toggle--in-drawer,.is-dense.p-pagination__link--previous,.is-dense.p-pagination__link--next,.is-dense.p-pagination__link,.is-dense.p-button--base,.is-dense.p-button--negative,.is-dense.p-button--positive,.is-dense.p-button--brand,.is-dense.p-button,.is-dense.p-article-pagination__link--next,.is-dense.p-article-pagination__link--previous,button.is-dense{margin-bottom:.1rem}.is-small.p-tabs__link,.is-small.p-side-navigation__toggle,.is-small.p-side-navigation__toggle--in-drawer,.is-small.p-pagination__link--previous,.is-small.p-pagination__link--next,.is-small.p-pagination__link,.is-small.p-button--base,.is-small.p-button--negative,.is-small.p-button--positive,.is-small.p-button--brand,.is-small.p-button,.is-small.p-article-pagination__link--next,.is-small.p-article-pagination__link--previous,button.is-small{margin-bottom:.7rem;padding:calc(.05rem - 1px) .5rem;font-size:.875rem;line-height:1.25rem}.is-small.is-dense.p-tabs__link,.is-small.is-dense.p-side-navigation__toggle,.is-small.is-dense.p-side-navigation__toggle--in-drawer,.is-small.is-dense.p-pagination__link--previous,.is-small.is-dense.p-pagination__link--next,.is-small.is-dense.p-pagination__link,.is-small.is-dense.p-button--base,.is-small.is-dense.p-button--negative,.is-small.is-dense.p-button--positive,.is-small.is-dense.p-button--brand,.is-small.is-dense.p-button,.is-small.is-dense.p-article-pagination__link--next,.is-small.is-dense.p-article-pagination__link--previous,button.is-small.is-dense{margin-bottom:.1rem;padding-top:calc(.15rem - 1px);padding-bottom:calc(.15rem - 1px)}p .p-tabs__link,p .p-side-navigation__toggle,p .p-side-navigation__toggle--in-drawer,p .p-pagination__link--previous,p .p-pagination__link--next,p .p-pagination__link,p .p-button--base,p .p-button--negative,p .p-button--positive,p .p-button--brand,p .p-button,p .p-article-pagination__link--next,p .p-article-pagination__link--previous,p button{margin-top:-.4rem;margin-bottom:.6rem}p+p>.p-tabs__link,p+p>.p-side-navigation__toggle,p+p>.p-side-navigation__toggle--in-drawer,p+p>.p-pagination__link--previous,p+p>.p-pagination__link--next,p+p>.p-pagination__link,p+p>.p-button--base,p+p>.p-button--negative,p+p>.p-button--positive,p+p>.p-button--brand,p+p>.p-button,p+p>.p-article-pagination__link--next,p+p>.p-article-pagination__link--previous,p+p>button{margin-top:.1rem}.p-button--negative .p-icon--success,.p-button--positive .p-icon--success,.p-button--brand .p-icon--success{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cg fill='none' fill-rule='nonzero'%3E%3Cpath fill='%23fff' d='M8 1a7 7 0 110 14A7 7 0 018 1zm2.83 3.502L6.863 9.884 5.174 8.096l-1.09 1.03 2.92 3.096 5.034-6.83-1.208-.89z'/%3E%3Cpath fill='transparent' d='M10.83 4.502l1.208.89-5.033 6.83-2.922-3.096 1.091-1.03 1.689 1.789z'/%3E%3C/g%3E%3C/svg%3E")}.p-segmented-control .p-segmented-control__button [class*=p-icon],.p-segmented-control .p-tab-buttons__button [class*=p-icon],.p-tab-buttons .p-segmented-control__button [class*=p-icon],.p-tab-buttons .p-tab-buttons__button [class*=p-icon],.p-search-and-filter .p-search-and-filter__clear [class*=p-icon],[class*=p-button].has-icon [class*=p-icon]{margin-left:.5rem;margin-right:.5rem}.p-segmented-control .p-segmented-control__button [class*=p-icon]:first-child,.p-segmented-control .p-tab-buttons__button [class*=p-icon]:first-child,.p-tab-buttons .p-segmented-control__button [class*=p-icon]:first-child,.p-tab-buttons .p-tab-buttons__button [class*=p-icon]:first-child,.p-search-and-filter .p-search-and-filter__clear [class*=p-icon]:first-child,[class*=p-button].has-icon [class*=p-icon]:first-child{margin-left:-.5rem}.p-segmented-control .p-segmented-control__button [class*=p-icon]:last-child,.p-segmented-control .p-tab-buttons__button [class*=p-icon]:last-child,.p-tab-buttons .p-segmented-control__button [class*=p-icon]:last-child,.p-tab-buttons .p-tab-buttons__button [class*=p-icon]:last-child,.p-search-and-filter .p-search-and-filter__clear [class*=p-icon]:last-child,[class*=p-button].has-icon [class*=p-icon]:last-child{margin-right:-.5rem}code,kbd,pre,samp{text-align:left;font-family:Ubuntu Mono,Consolas,Monaco,Courier,monospace;font-weight:300}code b,code strong,kbd b,kbd strong,pre b,pre strong,samp b,samp strong{font-weight:400}code,kbd,samp{box-decoration-break:slice;color:inherit;background-color:#00000008;border-radius:.125rem;padding:calc(.25rem - 1px) .25rem;line-height:1.25rem}code,pre{direction:ltr;hyphens:none;tab-size:4;word-spacing:normal;word-wrap:break-word}pre code{box-shadow:none;background:0 0;margin-left:0;margin-right:0;padding:0;line-height:1.5rem;display:inline-block}pre{color:#111;text-align:left;text-shadow:none;white-space:pre;background-color:#00000008;margin-top:0;margin-bottom:1.5rem;padding:.5rem 1rem;display:block;overflow:auto}[class*=--dark] code,code.is-dark{color:#fff;background-color:#ffffff4d}.p-code-snippet .p-code-snippet__block--icon:before{content:"";width:1rem;background-image:url("data:image/svg+xml,%3Csvg width='16px' height='16px' viewBox='0 0 16 16' version='1.1' xmlns='http://www.w3.org/2000/svg'%3E%3Cg id='dollar-sign' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cpath d='M8.85063291,15 L8.85063291,13.1075949 C9.73924051,12.9978903 10.3974684,12.7181434 10.8253165,12.2683544 C11.2531646,11.8185654 11.4670886,11.2700422 11.4670886,10.6227848 C11.4670886,10.1949367 11.3875528,9.82742616 11.228481,9.52025316 C11.0694092,9.21308017 10.8582278,8.94978903 10.5949367,8.73037975 C10.3316456,8.51097047 10.0244726,8.32172996 9.67341772,8.16265823 C9.32236287,8.00358649 8.96033756,7.85274262 8.58734177,7.71012658 C8.29113924,7.60042194 8.02510548,7.49620253 7.78924051,7.39746835 C7.55337553,7.29873418 7.34767933,7.18902953 7.1721519,7.06835443 C6.99662447,6.94767933 6.86223629,6.81054852 6.76898734,6.65696203 C6.67573839,6.50337553 6.62911392,6.31139241 6.62911392,6.08101266 C6.62911392,5.66413502 6.78544304,5.34599156 7.09810127,5.12658228 C7.41075949,4.907173 7.86329114,4.79746835 8.4556962,4.79746835 C8.99324895,4.79746835 9.43755275,4.84409282 9.78860759,4.93734177 C10.1396624,5.03059072 10.4303797,5.12109705 10.6607595,5.20886076 L10.9405063,4.05696203 C10.7210971,3.96919832 10.4276371,3.88417722 10.0601266,3.80189873 C9.69261604,3.71962025 9.28945148,3.66751055 8.85063291,3.64556962 L8.85063291,2 L7.63291139,2 L7.63291139,3.69493671 C6.84303797,3.81561181 6.23966244,4.09535865 5.82278481,4.53417722 C5.40590718,4.97299578 5.19746835,5.54345991 5.19746835,6.24556962 C5.19746835,6.64050633 5.26877637,6.97236287 5.41139241,7.24113924 C5.55400844,7.50991561 5.73776371,7.74029536 5.96265823,7.93227848 C6.18755275,8.12426161 6.44535865,8.28607595 6.73607595,8.41772152 C7.02679325,8.54936709 7.32025316,8.67004219 7.6164557,8.77974684 C7.9236287,8.88945148 8.21983123,9.00189873 8.50506329,9.11708861 C8.79029536,9.23227848 9.04535865,9.36392405 9.27025316,9.51202532 C9.49514768,9.66012658 9.67341772,9.83016877 9.80506329,10.0221519 C9.93670886,10.214135 10.0025316,10.4472574 10.0025316,10.721519 C10.0025316,10.9080169 9.96962025,11.0808017 9.90379747,11.2398734 C9.83797468,11.3989452 9.72827004,11.5360759 9.57468354,11.6512658 C9.42109705,11.7664557 9.20991561,11.8542194 8.94113924,11.914557 C8.67236287,11.9748945 8.34050633,12.0050633 7.94556962,12.0050633 C7.33122363,12.0050633 6.82109705,11.9419832 6.41518987,11.8158228 C6.0092827,11.6896624 5.65822785,11.5552743 5.36202532,11.4126582 L5,12.5481013 C5.20843882,12.6687763 5.52658228,12.7949367 5.95443038,12.9265823 C6.38227848,13.0582278 6.94177215,13.1350211 7.63291139,13.156962 L7.63291139,15 L8.85063291,15 Z' id='$' fill='%23666' fill-rule='nonzero'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");position:absolute;top:.75rem;left:1rem}@media (min-width:1681px){.p-code-snippet .p-code-snippet__block--icon:before{top:.84375rem}}.p-code-snippet .p-code-snippet__block--numbered .p-code-snippet__line{width:100%;padding:0 1rem 0 calc(1rem + 4ch);display:inline-block;position:relative}.p-code-snippet .p-code-snippet__block--numbered .p-code-snippet__line:empty:after{content:" ";user-select:none}.p-code-snippet .p-code-snippet__block--numbered .p-code-snippet__line:before{color:#666;content:counter(line-numbering);counter-increment:line-numbering;height:100%;pointer-events:none;text-align:right;user-select:none;width:calc(1rem + 5ch);padding-right:1rem;position:absolute;left:-1ch;overflow:hidden}details{margin-bottom:1.5rem;overflow:auto}summary{max-width:40em;margin-bottom:.4rem;padding-bottom:.6rem}summary:focus,summary:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}summary:focus:not(:focus-visible){outline-offset:0;outline:0}input[type=range]{appearance:none;width:100%;border-radius:.1875rem;margin:.5rem 0;padding:0}input[type=range]::-webkit-slider-runnable-track{height:.1875rem;border-radius:.1875rem}input[type=range]::-webkit-slider-thumb{appearance:none;height:1rem;width:1rem;background:#fff;border:1px solid #666;border-radius:50%;margin-top:-.40625rem;box-shadow:0 0 .1875rem 1px #0003}input[type=range]::-webkit-slider-thumb:hover{cursor:pointer}input[type=range]::-moz-range-track{height:.1875rem;background:#d9d9d9;border-radius:.1875rem}input[type=range]::-moz-range-progress{height:.1875rem;background-color:#06c;border-radius:.1875rem}input[type=range]::-moz-range-thumb{height:1rem;width:1rem;background:#fff;border:1px solid #666;border-radius:50%;box-shadow:0 0 .1875rem 1px #0003}input[type=range]::-moz-range-thumb:hover{cursor:pointer}input[type=range]::-moz-focus-outer{border:0}input[type=range]:focus{outline:none}input[type=range]:focus::-webkit-slider-thumb{outline:.1875rem solid #2e96ff}input[type=range]:focus::-moz-range-thumb{outline:.1875rem solid #2e96ff}input[type=range]:disabled{opacity:.5}[type=file],textarea,[type=text],[type=date],[type=datetime],[type=datetime-local],[type=month],[type=time],[type=week],[type=number],[type=search],[type=password],[type=email],[type=url],[type=tel],select{padding-top:calc(.4rem - 1px);padding-bottom:calc(.4rem - 1px)}textarea,[type=text],[type=date],[type=datetime],[type=datetime-local],[type=month],[type=time],[type=week],[type=number],[type=search],[type=password],[type=email],[type=url],[type=tel],select{appearance:textfield;color:#111;min-width:10em;vertical-align:baseline;width:100%;background-color:#fff;border:1px solid #0000008f;border-radius:0;margin-bottom:1.2rem;padding-left:.5rem;padding-right:.5rem;font-family:Ubuntu,-apple-system,Segoe UI,Roboto,Oxygen,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:1rem;font-weight:300;line-height:1.5rem;box-shadow:inset 0 1px 1px #0000001f}textarea:focus,[type=text]:focus,[type=date]:focus,[type=datetime]:focus,[type=datetime-local]:focus,[type=month]:focus,[type=time]:focus,[type=week]:focus,[type=number]:focus,[type=search]:focus,[type=password]:focus,[type=email]:focus,[type=url]:focus,[type=tel]:focus,select:focus,textarea:focus-visible,[type=text]:focus-visible,[type=date]:focus-visible,[type=datetime]:focus-visible,[type=datetime-local]:focus-visible,[type=month]:focus-visible,[type=time]:focus-visible,[type=week]:focus-visible,[type=number]:focus-visible,[type=search]:focus-visible,[type=password]:focus-visible,[type=email]:focus-visible,[type=url]:focus-visible,[type=tel]:focus-visible,select:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}textarea:focus:not(:focus-visible),[type=text]:focus:not(:focus-visible),[type=date]:focus:not(:focus-visible),[type=datetime]:focus:not(:focus-visible),[type=datetime-local]:focus:not(:focus-visible),[type=month]:focus:not(:focus-visible),[type=time]:focus:not(:focus-visible),[type=week]:focus:not(:focus-visible),[type=number]:focus:not(:focus-visible),[type=search]:focus:not(:focus-visible),[type=password]:focus:not(:focus-visible),[type=email]:focus:not(:focus-visible),[type=url]:focus:not(:focus-visible),[type=tel]:focus:not(:focus-visible),select:focus:not(:focus-visible){outline-offset:0;outline:0}.is-error textarea:focus,.is-error [type=text]:focus,.is-error [type=date]:focus,.is-error [type=datetime]:focus,.is-error [type=datetime-local]:focus,.is-error [type=month]:focus,.is-error [type=time]:focus,.is-error [type=week]:focus,.is-error [type=number]:focus,.is-error [type=search]:focus,.is-error [type=password]:focus,.is-error [type=email]:focus,.is-error [type=url]:focus,.is-error [type=tel]:focus,.is-error select:focus{outline-color:#c7162b}.is-caution textarea:focus,.is-caution [type=text]:focus,.is-caution [type=date]:focus,.is-caution [type=datetime]:focus,.is-caution [type=datetime-local]:focus,.is-caution [type=month]:focus,.is-caution [type=time]:focus,.is-caution [type=week]:focus,.is-caution [type=number]:focus,.is-caution [type=search]:focus,.is-caution [type=password]:focus,.is-caution [type=email]:focus,.is-caution [type=url]:focus,.is-caution [type=tel]:focus,.is-caution select:focus{outline-color:#f99b11}.is-success textarea:focus,.is-success [type=text]:focus,.is-success [type=date]:focus,.is-success [type=datetime]:focus,.is-success [type=datetime-local]:focus,.is-success [type=month]:focus,.is-success [type=time]:focus,.is-success [type=week]:focus,.is-success [type=number]:focus,.is-success [type=search]:focus,.is-success [type=password]:focus,.is-success [type=email]:focus,.is-success [type=url]:focus,.is-success [type=tel]:focus,.is-success select:focus{outline-color:#0e8420}textarea.is-dense,.is-dense[type=text],.is-dense[type=date],.is-dense[type=datetime],.is-dense[type=datetime-local],.is-dense[type=month],.is-dense[type=time],.is-dense[type=week],.is-dense[type=number],.is-dense[type=search],.is-dense[type=password],.is-dense[type=email],.is-dense[type=url],.is-dense[type=tel],select.is-dense{margin:0 0 .1rem;padding-top:calc(.15rem - 1px);padding-bottom:calc(.15rem - 1px)}textarea.has-error,.has-error[type=text],.has-error[type=date],.has-error[type=datetime],.has-error[type=datetime-local],.has-error[type=month],.has-error[type=time],.has-error[type=week],.has-error[type=number],.has-error[type=search],.has-error[type=password],.has-error[type=email],.has-error[type=url],.has-error[type=tel],select.has-error{border:1px solid #c7162b}textarea.has-caution,.has-caution[type=text],.has-caution[type=date],.has-caution[type=datetime],.has-caution[type=datetime-local],.has-caution[type=month],.has-caution[type=time],.has-caution[type=week],.has-caution[type=number],.has-caution[type=search],.has-caution[type=password],.has-caution[type=email],.has-caution[type=url],.has-caution[type=tel],select.has-caution{border:1px solid #f99b11}textarea.has-success,.has-success[type=text],.has-success[type=date],.has-success[type=datetime],.has-success[type=datetime-local],.has-success[type=month],.has-success[type=time],.has-success[type=week],.has-success[type=number],.has-success[type=search],.has-success[type=password],.has-success[type=email],.has-success[type=url],.has-success[type=tel],select.has-success{border:1px solid #0e8420}textarea.has-information,.has-information[type=text],.has-information[type=date],.has-information[type=datetime],.has-information[type=datetime-local],.has-information[type=month],.has-information[type=time],.has-information[type=week],.has-information[type=number],.has-information[type=search],.has-information[type=password],.has-information[type=email],.has-information[type=url],.has-information[type=tel],select.has-information{border:1px solid #24598f}.p-switch__input:disabled+.p-switch__slider,.p-checkbox__input:disabled+.p-checkbox__label,.p-radio__input:disabled+.p-radio__label,textarea[disabled],[disabled][type=text],[disabled][type=date],[disabled][type=datetime],[disabled][type=datetime-local],[disabled][type=month],[disabled][type=time],[disabled][type=week],[disabled][type=number],[disabled][type=search],[disabled][type=password],[disabled][type=email],[disabled][type=url],[disabled][type=tel],select[disabled],textarea[disabled=disabled],[disabled=disabled][type=text],[disabled=disabled][type=date],[disabled=disabled][type=datetime],[disabled=disabled][type=datetime-local],[disabled=disabled][type=month],[disabled=disabled][type=time],[disabled=disabled][type=week],[disabled=disabled][type=number],[disabled=disabled][type=search],[disabled=disabled][type=password],[disabled=disabled][type=email],[disabled=disabled][type=url],[disabled=disabled][type=tel],select[disabled=disabled]{cursor:not-allowed;opacity:.33}textarea[readonly],[readonly][type=text],[readonly][type=date],[readonly][type=datetime],[readonly][type=datetime-local],[readonly][type=month],[readonly][type=time],[readonly][type=week],[readonly][type=number],[readonly][type=search],[readonly][type=password],[readonly][type=email],[readonly][type=url],[readonly][type=tel],select[readonly],textarea[readonly=readonly],[readonly=readonly][type=text],[readonly=readonly][type=date],[readonly=readonly][type=datetime],[readonly=readonly][type=datetime-local],[readonly=readonly][type=month],[readonly=readonly][type=time],[readonly=readonly][type=week],[readonly=readonly][type=number],[readonly=readonly][type=search],[readonly=readonly][type=password],[readonly=readonly][type=email],[readonly=readonly][type=url],[readonly=readonly][type=tel],select[readonly=readonly]{color:#d9d9d9;cursor:default}textarea[readonly]:hover,[readonly][type=text]:hover,[readonly][type=date]:hover,[readonly][type=datetime]:hover,[readonly][type=datetime-local]:hover,[readonly][type=month]:hover,[readonly][type=time]:hover,[readonly][type=week]:hover,[readonly][type=number]:hover,[readonly][type=search]:hover,[readonly][type=password]:hover,[readonly][type=email]:hover,[readonly][type=url]:hover,[readonly][type=tel]:hover,select[readonly]:hover,textarea[readonly=readonly]:hover,[readonly=readonly][type=text]:hover,[readonly=readonly][type=date]:hover,[readonly=readonly][type=datetime]:hover,[readonly=readonly][type=datetime-local]:hover,[readonly=readonly][type=month]:hover,[readonly=readonly][type=time]:hover,[readonly=readonly][type=week]:hover,[readonly=readonly][type=number]:hover,[readonly=readonly][type=search]:hover,[readonly=readonly][type=password]:hover,[readonly=readonly][type=email]:hover,[readonly=readonly][type=url]:hover,[readonly=readonly][type=tel]:hover,select[readonly=readonly]:hover,textarea[readonly]:active,[readonly][type=text]:active,[readonly][type=date]:active,[readonly][type=datetime]:active,[readonly][type=datetime-local]:active,[readonly][type=month]:active,[readonly][type=time]:active,[readonly][type=week]:active,[readonly][type=number]:active,[readonly][type=search]:active,[readonly][type=password]:active,[readonly][type=email]:active,[readonly][type=url]:active,[readonly][type=tel]:active,select[readonly]:active,textarea[readonly=readonly]:active,[readonly=readonly][type=text]:active,[readonly=readonly][type=date]:active,[readonly=readonly][type=datetime]:active,[readonly=readonly][type=datetime-local]:active,[readonly=readonly][type=month]:active,[readonly=readonly][type=time]:active,[readonly=readonly][type=week]:active,[readonly=readonly][type=number]:active,[readonly=readonly][type=search]:active,[readonly=readonly][type=password]:active,[readonly=readonly][type=email]:active,[readonly=readonly][type=url]:active,[readonly=readonly][type=tel]:active,select[readonly=readonly]:active{border-color:#666;outline:none}label{cursor:pointer;max-width:40em;width:fit-content;margin-top:0;margin-bottom:.6rem;padding-top:.4rem;display:inline-block}label.is-required:before{content:"* ";position:relative}label.u-truncate{width:auto}label.has-error{color:#c7162b}label.has-caution{color:#f99b11}label.has-success{color:#0e8420}label.has-information{color:#24598f}[type=file]{width:100%;margin-bottom:1.2rem}[type=file]:focus,[type=file]:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}[type=file]:focus:not(:focus-visible){outline-offset:0;outline:0}[type=search]{appearance:none;border-radius:0}[type=search]::-webkit-search-results-decoration{display:none}[type=search]::-webkit-search-cancel-button{-webkit-appearance:searchfield-cancel-button;cursor:pointer}input[list]::-webkit-calendar-picker-indicator{opacity:0}select{appearance:none;box-shadow:none;color:#111;min-height:1.5rem;text-indent:.01px;text-overflow:"";background-color:#fff;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23666' d='M8.187 11.748l6.187-6.187-1.06-1.061-5.127 5.127L3.061 4.5 2 5.561z'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1rem;padding-right:2rem}select:hover{cursor:pointer}select[multiple],select[size]{box-shadow:none;height:auto;background-image:none}select[multiple] option,select[size] option{padding:.25rem 0;font-weight:300;line-height:calc(1rem - 2px)}textarea{vertical-align:top;margin-bottom:1.2rem;overflow:auto}fieldset{margin-left:0;margin-right:0;padding:calc(1rem - 1px)}hr{margin-bottom:calc(.5rem - 1px)}hr.is-muted{background-color:#0000001a}hr.is-fixed-width{max-width:70rem;width:calc(100% - 2rem);margin-left:auto;margin-right:auto}@media (min-width:620px){hr.is-fixed-width{max-width:69rem;width:calc(100% - 3rem)}}@media (min-width:1036px){hr.is-fixed-width{max-width:69rem;width:calc(100% - 3rem)}}.row hr.is-fixed-width,.u-fixed-width hr.is-fixed-width{width:100%}hr{background:#00000026}hr.is-dark{background:#fff3}.p-button--link,a{color:#06c;text-decoration:none}.p-button--link:focus,a:focus,.p-button--link:focus-visible,a:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}.p-button--link:focus:not(:focus-visible),a:focus:not(:focus-visible){outline-offset:0;outline:0}.p-button--link:focus,a:focus{outline-offset:0}.p-button--link:hover,a:hover{cursor:pointer;text-decoration:underline}.p-button--link:visited,a:visited{color:#7d42b8}ol,ul{margin-top:0;margin-bottom:1.5rem;margin-left:1rem;padding-left:1rem}nav ol,nav ul{list-style:none}li{margin:0;padding:0}li>ul,li>ol{margin-bottom:0;padding-top:0}li>ul>li:last-of-type,li>ol>li:last-of-type{padding-bottom:0}dl{margin-top:0;margin-bottom:1.5rem;padding:0}dd{margin-left:1rem}img{height:auto;max-width:100%;border:0;border-radius:.125rem}figure{width:100%;margin-bottom:1.5rem;margin-left:0}figure caption,figure figcaption{width:100%;margin-top:.25rem;font-style:italic;display:block}iframe{border:0}object,iframe,embed,canvas,video,audio{max-width:100%;margin:0 auto 20px;display:block}audio:not([controls]){height:0;display:none}[hidden]{display:none}table{border-collapse:collapse;caption-side:bottom;width:100%;table-layout:fixed;border:0;margin-bottom:1.5rem;line-height:1.5rem;overflow-x:auto}td,th{text-align:left;text-overflow:ellipsis;vertical-align:top;padding-left:.5rem;padding-right:.5rem;font-weight:300;overflow:hidden}td.has-overflow,th.has-overflow{overflow:visible}thead th{padding-top:.7505rem;padding-bottom:.75rem}thead tr{vertical-align:top;border-bottom:1px solid #00000026}caption{padding-top:.5rem;padding-bottom:.5rem}tfoot tr,tbody tr:not(:first-child){border-top:1px solid #0000001a}.col-12,.col-11,.col-10,.col-9,.col-8,.col-7,.col-6,.col-5,.col-4,.col-3,.col-2,.col-1,.col-medium-6,.col-medium-5,.col-medium-4,.col-medium-3,.col-medium-2,.col-medium-1,.col-small-4,.col-small-3,.col-small-2,.col-small-1{display:block}@media (max-width:619px){.col-12,.col-11,.col-10,.col-9,.col-8,.col-7,.col-6,.col-5,.col-4,.col-3,.col-2,.col-1,.col-medium-6,.col-medium-5,.col-medium-4,.col-medium-3,.col-medium-2,.col-medium-1{grid-column:auto/span 4}}@media (min-width:620px) and (max-width:1035px){.col-12,.col-11,.col-10,.col-9,.col-8,.col-7,.col-6,.col-5,.col-4,.col-3,.col-2,.col-1,.col-small-4,.col-small-3,.col-small-2,.col-small-1{grid-column:auto/span 6}}@media (min-width:1036px){.col-medium-6,.col-medium-5,.col-medium-4,.col-medium-3,.col-medium-2,.col-medium-1,.col-small-4,.col-small-3,.col-small-2,.col-small-1{grid-column:auto/span 12}}.u-fixed-width,.p-navigation__row,.p-stepped-list--detailed .p-stepped-list__item,.row,.p-divider{width:100%;max-width:72rem;margin-left:auto;margin-right:auto}.p-stepped-list--detailed .p-stepped-list__item .p-stepped-list__item,.row .p-stepped-list--detailed .p-stepped-list__item,.p-stepped-list--detailed .row .p-stepped-list__item,.p-stepped-list--detailed .p-stepped-list__item .row,.row .row,.p-divider .p-stepped-list--detailed .p-stepped-list__item,.p-stepped-list--detailed .p-divider .p-stepped-list__item,.p-divider .row,.p-stepped-list--detailed .p-stepped-list__item .p-divider,.row .p-divider,.p-divider .p-divider{margin-left:0;margin-right:0;padding-left:0;padding-right:0}@supports (display: grid){.p-stepped-list--detailed .p-stepped-list__item,.row,.p-divider{grid-gap:0 1.5rem;max-width:72rem;grid-template-rows:auto;grid-template-columns:repeat(4,minmax(0,1fr));margin-left:auto;margin-right:auto;display:grid}.p-stepped-list--detailed .p-stepped-list__item>*,.row>*,.p-divider>*{grid-column-end:span 4}.p-stepped-list--detailed .p-stepped-list__item [class*=col-],.row [class*=col-],.p-divider [class*=col-]{grid-column-start:auto}@media (min-width:620px){.p-stepped-list--detailed .p-stepped-list__item,.row,.p-divider{grid-gap:0 2rem;grid-template-columns:repeat(6,minmax(0,1fr))}.p-stepped-list--detailed .p-stepped-list__item>*,.row>*,.p-divider>*{grid-column-end:span 6}}@media (min-width:1036px){.p-stepped-list--detailed .p-stepped-list__item,.row,.p-divider{grid-gap:0 2rem;grid-template-columns:repeat(12,minmax(0,1fr))}.p-stepped-list--detailed .p-stepped-list__item>*,.row>*,.p-divider>*{grid-column-end:span 12}}}.p-panel__header,.u-fixed-width,.p-navigation__row,.p-stepped-list--detailed .p-stepped-list__item,.row,.p-divider{padding-left:1rem;padding-right:1rem}@media (min-width:620px){.p-panel__header,.u-fixed-width,.p-navigation__row,.p-stepped-list--detailed .p-stepped-list__item,.row,.p-divider{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width:1036px){.p-panel__header,.u-fixed-width,.p-navigation__row,.p-stepped-list--detailed .p-stepped-list__item,.row,.p-divider{padding-left:1.5rem;padding-right:1.5rem}}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:#0009}.token.punctuation{color:#111}.token.namespace{opacity:.7}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.deleted{color:#77216f}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:#0e811f}.token .operator,.token .entity,.token .url,.language-css .token.string,.style .token.string{color:#a86500}.token.atrule,.token.attr-value,.token.keyword{color:#06c}.token.function,.token.class-name{color:#c7162b}.token.regex,.token.important,.token.variable{color:#dc3023}.token.important,.token.bold{font-weight:400}.token.italic{font-style:italic}.token.entity{cursor:help}.p-accordion__list{margin:0 0 1.5rem;padding:0;list-style-type:none}.p-accordion__tab{background-color:inherit;font-size:inherit;text-align:left;width:100%;z-index:2;border:0;border-radius:0;justify-content:flex-start;margin-bottom:0;padding-right:1rem;transition-duration:0s;position:relative}.p-accordion__tab:focus,.p-accordion__tab:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}.p-accordion__tab:focus:not(:focus-visible){outline-offset:0;outline:0}.p-accordion__tab:before{content:"";background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23666' d='M8.187 11.748l6.187-6.187-1.06-1.061-5.127 5.127L3.061 4.5 2 5.561z'/%3E%3C/svg%3E");margin-right:1rem;transition-property:transform;transition-duration:.165s;transition-timing-function:cubic-bezier(.215,.61,.355,1)}.p-accordion__tab[aria-expanded=true]{background-color:inherit}.p-accordion__tab[aria-expanded=true]:hover{background-color:#f2f2f2}.p-accordion__tab[aria-expanded=false]:before{transform:rotate(-90deg)}.p-accordion__heading{max-width:none;margin-bottom:0;padding-top:0}.p-accordion__heading>.p-accordion__tab{font-size:inherit;font-weight:inherit;line-height:inherit}.p-heading--2>.p-accordion__tab:before,h2.p-accordion__heading>.p-accordion__tab:before{height:.517em;width:.517em;vertical-align:0;background-size:contain}.p-heading--3>.p-accordion__tab:before,.p-heading--4>.p-accordion__tab:before,h3.p-accordion__heading>.p-accordion__tab:before,h4.p-accordion__heading>.p-accordion__tab:before{vertical-align:0}.p-accordion__panel{margin:0;padding-left:4rem;overflow:auto}.p-accordion__panel[aria-hidden=true]{display:none}.p-accordion__panel.has-tick-elements{padding-left:1em}.p-article-pagination__link--next:after,.p-article-pagination__link--previous:before{color:#666;content:"›";font-size:2em;position:absolute;top:1rem}.p-article-pagination{width:100%;display:flex}.p-article-pagination__label,.p-article-pagination__title{color:#111;width:100%;margin-top:0;display:block}.p-article-pagination__label{margin-bottom:.25rem}.p-article-pagination__title{font-size:1.125em}@media (min-width:620px){.p-article-pagination__title{font-size:1.25em}}.p-article-pagination__link--next,.p-article-pagination__link--previous{color:#111;width:50%;background-color:#fff;border-color:#0000;margin-top:0;padding:1rem;position:relative}.p-article-pagination__link--next:visited,.p-article-pagination__link--previous:visited{color:#111}.p-article-pagination__link--next:hover,.p-article-pagination__link--previous:hover{background-color:#f2f2f2;border-color:#0000}.p-article-pagination__link--next:active,.p-article-pagination__link--previous:active,[aria-pressed=true].p-article-pagination__link--next,[aria-pressed=true].p-article-pagination__link--previous,[aria-selected=true].p-article-pagination__link--next,[aria-selected=true].p-article-pagination__link--previous,[aria-expanded=true].p-article-pagination__link--next,[aria-expanded=true].p-article-pagination__link--previous{background-color:#e6e6e6;border-color:#0000;transition-duration:0s}.p-article-pagination__link--next:disabled:active,.p-article-pagination__link--previous:disabled:active,.p-article-pagination__link--next:disabled[aria-pressed=true],.p-article-pagination__link--previous:disabled[aria-pressed=true],.p-article-pagination__link--next:disabled[aria-selected=true],.p-article-pagination__link--previous:disabled[aria-selected=true],.p-article-pagination__link--next:disabled[aria-expanded=true],.p-article-pagination__link--previous:disabled[aria-expanded=true],.p-article-pagination__link--next:disabled:hover,.p-article-pagination__link--previous:disabled:hover,.is-disabled.p-article-pagination__link--next:active,.is-disabled.p-article-pagination__link--previous:active,.is-disabled[aria-pressed=true].p-article-pagination__link--next,.is-disabled[aria-pressed=true].p-article-pagination__link--previous,.is-disabled[aria-selected=true].p-article-pagination__link--next,.is-disabled[aria-selected=true].p-article-pagination__link--previous,.is-disabled[aria-expanded=true].p-article-pagination__link--next,.is-disabled[aria-expanded=true].p-article-pagination__link--previous,.is-disabled.p-article-pagination__link--next:hover,.is-disabled.p-article-pagination__link--previous:hover{background-color:#0000;border-color:#0000}.p-article-pagination__link--previous{text-align:left;padding-left:2.5rem}@media (max-width:459px){.p-article-pagination__link--previous{width:auto;margin-right:0}.p-article-pagination__link--previous:only-child{width:100%}.p-article-pagination__link--previous:not(:only-child) *{max-width:.25rem;padding-left:1.5rem;display:none}}.p-article-pagination__link--previous:before{left:.5rem;transform:scaleX(-1)}.p-article-pagination__link--next{text-align:right;padding-right:2.5rem}@media (max-width:459px){.p-article-pagination__link--next{width:100%}}.p-article-pagination__link--next:only-child{margin-left:auto}.p-article-pagination__link--next:after{right:.5rem}.p-breadcrumbs{width:100%;margin:0;padding:0;list-style:none}.p-breadcrumbs__items{margin-left:0;padding-left:0}.p-breadcrumbs__item{margin-bottom:.1rem;display:inline-block}.p-breadcrumbs__item:not(:first-of-type){text-indent:1rem}.p-breadcrumbs__item:not(:first-of-type):before{content:"›";margin-left:-.75rem;margin-right:.5rem}.p-button{color:#111;background-color:#fff;border-color:#0000008f}.p-button:visited{color:#111}.p-button:hover{background-color:#f2f2f2;border-color:#0000008f}.p-button:active,[aria-pressed=true].p-button,[aria-selected=true].p-button,[aria-expanded=true].p-button{background-color:#e6e6e6;border-color:#0000008f;transition-duration:0s}.p-button:disabled:active,.p-button:disabled[aria-pressed=true],.p-button:disabled[aria-selected=true],.p-button:disabled[aria-expanded=true],.p-button:disabled:hover,.is-disabled.p-button:active,.is-disabled[aria-pressed=true].p-button,.is-disabled[aria-selected=true].p-button,.is-disabled[aria-expanded=true].p-button,.is-disabled.p-button:hover{background-color:#0000;border-color:#0000008f}.p-button.is-dark{color:#fff;background-color:#262626;border-color:#999}.p-button.is-dark:visited{color:#fff}.p-button.is-dark:hover{background-color:#ffffff0d;border-color:#999}.p-button.is-dark:active,[aria-pressed=true].p-button.is-dark,[aria-selected=true].p-button.is-dark,[aria-expanded=true].p-button.is-dark{background-color:#ffffff1a;border-color:#999;transition-duration:0s}.p-button.is-dark:disabled:active,.p-button.is-dark:disabled[aria-pressed=true],.p-button.is-dark:disabled[aria-selected=true],.p-button.is-dark:disabled[aria-expanded=true],.p-button.is-dark:disabled:hover,.is-disabled.p-button.is-dark:active,.is-disabled[aria-pressed=true].p-button.is-dark,.is-disabled[aria-selected=true].p-button.is-dark,.is-disabled[aria-expanded=true].p-button.is-dark,.is-disabled.p-button.is-dark:hover{background-color:#0000;border-color:#999}.p-button--brand{color:#fff;background-color:#333;border-color:#333}.p-button--brand:visited{color:#fff}.p-button--brand:hover{background-color:#262626;border-color:#262626}.p-button--brand:active,[aria-pressed=true].p-button--brand,[aria-selected=true].p-button--brand,[aria-expanded=true].p-button--brand{background-color:#1a1a1a;border-color:#1a1a1a;transition-duration:0s}.p-button--brand:disabled:active,.p-button--brand:disabled[aria-pressed=true],.p-button--brand:disabled[aria-selected=true],.p-button--brand:disabled[aria-expanded=true],.p-button--brand:disabled:hover,.is-disabled.p-button--brand:active,.is-disabled[aria-pressed=true].p-button--brand,.is-disabled[aria-selected=true].p-button--brand,.is-disabled[aria-expanded=true].p-button--brand,.is-disabled.p-button--brand:hover{background-color:#333;border-color:#333}.p-button--brand.is-dark{color:#fff;background-color:#333;border-color:#333}.p-button--brand.is-dark:visited{color:#fff}.p-button--brand.is-dark:hover{background-color:#262626;border-color:#262626}.p-button--brand.is-dark:active,[aria-pressed=true].p-button--brand.is-dark,[aria-selected=true].p-button--brand.is-dark,[aria-expanded=true].p-button--brand.is-dark{background-color:#1a1a1a;border-color:#1a1a1a;transition-duration:0s}.p-button--brand.is-dark:disabled:active,.p-button--brand.is-dark:disabled[aria-pressed=true],.p-button--brand.is-dark:disabled[aria-selected=true],.p-button--brand.is-dark:disabled[aria-expanded=true],.p-button--brand.is-dark:disabled:hover,.is-disabled.p-button--brand.is-dark:active,.is-disabled[aria-pressed=true].p-button--brand.is-dark,.is-disabled[aria-selected=true].p-button--brand.is-dark,.is-disabled[aria-expanded=true].p-button--brand.is-dark,.is-disabled.p-button--brand.is-dark:hover{background-color:#333;border-color:#333}.p-button--positive{color:#fff;background-color:#0e8420;border-color:#0e8420}.p-button--positive:visited{color:#fff}.p-button--positive:hover{background-color:#0c6d1a;border-color:#0c6d1a}.p-button--positive:active,[aria-pressed=true].p-button--positive,[aria-selected=true].p-button--positive,[aria-expanded=true].p-button--positive{background-color:#095615;border-color:#095615;transition-duration:0s}.p-button--positive:disabled:active,.p-button--positive:disabled[aria-pressed=true],.p-button--positive:disabled[aria-selected=true],.p-button--positive:disabled[aria-expanded=true],.p-button--positive:disabled:hover,.is-disabled.p-button--positive:active,.is-disabled[aria-pressed=true].p-button--positive,.is-disabled[aria-selected=true].p-button--positive,.is-disabled[aria-expanded=true].p-button--positive,.is-disabled.p-button--positive:hover{background-color:#0e8420;border-color:#0e8420}.p-button--positive:focus,.p-button--positive:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #003008}.p-button--positive:focus:not(:focus-visible){outline-offset:0;outline:0}.p-button--positive.is-dark{color:#fff;background-color:#008013;border-color:#008013}.p-button--positive.is-dark:visited{color:#fff}.p-button--positive.is-dark:hover{background-color:#00670f;border-color:#00670f}.p-button--positive.is-dark:active,[aria-pressed=true].p-button--positive.is-dark,[aria-selected=true].p-button--positive.is-dark,[aria-expanded=true].p-button--positive.is-dark{background-color:#004d0b;border-color:#004d0b;transition-duration:0s}.p-button--positive.is-dark:disabled:active,.p-button--positive.is-dark:disabled[aria-pressed=true],.p-button--positive.is-dark:disabled[aria-selected=true],.p-button--positive.is-dark:disabled[aria-expanded=true],.p-button--positive.is-dark:disabled:hover,.is-disabled.p-button--positive.is-dark:active,.is-disabled[aria-pressed=true].p-button--positive.is-dark,.is-disabled[aria-selected=true].p-button--positive.is-dark,.is-disabled[aria-expanded=true].p-button--positive.is-dark,.is-disabled.p-button--positive.is-dark:hover{background-color:#008013;border-color:#008013}.p-button--positive.is-dark:focus,.p-button--positive.is-dark:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #003008}.p-button--positive.is-dark:focus:not(:focus-visible){outline-offset:0;outline:0}.p-button--negative{color:#fff;background-color:#c7162b;border-color:#c7162b}.p-button--negative:visited{color:#fff}.p-button--negative:hover{background-color:#b01326;border-color:#b01326}.p-button--negative:active,[aria-pressed=true].p-button--negative,[aria-selected=true].p-button--negative,[aria-expanded=true].p-button--negative{background-color:#991121;border-color:#991121;transition-duration:0s}.p-button--negative:disabled:active,.p-button--negative:disabled[aria-pressed=true],.p-button--negative:disabled[aria-selected=true],.p-button--negative:disabled[aria-expanded=true],.p-button--negative:disabled:hover,.is-disabled.p-button--negative:active,.is-disabled[aria-pressed=true].p-button--negative,.is-disabled[aria-selected=true].p-button--negative,.is-disabled[aria-expanded=true].p-button--negative,.is-disabled.p-button--negative:hover{background-color:#c7162b;border-color:#c7162b}.p-button--negative:focus,.p-button--negative:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #3b0006}.p-button--negative:focus:not(:focus-visible){outline-offset:0;outline:0}.p-button--negative.is-dark{color:#fff;background-color:#a11223;border-color:#a11223}.p-button--negative.is-dark:visited{color:#fff}.p-button--negative.is-dark:hover{background-color:#8a0f1e;border-color:#8a0f1e}.p-button--negative.is-dark:active,[aria-pressed=true].p-button--negative.is-dark,[aria-selected=true].p-button--negative.is-dark,[aria-expanded=true].p-button--negative.is-dark{background-color:#730d19;border-color:#730d19;transition-duration:0s}.p-button--negative.is-dark:disabled:active,.p-button--negative.is-dark:disabled[aria-pressed=true],.p-button--negative.is-dark:disabled[aria-selected=true],.p-button--negative.is-dark:disabled[aria-expanded=true],.p-button--negative.is-dark:disabled:hover,.is-disabled.p-button--negative.is-dark:active,.is-disabled[aria-pressed=true].p-button--negative.is-dark,.is-disabled[aria-selected=true].p-button--negative.is-dark,.is-disabled[aria-expanded=true].p-button--negative.is-dark,.is-disabled.p-button--negative.is-dark:hover{background-color:#a11223;border-color:#a11223}.p-button--negative.is-dark:focus,.p-button--negative.is-dark:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #3b0006}.p-button--negative.is-dark:focus:not(:focus-visible){outline-offset:0;outline:0}.p-button--base{color:#111;background-color:#0000;border-color:#0000}.p-button--base:visited{color:#111}.p-button--base:hover{background-color:#f2f2f2;border-color:#0000}.p-button--base:active,[aria-pressed=true].p-button--base,[aria-selected=true].p-button--base,[aria-expanded=true].p-button--base{background-color:#e6e6e6;border-color:#0000;transition-duration:0s}.p-button--base:disabled:active,.p-button--base:disabled[aria-pressed=true],.p-button--base:disabled[aria-selected=true],.p-button--base:disabled[aria-expanded=true],.p-button--base:disabled:hover,.is-disabled.p-button--base:active,.is-disabled[aria-pressed=true].p-button--base,.is-disabled[aria-selected=true].p-button--base,.is-disabled[aria-expanded=true].p-button--base,.is-disabled.p-button--base:hover{background-color:#0000;border-color:#0000}.p-button--base.is-dark{color:#fff;background-color:#0000;border-color:#0000}.p-button--base.is-dark:visited{color:#fff}.p-button--base.is-dark:hover{background-color:#ffffff0d;border-color:#0000}.p-button--base.is-dark:active,[aria-pressed=true].p-button--base.is-dark,[aria-selected=true].p-button--base.is-dark,[aria-expanded=true].p-button--base.is-dark{background-color:#ffffff1a;border-color:#0000;transition-duration:0s}.p-button--base.is-dark:disabled:active,.p-button--base.is-dark:disabled[aria-pressed=true],.p-button--base.is-dark:disabled[aria-selected=true],.p-button--base.is-dark:disabled[aria-expanded=true],.p-button--base.is-dark:disabled:hover,.is-disabled.p-button--base.is-dark:active,.is-disabled[aria-pressed=true].p-button--base.is-dark,.is-disabled[aria-selected=true].p-button--base.is-dark,.is-disabled[aria-expanded=true].p-button--base.is-dark,.is-disabled.p-button--base.is-dark:hover{background-color:#0000;border-color:#0000}.p-button--link{background-color:#0000;border:none;border-radius:0;margin-right:0;padding-bottom:0;padding-left:0;padding-right:0}.p-button--link:hover{background:0 0}p .p-button--link{margin-bottom:0;padding-top:0}[class*=p-button].is-inline{margin-left:1rem}[class*=p-button].is-processing{opacity:1!important}.p-card{padding:calc(1rem - 1px)}.p-card--overlay{color:#111;background:#ffffffe6;margin-bottom:1.5rem;padding:1rem;overflow:auto}.p-card--muted{margin-bottom:1.5rem;padding:1rem;overflow:auto}.p-card__image{width:100%;margin-bottom:.5rem;display:block}.p-card__header{border-bottom:1px solid #d9d9d9;padding-bottom:1rem}.p-card__header>.p-link--soft{display:inline-block;overflow:auto}.p-card__thumbnail{max-height:2rem}[class*=p-card]>p:not([class*=p-heading--]):last-child,[class*=p-card]>h5:last-child,[class*=p-card]>h6:last-child{margin-bottom:.1rem}[class*=p-card]>p:not([class*=p-heading--]):first-child,[class*=p-card]>h5:first-child,[class*=p-card]>h6:first-child{margin-top:-.5rem}.p-chip,.p-chip--positive,.p-chip--caution,.p-chip--negative,.p-chip--information{max-width:100%;user-select:none;vertical-align:calc(1px - .4rem);white-space:nowrap;border-radius:1rem;align-items:baseline;margin:0 .5rem 1.2rem 0;padding:calc(.25rem - 1px) .5rem;transition-property:background-color,border-color;transition-duration:.1s;transition-timing-function:cubic-bezier(.215,.61,.355,1);display:inline-flex;position:relative}.p-chip:focus,.p-chip--positive:focus,.p-chip--caution:focus,.p-chip--negative:focus,.p-chip--information:focus,.p-chip:focus-visible,.p-chip--positive:focus-visible,.p-chip--caution:focus-visible,.p-chip--negative:focus-visible,.p-chip--information:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}.p-chip:focus:not(:focus-visible),.p-chip--positive:focus:not(:focus-visible),.p-chip--caution:focus:not(:focus-visible),.p-chip--negative:focus:not(:focus-visible),.p-chip--information:focus:not(:focus-visible){outline-offset:0;outline:0}.p-chip .p-chip__lead,.p-chip--positive .p-chip__lead,.p-chip--caution .p-chip__lead,.p-chip--negative .p-chip__lead,.p-chip--information .p-chip__lead,.p-chip .p-chip__value,.p-chip--positive .p-chip__value,.p-chip--caution .p-chip__value,.p-chip--negative .p-chip__value,.p-chip--information .p-chip__value{text-overflow:ellipsis;vertical-align:baseline;margin-bottom:0;padding:0;display:inline;overflow:hidden}.p-chip .p-chip__lead,.p-chip--positive .p-chip__lead,.p-chip--caution .p-chip__lead,.p-chip--negative .p-chip__lead,.p-chip--information .p-chip__lead{text-transform:uppercase}.p-chip .p-chip__lead+.p-chip__value:before,.p-chip--positive .p-chip__lead+.p-chip__value:before,.p-chip--caution .p-chip__lead+.p-chip__value:before,.p-chip--negative .p-chip__lead+.p-chip__value:before,.p-chip--information .p-chip__lead+.p-chip__value:before{content:": "}.p-chip .p-chip__value,.p-chip--positive .p-chip__value,.p-chip--caution .p-chip__value,.p-chip--negative .p-chip__value,.p-chip--information .p-chip__value{font-weight:400}.p-chip .p-chip__dismiss,.p-chip--positive .p-chip__dismiss,.p-chip--caution .p-chip__dismiss,.p-chip--negative .p-chip__dismiss,.p-chip--information .p-chip__dismiss{background-size:.75rem;border-radius:50%;flex:none;align-self:center;margin-left:.25rem}@media (min-width:1681px){.p-chip .p-chip__dismiss,.p-chip--positive .p-chip__dismiss,.p-chip--caution .p-chip__dismiss,.p-chip--negative .p-chip__dismiss,.p-chip--information .p-chip__dismiss{background-size:.666667rem}}.is-dense.p-chip,.is-dense.p-chip--positive,.is-dense.p-chip--caution,.is-dense.p-chip--negative,.is-dense.p-chip--information{padding:0 .5rem}.is-inline.p-chip,.is-inline.p-chip--positive,.is-inline.p-chip--caution,.is-inline.p-chip--negative,.is-inline.p-chip--information{vertical-align:baseline;margin:0}.p-chip{background-color:#f2f2f2;border:1px solid #0000008f}.p-chip .p-chip__value,.p-chip .p-chip__lead,.p-chip .p-chip__lead+.p-chip__value:before{color:#111}.p-chip .p-chip__dismiss{color:#111;background-color:#0000;background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23111' fill-rule='nonzero' d='M13.041 1.898l1.06 1.06L9.062 8l5.04 5.042-1.06 1.06L8 9.062 2.96 14.1l-1.06-1.06L6.938 8 1.9 2.96l1.06-1.06 5.04 5.04z'/%3E%3C/svg%3E");border-color:#0000}.p-chip .p-chip__dismiss:visited{color:#111}.p-chip .p-chip__dismiss:hover{background-color:#e5e5e5;border-color:#0000}.p-chip .p-chip__dismiss:active,.p-chip .p-chip__dismiss[aria-pressed=true],.p-chip .p-chip__dismiss[aria-selected=true],.p-chip .p-chip__dismiss[aria-expanded=true]{background-color:#d9d9d9;border-color:#0000;transition-duration:0s}.p-chip .p-chip__dismiss:disabled:active,.p-chip .p-chip__dismiss:disabled[aria-pressed=true],.p-chip .p-chip__dismiss:disabled[aria-selected=true],.p-chip .p-chip__dismiss:disabled[aria-expanded=true],.p-chip .p-chip__dismiss:disabled:hover,.p-chip .p-chip__dismiss.is-disabled:active,.p-chip .p-chip__dismiss.is-disabled[aria-pressed=true],.p-chip .p-chip__dismiss.is-disabled[aria-selected=true],.p-chip .p-chip__dismiss.is-disabled[aria-expanded=true],.p-chip .p-chip__dismiss.is-disabled:hover{background-color:#0000;border-color:#0000008f}.p-chip.is-dark{background-color:#ffffff26;border:1px solid #a6a6a6}.p-chip.is-dark .p-chip__value,.p-chip.is-dark .p-chip__lead,.p-chip.is-dark .p-chip__lead+.p-chip__value:before{color:#fff}.p-chip.is-dark .p-chip__dismiss{color:#111;background-color:#0000;background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='hsl(0deg%2C0%%2C100%)' fill-rule='nonzero' d='M13.041 1.898l1.06 1.06L9.062 8l5.04 5.042-1.06 1.06L8 9.062 2.96 14.1l-1.06-1.06L6.938 8 1.9 2.96l1.06-1.06 5.04 5.04z'/%3E%3C/svg%3E");border-color:#0000}.p-chip.is-dark .p-chip__dismiss:visited{color:#111}.p-chip.is-dark .p-chip__dismiss:hover{background-color:#fff3;border-color:#0000}.p-chip.is-dark .p-chip__dismiss:active,.p-chip.is-dark .p-chip__dismiss[aria-pressed=true],.p-chip.is-dark .p-chip__dismiss[aria-selected=true],.p-chip.is-dark .p-chip__dismiss[aria-expanded=true]{background-color:#ffffff40;border-color:#0000;transition-duration:0s}.p-chip.is-dark .p-chip__dismiss:disabled:active,.p-chip.is-dark .p-chip__dismiss:disabled[aria-pressed=true],.p-chip.is-dark .p-chip__dismiss:disabled[aria-selected=true],.p-chip.is-dark .p-chip__dismiss:disabled[aria-expanded=true],.p-chip.is-dark .p-chip__dismiss:disabled:hover,.p-chip.is-dark .p-chip__dismiss.is-disabled:active,.p-chip.is-dark .p-chip__dismiss.is-disabled[aria-pressed=true],.p-chip.is-dark .p-chip__dismiss.is-disabled[aria-selected=true],.p-chip.is-dark .p-chip__dismiss.is-disabled[aria-expanded=true],.p-chip.is-dark .p-chip__dismiss.is-disabled:hover{background-color:#0000;border-color:#0000008f}button.p-chip{background-color:#f2f2f2;border:1px solid #0000008f}button.p-chip .p-chip__value,button.p-chip .p-chip__lead,button.p-chip .p-chip__lead+.p-chip__value:before{color:#111}button.p-chip:hover{background-color:#e5e5e5;border-color:#0000008f}button.p-chip[aria-pressed=true],button.p-chip.is-selected,button.p-chip:active{background-color:#d9d9d9;border-color:#0000008f}button.p-chip.is-dark{background-color:#ffffff26;border:1px solid #a6a6a6}button.p-chip.is-dark .p-chip__value,button.p-chip.is-dark .p-chip__lead,button.p-chip.is-dark .p-chip__lead+.p-chip__value:before{color:#fff}button.p-chip.is-dark:hover{background-color:#fff3;border-color:#a6a6a6}button.p-chip.is-dark[aria-pressed=true],button.p-chip.is-dark.is-selected,button.p-chip.is-dark:active{background-color:#ffffff40;border-color:#a6a6a6}.p-chip--positive{background-color:#0abd251a;border:1px solid #0e8420}.p-chip--positive .p-chip__value,.p-chip--positive .p-chip__lead,.p-chip--positive .p-chip__lead+.p-chip__value:before{color:#111}.p-chip--positive .p-chip__dismiss{color:#111;background-color:#0000;background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23111' fill-rule='nonzero' d='M13.041 1.898l1.06 1.06L9.062 8l5.04 5.042-1.06 1.06L8 9.062 2.96 14.1l-1.06-1.06L6.938 8 1.9 2.96l1.06-1.06 5.04 5.04z'/%3E%3C/svg%3E");border-color:#0000}.p-chip--positive .p-chip__dismiss:visited{color:#111}.p-chip--positive .p-chip__dismiss:hover{background-color:#00c71e26;border-color:#0000}.p-chip--positive .p-chip__dismiss:active,.p-chip--positive .p-chip__dismiss[aria-pressed=true],.p-chip--positive .p-chip__dismiss[aria-selected=true],.p-chip--positive .p-chip__dismiss[aria-expanded=true]{background-color:#00c71e33;border-color:#0000;transition-duration:0s}.p-chip--positive .p-chip__dismiss:disabled:active,.p-chip--positive .p-chip__dismiss:disabled[aria-pressed=true],.p-chip--positive .p-chip__dismiss:disabled[aria-selected=true],.p-chip--positive .p-chip__dismiss:disabled[aria-expanded=true],.p-chip--positive .p-chip__dismiss:disabled:hover,.p-chip--positive .p-chip__dismiss.is-disabled:active,.p-chip--positive .p-chip__dismiss.is-disabled[aria-pressed=true],.p-chip--positive .p-chip__dismiss.is-disabled[aria-selected=true],.p-chip--positive .p-chip__dismiss.is-disabled[aria-expanded=true],.p-chip--positive .p-chip__dismiss.is-disabled:hover{background-color:#0000;border-color:#0000008f}.p-chip--positive.is-dark{background-color:#0abd2533;border:1px solid #70db80}.p-chip--positive.is-dark .p-chip__value,.p-chip--positive.is-dark .p-chip__lead,.p-chip--positive.is-dark .p-chip__lead+.p-chip__value:before{color:#fff}.p-chip--positive.is-dark .p-chip__dismiss{color:#111;background-color:#0000;background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='hsl(0deg%2C0%%2C100%)' fill-rule='nonzero' d='M13.041 1.898l1.06 1.06L9.062 8l5.04 5.042-1.06 1.06L8 9.062 2.96 14.1l-1.06-1.06L6.938 8 1.9 2.96l1.06-1.06 5.04 5.04z'/%3E%3C/svg%3E");border-color:#0000}.p-chip--positive.is-dark .p-chip__dismiss:visited{color:#111}.p-chip--positive.is-dark .p-chip__dismiss:hover{background-color:#00c71e4d;border-color:#0000}.p-chip--positive.is-dark .p-chip__dismiss:active,.p-chip--positive.is-dark .p-chip__dismiss[aria-pressed=true],.p-chip--positive.is-dark .p-chip__dismiss[aria-selected=true],.p-chip--positive.is-dark .p-chip__dismiss[aria-expanded=true]{background-color:#00c71e66;border-color:#0000;transition-duration:0s}.p-chip--positive.is-dark .p-chip__dismiss:disabled:active,.p-chip--positive.is-dark .p-chip__dismiss:disabled[aria-pressed=true],.p-chip--positive.is-dark .p-chip__dismiss:disabled[aria-selected=true],.p-chip--positive.is-dark .p-chip__dismiss:disabled[aria-expanded=true],.p-chip--positive.is-dark .p-chip__dismiss:disabled:hover,.p-chip--positive.is-dark .p-chip__dismiss.is-disabled:active,.p-chip--positive.is-dark .p-chip__dismiss.is-disabled[aria-pressed=true],.p-chip--positive.is-dark .p-chip__dismiss.is-disabled[aria-selected=true],.p-chip--positive.is-dark .p-chip__dismiss.is-disabled[aria-expanded=true],.p-chip--positive.is-dark .p-chip__dismiss.is-disabled:hover{background-color:#0000;border-color:#0000008f}button.p-chip--positive{background-color:#0abd251a;border:1px solid #0e8420}button.p-chip--positive .p-chip__value,button.p-chip--positive .p-chip__lead,button.p-chip--positive .p-chip__lead+.p-chip__value:before{color:#111}button.p-chip--positive:hover{background-color:#00c71e26;border-color:#0e8420}button.p-chip--positive[aria-pressed=true],button.p-chip--positive.is-selected,button.p-chip--positive:active{background-color:#00c71e33;border-color:#0e8420}button.p-chip--positive.is-dark{background-color:#0abd2533;border:1px solid #70db80}button.p-chip--positive.is-dark .p-chip__value,button.p-chip--positive.is-dark .p-chip__lead,button.p-chip--positive.is-dark .p-chip__lead+.p-chip__value:before{color:#fff}button.p-chip--positive.is-dark:hover{background-color:#00c71e4d;border-color:#70db80}button.p-chip--positive.is-dark[aria-pressed=true],button.p-chip--positive.is-dark.is-selected,button.p-chip--positive.is-dark:active{background-color:#00c71e66;border-color:#70db80}.p-chip--caution{background-color:#c75a001a;border:1px solid #c75a00}.p-chip--caution .p-chip__value,.p-chip--caution .p-chip__lead,.p-chip--caution .p-chip__lead+.p-chip__value:before{color:#111}.p-chip--caution .p-chip__dismiss{color:#111;background-color:#0000;background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23111' fill-rule='nonzero' d='M13.041 1.898l1.06 1.06L9.062 8l5.04 5.042-1.06 1.06L8 9.062 2.96 14.1l-1.06-1.06L6.938 8 1.9 2.96l1.06-1.06 5.04 5.04z'/%3E%3C/svg%3E");border-color:#0000}.p-chip--caution .p-chip__dismiss:visited{color:#111}.p-chip--caution .p-chip__dismiss:hover{background-color:#c75a0026;border-color:#0000}.p-chip--caution .p-chip__dismiss:active,.p-chip--caution .p-chip__dismiss[aria-pressed=true],.p-chip--caution .p-chip__dismiss[aria-selected=true],.p-chip--caution .p-chip__dismiss[aria-expanded=true]{background-color:#c75a0033;border-color:#0000;transition-duration:0s}.p-chip--caution .p-chip__dismiss:disabled:active,.p-chip--caution .p-chip__dismiss:disabled[aria-pressed=true],.p-chip--caution .p-chip__dismiss:disabled[aria-selected=true],.p-chip--caution .p-chip__dismiss:disabled[aria-expanded=true],.p-chip--caution .p-chip__dismiss:disabled:hover,.p-chip--caution .p-chip__dismiss.is-disabled:active,.p-chip--caution .p-chip__dismiss.is-disabled[aria-pressed=true],.p-chip--caution .p-chip__dismiss.is-disabled[aria-selected=true],.p-chip--caution .p-chip__dismiss.is-disabled[aria-expanded=true],.p-chip--caution .p-chip__dismiss.is-disabled:hover{background-color:#0000;border-color:#0000008f}.p-chip--caution.is-dark{background-color:#ff730033;border:1px solid #ed9f5e}.p-chip--caution.is-dark .p-chip__value,.p-chip--caution.is-dark .p-chip__lead,.p-chip--caution.is-dark .p-chip__lead+.p-chip__value:before{color:#fff}.p-chip--caution.is-dark .p-chip__dismiss{color:#111;background-color:#0000;background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='hsl(0deg%2C0%%2C100%)' fill-rule='nonzero' d='M13.041 1.898l1.06 1.06L9.062 8l5.04 5.042-1.06 1.06L8 9.062 2.96 14.1l-1.06-1.06L6.938 8 1.9 2.96l1.06-1.06 5.04 5.04z'/%3E%3C/svg%3E");border-color:#0000}.p-chip--caution.is-dark .p-chip__dismiss:visited{color:#111}.p-chip--caution.is-dark .p-chip__dismiss:hover{background-color:#ff8f334d;border-color:#0000}.p-chip--caution.is-dark .p-chip__dismiss:active,.p-chip--caution.is-dark .p-chip__dismiss[aria-pressed=true],.p-chip--caution.is-dark .p-chip__dismiss[aria-selected=true],.p-chip--caution.is-dark .p-chip__dismiss[aria-expanded=true]{background-color:#ff730066;border-color:#0000;transition-duration:0s}.p-chip--caution.is-dark .p-chip__dismiss:disabled:active,.p-chip--caution.is-dark .p-chip__dismiss:disabled[aria-pressed=true],.p-chip--caution.is-dark .p-chip__dismiss:disabled[aria-selected=true],.p-chip--caution.is-dark .p-chip__dismiss:disabled[aria-expanded=true],.p-chip--caution.is-dark .p-chip__dismiss:disabled:hover,.p-chip--caution.is-dark .p-chip__dismiss.is-disabled:active,.p-chip--caution.is-dark .p-chip__dismiss.is-disabled[aria-pressed=true],.p-chip--caution.is-dark .p-chip__dismiss.is-disabled[aria-selected=true],.p-chip--caution.is-dark .p-chip__dismiss.is-disabled[aria-expanded=true],.p-chip--caution.is-dark .p-chip__dismiss.is-disabled:hover{background-color:#0000;border-color:#0000008f}button.p-chip--caution{background-color:#c75a001a;border:1px solid #c75a00}button.p-chip--caution .p-chip__value,button.p-chip--caution .p-chip__lead,button.p-chip--caution .p-chip__lead+.p-chip__value:before{color:#111}button.p-chip--caution:hover{background-color:#c75a0026;border-color:#c75a00}button.p-chip--caution[aria-pressed=true],button.p-chip--caution.is-selected,button.p-chip--caution:active{background-color:#c75a0033;border-color:#c75a00}button.p-chip--caution.is-dark{background-color:#ff730033;border:1px solid #ed9f5e}button.p-chip--caution.is-dark .p-chip__value,button.p-chip--caution.is-dark .p-chip__lead,button.p-chip--caution.is-dark .p-chip__lead+.p-chip__value:before{color:#fff}button.p-chip--caution.is-dark:hover{background-color:#ff8f334d;border-color:#ed9f5e}button.p-chip--caution.is-dark[aria-pressed=true],button.p-chip--caution.is-dark.is-selected,button.p-chip--caution.is-dark:active{background-color:#ff730066;border-color:#ed9f5e}.p-chip--negative{background-color:#c700141a;border:1px solid #c7162b}.p-chip--negative .p-chip__value,.p-chip--negative .p-chip__lead,.p-chip--negative .p-chip__lead+.p-chip__value:before{color:#111}.p-chip--negative .p-chip__dismiss{color:#111;background-color:#0000;background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23111' fill-rule='nonzero' d='M13.041 1.898l1.06 1.06L9.062 8l5.04 5.042-1.06 1.06L8 9.062 2.96 14.1l-1.06-1.06L6.938 8 1.9 2.96l1.06-1.06 5.04 5.04z'/%3E%3C/svg%3E");border-color:#0000}.p-chip--negative .p-chip__dismiss:visited{color:#111}.p-chip--negative .p-chip__dismiss:hover{background-color:#c7001426;border-color:#0000}.p-chip--negative .p-chip__dismiss:active,.p-chip--negative .p-chip__dismiss[aria-pressed=true],.p-chip--negative .p-chip__dismiss[aria-selected=true],.p-chip--negative .p-chip__dismiss[aria-expanded=true]{background-color:#c7001433;border-color:#0000;transition-duration:0s}.p-chip--negative .p-chip__dismiss:disabled:active,.p-chip--negative .p-chip__dismiss:disabled[aria-pressed=true],.p-chip--negative .p-chip__dismiss:disabled[aria-selected=true],.p-chip--negative .p-chip__dismiss:disabled[aria-expanded=true],.p-chip--negative .p-chip__dismiss:disabled:hover,.p-chip--negative .p-chip__dismiss.is-disabled:active,.p-chip--negative .p-chip__dismiss.is-disabled[aria-pressed=true],.p-chip--negative .p-chip__dismiss.is-disabled[aria-selected=true],.p-chip--negative .p-chip__dismiss.is-disabled[aria-expanded=true],.p-chip--negative .p-chip__dismiss.is-disabled:hover{background-color:#0000;border-color:#0000008f}.p-chip--negative.is-dark{background-color:#ff667833;border:1px solid #f07584}.p-chip--negative.is-dark .p-chip__value,.p-chip--negative.is-dark .p-chip__lead,.p-chip--negative.is-dark .p-chip__lead+.p-chip__value:before{color:#fff}.p-chip--negative.is-dark .p-chip__dismiss{color:#111;background-color:#0000;background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='hsl(0deg%2C0%%2C100%)' fill-rule='nonzero' d='M13.041 1.898l1.06 1.06L9.062 8l5.04 5.042-1.06 1.06L8 9.062 2.96 14.1l-1.06-1.06L6.938 8 1.9 2.96l1.06-1.06 5.04 5.04z'/%3E%3C/svg%3E");border-color:#0000}.p-chip--negative.is-dark .p-chip__dismiss:visited{color:#111}.p-chip--negative.is-dark .p-chip__dismiss:hover{background-color:#ff66784d;border-color:#0000}.p-chip--negative.is-dark .p-chip__dismiss:active,.p-chip--negative.is-dark .p-chip__dismiss[aria-pressed=true],.p-chip--negative.is-dark .p-chip__dismiss[aria-selected=true],.p-chip--negative.is-dark .p-chip__dismiss[aria-expanded=true]{background-color:#ff667866;border-color:#0000;transition-duration:0s}.p-chip--negative.is-dark .p-chip__dismiss:disabled:active,.p-chip--negative.is-dark .p-chip__dismiss:disabled[aria-pressed=true],.p-chip--negative.is-dark .p-chip__dismiss:disabled[aria-selected=true],.p-chip--negative.is-dark .p-chip__dismiss:disabled[aria-expanded=true],.p-chip--negative.is-dark .p-chip__dismiss:disabled:hover,.p-chip--negative.is-dark .p-chip__dismiss.is-disabled:active,.p-chip--negative.is-dark .p-chip__dismiss.is-disabled[aria-pressed=true],.p-chip--negative.is-dark .p-chip__dismiss.is-disabled[aria-selected=true],.p-chip--negative.is-dark .p-chip__dismiss.is-disabled[aria-expanded=true],.p-chip--negative.is-dark .p-chip__dismiss.is-disabled:hover{background-color:#0000;border-color:#0000008f}button.p-chip--negative{background-color:#c700141a;border:1px solid #c7162b}button.p-chip--negative .p-chip__value,button.p-chip--negative .p-chip__lead,button.p-chip--negative .p-chip__lead+.p-chip__value:before{color:#111}button.p-chip--negative:hover{background-color:#c7001426;border-color:#c7162b}button.p-chip--negative[aria-pressed=true],button.p-chip--negative.is-selected,button.p-chip--negative:active{background-color:#c7001433;border-color:#c7162b}button.p-chip--negative.is-dark{background-color:#ff667833;border:1px solid #f07584}button.p-chip--negative.is-dark .p-chip__value,button.p-chip--negative.is-dark .p-chip__lead,button.p-chip--negative.is-dark .p-chip__lead+.p-chip__value:before{color:#fff}button.p-chip--negative.is-dark:hover{background-color:#ff66784d;border-color:#f07584}button.p-chip--negative.is-dark[aria-pressed=true],button.p-chip--negative.is-dark.is-selected,button.p-chip--negative.is-dark:active{background-color:#ff667866;border-color:#f07584}.p-chip--information{background-color:#0063c71a;border:1px solid #24598f}.p-chip--information .p-chip__value,.p-chip--information .p-chip__lead,.p-chip--information .p-chip__lead+.p-chip__value:before{color:#111}.p-chip--information .p-chip__dismiss{color:#111;background-color:#0000;background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23111' fill-rule='nonzero' d='M13.041 1.898l1.06 1.06L9.062 8l5.04 5.042-1.06 1.06L8 9.062 2.96 14.1l-1.06-1.06L6.938 8 1.9 2.96l1.06-1.06 5.04 5.04z'/%3E%3C/svg%3E");border-color:#0000}.p-chip--information .p-chip__dismiss:visited{color:#111}.p-chip--information .p-chip__dismiss:hover{background-color:#0063c726;border-color:#0000}.p-chip--information .p-chip__dismiss:active,.p-chip--information .p-chip__dismiss[aria-pressed=true],.p-chip--information .p-chip__dismiss[aria-selected=true],.p-chip--information .p-chip__dismiss[aria-expanded=true]{background-color:#0063c733;border-color:#0000;transition-duration:0s}.p-chip--information .p-chip__dismiss:disabled:active,.p-chip--information .p-chip__dismiss:disabled[aria-pressed=true],.p-chip--information .p-chip__dismiss:disabled[aria-selected=true],.p-chip--information .p-chip__dismiss:disabled[aria-expanded=true],.p-chip--information .p-chip__dismiss:disabled:hover,.p-chip--information .p-chip__dismiss.is-disabled:active,.p-chip--information .p-chip__dismiss.is-disabled[aria-pressed=true],.p-chip--information .p-chip__dismiss.is-disabled[aria-selected=true],.p-chip--information .p-chip__dismiss.is-disabled[aria-expanded=true],.p-chip--information .p-chip__dismiss.is-disabled:hover{background-color:#0000;border-color:#0000008f}.p-chip--information.is-dark{background-color:#0080ff33;border:1px solid #5ea6ed}.p-chip--information.is-dark .p-chip__value,.p-chip--information.is-dark .p-chip__lead,.p-chip--information.is-dark .p-chip__lead+.p-chip__value:before{color:#fff}.p-chip--information.is-dark .p-chip__dismiss{color:#111;background-color:#0000;background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='hsl(0deg%2C0%%2C100%)' fill-rule='nonzero' d='M13.041 1.898l1.06 1.06L9.062 8l5.04 5.042-1.06 1.06L8 9.062 2.96 14.1l-1.06-1.06L6.938 8 1.9 2.96l1.06-1.06 5.04 5.04z'/%3E%3C/svg%3E");border-color:#0000}.p-chip--information.is-dark .p-chip__dismiss:visited{color:#111}.p-chip--information.is-dark .p-chip__dismiss:hover{background-color:#0080ff4d;border-color:#0000}.p-chip--information.is-dark .p-chip__dismiss:active,.p-chip--information.is-dark .p-chip__dismiss[aria-pressed=true],.p-chip--information.is-dark .p-chip__dismiss[aria-selected=true],.p-chip--information.is-dark .p-chip__dismiss[aria-expanded=true]{background-color:#0080ff66;border-color:#0000;transition-duration:0s}.p-chip--information.is-dark .p-chip__dismiss:disabled:active,.p-chip--information.is-dark .p-chip__dismiss:disabled[aria-pressed=true],.p-chip--information.is-dark .p-chip__dismiss:disabled[aria-selected=true],.p-chip--information.is-dark .p-chip__dismiss:disabled[aria-expanded=true],.p-chip--information.is-dark .p-chip__dismiss:disabled:hover,.p-chip--information.is-dark .p-chip__dismiss.is-disabled:active,.p-chip--information.is-dark .p-chip__dismiss.is-disabled[aria-pressed=true],.p-chip--information.is-dark .p-chip__dismiss.is-disabled[aria-selected=true],.p-chip--information.is-dark .p-chip__dismiss.is-disabled[aria-expanded=true],.p-chip--information.is-dark .p-chip__dismiss.is-disabled:hover{background-color:#0000;border-color:#0000008f}button.p-chip--information{background-color:#0063c71a;border:1px solid #24598f}button.p-chip--information .p-chip__value,button.p-chip--information .p-chip__lead,button.p-chip--information .p-chip__lead+.p-chip__value:before{color:#111}button.p-chip--information:hover{background-color:#0063c726;border-color:#24598f}button.p-chip--information[aria-pressed=true],button.p-chip--information.is-selected,button.p-chip--information:active{background-color:#0063c733;border-color:#24598f}button.p-chip--information.is-dark{background-color:#0080ff33;border:1px solid #5ea6ed}button.p-chip--information.is-dark .p-chip__value,button.p-chip--information.is-dark .p-chip__lead,button.p-chip--information.is-dark .p-chip__lead+.p-chip__value:before{color:#fff}button.p-chip--information.is-dark:hover{background-color:#0080ff4d;border-color:#5ea6ed}button.p-chip--information.is-dark[aria-pressed=true],button.p-chip--information.is-dark.is-selected,button.p-chip--information.is-dark:active{background-color:#0080ff66;border-color:#5ea6ed}.p-badge,.p-badge--negative{box-sizing:content-box;color:#fff;max-width:4ch;background-color:#111;border-radius:1rem;margin-bottom:0;padding:0 .25rem;overflow:hidden}.p-badge--negative{background-color:#c7162b}.p-chip .p-badge,.p-chip .p-badge--negative,[class*=p-chip--] .p-badge,[class*=p-chip--] .p-badge--negative{align-self:center;margin-left:.5rem;margin-right:-.15rem}.p-code-snippet{margin-bottom:1.5rem}.p-code-snippet.is-bordered{border:1px solid #0000001a}.p-code-snippet .p-code-snippet__block,.p-code-snippet .p-code-snippet__block--icon,.p-code-snippet .p-code-snippet__block--numbered{margin:0}.p-code-snippet .p-code-snippet__block.is-wrapped,.p-code-snippet .p-code-snippet__block--icon.is-wrapped,.p-code-snippet .p-code-snippet__block--numbered.is-wrapped{white-space:pre-wrap}.p-code-snippet .p-code-snippet__block--icon{padding-left:2.5rem;position:relative}.p-code-snippet .p-code-snippet__block--icon.is-windows-prompt:before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23666' d='M8.187 11.748l6.187-6.187-1.06-1.061-5.127 5.127L3.061 4.5 2 5.561z'/%3E%3C/svg%3E");transform:rotate(270deg)}.p-code-snippet .p-code-snippet__block--icon.is-url:before{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8.781 4.772c.976.683 1.5 1.77 1.508 2.876l-.065.105c-.317.457-.88.637-1.308.399a.831.831 0 01-.162-.117A2.036 2.036 0 005.177 6.38l-.091.121L2.832 9.72a2.036 2.036 0 003.243 2.456l.092-.121.114-.162a3.582 3.582 0 001.34.7l-.225.322a3.536 3.536 0 11-5.792-4.056L3.857 5.64a3.536 3.536 0 014.924-.868zm4.747-3.042a3.536 3.536 0 01.868 4.924l-2.253 3.218A3.536 3.536 0 015.71 7.865l.065-.105c.317-.458.88-.637 1.308-.4.06.033.113.073.162.117a2.036 2.036 0 003.577 1.656l.091-.121 2.254-3.218a2.036 2.036 0 00-3.243-2.457l-.092.122-.114.162a3.582 3.582 0 00-1.34-.701l.225-.322a3.536 3.536 0 014.924-.868z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-code-snippet .p-code-snippet__block--numbered{counter-reset:line-numbering}.p-code-snippet .p-code-snippet__header{background-color:#00000014;justify-content:space-between;align-items:flex-start;padding-left:1rem;padding-right:1rem;display:flex}.p-code-snippet .p-code-snippet__title{text-overflow:ellipsis;white-space:nowrap;flex:0 auto;margin-bottom:.5rem;padding-top:.5rem;overflow:hidden}.p-code-snippet .p-code-snippet__dropdown{color:#111;min-width:min-content;width:min-content;background-color:#0000;border:0;margin-bottom:0;margin-left:.5rem;padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem}.p-code-snippet .p-code-snippet__dropdowns{flex-shrink:0;display:flex}.p-code-snippet .p-code-snippet__dropdowns:first-child{margin-left:auto}.p-code-snippet .p-code-snippet__dropdown+.p-code-snippet__dropdown{border-left:1px solid #00000026}.p-code-snippet .p-code-snippet__header.is-stacked{flex-direction:column}.p-code-snippet .p-code-snippet__header.is-stacked .p-code-snippet__title{white-space:normal}.p-code-snippet .p-code-snippet__header.is-stacked .p-code-snippet__dropdowns{width:100%;flex:1 0 100%;justify-content:flex-end}.p-code-snippet .p-code-snippet__header.is-stacked .p-code-snippet__title+.p-code-snippet__dropdowns{border-top:1px solid #00000026}.p-code-snippet iframe{width:calc(100% - 1px);margin:0}.p-contextual-menu--center,.p-contextual-menu--left,.p-contextual-menu{margin:0;display:inline-block;position:relative}.p-contextual-menu__dropdown{max-width:21rem;min-width:10rem;width:fit-content;z-index:9;margin:0;padding:0;display:none;position:absolute;right:0}.p-contextual-menu__dropdown[aria-hidden=false]{display:block}.p-contextual-menu--left .p-contextual-menu__dropdown{left:0}.p-contextual-menu--center .p-contextual-menu__dropdown{left:50%;transform:translate(-50%)}.p-contextual-menu__group{display:block}.p-contextual-menu__group+.p-contextual-menu__group{border-top-style:solid;border-top-width:1px;margin:-1px 0 0}.p-contextual-menu__link{clear:both;text-align:left;text-overflow:ellipsis;white-space:nowrap;width:100%;border:0;margin:0;padding:.25rem 1rem;display:block;overflow:hidden}.p-contextual-menu__link:focus,.p-contextual-menu__link:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}.p-contextual-menu__link:focus:not(:focus-visible){outline-offset:0;outline:0}.p-contextual-menu__link:hover{border-radius:.125rem;text-decoration:none}.p-contextual-menu__toggle{margin-right:0}.p-contextual-menu__toggle[aria-expanded=true] .p-contextual-menu__indicator{transform:rotate(180deg)}.p-contextual-menu__dropdown{background:#fff}.p-contextual-menu__group+.p-contextual-menu__group{border-top-color:#00000026}.p-contextual-menu__link,.p-contextual-menu__link:active,.p-contextual-menu__link:hover,.p-contextual-menu__link:visited{color:#111;background-color:#0000}.p-contextual-menu__link:hover{background-color:#f2f2f2}.p-contextual-menu__link:active{cursor:default;background-color:#e6e6e6}[class*=p-contextual-menu].is-dark .p-contextual-menu__dropdown{background:#262626}[class*=p-contextual-menu].is-dark .p-contextual-menu__group+.p-contextual-menu__group{border-top-color:#fff3}[class*=p-contextual-menu].is-dark .p-contextual-menu__link,[class*=p-contextual-menu].is-dark .p-contextual-menu__link:active,[class*=p-contextual-menu].is-dark .p-contextual-menu__link:hover,[class*=p-contextual-menu].is-dark .p-contextual-menu__link:visited{color:#fff;background-color:#0000}[class*=p-contextual-menu].is-dark .p-contextual-menu__link:hover{background-color:#ffffff0d}[class*=p-contextual-menu].is-dark .p-contextual-menu__link:active{cursor:default;background-color:#ffffff1a}.p-divider{margin-bottom:1.5rem}.p-divider__block{position:relative}@media (max-width:1035px){.p-divider__block{padding-top:1rem;padding-bottom:1rem}.p-divider__block:not(:first-child):before{content:"";height:1px;position:absolute;top:0;left:0;right:0}}@media (min-width:1036px){.p-divider__block:not(:first-child):before{content:"";width:1px;position:absolute;top:0;bottom:0;left:-1rem}}.p-divider__block{color:#111}.p-divider__block:not(:first-child):before{background-color:#00000026}.p-divider.is-dark .p-divider__block{color:#fff}.p-divider.is-dark .p-divider__block:not(:first-child):before{background-color:#fff3}.p-form-help-text{color:#666;margin-top:-.5rem}.p-form-help-text.is-tick-element{margin-left:2rem}.is-error .p-form-validation__message,.is-caution .p-form-validation__message,.is-success .p-form-validation__message{background-position:0,50%;background-repeat:no-repeat;padding-top:0;padding-left:1.5rem}.p-form-validation__message{margin-top:-.5rem}.is-success .p-form-validation__input{border-color:#0e8420}.is-success .p-form-validation__message{color:#0e8420;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cg fill='none' fill-rule='nonzero'%3E%3Cpath fill='%230e8420' d='M8 1a7 7 0 110 14A7 7 0 018 1zm2.83 3.502L6.863 9.884 5.174 8.096l-1.09 1.03 2.92 3.096 5.034-6.83-1.208-.89z'/%3E%3Cpath fill='%23fff' d='M10.83 4.502l1.208.89-5.033 6.83-2.922-3.096 1.091-1.03 1.689 1.789z'/%3E%3C/g%3E%3C/svg%3E")}.is-caution .p-form-validation__input{border-color:#f99b11}.is-caution .p-form-validation__message{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath d='M9.34 1.2l5.842 11.627A1.5 1.5 0 0113.842 15H2.158a1.5 1.5 0 01-1.34-2.173L6.66 1.2a1.5 1.5 0 012.68 0z' fill='%23f99b11'/%3E%3Cpath d='M8.5 11a.5.5 0 01.492.41L9 11.5v1a.5.5 0 01-.41.492L8.5 13h-1a.5.5 0 01-.492-.41L7 12.5v-1a.5.5 0 01.41-.492L7.5 11h1zM9 5v4.5H7V5h2z' fill='%23FFF'/%3E%3C/g%3E%3C/svg%3E")}.is-error .p-form-validation__input{border-color:#c7162b}.is-error .p-form-validation__message{color:#c7162b;background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Ccircle stroke='%23c7162b' stroke-width='1.5' fill='%23c7162b' cx='8' cy='8' r='6.25'/%3E%3Cpath fill='%23FFF' fill-rule='nonzero' d='M10.282 4.638l1.06 1.06L9.05 7.99l2.293 2.292-1.06 1.06L7.99 9.05 5.7 11.343l-1.06-1.06 2.29-2.293L4.64 5.7l1.06-1.06 2.291 2.29z'/%3E%3C/g%3E%3C/svg%3E")}.p-checkbox__input,.p-radio__input{float:none;height:1rem;opacity:0;width:1rem;margin:0;position:absolute}.p-checkbox__label,.p-radio__label{padding-left:2rem;position:relative}.p-checkbox__label:before,.p-radio__label:before,.p-checkbox__label:after,.p-radio__label:after{transition-property:background-color,border-color;transition-duration:.333s;transition-timing-function:cubic-bezier(.215,.61,.355,1);position:absolute}.p-checkbox__label:before,.p-radio__label:before{content:"";height:1rem;outline-offset:1px;width:1rem;top:calc(.932em - .85rem);left:0}.p-checkbox__label:after,.p-radio__label:after{content:"";opacity:0}.p-muted-heading .p-checkbox__label,.p-muted-heading .p-radio__label{color:#0009}.p-checkbox__input:checked+.p-checkbox__label:before,.p-radio__input:checked+.p-radio__label:before,[aria-checked=mixed]+.p-checkbox__label:before,:indeterminate+.p-checkbox__label:before{background-color:#06c;border-color:#06c}.p-checkbox__input:checked+.p-checkbox__label:after,.p-radio__input:checked+.p-radio__label:after,[aria-checked=mixed]+.p-checkbox__label:after,:indeterminate+.p-checkbox__label:after{opacity:1}.p-checkbox__input:focus+.p-checkbox__label:before,.p-radio__input:focus+.p-radio__label:before{outline:.1875rem solid #2e96ff}.p-checkbox__label:before{border-radius:.125rem}.p-checkbox__label:after{height:.375rem;width:.625rem;border-bottom:2px solid;border-left:2px solid;top:calc(.932em - .6625rem);left:.1875rem;transform:rotate(-45deg)}[aria-checked=mixed]+.p-checkbox__label:after,:indeterminate+.p-checkbox__label:after{border-left:none;transform:none}.p-radio__label:before{border-radius:50%}.p-radio__label:after{height:.375rem;width:.375rem;border-radius:50%;top:calc(.932em - .5375rem);left:.3125rem}.p-checkbox--heading .p-checkbox__label:before,.p-checkbox--heading .p-checkbox__label:after,.p-radio--heading .p-radio__label:before,.p-radio--heading .p-radio__label:after{margin-top:-.15rem}.p-checkbox,.p-checkbox--heading,.p-checkbox--inline,.p-radio,.p-radio--heading,.p-radio--inline{position:relative}.p-checkbox.is-required:before,.p-checkbox--heading.is-required:before,.p-checkbox--inline.is-required:before,.p-radio.is-required:before,.p-radio--heading.is-required:before,.p-radio--inline.is-required:before{width:1ch;display:block;position:absolute;left:2rem}.p-checkbox.is-required .p-radio__label,.p-checkbox.is-required .p-checkbox__label,.p-checkbox--heading.is-required .p-radio__label,.p-checkbox--heading.is-required .p-checkbox__label,.p-checkbox--inline.is-required .p-radio__label,.p-checkbox--inline.is-required .p-checkbox__label,.p-radio.is-required .p-radio__label,.p-radio.is-required .p-checkbox__label,.p-radio--heading.is-required .p-radio__label,.p-radio--heading.is-required .p-checkbox__label,.p-radio--inline.is-required .p-radio__label,.p-radio--inline.is-required .p-checkbox__label{padding-left:calc(2rem + 1ch)}.p-checkbox,.p-radio{text-indent:-2rem;padding-left:2rem;display:block}.p-checkbox.is-required:before,.p-radio.is-required:before{left:4rem}.p-checkbox__input,.p-radio__input{bottom:.2em}.p-checkbox--heading,.p-checkbox--inline,.p-radio--heading,.p-radio--inline{display:inline}.p-radio+.p-radio,.p-checkbox+.p-checkbox,.p-checkbox+.p-radio,.p-radio+.p-checkbox{margin-top:-.5rem}.p-checkbox__label{color:#111}.p-checkbox__label:before{background:#fff;border:1px solid #0000008f}.p-checkbox__label:after{color:#fff}.p-radio__label{color:#111}.p-radio__label:before{background:#fff;border:1px solid #0000008f}.p-radio__label:after{background-color:#fff}.p-checkbox.is-dark .p-checkbox__label{color:#fff}.p-checkbox.is-dark .p-checkbox__label:before{background:#262626;border:1px solid #999}.p-checkbox.is-dark .p-checkbox__label:after,.p-radio.is-dark .p-radio__label{color:#fff}.p-radio.is-dark .p-radio__label:before{background:#262626;border:1px solid #999}.p-radio.is-dark .p-radio__label:after{background-color:#fff}.p-form--stacked{width:100%}@media (min-width:1036px){.p-form--stacked .p-form__group{align-items:baseline}.p-form--stacked .p-form__group+.p-form__group{margin-top:.5rem}.p-form--inline{flex-flow:wrap;align-items:baseline;display:inline-flex}.p-form--inline>*{margin-right:1.5rem}.p-form--inline .p-form__group{width:auto;flex-shrink:1;display:flex}.p-form--inline .p-form__group+[class*=p-button]{flex-shrink:1}.p-form--inline .p-form__group .p-form__label,.p-form--inline .p-form__group .p-form__control,.p-form--inline .p-form__group .p-form-validation__message{box-sizing:border-box;align-self:baseline}.p-form--inline .p-form__group .p-form__label{flex-shrink:0;padding-right:1rem}.p-form--inline .p-form__group .p-form__control{display:inline-block}}form+[class*=p-button]{margin-top:1.5rem}.grid-demo [class*=col-]{background:#c7162b1a;margin-bottom:.5rem}@media (max-width:619px){.col-small-4{width:100%}@supports (display: grid){.col-small-4{grid-column-end:span 4}.col-small-4 .row{grid-template-columns:repeat(4,minmax(0,1fr))}}.col-small-3{width:100%}@supports (display: grid){.col-small-3{grid-column-end:span 3}.col-small-3 .row{grid-template-columns:repeat(3,minmax(0,1fr))}}.col-small-2{width:100%}@supports (display: grid){.col-small-2{grid-column-end:span 2}.col-small-2 .row{grid-template-columns:repeat(2,minmax(0,1fr))}}.col-small-1{width:100%}@supports (display: grid){.col-small-1{grid-column-end:span 1}}}@media (min-width:620px) and (max-width:1035px){.col-medium-6{width:100%}@supports (display: grid){.col-medium-6{grid-column-end:span 6}.col-medium-6 .row{grid-template-columns:repeat(6,minmax(0,1fr))}}.col-medium-5{width:100%}@supports (display: grid){.col-medium-5{grid-column-end:span 5}.col-medium-5 .row{grid-template-columns:repeat(5,minmax(0,1fr))}}.col-medium-4{width:100%}@supports (display: grid){.col-medium-4{grid-column-end:span 4}.col-medium-4 .row{grid-template-columns:repeat(4,minmax(0,1fr))}}.col-medium-3{width:100%}@supports (display: grid){.col-medium-3{grid-column-end:span 3}.col-medium-3 .row{grid-template-columns:repeat(3,minmax(0,1fr))}}.col-medium-2{width:100%}@supports (display: grid){.col-medium-2{grid-column-end:span 2}.col-medium-2 .row{grid-template-columns:repeat(2,minmax(0,1fr))}}.col-medium-1{width:100%}@supports (display: grid){.col-medium-1{grid-column-end:span 1}}}@media (min-width:1036px){@supports (display: grid){.col-12{grid-column-end:span 12}.col-12 .row{grid-template-columns:repeat(12,minmax(0,1fr))}.col-11{grid-column-end:span 11}.col-11 .row{grid-template-columns:repeat(11,minmax(0,1fr))}.col-10{grid-column-end:span 10}.col-10 .row{grid-template-columns:repeat(10,minmax(0,1fr))}.col-9{grid-column-end:span 9}.col-9 .row{grid-template-columns:repeat(9,minmax(0,1fr))}.col-8{grid-column-end:span 8}.col-8 .row{grid-template-columns:repeat(8,minmax(0,1fr))}.col-7{grid-column-end:span 7}.col-7 .row{grid-template-columns:repeat(7,minmax(0,1fr))}.col-6{grid-column-end:span 6}.col-6 .row{grid-template-columns:repeat(6,minmax(0,1fr))}.col-5{grid-column-end:span 5}.col-5 .row{grid-template-columns:repeat(5,minmax(0,1fr))}.col-4{grid-column-end:span 4}.col-4 .row{grid-template-columns:repeat(4,minmax(0,1fr))}.col-3{grid-column-end:span 3}.col-3 .row{grid-template-columns:repeat(3,minmax(0,1fr))}.col-2{grid-column-end:span 2}.col-2 .row{grid-template-columns:repeat(2,minmax(0,1fr))}.col-1{grid-column-end:span 1}}}@media (max-width:619px){.row [class*=col-].col-start-small-1{grid-column-start:1}.col-order-small-1{order:1}.row [class*=col-].col-start-small-2{grid-column-start:2}.col-order-small-2{order:2}.row [class*=col-].col-start-small-3{grid-column-start:3}.col-order-small-3{order:3}}@media (min-width:620px) and (max-width:1035px){.row [class*=col-].col-start-medium-1{grid-column-start:1}.col-order-medium-1{order:1}.row [class*=col-].col-start-medium-2{grid-column-start:2}.col-order-medium-2{order:2}.row [class*=col-].col-start-medium-3{grid-column-start:3}.col-order-medium-3{order:3}.row [class*=col-].col-start-medium-4{grid-column-start:4}.col-order-medium-4{order:4}.row [class*=col-].col-start-medium-5{grid-column-start:5}.col-order-medium-5{order:5}}@media (min-width:1036px){.row [class*=col-].col-start-large-1{grid-column-start:1}.col-order-large-1{order:1}.row [class*=col-].col-start-large-2{grid-column-start:2}.col-order-large-2{order:2}.row [class*=col-].col-start-large-3{grid-column-start:3}.col-order-large-3{order:3}.row [class*=col-].col-start-large-4{grid-column-start:4}.col-order-large-4{order:4}.row [class*=col-].col-start-large-5{grid-column-start:5}.col-order-large-5{order:5}.row [class*=col-].col-start-large-6{grid-column-start:6}.col-order-large-6{order:6}.row [class*=col-].col-start-large-7{grid-column-start:7}.col-order-large-7{order:7}.row [class*=col-].col-start-large-8{grid-column-start:8}.col-order-large-8{order:8}.row [class*=col-].col-start-large-9{grid-column-start:9}.col-order-large-9{order:9}.row [class*=col-].col-start-large-10{grid-column-start:10}.col-order-large-10{order:10}.row [class*=col-].col-start-large-11{grid-column-start:11}.col-order-large-11{order:11}}.row.is-bordered{position:relative}.row.is-bordered:before{content:"";height:1px;background:#d9d9d9;position:absolute;left:1rem;right:1rem}@media (min-width:620px) and (max-width:1035px){.row.is-bordered:before{left:1.5rem;right:1.5rem}}@media (min-width:1036px){.row.is-bordered:before{left:1.5rem;right:1.5rem}}.p-heading-icon{margin-bottom:1.5rem}@media (min-width:1036px){.p-heading-icon{margin-bottom:0}}.p-heading-icon__header{display:flex}.p-heading-icon__header.is-stacked{display:inherit}.p-heading-icon__img{height:2rem;width:2rem;flex-shrink:0;margin-top:.5rem;margin-bottom:0;margin-right:1rem}@media (min-width:1036px){.p-heading-icon__img{height:2.5rem;width:2.5rem;margin-top:.1rem}}.p-heading-icon--small .p-heading-icon__img{height:1.5rem;width:1.5rem;margin-top:.25rem}@media (min-width:1036px){.p-heading-icon--small .p-heading-icon__img{height:2rem;width:2rem;margin-top:0}}.p-form-password-toggle{justify-content:space-between;align-items:flex-start;display:flex}.p-form-password-toggle__label{margin-right:.125rem;display:inline-block}h1 [class*=p-icon],.p-heading--1 [class*=p-icon],.u-match-h1 [class*=p-icon],h2 [class*=p-icon],.p-heading--2 [class*=p-icon],.u-match-h2 [class*=p-icon]{height:.517em;width:.517em;vertical-align:0;background-size:contain}h3 [class*=p-icon],.p-heading--3 [class*=p-icon],.u-match-h3 [class*=p-icon]{height:1rem;width:1rem;vertical-align:0;background-size:contain}h4 [class*=p-icon],.p-heading--4 [class*=p-icon],.u-match-h4 [class*=p-icon]{vertical-align:0}.p-icon--anchor{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 1a2.5 2.5 0 01.75 4.885v1.068h2.27v1.5H8.75v5.022c2.438-.161 4.172-1.077 4.172-1.669h1.5C14.422 13.57 11.547 15 8 15c-3.547 0-6.422-1.43-6.422-3.194h1.5c0 .592 1.734 1.508 4.172 1.67V8.452H4.904v-1.5H7.25V5.886A2.501 2.501 0 018 1zm0 1.5a1 1 0 100 2 1 1 0 000-2z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--anchor,.p-icon--anchor.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 1a2.5 2.5 0 01.75 4.885v1.068h2.27v1.5H8.75v5.022c2.438-.161 4.172-1.077 4.172-1.669h1.5C14.422 13.57 11.547 15 8 15c-3.547 0-6.422-1.43-6.422-3.194h1.5c0 .592 1.734 1.508 4.172 1.67V8.452H4.904v-1.5H7.25V5.886A2.501 2.501 0 018 1zm0 1.5a1 1 0 100 2 1 1 0 000-2z' fill='%23e5e5e5' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-icon--plus{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23666' fill-rule='nonzero' d='M8.75 1.151V7.25l6.099.001v1.5h-6.1l.001 6.099h-1.5v-6.1L1.15 8.75v-1.5H7.25L7.25 1.15z'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--plus,.p-icon--plus.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23e5e5e5' fill-rule='nonzero' d='M8.75 1.151V7.25l6.099.001v1.5h-6.1l.001 6.099h-1.5v-6.1L1.15 8.75v-1.5H7.25L7.25 1.15z'/%3E%3C/svg%3E")}.p-icon--minus{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23666' fill-rule='nonzero' d='M14.849 7.25v1.5H1.15v-1.5z'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--minus,.p-icon--minus.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23e5e5e5' fill-rule='nonzero' d='M14.849 7.25v1.5H1.15v-1.5z'/%3E%3C/svg%3E")}.p-icon--expand{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 1a3 3 0 012.995 2.824L15 4v8a3 3 0 01-2.824 2.995L12 15H4a3 3 0 01-2.995-2.824L1 12V4a3 3 0 012.824-2.995L4 1h8zm0 1.5H4l-.144.007a1.5 1.5 0 00-1.35 1.349L2.5 4v8l.007.144a1.5 1.5 0 001.349 1.35L4 13.5h8l.144-.007a1.5 1.5 0 001.35-1.349L13.5 12V4l-.007-.144a1.5 1.5 0 00-1.349-1.35L12 2.5zm-1.25 3.372l1.061 1.06-3.784 3.786-3.785-3.785 1.06-1.06 2.724 2.723 2.725-2.724z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--expand,.p-icon--expand.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 1a3 3 0 012.995 2.824L15 4v8a3 3 0 01-2.824 2.995L12 15H4a3 3 0 01-2.995-2.824L1 12V4a3 3 0 012.824-2.995L4 1h8zm0 1.5H4l-.144.007a1.5 1.5 0 00-1.35 1.349L2.5 4v8l.007.144a1.5 1.5 0 001.349 1.35L4 13.5h8l.144-.007a1.5 1.5 0 001.35-1.349L13.5 12V4l-.007-.144a1.5 1.5 0 00-1.349-1.35L12 2.5zm-1.25 3.372l1.061 1.06-3.784 3.786-3.785-3.785 1.06-1.06 2.724 2.723 2.725-2.724z' fill='%23e5e5e5' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-icon--collapse{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 1a3 3 0 013 3v8a3 3 0 01-3 3H4a3 3 0 01-3-3V4a3 3 0 013-3h8zm0 1.5H4a1.5 1.5 0 00-1.493 1.356L2.5 4v8a1.5 1.5 0 001.356 1.493L4 13.5h8a1.5 1.5 0 001.493-1.356L13.5 12V4a1.5 1.5 0 00-1.356-1.493L12 2.5zM8.027 5.282l3.76 3.76-1.06 1.061-2.701-2.7-2.699 2.7-1.06-1.06 3.76-3.76z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--collapse,.p-icon--collapse.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 1a3 3 0 013 3v8a3 3 0 01-3 3H4a3 3 0 01-3-3V4a3 3 0 013-3h8zm0 1.5H4a1.5 1.5 0 00-1.493 1.356L2.5 4v8a1.5 1.5 0 001.356 1.493L4 13.5h8a1.5 1.5 0 001.493-1.356L13.5 12V4a1.5 1.5 0 00-1.356-1.493L12 2.5zM8.027 5.282l3.76 3.76-1.06 1.061-2.701-2.7-2.699 2.7-1.06-1.06 3.76-3.76z' fill='%23e5e5e5' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-icon--chevron-up{transform:rotate(180deg)}.p-icon--chevron-down,.p-icon--chevron-up{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23666' d='M8.187 11.748l6.187-6.187-1.06-1.061-5.127 5.127L3.061 4.5 2 5.561z'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--chevron-down,.p-icon--chevron-down.is-light,[class*=--dark] .p-icon--chevron-up,.p-icon--chevron-up.is-light{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23e5e5e5' d='M8.187 11.748l6.187-6.187-1.06-1.061-5.127 5.127L3.061 4.5 2 5.561z'/%3E%3C/svg%3E")}.p-icon--close{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23666' fill-rule='nonzero' d='M13.041 1.898l1.06 1.06L9.062 8l5.04 5.042-1.06 1.06L8 9.062 2.96 14.1l-1.06-1.06L6.938 8 1.9 2.96l1.06-1.06 5.04 5.04z'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--close,.p-icon--close.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23e5e5e5' fill-rule='nonzero' d='M13.041 1.898l1.06 1.06L9.062 8l5.04 5.042-1.06 1.06L8 9.062 2.96 14.1l-1.06-1.06L6.938 8 1.9 2.96l1.06-1.06 5.04 5.04z'/%3E%3C/svg%3E")}.p-icon--help,.p-icon--question{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 1a7 7 0 110 14A7 7 0 018 1zm0 1.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zm.5 7.5a.5.5 0 01.5.5v1a.5.5 0 01-.5.5h-1a.5.5 0 01-.5-.5v-1a.5.5 0 01.5-.5h1zm-.33-6.154c.448 0 .818.06 1.11.18.29.119.52.27.688.452.169.182.286.382.353.6.066.217.1.424.1.62s-.03.377-.09.542c-.06.165-.135.317-.226.457s-.196.274-.315.4l-.177.184-.434.442a2.493 2.493 0 00-.247.3 1.808 1.808 0 00-.184.331.92.92 0 00-.065.234l-.009.119v.126l.003.079.008.068H7.296l-.017-.112-.009-.124-.005-.227c0-.196.024-.373.073-.53.05-.159.114-.306.195-.443.08-.137.174-.264.279-.384l.16-.176.166-.17c.161-.162.309-.322.442-.48a.816.816 0 00.2-.541.565.565 0 00-.195-.432c-.13-.119-.32-.178-.573-.178-.253 0-.491.031-.716.094-.168.048-.35.117-.546.207l-.2.098-.442-1.188.17-.1c.234-.128.5-.23.797-.305a4.422 4.422 0 011.095-.143z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--help,.p-icon--help.is-light,[class*=--dark] .p-icon--question,.p-icon--question.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 1a7 7 0 110 14A7 7 0 018 1zm0 1.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zm.5 7.5a.5.5 0 01.5.5v1a.5.5 0 01-.5.5h-1a.5.5 0 01-.5-.5v-1a.5.5 0 01.5-.5h1zm-.33-6.154c.448 0 .818.06 1.11.18.29.119.52.27.688.452.169.182.286.382.353.6.066.217.1.424.1.62s-.03.377-.09.542c-.06.165-.135.317-.226.457s-.196.274-.315.4l-.177.184-.434.442a2.493 2.493 0 00-.247.3 1.808 1.808 0 00-.184.331.92.92 0 00-.065.234l-.009.119v.126l.003.079.008.068H7.296l-.017-.112-.009-.124-.005-.227c0-.196.024-.373.073-.53.05-.159.114-.306.195-.443.08-.137.174-.264.279-.384l.16-.176.166-.17c.161-.162.309-.322.442-.48a.816.816 0 00.2-.541.565.565 0 00-.195-.432c-.13-.119-.32-.178-.573-.178-.253 0-.491.031-.716.094-.168.048-.35.117-.546.207l-.2.098-.442-1.188.17-.1c.234-.128.5-.23.797-.305a4.422 4.422 0 011.095-.143z' fill='%23e5e5e5' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-icon--information{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 1a7 7 0 110 14A7 7 0 018 1zm0 1.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM8.75 7v5.02h-1.5V7h1.5zM8.5 3.944a.5.5 0 01.5.5v1a.5.5 0 01-.5.5h-1a.5.5 0 01-.5-.5v-1a.5.5 0 01.5-.5h1z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--information,.p-icon--information.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 1a7 7 0 110 14A7 7 0 018 1zm0 1.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM8.75 7v5.02h-1.5V7h1.5zM8.5 3.944a.5.5 0 01.5.5v1a.5.5 0 01-.5.5h-1a.5.5 0 01-.5-.5v-1a.5.5 0 01.5-.5h1z' fill='%23e5e5e5' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-icon--delete{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.5 6v6a1.5 1.5 0 001.356 1.493L6 13.5h4a1.5 1.5 0 001.493-1.356L11.5 12V6H13v6a3 3 0 01-3 3H6a3 3 0 01-3-3V6h1.5zm3 0v5.994H6V6h1.5zm2.498 0v5.994h-1.5V6h1.5zM8.5 0A2.5 2.5 0 0111 2.5V3h3v1.5H2V3h3v-.5A2.5 2.5 0 017.5 0h1zm0 1.5h-1a1 1 0 00-.993.883L6.5 2.5V3h3v-.5a1 1 0 00-.883-.993L8.5 1.5z' fill='%23666' fill-rule='evenodd'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--delete,.p-icon--delete.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.5 6v6a1.5 1.5 0 001.356 1.493L6 13.5h4a1.5 1.5 0 001.493-1.356L11.5 12V6H13v6a3 3 0 01-3 3H6a3 3 0 01-3-3V6h1.5zm3 0v5.994H6V6h1.5zm2.498 0v5.994h-1.5V6h1.5zM8.5 0A2.5 2.5 0 0111 2.5V3h3v1.5H2V3h3v-.5A2.5 2.5 0 017.5 0h1zm0 1.5h-1a1 1 0 00-.993.883L6.5 2.5V3h3v-.5a1 1 0 00-.883-.993L8.5 1.5z' fill='%23e5e5e5' fill-rule='evenodd'/%3E%3C/svg%3E")}.p-icon--error{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Ccircle stroke='%23c7162b' stroke-width='1.5' fill='%23c7162b' cx='8' cy='8' r='6.25'/%3E%3Cpath fill='%23FFF' fill-rule='nonzero' d='M10.282 4.638l1.06 1.06L9.05 7.99l2.293 2.292-1.06 1.06L7.99 9.05 5.7 11.343l-1.06-1.06 2.29-2.293L4.64 5.7l1.06-1.06 2.291 2.29z'/%3E%3C/g%3E%3C/svg%3E")}.p-icon--warning{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath d='M9.34 1.2l5.842 11.627A1.5 1.5 0 0113.842 15H2.158a1.5 1.5 0 01-1.34-2.173L6.66 1.2a1.5 1.5 0 012.68 0z' fill='%23f99b11'/%3E%3Cpath d='M8.5 11a.5.5 0 01.492.41L9 11.5v1a.5.5 0 01-.41.492L8.5 13h-1a.5.5 0 01-.492-.41L7 12.5v-1a.5.5 0 01.41-.492L7.5 11h1zM9 5v4.5H7V5h2z' fill='%23FFF'/%3E%3C/g%3E%3C/svg%3E")}.p-icon--external-link{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9.157 3l-1.5 1.5H6a.5.5 0 00-.492.41L5.5 5v5a.5.5 0 00.41.492L6 10.5h5a.5.5 0 00.492-.41L11.5 10V8.538l1.5-1.5V10a2 2 0 01-2 2H6a2 2 0 01-2-2V5a2 2 0 012-2h3.157zm5.593-1.75V6h-1.5V3.81L8.5 8.56 7.44 7.5l4.748-4.75H10v-1.5h4.75z' fill='%23666' fill-rule='evenodd'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--external-link,.p-icon--external-link.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9.157 3l-1.5 1.5H6a.5.5 0 00-.492.41L5.5 5v5a.5.5 0 00.41.492L6 10.5h5a.5.5 0 00.492-.41L11.5 10V8.538l1.5-1.5V10a2 2 0 01-2 2H6a2 2 0 01-2-2V5a2 2 0 012-2h3.157zm5.593-1.75V6h-1.5V3.81L8.5 8.56 7.44 7.5l4.748-4.75H10v-1.5h4.75z' fill='%23e5e5e5' fill-rule='evenodd'/%3E%3C/svg%3E")}.p-icon--drag{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 12.49a1.5 1.5 0 110 3 1.5 1.5 0 010-3zm-6 0a1.5 1.5 0 110 3 1.5 1.5 0 010-3zm6-5.99a1.5 1.5 0 110 3 1.5 1.5 0 010-3zm-6 0a1.5 1.5 0 110 3 1.5 1.5 0 010-3zm6-5.99a1.5 1.5 0 110 3 1.5 1.5 0 010-3zm-6 0a1.5 1.5 0 110 3 1.5 1.5 0 010-3z' fill='%23666' fill-rule='evenodd'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--drag,.p-icon--drag.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 12.49a1.5 1.5 0 110 3 1.5 1.5 0 010-3zm-6 0a1.5 1.5 0 110 3 1.5 1.5 0 010-3zm6-5.99a1.5 1.5 0 110 3 1.5 1.5 0 010-3zm-6 0a1.5 1.5 0 110 3 1.5 1.5 0 010-3zm6-5.99a1.5 1.5 0 110 3 1.5 1.5 0 010-3zm-6 0a1.5 1.5 0 110 3 1.5 1.5 0 010-3z' fill='%23e5e5e5' fill-rule='evenodd'/%3E%3C/svg%3E")}.p-icon--code{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.385 2.09v1.38l.27.028c.35.041.668.102.952.182.284.08.519.154.704.22l.129.05-.42 1.545-.18-.07a7.536 7.536 0 00-.848-.252A5.21 5.21 0 004.77 5.03c-.48 0-.812.085-.997.255a.79.79 0 00-.278.6c0 .16.032.293.097.398a.854.854 0 00.3.277c.135.08.298.158.488.233l.311.118.364.13c.39.15.75.307 1.08.472.33.165.615.355.855.57.24.215.428.467.563.757.135.29.202.63.202 1.02 0 .27-.04.538-.12.803a2.11 2.11 0 01-.397.735c-.186.225-.43.42-.736.585a3.275 3.275 0 01-.923.313l-.224.04v1.604h-1.71v-1.59l-.263-.028c-.51-.061-.93-.152-1.26-.272a6.716 6.716 0 01-.759-.319l-.103-.056.57-1.47.199.089c.273.116.582.224.926.324.43.125.885.187 1.365.187.56 0 .95-.072 1.17-.217.22-.145.33-.373.33-.683a.83.83 0 00-.128-.465 1.219 1.219 0 00-.375-.352 3 3 0 00-.607-.285L3.9 8.51c-.29-.1-.575-.215-.855-.345a3.35 3.35 0 01-.75-.472 2.14 2.14 0 01-.532-.675c-.135-.265-.203-.593-.203-.983 0-.28.037-.55.113-.81.075-.26.194-.5.36-.72.164-.22.382-.412.652-.577.216-.132.47-.24.763-.324l.227-.059V2.09h1.71zm9.603 9.16v1.5H8.982v-1.5h6.006z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--code,.p-icon--code.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.385 2.09v1.38l.27.028c.35.041.668.102.952.182.284.08.519.154.704.22l.129.05-.42 1.545-.18-.07a7.536 7.536 0 00-.848-.252A5.21 5.21 0 004.77 5.03c-.48 0-.812.085-.997.255a.79.79 0 00-.278.6c0 .16.032.293.097.398a.854.854 0 00.3.277c.135.08.298.158.488.233l.311.118.364.13c.39.15.75.307 1.08.472.33.165.615.355.855.57.24.215.428.467.563.757.135.29.202.63.202 1.02 0 .27-.04.538-.12.803a2.11 2.11 0 01-.397.735c-.186.225-.43.42-.736.585a3.275 3.275 0 01-.923.313l-.224.04v1.604h-1.71v-1.59l-.263-.028c-.51-.061-.93-.152-1.26-.272a6.716 6.716 0 01-.759-.319l-.103-.056.57-1.47.199.089c.273.116.582.224.926.324.43.125.885.187 1.365.187.56 0 .95-.072 1.17-.217.22-.145.33-.373.33-.683a.83.83 0 00-.128-.465 1.219 1.219 0 00-.375-.352 3 3 0 00-.607-.285L3.9 8.51c-.29-.1-.575-.215-.855-.345a3.35 3.35 0 01-.75-.472 2.14 2.14 0 01-.532-.675c-.135-.265-.203-.593-.203-.983 0-.28.037-.55.113-.81.075-.26.194-.5.36-.72.164-.22.382-.412.652-.577.216-.132.47-.24.763-.324l.227-.059V2.09h1.71zm9.603 9.16v1.5H8.982v-1.5h6.006z' fill='%23e5e5e5' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-icon--menu{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M14 12.25v1.5H2v-1.5h12zm0-5v1.5H2v-1.5h12zm0-5v1.5H2v-1.5h12z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--menu,.p-icon--menu.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M14 12.25v1.5H2v-1.5h12zm0-5v1.5H2v-1.5h12zm0-5v1.5H2v-1.5h12z' fill='%23e5e5e5' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-icon--copy{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.731 10v2.274h2.275v1.5h-2.275v2.232h-1.5v-2.232H10v-1.5h2.231V10h1.5zM11 4.948H5V3.5H3.5v10h5V15h-5A1.5 1.5 0 012 13.5v-10A1.5 1.5 0 013.5 2h1.67a3.001 3.001 0 015.66 0h1.67A1.5 1.5 0 0114 3.5v3.709h-1.5V3.5H11v1.448zM8 1.5a1.5 1.5 0 00-1.493 1.356L6.5 3v.447h3V3a1.5 1.5 0 00-1.356-1.493L8 1.5z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--copy,.p-icon--copy.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.731 10v2.274h2.275v1.5h-2.275v2.232h-1.5v-2.232H10v-1.5h2.231V10h1.5zM11 4.948H5V3.5H3.5v10h5V15h-5A1.5 1.5 0 012 13.5v-10A1.5 1.5 0 013.5 2h1.67a3.001 3.001 0 015.66 0h1.67A1.5 1.5 0 0114 3.5v3.709h-1.5V3.5H11v1.448zM8 1.5a1.5 1.5 0 00-1.493 1.356L6.5 3v.447h3V3a1.5 1.5 0 00-1.356-1.493L8 1.5z' fill='%23e5e5e5' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-icon--search{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.964 1a5.964 5.964 0 014.709 9.623l4.303 4.305-1.06 1.06-4.306-4.305A5.964 5.964 0 116.963 1zm0 1.5a4.464 4.464 0 100 8.927 4.464 4.464 0 000-8.927z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--search,.p-icon--search.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.964 1a5.964 5.964 0 014.709 9.623l4.303 4.305-1.06 1.06-4.306-4.305A5.964 5.964 0 116.963 1zm0 1.5a4.464 4.464 0 100 8.927 4.464 4.464 0 000-8.927z' fill='%23e5e5e5' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-icon--success{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cg fill='none' fill-rule='nonzero'%3E%3Cpath fill='%230e8420' d='M8 1a7 7 0 110 14A7 7 0 018 1zm2.83 3.502L6.863 9.884 5.174 8.096l-1.09 1.03 2.92 3.096 5.034-6.83-1.208-.89z'/%3E%3Cpath fill='%23fff' d='M10.83 4.502l1.208.89-5.033 6.83-2.922-3.096 1.091-1.03 1.689 1.789z'/%3E%3C/g%3E%3C/svg%3E")}.p-icon--share{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 0a3 3 0 11-2.123 5.12L6.869 7.12a3 3 0 01-.029 1.848l3.058 1.89a3 3 0 11-.774 1.285l-3.109-1.922a3 3 0 11.068-4.381l3.032-2.017A3.002 3.002 0 0112 0zm0 11.5a1.5 1.5 0 100 3 1.5 1.5 0 000-3zm-8-5a1.5 1.5 0 100 3 1.5 1.5 0 000-3zm8-5a1.5 1.5 0 100 3 1.5 1.5 0 000-3z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--share,.p-icon--share.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 0a3 3 0 11-2.123 5.12L6.869 7.12a3 3 0 01-.029 1.848l3.058 1.89a3 3 0 11-.774 1.285l-3.109-1.922a3 3 0 11.068-4.381l3.032-2.017A3.002 3.002 0 0112 0zm0 11.5a1.5 1.5 0 100 3 1.5 1.5 0 000-3zm-8-5a1.5 1.5 0 100 3 1.5 1.5 0 000-3zm8-5a1.5 1.5 0 100 3 1.5 1.5 0 000-3z' fill='%23e5e5e5' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-icon--user{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 1a4 4 0 014 4v.5a3.987 3.987 0 01-1.139 2.795 6 6 0 014.135 5.48L15 14H1a6.003 6.003 0 014.14-5.706A3.98 3.98 0 014 5.5V5a4 4 0 014-4zm1 8.5H7a4.502 4.502 0 00-4.203 2.888l-.04.112h10.486l-.03-.084a4.504 4.504 0 00-4-2.911L9 9.5zm-1-7a2.5 2.5 0 00-2.495 2.336L5.5 5v.5a2.5 2.5 0 004.995.164L10.5 5.5V5A2.5 2.5 0 008 2.5z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--user,.p-icon--user.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 1a4 4 0 014 4v.5a3.987 3.987 0 01-1.139 2.795 6 6 0 014.135 5.48L15 14H1a6.003 6.003 0 014.14-5.706A3.98 3.98 0 014 5.5V5a4 4 0 014-4zm1 8.5H7a4.502 4.502 0 00-4.203 2.888l-.04.112h10.486l-.03-.084a4.504 4.504 0 00-4-2.911L9 9.5zm-1-7a2.5 2.5 0 00-2.495 2.336L5.5 5v.5a2.5 2.5 0 004.995.164L10.5 5.5V5A2.5 2.5 0 008 2.5z' fill='%23e5e5e5' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-icon--spinner{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 13.5a5.488 5.488 0 004.183-1.929l1.317.76A6.988 6.988 0 018 15a6.988 6.988 0 01-5.5-2.669l1.316-.76A5.488 5.488 0 008 13.5zM6.999 1.071v1.52A5.502 5.502 0 002.815 9.84L1.5 10.6A7.002 7.002 0 016.764 1.11l.235-.038zM15 8c0 .918-.177 1.795-.498 2.6l-1.317-.761A5.502 5.502 0 009 2.59V1.07c3.392.485 6 3.403 6 6.929z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--spinner,.p-icon--spinner.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 13.5a5.488 5.488 0 004.183-1.929l1.317.76A6.988 6.988 0 018 15a6.988 6.988 0 01-5.5-2.669l1.316-.76A5.488 5.488 0 008 13.5zM6.999 1.071v1.52A5.502 5.502 0 002.815 9.84L1.5 10.6A7.002 7.002 0 016.764 1.11l.235-.038zM15 8c0 .918-.177 1.795-.498 2.6l-1.317-.761A5.502 5.502 0 009 2.59V1.07c3.392.485 6 3.403 6 6.929z' fill='%23e5e5e5' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-icon--facebook{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='40' height='40'%3E%3Cdefs%3E%3Cpath id='a' d='M.002.002H40v39.755H.002z'/%3E%3C/defs%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cmask id='b' fill='%23fff'%3E%3Cuse xlink:href='%23a'/%3E%3C/mask%3E%3Cpath fill='%231877F2' d='M40 20C40 8.954 31.046 0 20 0S0 8.954 0 20c0 9.983 7.314 18.257 16.875 19.757V25.781h-5.078V20h5.078v-4.406c0-5.013 2.986-7.781 7.554-7.781 2.188 0 4.477.39 4.477.39v4.922h-2.522c-2.484 0-3.259 1.542-3.259 3.123V20h5.547l-.887 5.781h-4.66v13.976C32.686 38.257 40 29.983 40 20' mask='url(%23b)'/%3E%3Cpath fill='%23FFF' d='M27.785 25.781L28.672 20h-5.547v-3.752c0-1.581.775-3.123 3.26-3.123h2.521V8.203s-2.289-.39-4.477-.39c-4.568 0-7.554 2.768-7.554 7.78V20h-5.078v5.781h5.078v13.976a20.15 20.15 0 006.25 0V25.781h4.66'/%3E%3C/g%3E%3C/svg%3E")}.p-icon--github{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 187 182'%3E%3Cpath d='M93.04.43C41.669.43.013 42.079.013 93.457c0 41.103 26.655 75.973 63.617 88.273 4.649.86 6.356-2.02 6.356-4.48 0-2.21-.086-9.54-.126-17.32-25.88 5.63-31.341-10.97-31.341-10.97-4.232-10.75-10.329-13.61-10.329-13.61-8.441-5.78.636-5.66.636-5.66 9.341.66 14.26 9.59 14.26 9.59 8.297 14.22 21.762 10.11 27.071 7.73.835-6.01 3.246-10.12 5.906-12.44C55.4 132.22 33.68 124.24 33.68 88.598c0-10.156 3.634-18.454 9.585-24.97-.966-2.344-4.15-11.804.901-24.618 0 0 7.812-2.501 25.589 9.535 7.421-2.061 15.379-3.095 23.284-3.13 7.901.035 15.871 1.069 23.301 3.13 17.76-12.036 25.56-9.535 25.56-9.535 5.06 12.814 1.88 22.274.91 24.618 5.97 6.515 9.58 14.814 9.58 24.97 0 35.732-21.77 43.602-42.48 45.902 3.34 2.89 6.31 8.55 6.31 17.23 0 12.44-.11 22.46-.11 25.52 0 2.48 1.68 5.38 6.39 4.47 36.94-12.32 63.57-47.18 63.57-88.264 0-51.378-41.65-93.027-93.03-93.027' fill='%231B1817' fill-rule='evenodd'/%3E%3C/svg%3E")}.p-icon--twitter{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40'%3E%3Cg fill='none'%3E%3Ccircle cx='20' cy='20' r='20' fill='%231DA1F2'/%3E%3Cpath fill='%23FFF' d='M16.34 30.55c8.87 0 13.72-7.35 13.72-13.72 0-.21 0-.42-.01-.62.94-.68 1.76-1.53 2.41-2.5-.86.38-1.79.64-2.77.76 1-.6 1.76-1.54 2.12-2.67-.93.55-1.96.95-3.06 1.17a4.799 4.799 0 00-3.52-1.52c-2.66 0-4.82 2.16-4.82 4.82 0 .38.04.75.13 1.1a13.68 13.68 0 01-9.94-5.04c-.41.71-.65 1.54-.65 2.42a4.8 4.8 0 002.15 4.01c-.79-.02-1.53-.24-2.18-.6v.06c0 2.34 1.66 4.28 3.87 4.73a4.807 4.807 0 01-2.18.08 4.815 4.815 0 004.5 3.35 9.693 9.693 0 01-7.14 1.99c2.11 1.38 4.65 2.18 7.37 2.18'/%3E%3C/g%3E%3C/svg%3E")}.p-icon--instagram{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40'%3E%3Cdefs%3E%3ClinearGradient id='a' x1='50%25' x2='50%25' y1='99.709%25' y2='.777%25'%3E%3Cstop offset='0%25' stop-color='%23E09B3D'/%3E%3Cstop offset='30%25' stop-color='%23C74C4D'/%3E%3Cstop offset='60%25' stop-color='%23C21975'/%3E%3Cstop offset='100%25' stop-color='%237024C4'/%3E%3C/linearGradient%3E%3ClinearGradient id='b' x1='50%25' x2='50%25' y1='146.099%25' y2='-45.16%25'%3E%3Cstop offset='0%25' stop-color='%23E09B3D'/%3E%3Cstop offset='30%25' stop-color='%23C74C4D'/%3E%3Cstop offset='60%25' stop-color='%23C21975'/%3E%3Cstop offset='100%25' stop-color='%237024C4'/%3E%3C/linearGradient%3E%3ClinearGradient id='c' x1='50%25' x2='50%25' y1='658.141%25' y2='-140.029%25'%3E%3Cstop offset='0%25' stop-color='%23E09B3D'/%3E%3Cstop offset='30%25' stop-color='%23C74C4D'/%3E%3Cstop offset='60%25' stop-color='%23C21975'/%3E%3Cstop offset='100%25' stop-color='%237024C4'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cg fill='none'%3E%3Cpath fill='url(%23a)' d='M28.035 0h-16.14C5.336 0 0 5.336 0 11.895v16.14C0 34.594 5.336 39.93 11.895 39.93h16.14c6.559 0 11.895-5.336 11.895-11.895v-16.14C39.93 5.336 34.594 0 28.035 0zm7.878 28.035a7.878 7.878 0 01-7.878 7.878h-16.14a7.878 7.878 0 01-7.878-7.878v-16.14a7.878 7.878 0 017.878-7.878h16.14a7.878 7.878 0 017.878 7.878v16.14z'/%3E%3Cpath fill='url(%23b)' d='M19.965 9.638c-5.694 0-10.327 4.633-10.327 10.327s4.633 10.327 10.327 10.327 10.327-4.633 10.327-10.327c0-5.695-4.633-10.327-10.327-10.327zm0 16.637a6.31 6.31 0 110-12.62 6.31 6.31 0 010 12.62z'/%3E%3Ccircle cx='30.312' cy='9.715' r='2.475' fill='url(%23c)'/%3E%3C/g%3E%3C/svg%3E")}.p-icon--linkedin{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath fill='%232867B2' fill-rule='nonzero' d='M2.956 0h34.088C38.677 0 40 1.283 40 2.865v34.27C40 38.717 38.677 40 37.044 40H2.956C1.323 40 0 38.717 0 37.135V2.865C0 1.283 1.323 0 2.956 0z'/%3E%3Cpath fill='%23FFF' d='M12.146 34.5V15H6v19.5zM9.054 12.65c2.216 0 3.596-1.589 3.596-3.575-.041-2.03-1.38-3.575-3.554-3.575S5.5 7.045 5.5 9.075c0 1.986 1.38 3.575 3.512 3.575h.042zM21.724 34.5V23.587c0-.584.04-1.167.205-1.585.45-1.167 1.474-2.375 3.194-2.375 2.252 0 3.153 1.792 3.153 4.419V34.5H34.5V23.295c0-6.002-3.07-8.795-7.166-8.795-3.358 0-4.832 1.959-5.651 3.293h.042v-2.834H15.5c.082 1.833 0 19.541 0 19.541h6.224z'/%3E%3C/g%3E%3C/svg%3E")}.p-icon--youtube{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='40' height='40'%3E%3Cdefs%3E%3Cpath id='a' d='M.014.009H40v28.173H.014z'/%3E%3C/defs%3E%3Cg fill='none' fill-rule='evenodd' transform='translate(0 6)'%3E%3Cmask id='b' fill='%23fff'%3E%3Cuse xlink:href='%23a'/%3E%3C/mask%3E%3Cpath fill='%23DA322A' d='M39.164 4.4A5.026 5.026 0 0035.628.842C32.508 0 20 0 20 0S7.492 0 4.372.841a5.026 5.026 0 00-3.536 3.56C0 7.54 0 14.09 0 14.09s0 6.55.836 9.69a5.026 5.026 0 003.536 3.56c3.12.84 15.628.84 15.628.84s12.508 0 15.628-.84a5.026 5.026 0 003.536-3.56c.836-3.14.836-9.69.836-9.69s0-6.55-.836-9.69' mask='url(%23b)'/%3E%3Cpath fill='%23FFFFFE' d='M15.909 20.038V8.143l10.455 5.948-10.455 5.947'/%3E%3C/g%3E%3C/svg%3E")}.p-icon--rss{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40'%3E%3Cg fill='none'%3E%3Crect width='40' height='40' fill='%23EA7819' rx='5' transform='rotate(180 20 20)'/%3E%3Cpath fill='%23FFF' d='M6.34 6.274c15.07 0 27.332 12.314 27.332 27.452H28.41c0-12.236-9.9-22.19-22.07-22.19zM6.334 15.6c9.95 0 18.044 8.128 18.044 18.119h-5.261c0-3.44-1.33-6.671-3.747-9.097a12.657 12.657 0 00-9.036-3.76zm3.639 10.805a3.645 3.645 0 110 7.29 3.645 3.645 0 010-7.29z'/%3E%3C/g%3E%3C/svg%3E")}.p-icon--email{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40'%3E%3Cg fill='none'%3E%3Ccircle cx='20' cy='20' r='20' fill='%23666'/%3E%3Cpath fill='%23FFF' d='M13.688 20.68a.312.312 0 01.432 0l2.888 2.752A4.344 4.344 0 0020 24.624l.238-.006a4.344 4.344 0 002.754-1.186l2.864-2.752a.312.312 0 01.432 0l7.92 7.92a.312.312 0 01-.224.528h-28a.312.312 0 01-.216-.528zM33.8 13.184a.304.304 0 01.512.224V26.52a.304.304 0 01-.52.224l-6.664-6.728a.304.304 0 010-.432zm-27.608 0l6.664 6.4a.296.296 0 010 .432l-6.664 6.728a.304.304 0 01-.52-.224V13.408a.312.312 0 01.52-.224zm27.696-2.328a.352.352 0 01.24.608L22.544 22.496A3.688 3.688 0 0120 23.512l-.218-.006a3.656 3.656 0 01-2.326-1.01L5.864 11.464a.352.352 0 01.24-.608z'/%3E%3C/g%3E%3C/svg%3E")}.p-icon--medium{height:1.25rem;width:1.25rem;background-size:contain}.p-icon--large{height:1.5rem;width:1.5rem;background-size:contain}.p-icon--x-large{height:2.25rem;width:2.25rem;background-size:contain}.p-icon--xx-large{height:3rem;width:3rem;background-size:contain}.p-icon--show{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 3.002c2.946 0 5.612 1.666 8 4.998-2.388 3.332-5.054 4.998-8 4.998-2.946 0-5.612-1.666-8-4.998 2.388-3.332 5.054-4.998 8-4.998zM8 5a3 3 0 100 6 3 3 0 000-6zm0 1.49a1.51 1.51 0 110 3.02 1.51 1.51 0 010-3.02z' fill='%23666' fill-rule='evenodd'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--show,.p-icon--show.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 3.002c2.946 0 5.612 1.666 8 4.998-2.388 3.332-5.054 4.998-8 4.998-2.946 0-5.612-1.666-8-4.998 2.388-3.332 5.054-4.998 8-4.998zM8 5a3 3 0 100 6 3 3 0 000-6zm0 1.49a1.51 1.51 0 110 3.02 1.51 1.51 0 010-3.02z' fill='%23e5e5e5' fill-rule='evenodd'/%3E%3C/svg%3E")}.p-icon--hide{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.938.624l1.06 1.06-2.653 2.653c1.27.823 2.475 2.026 3.616 3.61v.106l-.193.264C13.44 11.44 10.851 13 8 13a7.654 7.654 0 01-3.479-.839l-2.354 2.354-1.06-1.06L13.937.624zm-2.682 4.802L9.714 6.969a2 2 0 01-2.745 2.745L5.653 11.03a6.114 6.114 0 002.098.465L8 11.5c2.076 0 4.03-1.042 5.893-3.233l.222-.268-.222-.266c-.858-1.01-1.736-1.775-2.637-2.307zM8 3c.608 0 1.203.07 1.787.213L8.482 4.519a6.072 6.072 0 00-.233-.014L8 4.5c-2.076 0-4.03 1.042-5.893 3.233L1.884 8l.223.267c.428.503.86.946 1.3 1.33l-1.062 1.061C1.535 9.938.754 9.052 0 8c2.388-3.333 5.054-5 8-5z' fill='%23666' fill-rule='evenodd'/%3E%3C/svg%3E")}[class*=--dark] .p-icon--hide,.p-icon--hide.is-light{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.938.624l1.06 1.06-2.653 2.653c1.27.823 2.475 2.026 3.616 3.61v.106l-.193.264C13.44 11.44 10.851 13 8 13a7.654 7.654 0 01-3.479-.839l-2.354 2.354-1.06-1.06L13.937.624zm-2.682 4.802L9.714 6.969a2 2 0 01-2.745 2.745L5.653 11.03a6.114 6.114 0 002.098.465L8 11.5c2.076 0 4.03-1.042 5.893-3.233l.222-.268-.222-.266c-.858-1.01-1.736-1.775-2.637-2.307zM8 3c.608 0 1.203.07 1.787.213L8.482 4.519a6.072 6.072 0 00-.233-.014L8 4.5c-2.076 0-4.03 1.042-5.893 3.233L1.884 8l.223.267c.428.503.86.946 1.3 1.33l-1.062 1.061C1.535 9.938.754 9.052 0 8c2.388-3.333 5.054-5 8-5z' fill='%23e5e5e5' fill-rule='evenodd'/%3E%3C/svg%3E")}.p-image--bordered{border:1px solid #d9d9d9}.p-image--shadowed{box-shadow:0 1px 5px 1px #d9d9d933}.p-link--soft{color:#111}.p-link--soft:visited{color:#111;text-decoration:none}.p-link--soft:hover{color:#06c}.p-link--soft.is-selected{font-weight:400}.p-link--inverted{color:#f7f7f7;font-weight:400}.p-link--inverted:hover{color:#f7f7f7}.p-link--inverted:visited{color:#dedede}.p-link--skip{color:#06c;display:block;position:absolute;top:-999px;left:-999px}.p-link--skip:focus{z-index:999999;padding:.25rem;position:relative;top:0;left:0}.p-link--skip:focus:focus,.p-link--skip:focus:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}.p-link--skip:focus:focus:not(:focus-visible){outline-offset:0;outline:0}.p-top{align-items:center;display:flex}.p-top:before{content:"";border-bottom:1px solid #00000026;flex-grow:1;margin:1.5rem 0 calc(1.5rem - 1px)}.p-top:after{content:"";background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 4.349l4.685 4.684-.884.884-3.052-3.051.001 7.526h-1.5V6.866L4.2 9.917l-.885-.884L8 4.35zm7.025-3.099v1.5H1.051v-1.5h13.974z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E");margin-right:.5rem}.p-top__link{color:#111;padding:0 .5rem 0 1rem;text-decoration:none}.p-list-tree__item--group:after,.p-list-tree .p-list-tree[aria-hidden=false]:after{content:" ";height:.9375rem;pointer-events:none;width:.9375rem;background-position:50%;background-repeat:no-repeat;display:block;position:absolute;top:.4rem;left:-.75rem}.p-list-tree{border-left:1px solid #d9d9d9;margin-left:1rem;padding:0 0 0 .25rem;list-style-type:none}.p-list-tree .p-list-tree{margin-left:0;display:none}.p-list-tree .p-list-tree[aria-hidden=false]{display:block}.p-list-tree .p-list-tree[aria-hidden=false]:after{z-index:1;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='15' width='15' viewBox='0 0 15 15'%3E%3Cdefs%3E%3Cpath id='a' d='M0 0h15v15H0z'/%3E%3C/defs%3E%3Cg fill-rule='evenodd' fill='none'%3E%3Cuse xlink:href='%23a' fill='%23FFF'/%3E%3Cpath stroke='%23888' d='M.5.5h14v14H.5z'/%3E%3Cpath fill='%23888' d='M4 8V7h7v1z'/%3E%3C/g%3E%3C/svg%3E")}.p-list-tree__item{margin-top:.125rem;padding-left:.8rem;position:relative}.p-list-tree__item:focus,.p-list-tree__item:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}.p-list-tree__item:focus:not(:focus-visible){outline-offset:0;outline:0}.p-list-tree__item:before{content:" ";height:1px;pointer-events:none;width:.625rem;background:#d9d9d9;display:block;position:absolute;top:.8rem;left:-.25rem}.p-list-tree__item--group:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='15' width='15' viewBox='0 0 15 15'%3E%3Cdefs%3E%3Cpath id='a' d='M0 0h15v15H0z'/%3E%3C/defs%3E%3Cg fill-rule='evenodd' fill='none'%3E%3Cuse xlink:href='%23a' fill='%23FFF'/%3E%3Cpath stroke='%23888' d='M.5.5h14v14H.5z'/%3E%3Cpath fill='%23888' d='M7 4h1v7H7z'/%3E%3Cpath fill='%23888' d='M4 8V7h7v1z'/%3E%3C/g%3E%3C/svg%3E")}.p-list-tree__toggle{background:0 0;border:0;margin:0 .5rem 0 -1.75rem;padding:0 .5rem 0 1.75rem;font-weight:400;transition-duration:0s}.p-list-tree__toggle:focus,.p-list-tree__toggle:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}.p-list-tree__toggle:focus:not(:focus-visible){outline-offset:0;outline:0}.p-list-tree__toggle:hover{color:#06c;background:0 0;text-decoration:underline}.p-stepped-list--detailed,.p-stepped-list{counter-reset:li;flex-direction:column;padding-left:0;list-style:none;display:flex}.p-stepped-list__title{margin-left:0;list-style:none}.p-stepped-list__title:before{content:counter(li);counter-increment:li;direction:rtl;text-align:center;background-color:#e5e5e5;border-radius:100%;align-self:start;display:block;position:absolute;left:0}.p-list--nested-counter{counter-reset:list-item}.p-list--nested-counter li::marker{content:counters(list-item,".")". ";counter-increment:list-item}.p-list--divided .p-list__item,.p-list__item{padding-top:.25rem;padding-bottom:.25rem}form .p-list--divided .p-list__item,.p-list--divided form .p-list__item,form .p-list__item{padding-top:0;padding-bottom:0}form .p-list--divided .p-list__item label,.p-list--divided form .p-list__item label,form .p-list__item label{margin-bottom:.1rem}.is-crossed,.is-ticked{background-position-y:.55rem;background-repeat:no-repeat;background-size:.875rem;padding-left:2rem}.p-list--divided .p-list__item{position:relative}.p-list--divided .p-list__item:after{content:"";height:1px;border-bottom:1px solid #d9d9d9;position:absolute;bottom:0;left:0;right:0}.p-list--divided .p-list__item:last-of-type:after,.p-list--divided .p-list__item .last-item:after{border-bottom:0}.p-list--divided.is-split .p-list__item:last-of-type{border-bottom:1px solid #d9d9d9}.is-ticked{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cg fill='none' fill-rule='nonzero'%3E%3Cpath fill='%230e8420' d='M8 1a7 7 0 110 14A7 7 0 018 1zm2.83 3.502L6.863 9.884 5.174 8.096l-1.09 1.03 2.92 3.096 5.034-6.83-1.208-.89z'/%3E%3Cpath fill='%23fff' d='M10.83 4.502l1.208.89-5.033 6.83-2.922-3.096 1.091-1.03 1.689 1.789z'/%3E%3C/g%3E%3C/svg%3E")}.is-crossed{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Ccircle stroke='%23c7162b' stroke-width='1.5' fill='%23c7162b' cx='8' cy='8' r='6.25'/%3E%3Cpath fill='%23FFF' fill-rule='nonzero' d='M10.282 4.638l1.06 1.06L9.05 7.99l2.293 2.292-1.06 1.06L7.99 9.05 5.7 11.343l-1.06-1.06 2.29-2.293L4.64 5.7l1.06-1.06 2.291 2.29z'/%3E%3C/g%3E%3C/svg%3E")}.p-inline-list{margin-left:0;padding-left:0}.p-inline-list__item{margin-right:1rem;list-style:none;display:inline}.p-inline-list__item.last-item,.p-inline-list__item:last-of-type{margin-right:0}.p-inline-list--middot{margin-left:0;padding-left:0}.p-inline-list--middot .p-inline-list__item{margin-right:.5rem;list-style:none;display:inline;position:relative}.p-inline-list--middot .p-inline-list__item.last-item,.p-inline-list--middot .p-inline-list__item:last-of-type{margin-right:0}.p-inline-list--middot .p-inline-list__item:after{content:"•";line-height:1.5rem;position:relative;right:-.25rem}.p-inline-list--middot .p-inline-list__item:last-of-type:after,.p-inline-list--middot .p-inline-list__item .last-item:after{content:""}.p-inline-list--middot{color:#111}.p-inline-list--middot.is-dark{color:#fff}.p-inline-list--stretch{flex-wrap:wrap;margin-left:0;padding-left:0;display:flex}.p-inline-list--stretch .p-inline-list__item{flex:auto;list-style:none}.p-stepped-list{margin-bottom:0;margin-left:0}.p-stepped-list__item{float:none;width:100%;margin-left:0;padding-bottom:1.5rem;position:relative;overflow:visible}.p-stepped-list__bullet{display:none}.p-stepped-list__title{padding-left:2.5rem}@media (min-width:1036px){.p-stepped-list__title{padding-left:2.5rem}}.p-stepped-list__title:before{width:1.5rem;margin-right:1rem}@media (min-width:1036px){.p-stepped-list__title:before{width:1.5rem}}.p-stepped-list__title+.p-stepped-list__content{margin-left:2.5rem}@media (min-width:1036px){.p-stepped-list__title+.p-stepped-list__content{margin-left:2.5rem}.p-stepped-list--detailed .p-stepped-list__title+.p-stepped-list__content{margin-left:0}}h6.p-stepped-list__title{padding-left:2.5rem}@media (min-width:1036px){h6.p-stepped-list__title{padding-left:2.5rem}}h6.p-stepped-list__title:before{width:1.5rem;margin-right:1rem}@media (min-width:1036px){h6.p-stepped-list__title:before{width:1.5rem}}h6.p-stepped-list__title+.p-stepped-list__content{margin-left:2.5rem}@media (min-width:1036px){h6.p-stepped-list__title+.p-stepped-list__content{margin-left:2.5rem}}h5.p-stepped-list__title{padding-left:2.5rem}@media (min-width:1036px){h5.p-stepped-list__title{padding-left:2.5rem}}h5.p-stepped-list__title:before{width:1.5rem;margin-right:1rem}@media (min-width:1036px){h5.p-stepped-list__title:before{width:1.5rem}}h5.p-stepped-list__title+.p-stepped-list__content{margin-left:2.5rem}@media (min-width:1036px){h5.p-stepped-list__title+.p-stepped-list__content{margin-left:2.5rem}}h4.p-stepped-list__title{padding-left:2.5rem}@media (min-width:1036px){h4.p-stepped-list__title{padding-left:3rem}}h4.p-stepped-list__title:before{width:1.5rem;margin-right:1rem}@media (min-width:1036px){h4.p-stepped-list__title:before{width:2rem}}h4.p-stepped-list__title+.p-stepped-list__content{margin-left:2.5rem}@media (min-width:1036px){h4.p-stepped-list__title+.p-stepped-list__content{margin-left:3rem}}h3.p-stepped-list__title{padding-left:3rem}@media (min-width:1036px){h3.p-stepped-list__title{padding-left:3.5rem}}h3.p-stepped-list__title:before{width:2rem;margin-right:1rem}@media (min-width:1036px){h3.p-stepped-list__title:before{width:2.5rem}}h3.p-stepped-list__title+.p-stepped-list__content{margin-left:3rem}@media (min-width:1036px){h3.p-stepped-list__title+.p-stepped-list__content{margin-left:3.5rem}}h2.p-stepped-list__title{padding-left:3.5rem}@media (min-width:1036px){h2.p-stepped-list__title{padding-left:4rem}}h2.p-stepped-list__title:before{width:2.5rem;margin-right:1rem}@media (min-width:1036px){h2.p-stepped-list__title:before{width:3rem}}h2.p-stepped-list__title+.p-stepped-list__content{margin-left:3.5rem}@media (min-width:1036px){h2.p-stepped-list__title+.p-stepped-list__content{margin-left:4rem}}h1.p-stepped-list__title{padding-left:4rem}@media (min-width:1036px){h1.p-stepped-list__title{padding-left:4.5rem}}h1.p-stepped-list__title:before{width:3rem;margin-right:1rem}@media (min-width:1036px){h1.p-stepped-list__title:before{width:3.5rem}}h1.p-stepped-list__title+.p-stepped-list__content{margin-left:4rem}@media (min-width:1036px){h1.p-stepped-list__title+.p-stepped-list__content{margin-left:4.5rem}}.p-stepped-list--detailed{margin-left:auto}@supports (display: grid){@media (min-width:1036px){.p-stepped-list--detailed .p-stepped-list__content{grid-column-end:span 6;margin-top:0}}.p-stepped-list--detailed .p-stepped-list__title{grid-column-end:span 6;margin-left:0;display:flex}}.p-stepped-list--detailed .p-stepped-list__item{margin-left:0;margin-right:0;padding-left:0;padding-right:0}@media (min-width:1036px){.p-stepped-list--detailed .p-stepped-list__item{padding-top:.5rem;position:relative}.p-stepped-list--detailed .p-stepped-list__item:after{content:"";height:1px;background-color:#0000001a;position:absolute;top:0;left:0;right:0}}@media (min-width:620px){@supports (-webkit-columns: 1) or (columns: 1){[class*=p-list].is-split{columns:2;column-gap:2rem}[class*=p-list].is-split .p-list__item{width:100%;display:inline-block}}@supports not ((-webkit-columns: 1) or (columns: 1)){[class*=p-list].is-split{flex-wrap:wrap;display:flex}[class*=p-list].is-split .p-list__item{width:calc(50% - .5rem)}}[class*=p-list].is-split:nth-child(2n-1){margin-right:1rem}}.p-logo-section__title{text-transform:uppercase;font-weight:400}.p-logo-section__items{width:calc(100% + 1.5rem);flex-wrap:wrap;justify-content:center;margin-bottom:1.5rem;margin-left:-1.5rem;display:flex}@media (min-width:620px){.p-logo-section__items{width:calc(100% + 2rem);margin-left:-2rem}}@media (min-width:1036px){.p-logo-section__items{width:calc(100% + 2rem);margin-left:-2rem}}.p-logo-section__item{flex:0 auto;align-items:center;margin-left:1.5rem;display:flex}@media (min-width:620px){.p-logo-section__item{margin-left:2rem}}@media (min-width:1036px){.p-logo-section__item{margin-left:2rem}}@media (max-width:620px){.p-logo-section__item{width:calc(25% - 1.5rem)}.col-small-3 .p-logo-section__item{width:calc(33.3333% - 1.5rem)}.col-small-2 .p-logo-section__item{width:calc(50% - 1.5rem)}.col-small-1 .p-logo-section__item{width:calc(100% - 1.5rem)}}@media (min-width:620px){.p-logo-section__item{width:calc(16.6667% - 2rem)}.col-medium-5 .p-logo-section__item{width:calc(20% - 2rem)}.col-medium-4 .p-logo-section__item{width:calc(25% - 2rem)}.col-medium-3 .p-logo-section__item{width:calc(33.3333% - 2rem)}.col-medium-2 .p-logo-section__item{width:calc(50% - 2rem)}.col-medium-1 .p-logo-section__item{width:calc(100% - 2rem)}}@media (min-width:1036px){.p-logo-section__item{width:calc(16.6667% - 2rem)}.col-11 .p-logo-section__item{width:calc(18.1818% - 2rem)}.col-10 .p-logo-section__item{width:calc(20% - 2rem)}.col-9 .p-logo-section__item{width:calc(22.2222% - 2rem)}.col-8 .p-logo-section__item{width:calc(25% - 2rem)}.col-7 .p-logo-section__item{width:calc(28.5714% - 2rem)}.col-6 .p-logo-section__item{width:calc(33.3333% - 2rem)}.col-5 .p-logo-section__item{width:calc(40% - 2rem)}.col-4 .p-logo-section__item{width:calc(50% - 2rem)}.col-3 .p-logo-section__item{width:calc(66.6667% - 2rem)}.col-2 .p-logo-section__item,.col-1 .p-logo-section__item{width:calc(100% - 2rem)}}.p-logo-section__logo{height:auto;width:100%}.p-matrix{flex-wrap:wrap;margin-bottom:1.5rem;margin-left:0;padding-left:0;list-style:none;display:flex}.p-matrix__item{border-top:1px solid #d9d9d9;flex:auto;padding-top:calc(1rem - 1px);padding-bottom:1rem;display:flex}.p-matrix__item:first-child{border-top:none}@media (min-width:620px){.p-matrix__item{width:33.333%;flex-wrap:wrap;display:flex}}@media (min-width:620px) and (max-width:1035px){.p-matrix__item{flex-direction:column}.p-matrix__item:nth-child(2),.p-matrix__item:nth-child(3){border-top:none}}@media (min-width:1036px){.p-matrix__item{width:33.333%;border-right:1px solid #d9d9d9;padding-left:1rem;padding-right:1rem}.p-matrix__item:empty{display:block}.p-matrix__item:nth-child(3n+1){padding-left:0}.p-matrix__item:nth-child(3n+3){border-right:0}.p-matrix__item:nth-child(1),.p-matrix__item:nth-child(2),.p-matrix__item:nth-child(3){border-top:0}.p-matrix__item{width:33.333%;border-right:1px solid #d9d9d9}.p-matrix__item:empty{display:block}.p-matrix__item:nth-child(3n+1){padding-left:0}.p-matrix__item:nth-child(3n+3){border-right:0;padding-right:0}.p-matrix__item:nth-last-child(1),.p-matrix__item:nth-last-child(2),.p-matrix__item:nth-last-child(3){border-bottom:0}}.p-matrix__img{height:auto;width:2rem;flex-shrink:0;align-self:flex-start;margin-top:0;margin-bottom:.5rem;margin-right:1rem}@media (min-width:1036px){.p-matrix__img{margin-top:-.05rem}}@media (min-width:1681px){.p-matrix__img{margin-top:0}}.p-matrix__content{flex-direction:column;flex:auto;padding-right:1rem;display:flex}@media (min-width:1036px){.p-matrix__content{width:calc(100% - 3rem)}.p-matrix__title{margin-bottom:-.05rem}}@media (min-width:1681px){.p-matrix__title{margin-bottom:0}}.p-matrix__desc{margin-bottom:.1rem}@media (max-width:1035px){.p-matrix__desc{margin-top:-.5rem}}.p-matrix__desc>:last-child{margin:0}.p-media-object--large,.p-media-object{flex-shrink:0;margin-bottom:1.5rem;display:flex}.p-media-object__meta-list-item,.p-media-object__meta-list-item--venue,.p-media-object__meta-list-item--location,.p-media-object__meta-list-item--date{color:#111;padding-left:2rem}.p-media-object__meta-list-item--venue,.p-media-object__meta-list-item--location,.p-media-object__meta-list-item--date{background-position:0 75%;background-repeat:no-repeat;background-size:1rem}.p-media-object__image{flex-basis:inherit;max-height:3rem;max-width:3rem;vertical-align:middle;width:auto;border-radius:.125rem;flex-shrink:0;align-self:flex-start;margin-right:1rem}.p-media-object__content{margin-top:0;margin-bottom:.6rem}.p-media-object__image.is-round{border-radius:50%}.p-media-object__meta-list{margin:0;padding-top:.5rem;padding-left:0;list-style:none}.p-media-object__meta-list-item--date{background-image:url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"90\" height=\"90\"><g transform=\"translate(0 -962.362)\"><path color=\"%23000\" fill=\"none\" stroke-width=\"7.5\" overflow=\"visible\" enable-background=\"accumulate\" d=\"M0 962.362h90v90H0z\"/><path d=\"M35.914 968.362v9c0 4.837-4.078 8.914-8.914 8.914-4.836 0-8.914-4.077-8.914-8.914v-8.547C7.56 969.892 6 973.59 6 986.362v42c0 18 3 18 30 18h18c27 0 30 0 30-18v-42c0-12.773-1.56-16.47-12.086-17.547v8.547c0 4.837-4.078 8.914-8.914 8.914-4.836 0-8.914-4.077-8.914-8.914v-9H35.914zm.086 24h18c24 0 24 0 24 12v24c0 12 0 12-24 12H36c-24 0-24 0-24-12v-24c0-12 0-12 24-12z\" fill=\"%23666\"/><rect width=\"6\" height=\"18\" x=\"24\" y=\"962.362\" ry=\"3\" color=\"%23000\" fill=\"%23666\" stroke-width=\".1\" overflow=\"visible\" enable-background=\"accumulate\"/><rect ry=\"3\" y=\"962.362\" x=\"60\" height=\"18\" width=\"6\" color=\"%23000\" fill=\"%23666\" stroke-width=\".1\" overflow=\"visible\" enable-background=\"accumulate\"/><path style=\"text-align:center;line-height:125%;-inkscape-font-specification:Ubuntu Medium\" d=\"M33.336 1001.364v.01c-1.8 0-3.5.348-5.087 1.043-1.548.663-2.913 1.553-4.08 2.664l-.352.337 3.06 4.335.474-.472c.158-.158.425-.388.787-.673l.01-.013.01-.012c.342-.295.74-.582 1.194-.86.467-.27 1.002-.507 1.607-.71.577-.19 1.206-.288 1.896-.288 1.048 0 1.885.26 2.58.768.626.46.964 1.222.964 2.497 0 .56-.114 1.1-.35 1.647-.246.538-.58 1.082-1.006 1.635h-.002c-.408.535-.896 1.088-1.466 1.658-.582.582-1.192 1.176-1.827 1.785h-.004c-.827.8-1.653 1.613-2.48 2.44-.846.845-1.61 1.748-2.292 2.704h-.002c-.692.967-1.26 2.02-1.702 3.15-.426 1.134-.635 2.372-.635 3.707v.72c0 .31.015.583.046.828l.064.493h18.65v-5.197H31.386c.072-.144.057-.21.18-.392l.006-.012h.002c.33-.507.727-1.034 1.192-1.576.47-.548.966-1.096 1.488-1.645l.008-.01c.527-.553.998-1.027 1.413-1.416h.007c.8-.775 1.6-1.56 2.4-2.36h.007c.813-.844 1.534-1.7 2.163-2.576h.002c.66-.906 1.197-1.83 1.613-2.773.428-.994.645-2.02.645-3.054 0-2.528-.756-4.605-2.28-6.102-1.524-1.55-3.862-2.28-6.9-2.28zm16.626.635v.01l-.024.537c-.106 2.31-.24 4.618-.4 6.927-.158 2.277-.384 4.688-.676 7.233l-.07.628h.632c2.187 0 3.982.12 5.37.353h.004c1.42.23 2.518.58 3.283 1.01h.01c.804.44 1.316.945 1.6 1.512.302.606.46 1.297.46 2.1 0 .514-.094.994-.278 1.457-.174.414-.456.79-.876 1.14h-.016c-.375.333-.9.615-1.582.836-.677.193-1.514.298-2.51.298-1.48 0-2.72-.144-3.718-.42-1.012-.31-1.79-.596-2.3-.84l-.638-.304-1.17 5.187.394.198c.32.16.74.313 1.287.477.553.167 1.168.315 1.847.45.703.163 1.43.3 2.184.407.77.11 1.527.163 2.273.163 1.826 0 3.44-.214 4.84-.66h.008c1.386-.473 2.56-1.12 3.502-1.948.94-.827 1.647-1.823 2.105-2.967.454-1.135.68-2.365.68-3.678 0-2.868-1.023-5.22-3.034-6.892-1.888-1.617-4.76-2.472-8.434-2.75.033-.27.064-.51.097-.834.055-.535.096-1.096.123-1.68l.002-.025c.052-.575.09-1.138.117-1.688l.003-.027c.035-.38.054-.693.077-1.02h10.055V1002H49.962z\" font-size=\"35.345\" font-weight=\"500\" letter-spacing=\"0\" word-spacing=\"0\" text-anchor=\"middle\" fill=\"%23666\" font-family=\"Ubuntu\"/></g></svg>")}.p-media-object__meta-list-item--location{background-image:url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"90\" height=\"90\"><g color=\"%23000\"><path d=\"M45 0C30.088 0 18 12.088 18 27c0 .562.03 1.103.063 1.656.013.248.012.497.03.75.02.23.07.46.095.688C20.22 51.854 41.922 90 45 90c3.078 0 24.78-38.146 26.813-59.906.02-.232.076-.46.093-.688.022-.248.016-.5.03-.75.032-.56.064-1.12.064-1.656C72 12.088 59.912 0 45 0zm0 18c4.97 0 9 4.03 9 9s-4.03 9-9 9-9-4.03-9-9 4.03-9 9-9z\" fill=\"%23666\" stroke-width=\"3\" overflow=\"visible\" enable-background=\"accumulate\"/><path fill=\"none\" stroke-width=\"7.5\" overflow=\"visible\" enable-background=\"accumulate\" d=\"M0 0h90v90H0z\"/></g></svg>")}.p-media-object__meta-list-item--venue{background-image:url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"90\" height=\"90\" viewBox=\"0 0 90 90.000001\"><g transform=\"translate(-111.967 -929.337)\" color=\"%23000\"><path fill=\"none\" stroke-width=\"4\" overflow=\"visible\" enable-background=\"accumulate\" d=\"M111.967 929.336h90v90h-90z\"/><circle r=\"6.5\" cy=\"24.5\" cx=\"23.5\" transform=\"matrix(1.846 0 0 1.846 113.583 929.105)\" fill=\"%23666\" stroke-width=\"2\" overflow=\"visible\" enable-background=\"accumulate\"/><circle r=\"21\" cy=\"45\" cx=\"45\" transform=\"matrix(1.429 0 0 1.429 92.682 910.05)\" fill=\"none\" stroke=\"%23666\" stroke-width=\"4.2\" stroke-linejoin=\"round\" overflow=\"visible\" enable-background=\"accumulate\"/><path d=\"M152.967 931.736l8-2.4v15h-8zM160.967 1016.336h-8v-12h8zM198.967 970.336v8h-12v-8zM114.967 978.336v-8h12v8z\" overflow=\"visible\" fill=\"%23666\" stroke-width=\"6\" enable-background=\"accumulate\"/></g></svg>")}.p-media-object--large .p-media-object__image{max-height:6rem;max-width:6rem}.p-modal{height:100vh;width:100%;z-index:101;background:#111111d9;justify-content:center;align-items:center;margin:0;padding:1rem;display:flex;position:fixed;inset:0}.p-modal__dialog{max-height:calc(100% - 2rem);max-width:72rem;width:auto;margin-bottom:0;padding-top:0;position:absolute;left:1.5rem;right:1.5rem;overflow:auto}@media (min-width:1036px){.p-modal__dialog{bottom:initial;left:initial;right:initial;top:initial;position:relative}}.p-modal__header{z-index:10;background:#fff;justify-content:space-between;margin-bottom:.5rem;padding-top:1rem;padding-right:2rem;display:flex;position:sticky;top:0}.p-modal__title{align-self:flex-end}.p-modal__close{box-sizing:content-box;height:1rem;text-indent:-999em;width:1rem;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='90' width='90'%3E%3Cg color='%23000'%3E%3Cpath fill='none' d='M0 0h90v90H0z'/%3E%3Cpath d='M14.52 6L6 14.52 36.48 45 6 75.49 14.52 84 45 53.52 75.48 84 84 75.49 53.52 45 84 14.52 75.48 6 45 36.49z' fill='%23888'/%3E%3C/g%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:1rem;border:0;margin:1rem 0 0;padding:.5rem;position:absolute;top:0;right:0}.p-modal__close:focus{outline:.1875rem solid #2e96ff}.p-modal__footer{text-align:right;padding-top:1rem}.p-navigation__toggle--open,.p-navigation__toggle--close,.p-navigation__toggle--search,.p-navigation__link--search-toggle,.p-navigation__tagged-logo .p-navigation__link,.p-navigation__link{padding-top:.75rem;padding-bottom:.75rem}@media (min-width:620px){.p-navigation__toggle--open,.p-navigation__toggle--close,.p-navigation__toggle--search,.p-navigation__link--search-toggle,.p-navigation__tagged-logo .p-navigation__link,.p-navigation__link{padding-top:1rem;padding-bottom:1rem}}.p-navigation__banner,.p-navigation__dropdown-item,.p-navigation__toggle--open,.p-navigation__toggle--close,.p-navigation__toggle--search,.p-navigation__link--search-toggle,.p-navigation__tagged-logo .p-navigation__link,.p-navigation__link{padding-left:1rem}@media (min-width:620px){.p-navigation__banner,.p-navigation__dropdown-item,.p-navigation__toggle--open,.p-navigation__toggle--close,.p-navigation__toggle--search,.p-navigation__link--search-toggle,.p-navigation__tagged-logo .p-navigation__link,.p-navigation__link{padding-left:1rem}}.p-navigation__dropdown-item,.p-navigation__toggle--open,.p-navigation__toggle--close,.p-navigation__toggle--search,.p-navigation__link--search-toggle,.p-navigation__tagged-logo .p-navigation__link,.p-navigation__link{padding-right:1rem}@media (min-width:620px){.p-navigation__dropdown-item,.p-navigation__toggle--open,.p-navigation__toggle--close,.p-navigation__toggle--search,.p-navigation__link--search-toggle,.p-navigation__tagged-logo .p-navigation__link,.p-navigation__link{padding-right:1rem}}.p-navigation__link--search-toggle,.p-navigation__tagged-logo .p-navigation__link,.p-navigation__link{text-align:left;text-overflow:ellipsis;white-space:nowrap;width:100%;background-color:#0000;border:none;border-radius:0;margin:0;font-weight:400;line-height:1.5rem;transition-property:background-color,color,opacity;transition-duration:.1s;transition-timing-function:cubic-bezier(.215,.61,.355,1);display:block;position:relative;overflow:hidden}.p-navigation__link--search-toggle:focus,.p-navigation__link:focus,.p-navigation__link--search-toggle:focus-visible,.p-navigation__link:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}.p-navigation__link--search-toggle:focus:not(:focus-visible),.p-navigation__link:focus:not(:focus-visible){outline-offset:0;outline:0}.p-navigation__link--search-toggle:before,.p-navigation__tagged-logo .p-navigation__link:before,.p-navigation__link:before{content:"";height:1px;position:absolute;top:0;left:0;right:0}@media (min-width:620px){.p-navigation__link--search-toggle:before,.p-navigation__tagged-logo .p-navigation__link:before,.p-navigation__link:before{content:none}}.p-navigation__link--search-toggle:visited,.p-navigation__link:visited,.p-navigation__link--search-toggle:focus,.p-navigation__link:focus,.p-navigation__link--search-toggle:hover,.p-navigation__link:hover{text-decoration:none}.p-navigation__row{padding-left:0;padding-right:0}.p-navigation{z-index:10;flex-direction:column;flex-shrink:0;display:flex;position:relative}@media (min-width:620px){.p-navigation{flex-direction:row}}.p-navigation .p-search-box{min-width:10em;flex:1 0 auto;order:-1;margin-top:-1px;margin-left:1rem;margin-right:1rem}@media (min-width:620px){.p-navigation .p-search-box{max-width:20rem;min-width:initial;flex:auto;order:1;margin:.6rem 0 auto auto;display:flex}}.p-navigation .u-image-position .u-image-position--right{right:initial;order:2;position:relative}.p-navigation__row,.p-navigation__row--full-width{flex-direction:column;display:flex}@media (min-width:620px){.p-navigation__row,.p-navigation__row--full-width{flex-direction:row}}.p-navigation__row--full-width{width:100%}@media (min-width:620px){.p-navigation__item,.p-navigation__item--dropdown-toggle{max-width:20em}}.p-navigation__banner{flex:none;justify-content:space-between;padding-right:0;display:flex}@media (min-width:620px){.p-navigation__banner{padding-left:1rem;padding-right:0}}.p-navigation__logo{height:3rem;flex:none;margin:0 1rem 0 0;display:flex}@media (min-width:620px){.p-navigation__logo{height:3.5rem}}.p-navigation__logo .p-navigation__item{display:flex}.p-navigation__logo .p-navigation__item:focus,.p-navigation__logo .p-navigation__item:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}.p-navigation__logo .p-navigation__item:focus:not(:focus-visible){outline-offset:0;outline:0}.p-navigation__tagged-logo{min-width:13rem;margin-right:0;display:flex}.p-navigation__tagged-logo .p-navigation__logo-tag{height:2.2rem;width:1.5rem;background-color:#e95420;position:absolute;top:0;left:0}@media (min-width:620px){.p-navigation__tagged-logo .p-navigation__logo-tag{height:2.4rem}}.p-navigation__tagged-logo .p-navigation__logo-icon{width:1.1rem;position:absolute;bottom:.3125rem;left:50%;transform:translate(-50%)}.p-navigation__tagged-logo .p-navigation__logo-title{font-size:1.30612rem;line-height:1rem}.p-navigation__tagged-logo .p-navigation__link{padding-left:1.8rem}.p-navigation__tagged-logo .p-navigation__link:hover{background-color:#0000!important}.p-navigation__tagged-logo .p-navigation__link:before{content:none}.p-navigation__image{max-height:2rem;min-height:1.5rem;align-self:center}.p-navigation__items{margin:-1px 0 0;padding:0;list-style:none;display:none}@media (min-width:620px){.p-navigation__items{flex-wrap:wrap;margin-top:0;display:flex}}.p-navigation__nav{flex-direction:column;display:none}@media (min-width:620px){.p-navigation__nav{width:100%;flex-direction:row;justify-content:space-between;margin-right:1.5rem;display:flex}}.p-navigation__banner .p-navigation__items{flex-wrap:wrap;margin-top:0;display:flex}@media (min-width:620px){.p-navigation__banner .p-navigation__items{display:none}}.p-navigation__toggle--close{display:none}.p-navigation__toggle--open,.p-navigation__toggle--search{display:block}@media (min-width:620px){.p-navigation__toggle--open,.p-navigation__toggle--search{display:none}}.p-navigation__toggle--open,.p-navigation__toggle--close,.p-navigation__toggle--search{margin:0 0 auto}.p-navigation__toggle--open:focus,.p-navigation__toggle--close:focus,.p-navigation__toggle--search:focus,.p-navigation__toggle--open:focus-visible,.p-navigation__toggle--close:focus-visible,.p-navigation__toggle--search:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}.p-navigation__toggle--open:focus:not(:focus-visible),.p-navigation__toggle--close:focus:not(:focus-visible),.p-navigation__toggle--search:focus:not(:focus-visible){outline-offset:0;outline:0}.p-navigation__toggle--open,.p-navigation__toggle--open:visited,.p-navigation__toggle--open:focus,.p-navigation__toggle--open:hover,.p-navigation__toggle--close,.p-navigation__toggle--close:visited,.p-navigation__toggle--close:focus,.p-navigation__toggle--close:hover,.p-navigation__toggle--search,.p-navigation__toggle--search:visited,.p-navigation__toggle--search:focus,.p-navigation__toggle--search:hover{text-decoration:none}.p-navigation:target:after{display:none}.p-navigation:target .p-navigation__nav{display:flex}.p-navigation:target .p-navigation__items{display:block}@media (min-width:620px){.p-navigation:target .p-navigation__items{display:flex}}.p-navigation:target .p-navigation__toggle--open{display:none}.p-navigation:target .p-navigation__toggle--close{display:block}@media (min-width:620px){.p-navigation:target .p-navigation__toggle--close{display:none}}.p-navigation__search{padding-top:1rem;display:none}.p-navigation__search .p-search-box{max-width:none}.p-navigation__link--search-toggle{height:100%;padding-left:0;padding-right:2rem;display:block;position:relative}.p-navigation__link--search-toggle .p-navigation__search-label{display:none}@media (min-width:1036px){.p-navigation__link--search-toggle{padding-left:1rem}.p-navigation__link--search-toggle .p-navigation__search-label{display:initial}}.p-navigation__link--search-toggle:after{content:"";height:1rem;pointer-events:none;text-indent:calc(100% + 10rem);width:1rem;background-position:50%;background-repeat:no-repeat;background-size:contain;display:block;position:absolute;top:1rem;right:calc(.5rem + 1px)}@media (min-width:620px){.p-navigation__link--search-toggle:after{top:1.25rem}}.p-navigation__nav .p-navigation__link--search-toggle{display:none}@media (min-width:620px){.p-navigation__nav .p-navigation__link--search-toggle{display:block}.p-navigation__search{flex-grow:1;align-items:center;padding:0;display:none}.p-navigation__search-overlay{height:100%;opacity:0;pointer-events:none;width:100%;z-index:59;background-color:#111111d9;transition-property:opacity;transition-duration:.1s;transition-timing-function:cubic-bezier(.215,.61,.355,1);display:block;position:fixed;top:0;left:0;right:0}}.p-navigation.has-search-open .p-navigation__nav{z-index:60;display:flex}.p-navigation.has-search-open .p-navigation__nav .p-navigation__items{display:none}.p-navigation.has-search-open .p-navigation__search{display:flex}.p-navigation.has-search-open .p-navigation__search-overlay{opacity:.5;pointer-events:all}.p-navigation.has-menu-open .p-navigation__nav{display:flex}.p-navigation.has-menu-open .p-navigation__nav .p-navigation__items{display:block}@media (min-width:620px){.p-navigation.has-menu-open .p-navigation__nav .p-navigation__items{display:flex}}.p-navigation.has-menu-open .p-navigation__search{display:none}.p-navigation__dropdown,.p-navigation__dropdown--right{min-width:100%;z-index:5;margin:0;padding:0;display:none}@media (min-width:620px){.p-navigation__dropdown,.p-navigation__dropdown--right{position:absolute;top:3.5rem}}@media (max-width:619px){.p-navigation__dropdown,.p-navigation__dropdown--right{box-shadow:none}}.p-navigation__dropdown--right{right:0}.p-navigation__item--dropdown-toggle{position:relative}.p-navigation__item--dropdown-toggle:after{content:"";height:1rem;pointer-events:none;text-indent:calc(100% + 10rem);width:1rem;background-position:50%;background-repeat:no-repeat;background-size:contain;display:block;position:absolute;top:1.25rem;right:1rem}@media (min-width:620px){.p-navigation__item--dropdown-toggle:after{right:calc(.5rem + 1px)}}.p-navigation__item--dropdown-toggle.is-active:after{transform:rotate(180deg)}.p-navigation__item--dropdown-toggle.is-active .p-navigation__dropdown,.p-navigation__item--dropdown-toggle.is-active .p-navigation__dropdown--right{display:block}.p-navigation__item--dropdown-toggle .p-navigation__link{padding-right:2rem}.p-navigation__dropdown-item{white-space:nowrap;padding-top:.5rem;padding-bottom:.5rem;display:block}@media (min-width:620px){.p-navigation__dropdown-item{padding-top:.75rem;padding-bottom:.75rem}}.p-navigation__dropdown-item,.p-navigation__dropdown-item:active,.p-navigation__dropdown-item:focus,.p-navigation__dropdown-item:hover,.p-navigation__dropdown-item:visited{text-decoration:none}.p-navigation{background-color:#fff}.p-navigation .p-navigation__link,.p-navigation .p-navigation__link:hover,.p-navigation .p-navigation__link:visited,.p-navigation .p-navigation__link:focus,.p-navigation .p-navigation__link--search-toggle,.p-navigation .p-navigation__link--search-toggle:hover,.p-navigation .p-navigation__link--search-toggle:visited,.p-navigation .p-navigation__link--search-toggle:focus,.p-navigation .p-navigation__toggle--close,.p-navigation .p-navigation__toggle--close:hover,.p-navigation .p-navigation__toggle--close:visited,.p-navigation .p-navigation__toggle--close:focus,.p-navigation .p-navigation__toggle--open,.p-navigation .p-navigation__toggle--open:hover,.p-navigation .p-navigation__toggle--open:visited,.p-navigation .p-navigation__toggle--open:focus,.p-navigation .p-navigation__dropdown-item,.p-navigation .p-navigation__dropdown-item:hover,.p-navigation .p-navigation__dropdown-item:visited,.p-navigation .p-navigation__dropdown-item:focus{color:#111}.p-navigation .p-navigation__link:hover,.p-navigation .p-navigation__link--search-toggle:hover,.p-navigation .p-navigation__toggle--close:hover,.p-navigation .p-navigation__toggle--open:hover,.p-navigation .p-navigation__dropdown-item:hover{background-color:#f7f7f7}.p-navigation .p-navigation__link[aria-pressed=true],.p-navigation .p-navigation__link:active,.p-navigation .p-navigation__link--search-toggle[aria-pressed=true],.p-navigation .p-navigation__link--search-toggle:active,.p-navigation .p-navigation__toggle--close[aria-pressed=true],.p-navigation .p-navigation__toggle--close:active,.p-navigation .p-navigation__toggle--open[aria-pressed=true],.p-navigation .p-navigation__toggle--open:active,.p-navigation .p-navigation__dropdown-item[aria-pressed=true],.p-navigation .p-navigation__dropdown-item:active{background-color:#e6e6e6}.p-navigation .p-navigation__logo-title{color:#111}.p-navigation .p-navigation__item--dropdown-toggle:after{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23111' d='M8.187 11.748l6.187-6.187-1.06-1.061-5.127 5.127L3.061 4.5 2 5.561z'/%3E%3C/svg%3E")}.p-navigation .p-navigation__item--dropdown-toggle.is-active>.p-navigation__link{background-color:#e6e6e6}.p-navigation .p-navigation__toggle--search:after,.p-navigation .p-navigation__item .p-navigation__link--search-toggle:after{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.964 1a5.964 5.964 0 014.709 9.623l4.303 4.305-1.06 1.06-4.306-4.305A5.964 5.964 0 116.963 1zm0 1.5a4.464 4.464 0 100 8.927 4.464 4.464 0 000-8.927z' fill='%23111' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-navigation .p-navigation__dropdown,.p-navigation .p-navigation__dropdown--right{background-color:#fff}.p-navigation [class*=p-navigation__item].is-selected>.p-navigation__link{background-color:#f7f7f7;position:relative}.p-navigation [class*=p-navigation__item].is-selected>.p-navigation__link:before{content:"";height:auto;width:.1875rem;z-index:1;background-color:#111;position:absolute;top:-1px;bottom:-1px;left:0}@media (min-width:620px){.p-navigation [class*=p-navigation__item].is-selected>.p-navigation__link{position:relative}.p-navigation [class*=p-navigation__item].is-selected>.p-navigation__link:before{content:"";height:.1875rem;width:auto;background-color:#111;position:absolute;inset:auto 0 0}}.p-navigation .p-navigation__nav .p-navigation__link:before{background:#0000001a}.p-navigation.has-menu-open .p-navigation__nav,.p-navigation.has-search-open .p-navigation__nav{background-color:#e6e6e6}@media (min-width:620px){.p-navigation.has-menu-open .p-navigation__nav,.p-navigation.has-search-open .p-navigation__nav{background-color:#0000}}.p-navigation.is-dark{background-color:#262626}.p-navigation.is-dark .p-navigation__link,.p-navigation.is-dark .p-navigation__link:hover,.p-navigation.is-dark .p-navigation__link:visited,.p-navigation.is-dark .p-navigation__link:focus,.p-navigation.is-dark .p-navigation__link--search-toggle,.p-navigation.is-dark .p-navigation__link--search-toggle:hover,.p-navigation.is-dark .p-navigation__link--search-toggle:visited,.p-navigation.is-dark .p-navigation__link--search-toggle:focus,.p-navigation.is-dark .p-navigation__toggle--close,.p-navigation.is-dark .p-navigation__toggle--close:hover,.p-navigation.is-dark .p-navigation__toggle--close:visited,.p-navigation.is-dark .p-navigation__toggle--close:focus,.p-navigation.is-dark .p-navigation__toggle--open,.p-navigation.is-dark .p-navigation__toggle--open:hover,.p-navigation.is-dark .p-navigation__toggle--open:visited,.p-navigation.is-dark .p-navigation__toggle--open:focus,.p-navigation.is-dark .p-navigation__dropdown-item,.p-navigation.is-dark .p-navigation__dropdown-item:hover,.p-navigation.is-dark .p-navigation__dropdown-item:visited,.p-navigation.is-dark .p-navigation__dropdown-item:focus{color:#fff}.p-navigation.is-dark .p-navigation__link:hover,.p-navigation.is-dark .p-navigation__link--search-toggle:hover,.p-navigation.is-dark .p-navigation__toggle--close:hover,.p-navigation.is-dark .p-navigation__toggle--open:hover,.p-navigation.is-dark .p-navigation__dropdown-item:hover{background-color:#ffffff0d}.p-navigation.is-dark .p-navigation__link[aria-pressed=true],.p-navigation.is-dark .p-navigation__link:active,.p-navigation.is-dark .p-navigation__link--search-toggle[aria-pressed=true],.p-navigation.is-dark .p-navigation__link--search-toggle:active,.p-navigation.is-dark .p-navigation__toggle--close[aria-pressed=true],.p-navigation.is-dark .p-navigation__toggle--close:active,.p-navigation.is-dark .p-navigation__toggle--open[aria-pressed=true],.p-navigation.is-dark .p-navigation__toggle--open:active,.p-navigation.is-dark .p-navigation__dropdown-item[aria-pressed=true],.p-navigation.is-dark .p-navigation__dropdown-item:active{background-color:#ffffff1a}.p-navigation.is-dark .p-navigation__logo-title{color:#fff}.p-navigation.is-dark .p-navigation__item--dropdown-toggle:after{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='hsl(0deg%2C0%%2C100%)' d='M8.187 11.748l6.187-6.187-1.06-1.061-5.127 5.127L3.061 4.5 2 5.561z'/%3E%3C/svg%3E")}.p-navigation.is-dark .p-navigation__item--dropdown-toggle.is-active>.p-navigation__link{background-color:#ffffff1a}.p-navigation.is-dark .p-navigation__toggle--search:after,.p-navigation.is-dark .p-navigation__item .p-navigation__link--search-toggle:after{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.964 1a5.964 5.964 0 014.709 9.623l4.303 4.305-1.06 1.06-4.306-4.305A5.964 5.964 0 116.963 1zm0 1.5a4.464 4.464 0 100 8.927 4.464 4.464 0 000-8.927z' fill='hsl(0deg%2C0%%2C100%)' fill-rule='nonzero'/%3E%3C/svg%3E")}.p-navigation.is-dark .p-navigation__dropdown,.p-navigation.is-dark .p-navigation__dropdown--right{background-color:#262626}.p-navigation.is-dark [class*=p-navigation__item].is-selected>.p-navigation__link{background-color:#ffffff0d;position:relative}.p-navigation.is-dark [class*=p-navigation__item].is-selected>.p-navigation__link:before{content:"";height:auto;width:.1875rem;z-index:1;background-color:#fff;position:absolute;top:-1px;bottom:-1px;left:0}@media (min-width:620px){.p-navigation.is-dark [class*=p-navigation__item].is-selected>.p-navigation__link{position:relative}.p-navigation.is-dark [class*=p-navigation__item].is-selected>.p-navigation__link:before{content:"";height:.1875rem;width:auto;background-color:#fff;position:absolute;inset:auto 0 0}}.p-navigation.is-dark .p-navigation__nav .p-navigation__link:before{background:#ffffff1a}.p-navigation.is-dark.has-menu-open .p-navigation__nav,.p-navigation.is-dark.has-search-open .p-navigation__nav{background-color:#ffffff1a}@media (min-width:620px){.p-navigation.is-dark.has-menu-open .p-navigation__nav,.p-navigation.is-dark.has-search-open .p-navigation__nav{background-color:#0000}}.p-notification--information,.p-notification--negative,.p-notification--caution,.p-notification--positive,.p-notification{background-position:1rem 1.15rem;background-repeat:no-repeat;background-size:1rem;border-radius:0 .125rem .125rem 0;margin-bottom:1.5rem;padding-top:calc(.5rem - 1px);padding-bottom:calc(.5rem - 1px);padding-left:3rem;position:relative}.p-notification--information:before,.p-notification--negative:before,.p-notification--caution:before,.p-notification--positive:before,.p-notification:before{left:-1px!important}.is-borderless.p-notification--information,.is-borderless.p-notification--negative,.is-borderless.p-notification--caution,.is-borderless.p-notification--positive,.is-borderless.p-notification{background-color:#0000;background-position:0 .65rem;border:none;margin-top:0;padding:0 0 0 2rem}.is-borderless.p-notification--information:before,.is-borderless.p-notification--negative:before,.is-borderless.p-notification--caution:before,.is-borderless.p-notification--positive:before,.is-borderless.p-notification:before{display:none}.is-inline.p-notification--information .p-notification__content,.is-inline.p-notification--negative .p-notification__content,.is-inline.p-notification--caution .p-notification__content,.is-inline.p-notification--positive .p-notification__content,.is-inline.p-notification .p-notification__content{margin-bottom:.6rem}.is-inline.p-notification--information .p-notification__meta,.is-inline.p-notification--negative .p-notification__meta,.is-inline.p-notification--caution .p-notification__meta,.is-inline.p-notification--positive .p-notification__meta,.is-inline.p-notification .p-notification__meta{padding-top:0}.is-inline.p-notification--information .p-notification__meta:after,.is-inline.p-notification--negative .p-notification__meta:after,.is-inline.p-notification--caution .p-notification__meta:after,.is-inline.p-notification--positive .p-notification__meta:after,.is-inline.p-notification .p-notification__meta:after{content:none}.is-inline.p-notification--information .p-notification__title,.is-inline.p-notification--negative .p-notification__title,.is-inline.p-notification--caution .p-notification__title,.is-inline.p-notification--positive .p-notification__title,.is-inline.p-notification .p-notification__title,.is-inline.p-notification--information .p-notification__message,.is-inline.p-notification--negative .p-notification__message,.is-inline.p-notification--caution .p-notification__message,.is-inline.p-notification--positive .p-notification__message,.is-inline.p-notification .p-notification__message{display:inline}.p-notification--information .p-notification__content,.p-notification--negative .p-notification__content,.p-notification--caution .p-notification__content,.p-notification--positive .p-notification__content,.p-notification .p-notification__content{max-width:unset;margin-bottom:.6rem;padding-right:2rem}.p-notification--information .p-notification__title,.p-notification--negative .p-notification__title,.p-notification--caution .p-notification__title,.p-notification--positive .p-notification__title,.p-notification .p-notification__title{margin:0;padding:0;font-size:1rem;font-weight:400;line-height:1.5rem}.p-notification--information .p-notification__message,.p-notification--negative .p-notification__message,.p-notification--caution .p-notification__message,.p-notification--positive .p-notification__message,.p-notification .p-notification__message{max-width:unset;margin:0;padding:0}.p-notification--information .p-notification__close,.p-notification--negative .p-notification__close,.p-notification--caution .p-notification__close,.p-notification--positive .p-notification__close,.p-notification .p-notification__close{background-color:#0000;background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23666' fill-rule='nonzero' d='M13.041 1.898l1.06 1.06L9.062 8l5.04 5.042-1.06 1.06L8 9.062 2.96 14.1l-1.06-1.06L6.938 8 1.9 2.96l1.06-1.06 5.04 5.04z'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:unset;height:2rem;width:1rem;border:0;position:absolute;top:.5rem;right:.5rem}.p-notification--information .p-notification__meta,.p-notification--negative .p-notification__meta,.p-notification--caution .p-notification__meta,.p-notification--positive .p-notification__meta,.p-notification .p-notification__meta{justify-content:space-between;align-items:flex-start;margin-bottom:.5rem;padding-top:.5rem;padding-right:1rem;display:flex}.p-notification--information .p-notification__actions,.p-notification--negative .p-notification__actions,.p-notification--caution .p-notification__actions,.p-notification--positive .p-notification__actions,.p-notification .p-notification__actions{align-items:flex-start;display:flex}.p-notification--information .p-notification__actions:only-child,.p-notification--negative .p-notification__actions:only-child,.p-notification--caution .p-notification__actions:only-child,.p-notification--positive .p-notification__actions:only-child,.p-notification .p-notification__actions:only-child{margin-left:auto}.p-notification--information .p-notification__action+.p-notification__action,.p-notification--negative .p-notification__action+.p-notification__action,.p-notification--caution .p-notification__action+.p-notification__action,.p-notification--positive .p-notification__action+.p-notification__action,.p-notification .p-notification__action+.p-notification__action{margin-left:1rem}.p-notification{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 1a7 7 0 110 14A7 7 0 018 1zm0 1.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM8.75 7v5.02h-1.5V7h1.5zM8.5 3.944a.5.5 0 01.5.5v1a.5.5 0 01-.5.5h-1a.5.5 0 01-.5-.5v-1a.5.5 0 01.5-.5h1z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E");position:relative}.p-notification:before{content:"";height:auto;width:.1875rem;z-index:1;background-color:#24598f;position:absolute;top:-1px;bottom:-1px;left:0}.p-notification--positive{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cg fill='none' fill-rule='nonzero'%3E%3Cpath fill='%230e8420' d='M8 1a7 7 0 110 14A7 7 0 018 1zm2.83 3.502L6.863 9.884 5.174 8.096l-1.09 1.03 2.92 3.096 5.034-6.83-1.208-.89z'/%3E%3Cpath fill='%23fff' d='M10.83 4.502l1.208.89-5.033 6.83-2.922-3.096 1.091-1.03 1.689 1.789z'/%3E%3C/g%3E%3C/svg%3E");position:relative}.p-notification--positive:before{content:"";height:auto;width:.1875rem;z-index:1;background-color:#0e8420;position:absolute;top:-1px;bottom:-1px;left:0}.p-notification--caution{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath d='M9.34 1.2l5.842 11.627A1.5 1.5 0 0113.842 15H2.158a1.5 1.5 0 01-1.34-2.173L6.66 1.2a1.5 1.5 0 012.68 0z' fill='%23f99b11'/%3E%3Cpath d='M8.5 11a.5.5 0 01.492.41L9 11.5v1a.5.5 0 01-.41.492L8.5 13h-1a.5.5 0 01-.492-.41L7 12.5v-1a.5.5 0 01.41-.492L7.5 11h1zM9 5v4.5H7V5h2z' fill='%23FFF'/%3E%3C/g%3E%3C/svg%3E");position:relative}.p-notification--caution:before{content:"";height:auto;width:.1875rem;z-index:1;background-color:#f99b11;position:absolute;top:-1px;bottom:-1px;left:0}.p-notification--negative{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Ccircle stroke='%23c7162b' stroke-width='1.5' fill='%23c7162b' cx='8' cy='8' r='6.25'/%3E%3Cpath fill='%23FFF' fill-rule='nonzero' d='M10.282 4.638l1.06 1.06L9.05 7.99l2.293 2.292-1.06 1.06L7.99 9.05 5.7 11.343l-1.06-1.06 2.29-2.293L4.64 5.7l1.06-1.06 2.291 2.29z'/%3E%3C/g%3E%3C/svg%3E");position:relative}.p-notification--negative:before{content:"";height:auto;width:.1875rem;z-index:1;background-color:#c7162b;position:absolute;top:-1px;bottom:-1px;left:0}.p-notification--information{background-image:url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 1a7 7 0 110 14A7 7 0 018 1zm0 1.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM8.75 7v5.02h-1.5V7h1.5zM8.5 3.944a.5.5 0 01.5.5v1a.5.5 0 01-.5.5h-1a.5.5 0 01-.5-.5v-1a.5.5 0 01.5-.5h1z' fill='%23666' fill-rule='nonzero'/%3E%3C/svg%3E");position:relative}.p-notification--information:before{content:"";height:auto;width:.1875rem;z-index:1;background-color:#24598f;position:absolute;top:-1px;bottom:-1px;left:0}.p-pagination__link--previous,.p-pagination__link--next,.p-pagination__link{color:#111;background-color:#fff;border-color:#0000008f}.p-pagination__link--previous:visited,.p-pagination__link--next:visited,.p-pagination__link:visited{color:#111}.p-pagination__link--previous:hover,.p-pagination__link--next:hover,.p-pagination__link:hover{background-color:#f2f2f2;border-color:#0000008f}.p-pagination__link--previous:active,.p-pagination__link--next:active,.p-pagination__link:active,[aria-pressed=true].p-pagination__link--previous,[aria-pressed=true].p-pagination__link--next,[aria-pressed=true].p-pagination__link,[aria-selected=true].p-pagination__link--previous,[aria-selected=true].p-pagination__link--next,[aria-selected=true].p-pagination__link,[aria-expanded=true].p-pagination__link--previous,[aria-expanded=true].p-pagination__link--next,[aria-expanded=true].p-pagination__link{background-color:#e6e6e6;border-color:#0000008f;transition-duration:0s}.p-pagination__link--previous:disabled:active,.p-pagination__link--next:disabled:active,.p-pagination__link:disabled:active,.p-pagination__link--previous:disabled[aria-pressed=true],.p-pagination__link--next:disabled[aria-pressed=true],.p-pagination__link:disabled[aria-pressed=true],.p-pagination__link--previous:disabled[aria-selected=true],.p-pagination__link--next:disabled[aria-selected=true],.p-pagination__link:disabled[aria-selected=true],.p-pagination__link--previous:disabled[aria-expanded=true],.p-pagination__link--next:disabled[aria-expanded=true],.p-pagination__link:disabled[aria-expanded=true],.p-pagination__link--previous:disabled:hover,.p-pagination__link--next:disabled:hover,.p-pagination__link:disabled:hover,.is-disabled.p-pagination__link--previous:active,.is-disabled.p-pagination__link--next:active,.is-disabled.p-pagination__link:active,.is-disabled[aria-pressed=true].p-pagination__link--previous,.is-disabled[aria-pressed=true].p-pagination__link--next,.is-disabled[aria-pressed=true].p-pagination__link,.is-disabled[aria-selected=true].p-pagination__link--previous,.is-disabled[aria-selected=true].p-pagination__link--next,.is-disabled[aria-selected=true].p-pagination__link,.is-disabled[aria-expanded=true].p-pagination__link--previous,.is-disabled[aria-expanded=true].p-pagination__link--next,.is-disabled[aria-expanded=true].p-pagination__link,.is-disabled.p-pagination__link--previous:hover,.is-disabled.p-pagination__link--next:hover,.is-disabled.p-pagination__link:hover{background-color:#0000;border-color:#0000008f}.is-active.p-pagination__link--previous,.is-active.p-pagination__link--next,.is-active.p-pagination__link,[aria-current=page].p-pagination__link--previous,[aria-current=page].p-pagination__link--next,[aria-current=page].p-pagination__link{color:#111;background-color:#e6e6e6;text-decoration:none}.p-pagination:not(nav),.p-pagination__items{flex-direction:row;margin-bottom:0;margin-left:0;padding-left:0;list-style:none;display:flex}.p-pagination__item{width:auto}.p-pagination__item+.p-pagination__item:not(:nth-child(2)):not(:nth-last-child(1)){margin-left:.5rem}.p-pagination__item+.p-pagination__item:nth-child(2),.p-pagination__item+.p-pagination__item:nth-last-child(1){margin-left:1rem}.p-pagination__item--truncation{padding:calc(.4rem - 1px) 0}.p-pagination__link--next [class*=p-icon],.p-pagination__link--previous [class*=p-icon]{margin-left:.5rem;margin-right:.5rem}.p-pagination__link--next [class*=p-icon]:first-child,.p-pagination__link--previous [class*=p-icon]:first-child{margin-left:-.5rem}.p-pagination__link--next [class*=p-icon]:last-child,.p-pagination__link--previous [class*=p-icon]:last-child{margin-right:-.5rem}.p-pagination__link--previous [class*=p-icon]{transform:rotate(90deg)}.p-pagination__link--next [class*=p-icon]{transform:rotate(-.25turn)}.p-pull-quote,.p-pull-quote--small,.p-pull-quote--large{border:0;margin:1.5rem 0;position:relative;overflow:visible}.p-pull-quote.has-image,.p-pull-quote--small.has-image,.p-pull-quote--large.has-image{margin-top:0}.p-pull-quote .p-pull-quote__citation,.p-pull-quote--small .p-pull-quote__citation,.p-pull-quote--large .p-pull-quote__citation{margin-top:.5rem;display:block}.p-pull-quote__image{height:2rem;margin:1rem 0 .5rem}.p-pull-quote__quote{position:relative}.p-pull-quote__quote:first-of-type:before{color:#666;width:.5em;content:"“";text-align:right;display:inline-block;position:absolute;top:.5rem;left:-.75em}.p-pull-quote__quote:last-of-type{margin-bottom:0}.p-pull-quote__quote:last-of-type:after{color:#666;width:.5em;content:"„";margin-left:.25em;display:inline-block;position:absolute;bottom:.55em}.p-pull-quote{padding:0 2rem}.p-pull-quote .p-pull-quote__quote:before,.p-pull-quote .p-pull-quote__quote:after{font-size:2em}.p-pull-quote--small{padding:0 1.5rem}.p-pull-quote--small .p-pull-quote__quote:before,.p-pull-quote--small .p-pull-quote__quote:after{font-size:1.5em}.p-pull-quote--large{padding:0 2.5rem}.p-pull-quote--large .p-pull-quote__quote:before,.p-pull-quote--large .p-pull-quote__quote:after{max-width:1em;font-size:2em}@media (max-width:1035px){.p-pull-quote .p-pull-quote__quote:first-of-type:before,.p-pull-quote--large .p-pull-quote__quote:first-of-type:before{top:.75rem}}.p-search-and-filter{border:1px solid #0000008f;position:relative}.p-search-and-filter .p-search-and-filter__search-container{height:auto;background-color:#fff;flex-wrap:wrap;align-items:center;margin:0;padding-left:.5rem;padding-right:2.1875rem;display:flex;position:relative;overflow:hidden}.p-search-and-filter .p-search-and-filter__search-container[data-active=true]{height:auto}.p-search-and-filter .p-search-and-filter__search-container[data-empty=false],.p-search-and-filter .p-search-and-filter__search-container[aria-expanded=false]{height:calc(2.3rem - 2px)}.p-search-and-filter .p-search-and-filter__search-container .p-chip{margin-top:.25rem;margin-bottom:.25rem}.p-search-and-filter .p-search-and-filter__search-container .p-search-and-filter__selected-count{color:#24598f;cursor:pointer;position:absolute;top:.1875rem;right:.5rem}.p-search-and-filter .p-search-and-filter__search-container[aria-expanded=true]{height:auto;max-height:100%}.p-search-and-filter .p-search-and-filter__search-container[aria-expanded=true] .p-search-and-filter__selected-count{display:none}.p-search-and-filter .p-search-and-filter__panel{opacity:1;width:100%;z-index:9999;background:#fff;border-radius:.125rem;padding:calc(.4rem - 1px) 1rem 0;transition-property:opacity;transition-duration:.165s;transition-timing-function:cubic-bezier(.215,.61,.355,1);position:absolute;box-shadow:0 1px 1px #00000026,0 2px 2px -1px #00000026,0 0 3px #0003}.p-search-and-filter .p-search-and-filter__panel[aria-hidden=true]{opacity:0;pointer-events:none}.p-search-and-filter .p-search-and-filter__search-prompt{cursor:pointer;text-overflow:ellipsis;white-space:nowrap;background:#f7f7f7;margin-left:-1rem;margin-right:-1rem;padding:1rem;overflow:hidden}.p-search-and-filter .p-search-and-filter__clear{z-index:9999;border:none;margin:0;line-height:1.25rem;position:absolute;top:.1875rem;bottom:.1875rem;right:.1875rem}.p-search-and-filter .p-search-and-filter__box{flex:1;margin:0;display:inline-flex;position:relative}.p-search-and-filter .p-search-and-filter__input{box-shadow:none;min-width:6rem;border:0;flex-grow:1;margin-bottom:0;margin-left:-.5rem;margin-right:-2.1875rem;position:relative}.p-search-and-filter .p-search-and-filter__input::-webkit-search-cancel-button{-webkit-appearance:none}.p-search-and-filter .p-chip+.p-search-and-filter__box{margin-left:.5rem}.p-filter-panel-section{border-bottom:1px solid #e5e5e5;margin:0;padding-bottom:1rem}.p-filter-panel-section:last-child{border:0}.p-filter-panel-section .p-chip{margin-bottom:.5rem}.p-filter-panel-section .p-chip .p-chip__lead,.p-filter-panel-section .p-chip .p-chip__lead+.p-chip__value:before{display:none}.p-filter-panel-section .p-filter-panel-section__heading{color:#666;margin-bottom:0;font-size:1rem}.p-filter-panel-section .p-filter-panel-section__chips{padding-right:1.25rem;position:relative;overflow:hidden}.p-filter-panel-section .p-filter-panel-section__chips[aria-expanded=false]{max-height:5rem}.p-filter-panel-section .p-filter-panel-section__counter{color:#24598f;cursor:pointer;position:absolute;bottom:0;right:.25rem}.p-search-box .p-search-box__button,.p-search-box .p-search-box__reset{height:1.925rem;margin:.1875rem 0;display:block;position:relative}.p-search-box .p-search-box__button:hover,.p-search-box .p-search-box__reset:hover{background:inherit}.p-search-box .p-search-box__button:hover:disabled,.p-search-box .p-search-box__reset:hover:disabled{cursor:not-allowed}.p-search-box .p-search-box__button [class*=p-icon],.p-search-box .p-search-box__reset [class*=p-icon]{vertical-align:0}.p-search-box .p-search-box__button [class*=p-icon]:only-child,.p-search-box .p-search-box__reset [class*=p-icon]:only-child{margin-left:-.5rem;margin-right:-.5rem}.p-search-box{justify-content:flex-end;margin-bottom:1.2rem;display:flex;position:relative}.p-search-box .p-search-box__reset:not(:last-of-type):not(:only-of-type){margin-right:.1875rem}.p-search-box .p-search-box__input{flex:100%;margin-bottom:0;padding-right:4.6rem;position:absolute;right:0}.p-search-box .p-search-box__input::-webkit-search-cancel-button{-webkit-appearance:none}.p-search-box .p-search-box__input:not(:valid)~.p-search-box__reset{display:none}.p-search-box .p-search-box__button{border-left-style:solid;border-left-width:1px;border-radius:0 .125rem .125rem 0;margin-right:.1875rem}.p-search-box .p-search-box__reset,.p-search-box .p-search-box__button{border-width:0;background-color:#0000!important}.p-search-box .p-search-box__input{color:#111;background-color:#fff;border-color:#0000008f}.p-search-box .p-search-box__input:active,.p-search-box .p-search-box__input:focus,.p-search-box .p-search-box__input:hover,.p-search-box .p-search-box__input:-internal-autofill-selected,.p-search-box .p-search-box__input:-webkit-autofill,.p-search-box .p-search-box__input:-webkit-autofill:hover,.p-search-box .p-search-box__input:-webkit-autofill:focus{background-color:#fff!important;border-color:#0000008f!important}.p-search-box.is-dark .p-search-box__input{color:#fff;background-color:#262626;border-color:#999}.p-search-box.is-dark .p-search-box__input:active,.p-search-box.is-dark .p-search-box__input:focus,.p-search-box.is-dark .p-search-box__input:hover,.p-search-box.is-dark .p-search-box__input:-internal-autofill-selected,.p-search-box.is-dark .p-search-box__input:-webkit-autofill,.p-search-box.is-dark .p-search-box__input:-webkit-autofill:hover,.p-search-box.is-dark .p-search-box__input:-webkit-autofill:focus{background-color:#262626!important;border-color:#999!important}.p-segmented-control .p-segmented-control__list,.p-segmented-control .p-tab-buttons__list,.p-tab-buttons .p-segmented-control__list,.p-tab-buttons .p-tab-buttons__list{display:flex}.p-segmented-control .p-segmented-control__button,.p-segmented-control .p-tab-buttons__button,.p-tab-buttons .p-segmented-control__button,.p-tab-buttons .p-tab-buttons__button{text-overflow:ellipsis;white-space:nowrap;border-radius:0;margin-right:0;position:relative;overflow:hidden}.p-segmented-control .p-segmented-control__button:not(:first-child),.p-segmented-control .p-tab-buttons__button:not(:first-child),.p-tab-buttons .p-segmented-control__button:not(:first-child),.p-tab-buttons .p-tab-buttons__button:not(:first-child){border-left:0}.p-segmented-control .p-segmented-control__button:not(:last-child),.p-segmented-control .p-tab-buttons__button:not(:last-child),.p-tab-buttons .p-segmented-control__button:not(:last-child),.p-tab-buttons .p-tab-buttons__button:not(:last-child){border-right:0}.p-segmented-control .p-segmented-control__button:not(:last-child):after,.p-segmented-control .p-tab-buttons__button:not(:last-child):after,.p-tab-buttons .p-segmented-control__button:not(:last-child):after,.p-tab-buttons .p-tab-buttons__button:not(:last-child):after{content:"";width:1px;background-color:#0000001a;position:absolute;top:0;bottom:0;right:0}.p-segmented-control .p-segmented-control__button:first-child,.p-segmented-control .p-tab-buttons__button:first-child,.p-tab-buttons .p-segmented-control__button:first-child,.p-tab-buttons .p-tab-buttons__button:first-child{border-radius:.125rem 0 0 .125rem}.p-segmented-control .p-segmented-control__button:last-child,.p-segmented-control .p-tab-buttons__button:last-child,.p-tab-buttons .p-segmented-control__button:last-child,.p-tab-buttons .p-tab-buttons__button:last-child{border-radius:0 .125rem .125rem 0}.p-separator{margin-top:2rem;margin-bottom:2rem}@media (min-width:1036px){.p-separator{margin-top:4rem;margin-bottom:4rem}}@keyframes vf-p-side-navigation-expand{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes vf-p-side-navigation-collapse{0%{transform:translate(0)}to{transform:translate(-100%)}}.p-side-navigation__drawer{width:100%;z-index:102;position:fixed;top:0;bottom:0;left:0;overflow:auto;transform:translate(-100%)}.p-side-navigation:target .p-side-navigation__drawer,[class*=p-side-navigation--]:target .p-side-navigation__drawer,.p-side-navigation.is-expanded .p-side-navigation__drawer,.p-side-navigation.is-drawer-expanded .p-side-navigation__drawer,[class*=p-side-navigation--].is-expanded .p-side-navigation__drawer,[class*=p-side-navigation--].is-drawer-expanded .p-side-navigation__drawer{animation:vf-p-side-navigation-expand .333s;transform:translate(0)}.p-side-navigation.is-collapsed .p-side-navigation__drawer,.p-side-navigation.is-drawer-collapsed .p-side-navigation__drawer,[class*=p-side-navigation--].is-collapsed .p-side-navigation__drawer,[class*=p-side-navigation--].is-drawer-collapsed .p-side-navigation__drawer{animation:vf-p-side-navigation-collapse .333s}.p-side-navigation.is-drawer-hidden .p-side-navigation__drawer,[class*=p-side-navigation--].is-drawer-hidden .p-side-navigation__drawer{display:none}@media (min-width:1036px){.p-side-navigation.is-drawer-hidden .p-side-navigation__drawer,[class*=p-side-navigation--].is-drawer-hidden .p-side-navigation__drawer{display:block}}@media (min-width:460px){.p-side-navigation__drawer{max-width:20rem}}.p-side-navigation__overlay{opacity:0;pointer-events:none;z-index:101;transition-property:opacity;transition-duration:.333s;transition-timing-function:cubic-bezier(.215,.61,.355,1);position:fixed;inset:0}.p-side-navigation:target .p-side-navigation__overlay,[class*=p-side-navigation--]:target .p-side-navigation__overlay,.p-side-navigation.is-expanded .p-side-navigation__overlay,.p-side-navigation.is-drawer-expanded .p-side-navigation__overlay,[class*=p-side-navigation--].is-expanded .p-side-navigation__overlay,[class*=p-side-navigation--].is-drawer-expanded .p-side-navigation__overlay{opacity:1;pointer-events:all}.p-side-navigation__drawer-header{z-index:1;border-bottom-style:solid;border-bottom-width:1px;margin-bottom:.5rem;padding-top:.5rem;padding-bottom:calc(.5rem - 1px);padding-left:.25rem;position:sticky;top:0}.p-side-navigation__toggle:before,.p-side-navigation__toggle--in-drawer:before{content:"";margin-left:-.5rem;margin-right:.5rem}.p-side-navigation__toggle:before{transform:rotate(-90deg)}.p-side-navigation__toggle--in-drawer{margin-bottom:.2rem}.p-side-navigation__toggle--in-drawer:before{transform:rotate(90deg)}@media (min-width:1036px){.p-side-navigation.is-sticky,[class*=p-side-navigation--].is-sticky{max-height:100vh;position:sticky;top:0;overflow-y:auto}.p-side-navigation__toggle,.p-side-navigation__toggle--in-drawer,.p-side-navigation__drawer-header{display:none}.p-side-navigation__drawer,.p-side-navigation:target .p-side-navigation__drawer,[class*=p-side-navigation--]:target .p-side-navigation__drawer,.p-side-navigation.is-expanded .p-side-navigation__drawer,.p-side-navigation.is-drawer-expanded .p-side-navigation__drawer,[class*=p-side-navigation--].is-expanded .p-side-navigation__drawer,[class*=p-side-navigation--].is-drawer-expanded .p-side-navigation__drawer{box-shadow:none;max-width:none;display:block;position:static;overflow:visible;transform:translate(0)}.p-side-navigation__overlay{display:none}}.p-side-navigation--raw-html ul:after,.p-side-navigation__list:after{bottom:-.75rem;left:1rem}@media (min-width:620px){.p-side-navigation--raw-html ul:after,.p-side-navigation__list:after{left:1.5rem}}@media (min-width:1036px){.p-side-navigation--raw-html ul:after,.p-side-navigation__list:after{left:1.5rem}}.p-side-navigation--icons .p-side-navigation--raw-html ul:after,.p-side-navigation--raw-html .p-side-navigation--icons ul:after,.p-side-navigation--icons .p-side-navigation__list:after{left:3rem}@media (min-width:620px){.p-side-navigation--icons .p-side-navigation--raw-html ul:after,.p-side-navigation--raw-html .p-side-navigation--icons ul:after,.p-side-navigation--icons .p-side-navigation__list:after{left:4rem}}@media (min-width:1036px){.p-side-navigation--icons .p-side-navigation--raw-html ul:after,.p-side-navigation--raw-html .p-side-navigation--icons ul:after,.p-side-navigation--icons .p-side-navigation__list:after{left:4rem}}.p-side-navigation--raw-html ul:last-of-type:after,.p-side-navigation__list:last-of-type:after{content:none}.p-side-navigation--raw-html li>span,.p-side-navigation--raw-html li>strong,.p-side-navigation--raw-html li>a,.p-side-navigation__heading,.p-side-navigation__text,.p-side-navigation__link,.p-side-navigation--raw-html h2,.p-side-navigation--raw-html h3,.p-side-navigation--raw-html h4,.p-side-navigation--raw-html h5,.p-side-navigation--raw-html h6,.p-side-navigation__heading--linked{padding:.25rem 1rem;display:flex}@media (min-width:620px){.p-side-navigation--raw-html li>span,.p-side-navigation--raw-html li>strong,.p-side-navigation--raw-html li>a,.p-side-navigation__heading,.p-side-navigation__text,.p-side-navigation__link,.p-side-navigation--raw-html h2,.p-side-navigation--raw-html h3,.p-side-navigation--raw-html h4,.p-side-navigation--raw-html h5,.p-side-navigation--raw-html h6,.p-side-navigation__heading--linked{padding-left:1.5rem}}@media (min-width:1036px){.p-side-navigation--raw-html li>span,.p-side-navigation--raw-html li>strong,.p-side-navigation--raw-html li>a,.p-side-navigation__heading,.p-side-navigation__text,.p-side-navigation__link,.p-side-navigation--raw-html h2,.p-side-navigation--raw-html h3,.p-side-navigation--raw-html h4,.p-side-navigation--raw-html h5,.p-side-navigation--raw-html h6,.p-side-navigation__heading--linked{padding-left:1.5rem}}.p-side-navigation--raw-html li.p-side-navigation__item--title>span,.p-side-navigation--raw-html li.p-side-navigation__item--title>strong,.p-side-navigation--raw-html li.p-side-navigation__item--title>a,.p-side-navigation__item--title>.p-side-navigation__heading,.p-side-navigation__item--title>.p-side-navigation__text,.p-side-navigation__item--title>.p-side-navigation__link,.p-side-navigation--raw-html .p-side-navigation__item--title>h2,.p-side-navigation--raw-html .p-side-navigation__item--title>h3,.p-side-navigation--raw-html .p-side-navigation__item--title>h4,.p-side-navigation--raw-html .p-side-navigation__item--title>h5,.p-side-navigation--raw-html .p-side-navigation__item--title>h6,.p-side-navigation__item--title>.p-side-navigation__heading--linked{font-weight:400}.p-side-navigation--raw-html h2,.p-side-navigation--raw-html h3,.p-side-navigation--raw-html h4,.p-side-navigation--raw-html h5,.p-side-navigation--raw-html h6,.p-side-navigation__heading,.p-side-navigation__heading--linked{margin:0;font-size:1rem;display:block}.p-side-navigation--raw-html li>a:focus,.p-side-navigation__link:focus,.p-side-navigation--raw-html li>a:focus-visible,.p-side-navigation__link:focus-visible{outline-offset:-.1875rem;outline:.1875rem solid #2e96ff}.p-side-navigation--raw-html li>a:focus:not(:focus-visible),.p-side-navigation__link:focus:not(:focus-visible){outline-offset:0;outline:0}.p-side-navigation--raw-html li>a:focus:before,.p-side-navigation__link:focus:before{display:none}.p-side-navigation--raw-html li>a:focus:not(:focus-visible):before,.p-side-navigation__link:focus:not(:focus-visible):before{display:block}.p-side-navigation--raw-html li>a:hover,.p-side-navigation__link:hover{text-decoration:none}.p-side-navigation--icons .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__link{padding-left:3rem;position:relative}@media (min-width:620px){.p-side-navigation--icons .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__link{padding-left:4rem}}@media (min-width:1036px){.p-side-navigation--icons .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__link{padding-left:4rem}}.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__text,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__link,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__link{padding-left:2rem}@media (min-width:620px){.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__text,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__link,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__link{padding-left:3rem}}@media (min-width:1036px){.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__text,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__link,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__link{padding-left:3rem}}.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__link,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link{padding-left:4rem}@media (min-width:620px){.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__link,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link{padding-left:5.5rem}}@media (min-width:1036px){.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__link,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link{padding-left:5.5rem}}.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link{padding-left:3rem}@media (min-width:620px){.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link{padding-left:4.5rem}}@media (min-width:1036px){.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link,.p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link{padding-left:4.5rem}}.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link{padding-left:5rem}@media (min-width:620px){.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link{padding-left:7rem}}@media (min-width:1036px){.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__heading,.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__text,.p-side-navigation--icons .p-side-navigation__item--title .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link,.p-side-navigation--icons .p-side-navigation__item .p-side-navigation__item .p-side-navigation__item .p-side-navigation__link{padding-left:7rem}}.p-side-navigation--icons .p-side-navigation__icon{position:absolute;top:.5rem;left:1rem}@media (min-width:620px){.p-side-navigation--icons .p-side-navigation__icon{left:1.5rem}}@media (min-width:1036px){.p-side-navigation--icons .p-side-navigation__icon{left:1.5rem}}.p-side-navigation__status{margin-left:auto;padding-left:.5rem}.p-side-navigation__heading--linked{padding:0}.p-side-navigation--raw-html li>span,.p-side-navigation--raw-html li>strong,.p-side-navigation--raw-html li>a{display:block}.p-side-navigation--raw-html li li>span,.p-side-navigation--raw-html li li>strong,.p-side-navigation--raw-html li li>a{padding-left:2rem}@media (min-width:620px){.p-side-navigation--raw-html li li>span,.p-side-navigation--raw-html li li>strong,.p-side-navigation--raw-html li li>a{padding-left:3rem}}@media (min-width:1036px){.p-side-navigation--raw-html li li>span,.p-side-navigation--raw-html li li>strong,.p-side-navigation--raw-html li li>a{padding-left:3rem}}.p-side-navigation--raw-html li li li>span,.p-side-navigation--raw-html li li li>strong,.p-side-navigation--raw-html li li li>a{padding-left:3rem}@media (min-width:620px){.p-side-navigation--raw-html li li li>span,.p-side-navigation--raw-html li li li>strong,.p-side-navigation--raw-html li li li>a{padding-left:4.5rem}}@media (min-width:1036px){.p-side-navigation--raw-html li li li>span,.p-side-navigation--raw-html li li li>strong,.p-side-navigation--raw-html li li li>a{padding-left:4.5rem}}.p-side-navigation,[class*=p-side-navigation--]{color:#000000bf}.p-side-navigation .p-side-navigation__toggle,[class*=p-side-navigation--] .p-side-navigation__toggle{color:#111;background-color:#fff;border-color:#0000008f}.p-side-navigation .p-side-navigation__toggle:visited,[class*=p-side-navigation--] .p-side-navigation__toggle:visited{color:#111}.p-side-navigation .p-side-navigation__toggle:hover,[class*=p-side-navigation--] .p-side-navigation__toggle:hover{background-color:#f2f2f2;border-color:#0000008f}.p-side-navigation .p-side-navigation__toggle:active,.p-side-navigation .p-side-navigation__toggle[aria-pressed=true],.p-side-navigation .p-side-navigation__toggle[aria-selected=true],.p-side-navigation .p-side-navigation__toggle[aria-expanded=true],[class*=p-side-navigation--] .p-side-navigation__toggle:active,[class*=p-side-navigation--] .p-side-navigation__toggle[aria-pressed=true],[class*=p-side-navigation--] .p-side-navigation__toggle[aria-selected=true],[class*=p-side-navigation--] .p-side-navigation__toggle[aria-expanded=true]{background-color:#e6e6e6;border-color:#0000008f;transition-duration:0s}.p-side-navigation .p-side-navigation__toggle:disabled:active,.p-side-navigation .p-side-navigation__toggle:disabled[aria-pressed=true],.p-side-navigation .p-side-navigation__toggle:disabled[aria-selected=true],.p-side-navigation .p-side-navigation__toggle:disabled[aria-expanded=true],.p-side-navigation .p-side-navigation__toggle:disabled:hover,.p-side-navigation .p-side-navigation__toggle.is-disabled:active,.p-side-navigation .p-side-navigation__toggle.is-disabled[aria-pressed=true],.p-side-navigation .p-side-navigation__toggle.is-disabled[aria-selected=true],.p-side-navigation .p-side-navigation__toggle.is-disabled[aria-expanded=true],.p-side-navigation .p-side-navigation__toggle.is-disabled:hover,[class*=p-side-navigation--] .p-side-navigation__toggle:disabled:active,[class*=p-side-navigation--] .p-side-navigation__toggle:disabled[aria-pressed=true],[class*=p-side-navigation--] .p-side-navigation__toggle:disabled[aria-selected=true],[class*=p-side-navigation--] .p-side-navigation__toggle:disabled[aria-expanded=true],[class*=p-side-navigation--] .p-side-navigation__toggle:disabled:hover,[class*=p-side-navigation--] .p-side-navigation__toggle.is-disabled:active,[class*=p-side-navigation--] .p-side-navigation__toggle.is-disabled[aria-pressed=true],[class*=p-side-navigation--] .p-side-navigation__toggle.is-disabled[aria-selected=true],[class*=p-side-navigation--] .p-side-navigation__toggle.is-disabled[aria-expanded=true],[class*=p-side-navigation--] .p-side-navigation__toggle.is-disabled:hover{background-color:#0000;border-color:#0000008f}.p-side-navigation .p-side-navigation__toggle:before,[class*=p-side-navigation--] .p-side-navigation__toggle:before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23666' d='M8.187 11.748l6.187-6.187-1.06-1.061-5.127 5.127L3.061 4.5 2 5.561z'/%3E%3C/svg%3E")}.p-side-navigation .p-side-navigation__toggle--in-drawer,[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer{color:#000000bf;background-color:#0000;border-color:#0000}.p-side-navigation .p-side-navigation__toggle--in-drawer:visited,[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer:visited{color:#000000bf}.p-side-navigation .p-side-navigation__toggle--in-drawer:hover,[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer:hover{background-color:#f2f2f2;border-color:#0000}.p-side-navigation .p-side-navigation__toggle--in-drawer:active,.p-side-navigation .p-side-navigation__toggle--in-drawer[aria-pressed=true],.p-side-navigation .p-side-navigation__toggle--in-drawer[aria-selected=true],.p-side-navigation .p-side-navigation__toggle--in-drawer[aria-expanded=true],[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer:active,[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer[aria-pressed=true],[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer[aria-selected=true],[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer[aria-expanded=true]{background-color:#e6e6e6;border-color:#0000;transition-duration:0s}.p-side-navigation .p-side-navigation__toggle--in-drawer:disabled:active,.p-side-navigation .p-side-navigation__toggle--in-drawer:disabled[aria-pressed=true],.p-side-navigation .p-side-navigation__toggle--in-drawer:disabled[aria-selected=true],.p-side-navigation .p-side-navigation__toggle--in-drawer:disabled[aria-expanded=true],.p-side-navigation .p-side-navigation__toggle--in-drawer:disabled:hover,.p-side-navigation .p-side-navigation__toggle--in-drawer.is-disabled:active,.p-side-navigation .p-side-navigation__toggle--in-drawer.is-disabled[aria-pressed=true],.p-side-navigation .p-side-navigation__toggle--in-drawer.is-disabled[aria-selected=true],.p-side-navigation .p-side-navigation__toggle--in-drawer.is-disabled[aria-expanded=true],.p-side-navigation .p-side-navigation__toggle--in-drawer.is-disabled:hover,[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer:disabled:active,[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer:disabled[aria-pressed=true],[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer:disabled[aria-selected=true],[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer:disabled[aria-expanded=true],[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer:disabled:hover,[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer.is-disabled:active,[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer.is-disabled[aria-pressed=true],[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer.is-disabled[aria-selected=true],[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer.is-disabled[aria-expanded=true],[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer.is-disabled:hover{background-color:#0000;border-color:#0000008f}.p-side-navigation .p-side-navigation__toggle--in-drawer:before,[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer:before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='rgba(0%2C0%2C0%2C0.75)' d='M8.187 11.748l6.187-6.187-1.06-1.061-5.127 5.127L3.061 4.5 2 5.561z'/%3E%3C/svg%3E")}.p-side-navigation .p-side-navigation__toggle--in-drawer[aria-expanded=true],[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer[aria-expanded=true]{background-color:#0000}.p-side-navigation .p-side-navigation__toggle--in-drawer[aria-expanded=true]:hover,[class*=p-side-navigation--] .p-side-navigation__toggle--in-drawer[aria-expanded=true]:hover{color:#111;background:#f2f2f2}.p-side-navigation .p-side-navigation__drawer,[class*=p-side-navigation--] .p-side-navigation__drawer{background:#fff}.p-side-navigation .p-side-navigation__overlay,[class*=p-side-navigation--] .p-side-navigation__overlay{background:#111111d9}.p-side-navigation .p-side-navigation__drawer-header,[class*=p-side-navigation--] .p-side-navigation__drawer-header{background:#fff;border-color:#0000001a}.p-side-navigation .p-side-navigation__list:after,[class*=p-side-navigation--] .p-side-navigation__list:after{background:#0000001a}.p-side-navigation .p-side-navigation__link,.p-side-navigation .p-side-navigation__link:visited,[class*=p-side-navigation--] .p-side-navigation__link,[class*=p-side-navigation--] .p-side-navigation__link:visited{color:#000000bf}.p-side-navigation .p-side-navigation__link:hover,[class*=p-side-navigation--] .p-side-navigation__link:hover{color:#111;background:#f2f2f2}.p-side-navigation .p-side-navigation__link:active,.p-side-navigation .p-side-navigation__link.is-active,.p-side-navigation .p-side-navigation__link[aria-current=page],.p-side-navigation .p-side-navigation__link[aria-current=true],[class*=p-side-navigation--] .p-side-navigation__link:active,[class*=p-side-navigation--] .p-side-navigation__link.is-active,[class*=p-side-navigation--] .p-side-navigation__link[aria-current=page],[class*=p-side-navigation--] .p-side-navigation__link[aria-current=true]{color:#111;cursor:default;background:#e6e6e6}.p-side-navigation .p-side-navigation__link.is-active,.p-side-navigation .p-side-navigation__link[aria-current=page],.p-side-navigation .p-side-navigation__link[aria-current=true],[class*=p-side-navigation--] .p-side-navigation__link.is-active,[class*=p-side-navigation--] .p-side-navigation__link[aria-current=page],[class*=p-side-navigation--] .p-side-navigation__link[aria-current=true]{position:relative}.p-side-navigation .p-side-navigation__link.is-active:before,.p-side-navigation .p-side-navigation__link[aria-current=page]:before,.p-side-navigation .p-side-navigation__link[aria-current=true]:before,[class*=p-side-navigation--] .p-side-navigation__link.is-active:before,[class*=p-side-navigation--] .p-side-navigation__link[aria-current=page]:before,[class*=p-side-navigation--] .p-side-navigation__link[aria-current=true]:before{content:"";height:auto;width:.1875rem;background-color:#111;position:absolute;top:0;bottom:0;left:0}.p-side-navigation .p-side-navigation__heading,.p-side-navigation .p-side-navigation__heading--linked .p-side-navigation__link,.p-side-navigation .p-side-navigation__item--title,.p-side-navigation .p-side-navigation__item--title .p-side-navigation__link,[class*=p-side-navigation--] .p-side-navigation__heading,[class*=p-side-navigation--] .p-side-navigation__heading--linked .p-side-navigation__link,[class*=p-side-navigation--] .p-side-navigation__item--title,[class*=p-side-navigation--] .p-side-navigation__item--title .p-side-navigation__link{color:#111}@media (min-width:620px){.l-navigation .p-side-navigation .p-side-navigation__item.has-active-child,.l-navigation [class*=p-side-navigation--] .p-side-navigation__item.has-active-child{color:#111;background:#f2f2f2;position:relative}.l-navigation .p-side-navigation .p-side-navigation__item.has-active-child:before,.l-navigation [class*=p-side-navigation--] .p-side-navigation__item.has-active-child:before{content:"";height:auto;width:.1875rem;background-color:#111;position:absolute;top:0;bottom:0;left:0}.l-navigation.is-pinned .p-side-navigation .p-side-navigation__item.has-active-child,.l-navigation:focus-within .p-side-navigation .p-side-navigation__item.has-active-child,.l-navigation:hover .p-side-navigation .p-side-navigation__item.has-active-child,.l-navigation.is-pinned [class*=p-side-navigation--] .p-side-navigation__item.has-active-child,.l-navigation:focus-within [class*=p-side-navigation--] .p-side-navigation__item.has-active-child,.l-navigation:hover [class*=p-side-navigation--] .p-side-navigation__item.has-active-child{color:#000000bf;background:0 0;position:relative}.l-navigation.is-pinned .p-side-navigation .p-side-navigation__item.has-active-child:before,.l-navigation:focus-within .p-side-navigation .p-side-navigation__item.has-active-child:before,.l-navigation:hover .p-side-navigation .p-side-navigation__item.has-active-child:before,.l-navigation.is-pinned [class*=p-side-navigation--] .p-side-navigation__item.has-active-child:before,.l-navigation:focus-within [class*=p-side-navigation--] .p-side-navigation__item.has-active-child:before,.l-navigation:hover [class*=p-side-navigation--] .p-side-navigation__item.has-active-child:before{content:"";height:auto;width:.1875rem;background-color:#0000;position:absolute;top:0;bottom:0;left:0}}@media (min-width:1036px){.l-navigation .p-side-navigation .p-side-navigation__item.has-active-child,.l-navigation [class*=p-side-navigation--] .p-side-navigation__item.has-active-child{color:#000000bf;background:0 0;position:relative}.l-navigation .p-side-navigation .p-side-navigation__item.has-active-child:before,.l-navigation [class*=p-side-navigation--] .p-side-navigation__item.has-active-child:before{content:"";height:auto;width:.1875rem;background-color:#0000;position:absolute;top:0;bottom:0;left:0}}.p-side-navigation.is-dark,[class*=p-side-navigation--].is-dark{color:#ffffffbf}.p-side-navigation.is-dark .p-side-navigation__toggle,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle{color:#111;background-color:#fff;border-color:#0000008f}.p-side-navigation.is-dark .p-side-navigation__toggle:visited,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle:visited{color:#111}.p-side-navigation.is-dark .p-side-navigation__toggle:hover,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle:hover{background-color:#f2f2f2;border-color:#0000008f}.p-side-navigation.is-dark .p-side-navigation__toggle:active,.p-side-navigation.is-dark .p-side-navigation__toggle[aria-pressed=true],.p-side-navigation.is-dark .p-side-navigation__toggle[aria-selected=true],.p-side-navigation.is-dark .p-side-navigation__toggle[aria-expanded=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle:active,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle[aria-pressed=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle[aria-selected=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle[aria-expanded=true]{background-color:#e6e6e6;border-color:#0000008f;transition-duration:0s}.p-side-navigation.is-dark .p-side-navigation__toggle:disabled:active,.p-side-navigation.is-dark .p-side-navigation__toggle:disabled[aria-pressed=true],.p-side-navigation.is-dark .p-side-navigation__toggle:disabled[aria-selected=true],.p-side-navigation.is-dark .p-side-navigation__toggle:disabled[aria-expanded=true],.p-side-navigation.is-dark .p-side-navigation__toggle:disabled:hover,.p-side-navigation.is-dark .p-side-navigation__toggle.is-disabled:active,.p-side-navigation.is-dark .p-side-navigation__toggle.is-disabled[aria-pressed=true],.p-side-navigation.is-dark .p-side-navigation__toggle.is-disabled[aria-selected=true],.p-side-navigation.is-dark .p-side-navigation__toggle.is-disabled[aria-expanded=true],.p-side-navigation.is-dark .p-side-navigation__toggle.is-disabled:hover,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle:disabled:active,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle:disabled[aria-pressed=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle:disabled[aria-selected=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle:disabled[aria-expanded=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle:disabled:hover,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle.is-disabled:active,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle.is-disabled[aria-pressed=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle.is-disabled[aria-selected=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle.is-disabled[aria-expanded=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle.is-disabled:hover{background-color:#0000;border-color:#0000008f}.p-side-navigation.is-dark .p-side-navigation__toggle:before,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle:before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23666' d='M8.187 11.748l6.187-6.187-1.06-1.061-5.127 5.127L3.061 4.5 2 5.561z'/%3E%3C/svg%3E")}.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer{color:#ffffffbf;background-color:#0000;border-color:#0000}.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer:visited,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer:visited{color:#ffffffbf}.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer:hover,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer:hover{background-color:#ffffff0d;border-color:#0000}.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer:active,.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer[aria-pressed=true],.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer[aria-selected=true],.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer[aria-expanded=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer:active,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer[aria-pressed=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer[aria-selected=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer[aria-expanded=true]{background-color:#ffffff1a;border-color:#0000;transition-duration:0s}.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer:disabled:active,.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer:disabled[aria-pressed=true],.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer:disabled[aria-selected=true],.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer:disabled[aria-expanded=true],.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer:disabled:hover,.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer.is-disabled:active,.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer.is-disabled[aria-pressed=true],.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer.is-disabled[aria-selected=true],.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer.is-disabled[aria-expanded=true],.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer.is-disabled:hover,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer:disabled:active,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer:disabled[aria-pressed=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer:disabled[aria-selected=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer:disabled[aria-expanded=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer:disabled:hover,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer.is-disabled:active,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer.is-disabled[aria-pressed=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer.is-disabled[aria-selected=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer.is-disabled[aria-expanded=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer.is-disabled:hover{background-color:#0000;border-color:#0000008f}.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer:before,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer:before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23999' d='M8.187 11.748l6.187-6.187-1.06-1.061-5.127 5.127L3.061 4.5 2 5.561z'/%3E%3C/svg%3E")}.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer[aria-expanded=true],[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer[aria-expanded=true]{background-color:#0000}.p-side-navigation.is-dark .p-side-navigation__toggle--in-drawer[aria-expanded=true]:hover,[class*=p-side-navigation--].is-dark .p-side-navigation__toggle--in-drawer[aria-expanded=true]:hover{color:#fff;background:#ffffff0d}.p-side-navigation.is-dark .p-side-navigation__drawer,[class*=p-side-navigation--].is-dark .p-side-navigation__drawer{background:#262626}.p-side-navigation.is-dark .p-side-navigation__overlay,[class*=p-side-navigation--].is-dark .p-side-navigation__overlay{background:#111111d9}.p-side-navigation.is-dark .p-side-navigation__drawer-header,[class*=p-side-navigation--].is-dark .p-side-navigation__drawer-header{background:#262626;border-color:#ffffff1a}.p-side-navigation.is-dark .p-side-navigation__list:after,[class*=p-side-navigation--].is-dark .p-side-navigation__list:after{background:#ffffff1a}.p-side-navigation.is-dark .p-side-navigation__link,.p-side-navigation.is-dark .p-side-navigation__link:visited,[class*=p-side-navigation--].is-dark .p-side-navigation__link,[class*=p-side-navigation--].is-dark .p-side-navigation__link:visited{color:#ffffffbf}.p-side-navigation.is-dark .p-side-navigation__link:hover,[class*=p-side-navigation--].is-dark .p-side-navigation__link:hover{color:#fff;background:#ffffff0d}.p-side-navigation.is-dark .p-side-navigation__link:active,.p-side-navigation.is-dark .p-side-navigation__link.is-active,.p-side-navigation.is-dark .p-side-navigation__link[aria-current=page],.p-side-navigation.is-dark .p-side-navigation__link[aria-current=true],[class*=p-side-navigation--].is-dark .p-side-navigation__link:active,[class*=p-side-navigation--].is-dark .p-side-navigation__link.is-active,[class*=p-side-navigation--].is-dark .p-side-navigation__link[aria-current=page],[class*=p-side-navigation--].is-dark .p-side-navigation__link[aria-current=true]{color:#fff;cursor:default;background:#ffffff1a}.p-side-navigation.is-dark .p-side-navigation__link.is-active,.p-side-navigation.is-dark .p-side-navigation__link[aria-current=page],.p-side-navigation.is-dark .p-side-navigation__link[aria-current=true],[class*=p-side-navigation--].is-dark .p-side-navigation__link.is-active,[class*=p-side-navigation--].is-dark .p-side-navigation__link[aria-current=page],[class*=p-side-navigation--].is-dark .p-side-navigation__link[aria-current=true]{position:relative}.p-side-navigation.is-dark .p-side-navigation__link.is-active:before,.p-side-navigation.is-dark .p-side-navigation__link[aria-current=page]:before,.p-side-navigation.is-dark .p-side-navigation__link[aria-current=true]:before,[class*=p-side-navigation--].is-dark .p-side-navigation__link.is-active:before,[class*=p-side-navigation--].is-dark .p-side-navigation__link[aria-current=page]:before,[class*=p-side-navigation--].is-dark .p-side-navigation__link[aria-current=true]:before{content:"";height:auto;width:.1875rem;background-color:#fff;position:absolute;top:0;bottom:0;left:0}.p-side-navigation.is-dark .p-side-navigation__heading,.p-side-navigation.is-dark .p-side-navigation__heading--linked .p-side-navigation__link,.p-side-navigation.is-dark .p-side-navigation__item--title,.p-side-navigation.is-dark .p-side-navigation__item--title .p-side-navigation__link,[class*=p-side-navigation--].is-dark .p-side-navigation__heading,[class*=p-side-navigation--].is-dark .p-side-navigation__heading--linked .p-side-navigation__link,[class*=p-side-navigation--].is-dark .p-side-navigation__item--title,[class*=p-side-navigation--].is-dark .p-side-navigation__item--title .p-side-navigation__link{color:#fff}@media (min-width:620px){.l-navigation .p-side-navigation.is-dark .p-side-navigation__item.has-active-child,.l-navigation [class*=p-side-navigation--].is-dark .p-side-navigation__item.has-active-child{color:#fff;background:#ffffff0d;position:relative}.l-navigation .p-side-navigation.is-dark .p-side-navigation__item.has-active-child:before,.l-navigation [class*=p-side-navigation--].is-dark .p-side-navigation__item.has-active-child:before{content:"";height:auto;width:.1875rem;background-color:#fff;position:absolute;top:0;bottom:0;left:0}.l-navigation.is-pinned .p-side-navigation.is-dark .p-side-navigation__item.has-active-child,.l-navigation:focus-within .p-side-navigation.is-dark .p-side-navigation__item.has-active-child,.l-navigation:hover .p-side-navigation.is-dark .p-side-navigation__item.has-active-child,.l-navigation.is-pinned [class*=p-side-navigation--].is-dark .p-side-navigation__item.has-active-child,.l-navigation:focus-within [class*=p-side-navigation--].is-dark .p-side-navigation__item.has-active-child,.l-navigation:hover [class*=p-side-navigation--].is-dark .p-side-navigation__item.has-active-child{color:#ffffffbf;background:0 0;position:relative}.l-navigation.is-pinned .p-side-navigation.is-dark .p-side-navigation__item.has-active-child:before,.l-navigation:focus-within .p-side-navigation.is-dark .p-side-navigation__item.has-active-child:before,.l-navigation:hover .p-side-navigation.is-dark .p-side-navigation__item.has-active-child:before,.l-navigation.is-pinned [class*=p-side-navigation--].is-dark .p-side-navigation__item.has-active-child:before,.l-navigation:focus-within [class*=p-side-navigation--].is-dark .p-side-navigation__item.has-active-child:before,.l-navigation:hover [class*=p-side-navigation--].is-dark .p-side-navigation__item.has-active-child:before{content:"";height:auto;width:.1875rem;background-color:#0000;position:absolute;top:0;bottom:0;left:0}}@media (min-width:1036px){.l-navigation .p-side-navigation.is-dark .p-side-navigation__item.has-active-child,.l-navigation [class*=p-side-navigation--].is-dark .p-side-navigation__item.has-active-child{color:#ffffffbf;background:0 0;position:relative}.l-navigation .p-side-navigation.is-dark .p-side-navigation__item.has-active-child:before,.l-navigation [class*=p-side-navigation--].is-dark .p-side-navigation__item.has-active-child:before{content:"";height:auto;width:.1875rem;background-color:#0000;position:absolute;top:0;bottom:0;left:0}}.p-side-navigation--raw-html ul:after{background:#0000001a}.p-side-navigation--raw-html li>a,.p-side-navigation--raw-html li>a:visited{color:#000000bf}.p-side-navigation--raw-html li>a:hover{color:#111;background:#f2f2f2}.p-side-navigation--raw-html li>a:active,.p-side-navigation--raw-html li>a.is-active,.p-side-navigation--raw-html li>a[aria-current=page],.p-side-navigation--raw-html li>a[aria-current=true]{color:#111;background:#e6e6e6;position:relative}.p-side-navigation--raw-html li>a:active:before,.p-side-navigation--raw-html li>a.is-active:before,.p-side-navigation--raw-html li>a[aria-current=page]:before,.p-side-navigation--raw-html li>a[aria-current=true]:before{content:"";height:auto;width:.1875rem;background-color:#111;position:absolute;top:0;bottom:0;left:0}.p-side-navigation--raw-html h2,.p-side-navigation--raw-html h3,.p-side-navigation--raw-html h4,.p-side-navigation--raw-html h5,.p-side-navigation--raw-html h6{color:#111}.p-side-navigation--raw-html.is-light ul:after{background:#ffffff1a}.p-side-navigation--raw-html.is-light li>a,.p-side-navigation--raw-html.is-light li>a:visited{color:#ffffffbf}.p-side-navigation--raw-html.is-light li>a:hover{color:#fff;background:#ffffff0d}.p-side-navigation--raw-html.is-light li>a:active,.p-side-navigation--raw-html.is-light li>a.is-active,.p-side-navigation--raw-html.is-light li>a[aria-current=page],.p-side-navigation--raw-html.is-light li>a[aria-current=true]{color:#fff;background:#ffffff1a;position:relative}.p-side-navigation--raw-html.is-light li>a:active:before,.p-side-navigation--raw-html.is-light li>a.is-active:before,.p-side-navigation--raw-html.is-light li>a[aria-current=page]:before,.p-side-navigation--raw-html.is-light li>a[aria-current=true]:before{content:"";height:auto;width:.1875rem;background-color:#fff;position:absolute;top:0;bottom:0;left:0}.p-side-navigation--raw-html.is-light h2,.p-side-navigation--raw-html.is-light h3,.p-side-navigation--raw-html.is-light h4,.p-side-navigation--raw-html.is-light h5,.p-side-navigation--raw-html.is-light h6{color:#fff}.p-slider__wrapper{width:100%;align-items:center;display:inline-flex}.p-slider__input{height:2.625rem;min-width:5rem;text-align:center;width:5%;margin:0 0 0 1rem}.p-status-label--negative,.p-label--negative,.p-status-label--information,.p-label--information,.p-status-label--caution,.p-label--caution,.p-status-label--positive,.p-label--positive,.p-status-label,.p-label{text-align:center;white-space:nowrap;border-radius:.125rem;padding:.25rem .5rem;font-weight:400;text-decoration:none;display:inline-block}.p-status-label,.p-label{color:#fff;background-color:#666}.p-status-label--positive,.p-label--positive{color:#fff;background-color:#0e8420}.p-status-label--caution,.p-label--caution{color:#111;background-color:#f99b11}.p-status-label--information,.p-label--information{color:#fff;background-color:#24598f}.p-status-label--negative,.p-label--negative{color:#fff;background-color:#c7162b}.p-strip--suru-topped,.p-strip--suru,.p-strip--image,.p-strip--accent,.p-strip--dark,.p-strip--light,.p-strip{clear:both;width:100%;position:relative}.p-strip{background-color:#0000}.p-strip--light{background-color:#f7f7f7}.p-strip--dark{color:#f7f7f7;background-color:#111}.p-strip--accent{color:#fff;background-color:#333}.p-strip--image{background-repeat:no-repeat;background-size:cover}.p-strip--image.is-light{color:#111}.p-strip--image.is-dark{color:#fff}.p-strip--suru{color:#fff;background-image:linear-gradient(to bottom right,#cdcdcd24 0% 49.8%,#0000 50% 100%),linear-gradient(to bottom left,#cdcdcd24 0% 49.8%,#0000 50% 100%),linear-gradient(to top right,#fff 0% 49%,#0000 50% 100%),linear-gradient(to top right,#fff 0% 100%),linear-gradient(111deg,#4d4d4d 10%,#333 37%,#1a1a1a 100%);background-position:0 0,100% 0,right 0 bottom 4rem,100% 100%,0 0;background-repeat:no-repeat;background-size:100% calc(100% - 4rem),50% 100%,100% 4rem,100% 4rem,auto;margin-bottom:-4rem;padding-bottom:12rem;position:relative;overflow:hidden}@supports (background-blend-mode: multiply){.p-strip--suru{background-blend-mode:multiply,multiply,normal,normal,normal;background-image:linear-gradient(to bottom right,#cdcdcd8c 0% 49.8%,#0000 50% 100%),linear-gradient(to bottom left,#cdcdcd8c 0% 49.8%,#0000 50% 100%),linear-gradient(to top right,#fff 0% 49%,#0000 50% 100%),linear-gradient(#fff 0% 100%),linear-gradient(111deg,#4d4d4d 10%,#333 37%,#1a1a1a 100%)}}.p-strip--suru.is-deep{background-position:0 0,100% 0,right 0 bottom 3rem,100% 100%,0 0;background-size:100% calc(100% - 3rem),100% 100%,100% 3rem,100% 3rem,auto;margin-bottom:-3rem;padding-bottom:9rem!important}@media (min-width:1036px){.p-strip--suru.is-deep{background-position:0 0,100% 0,right 0 bottom 6rem,100% 100%,0 0;background-size:100% calc(100% - 6rem),50% 100%,100% 6rem,100% 6rem,auto;margin-bottom:-6rem;padding-bottom:18rem!important}}.p-strip--suru.is-shallow{padding:4rem 0 12rem}.p-strip--suru-topped{background-image:linear-gradient(to bottom left,#e5e5e524 0% 49%,#0000 50% 100%),linear-gradient(to bottom left,#33333324 0% 49%,#0000 50% 100%),linear-gradient(to bottom right,#0000 0% 49%,#fff 50% 100%),linear-gradient(90deg,#4d4d4d 4%,#333 50%,#1a1a1a 88%);background-position:100% 0,100% 0,0 0,0 0;background-repeat:no-repeat;background-size:39.4% 6rem,54% 4rem,63% 4rem,62.6% 4rem;padding-top:6rem;padding-bottom:4rem}@supports (background-blend-mode: multiply){.p-strip--suru-topped{background-blend-mode:multiply,multiply,normal,normal;background-image:linear-gradient(to bottom left,#e5e5e580 0% 49%,#0000 50% 100%),linear-gradient(to bottom left,#33333329 0% 49%,#0000 50% 100%),linear-gradient(to bottom right,#0000 0% 49%,#fff 50% 100%),linear-gradient(90deg,#4d4d4d 4%,#333 50%,#1a1a1a 88%)}}.p-strip--suru-topped.is-shallow{padding:6rem 0 4rem}.p-switch{align-items:center;display:flex}.p-switch__input{opacity:0;margin:0;position:absolute}.p-switch__input:checked+.p-switch__slider:before{border:1px solid #06c;left:50%}.p-switch__input:checked+.p-switch__slider{background:#06c}.p-switch__input:focus{outline:none}.p-switch__input:focus+.p-switch__slider{outline:.1875rem solid #2e96ff}.p-switch__slider{height:1rem;width:2rem;background:#d9d9d9;border-radius:1rem;margin:0;display:inline-block;position:relative;box-shadow:inset 0 2px 5px #1113}.p-switch__slider:before{content:"";height:1rem;width:1rem;background:#fff;border:1px solid #666;border-radius:50%;transition-property:all;transition-duration:.5s;transition-timing-function:cubic-bezier(.215,.61,.355,1);position:absolute;left:0}.p-switch__label{margin-left:.5rem}.p-table__cell--icon-placeholder{padding-left:2rem}.p-table__cell--icon-placeholder [class^=p-icon]:first-child{margin-left:-1.5rem;margin-right:.5rem}.p-table--expanding{flex-flow:column;justify-content:space-between;display:flex}.p-table--expanding thead,.p-table--expanding tbody{margin:0}.p-table--expanding tr{width:100%;flex-flow:wrap;margin:0;display:flex}.p-table--expanding th,.p-table--expanding td{text-overflow:ellipsis;flex-grow:1;flex-basis:0;align-items:flex-start;margin:0;display:block}.p-table--expanding th.p-table__expanding-panel,.p-table--expanding td.p-table__expanding-panel{max-width:100%;flex-basis:100%}.p-table--expanding th.p-table__expanding-panel[aria-hidden=true],.p-table--expanding td.p-table__expanding-panel[aria-hidden=true]{display:none}.p-table--expanding th.p-table__expanding-panel .row,.p-table--expanding td.p-table__expanding-panel .row{max-width:100%;width:100%;padding:0}.p-table--expanding th[aria-hidden=true],.p-table--expanding td[aria-hidden=true]{display:none}.p-table-of-contents{border-top:1px solid #d9d9d9;padding:0 1.5rem;font-size:.875rem}@media (min-width:1036px){.p-table-of-contents{border-top:0;border-left:1px solid #d9d9d9;padding:0 1rem}}.p-table-of-contents__header{color:#666;text-transform:uppercase;margin-bottom:1rem;font-size:1rem;line-height:1.5}.p-table-of-contents__section{padding:1rem 0}.p-table-of-contents__section:not(:last-child){border-bottom:1px dotted #d9d9d9}.p-table-of-contents__nav{margin:0;padding:0;list-style:none}.p-table-of-contents__nav .p-table-of-contents__link{color:#111;border-bottom:0;margin-bottom:.25rem}.p-table-of-contents__nav .p-table-of-contents__link:visited{color:#111}.p-table-of-contents__nav .p-table-of-contents__link:hover{color:#06c}.p-table-of-contents__nav .p-table-of-contents__link.is-active{padding-left:.25rem;font-weight:400}.p-table--mobile-card td:before,.p-table--mobile-card tbody th:before{text-align:left}@media (max-width:1035px){@supports (display: grid){.p-table--mobile-card thead{display:none}.p-table--mobile-card tbody{grid-gap:0 1.5rem;width:100%;grid-template-rows:auto;grid-template-columns:repeat(auto-fit,minmax(12rem,1fr));display:grid}.p-table--mobile-card tr{border:1px solid #d9d9d9;border-radius:.125rem;margin-bottom:1.5rem;padding:0 1rem;display:block}.p-table--mobile-card td,.p-table--mobile-card tbody th{min-width:100%;text-overflow:ellipsis;white-space:nowrap;width:100%;word-break:break-word;padding-left:0;padding-right:0;display:block;position:relative;overflow:hidden}.p-table--mobile-card td.u-align--right,.p-table--mobile-card tbody th.u-align--right{justify-content:unset!important;text-align:left!important}.p-table--mobile-card td.has-overflow,.p-table--mobile-card tbody th.has-overflow{overflow:visible}.p-table--mobile-card td[data-heading]:before,.p-table--mobile-card tbody th[data-heading]:before{content:attr(data-heading);text-overflow:ellipsis;width:100%;margin-bottom:.25rem;padding-left:0;padding-right:0;display:block;overflow:hidden}.p-table--mobile-card td:not(:first-child):after,.p-table--mobile-card tbody th:not(:first-child):after{content:"";height:1px;background-color:#d9d9d9;position:absolute;top:0;left:0;right:0}}}table th[aria-sort=descending]:after,table th[aria-sort=ascending]:after{height:1rem;width:1rem;content:"";vertical-align:calc(.5px + .3465em - .5rem);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23666' d='M8.187 11.748l6.187-6.187-1.06-1.061-5.127 5.127L3.061 4.5 2 5.561z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:100%;margin-top:-.234375rem;margin-left:.25rem;display:inline-block}table th[aria-sort]{cursor:pointer;white-space:nowrap;align-items:center}table th[aria-sort=descending]:after{transform:rotate(180deg)}table th[aria-sort]:hover{color:#06c;text-decoration:underline}.p-tabs{border-radius:0;padding:0;position:relative;overflow:hidden}.p-tabs__list{white-space:nowrap;width:100%;margin:0 auto 1.5rem;padding:0;display:flex;position:relative;overflow-x:auto}.p-tabs__item{width:auto;margin:0;padding:0}.p-tabs__item:last-child{margin-right:3rem}.p-tabs__link{color:#111;color:#111;height:100%;background-color:#fff;border:none;align-items:center;gap:.5rem;margin-bottom:0;padding:.75rem 1rem;line-height:1.5rem;display:flex;position:relative}.p-tabs__link:visited{color:#111}.p-tabs__link:hover{background-color:#f2f2f2;border-color:#0000}.p-tabs__link:active,.p-tabs__link[aria-pressed=true],.p-tabs__link[aria-selected=true],.p-tabs__link[aria-expanded=true]{background-color:#e6e6e6;border-color:#0000;transition-duration:0s}.p-tabs__link:disabled:active,.p-tabs__link:disabled[aria-pressed=true],.p-tabs__link:disabled[aria-selected=true],.p-tabs__link:disabled[aria-expanded=true],.p-tabs__link:disabled:hover,.p-tabs__link.is-disabled:active,.p-tabs__link.is-disabled[aria-pressed=true],.p-tabs__link.is-disabled[aria-selected=true],.p-tabs__link.is-disabled[aria-expanded=true],.p-tabs__link.is-disabled:hover{background-color:#0000;border-color:#0000}.p-tabs__link:before{content:"";height:.1875rem;width:auto;z-index:1;background-color:#0000;transition-property:background-color,border-color;transition-duration:.1s;transition-timing-function:cubic-bezier(.55,.055,.675,.19);position:absolute;inset:auto 0 0}.p-tabs__link:focus{z-index:1}.p-tabs__link:focus:before,.p-tabs__link:focus:after{content:none}.p-tabs__link:focus:not(:focus-visible){position:relative}.p-tabs__link:focus:not(:focus-visible):before{content:"";height:.1875rem;width:auto;background-color:#111;position:absolute;inset:auto 0 0}.p-tabs__link:active,.p-tabs__link[aria-selected=true]{position:relative}.p-tabs__link:active:before,.p-tabs__link[aria-selected=true]:before{content:"";height:.1875rem;width:auto;background-color:#111;position:absolute;inset:auto 0 0}.p-tabs__link:active:focus:not(:focus-visible),.p-tabs__link[aria-selected=true]:focus:not(:focus-visible){position:relative}.p-tabs__link:active:focus:not(:focus-visible):before,.p-tabs__link[aria-selected=true]:focus:not(:focus-visible):before{content:"";height:.1875rem;width:auto;background-color:#111;position:absolute;inset:auto 0 0}.p-tabs__link:active:focus:before,.p-tabs__link:active:focus:after,.p-tabs__link[aria-selected=true]:focus:before,.p-tabs__link[aria-selected=true]:focus:after{content:none}.p-tooltip--left,.p-tooltip--right,.p-tooltip--top-right,.p-tooltip--top-center,.p-tooltip--top-left,.p-tooltip--btm-right,.p-tooltip--btm-center,.p-tooltip{position:relative}.p-tooltip--left:focus .p-tooltip__message,.p-tooltip--right:focus .p-tooltip__message,.p-tooltip--top-right:focus .p-tooltip__message,.p-tooltip--top-center:focus .p-tooltip__message,.p-tooltip--top-left:focus .p-tooltip__message,.p-tooltip--btm-right:focus .p-tooltip__message,.p-tooltip--btm-center:focus .p-tooltip__message,.p-tooltip:focus .p-tooltip__message,.p-tooltip--left:hover .p-tooltip__message,.p-tooltip--right:hover .p-tooltip__message,.p-tooltip--top-right:hover .p-tooltip__message,.p-tooltip--top-center:hover .p-tooltip__message,.p-tooltip--top-left:hover .p-tooltip__message,.p-tooltip--btm-right:hover .p-tooltip__message,.p-tooltip--btm-center:hover .p-tooltip__message,.p-tooltip:hover .p-tooltip__message{text-decoration:initial;display:inline}.is-detached.p-tooltip--left,.is-detached.p-tooltip--right,.is-detached.p-tooltip--top-right,.is-detached.p-tooltip--top-center,.is-detached.p-tooltip--top-left,.is-detached.p-tooltip--btm-right,.is-detached.p-tooltip--btm-center,.is-detached.p-tooltip{display:block;position:absolute}.p-tooltip__message{color:#fff;text-align:left;text-decoration:initial;white-space:pre;z-index:11;background-color:#111;border:0;border-radius:.125rem;margin-bottom:0;padding:.5rem 1rem;display:none;position:absolute;top:100%;left:-1rem;transform:translate(0%)translateY(13px)}.is-detached .p-tooltip__message{display:block}.p-tooltip__message:before{content:"";height:0;pointer-events:none;width:0;border-bottom:.5rem solid #111;border-left:.5rem solid #0000;border-right:.5rem solid #0000;position:absolute;bottom:100%;left:1rem}.p-tooltip__message:after{content:"";height:1rem;border-radius:10% 90% 0% 100%/100% 100% 0% 0%;position:absolute;top:-1rem;left:0;right:0}.p-tooltip--btm-center .p-tooltip__message{bottom:inherit;top:100%;left:50%;transform:translate(-50%)translateY(13px)}.p-tooltip--btm-center .p-tooltip__message:before{left:50%;transform:translate(-50%)}.p-tooltip--btm-center .p-tooltip__message:after{height:1rem;border-radius:50% 50% 0% 100%/100% 100% 0% 0%}.p-tooltip--btm-right .p-tooltip__message{bottom:inherit;left:initial;top:100%;right:-1rem;transform:translateY(13px)}.p-tooltip--btm-right .p-tooltip__message:before{left:initial;right:1rem}.p-tooltip--btm-right .p-tooltip__message:after{height:1rem;border-radius:90% 10% 0% 100%/100% 100% 0% 0%}.p-tooltip--top-left .p-tooltip__message{bottom:100%;left:-1rem;top:initial;transform:translate(0%)translateY(-13px)}.p-tooltip--top-left .p-tooltip__message:before{border:.5rem solid #0000;border-top-color:#111;bottom:-1rem;left:1rem}.p-tooltip--top-left .p-tooltip__message:after{height:1rem;border-radius:0% 100% 90% 10%/0% 0% 100% 100%;top:auto;bottom:-1rem}.p-tooltip--top-center .p-tooltip__message{bottom:100%;left:50%;top:initial;transform:translate(-50%)translateY(-13px)}.p-tooltip--top-center .p-tooltip__message:before{border:.5rem solid #0000;border-top-color:#111;bottom:-1rem;left:50%;transform:translate(-50%)}.p-tooltip--top-center .p-tooltip__message:after{height:1rem;border-radius:100% 0% 50% 50%/0% 0% 100% 100%;top:auto;bottom:-1rem}.p-tooltip--top-right .p-tooltip__message{bottom:100%;left:initial;right:-1rem;top:initial;transform:translate(0%)translateY(-13px)}.p-tooltip--top-right .p-tooltip__message:before{bottom:-1rem;left:initial;border:.5rem solid #0000;border-top-color:#111;right:1rem}.p-tooltip--top-right .p-tooltip__message:after{height:1rem;border-radius:100% 0% 10% 90%/0% 0% 100% 100%;top:auto;bottom:-1rem}.p-tooltip--right .p-tooltip__message{bottom:inherit;top:50%;left:100%;transform:translate(14px)translateY(-50%)}.p-tooltip--right .p-tooltip__message:before{bottom:inherit;border:.5rem solid #0000;border-right-color:#111;top:50%;left:0;transform:translate(-16px)translateY(-50%)}.p-tooltip--right .p-tooltip__message:after{height:auto;width:1rem;border-radius:0;inset:0 auto 0 -1rem}.p-tooltip--left .p-tooltip__message{bottom:inherit;top:50%;left:-16px;transform:translate(-100%)translateY(-50%)}.p-tooltip--left .p-tooltip__message:before{bottom:inherit;border:.5rem solid #0000;border-left-color:#111;top:50%;left:100%;transform:translate(0)translateY(-50%)}.p-tooltip--left .p-tooltip__message:after{height:auto;width:1rem;border-radius:0;inset:0 -1rem 0 auto}.l-application{height:100vh;width:100vw;grid-template:"nav navbar navbar"min-content"nav main aside"1fr"nav status status"min-content/min-content minmax(0,1fr) minmax(0,min-content);display:grid;overflow:hidden}.l-navigation-bar{grid-area:navbar}.l-navigation{height:100vh;width:100%;z-index:103;transition-property:transform,box-shadow;transition-duration:.165s;transition-timing-function:cubic-bezier(.215,.61,.355,1);position:fixed;top:0;bottom:0;left:0;overflow-y:auto;transform:translate(0);box-shadow:0 0 2rem #0003}@media (min-width:460px){.l-navigation{width:auto}}.l-navigation.is-collapsed{transform:translate(-100%);box-shadow:0 0 #0000}.l-navigation.is-collapsed:focus-within{transform:none;box-shadow:0 0 2rem #0003}.l-navigation__drawer{height:100vh;width:auto}@media (min-width:460px){.l-navigation__drawer{width:15rem}}@media (min-width:620px){.l-navigation-bar{visibility:hidden;width:4rem;grid-area:nav;overflow:hidden}.l-navigation{width:4rem;transition-property:width,box-shadow;transition-duration:.165s;transition-timing-function:cubic-bezier(.215,.61,.355,1);overflow:hidden;transform:translate(0);box-shadow:0 0 #0000}.l-navigation.is-collapsed{width:4rem;transform:translate(0)}.l-navigation:hover,.l-navigation:focus-within,.l-navigation.is-pinned{width:15rem;overflow-y:auto}.l-navigation:hover{box-shadow:0 0 2rem #0003}.l-navigation.is-pinned{grid-area:nav;position:static;box-shadow:0 0 #0000}}@media (min-width:1036px){.l-navigation-bar{display:none}.l-navigation{box-shadow:none;width:15rem;grid-area:nav;position:static;overflow-y:auto}.l-navigation:hover{box-shadow:none}.l-navigation.is-collapsed{width:15rem;transform:translate(0)}}@media (min-width:620px){.l-navigation .p-side-navigation .p-side-navigation__list:after,.l-navigation [class*=p-side-navigation--] .p-side-navigation__list:after,.l-navigation .p-side-navigation .p-side-navigation__label,.l-navigation [class*=p-side-navigation--] .p-side-navigation__label,.l-navigation .is-fading-when-collapsed{opacity:0;transition-property:opacity;transition-duration:.1s;transition-timing-function:cubic-bezier(.215,.61,.355,1)}.l-navigation.is-pinned .p-side-navigation .p-side-navigation__list:after,.l-navigation.is-pinned [class*=p-side-navigation--] .p-side-navigation__list:after,.l-navigation.is-pinned .p-side-navigation .p-side-navigation__label,.l-navigation.is-pinned [class*=p-side-navigation--] .p-side-navigation__label,.l-navigation.is-pinned .is-fading-when-collapsed,.l-navigation:focus-within .p-side-navigation .p-side-navigation__list:after,.l-navigation:focus-within [class*=p-side-navigation--] .p-side-navigation__list:after,.l-navigation:focus-within .p-side-navigation .p-side-navigation__label,.l-navigation:focus-within [class*=p-side-navigation--] .p-side-navigation__label,.l-navigation:focus-within .is-fading-when-collapsed,.l-navigation:hover .p-side-navigation .p-side-navigation__list:after,.l-navigation:hover [class*=p-side-navigation--] .p-side-navigation__list:after,.l-navigation:hover .p-side-navigation .p-side-navigation__label,.l-navigation:hover [class*=p-side-navigation--] .p-side-navigation__label,.l-navigation:hover .is-fading-when-collapsed{opacity:1}}@media (min-width:1036px){.l-navigation .p-side-navigation .p-side-navigation__list:after,.l-navigation [class*=p-side-navigation--] .p-side-navigation__list:after,.l-navigation .p-side-navigation .p-side-navigation__label,.l-navigation [class*=p-side-navigation--] .p-side-navigation__label,.l-navigation .is-fading-when-collapsed{opacity:1}}@media (min-width:620px){.l-navigation .p-side-navigation__list .p-side-navigation__list{display:none}.l-navigation.is-pinned .p-side-navigation__list .p-side-navigation__list,.l-navigation:focus-within .p-side-navigation__list .p-side-navigation__list,.l-navigation:hover .p-side-navigation__list .p-side-navigation__list{display:block}}@media (min-width:1036px){.l-navigation .p-side-navigation__list .p-side-navigation__list{display:block}}@media (min-width:620px){.l-navigation .p-side-navigation__item{white-space:nowrap}.l-navigation.is-pinned .p-side-navigation__item,.l-navigation:focus-within .p-side-navigation__item,.l-navigation:hover .p-side-navigation__item{white-space:normal}}@media (min-width:1036px){.l-navigation .p-side-navigation__item{white-space:normal}}.l-main{grid-area:main;overflow-y:auto}.l-status{z-index:102;border-top:1px solid #0000001a;grid-area:status}.l-aside{width:100%;z-index:101;grid-area:main;justify-self:right;transition-property:transform,box-shadow;transition-duration:.1s;transition-timing-function:cubic-bezier(.215,.61,.355,1);overflow-y:auto;box-shadow:0 0 2rem #0003}@media (min-width:460px){.l-aside{max-width:100%;width:33.5rem}.l-aside.is-wide{width:72rem}.l-aside.is-narrow{width:21.65rem}}.l-aside.is-collapsed{transform:translate(100%);box-shadow:0 0 #0000}@media (min-width:620px){.l-aside.is-pinned{box-shadow:none;max-width:50vw;border-left:1px solid #0000001a;grid-area:aside;justify-self:auto}.l-aside.is-pinned.is-collapsed{display:none}}.p-panel{color:#111;max-width:100%;min-height:100%;background:#fff}.p-panel.is-dark{color:#fff;background:#262626}.p-panel__header{display:flex}.p-panel__header.is-sticky{z-index:1;position:sticky;top:0}.p-panel.is-dark .p-panel__header.is-sticky{background:#262626}.p-panel__content{overflow:hidden}.p-panel__logo{align-items:center;margin-top:1.25rem;margin-bottom:1.25rem;margin-left:-.25rem;display:flex}.p-panel__logo .p-panel__logo-icon{height:1.5rem}.p-panel__logo .p-panel__logo-name{height:1rem;margin-left:.5rem}.p-panel__title{margin:0;padding-top:1rem;padding-bottom:1rem}.p-panel__controls{margin-left:auto;padding-top:1rem}.p-panel__toggle{cursor:pointer;margin-top:.25rem;margin-bottom:1.25rem;display:block}@media (min-width:620px){.l-site{min-height:100vh;flex-direction:column;display:flex}.l-footer--sticky{margin-top:auto}}.l-fluid-breakout{grid-gap:0 0;padding-left:1rem;padding-right:1rem;display:block}@media (min-width:1036px){.l-fluid-breakout{max-width:100rem;grid-template-rows:auto;grid-template-columns:minmax(14rem,1fr) minmax(0,72rem) minmax(14rem,1fr);margin-left:auto;margin-right:auto;display:grid}}@media (min-width:620px){.l-fluid-breakout{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width:1036px){.l-fluid-breakout{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width:86rem){.l-fluid-breakout{padding-left:0;padding-right:0}@supports (display: grid){.l-fluid-breakout{grid-gap:0 0}}}.l-fluid-breakout .l-fluid-breakout__main{grid-gap:0 1rem;width:100%;grid-row:2;grid-template-columns:repeat(auto-fit,minmax(13rem,1fr));display:grid}@media (min-width:86rem){.l-fluid-breakout .l-fluid-breakout__main{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width:1036px){.l-fluid-breakout .l-fluid-breakout__main{grid-column:auto/span 2}.l-fluid-breakout .l-fluid-breakout__main.no-aside{grid-column:2/span 2}.l-fluid-breakout .l-fluid-breakout__main.is-full-width{grid-column:1/span 3}}.l-fluid-breakout .l-fluid-breakout__main .row{max-width:100%;padding-left:0;padding-right:0}@media (min-width:86rem){.l-fluid-breakout .l-fluid-breakout__item{width:initial;grid-column:auto}}.l-fluid-breakout .l-fluid-breakout__aside--right,.l-fluid-breakout .l-fluid-breakout__aside{grid-area:2/auto/100/span 1}@media (min-width:86rem){.l-fluid-breakout .l-fluid-breakout__aside--right,.l-fluid-breakout .l-fluid-breakout__aside{align-items:start}}@media (min-width:1036px){.l-fluid-breakout .l-fluid-breakout__aside{padding-right:1.5rem}}@media (min-width:86rem){.l-fluid-breakout .l-fluid-breakout__aside{padding-left:1.5rem;padding-right:0}}@media (min-width:1036px){.l-fluid-breakout .l-fluid-breakout__aside--right{padding-left:1.5rem;padding-right:0}}@media (min-width:86rem){.l-fluid-breakout .l-fluid-breakout__aside--right{padding-left:0;padding-right:1.5rem}}.l-fluid-breakout .l-fluid-breakout__toolbar{margin-block-end:1rem}@media (min-width:1036px){.l-fluid-breakout .l-fluid-breakout__toolbar{max-width:100rem;grid-column:1/-1;grid-template-rows:auto;grid-template-columns:minmax(14rem,1fr) minmax(0,72rem) minmax(14rem,1fr);margin-left:auto;margin-right:auto;display:grid}}@media (min-width:86rem){.l-fluid-breakout .l-fluid-breakout__toolbar{margin-left:1.5rem;margin-right:1.5rem}}.l-fluid-breakout .l-fluid-breakout__toolbar-items{grid-column:2/-1;grid-template-columns:repeat(2,minmax(0,1fr));display:grid}@media (max-width:619px){.l-fluid-breakout .l-fluid-breakout__toolbar-items{width:13rem;grid-template-columns:repeat(1,minmax(0,1fr))}}.l-fluid-breakout .l-fluid-breakout__toolbar-item{grid-column-end:span 1;align-items:center;display:flex}.l-fluid-breakout .l-fluid-breakout__toolbar-item:nth-child(2){justify-content:flex-end}@media (max-width:619px){.l-fluid-breakout .l-fluid-breakout__toolbar-item:nth-child(2){justify-content:flex-start}}.u-align--center{text-align:center!important;justify-content:center!important}.u-align--left{text-align:left!important;justify-content:flex-start!important}.u-align--right{text-align:right!important;justify-content:flex-end!important}.u-align--bottom{margin-top:auto!important}.u-align-text--center{text-align:center!important;margin-left:auto!important;margin-right:auto!important}.u-align-text--left{text-align:left!important;margin-right:auto!important}.u-align-text--right{text-align:right!important;margin-left:auto!important}.u-align-text--small-to-default{padding-top:.55rem}.u-align-text--x-small-to-default{padding-top:.75rem}@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}.u-animation--spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(360deg)}}.u-baseline-grid{position:relative}.u-baseline-grid:after{content:"";pointer-events:none;z-index:200;background:linear-gradient(0deg,#ff000026,#ff000026 1px,#0000 1px,#0000) 0 0/100% .5rem;display:block;position:absolute;inset:0}html.u-baseline-grid{background-color:#ff00000d;position:static}html.u-baseline-grid:after{z-index:-1}.u-baseline-grid__toggle{z-index:201;position:fixed;bottom:1.5rem;right:1.5rem}.u-embedded-media{height:0;max-width:100%;margin-top:.5rem;margin-bottom:1.5rem;padding-bottom:56.25%;position:relative;overflow:hidden}.u-embedded-media__element{height:100%;width:100%;position:absolute;top:0;left:0}@media (min-width:1036px){.u-equal-height{display:flex}.u-equal-height.row{display:grid}}.u-float-right{float:right!important}@media (max-width:619px){.u-float-right--small{float:right!important}}@media (min-width:620px) and (max-width:1035px){.u-float-right--medium{float:right!important}}@media (min-width:1036px){.u-float-right--large{float:right!important}}.u-float-left{float:left!important}@media (max-width:619px){.u-float-left--small{float:left!important}}@media (min-width:620px) and (max-width:1035px){.u-float-left--medium{float:left!important}}@media (min-width:1036px){.u-float-left--large{float:left!important}.u-image-position{position:relative;overflow:hidden}.u-image-position .u-image-position--right,.u-image-position .u-image-position--left,.u-image-position .u-image-position--bottom,.u-image-position .u-image-position--top{margin:0;position:absolute}.u-image-position [class*=col-]{position:static}.u-image-position--top{top:0}.u-image-position--bottom{bottom:0}.u-image-position--left{left:0}.u-image-position--right{right:0}}.u-fixed-width .u-fixed-width,.row .u-fixed-width{margin-left:0;margin-right:0;padding-left:0;padding-right:0}.u-table-layout--auto{table-layout:auto!important}.u-no-margin{margin:0!important}.u-no-margin--top{margin-top:0!important}.u-no-margin--right{margin-right:0!important}.u-no-margin--left{margin-left:0!important}.u-table-cell-padding-overlap{margin-top:calc(-.5rem - 1px)!important;margin-bottom:-.5rem!important}.u-no-max-width{max-width:unset!important}.u-off-screen{height:1px!important;width:1px!important;position:absolute!important;top:auto!important;left:-10000px!important;overflow:hidden!important}.u-no-padding{padding:0!important}.u-no-padding--top{padding-top:0!important}.u-no-padding--right{padding-right:0!important}.u-no-padding--bottom{padding-bottom:0!important}.u-no-padding--left{padding-left:0!important}.u-truncate{text-overflow:ellipsis!important;white-space:nowrap!important;overflow:hidden!important}.u-sv3:after,.u-sv2:after,.u-sv1:after,.u-sv-1:after,.u-sv-2:after,.u-sv-3:after{content:"";height:1px;display:block;position:relative}.u-sv-3:after{margin-top:calc(-1.5rem - 1px)}.u-sv-2:after{margin-top:calc(-1rem - 1px)}.u-sv-1:after{margin-top:calc(-.5rem - 1px)}.u-sv1:after{margin-top:calc(.5rem - 1px)}.u-sv2:after{margin-top:calc(1rem - 1px)}.u-sv3:after{margin-top:calc(1.5rem - 1px)}.u-vertically-center{align-items:center!important;display:grid!important}.u-vertically-center>img{align-self:center!important}.u-hide{display:none!important}@media (max-width:619px){.u-hide--small{display:none!important}}@media (min-width:620px) and (max-width:1035px){.u-hide--medium{display:none!important}}@media (min-width:1036px){.u-hide--large{display:none!important}}td.u-hide,th.u-hide{opacity:0!important;white-space:nowrap!important;width:0!important;padding:0!important;display:table-cell!important;overflow:hidden!important}@media (max-width:619px){td.u-hide--small,th.u-hide--small{opacity:0!important;white-space:nowrap!important;width:0!important;padding:0!important;display:table-cell!important;overflow:hidden!important}}@media (min-width:620px) and (max-width:1035px){td.u-hide--medium,th.u-hide--medium{opacity:0!important;white-space:nowrap!important;width:0!important;padding:0!important;display:table-cell!important;overflow:hidden!important}}@media (min-width:620px){td.u-hide--large,th.u-hide--large{opacity:0!important;white-space:nowrap!important;width:0!important;padding:0!important;display:table-cell!important;overflow:hidden!important}}.p-table--expanding .u-hide{display:none!important}@media (max-width:619px){.p-table--expanding .u-hide--small{display:none!important}}@media (min-width:620px) and (max-width:1035px){.p-table--expanding .u-hide--medium{display:none!important}}@media (min-width:1036px){.p-table--expanding .u-hide--large{display:none!important}}.u-show{display:initial!important}@media (max-width:619px){.u-show--small{display:inherit!important;display:initial!important}}@media (min-width:620px) and (max-width:1035px){.u-show--medium{display:inherit!important;display:initial!important}}@media (min-width:1036px){.u-show--large{display:inherit!important;display:initial!important}}.u-visualise-font-metrics{position:relative}.u-visualise-font-metrics:before{content:"";height:.176em;width:calc(4rem + 100%);border-width:1px;border-top-style:solid;border-top-color:#0e842080;border-bottom-style:solid;border-bottom-color:#24598f80;position:absolute;top:calc(.239em - 1px);left:-2rem}.u-visualise-font-metrics:after{content:"";height:1px;width:calc(4rem + 100%);background-color:#c7162b80;position:absolute;top:calc(.932em - 1px);left:-2rem}@media print{.u-no-print{display:none!important}}
2−/*# sourceMappingURL=build.css.map */
appname.apparmor → warden.apparmorrenamed+1−1
@@ -5,5 +5,5 @@
5 "audio",
5 "audio",
6 "networking"
6 "networking"
7 ],
7 ],
8− "policy_version": 16.04
8+ "policy_version": 20.04
9}
9}
appname.desktop → warden.desktoprenamed+3−3
@@ -1,7 +1,7 @@
1[Desktop Entry]
1[Desktop Entry]
2−Name=App Title
2+Name=Warden
3−Exec=webapp-container --local-content-can-access-remote-urls --app-id="appname.iko" $@ index.html
3+Exec=webapp-container --local-content-can-access-remote-urls --app-id="soy.iko.warden" $@ index.html
4−Icon=logo.svg
4+Icon=logo.png
5Terminal=false
5Terminal=false
6Type=Application
6Type=Application
7X-Ubuntu-Touch=true
7X-Ubuntu-Touch=true