diff --git a/app/main.656f1dffa218e8467958.css b/app/main.656f1dffa218e8467958.css new file mode 100644 index 00000000..b4bc4541 --- /dev/null +++ b/app/main.656f1dffa218e8467958.css @@ -0,0 +1,98 @@ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 300; + font-display: auto; + src: url(../fonts/Open_Sans-italic-300.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 400; + font-display: auto; + src: url(../fonts/Open_Sans-italic-400.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 600; + font-display: auto; + src: url(../fonts/Open_Sans-italic-600.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 700; + font-display: auto; + src: url(../fonts/Open_Sans-italic-700.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 800; + font-display: auto; + src: url(../fonts/Open_Sans-italic-800.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 300; + font-display: auto; + src: url(../fonts/Open_Sans-normal-300.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + font-display: auto; + src: url(../fonts/Open_Sans-normal-400.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 600; + font-display: auto; + src: url(../fonts/Open_Sans-normal-600.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + font-display: auto; + src: url(../fonts/Open_Sans-normal-700.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 800; + font-display: auto; + src: url(../fonts/Open_Sans-normal-800.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + + +:root{--blue: #007bff;--indigo: #6610f2;--purple: #6f42c1;--pink: #e83e8c;--red: #dc3545;--orange: #fd7e14;--yellow: #ffc107;--green: #28a745;--teal: #20c997;--cyan: #17a2b8;--white: #FFFFFF;--gray: #6c757d;--gray-dark: #343a40;--primary: #175DDC;--secondary: #CED4DA;--success: #00A65A;--info: #555555;--warning: #BF7E16;--danger: #DD4B39;--light: #f8f9fa;--dark: #343a40;--primary-accent: #1252A3;--secondary-alt: #1A3B66;--breakpoint-xs: 0;--breakpoint-sm: 1px;--breakpoint-md: 2px;--breakpoint-lg: 3px;--breakpoint-xl: 4px;--font-family-sans-serif: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}*,*::before,*::after{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#333;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0 !important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-original-title]{text-decoration:underline;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}a{color:#175ddc;text-decoration:none;background-color:transparent}a:hover{color:#104097;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button:not(:disabled),[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled){cursor:pointer}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{padding:0;border-style:none}input[type=radio],input[type=checkbox]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none !important}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}h1,.h1{font-size:1.7rem}h2,.h2{font-size:1.3rem}h3,.h3{font-size:1rem}h4,.h4{font-size:1rem}h5,.h5{font-size:1rem}h6,.h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:normal}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}small,.small{font-size:90%;font-weight:400}mark,.mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:90%;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid,.table td.table-list-icon img{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:100%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:100%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:100%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-xl,.container-lg,.container-md,.container-sm{width:100%;padding-right:10px;padding-left:10px;margin-right:auto;margin-left:auto}@media(min-width: 1px){.container-sm,.container{max-width:540px}}@media(min-width: 2px){.container-md,.container-sm,.container{max-width:720px}}@media(min-width: 3px){.container-lg,.container-md,.container-sm,.container{max-width:960px}}@media(min-width: 4px){.container-xl,.container-lg,.container-md,.container-sm,.container{max-width:1140px}}.row{display:flex;flex-wrap:wrap;margin-right:-10px;margin-left:-10px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col-xl,.col-xl-auto,.col-xl-12,.col-xl-11,.col-xl-10,.col-xl-9,.col-xl-8,.col-xl-7,.col-xl-6,.col-xl-5,.col-xl-4,.col-xl-3,.col-xl-2,.col-xl-1,.col-lg,.col-lg-auto,.col-lg-12,.col-lg-11,.col-lg-10,.col-lg-9,.col-lg-8,.col-lg-7,.col-lg-6,.col-lg-5,.col-lg-4,.col-lg-3,.col-lg-2,.col-lg-1,.col-md,.col-md-auto,.col-md-12,.col-md-11,.col-md-10,.col-md-9,.col-md-8,.col-md-7,.col-md-6,.col-md-5,.col-md-4,.col-md-3,.col-md-2,.col-md-1,.col-sm,.col-sm-auto,.col-sm-12,.col-sm-11,.col-sm-10,.col-sm-9,.col-sm-8,.col-sm-7,.col-sm-6,.col-sm-5,.col-sm-4,.col-sm-3,.col-sm-2,.col-sm-1,.col,.col-auto,.col-12,.col-11,.col-10,.col-9,.col-8,.col-7,.col-6,.col-5,.col-4,.col-3,.col-2,.col-1{position:relative;width:100%;padding-right:10px;padding-left:10px}.col{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}@media(min-width: 1px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-sm-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-sm-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-sm-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-sm-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}}@media(min-width: 2px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-md-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-md-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-md-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-md-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}}@media(min-width: 3px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-lg-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-lg-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-lg-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-lg-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}}@media(min-width: 4px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-xl-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-xl-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-xl-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-xl-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}}.table{width:100%;margin-bottom:1rem;color:#333}.table th,.table td{padding:.75rem;vertical-align:top;border-top:1px solid #ced4da}.table thead th{vertical-align:bottom;border-bottom:2px solid #ced4da}.table tbody+tbody{border-top:2px solid #ced4da}.table-sm th,.table-sm td{padding:.3rem}.table-bordered{border:1px solid #ced4da}.table-bordered th,.table-bordered td{border:1px solid #ced4da}.table-bordered thead th,.table-bordered thead td{border-bottom-width:2px}.table-borderless th,.table-borderless td,.table-borderless thead th,.table-borderless tbody+tbody{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.02)}.table-hover tbody tr:hover{color:#333;background-color:rgba(0,0,0,.03)}.table-primary,.table-primary>th,.table-primary>td{background-color:#bed2f5}.table-primary th,.table-primary td,.table-primary thead th,.table-primary tbody+tbody{border-color:#86abed}.table-hover .table-primary:hover{background-color:#a8c3f2}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#a8c3f2}.table-secondary,.table-secondary>th,.table-secondary>td{background-color:#f1f3f5}.table-secondary th,.table-secondary td,.table-secondary thead th,.table-secondary tbody+tbody{border-color:#e6e9ec}.table-hover .table-secondary:hover{background-color:#e2e6ea}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#e2e6ea}.table-success,.table-success>th,.table-success>td{background-color:#b8e6d1}.table-success th,.table-success td,.table-success thead th,.table-success tbody+tbody{border-color:#7ad1a9}.table-hover .table-success:hover{background-color:#a5dfc5}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#a5dfc5}.table-info,.table-info>th,.table-info>td{background-color:#cfcfcf}.table-info th,.table-info td,.table-info thead th,.table-info tbody+tbody{border-color:#a7a7a7}.table-hover .table-info:hover{background-color:#c2c2c2}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#c2c2c2}.table-warning,.table-warning>th,.table-warning>td{background-color:#eddbbe}.table-warning th,.table-warning td,.table-warning thead th,.table-warning tbody+tbody{border-color:#debc86}.table-hover .table-warning:hover{background-color:#e7d0aa}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#e7d0aa}.table-danger,.table-danger>th,.table-danger>td{background-color:#f5cdc8}.table-danger th,.table-danger td,.table-danger thead th,.table-danger tbody+tbody{border-color:#eda198}.table-hover .table-danger:hover{background-color:#f1b9b2}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b9b2}.table-light,.table-light>th,.table-light>td{background-color:#fdfdfe}.table-light th,.table-light td,.table-light thead th,.table-light tbody+tbody{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>th,.table-dark>td{background-color:#c6c8ca}.table-dark th,.table-dark td,.table-dark thead th,.table-dark tbody+tbody{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-primary-accent,.table-primary-accent>th,.table-primary-accent>td{background-color:#bdcfe5}.table-primary-accent th,.table-primary-accent td,.table-primary-accent thead th,.table-primary-accent tbody+tbody{border-color:#84a5cf}.table-hover .table-primary-accent:hover{background-color:#abc2de}.table-hover .table-primary-accent:hover>td,.table-hover .table-primary-accent:hover>th{background-color:#abc2de}.table-secondary-alt,.table-secondary-alt>th,.table-secondary-alt>td{background-color:#bfc8d4}.table-secondary-alt th,.table-secondary-alt td,.table-secondary-alt thead th,.table-secondary-alt tbody+tbody{border-color:#8899af}.table-hover .table-secondary-alt:hover{background-color:#b0bbca}.table-hover .table-secondary-alt:hover>td,.table-hover .table-secondary-alt:hover>th{background-color:#b0bbca}.table-active,.table-active>th,.table-active>td{background-color:rgba(0,0,0,.03)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.03)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.03)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#ced4da}.table-dark{color:#fff;background-color:#343a40}.table-dark th,.table-dark td,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media(max-width: 0.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media(max-width: 1.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media(max-width: 2.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media(max-width: 3.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + 0.75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fbfbfb;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#81a9f2;outline:0;box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}.form-control::placeholder{color:#b4b4b4;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e0e0e0;opacity:1}input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fbfbfb}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(0.375rem + 1px);padding-bottom:calc(0.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(0.5rem + 1px);padding-bottom:calc(0.5rem + 1px);font-size:1.15rem;line-height:1.5}.col-form-label-sm{padding-top:calc(0.25rem + 1px);padding-bottom:calc(0.25rem + 1px);font-size:0.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#333;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + 0.5rem + 2px);padding:.25rem .5rem;font-size:0.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.15rem;line-height:1.5;border-radius:.3rem}select.form-control[size],select.form-control[multiple]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input[disabled]~.form-check-label,.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:90%;color:#00a65a}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;line-height:1.5;color:#fff;background-color:rgba(0,166,90,.9);border-radius:.25rem}.form-row>.col>.valid-tooltip,.form-row>[class*=col-]>.valid-tooltip{left:5px}.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip,.is-valid~.valid-feedback,.is-valid~.valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#00a65a;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2300A65A' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#00a65a;box-shadow:0 0 0 .2rem rgba(0,166,90,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .custom-select:valid,.custom-select.is-valid{border-color:#00a65a;padding-right:calc(0.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fbfbfb url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2300A65A' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat}.was-validated .custom-select:valid:focus,.custom-select.is-valid:focus{border-color:#00a65a;box-shadow:0 0 0 .2rem rgba(0,166,90,.25)}.was-validated .form-check-input:valid~.form-check-label,.form-check-input.is-valid~.form-check-label{color:#00a65a}.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip,.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip{display:block}.was-validated .custom-control-input:valid~.custom-control-label,.custom-control-input.is-valid~.custom-control-label{color:#00a65a}.was-validated .custom-control-input:valid~.custom-control-label::before,.custom-control-input.is-valid~.custom-control-label::before{border-color:#00a65a}.was-validated .custom-control-input:valid:checked~.custom-control-label::before,.custom-control-input.is-valid:checked~.custom-control-label::before{border-color:#00d976;background-color:#00d976}.was-validated .custom-control-input:valid:focus~.custom-control-label::before,.custom-control-input.is-valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,166,90,.25)}.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before,.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before{border-color:#00a65a}.was-validated .custom-file-input:valid~.custom-file-label,.custom-file-input.is-valid~.custom-file-label{border-color:#00a65a}.was-validated .custom-file-input:valid:focus~.custom-file-label,.custom-file-input.is-valid:focus~.custom-file-label{border-color:#00a65a;box-shadow:0 0 0 .2rem rgba(0,166,90,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:90%;color:#dd4b39}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;line-height:1.5;color:#fff;background-color:rgba(221,75,57,.9);border-radius:.25rem}.form-row>.col>.invalid-tooltip,.form-row>[class*=col-]>.invalid-tooltip{left:5px}.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip,.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#dd4b39;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23DD4B39' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23DD4B39' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#dd4b39;box-shadow:0 0 0 .2rem rgba(221,75,57,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .custom-select:invalid,.custom-select.is-invalid{border-color:#dd4b39;padding-right:calc(0.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fbfbfb url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23DD4B39' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23DD4B39' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat}.was-validated .custom-select:invalid:focus,.custom-select.is-invalid:focus{border-color:#dd4b39;box-shadow:0 0 0 .2rem rgba(221,75,57,.25)}.was-validated .form-check-input:invalid~.form-check-label,.form-check-input.is-invalid~.form-check-label{color:#dd4b39}.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip,.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip{display:block}.was-validated .custom-control-input:invalid~.custom-control-label,.custom-control-input.is-invalid~.custom-control-label{color:#dd4b39}.was-validated .custom-control-input:invalid~.custom-control-label::before,.custom-control-input.is-invalid~.custom-control-label::before{border-color:#dd4b39}.was-validated .custom-control-input:invalid:checked~.custom-control-label::before,.custom-control-input.is-invalid:checked~.custom-control-label::before{border-color:#e47365;background-color:#e47365}.was-validated .custom-control-input:invalid:focus~.custom-control-label::before,.custom-control-input.is-invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(221,75,57,.25)}.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before,.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dd4b39}.was-validated .custom-file-input:invalid~.custom-file-label,.custom-file-input.is-invalid~.custom-file-label{border-color:#dd4b39}.was-validated .custom-file-input:invalid:focus~.custom-file-label,.custom-file-input.is-invalid:focus~.custom-file-label{border-color:#dd4b39;box-shadow:0 0 0 .2rem rgba(221,75,57,.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media(min-width: 1px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn,.swal2-popup .swal2-actions button{display:inline-block;font-weight:600;color:#333;text-align:center;vertical-align:middle;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.btn,.swal2-popup .swal2-actions button{transition:none}}.btn:hover,.swal2-popup .swal2-actions button:hover{color:#333;text-decoration:none}.btn:focus,.swal2-popup .swal2-actions button:focus,.btn.focus,.swal2-popup .swal2-actions button.focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}.btn.disabled,.swal2-popup .swal2-actions button.disabled,.btn:disabled,.swal2-popup .swal2-actions button:disabled{opacity:.65}.btn:not(:disabled):not(.disabled),.swal2-popup .swal2-actions button:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#175ddc;border-color:#175ddc}.btn-primary:hover{color:#fff;background-color:#134eb9;border-color:#1249ae}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#134eb9;border-color:#1249ae;box-shadow:0 0 0 .2rem rgba(58,117,225,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#175ddc;border-color:#175ddc}.btn-primary:not(:disabled):not(.disabled):active,.btn-primary:not(:disabled):not(.disabled).active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#1249ae;border-color:#1145a2}.btn-primary:not(:disabled):not(.disabled):active:focus,.btn-primary:not(:disabled):not(.disabled).active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,117,225,.5)}.btn-secondary{color:#212529;background-color:#ced4da;border-color:#ced4da}.btn-secondary:hover{color:#212529;background-color:#b8c1ca;border-color:#b1bbc4}.btn-secondary:focus,.btn-secondary.focus{color:#212529;background-color:#b8c1ca;border-color:#b1bbc4;box-shadow:0 0 0 .2rem rgba(180,186,191,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#212529;background-color:#ced4da;border-color:#ced4da}.btn-secondary:not(:disabled):not(.disabled):active,.btn-secondary:not(:disabled):not(.disabled).active,.show>.btn-secondary.dropdown-toggle{color:#212529;background-color:#b1bbc4;border-color:#aab4bf}.btn-secondary:not(:disabled):not(.disabled):active:focus,.btn-secondary:not(:disabled):not(.disabled).active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(180,186,191,.5)}.btn-success{color:#fff;background-color:#00a65a;border-color:#00a65a}.btn-success:hover{color:#fff;background-color:#008045;border-color:#00733e}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#008045;border-color:#00733e;box-shadow:0 0 0 .2rem rgba(38,179,115,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#00a65a;border-color:#00a65a}.btn-success:not(:disabled):not(.disabled):active,.btn-success:not(:disabled):not(.disabled).active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#00733e;border-color:#006637}.btn-success:not(:disabled):not(.disabled):active:focus,.btn-success:not(:disabled):not(.disabled).active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,179,115,.5)}.btn-info{color:#fff;background-color:#555;border-color:#555}.btn-info:hover{color:#fff;background-color:#424242;border-color:#3c3c3c}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#424242;border-color:#3c3c3c;box-shadow:0 0 0 .2rem rgba(111,111,111,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#555;border-color:#555}.btn-info:not(:disabled):not(.disabled):active,.btn-info:not(:disabled):not(.disabled).active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#3c3c3c;border-color:#353535}.btn-info:not(:disabled):not(.disabled):active:focus,.btn-info:not(:disabled):not(.disabled).active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(111,111,111,.5)}.btn-warning{color:#fff;background-color:#bf7e16;border-color:#bf7e16}.btn-warning:hover{color:#fff;background-color:#9d6712;border-color:#916011}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#9d6712;border-color:#916011;box-shadow:0 0 0 .2rem rgba(201,145,57,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#fff;background-color:#bf7e16;border-color:#bf7e16}.btn-warning:not(:disabled):not(.disabled):active,.btn-warning:not(:disabled):not(.disabled).active,.show>.btn-warning.dropdown-toggle{color:#fff;background-color:#916011;border-color:#86580f}.btn-warning:not(:disabled):not(.disabled):active:focus,.btn-warning:not(:disabled):not(.disabled).active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(201,145,57,.5)}.btn-danger{color:#fff;background-color:#dd4b39;border-color:#dd4b39}.btn-danger:hover{color:#fff;background-color:#cd3623;border-color:#c23321}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#cd3623;border-color:#c23321;box-shadow:0 0 0 .2rem rgba(226,102,87,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dd4b39;border-color:#dd4b39}.btn-danger:not(:disabled):not(.disabled):active,.btn-danger:not(:disabled):not(.disabled).active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#c23321;border-color:#b7301f}.btn-danger:not(:disabled):not(.disabled):active:focus,.btn-danger:not(:disabled):not(.disabled).active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(226,102,87,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light:focus,.btn-light.focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled):active,.btn-light:not(:disabled):not(.disabled).active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled):active:focus,.btn-light:not(:disabled):not(.disabled).active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark:focus,.btn-dark.focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled):active,.btn-dark:not(:disabled):not(.disabled).active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled):active:focus,.btn-dark:not(:disabled):not(.disabled).active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-primary-accent{color:#fff;background-color:#1252a3;border-color:#1252a3}.btn-primary-accent:hover{color:#fff;background-color:#0e4181;border-color:#0d3b75}.btn-primary-accent:focus,.btn-primary-accent.focus{color:#fff;background-color:#0e4181;border-color:#0d3b75;box-shadow:0 0 0 .2rem rgba(54,108,177,.5)}.btn-primary-accent.disabled,.btn-primary-accent:disabled{color:#fff;background-color:#1252a3;border-color:#1252a3}.btn-primary-accent:not(:disabled):not(.disabled):active,.btn-primary-accent:not(:disabled):not(.disabled).active,.show>.btn-primary-accent.dropdown-toggle{color:#fff;background-color:#0d3b75;border-color:#0c356a}.btn-primary-accent:not(:disabled):not(.disabled):active:focus,.btn-primary-accent:not(:disabled):not(.disabled).active:focus,.show>.btn-primary-accent.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(54,108,177,.5)}.btn-secondary-alt{color:#fff;background-color:#1a3b66;border-color:#1a3b66}.btn-secondary-alt:hover{color:#fff;background-color:#122948;border-color:#10233d}.btn-secondary-alt:focus,.btn-secondary-alt.focus{color:#fff;background-color:#122948;border-color:#10233d;box-shadow:0 0 0 .2rem rgba(60,88,125,.5)}.btn-secondary-alt.disabled,.btn-secondary-alt:disabled{color:#fff;background-color:#1a3b66;border-color:#1a3b66}.btn-secondary-alt:not(:disabled):not(.disabled):active,.btn-secondary-alt:not(:disabled):not(.disabled).active,.show>.btn-secondary-alt.dropdown-toggle{color:#fff;background-color:#10233d;border-color:#0d1e33}.btn-secondary-alt:not(:disabled):not(.disabled):active:focus,.btn-secondary-alt:not(:disabled):not(.disabled).active:focus,.show>.btn-secondary-alt.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(60,88,125,.5)}.btn-outline-primary{color:#175ddc;border-color:#175ddc}.btn-outline-primary:hover{color:#fff;background-color:#175ddc;border-color:#175ddc}.btn-outline-primary:focus,.btn-outline-primary.focus{box-shadow:0 0 0 .2rem rgba(23,93,220,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#175ddc;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled):active,.btn-outline-primary:not(:disabled):not(.disabled).active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#175ddc;border-color:#175ddc}.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,93,220,.5)}.btn-outline-secondary{color:#ced4da;border-color:#ced4da}.btn-outline-secondary:hover{color:#212529;background-color:#ced4da;border-color:#ced4da}.btn-outline-secondary:focus,.btn-outline-secondary.focus{box-shadow:0 0 0 .2rem rgba(206,212,218,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#ced4da;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled):active,.btn-outline-secondary:not(:disabled):not(.disabled).active,.show>.btn-outline-secondary.dropdown-toggle{color:#212529;background-color:#ced4da;border-color:#ced4da}.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(206,212,218,.5)}.btn-outline-success{color:#00a65a;border-color:#00a65a}.btn-outline-success:hover{color:#fff;background-color:#00a65a;border-color:#00a65a}.btn-outline-success:focus,.btn-outline-success.focus{box-shadow:0 0 0 .2rem rgba(0,166,90,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#00a65a;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled):active,.btn-outline-success:not(:disabled):not(.disabled).active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#00a65a;border-color:#00a65a}.btn-outline-success:not(:disabled):not(.disabled):active:focus,.btn-outline-success:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,166,90,.5)}.btn-outline-info{color:#555;border-color:#555}.btn-outline-info:hover{color:#fff;background-color:#555;border-color:#555}.btn-outline-info:focus,.btn-outline-info.focus{box-shadow:0 0 0 .2rem rgba(85,85,85,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#555;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled):active,.btn-outline-info:not(:disabled):not(.disabled).active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#555;border-color:#555}.btn-outline-info:not(:disabled):not(.disabled):active:focus,.btn-outline-info:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(85,85,85,.5)}.btn-outline-warning{color:#bf7e16;border-color:#bf7e16}.btn-outline-warning:hover{color:#fff;background-color:#bf7e16;border-color:#bf7e16}.btn-outline-warning:focus,.btn-outline-warning.focus{box-shadow:0 0 0 .2rem rgba(191,126,22,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#bf7e16;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled):active,.btn-outline-warning:not(:disabled):not(.disabled).active,.show>.btn-outline-warning.dropdown-toggle{color:#fff;background-color:#bf7e16;border-color:#bf7e16}.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(191,126,22,.5)}.btn-outline-danger{color:#dd4b39;border-color:#dd4b39}.btn-outline-danger:hover{color:#fff;background-color:#dd4b39;border-color:#dd4b39}.btn-outline-danger:focus,.btn-outline-danger.focus{box-shadow:0 0 0 .2rem rgba(221,75,57,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dd4b39;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled):active,.btn-outline-danger:not(:disabled):not(.disabled).active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dd4b39;border-color:#dd4b39}.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(221,75,57,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:focus,.btn-outline-light.focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled):active,.btn-outline-light:not(:disabled):not(.disabled).active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled):active:focus,.btn-outline-light:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:focus,.btn-outline-dark.focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled):active,.btn-outline-dark:not(:disabled):not(.disabled).active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-primary-accent{color:#1252a3;border-color:#1252a3}.btn-outline-primary-accent:hover{color:#fff;background-color:#1252a3;border-color:#1252a3}.btn-outline-primary-accent:focus,.btn-outline-primary-accent.focus{box-shadow:0 0 0 .2rem rgba(18,82,163,.5)}.btn-outline-primary-accent.disabled,.btn-outline-primary-accent:disabled{color:#1252a3;background-color:transparent}.btn-outline-primary-accent:not(:disabled):not(.disabled):active,.btn-outline-primary-accent:not(:disabled):not(.disabled).active,.show>.btn-outline-primary-accent.dropdown-toggle{color:#fff;background-color:#1252a3;border-color:#1252a3}.btn-outline-primary-accent:not(:disabled):not(.disabled):active:focus,.btn-outline-primary-accent:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-primary-accent.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(18,82,163,.5)}.btn-outline-secondary-alt{color:#1a3b66;border-color:#1a3b66}.btn-outline-secondary-alt:hover{color:#fff;background-color:#1a3b66;border-color:#1a3b66}.btn-outline-secondary-alt:focus,.btn-outline-secondary-alt.focus{box-shadow:0 0 0 .2rem rgba(26,59,102,.5)}.btn-outline-secondary-alt.disabled,.btn-outline-secondary-alt:disabled{color:#1a3b66;background-color:transparent}.btn-outline-secondary-alt:not(:disabled):not(.disabled):active,.btn-outline-secondary-alt:not(:disabled):not(.disabled).active,.show>.btn-outline-secondary-alt.dropdown-toggle{color:#fff;background-color:#1a3b66;border-color:#1a3b66}.btn-outline-secondary-alt:not(:disabled):not(.disabled):active:focus,.btn-outline-secondary-alt:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-secondary-alt.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(26,59,102,.5)}.btn-link{font-weight:400;color:#175ddc;text-decoration:none}.btn-link:hover{color:#104097;text-decoration:underline}.btn-link:focus,.btn-link.focus{text-decoration:underline}.btn-link:disabled,.btn-link.disabled{color:#6c757d;pointer-events:none}.btn-lg,.btn-group-lg>.btn,.swal2-popup .swal2-actions .btn-group-lg>button{padding:.5rem 1rem;font-size:1.15rem;line-height:1.5;border-radius:.3rem}.btn-sm,.btn-group-sm>.btn,.swal2-popup .swal2-actions .btn-group-sm>button{padding:.25rem .5rem;font-size:0.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{transition:opacity .15s linear}@media(prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media(prefers-reduced-motion: reduce){.collapsing{transition:none}}.dropup,.dropright,.dropdown,.dropleft{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#333;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media(min-width: 1px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media(min-width: 2px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media(min-width: 3px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media(min-width: 4px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=top],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1rem;clear:both;font-weight:400;color:#333;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:hover,.dropdown-item:focus{color:#16181b;text-decoration:none;background-color:rgba(0,0,0,.06)}.dropdown-item.active,.dropdown-item:active{color:#333;text-decoration:none;background-color:rgba(0,0,0,.1)}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:0.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#333}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.swal2-popup .swal2-actions .btn-group>button,.btn-group-vertical>.btn,.swal2-popup .swal2-actions .btn-group-vertical>button{position:relative;flex:1 1 auto}.btn-group>.btn:hover,.swal2-popup .swal2-actions .btn-group>button:hover,.btn-group-vertical>.btn:hover,.swal2-popup .swal2-actions .btn-group-vertical>button:hover{z-index:1}.btn-group>.btn:focus,.swal2-popup .swal2-actions .btn-group>button:focus,.btn-group>.btn:active,.swal2-popup .swal2-actions .btn-group>button:active,.btn-group>.btn.active,.swal2-popup .swal2-actions .btn-group>button.active,.btn-group-vertical>.btn:focus,.swal2-popup .swal2-actions .btn-group-vertical>button:focus,.btn-group-vertical>.btn:active,.swal2-popup .swal2-actions .btn-group-vertical>button:active,.btn-group-vertical>.btn.active,.swal2-popup .swal2-actions .btn-group-vertical>button.active{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.swal2-popup .swal2-actions .btn-group>button:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.swal2-popup .swal2-actions .btn-group>button:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn,.swal2-popup .swal2-actions .btn-group>.btn-group:not(:last-child)>button{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:not(:first-child),.swal2-popup .swal2-actions .btn-group>button:not(:first-child),.btn-group>.btn-group:not(:first-child)>.btn,.swal2-popup .swal2-actions .btn-group>.btn-group:not(:first-child)>button{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split,.swal2-popup .swal2-actions .btn-group-sm>button+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split,.swal2-popup .swal2-actions .btn-group-lg>button+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.swal2-popup .swal2-actions .btn-group-vertical>button,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.swal2-popup .swal2-actions .btn-group-vertical>button:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.swal2-popup .swal2-actions .btn-group-vertical>button:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn,.swal2-popup .swal2-actions .btn-group-vertical>.btn-group:not(:last-child)>button{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:not(:first-child),.swal2-popup .swal2-actions .btn-group-vertical>button:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child)>.btn,.swal2-popup .swal2-actions .btn-group-vertical>.btn-group:not(:first-child)>button{border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.swal2-popup .swal2-actions .btn-group-toggle>button,.btn-group-toggle>.btn-group>.btn,.swal2-popup .swal2-actions .btn-group-toggle>.btn-group>button{margin-bottom:0}.btn-group-toggle>.btn input[type=radio],.swal2-popup .swal2-actions .btn-group-toggle>button input[type=radio],.btn-group-toggle>.btn input[type=checkbox],.swal2-popup .swal2-actions .btn-group-toggle>button input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-control-plaintext,.input-group>.custom-select,.input-group>.custom-file{position:relative;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.form-control+.form-control,.input-group>.form-control+.custom-select,.input-group>.form-control+.custom-file,.input-group>.form-control-plaintext+.form-control,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.custom-file,.input-group>.custom-select+.form-control,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.custom-file,.input-group>.custom-file+.form-control,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.custom-file{margin-left:-1px}.input-group>.form-control:focus,.input-group>.custom-select:focus,.input-group>.custom-file .custom-file-input:focus~.custom-file-label{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.form-control:not(:first-child),.input-group>.custom-select:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group:not(.has-validation)>.form-control:not(:last-child),.input-group:not(.has-validation)>.custom-select:not(:last-child),.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.form-control:nth-last-child(n+3),.input-group.has-validation>.custom-select:nth-last-child(n+3),.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-prepend,.input-group-append{display:flex}.input-group-prepend .btn,.input-group-prepend .swal2-popup .swal2-actions button,.swal2-popup .swal2-actions .input-group-prepend button,.input-group-append .btn,.input-group-append .swal2-popup .swal2-actions button,.swal2-popup .swal2-actions .input-group-append button{position:relative;z-index:2}.input-group-prepend .btn:focus,.input-group-prepend .swal2-popup .swal2-actions button:focus,.swal2-popup .swal2-actions .input-group-prepend button:focus,.input-group-append .btn:focus,.input-group-append .swal2-popup .swal2-actions button:focus,.swal2-popup .swal2-actions .input-group-append button:focus{z-index:3}.input-group-prepend .btn+.btn,.input-group-prepend .swal2-popup .swal2-actions button+.btn,.swal2-popup .swal2-actions .input-group-prepend button+.btn,.input-group-prepend .swal2-popup .swal2-actions .btn+button,.swal2-popup .swal2-actions .input-group-prepend .btn+button,.input-group-prepend .swal2-popup .swal2-actions button+button,.swal2-popup .swal2-actions .input-group-prepend button+button,.input-group-prepend .btn+.input-group-text,.input-group-prepend .swal2-popup .swal2-actions button+.input-group-text,.swal2-popup .swal2-actions .input-group-prepend button+.input-group-text,.input-group-prepend .input-group-text+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .swal2-popup .swal2-actions .input-group-text+button,.swal2-popup .swal2-actions .input-group-prepend .input-group-text+button,.input-group-append .btn+.btn,.input-group-append .swal2-popup .swal2-actions button+.btn,.swal2-popup .swal2-actions .input-group-append button+.btn,.input-group-append .swal2-popup .swal2-actions .btn+button,.swal2-popup .swal2-actions .input-group-append .btn+button,.input-group-append .swal2-popup .swal2-actions button+button,.swal2-popup .swal2-actions .input-group-append button+button,.input-group-append .btn+.input-group-text,.input-group-append .swal2-popup .swal2-actions button+.input-group-text,.swal2-popup .swal2-actions .input-group-append button+.input-group-text,.input-group-append .input-group-text+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .swal2-popup .swal2-actions .input-group-text+button,.swal2-popup .swal2-actions .input-group-append .input-group-text+button{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=radio],.input-group-text input[type=checkbox]{margin-top:0}.input-group-lg>.form-control:not(textarea),.input-group-lg>.custom-select{height:calc(1.5em + 1rem + 2px)}.input-group-lg>.form-control,.input-group-lg>.custom-select,.input-group-lg>.input-group-prepend>.input-group-text,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.swal2-popup .swal2-actions .input-group-lg>.input-group-prepend>button,.input-group-lg>.input-group-append>.btn,.swal2-popup .swal2-actions .input-group-lg>.input-group-append>button{padding:.5rem 1rem;font-size:1.15rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.form-control:not(textarea),.input-group-sm>.custom-select{height:calc(1.5em + 0.5rem + 2px)}.input-group-sm>.form-control,.input-group-sm>.custom-select,.input-group-sm>.input-group-prepend>.input-group-text,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.swal2-popup .swal2-actions .input-group-sm>.input-group-prepend>button,.input-group-sm>.input-group-append>.btn,.swal2-popup .swal2-actions .input-group-sm>.input-group-append>button{padding:.25rem .5rem;font-size:0.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-prepend>.btn,.swal2-popup .swal2-actions .input-group>.input-group-prepend>button,.input-group>.input-group-prepend>.input-group-text,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.swal2-popup .swal2-actions .input-group:not(.has-validation)>.input-group-append:not(:last-child)>button,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.swal2-popup .swal2-actions .input-group.has-validation>.input-group-append:nth-last-child(n+3)>button,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.swal2-popup .swal2-actions .input-group>.input-group-append:last-child>button:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.swal2-popup .swal2-actions .input-group>.input-group-append>button,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:not(:first-child)>.btn,.swal2-popup .swal2-actions .input-group>.input-group-prepend:not(:first-child)>button,.input-group>.input-group-prepend:not(:first-child)>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.swal2-popup .swal2-actions .input-group>.input-group-prepend:first-child>button:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;color-adjust:exact}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#175ddc;background-color:#175ddc}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#81a9f2}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#afc8f7;border-color:#afc8f7}.custom-control-input[disabled]~.custom-control-label,.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input[disabled]~.custom-control-label::before,.custom-control-input:disabled~.custom-control-label::before{background-color:#e0e0e0}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fbfbfb;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:50%/50% 50% no-repeat}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23FFFFFF' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#175ddc;background-color:#175ddc}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23FFFFFF' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(23,93,220,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(23,93,220,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23FFFFFF'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(23,93,220,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(0.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fbfbfb;transform:translateX(0.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(23,93,220,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + 0.75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fbfbfb url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;appearance:none}.custom-select:focus{border-color:#81a9f2;outline:0;box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fbfbfb}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + 0.5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:0.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.15rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + 0.75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + 0.75rem + 2px);margin:0;overflow:hidden;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#81a9f2;box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}.custom-file-input[disabled]~.custom-file-label,.custom-file-input:disabled~.custom-file-label{background-color:#e0e0e0}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + 0.75rem + 2px);padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;background-color:#fbfbfb;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + 0.75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(23,93,220,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(23,93,220,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(23,93,220,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-0.25rem;background-color:#175ddc;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media(prefers-reduced-motion: reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#afc8f7}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#175ddc;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media(prefers-reduced-motion: reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#afc8f7}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#175ddc;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media(prefers-reduced-motion: reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#afc8f7}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:hover,.nav-link:focus{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#175ddc}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:.75rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-sm,.navbar .container-md,.navbar .container-lg,.navbar .container-xl{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:0;padding-bottom:0;margin-right:1rem;font-size:2.1875rem;line-height:inherit;white-space:nowrap}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.15rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:hover,.navbar-toggler:focus{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:50%/100% 100% no-repeat}.navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media(max-width: 0.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media(min-width: 1px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.8rem;padding-left:.8rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-xl{flex-wrap:nowrap}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media(max-width: 1.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-md,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media(min-width: 2px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.8rem;padding-left:.8rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-md,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-xl{flex-wrap:nowrap}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media(max-width: 2.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media(min-width: 3px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.8rem;padding-left:.8rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-xl{flex-wrap:nowrap}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media(max-width: 3.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media(min-width: 4px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.8rem;padding-left:.8rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-xl{flex-wrap:nowrap}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-sm,.navbar-expand>.container-md,.navbar-expand>.container-lg,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.8rem;padding-left:.8rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-sm,.navbar-expand>.container-md,.navbar-expand>.container-lg,.navbar-expand>.container-xl{flex-wrap:nowrap}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .nav-link.active{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.7)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:rgba(255,255,255,.9)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .nav-link.active{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.7);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.7%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.7)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(0.25rem - 1px);border-bottom-left-radius:calc(0.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.6rem}.card-subtitle{margin-top:-0.3rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.6rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.card-footer{padding:.6rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.card-header-tabs{margin-right:-0.625rem;margin-bottom:-0.6rem;margin-left:-0.625rem;border-bottom:0}.card-header-pills{margin-right:-0.625rem;margin-left:-0.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(0.25rem - 1px)}.card-img,.card-img-top,.card-img-bottom{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(0.25rem - 1px);border-bottom-left-radius:calc(0.25rem - 1px)}.card-deck .card{margin-bottom:10px}@media(min-width: 1px){.card-deck{display:flex;flex-flow:row wrap;margin-right:-10px;margin-left:-10px}.card-deck .card{flex:1 0 0%;margin-right:10px;margin-bottom:0;margin-left:10px}}.card-group>.card{margin-bottom:10px}@media(min-width: 1px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.6rem}@media(min-width: 1px){.card-columns{column-count:3;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#175ddc;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#104097;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#175ddc;border-color:#175ddc}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.15rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:0.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.badge{transition:none}}a.badge:hover,a.badge:focus{text-decoration:none}.badge:empty{display:none}.btn .badge,.swal2-popup .swal2-actions button .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#175ddc}a.badge-primary:hover,a.badge-primary:focus{color:#fff;background-color:#1249ae}a.badge-primary:focus,a.badge-primary.focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,93,220,.5)}.badge-secondary{color:#212529;background-color:#ced4da}a.badge-secondary:hover,a.badge-secondary:focus{color:#212529;background-color:#b1bbc4}a.badge-secondary:focus,a.badge-secondary.focus{outline:0;box-shadow:0 0 0 .2rem rgba(206,212,218,.5)}.badge-success{color:#fff;background-color:#00a65a}a.badge-success:hover,a.badge-success:focus{color:#fff;background-color:#00733e}a.badge-success:focus,a.badge-success.focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,166,90,.5)}.badge-info{color:#fff;background-color:#555}a.badge-info:hover,a.badge-info:focus{color:#fff;background-color:#3c3c3c}a.badge-info:focus,a.badge-info.focus{outline:0;box-shadow:0 0 0 .2rem rgba(85,85,85,.5)}.badge-warning{color:#fff;background-color:#bf7e16}a.badge-warning:hover,a.badge-warning:focus{color:#fff;background-color:#916011}a.badge-warning:focus,a.badge-warning.focus{outline:0;box-shadow:0 0 0 .2rem rgba(191,126,22,.5)}.badge-danger{color:#fff;background-color:#dd4b39}a.badge-danger:hover,a.badge-danger:focus{color:#fff;background-color:#c23321}a.badge-danger:focus,a.badge-danger.focus{outline:0;box-shadow:0 0 0 .2rem rgba(221,75,57,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:hover,a.badge-light:focus{color:#212529;background-color:#dae0e5}a.badge-light:focus,a.badge-light.focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:hover,a.badge-dark:focus{color:#fff;background-color:#1d2124}a.badge-dark:focus,a.badge-dark.focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.badge-primary-accent{color:#fff;background-color:#1252a3}a.badge-primary-accent:hover,a.badge-primary-accent:focus{color:#fff;background-color:#0d3b75}a.badge-primary-accent:focus,a.badge-primary-accent.focus{outline:0;box-shadow:0 0 0 .2rem rgba(18,82,163,.5)}.badge-secondary-alt{color:#fff;background-color:#1a3b66}a.badge-secondary-alt:hover,a.badge-secondary-alt:focus{color:#fff;background-color:#10233d}a.badge-secondary-alt:focus,a.badge-secondary-alt.focus{outline:0;box-shadow:0 0 0 .2rem rgba(26,59,102,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media(min-width: 1px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#0c3072;background-color:#d1dff8;border-color:#bed2f5}.alert-primary hr{border-top-color:#a8c3f2}.alert-primary .alert-link{color:#071d44}.alert-secondary{color:#6b6e71;background-color:#f5f6f8;border-color:#f1f3f5}.alert-secondary hr{border-top-color:#e2e6ea}.alert-secondary .alert-link{color:#525557}.alert-success{color:#00562f;background-color:#ccedde;border-color:#b8e6d1}.alert-success hr{border-top-color:#a5dfc5}.alert-success .alert-link{color:#002313}.alert-info{color:#2c2c2c;background-color:#ddd;border-color:#cfcfcf}.alert-info hr{border-top-color:#c2c2c2}.alert-info .alert-link{color:#131313}.alert-warning{color:#63420b;background-color:#f2e5d0;border-color:#eddbbe}.alert-warning hr{border-top-color:#e7d0aa}.alert-warning .alert-link{color:#352306}.alert-danger{color:#73271e;background-color:#f8dbd7;border-color:#f5cdc8}.alert-danger hr{border-top-color:#f1b9b2}.alert-danger .alert-link{color:#4b1913}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}.alert-primary-accent{color:#092b55;background-color:#d0dced;border-color:#bdcfe5}.alert-primary-accent hr{border-top-color:#abc2de}.alert-primary-accent .alert-link{color:#041427}.alert-secondary-alt{color:#0e1f35;background-color:#d1d8e0;border-color:#bfc8d4}.alert-secondary-alt hr{border-top-color:#b0bbca}.alert-secondary-alt .alert-link{color:#03070d}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:flex;height:1rem;overflow:hidden;line-height:0;font-size:0.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#175ddc;transition:width .6s ease}@media(prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-size:1rem 1rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media(prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#333;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.6rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#333;background-color:#fff;border-color:rgba(0,0,0,.125)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media(min-width: 1px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 2px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 3px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 4px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#0c3072;background-color:#bed2f5}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#0c3072;background-color:#a8c3f2}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#0c3072;border-color:#0c3072}.list-group-item-secondary{color:#6b6e71;background-color:#f1f3f5}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#6b6e71;background-color:#e2e6ea}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#6b6e71;border-color:#6b6e71}.list-group-item-success{color:#00562f;background-color:#b8e6d1}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#00562f;background-color:#a5dfc5}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#00562f;border-color:#00562f}.list-group-item-info{color:#2c2c2c;background-color:#cfcfcf}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#2c2c2c;background-color:#c2c2c2}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#2c2c2c;border-color:#2c2c2c}.list-group-item-warning{color:#63420b;background-color:#eddbbe}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#63420b;background-color:#e7d0aa}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#63420b;border-color:#63420b}.list-group-item-danger{color:#73271e;background-color:#f5cdc8}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#73271e;background-color:#f1b9b2}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#73271e;border-color:#73271e}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.list-group-item-primary-accent{color:#092b55;background-color:#bdcfe5}.list-group-item-primary-accent.list-group-item-action:hover,.list-group-item-primary-accent.list-group-item-action:focus{color:#092b55;background-color:#abc2de}.list-group-item-primary-accent.list-group-item-action.active{color:#fff;background-color:#092b55;border-color:#092b55}.list-group-item-secondary-alt{color:#0e1f35;background-color:#bfc8d4}.list-group-item-secondary-alt.list-group-item-action:hover,.list-group-item-secondary-alt.list-group-item-action:focus{color:#0e1f35;background-color:#b0bbca}.list-group-item-secondary-alt.list-group-item-action.active{color:#fff;background-color:#0e1f35;border-color:#0e1f35}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):hover,.close:not(:disabled):not(.disabled):focus{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0, -50px)}@media(prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-header,.modal-dialog-scrollable .modal-footer{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.3}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #ced4da;border-top-left-radius:calc(0.3rem - 1px);border-top-right-radius:calc(0.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #ced4da;border-bottom-right-radius:calc(0.3rem - 1px);border-bottom-left-radius:calc(0.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media(min-width: 1px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:min-content}.modal-sm{max-width:300px}}@media(min-width: 3px){.modal-lg,.modal-xl{max-width:800px}}@media(min-width: 4px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[x-placement^=top]{padding:.4rem 0}.bs-tooltip-top .arrow,.bs-tooltip-auto[x-placement^=top] .arrow{bottom:0}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[x-placement^=top] .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-right,.bs-tooltip-auto[x-placement^=right]{padding:0 .4rem}.bs-tooltip-right .arrow,.bs-tooltip-auto[x-placement^=right] .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-right .arrow::before,.bs-tooltip-auto[x-placement^=right] .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-bottom,.bs-tooltip-auto[x-placement^=bottom]{padding:.4rem 0}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[x-placement^=bottom] .arrow{top:0}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[x-placement^=bottom] .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-left,.bs-tooltip-auto[x-placement^=left]{padding:0 .4rem}.bs-tooltip-left .arrow,.bs-tooltip-auto[x-placement^=left] .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-left .arrow::before,.bs-tooltip-auto[x-placement^=left] .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::before,.popover .arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top,.bs-popover-auto[x-placement^=top]{margin-bottom:.5rem}.bs-popover-top>.arrow,.bs-popover-auto[x-placement^=top]>.arrow{bottom:calc(-0.5rem - 1px)}.bs-popover-top>.arrow::before,.bs-popover-auto[x-placement^=top]>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-top>.arrow::after,.bs-popover-auto[x-placement^=top]>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-right,.bs-popover-auto[x-placement^=right]{margin-left:.5rem}.bs-popover-right>.arrow,.bs-popover-auto[x-placement^=right]>.arrow{left:calc(-0.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-right>.arrow::before,.bs-popover-auto[x-placement^=right]>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-right>.arrow::after,.bs-popover-auto[x-placement^=right]>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-bottom,.bs-popover-auto[x-placement^=bottom]{margin-top:.5rem}.bs-popover-bottom>.arrow,.bs-popover-auto[x-placement^=bottom]>.arrow{top:calc(-0.5rem - 1px)}.bs-popover-bottom>.arrow::before,.bs-popover-auto[x-placement^=bottom]>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-bottom>.arrow::after,.bs-popover-auto[x-placement^=bottom]>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-bottom .popover-header::before,.bs-popover-auto[x-placement^=bottom] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-0.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-left,.bs-popover-auto[x-placement^=left]{margin-right:.5rem}.bs-popover-left>.arrow,.bs-popover-auto[x-placement^=left]>.arrow{right:calc(-0.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-left>.arrow::before,.bs-popover-auto[x-placement^=left]>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-left>.arrow::after,.bs-popover-auto[x-placement^=left]>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(0.3rem - 1px);border-top-right-radius:calc(0.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#333}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;transition:transform .6s ease-in-out}@media(prefers-reduced-motion: reduce){.carousel-item{transition:none}}.carousel-item.active,.carousel-item-next,.carousel-item-prev{display:block}.carousel-item-next:not(.carousel-item-left),.active.carousel-item-right{transform:translateX(100%)}.carousel-item-prev:not(.carousel-item-right),.active.carousel-item-left{transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item.active,.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media(prefers-reduced-motion: reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-prev,.carousel-control-next{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media(prefers-reduced-motion: reduce){.carousel-control-prev,.carousel-control-next{transition:none}}.carousel-control-prev:hover,.carousel-control-prev:focus,.carousel-control-next:hover,.carousel-control-next:focus{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-prev-icon,.carousel-control-next-icon{display:inline-block;width:20px;height:20px;background:50%/100% 100% no-repeat}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23FFFFFF' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23FFFFFF' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media(prefers-reduced-motion: reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media(prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s}}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.bg-primary{background-color:#175ddc !important}a.bg-primary:hover,a.bg-primary:focus,button.bg-primary:hover,button.bg-primary:focus{background-color:#1249ae !important}.bg-secondary{background-color:#ced4da !important}a.bg-secondary:hover,a.bg-secondary:focus,button.bg-secondary:hover,button.bg-secondary:focus{background-color:#b1bbc4 !important}.bg-success{background-color:#00a65a !important}a.bg-success:hover,a.bg-success:focus,button.bg-success:hover,button.bg-success:focus{background-color:#00733e !important}.bg-info{background-color:#555 !important}a.bg-info:hover,a.bg-info:focus,button.bg-info:hover,button.bg-info:focus{background-color:#3c3c3c !important}.bg-warning{background-color:#bf7e16 !important}a.bg-warning:hover,a.bg-warning:focus,button.bg-warning:hover,button.bg-warning:focus{background-color:#916011 !important}.bg-danger{background-color:#dd4b39 !important}a.bg-danger:hover,a.bg-danger:focus,button.bg-danger:hover,button.bg-danger:focus{background-color:#c23321 !important}.bg-light{background-color:#f8f9fa !important}a.bg-light:hover,a.bg-light:focus,button.bg-light:hover,button.bg-light:focus{background-color:#dae0e5 !important}.bg-dark{background-color:#343a40 !important}a.bg-dark:hover,a.bg-dark:focus,button.bg-dark:hover,button.bg-dark:focus{background-color:#1d2124 !important}.bg-primary-accent{background-color:#1252a3 !important}a.bg-primary-accent:hover,a.bg-primary-accent:focus,button.bg-primary-accent:hover,button.bg-primary-accent:focus{background-color:#0d3b75 !important}.bg-secondary-alt{background-color:#1a3b66 !important}a.bg-secondary-alt:hover,a.bg-secondary-alt:focus,button.bg-secondary-alt:hover,button.bg-secondary-alt:focus{background-color:#10233d !important}.bg-white{background-color:#fff !important}.bg-transparent{background-color:transparent !important}.border{border:1px solid #ced4da !important}.border-top{border-top:1px solid #ced4da !important}.border-right{border-right:1px solid #ced4da !important}.border-bottom{border-bottom:1px solid #ced4da !important}.border-left{border-left:1px solid #ced4da !important}.border-0{border:0 !important}.border-top-0{border-top:0 !important}.border-right-0{border-right:0 !important}.border-bottom-0{border-bottom:0 !important}.border-left-0{border-left:0 !important}.border-primary{border-color:#175ddc !important}.border-secondary{border-color:#ced4da !important}.border-success{border-color:#00a65a !important}.border-info{border-color:#555 !important}.border-warning{border-color:#bf7e16 !important}.border-danger{border-color:#dd4b39 !important}.border-light{border-color:#f8f9fa !important}.border-dark{border-color:#343a40 !important}.border-primary-accent{border-color:#1252a3 !important}.border-secondary-alt{border-color:#1a3b66 !important}.border-white{border-color:#fff !important}.rounded-sm{border-radius:.2rem !important}.rounded,.table td.table-list-icon img,app-avatar img{border-radius:.25rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-right{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-left{border-top-left-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-lg{border-radius:.3rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-0{border-radius:0 !important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}@media(min-width: 1px){.d-sm-none{display:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}}@media(min-width: 2px){.d-md-none{display:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}}@media(min-width: 3px){.d-lg-none{display:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}}@media(min-width: 4px){.d-xl-none{display:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}}@media print{.d-print-none{display:none !important}.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.8571428571%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-fill{flex:1 1 auto !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}@media(min-width: 1px){.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}}@media(min-width: 2px){.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}}@media(min-width: 3px){.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}}@media(min-width: 4px){.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}}.float-left{float:left !important}.float-right{float:right !important}.float-none{float:none !important}@media(min-width: 1px){.float-sm-left{float:left !important}.float-sm-right{float:right !important}.float-sm-none{float:none !important}}@media(min-width: 2px){.float-md-left{float:left !important}.float-md-right{float:right !important}.float-md-none{float:none !important}}@media(min-width: 3px){.float-lg-left{float:left !important}.float-lg-right{float:right !important}.float-lg-none{float:none !important}}@media(min-width: 4px){.float-xl-left{float:left !important}.float-xl-right{float:right !important}.float-xl-none{float:none !important}}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports(position: sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only,.table tr:not(:hover) td.table-list-options>.dropdown:not(.show) button:not(:focus):not(:active),.table tr:not(:hover) td.table-list-options>button:not(:focus):not(:active){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075) !important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175) !important}.shadow-none{box-shadow:none !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mw-100{max-width:100% !important}.mh-100{max-height:100% !important}.min-vw-100{min-width:100vw !important}.min-vh-100{min-height:100vh !important}.vw-100{width:100vw !important}.vh-100{height:100vh !important}.m-0{margin:0 !important}.mt-0,.my-0{margin-top:0 !important}.mr-0,.mx-0{margin-right:0 !important}.mb-0,.my-0{margin-bottom:0 !important}.ml-0,.mx-0{margin-left:0 !important}.m-1{margin:.25rem !important}.mt-1,.my-1{margin-top:.25rem !important}.mr-1,.mx-1{margin-right:.25rem !important}.mb-1,.my-1{margin-bottom:.25rem !important}.ml-1,.mx-1{margin-left:.25rem !important}.m-2{margin:.5rem !important}.mt-2,.form-check-block .form-check-label>span,.my-2{margin-top:.5rem !important}.mr-2,.mx-2{margin-right:.5rem !important}.mb-2,.my-2{margin-bottom:.5rem !important}.ml-2,.mx-2{margin-left:.5rem !important}.m-3{margin:1rem !important}.mt-3,.form-check-block+.form-check-block:not(.mt-2),.my-3{margin-top:1rem !important}.mr-3,.mx-3{margin-right:1rem !important}.mb-3,.my-3{margin-bottom:1rem !important}.ml-3,.mx-3{margin-left:1rem !important}.m-4{margin:1.5rem !important}.mt-4,.my-4{margin-top:1.5rem !important}.mr-4,.mx-4{margin-right:1.5rem !important}.mb-4,.card-body-header,.my-4{margin-bottom:1.5rem !important}.ml-4,.form-group .form-group-child-check,.mx-4{margin-left:1.5rem !important}.m-5{margin:3rem !important}.mt-5,.my-5{margin-top:3rem !important}.mr-5,.mx-5{margin-right:3rem !important}.mb-5,.my-5{margin-bottom:3rem !important}.ml-5,.mx-5{margin-left:3rem !important}.p-0{padding:0 !important}.pt-0,.py-0{padding-top:0 !important}.pr-0,.px-0{padding-right:0 !important}.pb-0,.py-0{padding-bottom:0 !important}.pl-0,.px-0{padding-left:0 !important}.p-1{padding:.25rem !important}.pt-1,.py-1{padding-top:.25rem !important}.pr-1,.px-1{padding-right:.25rem !important}.pb-1,.py-1{padding-bottom:.25rem !important}.pl-1,.px-1{padding-left:.25rem !important}.p-2{padding:.5rem !important}.pt-2,.py-2{padding-top:.5rem !important}.pr-2,.px-2{padding-right:.5rem !important}.pb-2,.py-2{padding-bottom:.5rem !important}.pl-2,.px-2{padding-left:.5rem !important}.p-3{padding:1rem !important}.pt-3,.py-3{padding-top:1rem !important}.pr-3,.px-3{padding-right:1rem !important}.pb-3,.py-3{padding-bottom:1rem !important}.pl-3,.px-3{padding-left:1rem !important}.p-4{padding:1.5rem !important}.pt-4,.py-4{padding-top:1.5rem !important}.pr-4,.px-4{padding-right:1.5rem !important}.pb-4,.py-4{padding-bottom:1.5rem !important}.pl-4,.px-4{padding-left:1.5rem !important}.p-5{padding:3rem !important}.pt-5,.py-5{padding-top:3rem !important}.pr-5,.px-5{padding-right:3rem !important}.pb-5,.py-5{padding-bottom:3rem !important}.pl-5,.px-5{padding-left:3rem !important}.m-n1{margin:-0.25rem !important}.mt-n1,.my-n1{margin-top:-0.25rem !important}.mr-n1,.mx-n1{margin-right:-0.25rem !important}.mb-n1,.my-n1{margin-bottom:-0.25rem !important}.ml-n1,.mx-n1{margin-left:-0.25rem !important}.m-n2{margin:-0.5rem !important}.mt-n2,.my-n2{margin-top:-0.5rem !important}.mr-n2,.mx-n2{margin-right:-0.5rem !important}.mb-n2,.my-n2{margin-bottom:-0.5rem !important}.ml-n2,.mx-n2{margin-left:-0.5rem !important}.m-n3{margin:-1rem !important}.mt-n3,.my-n3{margin-top:-1rem !important}.mr-n3,.mx-n3{margin-right:-1rem !important}.mb-n3,.my-n3{margin-bottom:-1rem !important}.ml-n3,.mx-n3{margin-left:-1rem !important}.m-n4{margin:-1.5rem !important}.mt-n4,.my-n4{margin-top:-1.5rem !important}.mr-n4,.mx-n4{margin-right:-1.5rem !important}.mb-n4,.my-n4{margin-bottom:-1.5rem !important}.ml-n4,.mx-n4{margin-left:-1.5rem !important}.m-n5{margin:-3rem !important}.mt-n5,.my-n5{margin-top:-3rem !important}.mr-n5,.mx-n5{margin-right:-3rem !important}.mb-n5,.my-n5{margin-bottom:-3rem !important}.ml-n5,.mx-n5{margin-left:-3rem !important}.m-auto{margin:auto !important}.mt-auto,.my-auto{margin-top:auto !important}.mr-auto,.mx-auto{margin-right:auto !important}.mb-auto,.my-auto{margin-bottom:auto !important}.ml-auto,.mx-auto{margin-left:auto !important}@media(min-width: 1px){.m-sm-0{margin:0 !important}.mt-sm-0,.my-sm-0{margin-top:0 !important}.mr-sm-0,.mx-sm-0{margin-right:0 !important}.mb-sm-0,.my-sm-0{margin-bottom:0 !important}.ml-sm-0,.mx-sm-0{margin-left:0 !important}.m-sm-1{margin:.25rem !important}.mt-sm-1,.my-sm-1{margin-top:.25rem !important}.mr-sm-1,.mx-sm-1{margin-right:.25rem !important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem !important}.ml-sm-1,.mx-sm-1{margin-left:.25rem !important}.m-sm-2{margin:.5rem !important}.mt-sm-2,.my-sm-2{margin-top:.5rem !important}.mr-sm-2,.mx-sm-2{margin-right:.5rem !important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem !important}.ml-sm-2,.mx-sm-2{margin-left:.5rem !important}.m-sm-3{margin:1rem !important}.mt-sm-3,.my-sm-3{margin-top:1rem !important}.mr-sm-3,.mx-sm-3{margin-right:1rem !important}.mb-sm-3,.my-sm-3{margin-bottom:1rem !important}.ml-sm-3,.mx-sm-3{margin-left:1rem !important}.m-sm-4{margin:1.5rem !important}.mt-sm-4,.my-sm-4{margin-top:1.5rem !important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem !important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem !important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem !important}.m-sm-5{margin:3rem !important}.mt-sm-5,.my-sm-5{margin-top:3rem !important}.mr-sm-5,.mx-sm-5{margin-right:3rem !important}.mb-sm-5,.my-sm-5{margin-bottom:3rem !important}.ml-sm-5,.mx-sm-5{margin-left:3rem !important}.p-sm-0{padding:0 !important}.pt-sm-0,.py-sm-0{padding-top:0 !important}.pr-sm-0,.px-sm-0{padding-right:0 !important}.pb-sm-0,.py-sm-0{padding-bottom:0 !important}.pl-sm-0,.px-sm-0{padding-left:0 !important}.p-sm-1{padding:.25rem !important}.pt-sm-1,.py-sm-1{padding-top:.25rem !important}.pr-sm-1,.px-sm-1{padding-right:.25rem !important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem !important}.pl-sm-1,.px-sm-1{padding-left:.25rem !important}.p-sm-2{padding:.5rem !important}.pt-sm-2,.py-sm-2{padding-top:.5rem !important}.pr-sm-2,.px-sm-2{padding-right:.5rem !important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem !important}.pl-sm-2,.px-sm-2{padding-left:.5rem !important}.p-sm-3{padding:1rem !important}.pt-sm-3,.py-sm-3{padding-top:1rem !important}.pr-sm-3,.px-sm-3{padding-right:1rem !important}.pb-sm-3,.py-sm-3{padding-bottom:1rem !important}.pl-sm-3,.px-sm-3{padding-left:1rem !important}.p-sm-4{padding:1.5rem !important}.pt-sm-4,.py-sm-4{padding-top:1.5rem !important}.pr-sm-4,.px-sm-4{padding-right:1.5rem !important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem !important}.pl-sm-4,.px-sm-4{padding-left:1.5rem !important}.p-sm-5{padding:3rem !important}.pt-sm-5,.py-sm-5{padding-top:3rem !important}.pr-sm-5,.px-sm-5{padding-right:3rem !important}.pb-sm-5,.py-sm-5{padding-bottom:3rem !important}.pl-sm-5,.px-sm-5{padding-left:3rem !important}.m-sm-n1{margin:-0.25rem !important}.mt-sm-n1,.my-sm-n1{margin-top:-0.25rem !important}.mr-sm-n1,.mx-sm-n1{margin-right:-0.25rem !important}.mb-sm-n1,.my-sm-n1{margin-bottom:-0.25rem !important}.ml-sm-n1,.mx-sm-n1{margin-left:-0.25rem !important}.m-sm-n2{margin:-0.5rem !important}.mt-sm-n2,.my-sm-n2{margin-top:-0.5rem !important}.mr-sm-n2,.mx-sm-n2{margin-right:-0.5rem !important}.mb-sm-n2,.my-sm-n2{margin-bottom:-0.5rem !important}.ml-sm-n2,.mx-sm-n2{margin-left:-0.5rem !important}.m-sm-n3{margin:-1rem !important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem !important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem !important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem !important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem !important}.m-sm-n4{margin:-1.5rem !important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem !important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem !important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem !important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem !important}.m-sm-n5{margin:-3rem !important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem !important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem !important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem !important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem !important}.m-sm-auto{margin:auto !important}.mt-sm-auto,.my-sm-auto{margin-top:auto !important}.mr-sm-auto,.mx-sm-auto{margin-right:auto !important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto !important}.ml-sm-auto,.mx-sm-auto{margin-left:auto !important}}@media(min-width: 2px){.m-md-0{margin:0 !important}.mt-md-0,.my-md-0{margin-top:0 !important}.mr-md-0,.mx-md-0{margin-right:0 !important}.mb-md-0,.my-md-0{margin-bottom:0 !important}.ml-md-0,.mx-md-0{margin-left:0 !important}.m-md-1{margin:.25rem !important}.mt-md-1,.my-md-1{margin-top:.25rem !important}.mr-md-1,.mx-md-1{margin-right:.25rem !important}.mb-md-1,.my-md-1{margin-bottom:.25rem !important}.ml-md-1,.mx-md-1{margin-left:.25rem !important}.m-md-2{margin:.5rem !important}.mt-md-2,.my-md-2{margin-top:.5rem !important}.mr-md-2,.mx-md-2{margin-right:.5rem !important}.mb-md-2,.my-md-2{margin-bottom:.5rem !important}.ml-md-2,.mx-md-2{margin-left:.5rem !important}.m-md-3{margin:1rem !important}.mt-md-3,.my-md-3{margin-top:1rem !important}.mr-md-3,.mx-md-3{margin-right:1rem !important}.mb-md-3,.my-md-3{margin-bottom:1rem !important}.ml-md-3,.mx-md-3{margin-left:1rem !important}.m-md-4{margin:1.5rem !important}.mt-md-4,.my-md-4{margin-top:1.5rem !important}.mr-md-4,.mx-md-4{margin-right:1.5rem !important}.mb-md-4,.my-md-4{margin-bottom:1.5rem !important}.ml-md-4,.mx-md-4{margin-left:1.5rem !important}.m-md-5{margin:3rem !important}.mt-md-5,.my-md-5{margin-top:3rem !important}.mr-md-5,.mx-md-5{margin-right:3rem !important}.mb-md-5,.my-md-5{margin-bottom:3rem !important}.ml-md-5,.mx-md-5{margin-left:3rem !important}.p-md-0{padding:0 !important}.pt-md-0,.py-md-0{padding-top:0 !important}.pr-md-0,.px-md-0{padding-right:0 !important}.pb-md-0,.py-md-0{padding-bottom:0 !important}.pl-md-0,.px-md-0{padding-left:0 !important}.p-md-1{padding:.25rem !important}.pt-md-1,.py-md-1{padding-top:.25rem !important}.pr-md-1,.px-md-1{padding-right:.25rem !important}.pb-md-1,.py-md-1{padding-bottom:.25rem !important}.pl-md-1,.px-md-1{padding-left:.25rem !important}.p-md-2{padding:.5rem !important}.pt-md-2,.py-md-2{padding-top:.5rem !important}.pr-md-2,.px-md-2{padding-right:.5rem !important}.pb-md-2,.py-md-2{padding-bottom:.5rem !important}.pl-md-2,.px-md-2{padding-left:.5rem !important}.p-md-3{padding:1rem !important}.pt-md-3,.py-md-3{padding-top:1rem !important}.pr-md-3,.px-md-3{padding-right:1rem !important}.pb-md-3,.py-md-3{padding-bottom:1rem !important}.pl-md-3,.px-md-3{padding-left:1rem !important}.p-md-4{padding:1.5rem !important}.pt-md-4,.py-md-4{padding-top:1.5rem !important}.pr-md-4,.px-md-4{padding-right:1.5rem !important}.pb-md-4,.py-md-4{padding-bottom:1.5rem !important}.pl-md-4,.px-md-4{padding-left:1.5rem !important}.p-md-5{padding:3rem !important}.pt-md-5,.py-md-5{padding-top:3rem !important}.pr-md-5,.px-md-5{padding-right:3rem !important}.pb-md-5,.py-md-5{padding-bottom:3rem !important}.pl-md-5,.px-md-5{padding-left:3rem !important}.m-md-n1{margin:-0.25rem !important}.mt-md-n1,.my-md-n1{margin-top:-0.25rem !important}.mr-md-n1,.mx-md-n1{margin-right:-0.25rem !important}.mb-md-n1,.my-md-n1{margin-bottom:-0.25rem !important}.ml-md-n1,.mx-md-n1{margin-left:-0.25rem !important}.m-md-n2{margin:-0.5rem !important}.mt-md-n2,.my-md-n2{margin-top:-0.5rem !important}.mr-md-n2,.mx-md-n2{margin-right:-0.5rem !important}.mb-md-n2,.my-md-n2{margin-bottom:-0.5rem !important}.ml-md-n2,.mx-md-n2{margin-left:-0.5rem !important}.m-md-n3{margin:-1rem !important}.mt-md-n3,.my-md-n3{margin-top:-1rem !important}.mr-md-n3,.mx-md-n3{margin-right:-1rem !important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem !important}.ml-md-n3,.mx-md-n3{margin-left:-1rem !important}.m-md-n4{margin:-1.5rem !important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem !important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem !important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem !important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem !important}.m-md-n5{margin:-3rem !important}.mt-md-n5,.my-md-n5{margin-top:-3rem !important}.mr-md-n5,.mx-md-n5{margin-right:-3rem !important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem !important}.ml-md-n5,.mx-md-n5{margin-left:-3rem !important}.m-md-auto{margin:auto !important}.mt-md-auto,.my-md-auto{margin-top:auto !important}.mr-md-auto,.mx-md-auto{margin-right:auto !important}.mb-md-auto,.my-md-auto{margin-bottom:auto !important}.ml-md-auto,.mx-md-auto{margin-left:auto !important}}@media(min-width: 3px){.m-lg-0{margin:0 !important}.mt-lg-0,.my-lg-0{margin-top:0 !important}.mr-lg-0,.mx-lg-0{margin-right:0 !important}.mb-lg-0,.my-lg-0{margin-bottom:0 !important}.ml-lg-0,.mx-lg-0{margin-left:0 !important}.m-lg-1{margin:.25rem !important}.mt-lg-1,.my-lg-1{margin-top:.25rem !important}.mr-lg-1,.mx-lg-1{margin-right:.25rem !important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem !important}.ml-lg-1,.mx-lg-1{margin-left:.25rem !important}.m-lg-2{margin:.5rem !important}.mt-lg-2,.my-lg-2{margin-top:.5rem !important}.mr-lg-2,.mx-lg-2{margin-right:.5rem !important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem !important}.ml-lg-2,.mx-lg-2{margin-left:.5rem !important}.m-lg-3{margin:1rem !important}.mt-lg-3,.my-lg-3{margin-top:1rem !important}.mr-lg-3,.mx-lg-3{margin-right:1rem !important}.mb-lg-3,.my-lg-3{margin-bottom:1rem !important}.ml-lg-3,.mx-lg-3{margin-left:1rem !important}.m-lg-4{margin:1.5rem !important}.mt-lg-4,.my-lg-4{margin-top:1.5rem !important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem !important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem !important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem !important}.m-lg-5{margin:3rem !important}.mt-lg-5,.my-lg-5{margin-top:3rem !important}.mr-lg-5,.mx-lg-5{margin-right:3rem !important}.mb-lg-5,.my-lg-5{margin-bottom:3rem !important}.ml-lg-5,.mx-lg-5{margin-left:3rem !important}.p-lg-0{padding:0 !important}.pt-lg-0,.py-lg-0{padding-top:0 !important}.pr-lg-0,.px-lg-0{padding-right:0 !important}.pb-lg-0,.py-lg-0{padding-bottom:0 !important}.pl-lg-0,.px-lg-0{padding-left:0 !important}.p-lg-1{padding:.25rem !important}.pt-lg-1,.py-lg-1{padding-top:.25rem !important}.pr-lg-1,.px-lg-1{padding-right:.25rem !important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem !important}.pl-lg-1,.px-lg-1{padding-left:.25rem !important}.p-lg-2{padding:.5rem !important}.pt-lg-2,.py-lg-2{padding-top:.5rem !important}.pr-lg-2,.px-lg-2{padding-right:.5rem !important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem !important}.pl-lg-2,.px-lg-2{padding-left:.5rem !important}.p-lg-3{padding:1rem !important}.pt-lg-3,.py-lg-3{padding-top:1rem !important}.pr-lg-3,.px-lg-3{padding-right:1rem !important}.pb-lg-3,.py-lg-3{padding-bottom:1rem !important}.pl-lg-3,.px-lg-3{padding-left:1rem !important}.p-lg-4{padding:1.5rem !important}.pt-lg-4,.py-lg-4{padding-top:1.5rem !important}.pr-lg-4,.px-lg-4{padding-right:1.5rem !important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem !important}.pl-lg-4,.px-lg-4{padding-left:1.5rem !important}.p-lg-5{padding:3rem !important}.pt-lg-5,.py-lg-5{padding-top:3rem !important}.pr-lg-5,.px-lg-5{padding-right:3rem !important}.pb-lg-5,.py-lg-5{padding-bottom:3rem !important}.pl-lg-5,.px-lg-5{padding-left:3rem !important}.m-lg-n1{margin:-0.25rem !important}.mt-lg-n1,.my-lg-n1{margin-top:-0.25rem !important}.mr-lg-n1,.mx-lg-n1{margin-right:-0.25rem !important}.mb-lg-n1,.my-lg-n1{margin-bottom:-0.25rem !important}.ml-lg-n1,.mx-lg-n1{margin-left:-0.25rem !important}.m-lg-n2{margin:-0.5rem !important}.mt-lg-n2,.my-lg-n2{margin-top:-0.5rem !important}.mr-lg-n2,.mx-lg-n2{margin-right:-0.5rem !important}.mb-lg-n2,.my-lg-n2{margin-bottom:-0.5rem !important}.ml-lg-n2,.mx-lg-n2{margin-left:-0.5rem !important}.m-lg-n3{margin:-1rem !important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem !important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem !important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem !important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem !important}.m-lg-n4{margin:-1.5rem !important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem !important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem !important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem !important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem !important}.m-lg-n5{margin:-3rem !important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem !important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem !important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem !important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem !important}.m-lg-auto{margin:auto !important}.mt-lg-auto,.my-lg-auto{margin-top:auto !important}.mr-lg-auto,.mx-lg-auto{margin-right:auto !important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto !important}.ml-lg-auto,.mx-lg-auto{margin-left:auto !important}}@media(min-width: 4px){.m-xl-0{margin:0 !important}.mt-xl-0,.my-xl-0{margin-top:0 !important}.mr-xl-0,.mx-xl-0{margin-right:0 !important}.mb-xl-0,.my-xl-0{margin-bottom:0 !important}.ml-xl-0,.mx-xl-0{margin-left:0 !important}.m-xl-1{margin:.25rem !important}.mt-xl-1,.my-xl-1{margin-top:.25rem !important}.mr-xl-1,.mx-xl-1{margin-right:.25rem !important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem !important}.ml-xl-1,.mx-xl-1{margin-left:.25rem !important}.m-xl-2{margin:.5rem !important}.mt-xl-2,.my-xl-2{margin-top:.5rem !important}.mr-xl-2,.mx-xl-2{margin-right:.5rem !important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem !important}.ml-xl-2,.mx-xl-2{margin-left:.5rem !important}.m-xl-3{margin:1rem !important}.mt-xl-3,.my-xl-3{margin-top:1rem !important}.mr-xl-3,.mx-xl-3{margin-right:1rem !important}.mb-xl-3,.my-xl-3{margin-bottom:1rem !important}.ml-xl-3,.mx-xl-3{margin-left:1rem !important}.m-xl-4{margin:1.5rem !important}.mt-xl-4,.my-xl-4{margin-top:1.5rem !important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem !important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem !important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem !important}.m-xl-5{margin:3rem !important}.mt-xl-5,.my-xl-5{margin-top:3rem !important}.mr-xl-5,.mx-xl-5{margin-right:3rem !important}.mb-xl-5,.my-xl-5{margin-bottom:3rem !important}.ml-xl-5,.mx-xl-5{margin-left:3rem !important}.p-xl-0{padding:0 !important}.pt-xl-0,.py-xl-0{padding-top:0 !important}.pr-xl-0,.px-xl-0{padding-right:0 !important}.pb-xl-0,.py-xl-0{padding-bottom:0 !important}.pl-xl-0,.px-xl-0{padding-left:0 !important}.p-xl-1{padding:.25rem !important}.pt-xl-1,.py-xl-1{padding-top:.25rem !important}.pr-xl-1,.px-xl-1{padding-right:.25rem !important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem !important}.pl-xl-1,.px-xl-1{padding-left:.25rem !important}.p-xl-2{padding:.5rem !important}.pt-xl-2,.py-xl-2{padding-top:.5rem !important}.pr-xl-2,.px-xl-2{padding-right:.5rem !important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem !important}.pl-xl-2,.px-xl-2{padding-left:.5rem !important}.p-xl-3{padding:1rem !important}.pt-xl-3,.py-xl-3{padding-top:1rem !important}.pr-xl-3,.px-xl-3{padding-right:1rem !important}.pb-xl-3,.py-xl-3{padding-bottom:1rem !important}.pl-xl-3,.px-xl-3{padding-left:1rem !important}.p-xl-4{padding:1.5rem !important}.pt-xl-4,.py-xl-4{padding-top:1.5rem !important}.pr-xl-4,.px-xl-4{padding-right:1.5rem !important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem !important}.pl-xl-4,.px-xl-4{padding-left:1.5rem !important}.p-xl-5{padding:3rem !important}.pt-xl-5,.py-xl-5{padding-top:3rem !important}.pr-xl-5,.px-xl-5{padding-right:3rem !important}.pb-xl-5,.py-xl-5{padding-bottom:3rem !important}.pl-xl-5,.px-xl-5{padding-left:3rem !important}.m-xl-n1{margin:-0.25rem !important}.mt-xl-n1,.my-xl-n1{margin-top:-0.25rem !important}.mr-xl-n1,.mx-xl-n1{margin-right:-0.25rem !important}.mb-xl-n1,.my-xl-n1{margin-bottom:-0.25rem !important}.ml-xl-n1,.mx-xl-n1{margin-left:-0.25rem !important}.m-xl-n2{margin:-0.5rem !important}.mt-xl-n2,.my-xl-n2{margin-top:-0.5rem !important}.mr-xl-n2,.mx-xl-n2{margin-right:-0.5rem !important}.mb-xl-n2,.my-xl-n2{margin-bottom:-0.5rem !important}.ml-xl-n2,.mx-xl-n2{margin-left:-0.5rem !important}.m-xl-n3{margin:-1rem !important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem !important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem !important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem !important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem !important}.m-xl-n4{margin:-1.5rem !important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem !important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem !important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem !important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem !important}.m-xl-n5{margin:-3rem !important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem !important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem !important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem !important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem !important}.m-xl-auto{margin:auto !important}.mt-xl-auto,.my-xl-auto{margin-top:auto !important}.mr-xl-auto,.mx-xl-auto{margin-right:auto !important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto !important}.ml-xl-auto,.mx-xl-auto{margin-left:auto !important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace,.totp .totp-code{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace !important}.text-justify{text-align:justify !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}@media(min-width: 1px){.text-sm-left{text-align:left !important}.text-sm-right{text-align:right !important}.text-sm-center{text-align:center !important}}@media(min-width: 2px){.text-md-left{text-align:left !important}.text-md-right{text-align:right !important}.text-md-center{text-align:center !important}}@media(min-width: 3px){.text-lg-left{text-align:left !important}.text-lg-right{text-align:right !important}.text-lg-center{text-align:center !important}}@media(min-width: 4px){.text-xl-left{text-align:left !important}.text-xl-right{text-align:right !important}.text-xl-center{text-align:center !important}}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.font-weight-light{font-weight:300 !important}.font-weight-lighter{font-weight:lighter !important}.font-weight-normal{font-weight:400 !important}.font-weight-bold{font-weight:700 !important}.font-weight-bolder{font-weight:bolder !important}.font-italic{font-style:italic !important}.text-white{color:#fff !important}.text-primary{color:#175ddc !important}a.text-primary:hover,a.text-primary:focus{color:#104097 !important}.text-secondary{color:#ced4da !important}a.text-secondary:hover,a.text-secondary:focus{color:#a2aeb9 !important}.text-success{color:#00a65a !important}a.text-success:hover,a.text-success:focus{color:#005a31 !important}.text-info{color:#555 !important}a.text-info:hover,a.text-info:focus{color:#2f2f2f !important}.text-warning{color:#bf7e16 !important}a.text-warning:hover,a.text-warning:focus{color:#7a510e !important}.text-danger{color:#dd4b39 !important}a.text-danger:hover,a.text-danger:focus{color:#ac2d1e !important}.text-light{color:#f8f9fa !important}a.text-light:hover,a.text-light:focus{color:#cbd3da !important}.text-dark{color:#343a40 !important}a.text-dark:hover,a.text-dark:focus{color:#121416 !important}.text-primary-accent{color:#1252a3 !important}a.text-primary-accent:hover,a.text-primary-accent:focus{color:#0a2f5e !important}.text-secondary-alt{color:#1a3b66 !important}a.text-secondary-alt:hover,a.text-secondary-alt:focus{color:#0a1829 !important}.text-body{color:#333 !important}.text-muted,.card-header small,.modal-header small{color:#6c757d !important}.text-black-50{color:rgba(0,0,0,.5) !important}.text-white-50{color:rgba(255,255,255,.5) !important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none !important}.text-break{word-break:break-word !important;word-wrap:break-word !important}.text-reset{color:inherit !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media print{*,*::before,*::after{text-shadow:none !important;box-shadow:none !important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap !important}pre,blockquote{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:3px !important}.container{min-width:3px !important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #dee2e6 !important}.table-dark{color:inherit}.table-dark th,.table-dark td,.table-dark thead th,.table-dark tbody+tbody{border-color:#ced4da}.table .thead-dark th{color:inherit;border-color:#ced4da}}.toast{display:flex;flex-direction:row;align-content:center;justify-content:center;position:relative;background-color:#030303}.toast-success{background-color:#51a351}.toast-error{background-color:#bd362f}.toast-info{background-color:#2f96b4}.toast-wait{background-color:#2f96b4}.toast-warning{background-color:#f89406}.icon-success{background-repeat:no-repeat;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important}.icon-error{background-repeat:no-repeat;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important}.icon-info{background-repeat:no-repeat;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important}.icon-wait{background-repeat:no-repeat;background-image:url("data:image/gif;base64,R0lGODlhIAAgAIQAAAQCBISGhMzKzERCROTm5CQiJKyurHx+fPz+/ExOTOzu7Dw+PIyOjCwqLFRWVAwKDIyKjMzOzOzq7CQmJLy6vFRSVPTy9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCQAXACwAAAAAIAAgAAAF3eAljmRpnmh6VRSVqLDpIDTixOdUlFSNUDhSQUAT7ES9GnD0SFQAKWItMqr4bqKHVPDI+WiTkaOFFVlrFe83rDrT0qeIjwrT0iLdU0GOiBxhAA4VeSk6QYeIOAsQEAuJKgw+EI8nA18IA48JBAQvFxCXDI8SNAQikV+iiaQIpheWX5mJmxKeF6g0qpQmA4yOu8C7EwYWCgZswRcTFj4KyMAGlwYxDwcHhCXMXxYxBzQHKNo+3DDeCOAn0V/TddbYJA0K48gAEAFQicMWFsfwNA3JSgAIAAFfwIMIL4QAACH5BAkJABoALAAAAAAgACAAhAQCBIyKjERCRMzOzCQiJPTy9DQyNGRmZMTCxOTm5CwqLHx+fBQWFJyenNTW1Pz6/Dw6PGxubAwKDIyOjNTS1CQmJCwuLPz+/Dw+PHRydAAAAAAAAAAAAAAAAAAAAAAAAAXboCaOZGmeaKoxWcSosMkk15W8cZ7VdZaXkcEgQtrxfD9RhHchima1GwlCGUBSFCaFxMrgRtnLFhWujWHhs2nJc8KoVlWGQnEn7/i8XgOwWAB7JwoONQ4KgSQAZRcOgHgSCwsSIhZMNRZ5CzULIgaWF5h4mhecfIQ8jXmQkiODhYeIiRYGjrG2PxgBARi3IhNMAbcCnwI5BAQpAZ8TIwK6vCQVDwUVKL+WzAANTA210g/VJ8OWxQefByQE4dZMzBoInwh4zrtgn2p725YNthUFTNRuGYB3AYGBHCEAACH5BAkJAB0ALAAAAAAgACAAhAQCBISChFRWVMzKzCQiJOTm5GxqbCwuLJSWlPz6/NTW1AwODJSSlGRmZCwqLOzu7HR2dDQ2NAQGBISGhFxaXNTS1CQmJOzq7GxubDQyNKSmpPz+/Nza3AAAAAAAAAAAAAXfYCeOZGmeaKqurHBdAiuP17Zdc0lMAVHWt9yI8LA9fCPB4xEjARoNSWpis01kBpshFahurqzsZosiGpErScMAUO0maKF8Tq/bTQCIQgFp30cQXhB1BHEcXhx0FgkJFiOHVYlzi42AgoRxeRx8fn+en3UABwedKgsBAwMBCygOCjYKDisLFV4VrCUAtVUKpSZdXl8mB8EbByQWcQPFAyYZxccdB7sV0cvBzbmvvG0LBV4FrFTBYCWuNhyyHRTFFB20trh4BxmdYl4YIqepq0IRxRE+IfDCAFQHARo0NGERAgAh+QQJCQAgACwAAAAAIAAgAIUEAgSEgoRMTkzMyswcHhzk5uR0cnQUFhRcXlwsKiz09vQMCgyMiozU1tQkJiR8fnxkZmT8/vwEBgSEhoRcWlzU0tQkIiT08vR0dnQcGhxkYmQ0MjT8+vwMDgyMjozc2twAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG+UCQcEgsGo/IpHLJXDweC6Z0+IhEHlOjRGIMWLHZoUZx0RQlAajxkFFKFFYFl5m5KNpIySU+X2bIBEoQZBBZGQdMElFhjI2Oj5AgHQEDAw8dQxYeDBaNHRVWVhWYCXsRFwmMXqFWEyAerB6MA6xWA6+xs7URt6VWqIwTu64gDh4eDp6goaORQ5OVAZjO1EgEGhB4RwAYDQ0YAEwIcBEKFEgYrBhLBORxgUYfrB9LELuF8fNDAAaVBuEg7NXCVyRdqHVCGLBiIIQAB1Yc4BXh9uEbwAXuyi2iQI7DuSwHdiFqCEGDtizLRFUDsaGAlQIbVoJYIEDAIiZBAAAh+QQJCQAbACwAAAAAIAAgAIQEAgSMioxcWlz08vQcHhysqqwMDgx8enwsKiykoqRkZmT8+vzEwsQMCgyUlpQkJiS0srQEBgSMjoxcXlz09vQkIiSsrqwUEhQ0MjRsamz8/vwAAAAAAAAAAAAAAAAAAAAF7+AmjmRpnmiqruz2PG0sIssCj4CQJAIgj4/abRNJaI6agu9kCAQaphdJgEQKUIFjgGWsahJYLdf7RTWfLKr3+jsBClVlG5Xb9eb4fImgUBBKDVB4ExRHFGwbGRQLGXMEhUgUfw2QC4IyCmSNDQtHlm2ZXgoiGQsUjW0EnUgLfyKBeYSeiHojfH61uS0GBisVEgEVLRcWRxAXKAgDRwMILMVIECgSVRIrBmS9JtRI1iMVBweuGxerSNolyszOIhjLGs0jEFXSKA8SEkMbcEgWIxfzNBxrw6AKgxIGkM05UOWALhERHJhysOThBgAVWYQAACH5BAkJABkALAAAAAAgACAAhAQGBIyKjERCRMzOzCwuLGRiZPz6/OTm5AwODLSytFRSVNTW1Dw6PHx6fAwKDJSSlERGRNTS1DQyNGxqbPz+/BQSFLy6vFRWVNza3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAXqYCaO5FgFwxBUZeu61ULNFMa+eBvQdJD/owFvFhkBBAwHsBQZUooZyWF2YOQkBNJu6ANMaQeli0AxSEwymi0DcUJeEgPlbEJFAghRe/h+Eeg/Dl9UYks5DF9VhksOAgKFi5GSSwh5kzgVCXIJNxknD5aSCTwJIw8zD5MITpanFKmSCHI8NxUPoJejNKWXLZkznL0vCJ3CxsckDpA/ChYJFzkTBgYTSxc80C4OswbLLhY8Fi/bMwYAJVgl4DTiL9LUJADrFuci1zTZLwD1IwU8BSQuWLCQb1EDHg2QiSDALYvCDAISJLDy8FIIACH5BAkJAB4ALAAAAAAgACAAhAQGBISGhFRSVNTW1CQiJKyqrGRmZOzu7CwuLIyOjGxubPz6/BQSFGRiZOTi5CwqLLy6vDQ2NIyKjFRWVCQmJKyurGxqbPT29DQyNJSSlHRydPz+/BQWFOzq7AAAAAAAAAXhoCeOJElYClGubOs117YtjWuvxCLLi3qbhc6h4FPsdorfiNI5dige43GT9AAkHUcCwCpMNxVP7tgTJY4J1uF7EBl0M8Ooueuo2SOCIkVa11kVX2E2EmgsFH4yBz4uAAkdHVstBAUHQ4xKmZqbnJ2bAhAQAiURGJ4eE0cTIxgzpp0QRxCsrp6xO7MjpaepO6unKxOhv8DFxsfIJBwaChw2DAkZDEocDjIOzi0ZMhlKUjIaLtsb3T8aR+EtDBkJ0yQUBQVQI9XX2ZsDMgMlyxr3mzE2XEgmotCGAARFIHiQ0FMIACH5BAkJABgALAAAAAAgACAAhAQCBISGhDw+POTi5CwuLLS2tPTy9BQSFJyenGRiZDQ2NIyOjLy+vPz6/BweHIyKjFRSVOzq7DQyNLy6vBQWFHRydDw6PPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXXICaOZHkcZaquIjVd10SxtFrAcFGrVhBYIwoON9uNAsOA6DCEFTEKBEKxEjQvAtELNxkpGrAGNfW4Plpb2QgxRKjKzfPoVGLj3CnLNUv7hscpSDhKOxJSgDwPP0ZGAACMjAQFDQYFBJA0BAZDBpeYGBQVFUU3TV2YFAMwAzNgTQ2PkBVDFRiuQ7CYszi1pUOnkKmrM5qcnqiiTwQTDQ2Wn9DR0tPUfRKQEBEREDQSFw3XRhEwEd3f4TvjF+XWKgJ8JNnb0QkwCdUlCzAL+CQODAwc9BtIMAQAOw==") !important}.icon-warning{background-repeat:no-repeat;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important}.toaster-icon{font-weight:normal;color:#fff}.toast-content{flex-grow:1;padding:15px 15px 15px 50px}.toast-title{font-weight:bold}.toast-message{word-wrap:break-word}.toast-message a,.toast-message label{color:#fff}.toast-message a:hover{color:#ccc;text-decoration:none}.toast-close-button,button.toast-close-button{align-self:flex-start;padding:3px;font-size:23px;line-height:90%;font-weight:bold;color:#fff;text-shadow:0 1px 0 #fff;opacity:.7;z-index:999;cursor:pointer;background:transparent;border:0}.toast-close-button:hover,.toast-close-button:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;border:none}.toast-close-button span{display:flex;flex-direction:column;align-items:flex-start}.toast-progress-bar{position:absolute;left:0;bottom:0;height:4px;background-color:#000;opacity:.4}.toast-container{position:fixed;z-index:999999;pointer-events:auto}.toast-container.toast-center,.toast-container.toast-top-center,.toast-container.toast-bottom-center{width:100%;pointer-events:none;left:0;right:0}.toast-container.toast-center>div,.toast-container.toast-top-center>div,.toast-container.toast-bottom-center>div{margin:6px auto;pointer-events:auto}.toast-container.toast-center>button,.toast-container.toast-top-center>button,.toast-container.toast-bottom-center>button{pointer-events:auto}.toast-container *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.toast-container>div{margin:0 0 6px;width:300px;border-radius:3px 3px 3px 3px;background-position:15px center;background-repeat:no-repeat;box-shadow:0 0 12px #999;color:#fff;opacity:.8}.toast-container>:hover{box-shadow:0 0 12px #000;opacity:1;cursor:pointer}.toast-container.toast-top-full-width>div,.toast-container.toast-bottom-full-width>div{width:96%;margin:auto}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-center{top:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-center{bottom:12px}.toast-bottom-left{bottom:12px;left:12px}.toast-center{top:45%}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:"FontAwesome";src:url(../fonts/fontawesome-webfont.eot);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0) format("embedded-opentype"),url(../fonts/fontawesome-webfont.woff2) format("woff2"),url(../fonts/fontawesome-webfont.woff) format("woff"),url(../fonts/fontawesome-webfont.ttf) format("truetype"),url(../fonts/fontawesome-webfont.svg#fontawesomeregular) format("svg");font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857em;text-align:center}.fa-ul{padding-left:0;margin-left:2.1428571429em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1428571429em;width:2.1428571429em;top:.1428571429em;text-align:center}.fa-li.fa-lg{left:-1.8571428571em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before{content:""}.fa-check-circle:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:""}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-signing:before,.fa-sign-language:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-vcard:before,.fa-address-card:before{content:""}.fa-vcard-o:before,.fa-address-card-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only,.table tr:not(:hover) td.table-list-options>.dropdown:not(.show) button:not(:focus):not(:active),.table tr:not(:hover) td.table-list-options>button:not(:focus):not(:active){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.swal2-popup.swal2-toast{flex-direction:column;align-items:stretch;width:auto;padding:1.25em;overflow-y:hidden;background:#fff;box-shadow:0 0 .625em #d9d9d9}.swal2-popup.swal2-toast .swal2-header{flex-direction:row;padding:0}.swal2-popup.swal2-toast .swal2-title{flex-grow:1;justify-content:flex-start;margin:0 .625em;font-size:1em}.swal2-popup.swal2-toast .swal2-loading{justify-content:center}.swal2-popup.swal2-toast .swal2-input{height:2em;margin:.3125em auto;font-size:1em}.swal2-popup.swal2-toast .swal2-validation-message{font-size:1em}.swal2-popup.swal2-toast .swal2-footer{margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-popup.swal2-toast .swal2-close{position:static;width:.8em;height:.8em;line-height:.8}.swal2-popup.swal2-toast .swal2-content{justify-content:flex-start;margin:0 .625em;padding:0;font-size:1em;text-align:initial}.swal2-popup.swal2-toast .swal2-html-container{padding:.625em 0 0}.swal2-popup.swal2-toast .swal2-html-container:empty{padding:0}.swal2-popup.swal2-toast .swal2-icon{width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-popup.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}@media all and (-ms-high-contrast: none),(-ms-high-contrast: active){.swal2-popup.swal2-toast .swal2-icon .swal2-icon-content{font-size:.25em}}.swal2-popup.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-popup.swal2-toast .swal2-actions{flex:1;flex-basis:auto !important;align-self:stretch;width:auto;height:2.2em;height:auto;margin:0 .3125em;margin-top:.3125em;padding:0}.swal2-popup.swal2-toast .swal2-styled{margin:.125em .3125em;padding:.3125em .625em;font-size:1em}.swal2-popup.swal2-toast .swal2-styled:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px rgba(100,150,200,.5)}.swal2-popup.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;transform:rotate(45deg);border-radius:50%}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-popup.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}.swal2-popup.swal2-toast.swal2-show{animation:swal2-toast-show .5s}.swal2-popup.swal2-toast.swal2-hide{animation:swal2-toast-hide .1s forwards}.swal2-container{display:flex;position:fixed;z-index:1060;top:0;right:0;bottom:0;left:0;flex-direction:row;align-items:center;justify-content:center;padding:.625em;overflow-x:hidden;transition:background-color .1s;-webkit-overflow-scrolling:touch}.swal2-container.swal2-backdrop-show,.swal2-container.swal2-noanimation{background:rgba(0,0,0,.4)}.swal2-container.swal2-backdrop-hide{background:transparent !important}.swal2-container.swal2-top{align-items:flex-start}.swal2-container.swal2-top-start,.swal2-container.swal2-top-left{align-items:flex-start;justify-content:flex-start}.swal2-container.swal2-top-end,.swal2-container.swal2-top-right{align-items:flex-start;justify-content:flex-end}.swal2-container.swal2-center{align-items:center}.swal2-container.swal2-center-start,.swal2-container.swal2-center-left{align-items:center;justify-content:flex-start}.swal2-container.swal2-center-end,.swal2-container.swal2-center-right{align-items:center;justify-content:flex-end}.swal2-container.swal2-bottom{align-items:flex-end}.swal2-container.swal2-bottom-start,.swal2-container.swal2-bottom-left{align-items:flex-end;justify-content:flex-start}.swal2-container.swal2-bottom-end,.swal2-container.swal2-bottom-right{align-items:flex-end;justify-content:flex-end}.swal2-container.swal2-bottom>:first-child,.swal2-container.swal2-bottom-start>:first-child,.swal2-container.swal2-bottom-left>:first-child,.swal2-container.swal2-bottom-end>:first-child,.swal2-container.swal2-bottom-right>:first-child{margin-top:auto}.swal2-container.swal2-grow-fullscreen>.swal2-modal{display:flex !important;flex:1;align-self:stretch;justify-content:center}.swal2-container.swal2-grow-row>.swal2-modal{display:flex !important;flex:1;align-content:center;justify-content:center}.swal2-container.swal2-grow-column{flex:1;flex-direction:column}.swal2-container.swal2-grow-column.swal2-top,.swal2-container.swal2-grow-column.swal2-center,.swal2-container.swal2-grow-column.swal2-bottom{align-items:center}.swal2-container.swal2-grow-column.swal2-top-start,.swal2-container.swal2-grow-column.swal2-center-start,.swal2-container.swal2-grow-column.swal2-bottom-start,.swal2-container.swal2-grow-column.swal2-top-left,.swal2-container.swal2-grow-column.swal2-center-left,.swal2-container.swal2-grow-column.swal2-bottom-left{align-items:flex-start}.swal2-container.swal2-grow-column.swal2-top-end,.swal2-container.swal2-grow-column.swal2-center-end,.swal2-container.swal2-grow-column.swal2-bottom-end,.swal2-container.swal2-grow-column.swal2-top-right,.swal2-container.swal2-grow-column.swal2-center-right,.swal2-container.swal2-grow-column.swal2-bottom-right{align-items:flex-end}.swal2-container.swal2-grow-column>.swal2-modal{display:flex !important;flex:1;align-content:center;justify-content:center}.swal2-container.swal2-no-transition{transition:none !important}.swal2-container:not(.swal2-top):not(.swal2-top-start):not(.swal2-top-end):not(.swal2-top-left):not(.swal2-top-right):not(.swal2-center-start):not(.swal2-center-end):not(.swal2-center-left):not(.swal2-center-right):not(.swal2-bottom):not(.swal2-bottom-start):not(.swal2-bottom-end):not(.swal2-bottom-left):not(.swal2-bottom-right):not(.swal2-grow-fullscreen)>.swal2-modal{margin:auto}@media all and (-ms-high-contrast: none),(-ms-high-contrast: active){.swal2-container .swal2-modal{margin:0 !important}}.swal2-popup{display:none;position:relative;box-sizing:border-box;flex-direction:column;justify-content:center;width:32em;max-width:100%;padding:1.25em;border:none;border-radius:5px;background:#fff;font-family:inherit;font-size:1rem}.swal2-popup:focus{outline:none}.swal2-popup.swal2-loading{overflow-y:hidden}.swal2-header{display:flex;flex-direction:column;align-items:center;padding:0 1.8em}.swal2-title{position:relative;max-width:100%;margin:0 0 .4em;padding:0;color:#595959;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word}.swal2-actions{display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:100%;margin:1.25em auto 0;padding:0}.swal2-actions:not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}.swal2-actions:not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1))}.swal2-actions:not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2))}.swal2-loader{display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 transparent #2778c4 transparent}.swal2-styled{margin:.3125em;padding:.625em 1.1em;box-shadow:none;font-weight:500}.swal2-styled:not([disabled]){cursor:pointer}.swal2-styled.swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:#2778c4;color:#fff;font-size:1em}.swal2-styled.swal2-deny{border:0;border-radius:.25em;background:initial;background-color:#d14529;color:#fff;font-size:1em}.swal2-styled.swal2-cancel{border:0;border-radius:.25em;background:initial;background-color:#757575;color:#fff;font-size:1em}.swal2-styled:focus{outline:none;box-shadow:0 0 0 3px rgba(100,150,200,.5)}.swal2-styled::-moz-focus-inner{border:0}.swal2-footer{justify-content:center;margin:1.25em 0 0;padding:1em 0 0;border-top:1px solid #eee;color:#545454;font-size:1em}.swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;height:.25em;overflow:hidden;border-bottom-right-radius:5px;border-bottom-left-radius:5px}.swal2-timer-progress-bar{width:100%;height:.25em;background:rgba(0,0,0,.2)}.swal2-image{max-width:100%;margin:1.25em auto}.swal2-close{position:absolute;z-index:2;top:0;right:0;align-items:center;justify-content:center;width:1.2em;height:1.2em;padding:0;overflow:hidden;transition:color .1s ease-out;border:none;border-radius:5px;background:transparent;color:#ccc;font-family:serif;font-size:2.5em;line-height:1.2;cursor:pointer}.swal2-close:hover{transform:none;background:transparent;color:#f27474}.swal2-close:focus{outline:none;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}.swal2-close::-moz-focus-inner{border:0}.swal2-content{z-index:1;justify-content:center;margin:0;padding:0 1.6em;color:#545454;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;word-wrap:break-word}.swal2-input,.swal2-file,.swal2-textarea,.swal2-select,.swal2-radio,.swal2-checkbox{margin:1em auto}.swal2-input,.swal2-file,.swal2-textarea{box-sizing:border-box;width:100%;transition:border-color .3s,box-shadow .3s;border:1px solid #d9d9d9;border-radius:.1875em;background:inherit;box-shadow:inset 0 1px 1px rgba(0,0,0,.06);color:inherit;font-size:1.125em}.swal2-input.swal2-inputerror,.swal2-file.swal2-inputerror,.swal2-textarea.swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}.swal2-input:focus,.swal2-file:focus,.swal2-textarea:focus{border:1px solid #b4dbed;outline:none;box-shadow:0 0 0 3px rgba(100,150,200,.5)}.swal2-input::placeholder,.swal2-file::placeholder,.swal2-textarea::placeholder{color:#ccc}.swal2-range{margin:1em auto;background:#fff}.swal2-range input{width:80%}.swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}.swal2-range input,.swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}.swal2-input{height:2.625em;padding:0 .75em}.swal2-input[type=number]{max-width:10em}.swal2-file{background:inherit;font-size:1.125em}.swal2-textarea{height:6.75em;padding:.75em}.swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:inherit;color:inherit;font-size:1.125em}.swal2-radio,.swal2-checkbox{align-items:center;justify-content:center;background:#fff;color:inherit}.swal2-radio label,.swal2-checkbox label{margin:0 .6em;font-size:1.125em}.swal2-radio input,.swal2-checkbox input{flex-shrink:0;margin:0 .4em}.swal2-input-label{display:flex;justify-content:center;margin:1em auto}.swal2-validation-message{align-items:center;justify-content:center;margin:0 -2.7em;padding:.625em;overflow:hidden;background:#f0f0f0;color:#666;font-size:1em;font-weight:300}.swal2-validation-message::before{content:"!";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}.swal2-icon{position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:1.25em auto 1.875em;border:0.25em solid transparent;border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}.swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}.swal2-icon.swal2-error{border-color:#f27474;color:#f27474}.swal2-icon.swal2-error .swal2-x-mark{position:relative;flex-grow:1}.swal2-icon.swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}.swal2-icon.swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}.swal2-icon.swal2-warning{border-color:#facea8;color:#f8bb86}.swal2-icon.swal2-info{border-color:#9de0f6;color:#3fc3ee}.swal2-icon.swal2-question{border-color:#c9dae1;color:#87adbd}.swal2-icon.swal2-success{border-color:#a5dc86;color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;transform:rotate(45deg);border-radius:50%}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}.swal2-icon.swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}.swal2-icon.swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}.swal2-icon.swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}.swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}.swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:0 0 1.25em;padding:0;background:inherit;font-weight:600}.swal2-progress-steps li{display:inline-block;position:relative}.swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:#add8e6;color:#fff}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:#add8e6}.swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}[class^=swal2]{-webkit-tap-highlight-color:transparent}.swal2-show{animation:swal2-show .3s}.swal2-hide{animation:swal2-hide .15s forwards}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{right:auto;left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}@supports(-ms-accelerator: true){.swal2-range input{width:100% !important}.swal2-range output{display:none}}@media all and (-ms-high-contrast: none),(-ms-high-contrast: active){.swal2-range input{width:100% !important}.swal2-range output{display:none}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}@keyframes swal2-show{0%{transform:scale(0.7)}45%{transform:scale(1.05)}80%{transform:scale(0.95)}100%{transform:scale(1)}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(0.5);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{top:auto;right:auto;bottom:auto;left:auto;max-width:calc(100% - 0.625em * 2);background-color:transparent !important}body.swal2-no-backdrop .swal2-container>.swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}body.swal2-no-backdrop .swal2-container.swal2-top{top:0;left:50%;transform:translateX(-50%)}body.swal2-no-backdrop .swal2-container.swal2-top-start,body.swal2-no-backdrop .swal2-container.swal2-top-left{top:0;left:0}body.swal2-no-backdrop .swal2-container.swal2-top-end,body.swal2-no-backdrop .swal2-container.swal2-top-right{top:0;right:0}body.swal2-no-backdrop .swal2-container.swal2-center{top:50%;left:50%;transform:translate(-50%, -50%)}body.swal2-no-backdrop .swal2-container.swal2-center-start,body.swal2-no-backdrop .swal2-container.swal2-center-left{top:50%;left:0;transform:translateY(-50%)}body.swal2-no-backdrop .swal2-container.swal2-center-end,body.swal2-no-backdrop .swal2-container.swal2-center-right{top:50%;right:0;transform:translateY(-50%)}body.swal2-no-backdrop .swal2-container.swal2-bottom{bottom:0;left:50%;transform:translateX(-50%)}body.swal2-no-backdrop .swal2-container.swal2-bottom-start,body.swal2-no-backdrop .swal2-container.swal2-bottom-left{bottom:0;left:0}body.swal2-no-backdrop .swal2-container.swal2-bottom-end,body.swal2-no-backdrop .swal2-container.swal2-bottom-right{right:0;bottom:0}@media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:static !important}}body.swal2-toast-shown .swal2-container{background-color:transparent}body.swal2-toast-shown .swal2-container.swal2-top{top:0;right:auto;bottom:auto;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{top:0;right:0;bottom:auto;left:auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{top:0;right:auto;bottom:auto;left:0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{top:50%;right:auto;bottom:auto;left:0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{top:50%;right:auto;bottom:auto;left:50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{top:50%;right:0;bottom:auto;left:auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{top:auto;right:auto;bottom:0;left:0}body.swal2-toast-shown .swal2-container.swal2-bottom{top:auto;right:auto;bottom:0;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{top:auto;right:0;bottom:0;left:auto}html{font-size:14px}body{min-width:1010px}@media(prefers-color-scheme: dark){body.layout_frontend{background-color:#1f242e}}@media(prefers-color-scheme: light){body.layout_frontend{background-color:#fff}}html.theme_light body.layout_frontend{background-color:#ecf0f5;color:#333}html.theme_dark body.layout_frontend{background-color:#1f242e;color:#fff}html.theme_light body{background-color:#fff;color:#333}html.theme_dark body{background-color:#1f242e;color:#bac0ce}body.full-width:not(.layout_frontend) .container{min-width:980px;width:90%}.container{margin:0 auto;max-width:none !important;padding:0;width:980px}.page-header,.secondary-header{margin-bottom:.5rem;padding-bottom:.6rem}html.theme_light .page-header,html.theme_light .secondary-header{border-bottom:1px solid #ced4da}html.theme_dark .page-header,html.theme_dark .secondary-header{border-bottom:1px solid #4c525f}.page-header:not(.text-danger) h1,.page-header:not(.text-danger) h2,.page-header:not(.text-danger) h3,.page-header:not(.text-danger) h4,.secondary-header:not(.text-danger) h1,.secondary-header:not(.text-danger) h2,.secondary-header:not(.text-danger) h3,.secondary-header:not(.text-danger) h4{margin:0}html.theme_light .page-header:not(.text-danger) h1,html.theme_light .page-header:not(.text-danger) h2,html.theme_light .page-header:not(.text-danger) h3,html.theme_light .page-header:not(.text-danger) h4,html.theme_light .secondary-header:not(.text-danger) h1,html.theme_light .secondary-header:not(.text-danger) h2,html.theme_light .secondary-header:not(.text-danger) h3,html.theme_light .secondary-header:not(.text-danger) h4{color:#333}html.theme_dark .page-header:not(.text-danger) h1,html.theme_dark .page-header:not(.text-danger) h2,html.theme_dark .page-header:not(.text-danger) h3,html.theme_dark .page-header:not(.text-danger) h4,html.theme_dark .secondary-header:not(.text-danger) h1,html.theme_dark .secondary-header:not(.text-danger) h2,html.theme_dark .secondary-header:not(.text-danger) h3,html.theme_dark .secondary-header:not(.text-danger) h4{color:#fff}.secondary-header,.spaced-header{margin-top:4rem}img.logo{display:block;height:43px;margin:0 auto;width:284px}html.theme_light img.logo.logo-themed{content:url(../images/logo-dark@2x.png)}html.theme_dark img.logo.logo-themed{content:url(../images/logo-white@2x.png)}.page-content{margin-top:20px}.footer{margin-top:40px;padding:40px 0 40px 0}html.theme_light .footer{border-top:1px solid #ced4da}html.theme_dark .footer{border-top:1px solid #4c525f}html.theme_light hr,html.theme_light .dropdown-divider{border-top:1px solid rgba(0,0,0,.1)}html.theme_dark hr,html.theme_dark .dropdown-divider{border-top:1px solid #4c525f}.min-height-fix{min-height:1px}.overflow-hidden{overflow:hidden}.cursor-move{cursor:move !important}html.theme_light h1,html.theme_light h2,html.theme_light h3,html.theme_light h4,html.theme_light h5{color:#333}html.theme_dark h1,html.theme_dark h2,html.theme_dark h3,html.theme_dark h4,html.theme_dark h5{color:#fff}h1 small,h2 small,h3 small,h4 small,h5 small{font-size:80%}html.theme_light h1.spaced-header,html.theme_light h2.spaced-header,html.theme_light h3.spaced-header,html.theme_light h4.spaced-header,html.theme_light h5.spaced-header{color:#333}html.theme_dark h1.spaced-header,html.theme_dark h2.spaced-header,html.theme_dark h3.spaced-header,html.theme_dark h4.spaced-header,html.theme_dark h5.spaced-header{color:#fff}html.theme_light a{color:#175ddc}html.theme_dark a{color:#6a99f0}html.theme_light a.text-body{color:#333 !important;font-weight:400}html.theme_dark a.text-body{color:#fff !important;font-weight:600}html.theme_light code{color:#e83e8c}html.theme_dark code{color:#e83e8c}.fa-icon-above-input{height:1.5em}.text-lg{font-size:1.15rem}.text-strike{text-decoration:line-through}.font-weight-semibold{font-weight:600}html.theme_light .btn:focus,.swal2-popup .swal2-actions html.theme_light button:focus,html.theme_light .swal2-popup .swal2-actions button:focus,html.theme_light .btn.focus,.swal2-popup .swal2-actions html.theme_light button.focus,html.theme_light .swal2-popup .swal2-actions button.focus,html.theme_light .form-control:focus{box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}html.theme_dark .btn:focus,.swal2-popup .swal2-actions html.theme_dark button:focus,html.theme_dark .swal2-popup .swal2-actions button:focus,html.theme_dark .btn.focus,.swal2-popup .swal2-actions html.theme_dark button.focus,html.theme_dark .swal2-popup .swal2-actions button.focus,html.theme_dark .form-control:focus{box-shadow:0 0 0 .2rem rgba(106,153,240,.25)}html.theme_light .bg-primary{background-color:#175ddc}html.theme_dark .bg-primary{background-color:#6a99f0}html.theme_light .bg-light{background-color:#f8f9fa !important}html.theme_dark .bg-light{background-color:#1f242e !important}html.theme_light .bg-success{background-color:#00a65a !important;color:#fff !important}html.theme_dark .bg-success{background-color:#52e07c !important;color:#1f242e !important}html.theme_light .bg-warning{background-color:#bf7e16 !important;color:#fff !important}html.theme_dark .bg-warning{background-color:#ffeb66 !important;color:#1f242e !important}html.theme_light .bg-error,html.theme_light .bg-danger{background-color:#dd4b39 !important;color:#fff !important}html.theme_dark .bg-error,html.theme_dark .bg-danger{background-color:#ff8d85 !important;color:#1f242e !important}html.theme_light .bg-info{background-color:#343a40 !important;color:#fff !important}html.theme_dark .bg-info{background-color:#a4b0c6 !important;color:#1f242e !important}html.theme_light .border-primary{border-color:#175ddc !important}html.theme_dark .border-primary{border-color:#6a99f0 !important}html.theme_light .border-warning{border-color:#bf7e16 !important}html.theme_dark .border-warning{border-color:#ffeb66 !important}html.theme_light .border-danger{border-color:#dd4b39 !important}html.theme_dark .border-danger{border-color:#ff8d85 !important}html.theme_light .border-info{border-color:#343a40 !important}html.theme_dark .border-info{border-color:#a4b0c6 !important}html.theme_light .text-success{color:#00a65a !important}html.theme_dark .text-success{color:#52e07c !important}html.theme_light .text-success>h1,html.theme_light .text-success h2,html.theme_light .text-success h3,html.theme_light .text-success h4{color:#00a65a !important}html.theme_dark .text-success>h1,html.theme_dark .text-success h2,html.theme_dark .text-success h3,html.theme_dark .text-success h4{color:#52e07c !important}html.theme_light .text-warning{color:#bf7e16 !important}html.theme_dark .text-warning{color:#ffeb66 !important}html.theme_light .text-warning>h1,html.theme_light .text-warning h2,html.theme_light .text-warning h3,html.theme_light .text-warning h4{color:#bf7e16 !important}html.theme_dark .text-warning>h1,html.theme_dark .text-warning h2,html.theme_dark .text-warning h3,html.theme_dark .text-warning h4{color:#ffeb66 !important}html.theme_light .text-danger:not(.dropdown-item){color:#dd4b39 !important}html.theme_dark .text-danger:not(.dropdown-item){color:#ff8d85 !important}html.theme_light .text-danger:not(.dropdown-item)>h1,html.theme_light .text-danger:not(.dropdown-item) h2,html.theme_light .text-danger:not(.dropdown-item) h3,html.theme_light .text-danger:not(.dropdown-item) h4{color:#dd4b39 !important}html.theme_dark .text-danger:not(.dropdown-item)>h1,html.theme_dark .text-danger:not(.dropdown-item) h2,html.theme_dark .text-danger:not(.dropdown-item) h3,html.theme_dark .text-danger:not(.dropdown-item) h4{color:#ff8d85 !important}html.theme_light .text-muted,html.theme_light .card-header small,.card-header html.theme_light small,html.theme_light .modal-header small,.modal-header html.theme_light small{color:#6c757d !important}html.theme_dark .text-muted,html.theme_dark .card-header small,.card-header html.theme_dark small,html.theme_dark .modal-header small,.modal-header html.theme_dark small{color:#bac0ce !important}html.theme_light .btn-primary,html.theme_light .swal2-confirm{background-color:#175ddc;border-color:#175ddc;color:#fff}html.theme_dark .btn-primary,html.theme_dark .swal2-confirm{background-color:#6a99f0;border-color:#6a99f0;color:#1f242e}html.theme_light .btn-primary:hover:not(:disabled),html.theme_light .btn-primary:active:not(:disabled),html.theme_light .swal2-confirm:hover:not(:disabled),html.theme_light .swal2-confirm:active:not(:disabled){background-color:#134eb9;border-color:#1249ae;color:#fff}html.theme_dark .btn-primary:hover:not(:disabled),html.theme_dark .btn-primary:active:not(:disabled),html.theme_dark .swal2-confirm:hover:not(:disabled),html.theme_dark .swal2-confirm:active:not(:disabled){background-color:#b4ccf9;border-color:#b4ccf9;color:#1f242e}.btn-primary:disabled,.swal2-confirm:disabled{opacity:.65}html.theme_light .btn-outline-primary{background-color:#fbfbfb;border-color:#ced4da;color:#175ddc}html.theme_dark .btn-outline-primary{background-color:#6a99f0;border-color:#6a99f0;color:#1f242e}html.theme_light .btn-outline-primary:hover:not(:disabled),html.theme_light .btn-outline-primary:active{background-color:#175ddc;border-color:#175ddc;color:#fff}html.theme_dark .btn-outline-primary:hover:not(:disabled),html.theme_dark .btn-outline-primary:active{background-color:#b4ccf9;border-color:#b4ccf9;color:#1f242e}html.theme_light .btn-secondary,html.theme_light .swal2-cancel{background-color:#ced4da;border-color:#ced4da;color:#212529}html.theme_dark .btn-secondary,html.theme_dark .swal2-cancel{background-color:transparent;border-color:#bac0ce;color:#fff}html.theme_light .btn-secondary:hover:not(:disabled),html.theme_light .btn-secondary:active:not(:disabled),html.theme_light .swal2-cancel:hover:not(:disabled),html.theme_light .swal2-cancel:active:not(:disabled){background-color:#b8c1ca;border-color:#b1bbc4;color:#212529}html.theme_dark .btn-secondary:hover:not(:disabled),html.theme_dark .btn-secondary:active:not(:disabled),html.theme_dark .swal2-cancel:hover:not(:disabled),html.theme_dark .swal2-cancel:active:not(:disabled){background-color:transparent;border-color:#8d94a5;color:#8d94a5}.btn-secondary:disabled,.swal2-cancel:disabled{opacity:.65}html.theme_light .btn-secondary:focus,html.theme_light .btn-secondary.focus,html.theme_light .swal2-cancel:focus,html.theme_light .swal2-cancel.focus{box-shadow:0 0 0 .2rem rgba(58,117,225,.5)}html.theme_dark .btn-secondary:focus,html.theme_dark .btn-secondary.focus,html.theme_dark .swal2-cancel:focus,html.theme_dark .swal2-cancel.focus{box-shadow:0 0 0 .2rem rgba(128,168,242,.5)}html.theme_light .btn-outline-secondary{background-color:#fbfbfb;border-color:#ced4da;color:#6c757d}html.theme_dark .btn-outline-secondary{background-color:transparent;border-color:#bac0ce;color:#fff}html.theme_light .btn-outline-secondary:hover:not(:disabled),html.theme_light .btn-outline-secondary:active{background-color:#ced4da;border-color:#ced4da;color:#333}html.theme_dark .btn-outline-secondary:hover:not(:disabled),html.theme_dark .btn-outline-secondary:active{background-color:transparent;border-color:#8d94a5;color:#8d94a5}html.theme_light .show>.btn-outline-secondary.dropdown-toggle,html.theme_light .show>.btn-outline-secondary:focus{background-color:#fbfbfb;border-color:#ced4da;color:#6c757d}html.theme_dark .show>.btn-outline-secondary.dropdown-toggle,html.theme_dark .show>.btn-outline-secondary:focus{background-color:transparent;border-color:#bac0ce;color:#fff}html.theme_light .show>.btn-outline-secondary:hover{background-color:#ced4da;border-color:#ced4da;color:#333}html.theme_dark .show>.btn-outline-secondary:hover{background-color:transparent;border-color:#8d94a5;color:#8d94a5}html.theme_light .btn-danger,html.theme_light .swal2-deny{background-color:#dd4b39;border-color:#dd4b39;color:#fff}html.theme_dark .btn-danger,html.theme_dark .swal2-deny{background-color:#ff8d85;border-color:#ff8d85;color:#1f242e}html.theme_light .btn-danger:hover:not(:disabled),html.theme_light .btn-danger:active:not(:disabled),html.theme_light .swal2-deny:hover:not(:disabled),html.theme_light .swal2-deny:active:not(:disabled){background-color:#c43421;border-color:#c43421;color:#fff}html.theme_dark .btn-danger:hover:not(:disabled),html.theme_dark .btn-danger:active:not(:disabled),html.theme_dark .swal2-deny:hover:not(:disabled),html.theme_dark .swal2-deny:active:not(:disabled){background-color:#ffbfbb;border-color:#ffbfbb;color:#1f242e}html.theme_light .btn-outline-danger{background-color:#fbfbfb;border-color:#ced4da;color:#dd4b39}html.theme_dark .btn-outline-danger{background-color:#ff8d85;border-color:#ff8d85;color:#1f242e}html.theme_light .btn-outline-danger:hover:not(:disabled),html.theme_light .btn-outline-danger:active{background-color:#dd4b39;border-color:#dd4b39;color:#fff}html.theme_dark .btn-outline-danger:hover:not(:disabled),html.theme_dark .btn-outline-danger:active{background-color:#ffbfbb;border-color:#ffbfbb;color:#1f242e}.btn-link:focus,.btn-link.focus{outline-color:-webkit-focus-ring-color;outline-offset:1px;outline-style:auto;outline-width:1px}html.theme_dark .btn-link:not(.text-danger):not(.cursor-move){color:#fff}html.theme_dark .btn-link:hover:not(.text-danger):not(.cursor-move){color:#bac0ce}.btn-submit{position:relative}.btn-submit .fa-spinner{align-items:center;bottom:0;display:none;justify-content:center;left:0;position:absolute;right:0;top:0}.btn-submit:disabled:not(.manual) .fa-spinner,.btn-submit.loading .fa-spinner{display:flex}.btn-submit:disabled:not(.manual) span,.btn-submit.loading span{visibility:hidden}html.theme_light .badge-primary{background-color:#175ddc;color:#fff}html.theme_dark .badge-primary{background-color:#6a99f0;color:#1f242e}html.theme_light .badge-primary:hover{background-color:#134eb9;color:#fff}html.theme_dark .badge-primary:hover{background-color:#b4ccf9;color:#1f242e}html.theme_light .badge-secondary{background-color:#ced4da;color:#212529}html.theme_dark .badge-secondary{background-color:#8d94a5;color:#1f242e}html.theme_light .badge-info{background-color:#555;color:#fff}html.theme_dark .badge-info{background-color:#a4b0c6;color:#1f242e}html.theme_light .badge-danger{background-color:#dd4b39;color:#fff}html.theme_dark .badge-danger{background-color:#ff8d85;color:#1f242e}html.theme_light .badge-warning{background-color:#bf7e16;color:#fff}html.theme_dark .badge-warning{background-color:#ffeb66;color:#1f242e}html.theme_light .badge-success{background-color:#00a65a;color:#fff}html.theme_dark .badge-success{background-color:#52e07c;color:#1f242e}.callout{border-left-width:5px !important;border-radius:calc(0.25rem - 1px);margin-bottom:1rem;padding:.75rem 1.25rem}html.theme_light .callout{background-color:#fafafa;border:1px solid #ced4da;color:#212529}html.theme_dark .callout{background-color:#3c424e;border:1px solid #4c525f;color:#fff}.callout .callout-heading{margin-top:0}.callout h3.callout-heading{font-weight:bold;text-transform:uppercase}html.theme_light .callout.callout-primary{border-left-color:#175ddc}html.theme_dark .callout.callout-primary{border-left-color:#6a99f0}html.theme_light .callout.callout-primary .callout-heading{color:#175ddc}html.theme_dark .callout.callout-primary .callout-heading{color:#6a99f0}html.theme_light .callout.callout-info{border-left-color:#343a40}html.theme_dark .callout.callout-info{border-left-color:#a4b0c6}html.theme_light .callout.callout-info .callout-heading{color:#343a40}html.theme_dark .callout.callout-info .callout-heading{color:#a4b0c6}html.theme_light .callout.callout-danger{border-left-color:#dd4b39}html.theme_dark .callout.callout-danger{border-left-color:#ff8d85}html.theme_light .callout.callout-danger .callout-heading{color:#dd4b39}html.theme_dark .callout.callout-danger .callout-heading{color:#ff8d85}html.theme_light .callout.callout-success{border-left-color:#00a65a}html.theme_dark .callout.callout-success{border-left-color:#52e07c}html.theme_light .callout.callout-success .callout-heading{color:#00a65a}html.theme_dark .callout.callout-success .callout-heading{color:#52e07c}html.theme_light .callout.callout-warning{border-left-color:#bf7e16}html.theme_dark .callout.callout-warning{border-left-color:#ffeb66}html.theme_light .callout.callout-warning .callout-heading{color:#bf7e16}html.theme_dark .callout.callout-warning .callout-heading{color:#ffeb66}.callout .enforced-policy-options ul{margin-bottom:0px}html.theme_light .card{background-color:#fff;border-color:#ced4da;color:#333}html.theme_dark .card{background-color:#2f343d;border-color:#4c525f;color:#bac0ce}html.theme_light .card.text-danger.text-danger>.card-body{color:#dd4b39}html.theme_dark .card.text-danger.text-danger>.card-body{color:#ff8d85}.card-header,.modal-header{font-weight:bold;text-transform:uppercase}.card-header small,.modal-header small{font-weight:normal;text-transform:none}html.theme_light .card-header{background-color:rgba(0,0,0,.03);color:#333}html.theme_dark .card-header{background-color:#4c525f;color:#fff}html.theme_light .card-header a:hover:not(.badge){color:#104097}html.theme_dark .card-header a:hover:not(.badge){color:#b4ccf9}.card-body-header{font-size:1.15rem}.card ul.fa-ul.card-ul{margin-left:1.9em}.card ul.fa-ul.card-ul li{word-break:break-all}.card ul.fa-ul.card-ul .fa-li{top:4px}.card ul.fa-ul.card-ul.carets{margin-left:1.1em}.card ul.fa-ul.card-ul.carets .fa-li{left:-17px;width:1.1em}.card ul.fa-ul.card-ul ul.carets{margin-left:.85em}.card-org-plans h2{font-size:1.15rem}html.theme_light .card-body:not(.bg-light>.card-body){background-color:#fff;color:#333}html.theme_dark .card-body:not(.bg-light>.card-body){background-color:#2f343d;color:#bac0ce}html.theme_light .card-body:not(.bg-light>.card-body).card-body a:not(li a){font-weight:400}html.theme_dark .card-body:not(.bg-light>.card-body).card-body a:not(li a){font-weight:600}::-ms-reveal{display:none}html.theme_light ::placeholder{color:#b6b8b8}html.theme_dark ::placeholder{color:#bac0ce}input:required,select:required,textarea:required{box-shadow:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:-cancel-button}label:not(.form-check-label):not(.btn),label.bold{font-weight:600}html.theme_light label:not(.form-check-label):not(.btn),html.theme_light label.bold{color:#333}html.theme_dark label:not(.form-check-label):not(.btn),html.theme_dark label.bold{color:#fff}html.theme_light label.form-check-label,html.theme_light .form-control-file{color:#333}html.theme_dark label.form-check-label,html.theme_dark .form-control-file{color:#fff}.form-check-block .form-check-label{font-weight:600}.form-check-block .form-check-label>small{display:block;font-weight:normal}html.theme_light .form-check-block .form-check-label>small{color:#6c757d}html.theme_dark .form-check-block .form-check-label>small{color:#bac0ce}.form-check-block .form-check-label>span{display:block;font-weight:normal}.form-inline input[type=datetime-local]{width:200px}html.theme_light .form-control{background-color:#fbfbfb;border-color:#ced4da;color:#465057}html.theme_dark .form-control{background-color:transparent;border-color:#bac0ce;color:#fff}html.theme_light .form-control:disabled,html.theme_light .form-control[readonly]{background-color:#e0e0e0;color:#6c757d}html.theme_dark .form-control:disabled,html.theme_dark .form-control[readonly]{background-color:#3c424e;color:#bac0ce}input[type=radio],input[type=checkbox]{cursor:pointer}.form-control.stripe-form-control{padding-top:.55rem}.form-control.stripe-form-control.is-focused{outline:0}html.theme_light .form-control.stripe-form-control.is-focused{background-color:#fbfbfb;border-color:#ced4da;box-shadow:0 0 0 .2rem rgba(58,117,225,.5);color:#465057}html.theme_dark .form-control.stripe-form-control.is-focused{background-color:transparent;border-color:#bac0ce;box-shadow:0 0 0 .2rem rgba(128,168,242,.5);color:#fff}.form-control.stripe-form-control.is-focused.is-invalid{opacity:.75}html.theme_light .form-control.stripe-form-control.is-focused.is-invalid{box-shadow:0 0 0 .2rem #dd4b39}html.theme_dark .form-control.stripe-form-control.is-focused.is-invalid{box-shadow:0 0 0 .2rem #ff8d85}html.theme_light .form-control.stripe-form-control.is-invalid{border-color:#dd4b39}html.theme_dark .form-control.stripe-form-control.is-invalid{border-color:#ff8d85}html.theme_light .dropdown-menu,html.theme_light .dropdown-item{background-color:#fff;color:#333}html.theme_dark .dropdown-menu,html.theme_dark .dropdown-item{background-color:#2f343d;color:#fff}html.theme_light .dropdown-item{color:#333}html.theme_dark .dropdown-item{color:#fff}html.theme_light .dropdown-item.text-danger{color:#dd4b39 !important}html.theme_dark .dropdown-item.text-danger{color:#ff8d85 !important}html.theme_light .dropdown-item:hover{background-color:rgba(0,0,0,.06)}html.theme_dark .dropdown-item:hover{background-color:rgba(255,255,255,.03)}.dropdown-item:active{background-color:rgba(0,0,0,.1) !important}.dropdown-menu button{cursor:pointer}html.theme_light .dropdown-menu{border:1px solid rgba(0,0,0,.125)}html.theme_dark .dropdown-menu{border:1px solid #4c525f}.list-group-item:focus,.list-group-item.focus{z-index:100}html.theme_light .list-group-item{background-color:#fff;border-color:rgba(0,0,0,.125);color:#333}html.theme_dark .list-group-item{background-color:#2f343d;border-color:#4c525f;color:#bac0ce}.list-group-item>.two-factor-content{justify-content:center;flex-direction:row;display:flex}.list-group-item>.two-factor-content>.text-col{flex-direction:column;flex:1}.list-group-item>.two-factor-content>.logo-col{min-width:100px;margin-right:20px;display:flex;align-items:center;justify-content:center}.list-group-item>.two-factor-content>.logo-col img{height:fit-content}.list-group-item>.two-factor-content>.btn-col{width:85px;display:flex;align-items:center;justify-content:center}.list-group-item.active{font-weight:bold !important;padding-left:calc(1.25rem - 3px)}html.theme_light .list-group-item.active{border-color:#ced4da;border-left:3px solid #175ddc;color:#333}html.theme_dark .list-group-item.active{border-color:#4c525f;border-left:3px solid #6a99f0;color:#6a99f0}html.theme_light ::-webkit-calendar-picker-indicator,html.theme_light input::-webkit-caps-lock-indicator,html.theme_light input::-webkit-credentials-auto-fill-button{filter:invert(0)}html.theme_dark ::-webkit-calendar-picker-indicator,html.theme_dark input::-webkit-caps-lock-indicator,html.theme_dark input::-webkit-credentials-auto-fill-button{filter:invert(1)}.navbar{padding-left:0;padding-right:0}html.theme_light .navbar{background-color:#175ddc}html.theme_dark .navbar{background-color:#2f343d}html.theme_light .navbar.nav-background-alt{background-color:#1a3b66}html.theme_dark .navbar.nav-background-alt{background-color:#2f343d}.navbar .dropdown-menu{max-width:300px;min-width:200px}.navbar .dropdown-menu .dropdown-item-text{line-height:1.3}html.theme_light .navbar .dropdown-menu .dropdown-item-text{color:#333}html.theme_dark .navbar .dropdown-menu .dropdown-item-text{color:#fff}.navbar .dropdown-menu .dropdown-item-text span,.navbar .dropdown-menu .dropdown-item-text small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}html.theme_light .navbar .dropdown-menu .dropdown-item-text span.text-muted,html.theme_light .navbar .dropdown-menu .dropdown-item-text small.text-muted,html.theme_light .navbar .dropdown-menu .dropdown-item-text .card-header small,.card-header html.theme_light .navbar .dropdown-menu .dropdown-item-text small,html.theme_light .navbar .dropdown-menu .dropdown-item-text .modal-header small,.modal-header html.theme_light .navbar .dropdown-menu .dropdown-item-text small{color:#6c757d !important}html.theme_dark .navbar .dropdown-menu .dropdown-item-text span.text-muted,html.theme_dark .navbar .dropdown-menu .dropdown-item-text small.text-muted,html.theme_dark .navbar .dropdown-menu .dropdown-item-text .card-header small,.card-header html.theme_dark .navbar .dropdown-menu .dropdown-item-text small,html.theme_dark .navbar .dropdown-menu .dropdown-item-text .modal-header small,.modal-header html.theme_dark .navbar .dropdown-menu .dropdown-item-text small{color:#bec6cf !important}html.theme_light .navbar .nav-item>.nav-link{font-weight:600}html.theme_dark .navbar .nav-item>.nav-link{font-weight:400}html.theme_light .navbar .nav-item.active>.nav-link{font-weight:600}html.theme_dark .navbar .nav-item.active>.nav-link{font-weight:600}.navbar-brand{margin-bottom:-20px;margin-top:-20px}html.theme_light .nav-tabs .nav-link.active{background:#fff;border-color:#ced4da}html.theme_dark .nav-tabs .nav-link.active{background:#1f242e;border-color:#4c525f}.org-nav{height:100px;min-height:100px}html.theme_light .org-nav{background-color:#fbfbfb;border-bottom:1px solid #ced4da;color:#333}html.theme_dark .org-nav{background-color:#161c26;border-bottom:1px solid #4c525f;color:#bac0ce}.org-nav .container{height:100%}.org-nav .nav-tabs{border-bottom:none}.org-nav .nav-tabs a:not(.active){border-color:transparent}html.theme_light .org-nav .nav-tabs a:not(.active){color:#333}html.theme_dark .org-nav .nav-tabs a:not(.active){color:#bac0ce}.org-nav .nav-tabs a.active{font-weight:bold;padding-top:calc(0.5rem - 2px)}html.theme_light .org-nav .nav-tabs a.active{border-top:3px solid #175ddc;color:#175ddc}html.theme_dark .org-nav .nav-tabs a.active{border-top:3px solid #6a99f0;color:#6a99f0}html.theme_light .org-nav .nav-tabs a.disabled{color:#6c757d}html.theme_dark .org-nav .nav-tabs a.disabled{color:#bac0ce}.org-nav .org-name{line-height:1}.org-nav .org-name span{display:block;font-size:1.15rem}html.theme_light .org-nav .org-name span{color:#333}html.theme_dark .org-nav .org-name span{color:#fff}.modal-content{border:none;border-radius:none}html.theme_light .modal-content{background-color:#fff}html.theme_dark .modal-content{background-color:#1f242e}.modal-dialog{border:1px solid rgba(0,0,0,.2);border-radius:.3rem;width:500px}.modal-sm{width:300px}.modal-lg{width:800px}html.theme_light .modal-header{background-color:#fff;border-bottom:1px solid #ced4da;color:#333}html.theme_dark .modal-header{background-color:#2f343d;border-bottom:1px solid #4c525f;color:#bac0ce}html.theme_light .modal-body{background-color:#fff;color:#333}html.theme_dark .modal-body{background-color:#2f343d;color:#bac0ce}.modal-body h3,.modal-body .section-header>*{font-weight:normal;text-transform:uppercase}html.theme_light .modal-body h3,html.theme_light .modal-body .section-header>*{color:#6c757d}html.theme_dark .modal-body h3,html.theme_dark .modal-body .section-header>*{color:#bac0ce}.modal .list-group-flush :first-child{border-top:none}.modal .list-group-flush :last-child{border-bottom:none}.modal .list-group-flush-2fa div{border-left:none;border-right:none}.modal .list-group-flush-2fa div:first-child{border-top:none}.modal .list-group-flush-2fa div:last-child{border-bottom:none}.modal-footer{border-radius:.3rem .3rem 0 0;justify-content:flex-start}html.theme_light .modal-footer{background-color:#fbfbfb;border-top:1px solid #ced4da}html.theme_dark .modal-footer{background-color:#4c525f;border-top:1px solid #4c525f}html.theme_light .close{color:#333}html.theme_dark .close{color:#bac0ce}html.theme_light #totpImage{filter:invert(0) grayscale(0)}html.theme_dark #totpImage{filter:invert(1) grayscale(1)}.totp .totp-code{font-size:1.2rem}.totp .totp-countdown{display:block;margin:3px 3px 0 0;user-select:none}.totp .totp-countdown .totp-sec{font-size:.85em;line-height:32px;position:absolute;text-align:center;width:32px}.totp .totp-countdown svg{height:32px;transform:rotate(-90deg);width:32px}.totp .totp-countdown .totp-circle{fill:none}html.theme_light .totp .totp-countdown .totp-circle{stroke:#175ddc}html.theme_dark .totp .totp-countdown .totp-circle{stroke:#6a99f0}.totp .totp-countdown .totp-circle.inner{stroke-dasharray:78.6;stroke-dashoffset:0;stroke-width:3}.totp .totp-countdown .totp-circle.outer{stroke-dasharray:88;stroke-dashoffset:0;stroke-width:2}.totp>.align-items-center{margin-bottom:-5px}html.theme_light .totp.low .totp-sec,html.theme_light .totp.low .totp-code{color:#dd4b39}html.theme_dark .totp.low .totp-sec,html.theme_dark .totp.low .totp-code{color:#ff8d85}html.theme_light .totp.low .totp-circle{stroke:#dd4b39}html.theme_dark .totp.low .totp-circle{stroke:#ff8d85}.cdk-drag-preview{border-radius:.25rem;opacity:.8;z-index:1070 !important}html.theme_light .cdk-drag-preview{background:#fff}html.theme_dark .cdk-drag-preview{background:#2f343d}.password-wrapper{min-width:0;white-space:pre-wrap;word-break:break-all}.password-row{min-width:0}html.theme_light .password-letter{color:#333}html.theme_dark .password-letter{color:#fff}html.theme_light .password-number{color:#007fde}html.theme_dark .password-number{color:#52bdfb}html.theme_light .password-special{color:#c40800}html.theme_dark .password-special{color:#ff7c70}app-vault-groupings .card #search,app-org-vault-groupings .card #search,.groupings .card #search{margin-bottom:1rem}html.theme_light app-vault-groupings .card #search,html.theme_light app-org-vault-groupings .card #search,html.theme_light .groupings .card #search{background-color:#fbfbfb;border-color:#ced4da;color:#465057}html.theme_dark app-vault-groupings .card #search,html.theme_dark app-org-vault-groupings .card #search,html.theme_dark .groupings .card #search{background-color:transparent;border-color:#bac0ce;color:#fff}html.theme_light app-vault-groupings .card #search::placeholder,html.theme_light app-org-vault-groupings .card #search::placeholder,html.theme_light .groupings .card #search::placeholder{color:#b6b8b8}html.theme_dark app-vault-groupings .card #search::placeholder,html.theme_dark app-org-vault-groupings .card #search::placeholder,html.theme_dark .groupings .card #search::placeholder{color:#bac0ce}app-vault-groupings .card h3,app-org-vault-groupings .card h3,.groupings .card h3{font-weight:normal;text-transform:uppercase}html.theme_light app-vault-groupings .card h3,html.theme_light app-org-vault-groupings .card h3,html.theme_light .groupings .card h3{color:#6c757d}html.theme_dark app-vault-groupings .card h3,html.theme_dark app-org-vault-groupings .card h3,html.theme_dark .groupings .card h3{color:#bac0ce}app-vault-groupings .card ul:last-child,app-org-vault-groupings .card ul:last-child,.groupings .card ul:last-child{margin-bottom:0}html.theme_light app-vault-groupings .card .card-body a,html.theme_light app-org-vault-groupings .card .card-body a,html.theme_light .groupings .card .card-body a{color:#333;font-weight:400}html.theme_dark app-vault-groupings .card .card-body a,html.theme_dark app-org-vault-groupings .card .card-body a,html.theme_dark .groupings .card .card-body a{color:#fff;font-weight:600}html.theme_light app-vault-groupings .card .card-body a:hover.text-muted,html.theme_light app-org-vault-groupings .card .card-body a:hover.text-muted,html.theme_light .groupings .card .card-body a:hover.text-muted{color:#333 !important}html.theme_dark app-vault-groupings .card .card-body a:hover.text-muted,html.theme_dark app-org-vault-groupings .card .card-body a:hover.text-muted,html.theme_dark .groupings .card .card-body a:hover.text-muted{color:#8d94a5 !important}app-vault-groupings .card .show-active,app-org-vault-groupings .card .show-active,.groupings .card .show-active{display:none}app-vault-groupings .card li>.fa,app-vault-groupings .card li>div>.fa,app-org-vault-groupings .card li>.fa,app-org-vault-groupings .card li>div>.fa,.groupings .card li>.fa,.groupings .card li>div>.fa{cursor:pointer}app-vault-groupings .card li.active>.show-active,app-vault-groupings .card li.active>div .show-active,app-org-vault-groupings .card li.active>.show-active,app-org-vault-groupings .card li.active>div .show-active,.groupings .card li.active>.show-active,.groupings .card li.active>div .show-active{display:inline}app-vault-groupings .card li.active>a:first-of-type,app-vault-groupings .card li.active>div a:first-of-type,app-org-vault-groupings .card li.active>a:first-of-type,app-org-vault-groupings .card li.active>div a:first-of-type,.groupings .card li.active>a:first-of-type,.groupings .card li.active>div a:first-of-type{font-weight:bold}html.theme_light app-vault-groupings .card li.active>a:first-of-type,html.theme_light app-vault-groupings .card li.active>div a:first-of-type,html.theme_light app-org-vault-groupings .card li.active>a:first-of-type,html.theme_light app-org-vault-groupings .card li.active>div a:first-of-type,html.theme_light .groupings .card li.active>a:first-of-type,html.theme_light .groupings .card li.active>div a:first-of-type{color:#175ddc}html.theme_dark app-vault-groupings .card li.active>a:first-of-type,html.theme_dark app-vault-groupings .card li.active>div a:first-of-type,html.theme_dark app-org-vault-groupings .card li.active>a:first-of-type,html.theme_dark app-org-vault-groupings .card li.active>div a:first-of-type,html.theme_dark .groupings .card li.active>a:first-of-type,html.theme_dark .groupings .card li.active>div a:first-of-type{color:#6a99f0}html.theme_light app-vault-groupings .card li.active>.fa,html.theme_light app-vault-groupings .card li.active>div>.fa,html.theme_light app-org-vault-groupings .card li.active>.fa,html.theme_light app-org-vault-groupings .card li.active>div>.fa,html.theme_light .groupings .card li.active>.fa,html.theme_light .groupings .card li.active>div>.fa{color:#175ddc}html.theme_dark app-vault-groupings .card li.active>.fa,html.theme_dark app-vault-groupings .card li.active>div>.fa,html.theme_dark app-org-vault-groupings .card li.active>.fa,html.theme_dark app-org-vault-groupings .card li.active>div>.fa,html.theme_dark .groupings .card li.active>.fa,html.theme_dark .groupings .card li.active>div>.fa{color:#6a99f0}app-password-generator #lengthRange{width:100%}app-password-generator .card-password .card-body{align-items:center;display:flex;flex-wrap:wrap;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1.15rem;justify-content:center;text-align:center}html.theme_light app-password-generator .card-password .card-body{background:#fff}html.theme_dark app-password-generator .card-password .card-body{background:#2f343d}app-password-generator-history .list-group-item{line-height:1}html.theme_light app-password-generator-history .list-group-item{background:#fff}html.theme_dark app-password-generator-history .list-group-item{background:#1f242e}app-password-generator-history .list-group-item .password{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}app-import textarea{height:150px}app-user-billing .progress{height:20px}app-user-billing .progress .progress-bar{min-width:50px}app-sponsored-families .inset-list{padding-left:1.5rem}.layout.enterprise2 header{background:#175ddc;color:#ced4da}.layout.enterprise2 header:before{background:#175ddc;content:"";height:416px;left:0;position:absolute;top:-76px;transform:skewY(-3deg);width:100%;z-index:-1}.layout.enterprise2 header img.logo{height:57px;margin:12px 0 0;max-width:284px;width:284px}.layout.enterprise2 h2{color:#fff;font-size:1.8rem;margin:100px 0 150px 0}.layout.enterprise2 p{font-size:1.4rem;margin:20px 0 40px 0}.layout.enterprise2 p:before{content:"/";padding-right:12px}.layout.enterprise2 p:not(.highlight):before{color:#1252a3}.layout.enterprise2 p b:after{content:"⟶";font-size:2rem;padding-left:6px}.layout.enterprise2 blockquote{font-size:1.4rem;margin:20px 0 0 0;padding-right:40px}#duo-frame{height:330px}html.theme_light #duo-frame{background:0 0 no-repeat}html.theme_dark #duo-frame{background:0 0 no-repeat}#duo-frame iframe{border:none;height:100%;width:100%}#web-authn-frame{height:290px}html.theme_light #web-authn-frame{background:0 0 no-repeat}html.theme_dark #web-authn-frame{background:0 0 no-repeat}#web-authn-frame iframe{border:none;height:100%;width:100%}#hcaptcha_iframe{border:none;transition:height .25s linear;width:100%}.list-group-2fa .logo-2fa{min-width:100px}.mfaType0{content:url(../images/0.png);max-width:100px}.mfaType2{content:url(../images/2.png);max-width:100px}.mfaType3{content:url(../images/3.png);max-width:100px}.mfaType4{content:url(../images/4.png);max-width:100px}.mfaType6{content:url(../images/6.png);max-width:100px}html.theme_light .mfaType1{content:url(../images/1.png);max-width:100px;max-height:45px}html.theme_dark .mfaType1{content:url(../images/1-w.png);max-width:100px;max-height:45px}html.theme_light .mfaType7{content:url(../images/7.png);max-width:100px}html.theme_dark .mfaType7{content:url(../images/7-w.png);max-width:100px}html.theme_light .recovery-code-img{content:url(../images/rc.png);max-width:100px;max-height:45px}html.theme_dark .recovery-code-img{content:url(../images/rc-w.png);max-width:100px;max-height:45px}html.theme_light .progress{background-color:#e9ecef}html.theme_dark .progress{background-color:#3c424e}#bt-dropin-container{min-height:50px}html.theme_light #bt-dropin-container{background:url(../images/loading.svg) center center no-repeat}html.theme_dark #bt-dropin-container{background:url(../images/loading-white.svg) center center no-repeat}.braintree-placeholder,.braintree-sheet__header{display:none}.braintree-sheet__content--button{min-height:0;padding:0;text-align:left}.braintree-sheet__container{margin-bottom:0}.braintree-sheet{border:none}html.theme_light [data-braintree-id=upper-container]::before{background-color:#fff}html.theme_dark [data-braintree-id=upper-container]::before{background-color:#1f242e}html.theme_light .card [data-braintree-id=upper-container]::before{background-color:#fff}html.theme_dark .card [data-braintree-id=upper-container]::before{background-color:#2f343d}html.theme_light [data-braintree-id=paypal-button]{background-color:#fff}html.theme_dark [data-braintree-id=paypal-button]{background-color:#1f242e}html.theme_light .card [data-braintree-id=paypal-button]{background-color:#fff}html.theme_dark .card [data-braintree-id=paypal-button]{background-color:#2f343d}html.theme_light .paypal-button-text{color:#333}html.theme_dark .paypal-button-text{color:#bac0ce}html.theme_light [class*=swal2-]:not(.swal2-container,.swal2-confirm,.swal2-cancel,.swal2-deny){background-color:#fff;color:#333}html.theme_dark [class*=swal2-]:not(.swal2-container,.swal2-confirm,.swal2-cancel,.swal2-deny){background-color:#1f242e;color:#bac0ce}.swal2-container{background-color:rgba(0,0,0,.3)}.swal2-popup{border:1px solid #9a9a9a;border-radius:.3rem;padding:15px 0 0;width:34em}html.theme_light .swal2-popup{background-color:#fff;color:#333}html.theme_dark .swal2-popup{background-color:#1f242e;color:#bac0ce}.swal2-popup .swal2-header{padding:0 15px}.swal2-popup .swal2-icon{border:none;height:auto;margin:0 auto;width:auto}.swal2-popup .swal2-content{font-size:1rem;padding-bottom:15px}html.theme_light .swal2-popup .swal2-content{border-bottom:1px solid #ced4da}html.theme_dark .swal2-popup .swal2-content{border-bottom:1px solid #4c525f}.swal2-popup i.swal-custom-icon{display:block;font-size:35px;margin:0 auto}.swal2-popup .swal2-title{font-size:1.15rem;margin:0;padding:10px 0 15px}html.theme_light .swal2-popup .swal2-title{color:#333}html.theme_dark .swal2-popup .swal2-title{color:#fff}.swal2-popup .swal2-content{font-size:1rem;padding:0 15px 15px}html.theme_light .swal2-popup .swal2-content{color:#333}html.theme_dark .swal2-popup .swal2-content{color:#bac0ce}.swal2-popup .swal2-actions{border-radius:.3rem;display:flex;flex-direction:row;font-size:1rem;justify-content:flex-start;margin:0;padding:15px}html.theme_light .swal2-popup .swal2-actions{background-color:#fff}html.theme_dark .swal2-popup .swal2-actions{background-color:#1f242e}.swal2-popup .swal2-actions button{margin-right:10px}.swal2-popup .swal2-validation-message{margin:0 -15px}date-input-polyfill[data-open=true]{z-index:10000 !important}html.theme_light .table{color:#333}html.theme_dark .table{color:#bac0ce}.table td{vertical-align:middle}html.theme_light .table td{color:#333}html.theme_dark .table td{color:#bac0ce}html.theme_light .table td>a:not(.badge){color:#175ddc}html.theme_dark .table td>a:not(.badge){color:#fff}html.theme_light .table td>a:not(.badge):hover{color:#104097}html.theme_dark .table td>a:not(.badge):hover{color:#fff}.table td.reduced-lh{line-height:1}.table td.reduced-lh small{font-size:80%}html.theme_light .table td small,html.theme_light .table td>.fa,html.theme_light .table td .icon{color:#6c757d}html.theme_dark .table td small,html.theme_dark .table td>.fa,html.theme_dark .table td .icon{color:#bac0ce}html.theme_light .table td .fa-globe{color:#777}html.theme_dark .table td .fa-globe{color:#777}.table td.wrap{word-break:break-all}.table td.table-list-options{height:50px;max-width:76px;text-align:right;width:76px}.table td.table-list-options.wider{max-width:100px;width:100px}.table td.table-list-options .btn,.table td.table-list-options .swal2-popup .swal2-actions button,.swal2-popup .swal2-actions .table td.table-list-options button{line-height:1;transition:initial}.table td.table-list-options .dropdown-menu{line-height:1.5}.table td.table-action-right{text-align:right}.table td.table-list-icon{max-width:45px;text-align:center;width:45px}.table td.table-list-icon img{max-height:24px}.table td.table-list-checkbox{max-width:35px;width:35px}.table td.table-list-strike{text-decoration:line-through}html.theme_light .table td.table-list-strike{color:#6c757d}html.theme_dark .table td.table-list-strike{color:#bac0ce}html.theme_light .table.table-list.table td:not(tr:first-child td),html.theme_light .table.table-list .table th:not(tr:first-child td){border-top:1px solid #dee2e6}html.theme_dark .table.table-list.table td:not(tr:first-child td),html.theme_dark .table.table-list .table th:not(tr:first-child td){border-top:1px solid #4c525f}.table.table-list thead th{border-top:none}.table.table-list tr:first-child td{border:none}html.theme_light .table-hover tbody tr:hover{background-color:rgba(0,0,0,.03);color:#333}html.theme_dark .table-hover tbody tr:hover{background-color:rgba(255,255,255,.03);color:#bac0ce}.toast-container.toast-top-right{top:76px}.toast-container .toast-close-button{font-size:18px;margin-right:4px}.toast-container .toast{align-items:center;background-image:none !important;border-radius:.25rem;box-shadow:0 0 8px rgba(0,0,0,.35);display:flex;opacity:1 !important}.toast-container .toast:hover{box-shadow:0 0 10px rgba(0,0,0,.6)}.toast-container .toast:before{color:#fff;float:left;font-family:FontAwesome;font-size:25px;line-height:20px;margin:auto 0 auto 15px}.toast-container .toast .toast-content{padding:15px}.toast-container .toast .toaster-icon{display:none}.toast-container .toast .toast-message p{margin-bottom:.5rem}.toast-container .toast .toast-message p:last-child{margin-bottom:0}.toast-container .toast.toast-danger,.toast-container .toast.toast-error{background-image:none !important}html.theme_light .toast-container .toast.toast-danger,html.theme_light .toast-container .toast.toast-error{background-color:#dd4b39}html.theme_dark .toast-container .toast.toast-danger,html.theme_dark .toast-container .toast.toast-error{background-color:#ff8d85}html.theme_light .toast-container .toast.toast-danger,html.theme_light .toast-container .toast.toast-danger:before,html.theme_light .toast-container .toast.toast-danger .toast-close-button,html.theme_light .toast-container .toast.toast-error,html.theme_light .toast-container .toast.toast-error:before,html.theme_light .toast-container .toast.toast-error .toast-close-button{color:#fff !important}html.theme_dark .toast-container .toast.toast-danger,html.theme_dark .toast-container .toast.toast-danger:before,html.theme_dark .toast-container .toast.toast-danger .toast-close-button,html.theme_dark .toast-container .toast.toast-error,html.theme_dark .toast-container .toast.toast-error:before,html.theme_dark .toast-container .toast.toast-error .toast-close-button{color:#1f242e !important}.toast-container .toast.toast-danger:before,.toast-container .toast.toast-error:before{content:""}.toast-container .toast.toast-warning{background-image:none !important}html.theme_light .toast-container .toast.toast-warning{background-color:#bf7e16}html.theme_dark .toast-container .toast.toast-warning{background-color:#ffeb66}html.theme_light .toast-container .toast.toast-warning,html.theme_light .toast-container .toast.toast-warning:before,html.theme_light .toast-container .toast.toast-warning .toast-close-button{color:#fff !important}html.theme_dark .toast-container .toast.toast-warning,html.theme_dark .toast-container .toast.toast-warning:before,html.theme_dark .toast-container .toast.toast-warning .toast-close-button{color:#1f242e !important}.toast-container .toast.toast-warning:before{content:""}.toast-container .toast.toast-info{background-image:none !important}html.theme_light .toast-container .toast.toast-info{background-color:#343a40}html.theme_dark .toast-container .toast.toast-info{background-color:#a4b0c6}html.theme_light .toast-container .toast.toast-info,html.theme_light .toast-container .toast.toast-info:before,html.theme_light .toast-container .toast.toast-info .toast-close-button{color:#fff !important}html.theme_dark .toast-container .toast.toast-info,html.theme_dark .toast-container .toast.toast-info:before,html.theme_dark .toast-container .toast.toast-info .toast-close-button{color:#1f242e !important}.toast-container .toast.toast-info:before{content:""}.toast-container .toast.toast-success{background-image:none !important}html.theme_light .toast-container .toast.toast-success{background-color:#00a65a}html.theme_dark .toast-container .toast.toast-success{background-color:#52e07c}html.theme_light .toast-container .toast.toast-success,html.theme_light .toast-container .toast.toast-success:before,html.theme_light .toast-container .toast.toast-success .toast-close-button{color:#fff !important}html.theme_dark .toast-container .toast.toast-success,html.theme_dark .toast-container .toast.toast-success:before,html.theme_dark .toast-container .toast.toast-success .toast-close-button{color:#1f242e !important}.toast-container .toast.toast-success:before{content:""}.toast-container .layout_frontend .toast-top-right{top:20px}.layout_frontend .toast-top-right{top:20px} + + +/*# sourceMappingURL=main.656f1dffa218e8467958.css.map*/ \ No newline at end of file diff --git a/app/main.656f1dffa218e8467958.css.map b/app/main.656f1dffa218e8467958.css.map new file mode 100644 index 00000000..9425e5dd --- /dev/null +++ b/app/main.656f1dffa218e8467958.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///./jslib/angular/src/scss/webfonts.css","webpack:///./src/scss/styles.scss","webpack:///./node_modules/bootstrap/scss/_root.scss","webpack:///./node_modules/bootstrap/scss/_reboot.scss","webpack:///./src/scss/variables.scss","webpack:///./node_modules/bootstrap/scss/vendor/_rfs.scss","webpack:///./node_modules/bootstrap/scss/_variables.scss","webpack:///./node_modules/bootstrap/scss/mixins/_hover.scss","webpack:///./node_modules/bootstrap/scss/_type.scss","webpack:///./node_modules/bootstrap/scss/mixins/_lists.scss","webpack:///./node_modules/bootstrap/scss/_images.scss","webpack:///./node_modules/bootstrap/scss/mixins/_image.scss","webpack:///./node_modules/bootstrap/scss/mixins/_border-radius.scss","webpack:///./node_modules/bootstrap/scss/_code.scss","webpack:///./node_modules/bootstrap/scss/_grid.scss","webpack:///./node_modules/bootstrap/scss/mixins/_grid.scss","webpack:///./node_modules/bootstrap/scss/mixins/_breakpoints.scss","webpack:///./node_modules/bootstrap/scss/mixins/_grid-framework.scss","webpack:///./node_modules/bootstrap/scss/_tables.scss","webpack:///./node_modules/bootstrap/scss/mixins/_table-row.scss","webpack:///./node_modules/bootstrap/scss/_forms.scss","webpack:///./node_modules/bootstrap/scss/mixins/_transition.scss","webpack:///./node_modules/bootstrap/scss/mixins/_forms.scss","webpack:///./node_modules/bootstrap/scss/_buttons.scss","webpack:///./node_modules/bootstrap/scss/mixins/_buttons.scss","webpack:///./node_modules/bootstrap/scss/_transitions.scss","webpack:///./node_modules/bootstrap/scss/_dropdown.scss","webpack:///./node_modules/bootstrap/scss/mixins/_caret.scss","webpack:///./node_modules/bootstrap/scss/mixins/_nav-divider.scss","webpack:///./node_modules/bootstrap/scss/_button-group.scss","webpack:///./node_modules/bootstrap/scss/_input-group.scss","webpack:///./node_modules/bootstrap/scss/_custom-forms.scss","webpack:///./node_modules/bootstrap/scss/_nav.scss","webpack:///./node_modules/bootstrap/scss/_navbar.scss","webpack:///./node_modules/bootstrap/scss/_card.scss","webpack:///./node_modules/bootstrap/scss/_breadcrumb.scss","webpack:///./node_modules/bootstrap/scss/_pagination.scss","webpack:///./node_modules/bootstrap/scss/mixins/_pagination.scss","webpack:///./node_modules/bootstrap/scss/_badge.scss","webpack:///./node_modules/bootstrap/scss/mixins/_badge.scss","webpack:///./node_modules/bootstrap/scss/_jumbotron.scss","webpack:///./node_modules/bootstrap/scss/_alert.scss","webpack:///./node_modules/bootstrap/scss/mixins/_alert.scss","webpack:///./node_modules/bootstrap/scss/_progress.scss","webpack:///./node_modules/bootstrap/scss/mixins/_gradients.scss","webpack:///./node_modules/bootstrap/scss/_media.scss","webpack:///./node_modules/bootstrap/scss/_list-group.scss","webpack:///./node_modules/bootstrap/scss/mixins/_list-group.scss","webpack:///./node_modules/bootstrap/scss/_close.scss","webpack:///./node_modules/bootstrap/scss/_modal.scss","webpack:///./node_modules/bootstrap/scss/_tooltip.scss","webpack:///./node_modules/bootstrap/scss/mixins/_reset-text.scss","webpack:///./node_modules/bootstrap/scss/_popover.scss","webpack:///./node_modules/bootstrap/scss/_carousel.scss","webpack:///./node_modules/bootstrap/scss/mixins/_clearfix.scss","webpack:///./node_modules/bootstrap/scss/_spinners.scss","webpack:///./node_modules/bootstrap/scss/utilities/_align.scss","webpack:///./node_modules/bootstrap/scss/mixins/_background-variant.scss","webpack:///./node_modules/bootstrap/scss/utilities/_background.scss","webpack:///./node_modules/bootstrap/scss/utilities/_borders.scss","webpack:///./node_modules/bootstrap/scss/utilities/_display.scss","webpack:///./node_modules/bootstrap/scss/utilities/_embed.scss","webpack:///./node_modules/bootstrap/scss/utilities/_flex.scss","webpack:///./node_modules/bootstrap/scss/utilities/_float.scss","webpack:///./node_modules/bootstrap/scss/utilities/_interactions.scss","webpack:///./node_modules/bootstrap/scss/utilities/_position.scss","webpack:///./node_modules/bootstrap/scss/utilities/_screenreaders.scss","webpack:///./node_modules/bootstrap/scss/mixins/_screen-reader.scss","webpack:///./node_modules/bootstrap/scss/utilities/_shadows.scss","webpack:///./node_modules/bootstrap/scss/utilities/_sizing.scss","webpack:///./node_modules/bootstrap/scss/utilities/_spacing.scss","webpack:///./node_modules/bootstrap/scss/utilities/_stretched-link.scss","webpack:///./node_modules/bootstrap/scss/utilities/_text.scss","webpack:///./node_modules/bootstrap/scss/mixins/_text-truncate.scss","webpack:///./node_modules/bootstrap/scss/mixins/_text-emphasis.scss","webpack:///./node_modules/bootstrap/scss/mixins/_text-hide.scss","webpack:///./node_modules/bootstrap/scss/utilities/_visibility.scss","webpack:///./node_modules/bootstrap/scss/_print.scss","webpack:///./node_modules/angular2-toaster/toaster.scss","webpack:///./node_modules/font-awesome/scss/font-awesome.scss","webpack:///./node_modules/font-awesome/scss/_path.scss","webpack:///./node_modules/font-awesome/scss/_core.scss","webpack:///./node_modules/font-awesome/scss/_larger.scss","webpack:///./node_modules/font-awesome/scss/_fixed-width.scss","webpack:///./node_modules/font-awesome/scss/_list.scss","webpack:///./node_modules/font-awesome/scss/_variables.scss","webpack:///./node_modules/font-awesome/scss/_bordered-pulled.scss","webpack:///./node_modules/font-awesome/scss/_animated.scss","webpack:///./node_modules/font-awesome/scss/_rotated-flipped.scss","webpack:///./node_modules/font-awesome/scss/_mixins.scss","webpack:///./node_modules/font-awesome/scss/_stacked.scss","webpack:///./node_modules/font-awesome/scss/_icons.scss","webpack:///./node_modules/font-awesome/scss/_screen-reader.scss","webpack:///./node_modules/sweetalert2/src/scss/_toasts.scss","webpack:///./node_modules/sweetalert2/src/variables.scss","webpack:///./node_modules/sweetalert2/src/scss/_mixins.scss","webpack:///./node_modules/sweetalert2/src/scss/_core.scss","webpack:///./node_modules/sweetalert2/src/scss/_polyfills.scss","webpack:///./node_modules/sweetalert2/src/scss/_toasts-animations.scss","webpack:///./node_modules/sweetalert2/src/scss/_animations.scss","webpack:///./node_modules/sweetalert2/src/scss/_body.scss","webpack:///./node_modules/sweetalert2/src/scss/_toasts-body.scss","webpack:///./src/scss/base.scss","webpack:///./src/scss/buttons.scss","webpack:///./src/scss/callouts.scss","webpack:///./src/scss/cards.scss","webpack:///./src/scss/forms.scss","webpack:///./src/scss/navigation.scss","webpack:///./src/scss/modals.scss","webpack:///./src/scss/pages.scss","webpack:///./src/scss/plugins.scss","webpack:///./src/scss/tables.scss","webpack:///./src/scss/toasts.scss"],"names":[],"mappings":"AAAA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;;ACxFQ,qBCGJ,iOAIA,oMAIA,oOAKF,8GACA,sBCCF,qBAGE,MAGF,sBACE,iBACA,8BACA,0CACA,uEAMF,aACE,MAUF,QACE,2HC5BuB,eCuEN,gBCsMW,gBAKA,WFpRjB,gBDoCX,sBC5CM,2CDyDR,oBACE,IASF,sBACE,SACA,iBACA,mBAaF,YACE,oBGiN4B,GHzM9B,YACE,mBGqF0B,uCHzE5B,yBAEE,iCACA,YACA,gBACA,8BACA,SAGF,kBACE,kBACA,oBACA,UAGF,YAGE,mBACA,yBAGF,eAIE,IAGF,eGkJ8B,IH9I9B,mBACE,cACA,YAGF,eACE,UAGF,kBGsI8B,OHjI9B,aExFI,SFiGJ,iBAEE,cEnGE,cFqGF,wBACA,KAGF,mBACA,aAOA,aGV0C,qBACA,6BHYxC,SIhLA,aDqKwC,0BACA,4BHuB1C,aACE,qBACA,kCI/LA,aJkME,qBACA,mBASJ,0FG6D8B,cD7M1B,KFwJJ,YAEE,mBAEA,cAEA,6BAGA,QAQF,eAEE,KAQF,qBACE,kBACA,KAGF,eAGE,sBACA,OAQF,wBACE,SAGF,kBG8E8B,oCAjVnB,gBHuQT,oBACA,IAOF,kBAEE,gCACA,OAQF,oBAEE,oBG4JsC,QHrJxC,eAEE,kCAQF,SACE,uCAGF,QAKE,oBACA,kBE5PE,oBF8PF,cAGF,gBAEE,eAGF,mBAEE,eAMF,cACE,QAMF,gBACE,iDAOF,yBAIE,6GASE,cACE,yHAMN,SAIE,kBACA,wCAGF,qBAEE,UACA,UAIF,aACE,gBAEA,UAGF,WAME,UAEA,SACA,SACA,QAKF,aACE,WACA,eACA,UACA,oBACA,iBEzUiB,oBF2UjB,cACA,mBACA,UAGF,uBACE,mFAIF,WAEE,eAGF,mBAKE,wBACA,0CAOF,uBACE,8BAQF,YACE,0BACA,QAOF,oBACE,SAGF,iBACE,eACA,UAGF,YACE,UAKF,uBACE,2CK5dF,mBFuS8B,gBAEA,gBACA,QEjS9B,gBH0EmB,QGzEnB,gBHyEmB,QGxEnB,cHwEmB,QGvEnB,cHuEmB,QGtEnB,cHsEmB,QGrEnB,cHqEmB,OGnEnB,iBHmEmB,mBDzBA,YIpCnB,cH6DmB,gBC+NW,gBARA,YE/Q9B,gBHwDmB,gBCgOW,gBATA,YE1Q9B,gBHmDmB,gBCiOW,gBAVA,YErQ9B,gBH8CmB,gBCkOW,gBAXA,IE1P9B,eFiFS,4BE9EP,oCACA,cAQF,aHMI,gBCuN0B,YEvN9B,YFoQ8B,yBASA,gBElQ9B,cC/EE,gBACA,cDmFF,cCpFE,gBACA,mBDsFF,oBACE,oCAEA,kBFqP4B,aE1O9B,aHjCI,yBGmCF,aAIF,kBFwBS,kBD9CU,oBG2BnB,aACE,cH7CE,cC3DO,4BE4GT,YACE,0CEnHJ,cCIE,YAGA,gBDDF,cJogCoC,sBFzgC5B,yBMQN,qBEEE,eDPF,YAGA,SDcF,oBAEE,aAGF,mBACE,cACA,iBAGF,aLkCI,cC3DO,MOZX,cRuEI,cClCM,qBOlCR,QAGA,aACE,KAKJ,mBACE,eR0DE,WDhEI,yBEQG,oBMEP,SCGF,SACE,eRkDA,gBCwN0B,KOlQ9B,aACE,eRyCE,cCxDO,UOoBT,iBRoCE,cQlCA,kBACA,iBAKJ,gBP+jCoC,kBO7jClC,qFCxCA,UCDA,mBACA,kBACA,kBACA,iBACA,wBCmDE,yBFzCE,eR+LiB,yBUtJnB,uCFzCE,eR+LiB,yBUtJnB,qDFzCE,eR+LiB,yBUtJnB,mEFzCE,gBR+LiB,OQlKrB,YCnCA,eACA,mBACA,kBACA,aDsCA,cACE,cACA,4CAEA,eAEE,eACA,uqBGtDJ,iBACE,WACA,mBACA,kBACA,MAsBE,YACE,YACA,eACA,eF4BN,aACE,eACA,eAFF,YACE,cACA,eAFF,uBACE,yBACA,eAFF,YACE,cACA,eAFF,YACE,cACA,eAFF,uBACE,yBACA,WEnBE,aFCJ,WACA,eACA,QEGQ,sBFbR,wBAIA,QESQ,uBFbR,yBAIA,QESQ,YFbR,cAIA,QESQ,uBFbR,yBAIA,QESQ,uBFbR,yBAIA,QESQ,YFbR,cAIA,QESQ,uBFbR,yBAIA,QESQ,uBFbR,yBAIA,QESQ,YFbR,cAIA,SESQ,uBFbR,yBAIA,SESQ,uBFbR,yBAIA,SESQ,aFbR,eAIA,cEeI,qBAEA,kBAGE,OADW,UACX,OADW,UACX,OADW,UACX,OADW,UACX,OADW,UACX,OADW,UACX,OADW,UACX,OADW,UACX,OADW,UACX,OADW,WACX,QADW,WACX,QADW,WACX,QADW,WAQP,yBFhBV,WEgBU,0BFhBV,WEgBU,eFhBV,WEgBU,0BFhBV,WEgBU,0BFhBV,WEgBU,eFhBV,WEgBU,0BFhBV,WEgBU,0BFhBV,WEgBU,eFhBV,YEgBU,0BFhBV,YEgBU,0BFhBV,wBCKE,QC3BE,YACE,YACA,eACA,kBF4BN,aACE,eACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,kBAFF,YACE,cACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,cEnBE,aFCJ,WACA,eACA,WEGQ,sBFbR,wBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,YESQ,uBFbR,yBAIA,YESQ,uBFbR,yBAIA,YESQ,aFbR,eAIA,iBEeI,wBAEA,qBAGE,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,cACX,QADW,cACX,QADW,cACX,QADW,cAQP,aFhBV,cEgBU,yBFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,eEgBU,0BFhBV,eEgBU,0BFhBV,yBCKE,QC3BE,YACE,YACA,eACA,kBF4BN,aACE,eACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,kBAFF,YACE,cACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,cEnBE,aFCJ,WACA,eACA,WEGQ,sBFbR,wBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,YESQ,uBFbR,yBAIA,YESQ,uBFbR,yBAIA,YESQ,aFbR,eAIA,iBEeI,wBAEA,qBAGE,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,cACX,QADW,cACX,QADW,cACX,QADW,cAQP,aFhBV,cEgBU,yBFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,eEgBU,0BFhBV,eEgBU,0BFhBV,yBCKE,QC3BE,YACE,YACA,eACA,kBF4BN,aACE,eACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,kBAFF,YACE,cACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,cEnBE,aFCJ,WACA,eACA,WEGQ,sBFbR,wBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,YESQ,uBFbR,yBAIA,YESQ,uBFbR,yBAIA,YESQ,aFbR,eAIA,iBEeI,wBAEA,qBAGE,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,cACX,QADW,cACX,QADW,cACX,QADW,cAQP,aFhBV,cEgBU,yBFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,eEgBU,0BFhBV,eEgBU,0BFhBV,yBCKE,QC3BE,YACE,YACA,eACA,kBF4BN,aACE,eACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,kBAFF,YACE,cACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,cEnBE,aFCJ,WACA,eACA,WEGQ,sBFbR,wBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,YESQ,uBFbR,yBAIA,YESQ,uBFbR,yBAIA,YESQ,aFbR,eAIA,iBEeI,wBAEA,qBAGE,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,cACX,QADW,cACX,QADW,cACX,QADW,cAQP,aFhBV,cEgBU,yBFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,eEgBU,0BFhBV,eEgBU,0BFhBV,SGnDF,UACE,mBZkIO,WFvHI,qBcNX,cZoV4B,mBYjV1B,6BACA,iBAGF,qBACE,gCACA,oBAGF,4BACE,2BAUF,aZ8T4B,iBYnT9B,wBACE,uCAEA,wBAEE,mDAIA,uBAEE,oGAMJ,QAIE,0CASF,gCdfgB,6BG/ChB,UHIW,iCA4CI,oDetDb,wBD8FiC,wFCvF/B,oBDuF2E,mCXxF/E,wBYaqB,2EAMf,wBANe,0DAnBnB,wBD8FiC,gGCvF/B,oBDuF2E,qCXxF/E,wBYaqB,+EAMf,wBANe,oDAnBnB,wBD8FiC,wFCvF/B,oBDuF2E,mCXxF/E,wBYaqB,2EAMf,wBANe,2CAnBnB,wBD8FiC,4ECvF/B,oBDuF2E,gCXxF/E,wBYaqB,qEAMf,wBANe,oDAnBnB,wBD8FiC,wFCvF/B,oBDuF2E,mCXxF/E,wBYaqB,2EAMf,wBANe,iDAnBnB,wBD8FiC,oFCvF/B,oBDuF2E,kCXxF/E,wBYaqB,yEAMf,wBANe,8CAnBnB,wBD8FiC,gFCvF/B,oBDuF2E,iCXxF/E,wBYaqB,uEAMf,wBANe,2CAnBnB,wBD8FiC,4ECvF/B,oBDuF2E,gCXxF/E,wBYaqB,qEAMf,wBANe,yEAnBnB,wBD8FiC,oHCvF/B,oBDuF2E,0CXxF/E,wBYaqB,yFAMf,wBANe,sEAnBnB,wBD8FiC,gHCvF/B,oBDuF2E,yCXxF/E,wBYaqB,uFAMf,wBANe,iDAnBnB,gCfsDa,kCGhDf,gCYaqB,yEAMf,gCANe,uBDwFnB,UdzGI,yBEOG,qBAqWmB,wBY3P1B,aZ3GO,yBALA,qBFPC,ac+HZ,UdzHQ,yBEOG,oDYsHT,oBZ+O4B,4BYzO5B,QACE,qDAIA,sCZiO0B,wCCrW5B,UHJM,wCE2WsB,2BU1S1B,qBEiGA,aAEI,WACA,gBACA,iCACA,sCAGA,QACE,4BF1GN,qBEiGA,aAEI,WACA,gBACA,iCACA,sCAGA,QACE,4BF1GN,qBEiGA,aAEI,WACA,gBACA,iCACA,sCAGA,QACE,4BF1GN,qBEiGA,aAEI,WACA,gBACA,iCACA,sCAGA,QACE,oBATN,aAEI,WACA,gBACA,iCACA,mCAGA,QACE,eE7KV,aACE,WACA,mCd2esC,uBczetC,ef+EiB,gBCsMW,gBAKA,cAtRnB,yBFwCA,4BgBrCT,yBACA,0FAMA,wCCJI,cDdN,eCeQ,4BDMN,4BACE,SACA,8BAIF,iBACE,0BACA,qBEtBF,aACE,sBlBNI,qBE6dgC,UgBpdpC,2ChByX0B,4BchW5B,ahBewB,UgBZtB,gDAQF,wBhBGkB,UgBChB,oIAQF,eACE,sCAKF,adzDS,yBFwCA,wCgB6BX,aAEE,WACA,iBAUF,gCACE,oCACA,gBACA,kBf3BE,gBC4N0B,oBc5L9B,8BACE,kCACA,kBfjBiB,gBCgJW,oBc1H9B,+BACE,mCACA,mBfxBiB,gBCiJW,yBc9G9B,aACE,WACA,kBACA,gBACA,efvCiB,gBC2MW,WFpRjB,6BgBoHX,yBACA,mBACA,iFAEA,eAEE,eACA,kBAYJ,iCd6VwC,qBc3VtC,mBfhEiB,gBCiJW,oBMxN1B,kBQ6IJ,+BdsVwC,mBcpVtC,kBfxEiB,gBCgJW,oBMvN1B,yDQuJF,WAEE,uBAIJ,WACE,aAQF,kBd2UwC,YcvUxC,aACE,kBd4TsC,WcnTxC,YACE,eACA,kBACA,iBACA,wCAEA,iBAEE,iBACA,aASJ,iBACE,cACA,qBdiSsC,mBc7RxC,iBACE,iBd6RsC,qBc3RtC,4FAGA,advNS,mBc6NX,eACE,oBAGF,mBACE,mBACA,eACA,oBd8QsC,sCc1QtC,eACE,aACA,sBdyQoC,ccvQpC,iBE7MF,YACE,WACA,kBhB2coC,cDjbpC,ce8LqC,gBElNvC,iBACE,SACA,OACA,UACA,aACA,eACA,qBACA,iBACA,mBjB6Be,gBC2MW,WgBrO1B,mCACA,qBV9CA,sEUmDA,QAEE,+HAKF,aAEE,2DA9CF,oBFsOqC,oCdyOD,iRgBvZhC,4BACA,2DACA,gEACA,uEAGF,oBFwKmC,0CEtKjC,2EAhEJ,mChB+coC,kFgBrYhC,6DA1EJ,oBFsOqC,uCdqUG,wjBgBtdpC,yEAGF,oBF8ImC,0CE5IjC,uGAOF,aFqImC,mMEjInC,aAEE,uHAOF,aFwHmC,uIErHjC,oBFqHiC,uJE/GjC,oBACE,yBACqB,mJAKvB,yCACE,+KAGF,oBATuB,2GAmBzB,oBAnByB,uHAwBvB,oBAxBuB,0CA0BrB,mBAvIR,YACE,WACA,kBhB2coC,cDjbpC,ce8LqC,kBElNvC,iBACE,SACA,OACA,UACA,aACA,eACA,qBACA,iBACA,mBjB6Be,gBC2MW,WgBrO1B,oCACA,qBV9CA,0EUmDA,QAEE,+IAKF,aAEE,+DA9CF,oBFsOqC,oCdyOD,4UgBvZhC,4BACA,2DACA,gEACA,2EAGF,oBFwKmC,2CEtKjC,+EAhEJ,mChB+coC,kFgBrYhC,iEA1EJ,oBFsOqC,uCdqUG,mnBgBtdpC,6EAGF,oBF8ImC,2CE5IjC,2GAOF,aFqImC,mNEjInC,aAEE,2HAOF,aFwHmC,2IErHjC,oBFqHiC,2JE/GjC,oBACE,yBACqB,uJAKvB,0CACE,mLAGF,oBATuB,+GAmBzB,oBAnByB,2HAwBvB,oBAxBuB,2CA0BrB,cF+FV,YACE,mBACA,mBACA,0BAKA,UACE,wBJ/NA,mBIoOA,YACE,mBACA,uBACA,gBACA,0BAIF,YACE,cACA,mBACA,mBACA,gBACA,4BAIF,oBACE,WACA,sBACA,sCAIF,oBACE,uDAGF,UAEE,0BAKF,YACE,mBACA,uBACA,WACA,eACA,gCAEF,iBACE,cACA,aACA,oBdgLkC,cc9KlC,8BAGF,kBACE,uBACA,oCAEF,eACE,0CGjVN,oBACE,gBnBwDgB,WA/CL,kBmBLX,sBAGA,iBACA,6BACA,6BACA,uBCuFA,enBfiB,gBC2MW,qBMlR1B,8HWCF,wCFCI,wCEdN,eFeQ,sDdTN,UHIW,qBmBOT,yGAGF,SAEE,2CjB8W0B,qHiBzW5B,WjBmZ4B,qGiB7Y5B,cACE,wCAcJ,mBAEE,cASA,UC3DA,yBlBsEa,yCChEb,mCiBP6D,qBAA0C,uCAYvG,UAEE,yBAd2D,qBAA0C,2CAqBnG,6CAKJ,UAEE,yBlB2CW,6JkBlCb,UAGE,yBAxC+I,qBAA0C,0JA+CzL,0CAKI,gBDQN,aC3DA,yBlBsEa,2CChEb,sCiBP6D,qBAA0C,2CAYvG,aAEE,yBAd2D,qBAA0C,4CAqBnG,iDAKJ,aAEE,yBlB2CW,mKkBlCb,aAGE,yBAxC+I,qBAA0C,gKA+CzL,2CAKI,cDQN,UC3DA,yBlBsEa,yCChEb,mCiBP6D,qBAA0C,uCAYvG,UAEE,yBAd2D,qBAA0C,2CAqBnG,6CAKJ,UAEE,yBlB2CW,6JkBlCb,UAGE,yBAxC+I,qBAA0C,0JA+CzL,0CAKI,WDQN,UC3DA,sBlBsEa,mCChEb,mCiBP6D,qBAA0C,iCAYvG,UAEE,yBAd2D,qBAA0C,4CAqBnG,uCAKJ,UAEE,sBlB2CW,iJkBlCb,UAGE,yBAxC+I,qBAA0C,iJA+CzL,2CAKI,cDQN,UC3DA,yBlBsEa,yCChEb,mCiBP6D,qBAA0C,uCAYvG,UAEE,yBAd2D,qBAA0C,2CAqBnG,6CAKJ,UAEE,yBlB2CW,6JkBlCb,UAGE,yBAxC+I,qBAA0C,0JA+CzL,0CAKI,aDQN,UC3DA,yBlBsEa,wCChEb,mCiBP6D,qBAA0C,qCAYvG,UAEE,yBAd2D,qBAA0C,2CAqBnG,2CAKJ,UAEE,yBlB2CW,0JkBlCb,UAGE,yBAxC+I,qBAA0C,uJA+CzL,0CAKI,YDQN,aC3DA,yBlBsEa,uCChEb,sCiBP6D,qBAA0C,mCAYvG,aAEE,yBAd2D,qBAA0C,4CAqBnG,yCAKJ,aAEE,yBlB2CW,uJkBlCb,aAGE,yBAxC+I,qBAA0C,oJA+CzL,2CAKI,WDQN,UC3DA,yBlBsEa,sCChEb,mCiBP6D,qBAA0C,iCAYvG,UAEE,yBAd2D,qBAA0C,yCAqBnG,uCAKJ,UAEE,yBlB2CW,oJkBlCb,UAGE,yBAxC+I,qBAA0C,iJA+CzL,wCAKI,qBDQN,UC3DA,yBlBsEa,gDChEb,mCiBP6D,qBAA0C,qDAYvG,UAEE,yBAd2D,qBAA0C,2CAqBnG,2DAKJ,UAEE,yBlB2CW,kLkBlCb,UAGE,yBAxC+I,qBAA0C,+KA+CzL,0CAKI,oBDQN,UC3DA,yBlBsEa,+CChEb,mCiBP6D,qBAA0C,mDAYvG,UAEE,yBAd2D,qBAA0C,0CAqBnG,yDAKJ,UAEE,yBlB2CW,+KkBlCb,UAGE,yBAxC+I,qBAA0C,4KA+CzL,yCAKI,sBDcN,ajBKa,iDChEb,UiBmDkD,yBlBarC,4EkBHb,yCAEE,6DAGF,alBFa,6BkBKX,gKAGF,UAGE,yBlBXW,uMkBeX,yCAKI,wBDzBN,ajBKa,mDChEb,aiBmDkD,yBlBarC,gFkBHb,2CAEE,iEAGF,alBFa,6BkBKX,sKAGF,aAGE,yBlBXW,6MkBeX,2CAKI,sBDzBN,ajBKa,iDChEb,UiBmDkD,yBlBarC,4EkBHb,wCAEE,6DAGF,alBFa,6BkBKX,gKAGF,UAGE,yBlBXW,uMkBeX,wCAKI,mBDzBN,UjBKa,2CChEb,UiBmDkD,sBlBarC,mEkBHb,wCAEE,uDAGF,UlBFa,6BkBKX,uJAGF,UAGE,sBlBXW,2LkBeX,wCAKI,sBDzBN,ajBKa,iDChEb,UiBmDkD,yBlBarC,4EkBHb,0CAEE,6DAGF,alBFa,6BkBKX,gKAGF,UAGE,yBlBXW,uMkBeX,0CAKI,qBDzBN,ajBKa,gDChEb,UiBmDkD,yBlBarC,0EkBHb,yCAEE,2DAGF,alBFa,6BkBKX,6JAGF,UAGE,yBlBXW,oMkBeX,yCAKI,oBDzBN,ajBKa,+CChEb,aiBmDkD,yBlBarC,wEkBHb,2CAEE,yDAGF,alBFa,6BkBKX,0JAGF,aAGE,yBlBXW,iMkBeX,2CAKI,mBDzBN,ajBKa,8CChEb,UiBmDkD,yBlBarC,sEkBHb,wCAEE,uDAGF,alBFa,6BkBKX,uJAGF,UAGE,yBlBXW,8LkBeX,wCAKI,6BDzBN,ajBKa,wDChEb,UiBmDkD,yBlBarC,0FkBHb,yCAEE,2EAGF,alBFa,6BkBKX,qLAGF,UAGE,yBlBXW,4NkBeX,yCAKI,4BDzBN,ajBKa,uDChEb,UiBmDkD,yBlBarC,wFkBHb,yCAEE,yEAGF,alBFa,6BkBKX,kLAGF,UAGE,yBlBXW,yNkBeX,yCAKI,WDdR,ejB6M8B,cAhHY,qBACA,iBCpKxC,aDqKwC,0BACA,iCiBtFxC,yBjBsFwC,uCiBjFxC,ajBpFS,oBiBuFP,6EAWJ,kBCPE,kBnBfiB,gBCgJW,oBMvN1B,6EWiGJ,oBCXE,mBnBfiB,gBCiJW,oBMxN1B,YW0GJ,aACE,WACA,uBAGA,gBjBwT4B,uFiB/S5B,UACE,OE3IJ,8BACE,wCJmBI,MIpBN,eJqBQ,mBIlBN,SACE,sBAKF,YACE,aAIJ,iBACE,SACA,gBACA,4BACA,wCJEI,YINN,eJOQ,yCKpBR,iBAIE,kBAGF,kBACE,yBCoBE,oBACE,mBrBgOwB,sBADA,WqB5NxB,sBAhCJ,oCACA,gBACA,mCACA,+BAqDE,aACE,gBD1CN,iBACE,SACA,OACA,apBypBkC,aoBvpBlC,WACA,gBpBiuBkC,gBoB/tBlC,mBACA,erBgEiB,WDzEN,gBsBYX,gBACA,sBtBrBM,4BsBuBN,iCACA,qBddE,qBcuBA,UACE,OACA,sBAGF,OACE,UACA,wBVYF,uBUnBA,UACE,OACA,yBAGF,OACE,UACA,yBVYF,uBUnBA,UACE,OACA,yBAGF,OACE,UACA,yBVYF,uBUnBA,UACE,OACA,yBAGF,OACE,UACA,yBVYF,uBUnBA,UACE,OACA,yBAGF,OACE,UACA,yBAQJ,QACE,YACA,aACA,sBpB+rBgC,iCqB7tBhC,oBACE,mBrBgOwB,sBADA,WqB5NxB,aAzBJ,oCACA,yBACA,mCACA,uCA8CE,aACE,2BDWJ,KACE,WACA,UACA,aACA,oBpBirBgC,oCqB7tBhC,oBACE,mBrBgOwB,sBADA,WqB5NxB,kCAlBJ,eACA,qCACA,uBACA,0CAuCE,aACE,oCDqBF,gBACE,0BAMJ,KACE,WACA,UACA,aACA,qBpBgqBgC,mCqB7tBhC,oBACE,mBrBgOwB,sBADA,WqB5NxB,mCAWA,YACE,oCAGF,oBACE,oBrB6MsB,sBADA,WqBzMtB,kCA9BN,wBACA,qCACA,yCAiCE,aACE,oCDsCF,gBACE,2IAQJ,UAIE,YACA,mBAKJ,QE9GE,eACA,gBACA,6BACA,gBFkHF,aACE,WACA,oBACA,WACA,gBpBiK4B,WF/QjB,mBsBiHX,mBAEA,6BACA,SACA,2CnBrHA,aDuvBkC,qBoBlnBhC,iCtB3GqB,6CsB+GvB,UtBzIW,qBsB4IT,gCtBhHsB,iDsBoHxB,apBpJS,oBoBuJP,6BACA,qBAQJ,aACE,kBAIF,aACE,mBpBimBkC,gBoB/lBlC,mBrB3FiB,cC5ER,mBoB0KT,qBAIF,aACE,oBACA,WtB7KW,gCyBbb,iBAEE,oBACA,sBACA,+IAEA,iBACE,cACA,uKtBCF,SsBII,2fAEF,SAGE,cAMN,YACE,eACA,2BACA,2BAEA,UACE,2IAMF,gBAEE,mQAIF,yBjBXE,6BACA,2NiBeF,wBjBFE,4BACA,wBiBmBJ,sBACE,sBACA,8GAEA,aAGE,0CAGF,cACE,kJAIJ,qBACE,qBACA,kJAGF,oBACE,oBACA,qBAoBF,qBACE,uBACA,uBACA,gHAEA,UAEE,sKAGF,eAEE,uSAIF,4BjBrFE,4BACA,+PiByFF,wBjBxGE,0BACA,+KiB2HF,eAEE,kVAEA,iBAEE,sBACA,oBACA,cCzJN,iBACE,aACA,eACA,oBACA,WACA,uHAEA,iBAIE,cACA,SACA,YACA,gBACA,2gBAEA,gBAGE,0IAKJ,SAGE,oDAIF,SACE,4FAKA,wBlBIA,4BACA,uCkBCA,mBACA,8HAEA,wBlBLA,4BACA,8NkBSA,yBlBxBA,6BACA,qNkB+BA,yBlBhCA,6BACA,0CkB8CJ,YAEE,kRAKA,iBACE,UACA,sTAEA,SACE,uoDAIJ,gBAIE,sBAIJ,sCACA,mCAQA,YACE,mBACA,uBACA,gBACA,ezB7BiB,gBCsMW,gBAKA,cAtRnB,kBwB6GT,mBACA,yBxBnHS,yBwBqHT,qBlB5GE,4EkBgHF,YAEE,4EAUJ,+BxBuWwC,6YwBlWxC,kBAME,kBzBhEiB,gBCgJW,oBMvN1B,4EkB6IJ,iCxBqVwC,6YwBhVxC,oBAME,mBzBjFiB,gBCiJW,oBMxN1B,+DkB8JJ,qBAEE,m9BAWF,yBlB3JI,6BACA,8mBkBqKJ,wBlBxJI,4BACA,iBmBxCJ,iBACE,UACA,cACA,kBACA,oBACA,mBACA,wBAGF,mBACE,kBzByfsC,uByBrfxC,iBACE,OACA,WACA,WzBqfsC,eyBnftC,UACA,6DAEA,U3BvBM,qBEkPsB,oFyBpN5B,0CzBoW4B,yEyB3V5B,oBzBsbsC,2EyBlbtC,U3B3CM,yBE8hBwC,iIyBze5C,azBhDO,4HyBmDL,wB3BRc,uB2BmBpB,iBACE,gBACA,mBAEA,+BAIA,iBACE,WACA,aACA,cACA,WzBwboC,gCyBrbpC,WACA,yB3BrCO,yB2BuCP,8BAKF,iBACE,WACA,aACA,cACA,WzByaoC,uByBtapC,iCACA,gDAUF,oBnBlGE,6EmBuGA,oOACE,oFAKF,oBzB2H0B,4GyBtH1B,iLACE,uFAKF,mCzBoZ4C,6FyBjZ5C,mCzBiZ4C,6CyBtY9C,iBzB2Z8C,0EyBrZ5C,gLACE,oFAKF,mCzB0X4C,gByB/WhD,oBACE,8CAGE,aACE,czBkY0C,mByBhY1C,oBzBiY0C,6CyB5X5C,uBACE,0BACA,uBzB2X0C,iDA5iBrC,oBA2iBqC,kIyBpX1C,wCV/KA,4CUuKF,eVtKI,4EUmLJ,wB3BlJO,8B2BoJL,qFAKF,mCzB+U4C,gByBlUhD,oBACE,WACA,mCzBqRsC,uCyBnRtC,e1BvIiB,gBCsMW,gBAKA,cAtRnB,sByBwNT,yOACA,yBACA,qBnBtNE,gBmByNF,sBAEA,oBzBwPsC,UyBtPpC,2CzBuWgC,iCyB/VhC,azBzOO,yBFwCA,+D2B4MT,WAEE,qBzB+H0B,sByB7H1B,yBAGF,azB5PS,yBAJA,4ByBsQT,YACE,+BAIF,iBACE,0BACA,mBAIJ,iCzB0NwC,mBAxGV,yCACA,mBDpTX,mB0ByMnB,+BzBmNwC,kBApGV,uCACA,kBDzTX,c0BsNnB,iBACE,qBACA,WACA,mCzBiMsC,gByB/LtC,oBAGF,iBACE,UACA,WACA,mCzByLsC,SyBvLtC,gBACA,UACA,6CAEA,oBzBqKsC,2CA3FV,gGyBpE5B,wB3B9QkB,uD2BoRhB,gBzB2Te,2DyBtTjB,yBACE,oBAIJ,iBACE,MACA,QACA,OACA,UACA,mCzBwJsC,uByBtJtC,gBACA,gBzB/D4B,gBAKA,cAtRnB,yBFwCA,yB2B8ST,qBnBlVE,2BmBsVF,iBACE,MACA,QACA,SACA,UACA,cACA,6BzBiIoC,uByB/HpC,gBzB5E0B,cAtRnB,iByBqWP,yBzB1WO,oByB4WP,gCnBnWA,emB8WJ,UACE,cACA,UACA,6BACA,gBACA,qBAEA,SACE,2CAIA,yDzBmOyC,uCyBlOzC,yDzBkOyC,gCyBjOzC,yDzBiOyC,iCyB9N3C,QACE,qCAGF,UzBoN2C,gCyBjNzC,yBzB9J0B,SAkXe,mBM1lBzC,uGmB2YA,gBACA,wCV1YE,oCUiYJ,eVhYM,6CU2YJ,wBzBiNyC,8CyB5M3C,UzB6LkC,aACA,kByB3LhC,ezB4LgC,yBA1lBzB,yByBiaP,mBnBzZA,iCmB8ZF,UzByL2C,qCA/Wf,SAkXe,mBM1lBzC,uGmBqaA,gBACA,wCVpaE,gCU4ZJ,eV3ZM,yCUqaJ,wBzBuLyC,iCyBlL3C,UzBmKkC,aACA,kByBjKhC,ezBkKgC,yBA1lBzB,yByB2bP,mBnBnbA,0BmBwbF,UzB+J2C,yByB5JzC,mBzBrE0B,2CA9IA,SAkXe,mBM1lBzC,uGmBkcA,gBACA,wCVjcE,yBUsbJ,eVrbM,kCUkcJ,wBzB0JyC,0ByBrJ3C,UzBsIkC,aACA,kByBpIhC,ezBqIgC,6ByBnIhC,yBACA,mBACA,+BAIF,wBzB7dS,mBMQP,+BmB0dF,iBACE,yBzBneO,mBMQP,8CmBieA,wBzBveO,uDyB2eP,cACE,0CAGF,wBzB/eO,0CyBmfP,cACE,mCAGF,wBzBvfO,iEyB6fX,sGAGE,wCVxfI,gEUqfN,eVpfQ,OWhBR,YACE,eACA,eACA,gBACA,gBACA,WAGF,aACE,mBACA,iCzBCA,oByBGE,oBAIF,a1BVS,oB0BYP,eACA,WAQJ,+BACE,qBAEA,kBACE,6BACA,8BpBZA,+BACA,qDLZF,oCD8qBkC,8B0BhpBhC,a1BjCO,6B0BmCL,yBACA,+DAIJ,a1BvCS,sBFNH,kCEyrB4B,0B0BroBlC,eAEE,yBpBnCA,0BACA,sBoB8CF,oBpBxDE,wDoB4DF,U5BtEM,yBEkPsB,yC0B/J5B,aAEE,kBACA,mDAKF,YAEE,YACA,kBACA,wBAUF,YACE,sBAEF,aACE,SCpGJ,iBACE,aACA,eACA,mBACA,8BACA,oBACA,qIAIA,YACE,eACA,mBACA,8BACA,eAoBJ,oBACE,c7BHuB,mCEsFhB,oBD9CU,oB4BhCjB,mBACA,yC1B1CA,oB0B6CE,aASJ,YACE,sBACA,eACA,gBACA,gBACA,uBAEA,eACE,eACA,4BAGF,eACE,WACA,cASJ,oBACE,kB3BylBkC,uC2B3kBpC,eACE,YACA,mBAGA,iBAIF,qBACE,kB5B7BiB,c4B+BjB,6BACA,6BACA,qBrBxGE,6CLFF,oB0B8GE,sBAMJ,oBACE,YACA,aACA,sBACA,WACA,mCACA,oBAGF,e3BglBoC,gB2B9kBlC,2BjBtEE,gMiBkFI,eACE,eACA,yBjBjGN,kBiB6FA,oBAoBI,2BACA,+BAEA,kBACE,8CAEA,iBACE,yCAGF,mB7BnIkB,oN6B0IpB,gBACE,sCAcF,gBACE,oCAGF,uBACE,gBAGA,mCAGF,YACE,4BjBhJN,gMiBkFI,eACE,eACA,yBjBjGN,kBiB6FA,oBAoBI,2BACA,+BAEA,kBACE,8CAEA,iBACE,yCAGF,mB7BnIkB,oN6B0IpB,gBACE,sCAcF,gBACE,oCAGF,uBACE,gBAGA,mCAGF,YACE,4BjBhJN,gMiBkFI,eACE,eACA,yBjBjGN,kBiB6FA,oBAoBI,2BACA,+BAEA,kBACE,8CAEA,iBACE,yCAGF,mB7BnIkB,oN6B0IpB,gBACE,sCAcF,gBACE,oCAGF,uBACE,gBAGA,mCAGF,YACE,4BjBhJN,gMiBkFI,eACE,eACA,yBjBjGN,kBiB6FA,oBAoBI,2BACA,+BAEA,kBACE,8CAEA,iBACE,yCAGF,mB7BnIkB,oN6B0IpB,gBACE,sCAcF,gBACE,oCAGF,uBACE,gBAGA,mCAGF,YACE,iBAhEN,oBAoBI,2BACA,+KAnBA,eACE,eACA,4BAmBF,kBACE,2CAEA,iBACE,sCAGF,mB7BnIkB,kM6B0IpB,gBACE,mCAcF,gBACE,iCAGF,uBACE,gBAGA,gCAGF,YACE,6BAcR,oB3BigBkC,qECxtBlC,oBDwtBkC,qC2BxfhC,oB3BsfgC,qFCttBlC,oBDutBkC,8C2Bhf9B,oB3Bkf8B,2K2B7ehC,oB3B4egC,+B2BpelC,oB3BkekC,4BAKA,oC2BlelC,kRACE,4BAGF,oB3BydkC,8B2BvdhC,oB3BydgC,uECxtBlC,oBDwtBkC,4B2B7clC,U7BnRM,mEGQN,UHRM,oC6B4RJ,0B7BlPgB,mFGlClB,0BHmCwB,6C6BwPpB,2B3Bub8B,uK2BlbhC,U7BxSI,8B6BgTN,0B7BtQkB,kCEkrBgB,mC2BvalC,wRACE,2BAGF,0B7B/QkB,6B6BiRhB,U7B3TI,qEGQN,UHRM,O8BJR,iBACE,aACA,sBACA,YACA,qBAEA,sB9BFM,2B8BIN,kCACA,qBtBKE,UsBFF,cACE,cACA,mBAGF,kBACE,sBACA,+BAEA,kBACE,2CtBCF,4CACA,8BsBEA,qBACE,+CtBUF,8CACA,+DsBJF,YAEE,YAIJ,aAGE,eAGA,gB5B+wBkC,a4B1wBpC,mB9BrBgB,gB8ByBhB,kBACE,gBACA,uBAGF,eACE,kB3BrDA,oB2B0DE,uBAGF,mB5BwvBkC,c4B/uBpC,qBACE,gBACA,iC5BkvBkC,yC4B/uBlC,0BAEA,yDtBvEE,csB4EJ,qBACE,iC5BuuBkC,sC4BpuBlC,yBAEA,yDtBlFE,mBsB4FJ,sBACE,sBACA,sBACA,gBACA,oBAGF,sBACE,sBACA,mBAIF,iBACE,MACA,QACA,SACA,OACA,gB5B4sBkC,kCM1zBhC,0CsBmHJ,aAGE,WACA,yBAGF,0CtBjHI,4CACA,4BsBqHJ,8CtBxGI,8CACA,kBsBgHF,kB5BorBkC,wBUlxBhC,WkB6FJ,YAMI,mBACA,mBACA,kBACA,kBAEA,WAEE,kB5BwqB8B,gB4BtqB9B,iB5BsqB8B,oB4BxpBlC,kB5BwpBkC,wBUlxBhC,YkBuHJ,YAQI,mBACA,mBAGA,WAEE,gBACA,yBAEA,aACE,cACA,oCAKA,yBtBzKJ,6BACA,kGsB2KM,yBAGE,qGAEF,4BAGE,qCAIJ,wBtB1KJ,4BACA,oGsB4KM,wBAGE,uGAEF,2BAGE,sBAcV,mB9BjNc,wBY0BZ,ckBsLJ,c5B+lBoC,mBACA,U4BxlBhC,SACA,qBAEA,oBACE,WACA,aAUN,oBACE,kBAEA,eACE,qCAEA,eACE,6BtBvOF,4BACA,sCsB0OA,wBtBzPA,0BACA,+BsB4PA,etBtQA,mBsBwQE,aC1RN,YACE,eACA,oBACA,mB7BoiCkC,gB6BjiClC,yB7BGS,qBMSP,mCuBLF,kB7BwhCkC,2C6BrhChC,UACE,oB7BohC8B,cAxhCzB,Y6BOL,iDAUJ,yBACE,iDAGF,oBACE,yBAGF,a7BzBS,a8BbX,YACE,e3BGA,gBACA,qBGaE,YwBZJ,iBACE,cACA,qBACA,iBACA,iB9BoxBkC,cA/mBM,sBFvKlC,yBgCON,kBAEA,SACE,c9B+JsC,qB8B7JtC,yB9BXO,qBACA,kB8BeT,SACE,U9B4wBgC,2CA5ZN,mC8BxW1B,aACE,8BxBaF,iCACA,kCwBTA,8BxBNA,kCACA,8BwBUF,SACE,WhCtCI,yBEkPsB,qD8BtM5B,a9BvCS,oB8ByCP,YAEA,sBhChDI,qBEEG,2B+BPT,qBACE,kBhCqFe,gBCgJW,kD+B9NxB,4BzBqCF,gCACA,iDyBjCE,6BzBkBF,iCACA,2ByBhCF,oBACE,mBhCqFe,gBCiJW,kD+B/NxB,4BzBqCF,gCACA,iDyBjCE,6BzBkBF,iCACA,Q0B9BJ,oBACE,mBACA,cjCiEE,gBCwN0B,cgCtR5B,kBACA,mBACA,wBACA,qB1BKE,8H0BHF,wCjBKI,OiBfN,ejBgBQ,8BdLN,oB+BGI,cAKJ,YACE,uDAKJ,iBACE,SACA,aAOF,kBhCg4BoC,sCMr5BhC,gB0BgCF,UCjDA,yBjC2Ea,6CC5Db,UgCVI,yBACA,6CAGF,SAEE,0CACA,kBDqCJ,aCjDA,yBjC2Ea,iDC5Db,agCVI,yBACA,iDAGF,SAEE,4CACA,gBDqCJ,UCjDA,yBjC2Ea,6CC5Db,UgCVI,yBACA,6CAGF,SAEE,yCACA,aDqCJ,UCjDA,sBjC2Ea,uCC5Db,UgCVI,yBACA,uCAGF,SAEE,yCACA,gBDqCJ,UCjDA,yBjC2Ea,6CC5Db,UgCVI,yBACA,6CAGF,SAEE,2CACA,eDqCJ,UCjDA,yBjC2Ea,2CC5Db,UgCVI,yBACA,2CAGF,SAEE,0CACA,cDqCJ,aCjDA,yBjC2Ea,yCC5Db,agCVI,yBACA,yCAGF,SAEE,4CACA,aDqCJ,UCjDA,yBjC2Ea,uCC5Db,UgCVI,yBACA,uCAGF,SAEE,yCACA,uBDqCJ,UCjDA,yBjC2Ea,2DC5Db,UgCVI,yBACA,2DAGF,SAEE,0CACA,sBDqCJ,UCjDA,yBjC2Ea,yDC5Db,UgCVI,yBACA,yDAGF,SAEE,0CACA,YCbN,iBACE,mBlCwzBkC,yBAhzBzB,oBMSP,wBI0CA,WwB5DJ,iBAQI,mBAIJ,eACE,eACA,gB5BIE,Q6BdJ,iBACE,uBACA,mBnCw9BkC,6BmCt9BlC,qB7BUE,gB6BLJ,aAEE,aAIF,enC6Q8B,oBmCpQ9B,kBACE,2BAGA,iBACE,MACA,QACA,UACA,uBACA,cACA,gBAUF,aACqH,yBAA5F,qBAA4C,mBC5CrE,wBACE,4BAGF,aACE,kBDsCF,aACqH,yBAA5F,qBAA4C,qBC5CrE,wBACE,8BAGF,aACE,gBDsCF,aACqH,yBAA5F,qBAA4C,mBC5CrE,wBACE,4BAGF,aACE,aDsCF,aACqH,sBAA5F,qBAA4C,gBC5CrE,wBACE,yBAGF,aACE,gBDsCF,aACqH,yBAA5F,qBAA4C,mBC5CrE,wBACE,4BAGF,aACE,eDsCF,aACqH,yBAA5F,qBAA4C,kBC5CrE,wBACE,2BAGF,aACE,cDsCF,aACqH,yBAA5F,qBAA4C,iBC5CrE,wBACE,0BAGF,aACE,aDsCF,aACqH,yBAA5F,qBAA4C,gBC5CrE,wBACE,yBAGF,aACE,uBDsCF,aACqH,yBAA5F,qBAA4C,0BC5CrE,wBACE,mCAGF,aACE,sBDsCF,aACqH,yBAA5F,qBAA4C,yBC5CrE,wBACE,kCAGF,aACE,iCCRF,KACE,8BACA,mCAIJ,YACE,YrCi+BkC,gBqC/9BlC,cACA,kBtC6EiB,yBChFR,qBMSP,e+BCJ,YACE,sBACA,uBACA,gBACA,WvCfM,kBuCiBN,mBACA,yBrCs9BkC,0BqCp9BlC,wCtBRI,csBDN,etBEQ,wBsBUR,oMCYE,0BDVA,wBAIA,iDACE,wCAGE,uBAJJ,cAKM,SE1CR,YACE,uBACA,aAGF,MACE,aCFF,YACE,sBACA,eAGA,gBACA,qBlCQE,yBkCEJ,UACE,cxCPS,mBwCST,6DvCPA,SuCWE,cxCbO,qBwCeP,yBxCrBO,gCwCyBT,U1CjBW,yBEPF,kBwCmCX,iBACE,cACA,sBACA,sB1CvCM,kC0C2CN,8BAEA,8BlC1BE,gCACA,6BkC6BF,kClChBE,kCACA,qDkCmBF,axChDS,oBwCmDP,sB1CxDI,yB0C6DN,SACE,W1CtDS,sBARL,8BA+ByB,mC0CqC/B,kBACE,0CAEA,eACE,qBxC4JwB,wBwC7I1B,kBACE,qDAGE,gClC1BJ,0BAZA,oDkC2CI,8BlC3CJ,4BAYA,gDkCoCI,YACE,0DAGF,oBxC2HsB,oBwCzHpB,iEAEA,gBACE,sBxCsHkB,wBUhL1B,0B8BmCA,kBACE,wDAGE,gClC1BJ,0BAZA,uDkC2CI,8BlC3CJ,4BAYA,mDkCoCI,YACE,6DAGF,oBxC2HsB,oBwCzHpB,oEAEA,gBACE,sBxCsHkB,yBUhL1B,0B8BmCA,kBACE,wDAGE,gClC1BJ,0BAZA,uDkC2CI,8BlC3CJ,4BAYA,mDkCoCI,YACE,6DAGF,oBxC2HsB,oBwCzHpB,oEAEA,gBACE,sBxCsHkB,yBUhL1B,0B8BmCA,kBACE,wDAGE,gClC1BJ,0BAZA,uDkC2CI,8BlC3CJ,4BAYA,mDkCoCI,YACE,6DAGF,oBxC2HsB,oBwCzHpB,oEAEA,gBACE,sBxCsHkB,yBUhL1B,0B8BmCA,kBACE,wDAGE,gClC1BJ,0BAZA,uDkC2CI,8BlC3CJ,4BAYA,mDkCoCI,YACE,6DAGF,oBxC2HsB,oBwCzHpB,oEAEA,gBACE,sBxCsHkB,oBwCvG9B,elCnHI,oCkCsHF,oBACE,+CAEA,qBACE,0BCzIJ,aDqJwE,yBAA/B,6GvCxIzC,auCwIwE,yBC9IlE,wDAGF,U3CLE,yB0CgJkE,iDCrJxE,aDqJwE,yBAA/B,iHvCxIzC,auCwIwE,yBC9IlE,0DAGF,U3CLE,yB0CgJkE,+CCrJxE,aDqJwE,yBAA/B,6GvCxIzC,auCwIwE,yBC9IlE,wDAGF,U3CLE,yB0CgJkE,4CCrJxE,aDqJwE,yBAA/B,uGvCxIzC,auCwIwE,yBC9IlE,qDAGF,U3CLE,yB0CgJkE,+CCrJxE,aDqJwE,yBAA/B,6GvCxIzC,auCwIwE,yBC9IlE,wDAGF,U3CLE,yB0CgJkE,8CCrJxE,aDqJwE,yBAA/B,2GvCxIzC,auCwIwE,yBC9IlE,uDAGF,U3CLE,yB0CgJkE,6CCrJxE,aDqJwE,yBAA/B,yGvCxIzC,auCwIwE,yBC9IlE,sDAGF,U3CLE,yB0CgJkE,4CCrJxE,aDqJwE,yBAA/B,uGvCxIzC,auCwIwE,yBC9IlE,qDAGF,U3CLE,yB0CgJkE,sDCrJxE,aDqJwE,yBAA/B,2HvCxIzC,auCwIwE,yBC9IlE,+DAGF,U3CLE,yB0CgJkE,qDCrJxE,aDqJwE,yBAA/B,yHvCxIzC,auCwIwE,yBC9IlE,8DAGF,U3CLE,yB0CgJkE,6BExJ1E,WACE,iB3CwFiB,gBCuMW,c0C5R5B,W1CaS,yBA2kCyB,W0CrlClC,czCKA,UDKS,qB0CLP,uFzCIF,WyCCI,cAWN,SACE,6BACA,SACA,kBAMF,mBACE,aChCF,eAEE,oBAEA,iBACE,gBACA,QAKJ,cACE,MACA,OACA,a3C4pBkC,a2C1pBlC,WACA,YACA,gBACA,UAGA,eAOF,iBACE,WACA,a3Cg5BkC,oB2C74BlC,2BAGA,iCACE,8B3Cs6BgC,wCe97B9B,0B4BuBJ,e5BtBM,4B4B0BN,c3Co6BkC,mC2C/5BlC,qB3Ci6BkC,0B2C55BpC,YACE,6BACA,yCAEA,6BACE,gBACA,+EAGF,aAEE,sCAGF,eACE,wBAIJ,YACE,mBACA,6BACA,gCAGA,aACE,0BACA,mBACA,WACA,gDAIF,qBACE,uBACA,YACA,+DAEA,eACE,wDAGF,YACE,gBAMN,iBACE,aACA,sBACA,WACA,oBAGA,sB7CzGM,4B6C2GN,gCACA,oBrClGE,UqCsGF,iBAIF,cACE,MACA,OACA,a3CgjBkC,Y2C9iBlC,aACA,sB3CjHS,sB2CqHT,+BACA,U7CzEuB,e6C8EzB,YACE,uBACA,8BACA,kB3C4zBkC,gC2C1zBlC,0CrCtHE,2CACA,sBqCwHF,iB3CuzBkC,8B2CpzBhC,cAKJ,eACE,gB3CuI4B,a2CjI9B,iBACE,cAGA,a3CywBkC,e2CpwBpC,YACE,eACA,mBACA,yBACA,eACA,6BACA,8CrCzIE,6CACA,iBqC8IF,aACE,0BAKJ,iBACE,YACA,WACA,YACA,gBACA,wBjCvIE,ciC6IF,e3CswBkC,oB2CpwBhC,0BAGF,8BACE,yCAEA,+BACE,wBAIJ,8BACE,gCAEA,2BACE,mBACA,WAQJ,e3C6uBkC,yBUp5BhC,oBiC2KF,e3CuuBkC,yBUl5BhC,UiCkLF,gB3C+tBkC,W4C58BpC,iBACE,a5CgrBkC,c4C9qBlC,S5C41BkC,2HF90BX,kB+CfvB,gB7C4R4B,gBAKA,gB6C9R5B,iBACA,qBACA,iBACA,oBACA,sBACA,kBACA,oBACA,mBACA,gBACA,mB9C0EiB,qB6C9EjB,UACA,eAEA,U5C+0BkC,iB4C70BlC,iBACE,cACA,Y5Cg1BgC,aACA,yB4C70BhC,iBACE,WACA,yBACA,mBACA,oDAKN,eACE,kEAEA,QACE,kFAEA,KACE,2BACA,sB5CtBK,wD4C4BX,eACE,sEAEA,MACE,Y5CkzBgC,aADA,sF4C7yBhC,OACE,iCACA,wB5CtCK,0D4C4CX,eACE,wEAEA,KACE,wFAEA,QACE,2BACA,yB5CpDK,sD4C0DX,eACE,oEAEA,OACE,Y5CoxBgC,aADA,oF4C/wBhC,MACE,iCACA,uB5CpEK,gB4C0FX,e5C8uBoC,qB4C5uBlC,W9CrGM,kB8CuGN,sB5C9FS,qBMCP,UwClBJ,iBACE,MACA,OACA,a9C8qBkC,c8C5qBlC,gB9C82BkC,2HFj2BX,kB+CfvB,gB7C4R4B,gBAKA,gB6C9R5B,iBACA,qBACA,iBACA,oBACA,sBACA,kBACA,oBACA,mBACA,gBACA,mB9C0EiB,qB+C7EjB,sBhDJM,4BgDMN,gCACA,oBxCGE,iBwCCF,iBACE,cACA,W9C82BgC,aACA,e8C52BhC,gDAEA,iBAEE,cACA,WACA,yBACA,mBACA,oDAKN,mB9C+1BoC,kE8C51BlC,0BACE,kFAEA,QACE,2BACA,iC9C01B8B,gF8Ct1BhC,U9C2L0B,2B8CzLxB,sBhD3CE,wDgDiDR,iB9C20BoC,sE8Cx0BlC,wBACE,Y9Cu0BgC,YADA,e8Cn0BhC,sFAEA,MACE,iCACA,mC9Cm0B8B,oF8C/zBhC,Q9CoK0B,iC8ClKxB,wBhDlEE,0DgDwER,gB9CozBoC,wE8CjzBlC,uBACE,wFAEA,KACE,iCACA,oC9C+yB8B,sF8C3yBhC,O9CgJ0B,iC8C9IxB,yBhDtFE,0GgD4FN,iBACE,MACA,SACA,cACA,W9C2xBgC,oB8CzxBhC,WACA,gCACA,sDAIJ,kB9CoxBoC,oE8CjxBlC,yBACE,Y9CgxBgC,YADA,e8C5wBhC,oFAEA,OACE,iCACA,kC9C4wB8B,kF8CxwBhC,S9C6G0B,iC8C3GxB,uBhDzHE,iBgDgJR,oBACE,gBACA,e/CjEiB,yBCiyBiB,gC8C5tBlC,0CxCnIE,2CACA,uBwCqIF,YACE,eAIJ,oBACE,WhDvJW,WiDHb,iBACE,yBAGF,kBACE,iBAGF,iBACE,WACA,gBACA,wBCvBA,aACE,WACA,WACA,gBDwBJ,iBACE,aACA,WACA,WACA,mBACA,2BACA,qCACA,wChCfI,egCQN,ehCPQ,gEgCiBR,aAGE,0EAGF,0BAEE,0EAGF,2BAEE,+BASA,SACE,4BACA,eACA,mJAGF,SAGE,UACA,sFAGF,SAEE,UACA,0BACA,wChCzDE,qFgCqDJ,ehCpDM,gDgCiER,iBAEE,MACA,SACA,UACA,aAEA,mBACA,uBACA,U/Cq9BmC,WF5iC7B,kBiD0FN,W/Cm9BmC,6B+Cj9BnC,wChChFI,8CgCkEN,ehCjEQ,sHdLN,UHRM,qBiDiGJ,UACA,W/C48BiC,wB+Cx8BrC,MACE,wBAKF,OACE,yDAOF,oBAEE,W/Cq8BmC,+C+Cl8BnC,6BAEF,wNACE,6BAEF,yNACE,sBASF,iBACE,QACA,SACA,OACA,WACA,aACA,uBACA,eACA,iB/C45BmC,gC+Cx5BnC,yBAEA,sBACE,cACA,W/Cy5BiC,WACA,iBAEA,mC+Cv5BjC,eACA,sBjD9JI,4BiDgKJ,kCAEA,qCACA,WACA,4BACA,wChCzJE,wBgC0IJ,ehCzIM,+BgC2JN,SACE,mBASJ,iBACE,UACA,YACA,SACA,WACA,iBACA,oBACA,WjDzLM,kBiD2LN,2BE/LF,GACE,0CAGF,oBACE,WjDqkCsB,uCiDlkCtB,gCACA,+BACA,kBAEA,8CACA,oBAGF,UjD8jC0B,8BAEA,yBiDtjC1B,GACE,kBACE,KAEF,SACE,eACA,gBAIJ,oBACE,WjDqiCsB,uCiDliCtB,8BACA,kBAEA,UACA,4CACA,kBAGF,UjD8hC0B,oDiDxhCxB,8BACE,uBAEE,kBC3DN,8CACA,4CACA,+CACA,oDACA,sDACA,+CCFE,mCACE,uFlDUF,mCkDLI,eANJ,mCACE,+FlDUF,mCkDLI,aANJ,mCACE,uFlDUF,mCkDLI,UANJ,gCACE,2ElDUF,mCkDLI,aANJ,mCACE,uFlDUF,mCkDLI,YANJ,mCACE,mFlDUF,mCkDLI,WANJ,mCACE,+ElDUF,mCkDLI,UANJ,mCACE,2ElDUF,mCkDLI,oBANJ,mCACE,mHlDUF,mCkDLI,mBANJ,mCACE,+GlDUF,mCkDLI,WCCN,gCACE,iBAGF,uCACE,SCXF,gDACA,sDACA,yDACA,wDACA,mDAEA,kCACA,wCACA,2CACA,0CACA,yCAGE,+BACE,mBADF,+BACE,iBADF,+BACE,cADF,4BACE,iBADF,+BACE,gBADF,+BACE,eADF,+BACE,cADF,+BACE,wBADF,+BACE,uBADF,+BACE,eAIJ,4BACE,aAOF,8BACE,uDAGF,+BACE,cAGF,wCACE,0CACA,gBAGF,yCACE,6CACA,iBAGF,4CACE,4CACA,eAGF,wCACE,4CACA,aAGF,8BACE,iBAGF,4BACE,eAGF,8BACE,YAGF,0BACE,kBLxEA,aACE,WACA,WACA,SMOE,2W5CiDF,W4CjDE,oY5CiDF,W4CjDE,oY5CiDF,W4CjDE,oY5CiDF,W4CjDE,0XAUN,cAEI,uZCrBJ,iBACE,cACA,WACA,UACA,gBACA,2BAEA,aACE,WACA,4IAGF,iBAKE,MACA,SACA,OACA,WACA,YACA,SACA,iCASA,0BACE,iCADF,kBACE,gCADF,eACE,gCADF,gBACE,WCzBF,2CACA,mDACA,2DACA,oDAEA,uCACA,+CACA,6CACA,sCACA,oCACA,sCACA,wCACA,gDAEA,2DACA,4DACA,2DACA,iEACA,2DAEA,mDACA,oDACA,oDACA,qDACA,oDAEA,uDACA,wDACA,uDACA,6DACA,6DACA,kDAEA,6CACA,iDACA,kDACA,kDACA,mDACA,qD9CYA,a8ClDA,8CACA,sDACA,8DACA,uDAEA,0CACA,kDACA,gDACA,yCACA,uCACA,yCACA,2CACA,mDAEA,8DACA,+DACA,8DACA,oEACA,8DAEA,sDACA,uDACA,uDACA,wDACA,uDAEA,0DACA,2DACA,0DACA,gEACA,gEACA,qDAEA,gDACA,oDACA,qDACA,qDACA,sDACA,sD9CYA,a8ClDA,8CACA,sDACA,8DACA,uDAEA,0CACA,kDACA,gDACA,yCACA,uCACA,yCACA,2CACA,mDAEA,8DACA,+DACA,8DACA,oEACA,8DAEA,sDACA,uDACA,uDACA,wDACA,uDAEA,0DACA,2DACA,0DACA,gEACA,gEACA,qDAEA,gDACA,oDACA,qDACA,qDACA,sDACA,sD9CYA,a8ClDA,8CACA,sDACA,8DACA,uDAEA,0CACA,kDACA,gDACA,yCACA,uCACA,yCACA,2CACA,mDAEA,8DACA,+DACA,8DACA,oEACA,8DAEA,sDACA,uDACA,uDACA,wDACA,uDAEA,0DACA,2DACA,0DACA,gEACA,gEACA,qDAEA,gDACA,oDACA,qDACA,qDACA,sDACA,sD9CYA,a8ClDA,8CACA,sDACA,8DACA,uDAEA,0CACA,kDACA,gDACA,yCACA,uCACA,yCACA,2CACA,mDAEA,8DACA,+DACA,8DACA,oEACA,8DAEA,sDACA,uDACA,uDACA,wDACA,uDAEA,0DACA,2DACA,0DACA,gEACA,gEACA,qDAEA,gDACA,oDACA,qDACA,qDACA,sDACA,2CC1CA,mCACA,mCACA,6C/CoDA,e+CtDA,sCACA,sCACA,8C/CoDA,e+CtDA,sCACA,sCACA,8C/CoDA,e+CtDA,sCACA,sCACA,8C/CoDA,e+CtDA,sCACA,sCACA,wCCLF,4NCCA,4NAKF,cACE,MACA,QACA,OACA,a3DiqBkC,e2D7pBpC,cACE,QACA,SACA,OACA,a3DypBkC,6B2DppBlC,YADF,eAEI,MACA,a3DipBgC,wL4DzqBpC,iBCEE,UACA,WACA,UACA,YACA,gBACA,sBACA,mBACA,SACA,oDAUA,eAEE,WACA,YACA,iBACA,UACA,mBACA,YC7BJ,gEACA,8DACA,gEACA,iCCCI,+RAIJ,kCACA,uCAIA,uCACA,oCAEA,+BACA,6BCTQ,gCACA,uBAEE,aAEF,yBAEE,aAEF,0BAEE,aAEF,wBAEE,MAfF,qCACA,4BAEE,aAEF,8BAEE,aAEF,+BAEE,aAEF,6BAEE,MAfF,6EACA,2BAEE,aAEF,6BAEE,aAEF,8BAEE,aAEF,4BAEE,MAfF,kFACA,0BAEE,aAEF,4BAEE,aAEF,6BAEE,aAEF,2BAEE,MAfF,qCACA,4BAEE,aAEF,8BAEE,+BAEF,+BAEE,iDAEF,6BAEE,MAfF,mCACA,0BAEE,aAEF,4BAEE,aAEF,6BAEE,aAEF,2BAEE,MAfF,iCACA,wBAEE,aAEF,0BAEE,aAEF,2BAEE,aAEF,yBAEE,MAfF,sCACA,6BAEE,aAEF,+BAEE,aAEF,gCAEE,aAEF,8BAEE,MAfF,qCACA,4BAEE,aAEF,8BAEE,aAEF,+BAEE,aAEF,6BAEE,MAfF,oCACA,2BAEE,aAEF,6BAEE,aAEF,8BAEE,aAEF,4BAEE,MAfF,sCACA,6BAEE,aAEF,+BAEE,aAEF,gCAEE,aAEF,8BAEE,MAfF,oCACA,2BAEE,aAEF,6BAEE,aAEF,8BAEE,aAEF,4BAEE,OAQF,yCACA,8BAEE,eAEF,gCAEE,eAEF,iCAEE,eAEF,+BAEE,OAfF,wCACA,6BAEE,eAEF,+BAEE,eAEF,gCAEE,eAEF,8BAEE,OAfF,sCACA,2BAEE,eAEF,6BAEE,eAEF,8BAEE,eAEF,4BAEE,OAfF,wCACA,6BAEE,eAEF,+BAEE,eAEF,gCAEE,eAEF,8BAEE,OAfF,sCACA,2BAEE,eAEF,6BAEE,eAEF,8BAEE,eAEF,4BAEE,SAMN,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,wBtDTF,QsDlDI,sCACA,uBAEE,mBAEF,yBAEE,mBAEF,0BAEE,mBAEF,wBAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,uCACA,wBAEE,mBAEF,0BAEE,mBAEF,2BAEE,mBAEF,yBAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,UAQF,+CACA,8BAEE,qBAEF,gCAEE,qBAEF,iCAEE,qBAEF,+BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,YAMN,+CACA,0BAEE,yBAEF,4BAEE,yBAEF,6BAEE,yBAEF,2BAEE,yBtDTF,QsDlDI,sCACA,uBAEE,mBAEF,yBAEE,mBAEF,0BAEE,mBAEF,wBAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,uCACA,wBAEE,mBAEF,0BAEE,mBAEF,2BAEE,mBAEF,yBAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,UAQF,+CACA,8BAEE,qBAEF,gCAEE,qBAEF,iCAEE,qBAEF,+BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,YAMN,+CACA,0BAEE,yBAEF,4BAEE,yBAEF,6BAEE,yBAEF,2BAEE,yBtDTF,QsDlDI,sCACA,uBAEE,mBAEF,yBAEE,mBAEF,0BAEE,mBAEF,wBAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,uCACA,wBAEE,mBAEF,0BAEE,mBAEF,2BAEE,mBAEF,yBAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,UAQF,+CACA,8BAEE,qBAEF,gCAEE,qBAEF,iCAEE,qBAEF,+BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,YAMN,+CACA,0BAEE,yBAEF,4BAEE,yBAEF,6BAEE,yBAEF,2BAEE,yBtDTF,QsDlDI,sCACA,uBAEE,mBAEF,yBAEE,mBAEF,0BAEE,mBAEF,wBAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,uCACA,wBAEE,mBAEF,0BAEE,mBAEF,2BAEE,mBAEF,yBAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,UAQF,+CACA,8BAEE,qBAEF,gCAEE,qBAEF,iCAEE,qBAEF,+BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,YAMN,+CACA,0BAEE,yBAEF,4BAEE,yBAEF,6BAEE,yBAEF,2BAEE,yBChEJ,iBACE,MACA,QACA,SACA,OACA,UACA,oBAEA,WACA,+BAEA,kCCVJ,oHAIA,yCACA,2CACA,6CACA,eCTE,uBACA,mBACA,YDeE,uCACA,yCACA,oDxDqCA,cwDvCA,0CACA,4CACA,qDxDqCA,cwDvCA,0CACA,4CACA,qDxDqCA,cwDvCA,0CACA,4CACA,qDxDqCA,cwDvCA,0CACA,4CACA,8CAMJ,oDACA,qDACA,wDAIA,gDACA,mDACA,6CACA,+CACA,2CACA,yCAIA,oCEvCE,wBACE,2CnEUF,wBmELM,iBANN,wBACE,+CnEUF,wBmELM,eANN,wBACE,2CnEUF,wBmELM,YANN,qBACE,qCnEUF,wBmELM,eANN,wBACE,2CnEUF,wBmELM,cANN,wBACE,yCnEUF,wBmELM,aANN,wBACE,uCnEUF,wBmELM,YANN,wBACE,qCnEUF,wBmELM,sBANN,wBACE,yDnEUF,wBmELM,qBANN,wBACE,uDnEUF,wBmELM,YFuCR,yEACA,wCAEA,+CACA,iDAIA,UGvDE,kBACA,iBACA,6BACA,SACA,uBHuDF,4CAEA,gCACE,gCACA,aAKF,kCIjEA,6BACE,YAGF,4BACE,mCCCE,2BAKE,2BAEA,aAIA,yBACE,oBASJ,4BACE,KAcF,+BACE,gBAEF,wBAEE,wBACA,OAQF,0BACE,QAGF,uBAEE,SAGF,SAGE,SACA,OAGF,sBAEE,OAQF,OvEgiCgC,MuE7hChC,wBACE,YAEF,wBACE,SAIF,YACE,QAEF,qBACE,QAGF,mCACE,qBAEA,gCAEE,uCAKF,mCAEE,aAIJ,aACE,4EAEA,oBzE3HM,uByEmIR,aACE,qBzEpIM,S0EoCZ,YACE,mBACA,qBACA,uBACA,kBACA,yBAzCgB,gBA8ChB,wBApCe,cAoCf,wBApCe,aAoCf,wBApCe,aAoCf,wBApCe,gBAoCf,wBApCe,eA0Cf,2BACE,sgBACA,aAFF,2BACE,kzBACA,YAFF,2BACE,0wBACA,YAFF,2BACE,00HACA,eAFF,2BACE,0uBACA,eAIJ,kBACE,WApDmB,gBAwDrB,WACE,4BACA,cAGF,gBACE,gBAGF,oBACE,uCAEA,UApEmB,wBAyEnB,UACE,qBACA,+CAIJ,qBACE,YACA,eACA,gBACA,iBACA,WApFmB,yBAsFnB,WACA,YACA,eACA,uBACA,SACA,qDAEA,UAEE,qBACA,eACA,WACA,YACA,0BAGF,YACE,sBACA,uBACA,qBAIJ,iBACE,OACA,SACA,WACA,sBACA,WACA,kBAWF,cACE,eACA,oBAEA,sGAEF,UAGE,oBACA,OACA,QACA,kHAEF,eAGE,oBACA,2HAEF,mBAGE,oBAEF,0BACE,8BACA,sBACA,sBAEF,cACE,YACA,8BACA,gCACA,4BACA,yBACA,WAlKmB,WAoKnB,yBAEF,wBACE,UACA,eACA,wFAGF,SAEE,YACA,uBAIF,KACE,QACA,WACA,0BAEF,QACE,QACA,WACA,iBAEF,QAnKiB,6BAuKjB,QAvKiB,kBA0KjB,QA1KiB,gCA8KjB,UA9KiB,kCAkLjB,WAlLiB,oBAqLjB,WArLiB,yBAyLjB,OACE;;;EC7NF,CCGA,WACE,0BACA,4CACA,wSAMA,mBACA,kBCVF,IACE,qBACA,6CACA,kBACA,oBACA,mCACA,kCCLF,OACE,yBACA,kBACA,oBAEF,qBACA,qBACA,qBACA,qBCVA,OACE,qBACA,kBCDF,OACE,eACA,0BCMoB,CDLpB,qBACA,4BAEF,OACE,kBACA,qBACA,oBCDoB,CDEpB,kBACA,kBACA,aACE,qBEbJ,WACE,yBACA,wBACA,mBAGF,yBACA,2BAGE,mCACA,mCAIF,wBACA,sBAGE,gCACA,gCCpBF,SACE,6CACQ,qCAGV,UACE,+CACQ,uCAGV,2BACE,GACE,+BACQ,uBAEV,KACE,iCACQ,0BAIZ,mBACE,GACE,+BACQ,uBAEV,KACE,iCACQ,0BC5BZ,cCWE,sEACA,gCACI,4BACI,wBDbV,eCUE,sEACA,iCACI,6BACI,yBDZV,eCSE,sEACA,iCACI,6BACI,yBDVV,oBCcE,gFACA,+BACI,2BACI,uBDhBV,kBCaE,gFACA,+BACI,2BACI,uBDXV,gHAKE,YEfF,UACE,kBACA,qBACA,UACA,WACA,gBACA,sBAEF,0BACE,kBACA,OACA,WACA,kBAEF,iCACA,2BACA,sBLTsB,CMPtB,4BNwUe,CMvUf,4BN2de,CM1df,6BN0jBgB,CMzjBhB,iCNsOoB,CMrOpB,4BNuWe,CMtWf,2BNknBc,CMjnBd,6BNsnBgB,CMrnBhB,2BNytBc,CMxtBd,2BNmRc,CMlRd,+BNupBkB,CMtpBlB,yBNqpBY,CMppBZ,8BNspBiB,CMrpBjB,4BNyIe,CMxIf,oDAEkC,WNqqBnB,CMpqBf,kCN8iBqB,CM7iBrB,mCN4iBsB,CM3iBtB,gCN4fmB,CM3fnB,6BNikBgB,CMhkBhB,+BACgC,WNgKnB,CM/Jb,8BN+qBiB,CM9qBjB,2BNwVc,CMvVd,6BNuPgB,CMtPhB,8BNgJiB,CM/IjB,2BNmhBc,CMlhBd,+BNgMkB,CM/LlB,0CNY6B,CMX7B,wCNc2B,CMb3B,4BNqWe,CMpWf,oCNweuB,CMvevB,0CACmC,WNsgBnB,CMrgBhB,8BNggBiB,CM/fjB,+BNwYkB,CMvYlB,2BN2Yc,CM1Yd,2BN4Pc,CM3Pd,iCNoUoB,CMnUpB,iCNitBoB,CMhtBpB,kCN+sBqB,CM9sBrB,gCNgtBmB,CM/sBnB,6BNyegB,CMxehB,8BNwBiB,CMvBjB,0BNymBa,CMxmBb,2BNymBc,CMxmBd,2BNyDc,CMxDd,+BNyDkB,CMxDlB,4BN+de,CM9df,6BN2EgB,CM1EhB,2BN0Pc,CMzPd,2BNiDc,CMhDd,6BN0VgB,CMzVhB,kCNwmBqB,CMvmBrB,iCNwmBoB,CMvmBpB,iCNpCoB,CMqCpB,mCNvCsB,CMwCtB,kCNrCqB,CMsCrB,oCNxCuB,CMyCvB,2BN+Wc,CM9Wd,qCACoC,WN2anB,CM1ajB,6BNsUgB,CMrUhB,mCNkrBsB,CMjrBtB,uDAEsC,WN0bnB,CMzbnB,6BNkbgB,CMjbhB,iCNwXoB,CMvXpB,6BNtDgB,CMuDhB,2BNmnBc,CMlnBd,2CAC4C,WN+anB,CM9azB,qCN8fwB,CM7fxB,qCN+EwB,CM9ExB,6BNzBgB,CM0BhB,oCNmjBuB,CMljBvB,oCNqLuB,CMpLvB,+BNlBkB,CMmBlB,2BNsbc,CMrbd,4BNgae,CM/Zf,2BNmjBc,CMljBd,8BN+NiB,CM9NjB,mCNgLsB,CM/KtB,mCN4iBsB,CM3iBtB,4BN+Ie,CM9If,mCNyEsB,CMxEtB,oCNyEuB,CMxEvB,kCNkbqB,CMjbrB,mCNuXsB,CMtXtB,mCN2lBsB,CM1lBtB,mCN2DsB,CM1DtB,sCNybyB,CMxbzB,kCN0SqB,CMzSrB,iCN0GoB,CMzGpB,qCNulBwB,CMtlBxB,qCNuDwB,CMtDxB,0BNnCa,CMoCb,iCNnDoB,CMoDpB,kCNnDqB,CMoDrB,+BNnDkB,CMoDlB,iCNvDoB,CMwDpB,yCACkC,WN4dnB,CM3df,6BN8IgB,CM7IhB,+BNsFkB,CMrFlB,2BN+Zc,CM9Zd,4BNoWe,CMnWf,+BNpDkB,CMqDlB,yCNuI4B,CMtI5B,2BNkNc,CMjNd,2BN0Sc,CMzSd,2BN6Kc,CM5Kd,0BNyIa,CMxIb,gCNyImB,CMxInB,mDACiD,WNiInB,CMhI9B,4BN+Ye,CM9Yf,gCACA,6BNoagB,CMnahB,8BNgEiB,CM/DjB,6BN6TgB,CM5ThB,iCNuCoB,CMtCpB,mCNmCsB,CMlCtB,8BN+aiB,CM9ajB,oCNkduB,CMjdvB,6BN0KgB,CMzKhB,kCN2KqB,CM1KrB,+BN3EkB,CM4ElB,+BN7EkB,CM8ElB,4CACsC,WNlEnB,CMmEnB,qCN+kBwB,CM9kBxB,sCN4HyB,CM3HzB,mCNTsB,CMUtB,0BN2Qa,CM1Qb,iCACiC,WN6CnB,CM5Cd,+BNkDkB,CMjDlB,kCNsiBqB,CMriBrB,oCNoiBuB,CMniBvB,gCN2emB,CM1enB,8BN8NiB,CM7NjB,+BNockB,CMnclB,sCNuRyB,CMtRzB,iCN6hBoB,CM5hBpB,oCNsGuB,CMrGvB,8BN8biB,CM7bjB,6BNqjBgB,CMpjBhB,oCNgLuB,CM/KvB,6BNukBgB,CMtkBhB,8BNqQiB,CMpQjB,4BNiWe,CMhWf,+BN2dkB,CM1dlB,iCNjDoB,CMkDpB,mCN+VsB,CM9VtB,8BNsjBiB,CMrjBjB,0CACqC,WNgGnB,CM/FlB,6BNoKgB,CMnKhB,6BN0jBgB,CMzjBhB,kCNoCqB,CMnCrB,+BACgC,WN+YnB,CM9Yb,4BNoMe,CMnMf,+BNrDkB,CMsDlB,2BNhFc,CMiFd,kCNrBqB,CMsBrB,mCNoLsB,CMnLtB,kCNkLqB,CMjLrB,gCNmLmB,CMlLnB,kCN+KqB,CM9KrB,wCNrI2B,CMsI3B,yCNjI4B,CMkI5B,sCNjIyB,CMkIzB,wCNzI2B,CM0I3B,4BN2Je,CM1Jf,6BN6lBgB,CM5lBhB,4BNqee,CMpef,6BNyGgB,CMxGhB,gCNzEmB,CM0EnB,iCNlIoB,CMmIpB,kCACkC,WNijBnB,CMhjBf,iCACiC,WN4OnB,CM3Od,4BNde,CMef,4BN0Ge,CMzGf,mCACqC,WN6XnB,CM5XlB,mCACoC,WN2FnB,CM1FjB,gCN6SmB,CM5SnB,oCACqC,WNqGnB,CMpGlB,6BNgbgB,CM/ahB,sDAEiC,WNlInB,CMmId,8BNsOiB,CMrOjB,8BNoOiB,CMnOjB,oCN+buB,CM9bvB,gCN2gBmB,CM1gBnB,4BNuce,CMtcf,4BNyOe,CMxOf,4BN6fe,CM5ff,gCNmTmB,CMlTnB,uCNoT0B,CMnT1B,yCNgI4B,CM/H5B,kCN4HqB,CM3HrB,4BNqQe,CMpQf,iCNpFoB,CMqFpB,+BN9EkB,CM+ElB,iCNrFoB,CMsFpB,kCNrFqB,CMsFrB,8BNhCiB,CMiCjB,oCACiC,WN0YnB,CMzYd,0CACsC,WN8YnB,CM7YnB,uCACqC,WN2YnB,CM1YlB,+BNUkB,CMTlB,+BNuMkB,CMtMlB,uCACiC,WNqfnB,CMpfd,kCACkC,WNoFnB,CMnFf,2CACuC,WN+anB,CM9apB,gCN7CmB,CM8CnB,iCN1CoB,CM2CpB,iCACiC,WNpInB,CMqId,8BN6WiB,CM5WjB,+BNyekB,CMxelB,sCACsC,WNrEnB,CMsEnB,kCNqLqB,CMpLrB,+BNGkB,CMFlB,qCNnEwB,CMoExB,mCNnEsB,CMoEtB,8BNifiB,CMhfjB,kCN8YqB,CM7YrB,+BNyZkB,CMxZlB,6BN9JgB,CM+JhB,6BNlEgB,CMmEhB,8BN1CiB,CM2CjB,kCN8BqB,CM7BrB,iCN1IoB,CM2IpB,iCNsHoB,CMrHpB,gCNrOmB,CMsOnB,6BN4MgB,CM3MhB,kCNUqB,CMTrB,2BN3Kc,CM4Kd,+BNuFkB,CMtFlB,kCN2QqB,CM1QrB,wCNrO2B,CMsO3B,yCNrO4B,CMsO5B,sCNrOyB,CMsOzB,wCNzO2B,CM0O3B,iCNrOoB,CMsOpB,kCNrOqB,CMsOrB,+BNrOkB,CMsOlB,iCNzOoB,CM0OpB,8BNpDiB,CMqDjB,6BN4IgB,CM3IhB,6BNwYgB,CMvYhB,0CACmC,WNuMnB,CMtMhB,+BNzGkB,CM0GlB,iCNyQoB,CMxQpB,kCNyQqB,CMxQrB,8BN+ViB,CM9VjB,6BN9GgB,CM+GhB,uCACkC,WNoRnB,CMnRf,iCN+CoB,CM9CpB,+BNmBkB,CMlBlB,oCNoBuB,CMnBvB,8BNqUiB,CMpUjB,8BN2BiB,CM1BjB,4BNgLe,CM/Kf,8BN2BiB,CM1BjB,iCNuHoB,CMtHpB,6BNMgB,CMLhB,qCNIwB,CMHxB,+BN6XkB,CM5XlB,2BNhHc,CMiHd,+CACsC,WNuQnB,CMtQnB,4EAEwC,WNsVnB,CMrVrB,qCNwIwB,CMvIxB,2BNhGc,CMiGd,gCNvHmB,CMwHnB,0CACyC,WNtJnB,CMuJtB,+BNyOkB,CMxOlB,2BN0Fc,CMzFd,kCN1DqB,CM2DrB,kCNkWqB,CMjWrB,gCN4VmB,CM3VnB,6BNlEgB,CMmEhB,mCNgOsB,CM/NtB,iCN2JoB,CM1JpB,uCN2J0B,CM1J1B,6BNsRgB,CMrRhB,iCN5LoB,CM6LpB,wCNxB2B,CMyB3B,6BNuPgB,CMtPhB,6BN6IgB,CM5IhB,0CN9J6B,CM+J7B,2CN9J8B,CM+J9B,wCN9J2B,CM+J3B,0CNlK6B,CMmK7B,4BN8De,CM7Df,2BNrHc,CMsHd,6BNvSgB,CMwShB,iCN2ZoB,CM1ZpB,+BNhNkB,CMiNlB,iCN7FoB,CM8FpB,iCN7FoB,CM8FpB,iCN+OoB,CM9OpB,kCNiMqB,CMhMrB,6BN6WgB,CM5WhB,mCN0IsB,CMzItB,qCN0IwB,CMzIxB,+BNqFkB,CMpFlB,iCNmFoB,CMlFpB,mCNnLsB,CMoLtB,oCN0KuB,CMzKvB,2CNpF8B,CMqF9B,mCNwPsB,CMvPtB,8BNjJiB,CMkJjB,sDACgD,WN/MnB,CMgN7B,kDAC8C,WN9MnB,CM+M3B,wDACiD,WNjNnB,CMkN9B,+BACgC,WNvGnB,CMwGb,0BNhCa,CMiCb,iCACgC,WNqYnB,CMpYb,gCACgC,WN4CnB,CM3Cb,4DAGgC,WNgDnB,CM/Cb,kDAEgC,WNiNnB,CMhNb,8BACgC,WN+CnB,CM9Cb,kCACgC,WN3PnB,CM4Pb,2BNhGc,CMiGd,gCNpFmB,CMqFnB,qCN0PwB,CMzPxB,sCN0PyB,CMzPzB,sCN0PyB,CMzPzB,uCN0P0B,CMzP1B,uCN6P0B,CM5P1B,wCN6P2B,CM5P3B,gCNkUmB,CMjUnB,kCN8TqB,CM7TrB,qCNyawB,CMxaxB,8BNsaiB,CMrajB,2BN2Zc,CM1Zd,kCN2ZqB,CM1ZrB,mCNoasB,CMnatB,8BNxJiB,CMyJjB,qCN8PwB,CM7PxB,gCNgBmB,CMfnB,6BNpFgB,CMqFhB,0BN3Wa,CM4Wb,gCN/RmB,CMgSnB,uCN/R0B,CMgS1B,6BN+UgB,CM9UhB,oCN+UuB,CM9UvB,sCNgDyB,CM/CzB,oCNkDuB,CMjDvB,sCN+CyB,CM9CzB,uCN+C0B,CM9C1B,4BNjWe,CMkWf,8BNmYiB,CMlYjB,8BN7WiB,CM8WjB,4BNkCe,CMjCf,+BN5KkB,CM6KlB,4BNgNe,CM/Mf,iCNxFoB,CMyFpB,6BN4TgB,CM3ThB,6BNtIgB,CMuIhB,2BN6Cc,CM5Cd,sCACqC,WN5DnB,CM6DlB,4BN8Pe,CM7Pf,6BNuEgB,CMtEhB,8BN9WiB,CM+WjB,0BNtSa,CMuSb,yBNiWY,CMhWZ,4BNuWe,CMtWf,6BN+IgB,CM9IhB,gCNkFmB,CMjFnB,qCN6NwB,CM5NxB,2CN/W8B,CMgX9B,0CNjX6B,CMkX7B,sDACgD,WNzRnB,CM0R7B,mCNnMsB,CMoMtB,iCNiWoB,CMhWpB,mCNoVsB,CMnVtB,uCACgC,WN0SnB,CMzSb,oCN0GuB,CMzGvB,oCN4MuB,CM3MvB,4BNsLe,CMrLf,sCNzLyB,CM0LzB,gCNoWmB,CMnWnB,6BN8DgB,CM7DhB,6DAEuC,WN8SnB,CM7SpB,kDAC2C,WN1FnB,CM2FxB,4BNsWe,CMrWf,6BNlGgB,CMmGhB,6BNgHgB,CM/GhB,oCNiHuB,CMhHvB,yCNyN4B,CMxN5B,kCNuNqB,CMtNrB,gCN/NmB,CMgOnB,2BN5Nc,CM6Nd,oCN2EuB,CM1EvB,qCNyEwB,CMxExB,6BNvNgB,CMwNhB,6BNzCgB,CM0ChB,+BNpCkB,CMqClB,0BNtLa,CMuLb,+BN7UkB,CM8UlB,4BN1Re,CM2Rf,0BNsDa,CMrDb,4BNmLe,CMlLf,2BNrPc,CMsPd,4BNrPe,CMsPf,8BN7WiB,CM8WjB,qCN7WwB,CM8WxB,4BN0Le,CMzLf,mCN0LsB,CMzLtB,8BNyFiB,CMxFjB,qCACgC,WNzUnB,CM0Ub,+BACiC,WN+MnB,CM9Md,2BN4Pc,CM3Pd,8BNuKiB,CMtKjB,iCNtPoB,CMuPpB,iCNiKoB,CMhKpB,+BN9PkB,CM+PlB,iCN/LoB,CMgMpB,kCNxLqB,CMyLrB,mCNrMsB,CMsMtB,wCN/L2B,CMgM3B,0EAEyC,WNxMnB,CMyMtB,gDAC2C,WN9MnB,CM+MxB,gDACyC,WN/MnB,CMgNtB,gDACyC,WNpMnB,CMqMtB,kCNjNqB,CMkNrB,2BNuRc,CMtRd,8BN5SiB,CM6SjB,+BN9EkB,CM+ElB,wGAIsC,WNnEnB,CMoEnB,qCN/TwB,CMgUxB,qDAEkC,WNqDnB,CMpDf,gCACmC,WNnQnB,CMoQhB,iCNzKoB,CM0KpB,0BN3Ka,CM4Kb,2EAEwC,WNxJnB,CMyJrB,oCN2KuB,CM1KvB,yBNiCY,CMhCZ,oCACmC,WN0QnB,CMzQhB,uCACwC,WNVnB,CMWrB,2CAC0C,WNXnB,CMYvB,8BN1IiB,CM2IjB,kCNlVqB,CMmVrB,6BNjJgB,CMkJhB,gCNbmB,CMcnB,8BN+FiB,CM9FjB,gCNuEmB,CMtEnB,uCNuE0B,CMtE1B,2BNzZc,CM0Zd,6CACqC,WN5MnB,CM6MlB,0BN0Ma,CMzMb,iCNxaoB,CMyapB,2BNIc,CMHd,iCNuFoB,CMtFpB,6BN2MgB,CM1MhB,2BN+Qc,CM9Qd,kCNzCqB,CM0CrB,2BNwPc,CMvPd,iCNrZoB,CMsZpB,6BNvBgB,CMwBhB,oCN3LuB,CM4LvB,8BN5XiB,CM6XjB,oCNhYuB,CMiYvB,kCNnYqB,CMoYrB,8BNtYiB,CMuYjB,gCNlYmB,CMmYnB,gCNlYmB,CMmYnB,iCN3boB,CM4bpB,mCN3bsB,CM4btB,4BN+Ke,CM9Kf,gCNnVmB,CMoVnB,yBN9dY,CM+dZ,iCN5RoB,CM6RpB,kCN/CqB,CMgDrB,oCN9buB,CM+bvB,iCNtfoB,CMufpB,gCN/BmB,CMgCnB,iCNzHoB,CM0HpB,6BNvIgB,CMwIhB,oCNvIuB,CMwIvB,iCN4JoB,CM3JpB,gCN4JmB,CM3JnB,8BNxciB,CMycjB,0BNjba,CMkbb,8BNvJiB,CMwJjB,gCN3gBmB,CM4gBnB,yBN7ZY,CM8ZZ,mDAEgC,WNzKnB,CM0Kb,+BNpGkB,CMqGlB,iCNxboB,CMybpB,qCN5WwB,CM6WxB,+BN9VkB,CM+VlB,+BN9PkB,CM+PlB,8BNrJiB,CMsJjB,6BNegB,CMdhB,mCN2BsB,CM1BtB,kCNoCqB,CMnCrB,+BNqCkB,CMpClB,gCN5amB,CM6anB,sCN9ayB,CM+azB,8BN/ViB,CMgWjB,2BNoBc,CMnBd,kCN8KqB,CM7KrB,iCN/FoB,CMgGpB,kCN6EqB,CM5ErB,gCN9MmB,CM+MnB,4BN+Ke,CM9Kf,2BN7Hc,CM8Hd,8BNnHiB,CMoHjB,2CACwC,WNkInB,CMjIrB,sCNkIyB,CMjIzB,mCN0KsB,CMzKtB,kCNlIqB,CMmIrB,iCNyKoB,CMxKpB,kCNnIqB,CMoIrB,oCNlIuB,CMmIvB,oCNpIuB,CMqIvB,6BN1GgB,CM2GhB,iCN7QoB,CM8QpB,wCN1U2B,CM2U3B,kCNzEqB,CM0ErB,+BNkLkB,CMjLlB,6BNXgB,CMYhB,gCNuJmB,CMtJnB,iCNwJoB,CMvJpB,gCACgC,WN/fnB,CMggBb,8BN4JiB,CM3JjB,4BN8Ge,CM7Gf,6BNwDgB,CMvDhB,6BN9IgB,CM+IhB,sCACyC,WN0LnB,CMzLtB,oCNjHuB,CMkHvB,+BNrHkB,CMsHlB,mCNnWsB,CMoWtB,gEAEyC,WN/gBnB,CMghBtB,uDACmD,WN9gBnB,CM+gBhC,6CACyC,WNlhBnB,CMmhBtB,gDAC4C,WNnhBnB,CMohBzB,8CAC0C,WNxhBnB,CMyhBvB,oCN3IuB,CM4IvB,+BN3OkB,CM4OlB,mCNxIsB,CMyItB,qCNxIwB,CMyIxB,kCNwBqB,CMvBrB,oCNwBuB,CMvBvB,6BN/dgB,CMgehB,qCNlewB,CMmexB,4BNpce,CMqcf,oCNljBuB,CMmjBvB,kCNxPqB,CMyPrB,kDAC4C,WNzPnB,CM0PzB,iDAC2C,WN7PnB,CM8PxB,gDAC0C,WNhQnB,CMiQvB,gCNrQmB,CMsQnB,8CACwC,WNxRnB,CMyRrB,+CACyC,WN7RnB,CM8RtB,sCN1RyB,CM2RzB,oCNpSuB,CMqSvB,mCN3RsB,CM4RtB,qCN/RwB,CMgSxB,mCNjSsB,CMkStB,gCN+DmB,CM9DnB,iCN/FoB,CMgGpB,uCN/b0B,CMgc1B,yBNtUY,CMuUZ,gCNtUmB,CMuUnB,kCNkEqB,CMjErB,oCNrKuB,CMsKvB,2CNrK8B,CMsK9B,iCN5UoB,CM6UpB,kCNwHqB,CMvHrB,6BNnFgB,CMoFhB,6BNzegB,CM0ehB,8BN9WiB,CM+WjB,4BNxKe,CMyKf,wCNpQ2B,CMqQ3B,oCACuC,WNSnB,CMRpB,6BNjdgB,CMkdhB,4BNzoBe,CM0oBf,6BN/nBgB,CMgoBhB,sCN3hByB,CM4hBzB,uCN9hB0B,CM+hB1B,uCN5hB0B,CM6hB1B,uCNjiB0B,CMkiB1B,+BNpRkB,CMqRlB,8BN5NiB,CM6NjB,gCN5NmB,CM6NnB,4BN/Ne,CMgOf,0BNlOa,CMmOb,iCNpeoB,CMqepB,mCNpesB,CMqetB,4BNtSe,CMuSf,4BNiFe,CMhFf,gCNlkBmB,CMmkBnB,gCNrXmB,CMsXnB,mCNpIsB,CMqItB,2BNpcc,CMqcd,sCNheyB,CMiezB,+BNpfkB,CMqflB,2BNlNc,CMmNd,mCN1XsB,CM2XtB,0BNoDa,CMnDb,mCN3JsB,CM4JtB,+BNzNkB,CM0NlB,6BNlHgB,CMmHhB,mCN7LsB,CM8LtB,qCN7LwB,CM8LxB,kCN3CqB,CM4CrB,oCN3CuB,CM4CvB,mCNrGsB,CMsGtB,sCNrGyB,CMsGzB,8BN7UiB,CM8UjB,gCNnlBmB,CMolBnB,kCNnlBqB,CMolBrB,8BN/LiB,CMgMjB,6BNlXgB,CMmXhB,iCNkFoB,CMjFpB,8BNmFiB,CMlFjB,6BN9cgB,CM+chB,uCN2B0B,CM1B1B,qCNmEwB,CMlExB,wCNxK2B,CMyK3B,4BN9lBe,CM+lBf,wCNtoB2B,CMuoB3B,2CNqD8B,CMpD9B,8BNxlBiB,CMylBjB,kDN5oBqC,CM6oBrC,2EACgE,WN9qBnB,CM+qB7C,+DAEiC,WNvfnB,CMwfd,4BNhYe,CMiYf,8BNhYiB,CMiYjB,4CAC0C,WN1HnB,CM2HvB,iCNzRoB,CM0RpB,6BNiCgB,CMhChB,oCNiCuB,CMhCvB,+BNlHkB,CMmHlB,qCNlHwB,CMmHxB,sCNlHyB,CMmHzB,iCNrNoB,CMsNpB,kCNpbqB,CMqbrB,4BNmEe,CMlEf,gCNpDmB,CMqDnB,8DACiD,WNzYnB,CM0Y9B,sCACyC,WN7anB,CM8atB,kCNtXqB,CMuXrB,oCNlfuB,CMmfvB,sCNlfyB,CMmfzB,6BNtTgB,CMuThB,mCNptBsB,CMqtBtB,qCNptBwB,CMqtBxB,yCACyC,WNrtBnB,CMstBtB,6CAC2C,WNttBnB,CMutBxB,kCNJqB,CMKrB,oCNJuB,CMKvB,6BNHgB,CMIhB,+BN3WkB,CM4WlB,8CACoC,WN5WnB,CM6WjB,kDACsC,WN7WnB,CM8WnB,4BNtNe,CMuNf,qCN3bwB,CM4bxB,+BNtFkB,CMuFlB,4EAE6C,WNxEnB,CMyE1B,+DACuD,WNvEnB,CMwEpC,qDAC6C,WN3EnB,CM4E1B,wDACgD,WN5EnB,CM6E7B,sDAC8C,WNjFnB,CMkF3B,6BN3KgB,CM4KhB,kDAEiC,WNzrBnB,CM0rBd,8BNlPiB,CMmPjB,sCNKyB,CMJzB,sCNKyB,CMJzB,qCNKwB,CMJxB,mDACyC,WNDnB,CMEtB,uDAC2C,WNFnB,CMGxB,+BNxsBkB,CMysBlB,2BNpbc,CMqbd,2BN1hBc,CM2hBd,2BNxYc,CMyYd,8BN/OiB,CMgPjB,8BNziBiB,CM0iBjB,gCNjUmB,CMkUnB,kCN7KqB,CM8KrB,kCNhIqB,CMiIrB,iCNJoB,CMKpB,6BNxUgB,COzchB,sLH8BE,kBACA,UACA,WACA,UACA,YACA,gBACA,sBACA,SAUA,mDAEE,gBACA,WACA,YACA,SACA,iBACA,UIxDF,yBACE,sBACA,oBACA,UC2NgB,CD1NhB,cC2NkB,CD1NlB,kBACA,eCPkB,CDQlB,6BCkNqB,CDhNrB,uCACE,mBACA,SCqNuB,CDlNzB,sCACE,YACA,2BACA,eCgNqB,CD/MrB,aCgNwB,CD7M1B,wCACE,uBAGF,sCACE,WACA,oBACA,aC2MwB,CDxM1B,mDACE,aCwM6B,CDrM/B,uCACE,eCuMsB,CDtMtB,gBCsMsB,CDrMtB,cCuMyB,CDpM3B,sCACE,gBACA,UCgL2B,CD/K3B,WCgL4B,CD/K5B,cCgLiC,CD7KnC,wCACE,2BACA,eCkLuB,CDjLvB,SCkLwB,CDjLxB,aCkL0B,CDjL1B,mBAGF,+CACE,mBAEA,qDACE,UAIJ,qCACE,UACA,cACA,WACA,kBAEA,yDACE,aACA,mBACA,eC0JqB,CDzJrB,iBE1EN,qEFsEI,yDAOI,iBAKF,uEACE,UACA,WAKF,4EACE,WACA,cAEA,yFACE,aAGF,0FACE,cAMR,wCACE,OACA,2BACA,mBACA,WACA,aACA,YACA,iBACA,mBACA,UAGF,uCACE,sBACA,uBACA,aCkH0B,CDhH1B,6CACE,wDCgH8B,CD5GlC,wCACE,oBCxFU,CD0FV,6EACE,kBACA,YACA,WACA,wBACA,kBAEA,0FACE,WACA,YACA,yBACA,yBACA,0BAGF,2FACE,YACA,aACA,yBACA,0BAIJ,4DACE,UACA,WAGF,2DACE,MACA,aACA,cACA,gBAGF,oEACE,eAEA,gFACE,YACA,aACA,YAGF,iFACE,YACA,cACA,cAMA,gFACE,oDAGF,iFACE,qDAMR,oCACE,8BCoBuB,CDjBzB,oCACE,uCCiBuB,CExN7B,iBAEE,aACA,eACA,aACA,MACA,QACA,SACA,OACA,mBACA,mBACA,uBACA,cFPwB,CEQxB,kBACA,+BFa0B,CEV1B,iCAEA,wEAEE,yBFKa,CEFf,qCACE,kCAGF,2BACE,uBAGF,iEAEE,uBACA,2BAGF,gEAEE,uBACA,yBAGF,8BACE,mBAGF,uEAEE,mBACA,2BAGF,sEAEE,mBACA,yBAGF,8BACE,qBAGF,uEAEE,qBACA,2BAGF,sEAEE,qBACA,yBAGF,4OAKE,gBAGF,oDACE,wBACA,OACA,mBACA,uBAGF,6CACE,wBACA,OACA,qBACA,uBAGF,mCACE,OACA,sBAEA,6IAGE,mBAGF,2TAME,uBAGF,wTAME,qBAGF,gDACE,wBACA,OACA,qBACA,uBAIJ,qCACE,2BAkBA,oXACE,YDzJJ,qEC8JE,8BACE,qBAKN,aACE,aACA,kBACA,sBACA,sBACA,uBACA,UFnKY,CEoKZ,eACA,cFpKc,CEqKd,WFpKa,CEqKb,iBFpKoB,CEqKpB,eFhLoB,CEiLpB,mBF3JW,CE4JX,cF3JgB,CE6JhB,mBACE,aAGF,2BACE,kBAIJ,cACE,aACA,sBACA,mBACA,eFnKqB,CEsKvB,aACE,kBACA,eACA,eFpJmB,CEqJnB,UACA,aFrJkB,CEsJlB,iBFrJsB,CEsJtB,gBACA,kBACA,oBACA,qBAGF,eACE,aACA,UACA,sBACA,cFrDwB,CEsDxB,kBFrD0B,CEsD1B,sBFrD8B,CEsD9B,UFrDoB,CEsDpB,oBFrDqB,CEsDrB,SFrDsB,CEyDlB,2DACE,WAGF,uDACE,yEAGF,wDACE,yEAMR,cACE,aACA,kBFpCyB,CEqCzB,sBFpC6B,CEqC7B,WFpCmB,CEqCnB,YFpCoB,CEqCpB,gBFpCoB,CEqCpB,6DFpCuB,CEqCvB,kBFpC0B,CEqC1B,kBFpC0B,CEqC1B,kBFpC2B,CEqC3B,oDFpC0B,CEuC5B,cACE,cF5DoB,CE6DpB,oBF5DqB,CE6DrB,eF5DwB,CE6DxB,eF5DyB,CE8DzB,8BACE,eAGF,4BAEE,QF9F0B,CE+F1B,mBF9FiC,CE+FjC,mBACA,wBF/FoC,CEgGpC,UF3QkB,CE4QlB,aF/F6B,CEkG/B,yBAEE,QFhGuB,CEiGvB,mBFhG8B,CEiG9B,mBACA,wBFjGiC,CEkGjC,UFrRkB,CEsRlB,aFjG0B,CEoG5B,2BAEE,QFlGyB,CEmGzB,mBFlGgC,CEmGhC,mBACA,wBFnGmC,CEoGnC,UF/RkB,CEgSlB,aFnG4B,CEsG9B,oBACE,YF9FyB,CEgGzB,yCF9F4B,CEiG9B,gCACE,SAIJ,cACE,uBACA,iBFrLoB,CEsLpB,eFrLqB,CEsLrB,0BACA,aFrLmB,CEsLnB,aFrLuB,CEwLzB,oCACE,kBACA,QACA,SACA,OACA,YF1LgC,CE2LhC,gBACA,8BFnToB,CEoTpB,6BFpToB,CEuTtB,0BACE,WACA,YFlMgC,CEmMhC,yBFlMoC,CEqMtC,aACE,eACA,kBF1RmB,CE6RrB,aACE,iBFnM4B,CEoM5B,UACA,KFpMuB,CEqMvB,OFrMuB,CEsMvB,kBF5M+B,CE6M/B,sBF5MmC,CE6MnC,WF5MyB,CE6MzB,YF5M0B,CE6M1B,UACA,gBACA,6BF3M8B,CE4M9B,WF3M0B,CE4M1B,iBF/UoB,CEiVpB,sBF3M8B,CE4M9B,UF3MyB,CE4MzB,iBF3M+B,CE4M/B,eF3M6B,CE4M7B,eFtN+B,CEuN/B,eAEA,mBACE,cF7MiC,CE8MjC,sBF5MkC,CE6MlC,aF5TU,CE+TZ,mBACE,YF9M+B,CE+M/B,+CF9MkC,CEiNpC,+BACE,SAIJ,eACE,UACA,sBF7T8B,CE8T9B,QF7TqB,CE8TrB,eF7TsB,CE8TtB,aF7ToB,CE8TpB,iBF7TwB,CE8TxB,kBF7T0B,CE8T1B,kBF7T0B,CE8T1B,iBF7TyB,CE8TzB,oBF7TwB,CEgU1B,oFAME,eFnUmB,CEsUrB,yCAGE,sBACA,UFzUkB,CE0UlB,0CFjUuB,CEkUvB,wBFxUmB,CEyUnB,qBFxU0B,CEyU1B,kBFtUuB,CEuUvB,0CFzUuB,CE0UvB,aFvUkB,CEwUlB,iBF1UsB,CE4UtB,4FACE,gCACA,sCAGF,2DACE,wBF5UuB,CE6UvB,YF5UwB,CE6UxB,yCF5U2B,CE+U7B,gFACE,WAIJ,aACE,eFpWmB,CEqWnB,eFxaoB,CE0apB,mBACE,UAGF,oBACE,UACA,aFpWgB,CEqWhB,gBACA,kBAGF,uCAEE,cFlXiB,CEmXjB,UACA,iBF/WoB,CEgXpB,mBFrXiB,CEyXrB,aACE,cF1XmB,CE2XnB,eF1XoB,CE4XpB,0BACE,eAIJ,YACE,kBF7XuB,CE8XvB,iBF/XsB,CEkYxB,gBACE,aFxXsB,CEyXtB,aFxXuB,CE2XzB,cACE,cACA,eACA,sBACA,kBF1YuB,CE2YvB,aF1YkB,CE2YlB,iBF7YsB,CEgZxB,6BAEE,mBACA,uBACA,eF9doB,CE+dpB,aFnZkB,CEqZlB,yCACE,cACA,iBFzZoB,CE4ZtB,yCACE,cACA,cAIJ,mBACE,aACA,sBFpZkC,CEqZlC,eFtZyB,CEyZ3B,0BACE,kBFtZqC,CEuZrC,sBFtZyC,CEuZzC,eFtZgC,CEuZhC,cFtZiC,CEuZjC,gBACA,kBFvZoC,CEwZpC,UFvZ+B,CEwZ/B,aFvZmC,CEwZnC,eFvZqC,CEyZrC,kCACE,YACA,qBACA,YACA,gBACA,aACA,gBAEA,kBACA,wBF5dU,CE6dV,UFvgBkB,CEwgBlB,gBACA,kBACA,kBAUJ,YACE,kBACA,uBACA,uBACA,SFvfgB,CEwfhB,UFxfgB,CEyfhB,0BFvfkB,CEyflB,gCACA,kBACA,iBFxfwB,CEyfxB,mBF3fuB,CE4fvB,eF/fgB,CEggBhB,eACA,iBAEA,gCACE,aACA,mBACA,gBFlgBmB,CEqgBrB,wBACE,oBFjgBU,CEkgBV,aFlgBU,CEogBV,sCACE,kBACA,YAOF,mDACE,cACA,kBACA,aACA,eACA,eACA,qBACA,wBFphBQ,CEshBR,gEACE,cACA,wBAGF,iEACE,UACA,yBAKJ,wCAEI,uCAEA,sDACE,yCAMR,0BACE,qBACA,aF9iBY,CEijBd,uBACE,qBACA,aFljBS,CEqjBX,2BACE,qBACA,aFtjBa,CEyjBf,0BACE,oBF/jBY,CEgkBZ,aFhkBY,CEkkBZ,+DAEE,kBACA,aACA,aACA,wBACA,kBAEA,4EACE,cACA,eACA,yBACA,+BACA,8BAOF,6EACE,cACA,aACA,yBACA,0BACA,8BAQJ,8CAEE,kBACA,UACA,YACA,aACA,uBACA,WACA,YACA,wCACA,kBAOF,6CAEE,kBACA,UACA,SACA,aACA,cACA,eACA,yBAOF,sDACE,cACA,kBACA,UACA,eACA,qBACA,wBFzoBU,CE2oBV,kEACE,YACA,aACA,eACA,wBAGF,mEACE,YACA,WACA,eACA,yBAWA,kEACE,8CAGF,mEACE,+CAGF,6EACE,2DAOV,sBACE,cFhnB+B,CEinB/B,kBFhnBiC,CEinBjC,cFhnB+B,CEinB/B,iBF/mB4B,CEgnB5B,SF/mB6B,CEgnB7B,kBFlnBgC,CEmnBhC,eFhnBiC,CEknBjC,yBACE,qBACA,kBAGF,2CACE,WACA,cACA,SFxnBwB,CEynBxB,UFxnByB,CEynBzB,iBFxnBgC,CEynBhC,kBFtnB2B,CEunB3B,UF9uBkB,CE+uBlB,eF5nByB,CE6nBzB,kBAEA,sEACE,kBF5nByB,CE8nBzB,2FACE,kBFjoByB,CEkoBzB,UFvvBc,CE0vBhB,gGACE,kBFtoByB,CE2oB/B,gDACE,WACA,cACA,WFlpB4B,CEmpB5B,YACA,cACA,kBF/oB2B,CEopB/B,eACE,wCAGF,YACE,wBFjwBqB,CEowBvB,YACE,kCFpwBqB,CEuwBvB,mBACE,gBAIF,yBACE,kBACA,YACA,WACA,YACA,gBAKA,wBACE,WACA,MF5pBqB,CE+pBvB,qCACE,QACA,UC5yBJ,iCAEI,mBACE,sBAGF,oBACE,cAMN,qEAGI,mBACE,sBAGF,oBACE,cCrBN,4BACE,GACE,6CAGF,IACE,uCAGF,IACE,6CAGF,KACE,uCAIJ,4BACE,KACE,wBACA,WAIJ,gDACE,GACE,YACA,aACA,QAGF,IACE,WACA,YACA,QAGF,IACE,WACA,aACA,cAGF,IACE,aACA,WACA,WAGF,KACE,YACA,aACA,aAIJ,iDACE,GACE,YACA,cACA,QAGF,IACE,WACA,cACA,QAGF,IACE,YACA,QACA,cAGF,KACE,YACA,cACA,eC7EJ,sBACE,GACE,qBAGF,IACE,sBAGF,IACE,sBAGF,KACE,oBAKJ,sBACE,GACE,mBACA,UAGF,KACE,qBACA,WAKJ,0CACE,GACE,aACA,aACA,QAGF,IACE,aACA,YACA,QAGF,IACE,aACA,cACA,cAGF,IACE,QACA,cACA,eAGF,KACE,aACA,aACA,gBAIJ,2CACE,GACE,YACA,cACA,QAGF,IACE,YACA,cACA,QAGF,IACE,aACA,QACA,eAGF,KACE,YACA,WACA,gBAIJ,8CACE,GACE,yBAGF,GACE,yBAGF,IACE,0BAGF,KACE,2BAKJ,sCACE,GACE,mBACA,qBACA,UAGF,IACE,mBACA,qBACA,UAGF,IACE,oBACA,sBAGF,KACE,aACA,mBACA,WAIJ,oCACE,GACE,0BACA,UAGF,KACE,wBACA,WAIJ,gCACE,GACE,uBAGF,KACE,0BJzIF,iEKbI,gBAIJ,uBACE,uBAIA,wCACE,SACA,WACA,YACA,UACA,mCACA,wCAEA,qDACE,mCAGF,kDACE,MACA,SACA,2BAGF,+GAEE,MACA,OAGF,8GAEE,MACA,QAGF,qDACE,QACA,SACA,gCAGF,qHAEE,QACA,OACA,2BAGF,oHAEE,QACA,QACA,2BAGF,qDACE,SACA,SACA,2BAGF,qHAEE,SACA,OAGF,oHAEE,QACA,SAKN,aLlEA,iEKqEM,6BAEA,oFACE,aAGF,kFACE,4BC5FN,wCACE,6BAEA,kDACE,MACA,WACA,YACA,SACA,2BAGF,8GAEE,MACA,QACA,YACA,UAGF,+GAEE,MACA,WACA,YACA,OAGF,qHAEE,QACA,WACA,YACA,OACA,2BAGF,qDACE,QACA,WACA,YACA,SACA,gCAGF,oHAEE,QACA,QACA,YACA,UACA,2BAGF,qHAEE,SACA,WACA,SACA,OAGF,qDACE,SACA,WACA,SACA,SACA,2BAGF,oHAEE,SACA,QACA,SACA,UC5ER,KACI,eAGJ,KACI,iBAGI,mCADJ,qBAEQ,wBlG2FI,EkGzFR,oCAJJ,qBAKQ,qBlGJJ,EAgVA,sCkGzUI,yBACA,WlGwUJ,qCkGzUI,yBACA,WlGwUJ,sBkGnUA,sBACA,WlGkUA,qBkGnUA,yBACA,cAIA,iDACI,gBACA,UAKZ,WACI,cACA,0BACA,UACA,YAGJ,+BACI,oBACA,qBlG8SI,iEkG5SA,gClG4SA,+DkG5SA,gCAIA,oSACI,SlGuSJ,4akGrSQ,WlGqSR,oakGrSQ,WAMhB,iCACI,gBAGJ,SACI,cACA,YACA,cACA,YlGuRI,sCkGnRI,gDlGmRJ,qCkGnRI,gDAKZ,cACI,gBAGJ,QACI,gBACA,sBlGwQI,yBkGtQA,6BlGsQA,wBkGtQA,6BlGsQA,uDkGhQA,oClGgQA,qDkGhQA,6BAIR,gBACI,eAGJ,iBACI,gBAGJ,aACI,uBlGmPI,oGkG7OA,WlG6OA,+FkG7OA,WAGJ,6CACI,clGyOA,0KkGpOI,WlGoOJ,qKkGpOI,WlGoOJ,mBkG7NA,clG6NA,kBkG7NA,clG6NA,6BkGxNI,sBACA,gBlGuNJ,4BkGxNI,sBACA,gBlGuNJ,sBkGhNA,clGgNA,qBkGhNA,cAIR,qBACI,aAGJ,SACI,iBlGpHW,CkGuHf,aACI,6BAGJ,sBACI,gBlG+LI,qUkG1LA,2ClG0LA,8TkG1LA,6ClG0LA,6BkGlLA,yBlGkLA,4BkGlLA,yBlGkLA,2BkG5KA,oClG4KA,0BkG5KA,oClG4KA,6BkGtKA,oCACA,sBlGqKA,4BkGtKA,oCACA,yBlGqKA,6BkG/JA,oCACA,sBlG8JA,4BkG/JA,oCACA,yBlG8JA,uDkGxJA,oCACA,sBlGuJA,qDkGxJA,oCACA,yBlGuJA,0BkGjJA,oCACA,sBlGgJA,yBkGjJA,oCACA,yBlGgJA,iCkG1IA,gClG0IA,gCkG1IA,gClG0IA,iCkGpIA,gClGoIA,gCkGpIA,gClGoIA,gCkG9HA,gClG8HA,+BkG9HA,gClG8HA,8BkGxHA,gClGwHA,6BkGxHA,gClGwHA,+BkGlHA,yBlGkHA,8BkGlHA,yBlGkHA,wIkG7GI,yBlG6GJ,oIkG7GI,yBlG6GJ,+BkGtGA,yBlGsGA,8BkGtGA,yBlGsGA,wIkGjGI,yBlGiGJ,oIkGjGI,yBlGiGJ,kDkGzFI,yBlGyFJ,iDkGzFI,yBlGyFJ,oNkGpFQ,yBlGoFR,gNkGpFQ,yBlGoFR,+KkG5EA,yBlG4EA,0KkG5EA,yBlG4EA,8DmGtVA,yBACA,qBACA,WnGoVA,4DmGtVA,yBACA,qBACA,cnGoVA,kNmG/UI,yBACA,qBACA,WnG6UJ,8MmG/UI,yBACA,qBACA,cAIR,8CACI,YnGwUA,sCmGlUA,yBACA,qBACA,cnGgUA,qCmGlUA,yBACA,qBACA,cnGgUA,wGmG3TI,yBACA,qBACA,WnGyTJ,sGmG3TI,yBACA,qBACA,cnGyTJ,+DmGlTA,yBACA,qBACA,cnGgTA,6DmGlTA,6BACA,qBACA,WnGgTA,oNmG3SI,yBACA,qBACA,cnGySJ,gNmG3SI,6BACA,qBACA,cAIR,+CACI,YnGoSA,sJmG9RI,2CnG8RJ,kJmG9RI,4CnG8RJ,wCmGvRA,yBACA,qBACA,cnGqRA,uCmGvRA,6BACA,qBACA,WnGqRA,4GmGhRI,yBACA,qBACA,WnG8QJ,0GmGhRI,6BACA,qBACA,cnG8QJ,kHmGtQI,yBACA,qBACA,cnGoQJ,gHmGtQI,6BACA,qBACA,WnGoQJ,oDmG9PI,yBACA,qBACA,WnG4PJ,mDmG9PI,6BACA,qBACA,cnG4PJ,0DmGrPA,yBACA,qBACA,WnGmPA,wDmGrPA,yBACA,qBACA,cnGmPA,0MmG9OI,yBACA,qBACA,WnG4OJ,sMmG9OI,yBACA,qBACA,cnG4OJ,qCmGrOA,yBACA,qBACA,cnGmOA,oCmGrOA,yBACA,qBACA,cnGmOA,sGmG9NI,yBACA,qBACA,WnG4NJ,oGmG9NI,yBACA,qBACA,cAMR,gCAEI,uCACA,mBACA,mBACA,kBnGiNA,8DmG5MI,WnG4MJ,oEmGtMI,cAKZ,YACI,kBAEA,wBACI,mBACA,SACA,aACA,uBACA,OACA,kBACA,QACA,MAIA,8EACI,aAGJ,gEACI,kBnG6KJ,gCmGtKA,yBACA,WnGqKA,+BmGtKA,yBACA,cnGqKA,sCmGhKI,yBACA,WnG+JJ,qCmGhKI,yBACA,cnG+JJ,kCmGxJA,yBACA,cnGuJA,iCmGxJA,yBACA,cnGuJA,6BmGjJA,sBACA,WnGgJA,4BmGjJA,yBACA,cnGgJA,+BmG1IA,yBACA,WnGyIA,8BmG1IA,yBACA,cnGyIA,gCmGnIA,yBACA,WnGkIA,+BmGnIA,yBACA,cnGkIA,gCmG5HA,yBACA,WnG2HA,+BmG5HA,yBACA,cC7NR,SACI,iCACA,iClGm0BgC,CkGl0BhC,kBlG29BgC,CkG19BhC,uBpGoVI,0BoGlVA,yBACA,yBACA,cpGgVA,yBoGlVA,yBACA,yBACA,WAGJ,0BACI,aAGJ,4BACI,iBACA,yBpGuUA,0CoGlUI,0BpGkUJ,yCoGlUI,0BpGkUJ,2DoG9TQ,cpG8TR,0DoG9TQ,cpG8TR,uCoGvTI,0BpGuTJ,sCoGvTI,0BpGuTJ,wDoGlTQ,cpGkTR,uDoGlTQ,cpGkTR,yCoG3SI,0BpG2SJ,wCoG3SI,0BpG2SJ,0DoGtSQ,cpGsSR,yDoGtSQ,cpGsSR,0CoG/RI,0BpG+RJ,yCoG/RI,0BpG+RJ,2DoG1RQ,cpG0RR,0DoG1RQ,cpG0RR,0CoGnRI,0BpGmRJ,yCoGnRI,0BpGmRJ,2DoG9QQ,cpG8QR,0DoG9QQ,cAKZ,qCACI,kBpGwQA,uBqGtVA,sBACA,qBACA,WrGoVA,sBqGtVA,yBACA,qBACA,crGoVA,0DqG9UQ,crG8UR,yDqG9UQ,cAMhB,2BACI,iBACA,yBAEA,uCACI,mBACA,oBrGkUA,8BqG3TA,iCACA,WrG0TA,6BqG3TA,yBACA,WrG0TA,kDqGpTQ,crGoTR,iDqGpTQ,cAMhB,kBACI,iBrGdW,CqGkBf,uBACI,kBAEA,0BACI,qBAGJ,8BACI,QAGJ,8BACI,kBAEA,qCACI,WACA,YAKJ,iCACI,kBAMR,mBACI,iBrG/CO,CA2TP,sDqGrQI,sBACA,WrGoQJ,qDqGrQI,yBACA,crGoQJ,4EqGhQQ,gBrGgQR,2EqGhQQ,gBCxFhB,aACI,atGuVI,+BsGlVA,ctGkVA,8BsGlVA,cAKJ,iDACI,gBAIR,iDACI,iCACA,CAGJ,kDACI,gBtGkUI,oFsGhUA,WtGgUA,kFsGhUA,WtGgUA,4EsG1TA,WtG0TA,0EsG1TA,WAKJ,oCACI,gBAEA,0CACI,cACA,mBtGgTJ,2DsG9SQ,ctG8SR,0DsG9SQ,cAIR,yCACI,cACA,mBAmBR,wCACI,YtGoRA,+BsG9QA,yBACA,qBACA,ctG4QA,8BsG9QA,6BACA,qBACA,WtG4QA,iFsGvQI,yBACA,ctGsQJ,+EsGvQI,yBACA,cAKZ,uCACI,eAGJ,kCACI,mBAEA,6CACI,UtGyPA,8DsGvPI,yBACA,qBACA,2CACA,ctGoPJ,6DsGvPI,6BACA,qBACA,4CACA,WAGJ,wDACI,YtGgPJ,yEsG9OQ,+BtG8OR,wEsG9OQ,+BtG8OR,8DsGvOI,qBtGuOJ,6DsGvOI,qBtGuOJ,gEsGhOA,sBACA,WtG+NA,8DsGhOA,yBACA,WtG+NA,gCsGzNA,WtGyNA,+BsGzNA,WtGyNA,4CsGpNI,yBtGoNJ,2CsGpNI,yBtGoNJ,sCsG/MI,iCtG+MJ,qCsG/MI,uCAGR,sBACI,2CAKJ,sBACI,etGqMA,gCsGlMA,kCtGkMA,+BsGlMA,yBAKJ,8CAEI,YtG2LA,kCsGxLA,sBACA,8BACA,WtGsLA,iCsGxLA,yBACA,qBACA,cAEJ,qCACI,uBACA,mBACA,aACA,+CACI,sBACA,OAEJ,+CACI,gBACA,kBACA,aACA,mBACA,uBACA,mDACI,mBAGR,8CACI,WACA,aACA,mBACA,uBAKZ,wBACI,4BACA,iCtGuJI,yCsGrJA,qBACA,8BACA,WtGmJA,wCsGrJA,qBACA,8BACA,ctGmJA,sKsG5IA,iBtG4IA,mKsG5IA,iBC5MR,QACI,eACA,gBvGsVI,yBuGpVA,yBvGoVA,wBuGpVA,yBvGoVA,4CuG/UI,yBvG+UJ,2CuG/UI,yBAIR,uBACI,gBACA,gBAEA,2CACI,gBvGsUJ,4DuGpUQ,WvGoUR,2DuGpUQ,WAGJ,iGACI,cACA,gBACA,uBACA,mBvG6TR,uduG1TgB,yBvG0ThB,iduG1TgB,yBvG0ThB,6CuGjTQ,gBvGiTR,4CuGjTQ,gBvGiTR,oDuG5SQ,gBvG4SR,mDuG5SQ,gBAMhB,cACI,oBACA,iBvGoSI,4CuG/RA,gBACA,qBvG8RA,2CuG/RA,mBACA,qBAIR,SACI,aACA,iBvGwRI,0BuGtRA,yBACA,gCACA,WvGoRA,yBuGtRA,yBACA,gCACA,cAGJ,oBACI,YAGJ,mBACI,mBAGI,kCACI,yBvGwQR,mDuGtQY,WvGsQZ,kDuGtQY,cAIR,4BACI,iBACA,+BvGgQR,6CuG9PY,6BACA,cvG6PZ,4CuG9PY,6BACA,cvG6PZ,+CuGvPY,cvGuPZ,8CuGvPY,cAMhB,mBACI,cACA,wBACI,cACA,iBvG9EG,CA2TP,yCuG3OQ,WvG2OR,wCuG3OQ,WC7GhB,eACI,YACA,mBxGsVI,gCwGpVA,sBxGoVA,+BwGpVA,yBAIR,cACI,gCACA,oBACA,WtGo8BgC,CsGj8BpC,UACI,WtGi8BgC,CsG97BpC,UACI,WtG27BgC,CFtnB5B,+BwGhUA,sBACA,gCACA,WxG8TA,8BwGhUA,yBACA,gCACA,cxG8TA,6BwGxTA,sBACA,WxGuTA,4BwGxTA,yBACA,cAGJ,6CACI,mBACA,yBxGkTA,+EwGhTI,cxGgTJ,6EwGhTI,cAKR,sCACI,gBAGJ,qCACI,mBAKJ,iCACI,iBACA,kBAEJ,6CACI,gBAGJ,4CACI,mBAIR,cACI,8BACA,2BxGkRI,+BwGhRA,yBACA,6BxG+QA,8BwGhRA,yBACA,6BxG+QA,wBwGzQA,WxGyQA,uBwGzQA,cxGyQA,4BwGnQA,8BxGmQA,2BwGnQA,8BAKJ,iBAEI,iBAGJ,sBACI,cACA,mBACA,iBAEA,gCACI,gBACA,iBACA,kBACA,kBACA,WAGJ,0BACI,YACA,yBACA,WAGJ,mCACI,UxGqOJ,oDwGnOQ,exGmOR,mDwGnOQ,eAGJ,yCACI,sBACA,oBACA,eAGJ,yCACI,oBACA,oBACA,eAKZ,0BACI,mBxGiNA,2EwG3MQ,cxG2MR,yEwG3MQ,cxG2MR,wCwGrMQ,exGqMR,uCwGrMQ,eAMhB,kBACI,oBtGqF0B,CsGpF1B,WACA,wBxG4LI,mCwG1LA,gBxG0LA,kCwG1LA,mBC9JR,kBACI,YACA,qBACA,qBAGJ,cACI,YzGiVI,kCyG5UA,WzG4UA,iCyG5UA,WzG4UA,kCyGtUA,czGsUA,iCyGtUA,czGsUA,mCyGhUA,czGgUA,kCyGhUA,cAMA,iGACI,mBzGyTJ,oJyGvTQ,yBACA,qBACA,czGqTR,iJyGvTQ,6BACA,qBACA,WzGqTR,2LyGhTY,czGgTZ,wLyGhTY,cAKZ,kFACI,mBACA,yBzGySJ,qIyGvSQ,czGuSR,kIyGvSQ,cAIR,mHACI,gBzGkSJ,mKyG7RQ,WACA,gBzG4RR,gKyG7RQ,WACA,gBzG4RR,sNyGtRgB,sBzGsRhB,mNyGtRgB,yBAMhB,gHACI,aAIA,wMACI,eAKJ,wSACI,eAKJ,0TACI,iBzG8PR,gayG5PY,czG4PZ,0ZyG5PY,czG4PZ,wVyGtPY,czGsPZ,kVyGtPY,cAQhB,oCACI,WAIA,iDAII,mBACA,aACA,eACA,0FvG+JkB,CuG9JlB,iBzG1FG,CyG2FH,uBACA,kBzG+NJ,kEyGvOQ,gBzGuOR,iEyGvOQ,mBAcZ,gDACI,czGwNA,iEyGtNI,gBzGsNJ,gEyGtNI,mBAGJ,0DACI,0FvG+IkB,CuGzI1B,oBACI,aAWJ,2BACI,YAEA,yCACI,eAMR,mCACI,oBAQA,2BACI,mBACA,cAEA,kCACI,mBACA,WACA,aACA,OACA,kBACA,UACA,uBACA,WACA,WAEJ,oCACI,YACA,gBACA,gBACA,YAIR,uBACI,WACA,iBACA,uBAGJ,sBACI,iBACA,qBAEA,6BACI,YACA,mBAGA,6CACI,cAKJ,8BACI,YACA,eACA,iBAKZ,+BACI,iBACA,kBACA,mBClOZ,WACI,a1GuVI,4B0GrVA,yB1GqVA,2B0GrVA,yBAGJ,kBACI,YACA,YACA,WAIR,iBACI,a1G0UI,kC0GxUA,yB1GwUA,iC0GxUA,yBAGJ,wBACI,YACA,YACA,WAIR,iBACI,YACA,8BACA,WAIA,0BACI,gBAKJ,UACI,gDACA,gBAFJ,UACI,gDACA,gBAFJ,UACI,iDACA,gBAFJ,UACI,iDACA,gBAFJ,UACI,iDACA,gB1G+SA,2B0GzSA,iDACA,gBACA,gB1GuSA,0B0GzSA,iDACA,gBACA,gB1GuSA,2B0GjSA,iDACA,gB1GgSA,0B0GjSA,iDACA,gB1GgSA,oC0G1RA,iDACA,gBACA,gB1GwRA,mC0G1RA,iDACA,gBACA,gB1GwRA,2B0GlRA,yB1GkRA,0B0GlRA,yBAMR,qBACI,gB1G2QI,sC0GzQA,4E1GyQA,qC0GzQA,4EAIR,gDACI,aAGJ,kCACI,aACA,UACA,gBAGJ,4BACI,gBAGJ,iBACI,Y1GsPI,6D0GjPA,sB1GiPA,4D0GjPA,yB1GiPA,mE0G3OA,sB1G2OA,kE0G3OA,yB1G2OA,mD0GrOA,sB1GqOA,kD0GrOA,yB1GqOA,yD0G/NA,sB1G+NA,wD0G/NA,yB1G+NA,qC0GzNA,W1GyNA,oC0GzNA,c1GyNA,gG0GhNI,sBACA,W1G+MJ,+F0GhNI,yBACA,cAKZ,iBACI,gCAGJ,aAKI,yBlGrIA,oBkGuIA,iBACA,W1G8LI,8B0GpMA,sBACA,W1GmMA,6B0GpMA,yBACA,cAOJ,2BACI,eAGJ,yBACI,YACA,YACA,cACA,WAGJ,4BACI,cxGiHsB,CwGhHtB,oB1G+KA,6C0G7KI,gC1G6KJ,4C0G7KI,gCAIR,gCACI,cACA,eACA,cAGJ,0BACI,iB1GzJO,C0G0JP,SACA,oB1GgKA,2C0G9JI,W1G8JJ,0C0G9JI,WAIR,4BACI,cxG0FsB,CwGzFtB,oB1GwJA,6C0GtJI,W1GsJJ,4C0GtJI,cAIR,4BlGpLA,oBkGsLI,aACA,mBACA,cxG+EsB,CwG9EtB,2BACA,SACA,a1G2IA,6C0GzII,sB1GyIJ,4C0GzII,yBAGJ,mCACI,kBAKR,uCACI,eAKJ,oCACI,yB1GyHA,wB2GtVA,W3GsVA,uB2GtVA,cAGJ,UACI,sB3GkVA,2B2GhVI,W3GgVJ,0B2GhVI,c3GgVJ,yC2G1UY,c3G0UZ,wC2G1UY,W3G0UZ,+C2GtUgB,c3GsUhB,8C2GtUgB,WAMhB,qBACI,cAEA,2BACI,c3G4TR,iG2GtTQ,c3GsTR,8F2GtTQ,c3GsTR,qC2GhTQ,W3GgTR,oC2GhTQ,WAKZ,eACI,qBAGJ,6BACI,YACA,eACA,iBACA,WAEA,mCACI,gBACA,YAGJ,kKACI,cACA,mBAGJ,4CACI,ezGkOkB,CyG9N1B,6BACI,iBASJ,0BACI,eACA,kBACA,WAEA,8BAGI,gBAIR,8BACI,eACA,WAGJ,4BACI,6B3GsPA,6C2GpPI,c3GoPJ,4C2GpPI,c3GoPJ,uI2G5OY,6B3G4OZ,qI2G5OY,6BAKZ,2BACI,gBAIA,oCACI,Y3GiOR,6C2GzNA,iCACA,W3GwNA,4C2GzNA,uCACA,cC/HJ,iCACI,SAGJ,qCACI,eACA,iBAGJ,wBACI,mBACA,iCACA,oB1GkOsB,C0GjOtB,mCACA,aACA,qBAEA,8BACI,mCAGJ,+BACI,WACA,WACA,wBACA,eACA,iBACA,wBAGJ,uCACI,aAGJ,sCACI,aAIA,yCACI,oBAEA,oDACI,gBAKZ,yEACI,iC5GsSJ,2G4GpSQ,yB5GoSR,yG4GpSQ,yB5GoSR,uX4G/RY,sB5G+RZ,iX4G/RY,yBAIR,uFACI,YAIR,sCACI,iC5GqRJ,uD4GnRQ,yB5GmRR,sD4GnRQ,yB5GmRR,gM4G9QY,sB5G8QZ,6L4G9QY,yBAIR,6CACI,YAIR,mCACI,iC5GoQJ,oD4GlQQ,yB5GkQR,mD4GlQQ,yB5GkQR,uL4G7PY,sB5G6PZ,oL4G7PY,yBAIR,0CACI,YAIR,sCACI,iC5GmPJ,uD4GjPQ,yB5GiPR,sD4GjPQ,yB5GiPR,gM4G5OY,sB5G4OZ,wJ","file":"app/main.656f1dffa218e8467958.css","sourcesContent":["@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: italic;\n\tfont-weight: 300;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-italic-300.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: italic;\n\tfont-weight: 400;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-italic-400.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: italic;\n\tfont-weight: 600;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-italic-600.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: italic;\n\tfont-weight: 700;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-italic-700.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: italic;\n\tfont-weight: 800;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-italic-800.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: normal;\n\tfont-weight: 300;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-normal-300.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: normal;\n\tfont-weight: 400;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-normal-400.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: normal;\n\tfont-weight: 600;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-normal-600.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: normal;\n\tfont-weight: 700;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-normal-700.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: normal;\n\tfont-weight: 800;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-normal-800.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n","@import \"../../jslib/angular/src/scss/webfonts.css\";\n@import \"./variables\";\n\n//@import \"~bootstrap/scss/bootstrap\";\n@import \"~bootstrap/scss/_functions\";\n@import \"~bootstrap/scss/_variables\";\n@import \"~bootstrap/scss/_mixins\";\n@import \"~bootstrap/scss/_root\";\n@import \"~bootstrap/scss/_reboot\";\n@import \"~bootstrap/scss/_type\";\n@import \"~bootstrap/scss/_images\";\n@import \"~bootstrap/scss/_code\";\n@import \"~bootstrap/scss/_grid\";\n@import \"~bootstrap/scss/_tables\";\n@import \"~bootstrap/scss/_forms\";\n@import \"~bootstrap/scss/_buttons\";\n@import \"~bootstrap/scss/_transitions\";\n@import \"~bootstrap/scss/_dropdown\";\n@import \"~bootstrap/scss/_button-group\";\n@import \"~bootstrap/scss/_input-group\";\n@import \"~bootstrap/scss/_custom-forms\";\n@import \"~bootstrap/scss/_nav\";\n@import \"~bootstrap/scss/_navbar\";\n@import \"~bootstrap/scss/_card\";\n@import \"~bootstrap/scss/_breadcrumb\";\n@import \"~bootstrap/scss/_pagination\";\n@import \"~bootstrap/scss/_badge\";\n@import \"~bootstrap/scss/_jumbotron\";\n@import \"~bootstrap/scss/_alert\";\n@import \"~bootstrap/scss/_progress\";\n@import \"~bootstrap/scss/_media\";\n@import \"~bootstrap/scss/_list-group\";\n@import \"~bootstrap/scss/_close\";\n//@import \"~bootstrap/scss/_toasts\";\n@import \"~bootstrap/scss/_modal\";\n@import \"~bootstrap/scss/_tooltip\";\n@import \"~bootstrap/scss/_popover\";\n@import \"~bootstrap/scss/_carousel\";\n@import \"~bootstrap/scss/_spinners\";\n@import \"~bootstrap/scss/_utilities\";\n@import \"~bootstrap/scss/_print\";\n\n@import \"~angular2-toaster/toaster\";\n@import \"~font-awesome/scss/font-awesome.scss\";\n@import \"~sweetalert2/src/sweetalert2.scss\";\n\n@import \"./base\";\n@import \"./buttons\";\n@import \"./callouts\";\n@import \"./cards\";\n@import \"./forms\";\n@import \"./navigation\";\n@import \"./modals\";\n@import \"./pages\";\n@import \"./plugins\";\n@import \"./tables\";\n@import \"./toasts\";\n",":root {\n // Custom variable values only support SassScript inside `#{}`.\n @each $color, $value in $colors {\n --#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$color}: #{$value};\n }\n\n @each $bp, $value in $grid-breakpoints {\n --breakpoint-#{$bp}: #{$value};\n }\n\n // Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --font-family-sans-serif: #{inspect($font-family-sans-serif)};\n --font-family-monospace: #{inspect($font-family-monospace)};\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline\n// on elements that programmatically receive focus but wouldn't normally show a visible\n// focus outline. In general, this would mean that the outline is only applied if the\n// interaction that led to the element receiving programmatic focus was a keyboard interaction,\n// or the browser has somehow determined that the user is primarily a keyboard user and/or\n// wants focus outlines to always be presented.\n//\n// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible\n// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `

`-`

` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `

`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n\n @include hover() {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,\n // making it impossible to interact with the content\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// Set the cursor for non-` {{'codeSent' | i18n}}

{{'confirmIdentity' | i18n}}
","import { ItemView } from './itemView';\nimport { LoginUriView } from './loginUriView';\n\nimport { Utils } from '../../misc/utils';\n\nimport { Login } from '../domain/login';\n\nimport { LoginLinkedId as LinkedId } from '../../enums/linkedIdType';\n\nimport { linkedFieldOption } from '../../misc/linkedFieldOption.decorator';\n\nexport class LoginView extends ItemView {\n @linkedFieldOption(LinkedId.Username)\n username: string = null;\n @linkedFieldOption(LinkedId.Password)\n password: string = null;\n\n passwordRevisionDate?: Date = null;\n totp: string = null;\n uris: LoginUriView[] = null;\n autofillOnPageLoad: boolean = null;\n\n constructor(l?: Login) {\n super();\n if (!l) {\n return;\n }\n\n this.passwordRevisionDate = l.passwordRevisionDate;\n this.autofillOnPageLoad = l.autofillOnPageLoad;\n }\n\n get uri(): string {\n return this.hasUris ? this.uris[0].uri : null;\n }\n\n get maskedPassword(): string {\n return this.password != null ? '••••••••' : null;\n }\n\n get subTitle(): string {\n return this.username;\n }\n\n get canLaunch(): boolean {\n return this.hasUris && this.uris.some(u => u.canLaunch);\n }\n\n get hasTotp(): boolean {\n return !Utils.isNullOrWhitespace(this.totp);\n }\n\n get launchUri(): string {\n if (this.hasUris) {\n const uri = this.uris.find(u => u.canLaunch);\n if (uri != null) {\n return uri.launchUri;\n }\n }\n return null;\n }\n\n get hasUris(): boolean {\n return this.uris != null && this.uris.length > 0;\n }\n}\n","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n ViewChild,\n} from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { PaymentComponent } from './payment.component';\nimport { TaxInfoComponent } from './tax-info.component';\n\nimport { EncString } from 'jslib-common/models/domain/encString';\nimport { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';\n\nimport { PaymentMethodType } from 'jslib-common/enums/paymentMethodType';\nimport { PlanType } from 'jslib-common/enums/planType';\nimport { PolicyType } from 'jslib-common/enums/policyType';\nimport { ProductType } from 'jslib-common/enums/productType';\n\nimport { OrganizationCreateRequest } from 'jslib-common/models/request/organizationCreateRequest';\nimport { OrganizationKeysRequest } from 'jslib-common/models/request/organizationKeysRequest';\nimport { OrganizationUpgradeRequest } from 'jslib-common/models/request/organizationUpgradeRequest';\nimport { ProviderOrganizationCreateRequest } from 'jslib-common/models/request/provider/providerOrganizationCreateRequest';\n\nimport { PlanResponse } from 'jslib-common/models/response/planResponse';\n\n@Component({\n selector: 'app-organization-plans',\n templateUrl: 'organization-plans.component.html',\n})\nexport class OrganizationPlansComponent implements OnInit {\n @ViewChild(PaymentComponent) paymentComponent: PaymentComponent;\n @ViewChild(TaxInfoComponent) taxComponent: TaxInfoComponent;\n\n @Input() organizationId: string;\n @Input() showFree = true;\n @Input() showCancel = false;\n @Input() acceptingSponsorship = false;\n @Input() product: ProductType = ProductType.Free;\n @Input() plan: PlanType = PlanType.Free;\n @Input() providerId: string;\n @Output() onSuccess = new EventEmitter();\n @Output() onCanceled = new EventEmitter();\n\n loading: boolean = true;\n selfHosted: boolean = false;\n ownedBusiness: boolean = false;\n premiumAccessAddon: boolean = false;\n additionalStorage: number = 0;\n additionalSeats: number = 0;\n name: string;\n billingEmail: string;\n clientOwnerEmail: string;\n businessName: string;\n productTypes = ProductType;\n formPromise: Promise;\n singleOrgPolicyBlock: boolean = false;\n discount = 0;\n\n plans: PlanResponse[];\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, platformUtilsService: PlatformUtilsService,\n private cryptoService: CryptoService, private router: Router, private syncService: SyncService,\n private policyService: PolicyService, private userService: UserService, private logService: LogService) {\n this.selfHosted = platformUtilsService.isSelfHost();\n }\n\n async ngOnInit() {\n if (!this.selfHosted) {\n const plans = await this.apiService.getPlans();\n this.plans = plans.data;\n if (this.product === ProductType.Enterprise || this.product === ProductType.Teams) {\n this.ownedBusiness = true;\n }\n }\n\n if (this.providerId) {\n this.ownedBusiness = true;\n this.changedOwnedBusiness();\n }\n\n this.loading = false;\n }\n\n get createOrganization() {\n return this.organizationId == null;\n }\n\n get selectedPlan() {\n return this.plans.find(plan => plan.type === this.plan);\n }\n\n get selectedPlanInterval() {\n return this.selectedPlan.isAnnual\n ? 'year'\n : 'month';\n }\n\n get selectableProducts() {\n let validPlans = this.plans.filter(plan => plan.type !== PlanType.Custom);\n\n if (this.ownedBusiness) {\n validPlans = validPlans.filter(plan => plan.canBeUsedByBusiness);\n }\n\n if (!this.showFree) {\n validPlans = validPlans.filter(plan => plan.product !== ProductType.Free);\n }\n\n validPlans = validPlans\n .filter(plan => !plan.legacyYear\n && !plan.disabled\n && (plan.isAnnual || plan.product === this.productTypes.Free));\n\n if (this.acceptingSponsorship) {\n const familyPlan = this.plans.find(plan => plan.type === PlanType.FamiliesAnnually);\n this.discount = familyPlan.basePrice;\n validPlans = [\n familyPlan,\n ];\n }\n\n return validPlans;\n }\n\n get selectablePlans() {\n return this.plans.filter(plan => !plan.legacyYear && !plan.disabled && plan.product === this.product);\n }\n\n additionalStoragePriceMonthly(selectedPlan: PlanResponse) {\n if (!selectedPlan.isAnnual) {\n return selectedPlan.additionalStoragePricePerGb;\n }\n return selectedPlan.additionalStoragePricePerGb / 12;\n }\n\n seatPriceMonthly(selectedPlan: PlanResponse) {\n if (!selectedPlan.isAnnual) {\n return selectedPlan.seatPrice;\n }\n return selectedPlan.seatPrice / 12;\n }\n\n additionalStorageTotal(plan: PlanResponse): number {\n if (!plan.hasAdditionalStorageOption) {\n return 0;\n }\n\n return plan.additionalStoragePricePerGb * Math.abs(this.additionalStorage || 0);\n }\n\n seatTotal(plan: PlanResponse): number {\n if (!plan.hasAdditionalSeatsOption) {\n return 0;\n }\n\n return plan.seatPrice * Math.abs(this.additionalSeats || 0);\n }\n\n get subtotal() {\n let subTotal = this.selectedPlan.basePrice;\n if (this.selectedPlan.hasAdditionalSeatsOption && this.additionalSeats) {\n subTotal += this.seatTotal(this.selectedPlan);\n }\n if (this.selectedPlan.hasAdditionalStorageOption && this.additionalStorage) {\n subTotal += this.additionalStorageTotal(this.selectedPlan);\n }\n if (this.selectedPlan.hasPremiumAccessOption && this.premiumAccessAddon) {\n subTotal += this.selectedPlan.premiumAccessOptionPrice;\n }\n return subTotal - this.discount;\n }\n\n get freeTrial() {\n return this.selectedPlan.trialPeriodDays != null;\n }\n\n get taxCharges() {\n return this.taxComponent != null && this.taxComponent.taxRate != null ?\n (this.taxComponent.taxRate / 100) * this.subtotal :\n 0;\n }\n\n get total() {\n return (this.subtotal + this.taxCharges) || 0;\n }\n\n get paymentDesc() {\n if (this.acceptingSponsorship) {\n return this.i18nService.t('paymentSponsored');\n } else if (this.freeTrial && this.createOrganization) {\n return this.i18nService.t('paymentChargedWithTrial');\n } else {\n return this.i18nService.t('paymentCharged', this.i18nService.t(this.selectedPlanInterval));\n }\n }\n\n changedProduct() {\n this.plan = this.selectablePlans[0].type;\n if (!this.selectedPlan.hasPremiumAccessOption) {\n this.premiumAccessAddon = false;\n }\n if (!this.selectedPlan.hasAdditionalStorageOption) {\n this.additionalStorage = 0;\n }\n if (!this.selectedPlan.hasAdditionalSeatsOption) {\n this.additionalSeats = 0;\n } else if (!this.additionalSeats && !this.selectedPlan.baseSeats &&\n this.selectedPlan.hasAdditionalSeatsOption) {\n this.additionalSeats = 1;\n }\n }\n\n changedOwnedBusiness() {\n if (!this.ownedBusiness || this.selectedPlan.canBeUsedByBusiness) {\n return;\n }\n this.product = ProductType.Teams;\n this.plan = PlanType.TeamsAnnually;\n }\n\n changedCountry() {\n this.paymentComponent.hideBank = this.taxComponent.taxInfo.country !== 'US';\n // Bank Account payments are only available for US customers\n if (this.paymentComponent.hideBank &&\n this.paymentComponent.method === PaymentMethodType.BankAccount) {\n this.paymentComponent.method = PaymentMethodType.Card;\n this.paymentComponent.changeMethod();\n }\n }\n\n cancel() {\n this.onCanceled.emit();\n }\n\n async submit() {\n this.singleOrgPolicyBlock = await this.userHasBlockingSingleOrgPolicy();\n\n if (this.singleOrgPolicyBlock) {\n return;\n }\n\n try {\n const doSubmit = async (): Promise => {\n let orgId: string = null;\n if (this.createOrganization) {\n const shareKey = await this.cryptoService.makeShareKey();\n const key = shareKey[0].encryptedString;\n const collection = await this.cryptoService.encrypt(\n this.i18nService.t('defaultCollection'), shareKey[1]);\n const collectionCt = collection.encryptedString;\n const orgKeys = await this.cryptoService.makeKeyPair(shareKey[1]);\n\n if (this.selfHosted) {\n orgId = await this.createSelfHosted(key, collectionCt, orgKeys);\n } else {\n orgId = await this.createCloudHosted(key, collectionCt, orgKeys, shareKey[1]);\n }\n\n this.toasterService.popAsync('success', this.i18nService.t('organizationCreated'), this.i18nService.t('organizationReadyToGo'));\n } else {\n orgId = await this.updateOrganization(orgId);\n this.toasterService.popAsync('success', null, this.i18nService.t('organizationUpgraded'));\n }\n\n await this.apiService.refreshIdentityToken();\n await this.syncService.fullSync(true);\n if (!this.acceptingSponsorship) {\n this.router.navigate(['/organizations/' + orgId]);\n }\n\n return orgId;\n };\n\n this.formPromise = doSubmit();\n const orgId = await this.formPromise;\n this.onSuccess.emit({ organizationId: orgId });\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n private async userHasBlockingSingleOrgPolicy() {\n return this.policyService.policyAppliesToUser(PolicyType.SingleOrg);\n }\n\n private async updateOrganization(orgId: string) {\n const request = new OrganizationUpgradeRequest();\n request.businessName = this.ownedBusiness ? this.businessName : null;\n request.additionalSeats = this.additionalSeats;\n request.additionalStorageGb = this.additionalStorage;\n request.premiumAccessAddon = this.selectedPlan.hasPremiumAccessOption && this.premiumAccessAddon;\n request.planType = this.selectedPlan.type;\n request.billingAddressCountry = this.taxComponent.taxInfo.country;\n request.billingAddressPostalCode = this.taxComponent.taxInfo.postalCode;\n\n // Retrieve org info to backfill pub/priv key if necessary\n const org = await this.userService.getOrganization(this.organizationId);\n if (!org.hasPublicAndPrivateKeys) {\n const orgShareKey = await this.cryptoService.getOrgKey(this.organizationId);\n const orgKeys = await this.cryptoService.makeKeyPair(orgShareKey);\n request.keys = new OrganizationKeysRequest(orgKeys[0], orgKeys[1].encryptedString);\n }\n\n const result = await this.apiService.postOrganizationUpgrade(this.organizationId, request);\n if (!result.success && result.paymentIntentClientSecret != null) {\n await this.paymentComponent.handleStripeCardPayment(result.paymentIntentClientSecret, null);\n }\n return this.organizationId;\n }\n\n private async createCloudHosted(key: string, collectionCt: string, orgKeys: [string, EncString], orgKey: SymmetricCryptoKey) {\n const request = new OrganizationCreateRequest();\n request.key = key;\n request.collectionName = collectionCt;\n request.name = this.name;\n request.billingEmail = this.billingEmail;\n request.keys = new OrganizationKeysRequest(orgKeys[0], orgKeys[1].encryptedString);\n\n if (this.selectedPlan.type === PlanType.Free) {\n request.planType = PlanType.Free;\n } else {\n const tokenResult = await this.paymentComponent.createPaymentToken();\n\n request.paymentToken = tokenResult[0];\n request.paymentMethodType = tokenResult[1];\n request.businessName = this.ownedBusiness ? this.businessName : null;\n request.additionalSeats = this.additionalSeats;\n request.additionalStorageGb = this.additionalStorage;\n request.premiumAccessAddon = this.selectedPlan.hasPremiumAccessOption &&\n this.premiumAccessAddon;\n request.planType = this.selectedPlan.type;\n request.billingAddressPostalCode = this.taxComponent.taxInfo.postalCode;\n request.billingAddressCountry = this.taxComponent.taxInfo.country;\n if (this.taxComponent.taxInfo.includeTaxId) {\n request.taxIdNumber = this.taxComponent.taxInfo.taxId;\n request.billingAddressLine1 = this.taxComponent.taxInfo.line1;\n request.billingAddressLine2 = this.taxComponent.taxInfo.line2;\n request.billingAddressCity = this.taxComponent.taxInfo.city;\n request.billingAddressState = this.taxComponent.taxInfo.state;\n }\n }\n\n if (this.providerId) {\n const providerRequest = new ProviderOrganizationCreateRequest(this.clientOwnerEmail, request);\n const providerKey = await this.cryptoService.getProviderKey(this.providerId);\n providerRequest.organizationCreateRequest.key = (await this.cryptoService.encrypt(orgKey.key, providerKey)).encryptedString;\n const orgId = (await this.apiService.postProviderCreateOrganization(this.providerId, providerRequest)).organizationId;\n\n return orgId;\n } else {\n return (await this.apiService.postOrganization(request)).id;\n }\n }\n\n private async createSelfHosted(key: string, collectionCt: string, orgKeys: [string, EncString]) {\n const fileEl = document.getElementById('file') as HTMLInputElement;\n const files = fileEl.files;\n if (files == null || files.length === 0) {\n throw new Error(this.i18nService.t('selectFile'));\n }\n\n const fd = new FormData();\n fd.append('license', files[0]);\n fd.append('key', key);\n fd.append('collectionName', collectionCt);\n const response = await this.apiService.postOrganizationLicense(fd);\n const orgId = response.id;\n\n // Org Keys live outside of the OrganizationLicense - add the keys to the org here\n const request = new OrganizationKeysRequest(orgKeys[0], orgKeys[1].encryptedString);\n await this.apiService.postOrganizationKeys(orgId, request);\n\n return orgId;\n }\n}\n"," {{'loading' | i18n}}

{{'uploadLicenseFileOrg' | i18n}}

{{'licenseFileDesc' | i18n : 'bitwarden_organization_license.json'}}

{{'generalInformation' | i18n}}

{{'clientOwnerDesc' | i18n : '20'}}

{{'chooseYourPlan' | i18n}}

{{'users' | i18n}}

{{'userSeatsHowManyDesc' | i18n}}

{{'addons' | i18n}}

{{'userSeatsAdditionalDesc' | i18n : selectedPlan.baseSeats : (seatPriceMonthly(selectedPlan) | currency:'$')}}
{{'additionalStorageIntervalDesc' | i18n : '1 GB' : (additionalStoragePriceMonthly(selectedPlan) | currency:'$') : ('month' | i18n)}}
{{'premiumAccessDesc' | i18n : (3.33 | currency:'$') : ('month' | i18n)}}

{{'summary' | i18n}}


{{ (createOrganization ? 'paymentInformation' : 'billingInformation') | i18n}}

{{paymentDesc}}
{{ 'planPrice' | i18n }}: {{ subtotal | currency: 'USD $' }}
{{ 'estimatedTax' | i18n }}: {{ taxCharges | currency: 'USD $' }}

{{'total' | i18n}}: {{total | currency:'USD $'}}/{{selectedPlanInterval | i18n}}

{{'singleOrgBlockCreateMessage' | i18n}}
","import { CollectionData } from '../data/collectionData';\n\nimport { CollectionView } from '../view/collectionView';\n\nimport Domain from './domainBase';\nimport { EncString } from './encString';\n\nexport class Collection extends Domain {\n id: string;\n organizationId: string;\n name: EncString;\n externalId: string;\n readOnly: boolean;\n hidePasswords: boolean;\n\n constructor(obj?: CollectionData, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.buildDomainModel(this, obj, {\n id: null,\n organizationId: null,\n name: null,\n externalId: null,\n readOnly: null,\n hidePasswords: null,\n }, alreadyEncrypted, ['id', 'organizationId', 'externalId', 'readOnly', 'hidePasswords']);\n }\n\n decrypt(): Promise {\n return this.decryptObj(new CollectionView(this), {\n name: null,\n }, this.organizationId);\n }\n}\n","import { View } from './view';\n\nimport { Collection } from '../domain/collection';\nimport { ITreeNodeObject } from '../domain/treeNode';\n\nimport { CollectionGroupDetailsResponse } from '../response/collectionResponse';\n\nexport class CollectionView implements View, ITreeNodeObject {\n id: string = null;\n organizationId: string = null;\n name: string = null;\n externalId: string = null;\n readOnly: boolean = null;\n hidePasswords: boolean = null;\n\n constructor(c?: Collection | CollectionGroupDetailsResponse) {\n if (!c) {\n return;\n }\n\n this.id = c.id;\n this.organizationId = c.organizationId;\n this.externalId = c.externalId;\n if (c instanceof Collection) {\n this.readOnly = c.readOnly;\n this.hidePasswords = c.hidePasswords;\n }\n }\n}\n","import { CipherRepromptType } from '../../enums/cipherRepromptType';\nimport { CipherType } from '../../enums/cipherType';\n\nimport { AttachmentData } from './attachmentData';\nimport { CardData } from './cardData';\nimport { FieldData } from './fieldData';\nimport { IdentityData } from './identityData';\nimport { LoginData } from './loginData';\nimport { PasswordHistoryData } from './passwordHistoryData';\nimport { SecureNoteData } from './secureNoteData';\n\nimport { CipherResponse } from '../response/cipherResponse';\n\nexport class CipherData {\n id: string;\n organizationId: string;\n folderId: string;\n userId: string;\n edit: boolean;\n viewPassword: boolean;\n organizationUseTotp: boolean;\n favorite: boolean;\n revisionDate: string;\n type: CipherType;\n sizeName: string;\n name: string;\n notes: string;\n login?: LoginData;\n secureNote?: SecureNoteData;\n card?: CardData;\n identity?: IdentityData;\n fields?: FieldData[];\n attachments?: AttachmentData[];\n passwordHistory?: PasswordHistoryData[];\n collectionIds?: string[];\n deletedDate: string;\n reprompt: CipherRepromptType;\n\n constructor(response?: CipherResponse, userId?: string, collectionIds?: string[]) {\n if (response == null) {\n return;\n }\n\n this.id = response.id;\n this.organizationId = response.organizationId;\n this.folderId = response.folderId;\n this.userId = userId;\n this.edit = response.edit;\n this.viewPassword = response.viewPassword;\n this.organizationUseTotp = response.organizationUseTotp;\n this.favorite = response.favorite;\n this.revisionDate = response.revisionDate;\n this.type = response.type;\n this.name = response.name;\n this.notes = response.notes;\n this.collectionIds = collectionIds != null ? collectionIds : response.collectionIds;\n this.deletedDate = response.deletedDate;\n this.reprompt = response.reprompt;\n\n switch (this.type) {\n case CipherType.Login:\n this.login = new LoginData(response.login);\n break;\n case CipherType.SecureNote:\n this.secureNote = new SecureNoteData(response.secureNote);\n break;\n case CipherType.Card:\n this.card = new CardData(response.card);\n break;\n case CipherType.Identity:\n this.identity = new IdentityData(response.identity);\n break;\n default:\n break;\n }\n\n if (response.fields != null) {\n this.fields = response.fields.map(f => new FieldData(f));\n }\n if (response.attachments != null) {\n this.attachments = response.attachments.map(a => new AttachmentData(a));\n }\n if (response.passwordHistory != null) {\n this.passwordHistory = response.passwordHistory.map(ph => new PasswordHistoryData(ph));\n }\n }\n}\n","export enum CipherRepromptType {\n None = 0,\n Password = 1,\n}\n","export enum SendType {\n Text = 0,\n File = 1,\n}\n","import { Utils } from '../../misc/utils';\n\nimport { BaseResponse } from './baseResponse';\n\nexport class ErrorResponse extends BaseResponse {\n message: string;\n validationErrors: { [key: string]: string[]; };\n statusCode: number;\n captchaRequired: boolean;\n captchaSiteKey: string;\n\n constructor(response: any, status: number, identityResponse?: boolean) {\n super(response);\n let errorModel = null;\n if (response != null) {\n const responseErrorModel = this.getResponseProperty('ErrorModel');\n if (responseErrorModel && identityResponse) {\n errorModel = responseErrorModel;\n } else {\n errorModel = response;\n }\n }\n\n if (errorModel) {\n this.message = this.getResponseProperty('Message', errorModel);\n this.validationErrors = this.getResponseProperty('ValidationErrors', errorModel);\n this.captchaSiteKey = this.validationErrors?.HCaptcha_SiteKey?.[0];\n this.captchaRequired = !Utils.isNullOrWhitespace(this.captchaSiteKey);\n } else {\n if (status === 429) {\n this.message = 'Rate limit exceeded. Try again later.';\n }\n }\n this.statusCode = status;\n }\n\n getSingleMessage(): string {\n if (this.validationErrors == null) {\n return this.message;\n }\n for (const key in this.validationErrors) {\n if (!this.validationErrors.hasOwnProperty(key)) {\n continue;\n }\n if (this.validationErrors[key].length) {\n return this.validationErrors[key][0];\n }\n }\n return this.message;\n }\n\n getAllMessages(): string[] {\n const messages: string[] = [];\n if (this.validationErrors == null) {\n return messages;\n }\n for (const key in this.validationErrors) {\n if (!this.validationErrors.hasOwnProperty(key)) {\n continue;\n }\n this.validationErrors[key].forEach((item: string) => {\n let prefix = '';\n if (key.indexOf('[') > -1 && key.indexOf(']') > -1) {\n const lastSep = key.lastIndexOf('.');\n prefix = key.substr(0, lastSep > -1 ? lastSep : key.length) + ': ';\n }\n messages.push(prefix + item);\n });\n }\n return messages;\n }\n}\n","export enum EventType {\n User_LoggedIn = 1000,\n User_ChangedPassword = 1001,\n User_Updated2fa = 1002,\n User_Disabled2fa = 1003,\n User_Recovered2fa = 1004,\n User_FailedLogIn = 1005,\n User_FailedLogIn2fa = 1006,\n User_ClientExportedVault = 1007,\n User_UpdatedTempPassword = 1008,\n User_MigratedKeyToKeyConnector = 1009,\n\n Cipher_Created = 1100,\n Cipher_Updated = 1101,\n Cipher_Deleted = 1102,\n Cipher_AttachmentCreated = 1103,\n Cipher_AttachmentDeleted = 1104,\n Cipher_Shared = 1105,\n Cipher_UpdatedCollections = 1106,\n Cipher_ClientViewed = 1107,\n Cipher_ClientToggledPasswordVisible = 1108,\n Cipher_ClientToggledHiddenFieldVisible = 1109,\n Cipher_ClientToggledCardCodeVisible = 1110,\n Cipher_ClientCopiedPassword = 1111,\n Cipher_ClientCopiedHiddenField = 1112,\n Cipher_ClientCopiedCardCode = 1113,\n Cipher_ClientAutofilled = 1114,\n Cipher_SoftDeleted = 1115,\n Cipher_Restored = 1116,\n Cipher_ClientToggledCardNumberVisible = 1117,\n\n Collection_Created = 1300,\n Collection_Updated = 1301,\n Collection_Deleted = 1302,\n\n Group_Created = 1400,\n Group_Updated = 1401,\n Group_Deleted = 1402,\n\n OrganizationUser_Invited = 1500,\n OrganizationUser_Confirmed = 1501,\n OrganizationUser_Updated = 1502,\n OrganizationUser_Removed = 1503,\n OrganizationUser_UpdatedGroups = 1504,\n OrganizationUser_UnlinkedSso = 1505,\n OrganizationUser_ResetPassword_Enroll = 1506,\n OrganizationUser_ResetPassword_Withdraw = 1507,\n OrganizationUser_AdminResetPassword = 1508,\n OrganizationUser_ResetSsoLink = 1509,\n OrganizationUser_FirstSsoLogin = 1510,\n\n Organization_Updated = 1600,\n Organization_PurgedVault = 1601,\n // Organization_ClientExportedVault = 1602,\n Organization_VaultAccessed = 1603,\n Organization_EnabledSso = 1604,\n Organization_DisabledSso = 1605,\n Organization_EnabledKeyConnector = 1606,\n Organization_DisabledKeyConnector = 1607,\n\n Policy_Updated = 1700,\n\n ProviderUser_Invited = 1800,\n ProviderUser_Confirmed = 1801,\n ProviderUser_Updated = 1802,\n ProviderUser_Removed = 1803,\n\n ProviderOrganization_Created = 1900,\n ProviderOrganization_Added = 1901,\n ProviderOrganization_Removed = 1902,\n ProviderOrganization_VaultAccessed = 1903,\n}\n","export enum OrganizationUserStatusType {\n Invited = 0,\n Accepted = 1,\n Confirmed = 2,\n}\n","import {\n Component,\n Input,\n OnChanges,\n} from '@angular/core';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\n@Component({\n selector: 'app-password-strength',\n templateUrl: 'password-strength.component.html',\n})\nexport class PasswordStrengthComponent implements OnChanges {\n @Input() score?: number;\n @Input() showText = false;\n\n scoreWidth = 0;\n color = 'bg-danger';\n text: string;\n\n constructor(private i18nService: I18nService) { }\n\n ngOnChanges(): void {\n this.scoreWidth = this.score == null ? 0 : (this.score + 1) * 20;\n switch (this.score) {\n case 4:\n this.color = 'bg-success';\n this.text = this.i18nService.t('strong');\n break;\n case 3:\n this.color = 'bg-primary';\n this.text = this.i18nService.t('good');\n break;\n case 2:\n this.color = 'bg-warning';\n this.text = this.i18nService.t('weak');\n break;\n default:\n this.color = 'bg-danger';\n this.text = this.score != null ? this.i18nService.t('weak') : null;\n break;\n }\n }\n}\n","
{{text}}
","import { CollectionDetailsResponse } from '../response/collectionResponse';\n\nexport class CollectionData {\n id: string;\n organizationId: string;\n name: string;\n externalId: string;\n readOnly: boolean;\n\n constructor(response: CollectionDetailsResponse) {\n this.id = response.id;\n this.organizationId = response.organizationId;\n this.name = response.name;\n this.externalId = response.externalId;\n this.readOnly = response.readOnly;\n }\n}\n","import {\n Component,\n EventEmitter,\n Input,\n Output,\n} from '@angular/core';\n\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\nimport { VerificationType } from 'jslib-common/enums/verificationType';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { Verification } from 'jslib-common/types/verification';\n\nimport { TwoFactorAuthenticatorResponse } from 'jslib-common/models/response/twoFactorAuthenticatorResponse';\nimport { TwoFactorDuoResponse } from 'jslib-common/models/response/twoFactorDuoResponse';\nimport { TwoFactorEmailResponse } from 'jslib-common/models/response/twoFactorEmailResponse';\nimport { TwoFactorRecoverResponse } from 'jslib-common/models/response/twoFactorRescoverResponse';\nimport { TwoFactorWebAuthnResponse } from 'jslib-common/models/response/twoFactorWebAuthnResponse';\nimport { TwoFactorYubiKeyResponse } from 'jslib-common/models/response/twoFactorYubiKeyResponse';\n\nimport { SecretVerificationRequest } from 'jslib-common/models/request/secretVerificationRequest';\n\ntype TwoFactorResponse = TwoFactorRecoverResponse | TwoFactorDuoResponse | TwoFactorEmailResponse |\n TwoFactorWebAuthnResponse | TwoFactorAuthenticatorResponse | TwoFactorYubiKeyResponse;\n\n@Component({\n selector: 'app-two-factor-verify',\n templateUrl: 'two-factor-verify.component.html',\n})\nexport class TwoFactorVerifyComponent {\n @Input() type: TwoFactorProviderType;\n @Input() organizationId: string;\n @Output() onAuthed = new EventEmitter();\n\n secret: Verification;\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private logService: LogService,\n private userVerificationService: UserVerificationService) { }\n\n async submit() {\n let hashedSecret: string;\n\n try {\n this.formPromise = this.userVerificationService.buildRequest(this.secret)\n .then(request => {\n hashedSecret = this.secret.type === VerificationType.MasterPassword\n ? request.masterPasswordHash\n : request.otp;\n return this.apiCall(request);\n });\n\n const response = await this.formPromise;\n this.onAuthed.emit({\n response: response,\n secret: hashedSecret,\n verificationType: this.secret.type,\n });\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n private apiCall(request: SecretVerificationRequest): Promise {\n switch (this.type) {\n case -1:\n return this.apiService.getTwoFactorRecover(request);\n case TwoFactorProviderType.Duo:\n case TwoFactorProviderType.OrganizationDuo:\n if (this.organizationId != null) {\n return this.apiService.getTwoFactorOrganizationDuo(this.organizationId, request);\n } else {\n return this.apiService.getTwoFactorDuo(request);\n }\n case TwoFactorProviderType.Email:\n return this.apiService.getTwoFactorEmail(request);\n case TwoFactorProviderType.WebAuthn:\n return this.apiService.getTwoFactorWebAuthn(request);\n case TwoFactorProviderType.Authenticator:\n return this.apiService.getTwoFactorAuthenticator(request);\n case TwoFactorProviderType.Yubikey:\n return this.apiService.getTwoFactorYubiKey(request);\n }\n }\n}\n","

{{'twoStepLoginAuthDesc' | i18n}}

","import { CipherRepromptType } from '../../enums/cipherRepromptType';\nimport { CipherType } from '../../enums/cipherType';\n\nimport { CipherData } from '../data/cipherData';\n\nimport { CipherView } from '../view/cipherView';\n\nimport { Attachment } from './attachment';\nimport { Card } from './card';\nimport Domain from './domainBase';\nimport { EncString } from './encString';\nimport { Field } from './field';\nimport { Identity } from './identity';\nimport { Login } from './login';\nimport { Password } from './password';\nimport { SecureNote } from './secureNote';\nimport { SymmetricCryptoKey } from './symmetricCryptoKey';\n\nexport class Cipher extends Domain {\n id: string;\n organizationId: string;\n folderId: string;\n name: EncString;\n notes: EncString;\n type: CipherType;\n favorite: boolean;\n organizationUseTotp: boolean;\n edit: boolean;\n viewPassword: boolean;\n revisionDate: Date;\n localData: any;\n login: Login;\n identity: Identity;\n card: Card;\n secureNote: SecureNote;\n attachments: Attachment[];\n fields: Field[];\n passwordHistory: Password[];\n collectionIds: string[];\n deletedDate: Date;\n reprompt: CipherRepromptType;\n\n constructor(obj?: CipherData, alreadyEncrypted: boolean = false, localData: any = null) {\n super();\n if (obj == null) {\n return;\n }\n\n this.buildDomainModel(this, obj, {\n id: null,\n userId: null,\n organizationId: null,\n folderId: null,\n name: null,\n notes: null,\n }, alreadyEncrypted, ['id', 'userId', 'organizationId', 'folderId']);\n\n this.type = obj.type;\n this.favorite = obj.favorite;\n this.organizationUseTotp = obj.organizationUseTotp;\n this.edit = obj.edit;\n if (obj.viewPassword != null) {\n this.viewPassword = obj.viewPassword;\n } else {\n this.viewPassword = true; // Default for already synced Ciphers without viewPassword\n }\n this.revisionDate = obj.revisionDate != null ? new Date(obj.revisionDate) : null;\n this.collectionIds = obj.collectionIds;\n this.localData = localData;\n this.deletedDate = obj.deletedDate != null ? new Date(obj.deletedDate) : null;\n this.reprompt = obj.reprompt;\n\n switch (this.type) {\n case CipherType.Login:\n this.login = new Login(obj.login, alreadyEncrypted);\n break;\n case CipherType.SecureNote:\n this.secureNote = new SecureNote(obj.secureNote, alreadyEncrypted);\n break;\n case CipherType.Card:\n this.card = new Card(obj.card, alreadyEncrypted);\n break;\n case CipherType.Identity:\n this.identity = new Identity(obj.identity, alreadyEncrypted);\n break;\n default:\n break;\n }\n\n if (obj.attachments != null) {\n this.attachments = obj.attachments.map(a => new Attachment(a, alreadyEncrypted));\n } else {\n this.attachments = null;\n }\n\n if (obj.fields != null) {\n this.fields = obj.fields.map(f => new Field(f, alreadyEncrypted));\n } else {\n this.fields = null;\n }\n\n if (obj.passwordHistory != null) {\n this.passwordHistory = obj.passwordHistory.map(ph => new Password(ph, alreadyEncrypted));\n } else {\n this.passwordHistory = null;\n }\n }\n\n async decrypt(encKey?: SymmetricCryptoKey): Promise {\n const model = new CipherView(this);\n\n await this.decryptObj(model, {\n name: null,\n notes: null,\n }, this.organizationId, encKey);\n\n switch (this.type) {\n case CipherType.Login:\n model.login = await this.login.decrypt(this.organizationId, encKey);\n break;\n case CipherType.SecureNote:\n model.secureNote = await this.secureNote.decrypt(this.organizationId, encKey);\n break;\n case CipherType.Card:\n model.card = await this.card.decrypt(this.organizationId, encKey);\n break;\n case CipherType.Identity:\n model.identity = await this.identity.decrypt(this.organizationId, encKey);\n break;\n default:\n break;\n }\n\n const orgId = this.organizationId;\n\n if (this.attachments != null && this.attachments.length > 0) {\n const attachments: any[] = [];\n await this.attachments.reduce((promise, attachment) => {\n return promise.then(() => {\n return attachment.decrypt(orgId, encKey);\n }).then(decAttachment => {\n attachments.push(decAttachment);\n });\n }, Promise.resolve());\n model.attachments = attachments;\n }\n\n if (this.fields != null && this.fields.length > 0) {\n const fields: any[] = [];\n await this.fields.reduce((promise, field) => {\n return promise.then(() => {\n return field.decrypt(orgId, encKey);\n }).then(decField => {\n fields.push(decField);\n });\n }, Promise.resolve());\n model.fields = fields;\n }\n\n if (this.passwordHistory != null && this.passwordHistory.length > 0) {\n const passwordHistory: any[] = [];\n await this.passwordHistory.reduce((promise, ph) => {\n return promise.then(() => {\n return ph.decrypt(orgId, encKey);\n }).then(decPh => {\n passwordHistory.push(decPh);\n });\n }, Promise.resolve());\n model.passwordHistory = passwordHistory;\n }\n\n return model;\n }\n\n toCipherData(userId: string): CipherData {\n const c = new CipherData();\n c.id = this.id;\n c.organizationId = this.organizationId;\n c.folderId = this.folderId;\n c.userId = this.organizationId != null ? userId : null;\n c.edit = this.edit;\n c.viewPassword = this.viewPassword;\n c.organizationUseTotp = this.organizationUseTotp;\n c.favorite = this.favorite;\n c.revisionDate = this.revisionDate != null ? this.revisionDate.toISOString() : null;\n c.type = this.type;\n c.collectionIds = this.collectionIds;\n c.deletedDate = this.deletedDate != null ? this.deletedDate.toISOString() : null;\n c.reprompt = this.reprompt;\n\n this.buildDataModel(this, c, {\n name: null,\n notes: null,\n });\n\n switch (c.type) {\n case CipherType.Login:\n c.login = this.login.toLoginData();\n break;\n case CipherType.SecureNote:\n c.secureNote = this.secureNote.toSecureNoteData();\n break;\n case CipherType.Card:\n c.card = this.card.toCardData();\n break;\n case CipherType.Identity:\n c.identity = this.identity.toIdentityData();\n break;\n default:\n break;\n }\n\n if (this.fields != null) {\n c.fields = this.fields.map(f => f.toFieldData());\n }\n if (this.attachments != null) {\n c.attachments = this.attachments.map(a => a.toAttachmentData());\n }\n if (this.passwordHistory != null) {\n c.passwordHistory = this.passwordHistory.map(ph => ph.toPasswordHistoryData());\n }\n return c;\n }\n}\n","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { TokenService } from 'jslib-common/abstractions/token.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Provider } from 'jslib-common/models/domain/provider';\n\n@Component({\n selector: 'app-navbar',\n templateUrl: 'navbar.component.html',\n})\nexport class NavbarComponent implements OnInit {\n selfHosted = false;\n name: string;\n email: string;\n providers: Provider[] = [];\n\n constructor(private messagingService: MessagingService, private platformUtilsService: PlatformUtilsService,\n private tokenService: TokenService, private userService: UserService, private syncService: SyncService) {\n this.selfHosted = this.platformUtilsService.isSelfHost();\n }\n\n async ngOnInit() {\n this.name = await this.tokenService.getName();\n this.email = await this.tokenService.getEmail();\n if (this.name == null || this.name.trim() === '') {\n this.name = this.email;\n }\n\n // Ensure provides are loaded\n if (await this.syncService.getLastSync() == null) {\n await this.syncService.fullSync(false);\n }\n this.providers = await this.userService.getAllProviders();\n }\n\n lock() {\n this.messagingService.send('lockVault');\n }\n\n logOut() {\n this.messagingService.send('logout');\n }\n}\n"," ","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\n@Component({\n selector: 'app-footer',\n templateUrl: 'footer.component.html',\n})\nexport class FooterComponent implements OnInit {\n version: string;\n year: string = '2015';\n\n constructor(private platformUtilsService: PlatformUtilsService) { }\n\n async ngOnInit() {\n this.year = new Date().getFullYear().toString();\n this.version = await this.platformUtilsService.getApplicationVersion();\n }\n}\n","
© {{year}}, Bitwarden Inc.
{{'versionNumber' | i18n : version}}
","export enum PlanType {\n Free = 0,\n FamiliesAnnually2019 = 1,\n TeamsMonthly2019 = 2,\n TeamsAnnually2019 = 3,\n EnterpriseMonthly2019 = 4,\n EnterpriseAnnually2019 = 5,\n Custom = 6,\n FamiliesAnnually = 7,\n TeamsMonthly = 8,\n TeamsAnnually = 9,\n EnterpriseMonthly = 10,\n EnterpriseAnnually = 11,\n}\n","import { BaseResponse } from '../response/baseResponse';\n\nexport class PermissionsApi extends BaseResponse {\n accessEventLogs: boolean;\n accessImportExport: boolean;\n accessReports: boolean;\n /**\n * @deprecated Sep 29 2021: This permission has been split out to `createNewCollections`, `editAnyCollection`, and\n * `deleteAnyCollection`. It exists here for backwards compatibility with Server versions <= 1.43.0\n */\n manageAllCollections: boolean;\n createNewCollections: boolean;\n editAnyCollection: boolean;\n deleteAnyCollection: boolean;\n /**\n * @deprecated Sep 29 2021: This permission has been split out to `editAssignedCollections` and\n * `deleteAssignedCollections`. It exists here for backwards compatibility with Server versions <= 1.43.0\n */\n manageAssignedCollections: boolean;\n editAssignedCollections: boolean;\n deleteAssignedCollections: boolean;\n manageCiphers: boolean;\n manageGroups: boolean;\n manageSso: boolean;\n managePolicies: boolean;\n manageUsers: boolean;\n manageResetPassword: boolean;\n\n constructor(data: any = null) {\n super(data);\n if (data == null) {\n return this;\n }\n this.accessEventLogs = this.getResponseProperty('AccessEventLogs');\n this.accessImportExport = this.getResponseProperty('AccessImportExport');\n this.accessReports = this.getResponseProperty('AccessReports');\n\n // For backwards compatibility with Server <= 1.43.0\n this.manageAllCollections = this.getResponseProperty('ManageAllCollections');\n this.manageAssignedCollections = this.getResponseProperty('ManageAssignedCollections');\n\n this.createNewCollections = this.getResponseProperty('CreateNewCollections');\n this.editAnyCollection = this.getResponseProperty('EditAnyCollection');\n this.deleteAnyCollection = this.getResponseProperty('DeleteAnyCollection');\n this.editAssignedCollections = this.getResponseProperty('EditAssignedCollections');\n this.deleteAssignedCollections = this.getResponseProperty('DeleteAssignedCollections');\n\n this.manageCiphers = this.getResponseProperty('ManageCiphers');\n this.manageGroups = this.getResponseProperty('ManageGroups');\n this.manageSso = this.getResponseProperty('ManageSso');\n this.managePolicies = this.getResponseProperty('ManagePolicies');\n this.manageUsers = this.getResponseProperty('ManageUsers');\n this.manageResetPassword = this.getResponseProperty('ManageResetPassword');\n }\n}\n","export enum OrganizationUserType {\n Owner = 0,\n Admin = 1,\n User = 2,\n Manager = 3,\n Custom = 4,\n}\n","import { EncryptionType } from '../../enums/encryptionType';\n\nimport { Utils } from '../../misc/utils';\n\nexport class SymmetricCryptoKey {\n key: ArrayBuffer;\n encKey?: ArrayBuffer;\n macKey?: ArrayBuffer;\n encType: EncryptionType;\n\n keyB64: string;\n encKeyB64: string;\n macKeyB64: string;\n\n meta: any;\n\n constructor(key: ArrayBuffer, encType?: EncryptionType) {\n if (key == null) {\n throw new Error('Must provide key');\n }\n\n if (encType == null) {\n if (key.byteLength === 32) {\n encType = EncryptionType.AesCbc256_B64;\n } else if (key.byteLength === 64) {\n encType = EncryptionType.AesCbc256_HmacSha256_B64;\n } else {\n throw new Error('Unable to determine encType.');\n }\n }\n\n this.key = key;\n this.encType = encType;\n\n if (encType === EncryptionType.AesCbc256_B64 && key.byteLength === 32) {\n this.encKey = key;\n this.macKey = null;\n } else if (encType === EncryptionType.AesCbc128_HmacSha256_B64 && key.byteLength === 32) {\n this.encKey = key.slice(0, 16);\n this.macKey = key.slice(16, 32);\n } else if (encType === EncryptionType.AesCbc256_HmacSha256_B64 && key.byteLength === 64) {\n this.encKey = key.slice(0, 32);\n this.macKey = key.slice(32, 64);\n } else {\n throw new Error('Unsupported encType/key length.');\n }\n\n if (this.key != null) {\n this.keyB64 = Utils.fromBufferToB64(this.key);\n }\n if (this.encKey != null) {\n this.encKeyB64 = Utils.fromBufferToB64(this.encKey);\n }\n if (this.macKey != null) {\n this.macKeyB64 = Utils.fromBufferToB64(this.macKey);\n }\n }\n}\n","import { CipherRepromptType } from '../../enums/cipherRepromptType';\nimport { CipherType } from '../../enums/cipherType';\n\nimport { Cipher } from '../domain/cipher';\n\nimport { CardApi } from '../api/cardApi';\nimport { FieldApi } from '../api/fieldApi';\nimport { IdentityApi } from '../api/identityApi';\nimport { LoginApi } from '../api/loginApi';\nimport { LoginUriApi } from '../api/loginUriApi';\nimport { SecureNoteApi } from '../api/secureNoteApi';\n\nimport { AttachmentRequest } from './attachmentRequest';\nimport { PasswordHistoryRequest } from './passwordHistoryRequest';\n\nexport class CipherRequest {\n type: CipherType;\n folderId: string;\n organizationId: string;\n name: string;\n notes: string;\n favorite: boolean;\n login: LoginApi;\n secureNote: SecureNoteApi;\n card: CardApi;\n identity: IdentityApi;\n fields: FieldApi[];\n passwordHistory: PasswordHistoryRequest[];\n // Deprecated, remove at some point and rename attachments2 to attachments\n attachments: { [id: string]: string; };\n attachments2: { [id: string]: AttachmentRequest; };\n lastKnownRevisionDate: Date;\n reprompt: CipherRepromptType;\n\n constructor(cipher: Cipher) {\n this.type = cipher.type;\n this.folderId = cipher.folderId;\n this.organizationId = cipher.organizationId;\n this.name = cipher.name ? cipher.name.encryptedString : null;\n this.notes = cipher.notes ? cipher.notes.encryptedString : null;\n this.favorite = cipher.favorite;\n this.lastKnownRevisionDate = cipher.revisionDate;\n this.reprompt = cipher.reprompt;\n\n switch (this.type) {\n case CipherType.Login:\n this.login = new LoginApi();\n this.login.uris = null;\n this.login.username = cipher.login.username ? cipher.login.username.encryptedString : null;\n this.login.password = cipher.login.password ? cipher.login.password.encryptedString : null;\n this.login.passwordRevisionDate = cipher.login.passwordRevisionDate != null ?\n cipher.login.passwordRevisionDate.toISOString() : null;\n this.login.totp = cipher.login.totp ? cipher.login.totp.encryptedString : null;\n this.login.autofillOnPageLoad = cipher.login.autofillOnPageLoad;\n\n if (cipher.login.uris != null) {\n this.login.uris = cipher.login.uris.map(u => {\n const uri = new LoginUriApi();\n uri.uri = u.uri != null ? u.uri.encryptedString : null;\n uri.match = u.match != null ? u.match : null;\n return uri;\n });\n }\n break;\n case CipherType.SecureNote:\n this.secureNote = new SecureNoteApi();\n this.secureNote.type = cipher.secureNote.type;\n break;\n case CipherType.Card:\n this.card = new CardApi();\n this.card.cardholderName = cipher.card.cardholderName != null ?\n cipher.card.cardholderName.encryptedString : null;\n this.card.brand = cipher.card.brand != null ? cipher.card.brand.encryptedString : null;\n this.card.number = cipher.card.number != null ? cipher.card.number.encryptedString : null;\n this.card.expMonth = cipher.card.expMonth != null ? cipher.card.expMonth.encryptedString : null;\n this.card.expYear = cipher.card.expYear != null ? cipher.card.expYear.encryptedString : null;\n this.card.code = cipher.card.code != null ? cipher.card.code.encryptedString : null;\n break;\n case CipherType.Identity:\n this.identity = new IdentityApi();\n this.identity.title = cipher.identity.title != null ? cipher.identity.title.encryptedString : null;\n this.identity.firstName = cipher.identity.firstName != null ?\n cipher.identity.firstName.encryptedString : null;\n this.identity.middleName = cipher.identity.middleName != null ?\n cipher.identity.middleName.encryptedString : null;\n this.identity.lastName = cipher.identity.lastName != null ?\n cipher.identity.lastName.encryptedString : null;\n this.identity.address1 = cipher.identity.address1 != null ?\n cipher.identity.address1.encryptedString : null;\n this.identity.address2 = cipher.identity.address2 != null ?\n cipher.identity.address2.encryptedString : null;\n this.identity.address3 = cipher.identity.address3 != null ?\n cipher.identity.address3.encryptedString : null;\n this.identity.city = cipher.identity.city != null ? cipher.identity.city.encryptedString : null;\n this.identity.state = cipher.identity.state != null ? cipher.identity.state.encryptedString : null;\n this.identity.postalCode = cipher.identity.postalCode != null ?\n cipher.identity.postalCode.encryptedString : null;\n this.identity.country = cipher.identity.country != null ?\n cipher.identity.country.encryptedString : null;\n this.identity.company = cipher.identity.company != null ?\n cipher.identity.company.encryptedString : null;\n this.identity.email = cipher.identity.email != null ? cipher.identity.email.encryptedString : null;\n this.identity.phone = cipher.identity.phone != null ? cipher.identity.phone.encryptedString : null;\n this.identity.ssn = cipher.identity.ssn != null ? cipher.identity.ssn.encryptedString : null;\n this.identity.username = cipher.identity.username != null ?\n cipher.identity.username.encryptedString : null;\n this.identity.passportNumber = cipher.identity.passportNumber != null ?\n cipher.identity.passportNumber.encryptedString : null;\n this.identity.licenseNumber = cipher.identity.licenseNumber != null ?\n cipher.identity.licenseNumber.encryptedString : null;\n break;\n default:\n break;\n }\n\n if (cipher.fields != null) {\n this.fields = cipher.fields.map(f => {\n const field = new FieldApi();\n field.type = f.type;\n field.name = f.name ? f.name.encryptedString : null;\n field.value = f.value ? f.value.encryptedString : null;\n field.linkedId = f.linkedId;\n return field;\n });\n }\n\n if (cipher.passwordHistory != null) {\n this.passwordHistory = [];\n cipher.passwordHistory.forEach(ph => {\n this.passwordHistory.push({\n lastUsedDate: ph.lastUsedDate,\n password: ph.password ? ph.password.encryptedString : null,\n });\n });\n }\n\n if (cipher.attachments != null) {\n this.attachments = {};\n this.attachments2 = {};\n cipher.attachments.forEach(attachment => {\n const fileName = attachment.fileName ? attachment.fileName.encryptedString : null;\n this.attachments[attachment.id] = fileName;\n const attachmentRequest = new AttachmentRequest();\n attachmentRequest.fileName = fileName;\n if (attachment.key != null) {\n attachmentRequest.key = attachment.key.encryptedString;\n }\n this.attachments2[attachment.id] = attachmentRequest;\n });\n }\n }\n}\n","import { Observable, Subject } from 'rxjs';\nimport { first } from 'rxjs/operators';\n\nexport class ModalRef {\n\n onCreated: Observable; // Modal added to the DOM.\n onClose: Observable; // Initiated close.\n onClosed: Observable; // Modal was closed (Remove element from DOM)\n onShow: Observable; // Start showing modal\n onShown: Observable; // Modal is fully visible\n\n private readonly _onCreated = new Subject();\n private readonly _onClose = new Subject();\n private readonly _onClosed = new Subject();\n private readonly _onShow = new Subject();\n private readonly _onShown = new Subject();\n private lastResult: any;\n\n constructor() {\n this.onCreated = this._onCreated.asObservable();\n this.onClose = this._onClose.asObservable();\n this.onClosed = this._onClosed.asObservable();\n this.onShow = this._onShow.asObservable();\n this.onShown = this._onShow.asObservable();\n }\n\n show() {\n this._onShow.next();\n }\n\n shown() {\n this._onShown.next();\n }\n\n close(result?: any) {\n this.lastResult = result;\n this._onClose.next(result);\n }\n\n closed() {\n this._onClosed.next(this.lastResult);\n }\n\n created(el: HTMLElement) {\n this._onCreated.next(el);\n }\n\n onClosedPromise(): Promise {\n return this.onClosed.pipe(first()).toPromise();\n }\n}\n","export enum Permissions {\n AccessEventLogs,\n AccessImportExport,\n AccessReports,\n /**\n * @deprecated Sep 29 2021: This permission has been split out to `createNewCollections`, `editAnyCollection`, and\n * `deleteAnyCollection`. It exists here for backwards compatibility with Server versions <= 1.43.0\n */\n ManageAllCollections,\n /**\n * @deprecated Sep 29 2021: This permission has been split out to `editAssignedCollections` and\n * `deleteAssignedCollections`. It exists here for backwards compatibility with Server versions <= 1.43.0\n */\n ManageAssignedCollections,\n ManageGroups,\n ManageOrganization ,\n ManagePolicies,\n ManageProvider,\n ManageUsers,\n ManageUsersPassword,\n CreateNewCollections,\n EditAnyCollection,\n DeleteAnyCollection,\n EditAssignedCollections,\n DeleteAssignedCollections,\n ManageSso,\n}\n","import { Injectable } from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\n\nimport { ProviderAddOrganizationRequest } from 'jslib-common/models/request/provider/providerAddOrganizationRequest';\n\n@Injectable()\nexport class ProviderService {\n constructor(private cryptoService: CryptoService, private syncService: SyncService, private apiService: ApiService) {}\n\n async addOrganizationToProvider(providerId: string, organizationId: string) {\n const orgKey = await this.cryptoService.getOrgKey(organizationId);\n const providerKey = await this.cryptoService.getProviderKey(providerId);\n\n const encryptedOrgKey = await this.cryptoService.encrypt(orgKey.key, providerKey);\n\n const request = new ProviderAddOrganizationRequest();\n request.organizationId = organizationId;\n request.key = encryptedOrgKey.encryptedString;\n\n const response = await this.apiService.postProviderAddOrganization(providerId, request);\n await this.syncService.fullSync(true);\n return response;\n }\n\n async detachOrganizastion(providerId: string, organizationId: string): Promise {\n await this.apiService.deleteProviderOrganization(providerId, organizationId);\n await this.syncService.fullSync(true);\n }\n}\n","export enum PaymentMethodType {\n Card = 0,\n BankAccount = 1,\n PayPal = 2,\n BitPay = 3,\n Credit = 4,\n WireTransfer = 5,\n AppleInApp = 6,\n GoogleInApp = 7,\n Check = 8,\n}\n","import { Injectable } from '@angular/core';\nimport { Title } from '@angular/platform-browser';\nimport {\n ActivatedRoute,\n NavigationEnd,\n Router,\n} from '@angular/router';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\n@Injectable()\nexport class RouterService {\n private previousUrl: string = undefined;\n private currentUrl: string = undefined;\n\n constructor(private router: Router, private activatedRoute: ActivatedRoute,\n private titleService: Title, i18nService: I18nService) {\n this.currentUrl = this.router.url;\n router.events.subscribe(event => {\n if (event instanceof NavigationEnd) {\n this.previousUrl = this.currentUrl;\n this.currentUrl = event.url;\n\n let title = i18nService.t('pageTitle', 'Bitwarden');\n let titleId: string = null;\n let rawTitle: string = null;\n let child = this.activatedRoute.firstChild;\n while (child != null) {\n if (child.firstChild != null) {\n child = child.firstChild;\n } else if (child.snapshot.data != null && child.snapshot.data.title != null) {\n rawTitle = child.snapshot.data.title;\n break;\n } else if (child.snapshot.data != null && child.snapshot.data.titleId != null) {\n titleId = child.snapshot.data.titleId;\n break;\n } else {\n titleId = null;\n rawTitle = null;\n break;\n }\n }\n\n if (titleId != null || rawTitle != null) {\n const newTitle = rawTitle != null ? rawTitle : i18nService.t(titleId);\n if (newTitle != null && newTitle !== '') {\n title = (newTitle + ' | ' + title);\n }\n }\n this.titleService.setTitle(title);\n }\n });\n }\n\n getPreviousUrl() {\n return this.previousUrl;\n }\n\n setPreviousUrl(url: string) {\n this.previousUrl = url;\n }\n}\n","export enum KdfType {\n PBKDF2_SHA256 = 0,\n}\n","import { BasePolicy } from '../organizations/policies/base-policy.component';\n\nexport class PolicyListService {\n private policies: BasePolicy[] = [];\n\n addPolicies(policies: BasePolicy[]) {\n this.policies.push(...policies);\n }\n\n getPolicies(): BasePolicy[] {\n return this.policies;\n }\n}\n","import {\n Directive,\n EventEmitter,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\nimport { VerificationType } from 'jslib-common/enums/verificationType';\n\nimport { SecretVerificationRequest } from 'jslib-common/models/request/secretVerificationRequest';\nimport { TwoFactorProviderRequest } from 'jslib-common/models/request/twoFactorProviderRequest';\n\n@Directive()\nexport abstract class TwoFactorBaseComponent {\n @Output() onUpdated = new EventEmitter();\n\n type: TwoFactorProviderType;\n organizationId: string;\n twoFactorProviderType = TwoFactorProviderType;\n enabled = false;\n authed = false;\n\n protected hashedSecret: string;\n protected verificationType: VerificationType;\n\n constructor(protected apiService: ApiService, protected i18nService: I18nService,\n protected toasterService: ToasterService, protected platformUtilsService: PlatformUtilsService,\n protected logService: LogService, protected userVerificationService: UserVerificationService) { }\n\n protected auth(authResponse: any) {\n this.hashedSecret = authResponse.secret;\n this.verificationType = authResponse.verificationType;\n this.authed = true;\n }\n\n protected async enable(enableFunction: () => Promise) {\n try {\n await enableFunction();\n this.onUpdated.emit(true);\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n protected async disable(promise: Promise) {\n const confirmed = await this.platformUtilsService.showDialog(this.i18nService.t('twoStepDisableDesc'),\n this.i18nService.t('disable'), this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return;\n }\n\n try {\n const request = await this.buildRequestModel(TwoFactorProviderRequest);\n request.type = this.type;\n if (this.organizationId != null) {\n promise = this.apiService.putTwoFactorOrganizationDisable(this.organizationId, request);\n } else {\n promise = this.apiService.putTwoFactorDisable(request);\n }\n await promise;\n this.enabled = false;\n this.toasterService.popAsync('success', null, this.i18nService.t('twoStepDisabled'));\n this.onUpdated.emit(false);\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n protected async buildRequestModel(requestClass: new() => T) {\n return this.userVerificationService.buildRequest({\n secret: this.hashedSecret,\n type: this.verificationType,\n }, requestClass, true);\n }\n}\n","import {\n Directive,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\n\nimport { AddEditComponent as OrgAddEditComponent } from '../organizations/vault/add-edit.component';\nimport { AddEditComponent } from '../vault/add-edit.component';\n\nimport { CipherRepromptType } from 'jslib-common/enums/cipherRepromptType';\n\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\n@Directive()\nexport class CipherReportComponent {\n @ViewChild('cipherAddEdit', { read: ViewContainerRef, static: true }) cipherAddEditModalRef: ViewContainerRef;\n\n loading = false;\n hasLoaded = false;\n ciphers: CipherView[] = [];\n organization: Organization;\n\n constructor(private modalService: ModalService, protected userService: UserService,\n protected messagingService: MessagingService, protected passwordRepromptService: PasswordRepromptService,\n public requiresPaid: boolean) { }\n\n async load() {\n this.loading = true;\n await this.setCiphers();\n this.loading = false;\n this.hasLoaded = true;\n }\n\n async selectCipher(cipher: CipherView) {\n if (!await this.repromptCipher(cipher)) {\n return;\n }\n\n const type = this.organization != null ? OrgAddEditComponent : AddEditComponent;\n\n const [modal, childComponent] = await this.modalService.openViewRef(type, this.cipherAddEditModalRef, (comp: OrgAddEditComponent | AddEditComponent) => {\n if (this.organization != null) {\n (comp as OrgAddEditComponent).organization = this.organization;\n comp.organizationId = this.organization.id;\n }\n\n comp.cipherId = cipher == null ? null : cipher.id;\n comp.onSavedCipher.subscribe(async (c: CipherView) => {\n modal.close();\n await this.load();\n });\n comp.onDeletedCipher.subscribe(async (c: CipherView) => {\n modal.close();\n await this.load();\n });\n comp.onRestoredCipher.subscribe(async (c: CipherView) => {\n modal.close();\n await this.load();\n });\n\n });\n\n return childComponent;\n }\n\n protected async checkAccess(): Promise {\n if (this.organization != null) {\n // TODO: Maybe we want to just make sure they are not on a free plan? Just compare useTotp for now\n // since all paid plans include useTotp\n if (this.requiresPaid && !this.organization.useTotp) {\n this.messagingService.send('upgradeOrganization', { organizationId: this.organization.id });\n return false;\n }\n } else {\n const accessPremium = await this.userService.canAccessPremium();\n if (this.requiresPaid && !accessPremium) {\n this.messagingService.send('premiumRequired');\n this.loading = false;\n return false;\n }\n }\n return true;\n }\n\n protected async setCiphers() {\n this.ciphers = [];\n }\n\n protected async repromptCipher(c: CipherView) {\n return c.reprompt === CipherRepromptType.None || await this.passwordRepromptService.showPasswordPrompt();\n }\n}\n","import { FieldType } from '../../enums/fieldType';\nimport { LinkedIdType } from '../../enums/linkedIdType';\n\nimport { View } from './view';\n\nimport { Field } from '../domain/field';\n\nexport class FieldView implements View {\n name: string = null;\n value: string = null;\n type: FieldType = null;\n newField: boolean = false; // Marks if the field is new and hasn't been saved\n showValue: boolean = false;\n linkedId: LinkedIdType = null;\n\n constructor(f?: Field) {\n if (!f) {\n return;\n }\n\n this.type = f.type;\n this.linkedId = f.linkedId;\n }\n\n get maskedValue(): string {\n return this.value != null ? '••••••••' : null;\n }\n}\n","import { Component } from '@angular/core';\n\nimport { CipherType } from 'jslib-common/enums/cipherType';\nimport { EventType } from 'jslib-common/enums/eventType';\n\nimport { AuditService } from 'jslib-common/abstractions/audit.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { EventService } from 'jslib-common/abstractions/event.service';\nimport { FolderService } from 'jslib-common/abstractions/folder.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { TotpService } from 'jslib-common/abstractions/totp.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { AddEditComponent as BaseAddEditComponent } from 'jslib-angular/components/add-edit.component';\nimport { LoginUriView } from 'jslib-common/models/view/loginUriView';\n\n@Component({\n selector: 'app-vault-add-edit',\n templateUrl: 'add-edit.component.html',\n})\nexport class AddEditComponent extends BaseAddEditComponent {\n canAccessPremium: boolean;\n totpCode: string;\n totpCodeFormatted: string;\n totpDash: number;\n totpSec: number;\n totpLow: boolean;\n showRevisionDate = false;\n hasPasswordHistory = false;\n viewingPasswordHistory = false;\n viewOnly = false;\n\n protected totpInterval: number;\n\n constructor(cipherService: CipherService, folderService: FolderService,\n i18nService: I18nService, platformUtilsService: PlatformUtilsService,\n auditService: AuditService, stateService: StateService,\n userService: UserService, collectionService: CollectionService,\n protected totpService: TotpService, protected passwordGenerationService: PasswordGenerationService,\n protected messagingService: MessagingService, eventService: EventService,\n protected policyService: PolicyService, passwordRepromptService: PasswordRepromptService,\n logService: LogService) {\n super(cipherService, folderService, i18nService, platformUtilsService, auditService, stateService,\n userService, collectionService, messagingService, eventService, policyService, passwordRepromptService,\n logService);\n }\n\n async ngOnInit() {\n await super.ngOnInit();\n await this.load();\n this.showRevisionDate = this.cipher.passwordRevisionDisplayDate != null;\n this.hasPasswordHistory = this.cipher.hasPasswordHistory;\n this.cleanUp();\n\n this.canAccessPremium = await this.userService.canAccessPremium();\n if (this.cipher.type === CipherType.Login && this.cipher.login.totp &&\n (this.cipher.organizationUseTotp || this.canAccessPremium)) {\n await this.totpUpdateCode();\n const interval = this.totpService.getTimeInterval(this.cipher.login.totp);\n await this.totpTick(interval);\n\n this.totpInterval = window.setInterval(async () => {\n await this.totpTick(interval);\n }, 1000);\n }\n }\n\n toggleFavorite() {\n this.cipher.favorite = !this.cipher.favorite;\n }\n\n launch(uri: LoginUriView) {\n if (!uri.canLaunch) {\n return;\n }\n\n this.platformUtilsService.launchUri(uri.launchUri);\n }\n\n copy(value: string, typeI18nKey: string, aType: string) {\n if (value == null) {\n return;\n }\n\n this.platformUtilsService.copyToClipboard(value, { window: window });\n this.platformUtilsService.showToast('info', null,\n this.i18nService.t('valueCopied', this.i18nService.t(typeI18nKey)));\n\n if (this.editMode) {\n if (typeI18nKey === 'password') {\n this.eventService.collect(EventType.Cipher_ClientToggledHiddenFieldVisible, this.cipherId);\n } else if (typeI18nKey === 'securityCode') {\n this.eventService.collect(EventType.Cipher_ClientCopiedCardCode, this.cipherId);\n } else if (aType === 'H_Field') {\n this.eventService.collect(EventType.Cipher_ClientCopiedHiddenField, this.cipherId);\n }\n }\n }\n\n async generatePassword(): Promise {\n const confirmed = await super.generatePassword();\n if (confirmed) {\n const options = (await this.passwordGenerationService.getOptions())[0];\n this.cipher.login.password = await this.passwordGenerationService.generatePassword(options);\n }\n return confirmed;\n }\n\n premiumRequired() {\n if (!this.canAccessPremium) {\n this.messagingService.send('premiumRequired');\n return;\n }\n }\n\n upgradeOrganization() {\n this.messagingService.send('upgradeOrganization', { organizationId: this.cipher.organizationId });\n }\n\n viewHistory() {\n this.viewingPasswordHistory = !this.viewingPasswordHistory;\n }\n\n protected cleanUp() {\n if (this.totpInterval) {\n window.clearInterval(this.totpInterval);\n }\n }\n\n protected async totpUpdateCode() {\n if (this.cipher == null || this.cipher.type !== CipherType.Login || this.cipher.login.totp == null) {\n if (this.totpInterval) {\n window.clearInterval(this.totpInterval);\n }\n return;\n }\n\n this.totpCode = await this.totpService.getCode(this.cipher.login.totp);\n if (this.totpCode != null) {\n if (this.totpCode.length > 4) {\n const half = Math.floor(this.totpCode.length / 2);\n this.totpCodeFormatted = this.totpCode.substring(0, half) + ' ' + this.totpCode.substring(half);\n } else {\n this.totpCodeFormatted = this.totpCode;\n }\n } else {\n this.totpCodeFormatted = null;\n if (this.totpInterval) {\n window.clearInterval(this.totpInterval);\n }\n }\n }\n\n protected allowOwnershipAssignment() {\n return (!this.editMode || this.cloneMode) && this.ownershipOptions != null\n && (this.ownershipOptions.length > 1 || !this.allowPersonal);\n }\n\n private async totpTick(intervalSeconds: number) {\n const epoch = Math.round(new Date().getTime() / 1000.0);\n const mod = epoch % intervalSeconds;\n\n this.totpSec = intervalSeconds - mod;\n this.totpDash = +(Math.round((((78.6 / intervalSeconds) * mod) + 'e+2') as any) + 'e-2');\n this.totpLow = this.totpSec <= 7;\n if (mod === 0) {\n await this.totpUpdateCode();\n }\n }\n}\n","

{{title}}

{{'personalOwnershipPolicyInEffect' | i18n}}
{{totpSec}} {{totpCodeFormatted}}
{{'newUri' | i18n}}

{{'ownership' | i18n}}

{{'collections' | i18n}}

{{'noCollectionsInList' | i18n}}
{{'dateUpdated' | i18n}}: {{cipher.revisionDate | date:'medium'}}
{{'datePasswordUpdated' | i18n}}: {{cipher.passwordRevisionDisplayDate | date:'medium'}}
{{'passwordHistory' | i18n}}: {{cipher.passwordHistory.length}}
{{ph.lastUsedDate | date:'short'}} - {{ph.password}}

{{'options' | i18n}}

","import { Importer } from '../importers/importer';\n\nexport interface ImportOption {\n id: string;\n name: string;\n}\nexport abstract class ImportService {\n featuredImportOptions: ImportOption[];\n regularImportOptions: ImportOption[];\n getImportOptions: () => ImportOption[];\n import: (importer: Importer, fileContents: string, organizationId?: string) => Promise;\n getImporter: (format: string, organizationId: string) => Importer;\n}\n","import {\n Component,\n EventEmitter,\n Input,\n OnDestroy,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { EventService } from 'jslib-common/abstractions/event.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { SearchService } from 'jslib-common/abstractions/search.service';\nimport { TotpService } from 'jslib-common/abstractions/totp.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { CiphersComponent as BaseCiphersComponent } from 'jslib-angular/components/ciphers.component';\n\nimport { CipherRepromptType } from 'jslib-common/enums/cipherRepromptType';\nimport { CipherType } from 'jslib-common/enums/cipherType';\nimport { EventType } from 'jslib-common/enums/eventType';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\nconst MaxCheckedCount = 500;\n\n@Component({\n selector: 'app-vault-ciphers',\n templateUrl: 'ciphers.component.html',\n})\nexport class CiphersComponent extends BaseCiphersComponent implements OnDestroy {\n @Input() showAddNew = true;\n @Output() onAttachmentsClicked = new EventEmitter();\n @Output() onShareClicked = new EventEmitter();\n @Output() onCollectionsClicked = new EventEmitter();\n @Output() onCloneClicked = new EventEmitter();\n\n pagedCiphers: CipherView[] = [];\n pageSize = 200;\n cipherType = CipherType;\n actionPromise: Promise;\n userHasPremiumAccess = false;\n\n private didScroll = false;\n private pagedCiphersCount = 0;\n private refreshing = false;\n\n constructor(searchService: SearchService, protected toasterService: ToasterService,\n protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService,\n protected cipherService: CipherService, protected eventService: EventService,\n protected totpService: TotpService, protected userService: UserService,\n protected passwordRepromptService: PasswordRepromptService, private logService: LogService) {\n super(searchService);\n }\n\n async ngOnInit() {\n this.userHasPremiumAccess = await this.userService.canAccessPremium();\n }\n\n ngOnDestroy() {\n this.selectAll(false);\n }\n\n loadMore() {\n if (this.ciphers.length <= this.pageSize) {\n return;\n }\n const pagedLength = this.pagedCiphers.length;\n let pagedSize = this.pageSize;\n if (this.refreshing && pagedLength === 0 && this.pagedCiphersCount > this.pageSize) {\n pagedSize = this.pagedCiphersCount;\n }\n if (this.ciphers.length > pagedLength) {\n this.pagedCiphers = this.pagedCiphers.concat(this.ciphers.slice(pagedLength, pagedLength + pagedSize));\n }\n this.pagedCiphersCount = this.pagedCiphers.length;\n this.didScroll = this.pagedCiphers.length > this.pageSize;\n }\n\n async refresh() {\n try {\n this.refreshing = true;\n await this.reload(this.filter, this.deleted);\n } finally {\n this.refreshing = false;\n }\n }\n\n isPaging() {\n const searching = this.isSearching();\n if (searching && this.didScroll) {\n this.resetPaging();\n }\n return !searching && this.ciphers.length > this.pageSize;\n }\n\n async resetPaging() {\n this.pagedCiphers = [];\n this.loadMore();\n }\n\n async doSearch(indexedCiphers?: CipherView[]) {\n this.ciphers = await this.searchService.searchCiphers(this.searchText, [this.filter, this.deletedFilter], indexedCiphers);\n this.resetPaging();\n }\n\n launch(uri: string) {\n this.platformUtilsService.launchUri(uri);\n }\n\n async attachments(c: CipherView) {\n if (!await this.repromptCipher(c)) {\n return;\n }\n this.onAttachmentsClicked.emit(c);\n }\n\n async share(c: CipherView) {\n if (!await this.repromptCipher(c)) {\n return;\n }\n this.onShareClicked.emit(c);\n }\n\n collections(c: CipherView) {\n this.onCollectionsClicked.emit(c);\n }\n\n async clone(c: CipherView) {\n if (!await this.repromptCipher(c)) {\n return;\n }\n this.onCloneClicked.emit(c);\n }\n\n async delete(c: CipherView): Promise {\n if (!await this.repromptCipher(c)) {\n return;\n }\n if (this.actionPromise != null) {\n return;\n }\n const permanent = c.isDeleted;\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t(permanent ? 'permanentlyDeleteItemConfirmation' : 'deleteItemConfirmation'),\n this.i18nService.t(permanent ? 'permanentlyDeleteItem' : 'deleteItem'),\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.actionPromise = this.deleteCipher(c.id, permanent);\n await this.actionPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t(permanent ? 'permanentlyDeletedItem'\n : 'deletedItem'));\n this.refresh();\n } catch (e) {\n this.logService.error(e);\n }\n this.actionPromise = null;\n }\n\n async restore(c: CipherView): Promise {\n if (this.actionPromise != null || !c.isDeleted) {\n return;\n }\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('restoreItemConfirmation'),\n this.i18nService.t('restoreItem'),\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.actionPromise = this.cipherService.restoreWithServer(c.id);\n await this.actionPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('restoredItem'));\n this.refresh();\n } catch (e) {\n this.logService.error(e);\n }\n this.actionPromise = null;\n }\n\n async copy(cipher: CipherView, value: string, typeI18nKey: string, aType: string) {\n if (this.passwordRepromptService.protectedFields().includes(aType) && !await this.repromptCipher(cipher)) {\n return;\n }\n\n if (value == null || aType === 'TOTP' && !this.displayTotpCopyButton(cipher)) {\n return;\n } else if (value === cipher.login.totp) {\n value = await this.totpService.getCode(value);\n }\n\n if (!cipher.viewPassword) {\n return;\n }\n\n this.platformUtilsService.copyToClipboard(value, { window: window });\n this.toasterService.popAsync('info', null,\n this.i18nService.t('valueCopied', this.i18nService.t(typeI18nKey)));\n\n if (typeI18nKey === 'password' || typeI18nKey === 'verificationCodeTotp') {\n this.eventService.collect(EventType.Cipher_ClientToggledHiddenFieldVisible, cipher.id);\n } else if (typeI18nKey === 'securityCode') {\n this.eventService.collect(EventType.Cipher_ClientCopiedCardCode, cipher.id);\n }\n }\n\n selectAll(select: boolean) {\n if (select) {\n this.selectAll(false);\n }\n const selectCount = select && this.ciphers.length > MaxCheckedCount\n ? MaxCheckedCount\n : this.ciphers.length;\n for (let i = 0; i < selectCount; i++) {\n this.checkCipher(this.ciphers[i], select);\n }\n }\n\n checkCipher(c: CipherView, select?: boolean) {\n (c as any).checked = select == null ? !(c as any).checked : select;\n }\n\n getSelected(): CipherView[] {\n if (this.ciphers == null) {\n return [];\n }\n return this.ciphers.filter(c => !!(c as any).checked);\n }\n\n getSelectedIds(): string[] {\n return this.getSelected().map(c => c.id);\n }\n\n displayTotpCopyButton(cipher: CipherView) {\n return (cipher?.login?.hasTotp ?? false) &&\n (cipher.organizationUseTotp || this.userHasPremiumAccess);\n }\n\n async selectCipher(cipher: CipherView) {\n if (await this.repromptCipher(cipher)) {\n super.selectCipher(cipher);\n }\n }\n\n protected deleteCipher(id: string, permanent: boolean) {\n return permanent ? this.cipherService.deleteWithServer(id) : this.cipherService.softDeleteWithServer(id);\n }\n\n protected showFixOldAttachments(c: CipherView) {\n return c.hasOldAttachments && c.organizationId == null;\n }\n\n protected async repromptCipher(c: CipherView) {\n return c.reprompt === CipherRepromptType.None || await this.passwordRepromptService.showPasswordPrompt();\n }\n}\n","
{{c.name}} {{'shared' | i18n}} {{'attachments' | i18n}} {{'attachmentsNeedFix' | i18n}}
{{c.subTitle}}
{{'loading' | i18n}}

{{'noItemsInList' | i18n}}

","import { OrganizationData } from '../data/organizationData';\n\nimport { OrganizationUserStatusType } from '../../enums/organizationUserStatusType';\nimport { OrganizationUserType } from '../../enums/organizationUserType';\nimport { ProductType } from '../../enums/productType';\nimport { PermissionsApi } from '../api/permissionsApi';\n\n\nexport class Organization {\n id: string;\n name: string;\n status: OrganizationUserStatusType;\n type: OrganizationUserType;\n enabled: boolean;\n usePolicies: boolean;\n useGroups: boolean;\n useDirectory: boolean;\n useEvents: boolean;\n useTotp: boolean;\n use2fa: boolean;\n useApi: boolean;\n useSso: boolean;\n useKeyConnector: boolean;\n useResetPassword: boolean;\n selfHost: boolean;\n usersGetPremium: boolean;\n seats: number;\n maxCollections: number;\n maxStorageGb?: number;\n ssoBound: boolean;\n identifier: string;\n permissions: PermissionsApi;\n resetPasswordEnrolled: boolean;\n userId: string;\n hasPublicAndPrivateKeys: boolean;\n providerId: string;\n providerName: string;\n isProviderUser: boolean;\n familySponsorshipFriendlyName: string;\n familySponsorshipAvailable: boolean;\n planProductType: ProductType;\n keyConnectorEnabled: boolean;\n keyConnectorUrl: string;\n\n constructor(obj?: OrganizationData) {\n if (obj == null) {\n return;\n }\n\n this.id = obj.id;\n this.name = obj.name;\n this.status = obj.status;\n this.type = obj.type;\n this.enabled = obj.enabled;\n this.usePolicies = obj.usePolicies;\n this.useGroups = obj.useGroups;\n this.useDirectory = obj.useDirectory;\n this.useEvents = obj.useEvents;\n this.useTotp = obj.useTotp;\n this.use2fa = obj.use2fa;\n this.useApi = obj.useApi;\n this.useSso = obj.useSso;\n this.useKeyConnector = obj.useKeyConnector;\n this.useResetPassword = obj.useResetPassword;\n this.selfHost = obj.selfHost;\n this.usersGetPremium = obj.usersGetPremium;\n this.seats = obj.seats;\n this.maxCollections = obj.maxCollections;\n this.maxStorageGb = obj.maxStorageGb;\n this.ssoBound = obj.ssoBound;\n this.identifier = obj.identifier;\n this.permissions = obj.permissions;\n this.resetPasswordEnrolled = obj.resetPasswordEnrolled;\n this.userId = obj.userId;\n this.hasPublicAndPrivateKeys = obj.hasPublicAndPrivateKeys;\n this.providerId = obj.providerId;\n this.providerName = obj.providerName;\n this.isProviderUser = obj.isProviderUser;\n this.familySponsorshipFriendlyName = obj.familySponsorshipFriendlyName;\n this.familySponsorshipAvailable = obj.familySponsorshipAvailable;\n this.planProductType = obj.planProductType;\n this.keyConnectorEnabled = obj.keyConnectorEnabled;\n this.keyConnectorUrl = obj.keyConnectorUrl;\n }\n\n get canAccess() {\n if (this.type === OrganizationUserType.Owner) {\n return true;\n }\n return this.enabled && this.status === OrganizationUserStatusType.Confirmed;\n }\n\n get isManager() {\n return this.type === OrganizationUserType.Manager || this.type === OrganizationUserType.Owner ||\n this.type === OrganizationUserType.Admin;\n }\n\n get isAdmin() {\n return this.type === OrganizationUserType.Owner || this.type === OrganizationUserType.Admin;\n }\n\n get isOwner() {\n return this.type === OrganizationUserType.Owner || this.isProviderUser;\n }\n\n get canAccessEventLogs() {\n return this.isAdmin || this.permissions.accessEventLogs;\n }\n\n get canAccessImportExport() {\n return this.isAdmin || this.permissions.accessImportExport;\n }\n\n get canAccessReports() {\n return this.isAdmin || this.permissions.accessReports;\n }\n\n get canCreateNewCollections() {\n return this.isManager || (this.permissions.createNewCollections ?? this.permissions.manageAllCollections);\n }\n\n get canEditAnyCollection() {\n return this.isAdmin || (this.permissions.editAnyCollection ?? this.permissions.manageAllCollections);\n }\n\n get canDeleteAnyCollection() {\n return this.isAdmin || (this.permissions.deleteAnyCollection ?? this.permissions.manageAllCollections);\n }\n\n get canViewAllCollections() {\n return this.canCreateNewCollections || this.canEditAnyCollection || this.canDeleteAnyCollection;\n }\n\n get canEditAssignedCollections() {\n return this.isManager || (this.permissions.editAssignedCollections ?? this.permissions.manageAssignedCollections);\n }\n\n get canDeleteAssignedCollections() {\n return this.isManager || (this.permissions.deleteAssignedCollections ?? this.permissions.manageAssignedCollections);\n }\n\n get canViewAssignedCollections() {\n return this.canDeleteAssignedCollections || this.canEditAssignedCollections;\n }\n\n get canManageGroups() {\n return this.isAdmin || this.permissions.manageGroups;\n }\n\n get canManageSso() {\n return this.isAdmin || this.permissions.manageSso;\n }\n\n get canManagePolicies() {\n return this.isAdmin || this.permissions.managePolicies;\n }\n\n get canManageUsers() {\n return this.isAdmin || this.permissions.manageUsers;\n }\n\n get canManageUsersPassword() {\n return this.isAdmin || this.permissions.manageResetPassword;\n }\n\n get isExemptFromPolicies() {\n return this.canManagePolicies;\n }\n}\n","import { Injectable } from '@angular/core';\nimport {\n ActivatedRouteSnapshot,\n CanActivate,\n Router,\n RouterStateSnapshot,\n} from '@angular/router';\n\nimport { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\nimport { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';\n\n@Injectable()\nexport class AuthGuardService implements CanActivate {\n constructor(private vaultTimeoutService: VaultTimeoutService, private userService: UserService,\n private router: Router, private messagingService: MessagingService, private keyConnectorService: KeyConnectorService) { }\n\n async canActivate(route: ActivatedRouteSnapshot, routerState: RouterStateSnapshot) {\n const isAuthed = await this.userService.isAuthenticated();\n if (!isAuthed) {\n this.messagingService.send('authBlocked');\n return false;\n }\n\n const locked = await this.vaultTimeoutService.isLocked();\n if (locked) {\n if (routerState != null) {\n this.messagingService.send('lockedUrl', { url: routerState.url });\n }\n this.router.navigate(['lock'], { queryParams: { promptBiometric: true }});\n return false;\n }\n\n if (!routerState.url.includes('remove-password') && await this.keyConnectorService.getConvertAccountRequired()) {\n this.router.navigate(['/remove-password']);\n return false;\n }\n\n return true;\n }\n}\n","export enum ProviderUserType {\n ProviderAdmin = 0,\n ServiceUser = 1,\n}\n","export enum ThemeType {\n System = 'system',\n Light = 'light',\n Dark = 'dark',\n Nord = 'nord',\n SolarizedDark = 'solarizedDark',\n}\n","export enum ProductType {\n Free = 0,\n Families = 1,\n Teams = 2,\n Enterprise = 3,\n}\n","export class KeysRequest {\n publicKey: string;\n encryptedPrivateKey: string;\n\n constructor(publicKey: string, encryptedPrivateKey: string) {\n this.publicKey = publicKey;\n this.encryptedPrivateKey = encryptedPrivateKey;\n }\n}\n","import {\n Directive,\n OnInit,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport {\n Toast,\n ToasterService,\n} from 'angular2-toaster';\n\nimport { first } from 'rxjs/operators';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\n@Directive()\nexport abstract class BaseAcceptComponent implements OnInit {\n loading = true;\n authed = false;\n email: string;\n actionPromise: Promise;\n\n protected requiredParameters: string[] = [];\n protected failedShortMessage = 'inviteAcceptFailedShort';\n protected failedMessage = 'inviteAcceptFailed';\n\n constructor(protected router: Router, protected toasterService: ToasterService,\n protected i18nService: I18nService, protected route: ActivatedRoute,\n protected userService: UserService, protected stateService: StateService) { }\n\n abstract authedHandler(qParams: any): Promise;\n abstract unauthedHandler(qParams: any): Promise;\n\n ngOnInit() {\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n await this.stateService.remove('loginRedirect');\n\n let error = this.requiredParameters.some(e => qParams?.[e] == null || qParams[e] === '');\n let errorMessage: string = null;\n if (!error) {\n this.authed = await this.userService.isAuthenticated();\n\n if (this.authed) {\n try {\n await this.authedHandler(qParams);\n } catch (e) {\n error = true;\n errorMessage = e.message;\n }\n } else {\n await this.stateService.save('loginRedirect', {\n route: this.getRedirectRoute(),\n qParams: qParams,\n });\n\n this.email = qParams.email;\n await this.unauthedHandler(qParams);\n }\n }\n\n if (error) {\n const toast: Toast = {\n type: 'error',\n title: null,\n body: errorMessage != null ? this.i18nService.t(this.failedShortMessage, errorMessage) :\n this.i18nService.t(this.failedMessage),\n timeout: 10000,\n };\n this.toasterService.popAsync(toast);\n this.router.navigate(['/']);\n }\n\n this.loading = false;\n });\n }\n\n getRedirectRoute() {\n const urlTree = this.router.parseUrl(this.router.url);\n urlTree.queryParams = {};\n return urlTree.toString();\n }\n}\n","import {\n Component,\n Input,\n OnInit,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\nimport { EventService } from '../../services/event.service';\n\nimport { UserNamePipe } from 'jslib-angular/pipes/user-name.pipe';\n\nimport { EventResponse } from 'jslib-common/models/response/eventResponse';\nimport { ListResponse } from 'jslib-common/models/response/listResponse';\n\n@Component({\n selector: 'app-entity-events',\n templateUrl: 'entity-events.component.html',\n})\nexport class EntityEventsComponent implements OnInit {\n @Input() name: string;\n @Input() entity: 'user' | 'cipher';\n @Input() entityId: string;\n @Input() organizationId: string;\n @Input() providerId: string;\n @Input() showUser = false;\n\n loading = true;\n loaded = false;\n events: any[];\n start: string;\n end: string;\n continuationToken: string;\n refreshPromise: Promise;\n morePromise: Promise;\n\n private orgUsersUserIdMap = new Map();\n private orgUsersIdMap = new Map();\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private eventService: EventService, private toasterService: ToasterService,\n private userNamePipe: UserNamePipe, private logService: LogService) { }\n\n async ngOnInit() {\n const defaultDates = this.eventService.getDefaultDateFilters();\n this.start = defaultDates[0];\n this.end = defaultDates[1];\n await this.load();\n }\n\n async load() {\n if (this.showUser) {\n const response = await this.apiService.getOrganizationUsers(this.organizationId);\n response.data.forEach(u => {\n const name = this.userNamePipe.transform(u);\n this.orgUsersIdMap.set(u.id, { name: name, email: u.email });\n this.orgUsersUserIdMap.set(u.userId, { name: name, email: u.email });\n });\n }\n await this.loadEvents(true);\n this.loaded = true;\n }\n\n async loadEvents(clearExisting: boolean) {\n if (this.refreshPromise != null || this.morePromise != null) {\n return;\n }\n\n let dates: string[] = null;\n try {\n dates = this.eventService.formatDateFilters(this.start, this.end);\n } catch (e) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('invalidDateRange'));\n return;\n }\n\n this.loading = true;\n let response: ListResponse;\n try {\n let promise: Promise;\n if (this.entity === 'user' && this.providerId) {\n promise = this.apiService.getEventsProviderUser(this.providerId, this.entityId,\n dates[0], dates[1], clearExisting ? null : this.continuationToken);\n } else if (this.entity === 'user') {\n promise = this.apiService.getEventsOrganizationUser(this.organizationId, this.entityId,\n dates[0], dates[1], clearExisting ? null : this.continuationToken);\n } else {\n promise = this.apiService.getEventsCipher(this.entityId,\n dates[0], dates[1], clearExisting ? null : this.continuationToken);\n }\n if (clearExisting) {\n this.refreshPromise = promise;\n } else {\n this.morePromise = promise;\n }\n response = await promise;\n } catch (e) {\n this.logService.error(e);\n }\n\n this.continuationToken = response.continuationToken;\n const events = await Promise.all(response.data.map(async r => {\n const userId = r.actingUserId == null ? r.userId : r.actingUserId;\n const eventInfo = await this.eventService.getEventInfo(r);\n const user = this.showUser && userId != null && this.orgUsersUserIdMap.has(userId) ?\n this.orgUsersUserIdMap.get(userId) : null;\n return {\n message: eventInfo.message,\n appIcon: eventInfo.appIcon,\n appName: eventInfo.appName,\n userId: userId,\n userName: user != null ? user.name : this.showUser ? this.i18nService.t('unknown') : null,\n userEmail: user != null ? user.email : this.showUser ? '' : null,\n date: r.date,\n ip: r.ipAddress,\n type: r.type,\n };\n }));\n\n if (!clearExisting && this.events != null && this.events.length > 0) {\n this.events = this.events.concat(events);\n } else {\n this.events = events;\n }\n\n this.loading = false;\n this.morePromise = null;\n this.refreshPromise = null;\n }\n}\n","

{{'eventLogs' | i18n}} {{name}}

{{'loading' | i18n}}
-

{{'noEventsInList' | i18n}}
{{'timestamp' | i18n}} {{'device' | i18n}} {{'user' | i18n}} {{'event' | i18n}}
{{e.date | date:'medium'}} {{e.appName}}, {{e.ip}} {{e.userName}}
","export class OrganizationUserResetPasswordEnrollmentRequest {\n resetPasswordKey: string;\n}\n","export enum HashPurpose {\n ServerAuthorization = 1,\n LocalAuthorization = 2,\n}\n","import { PolicyResponse } from '../response/policyResponse';\n\nimport { PolicyType } from '../../enums/policyType';\n\nexport class PolicyData {\n id: string;\n organizationId: string;\n type: PolicyType;\n data: any;\n enabled: boolean;\n\n constructor(response: PolicyResponse) {\n this.id = response.id;\n this.organizationId = response.organizationId;\n this.type = response.type;\n this.data = response.data;\n this.enabled = response.enabled;\n }\n}\n","import { Directive, OnInit } from '@angular/core';\n\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { EncString } from 'jslib-common/models/domain/encString';\nimport { MasterPasswordPolicyOptions } from 'jslib-common/models/domain/masterPasswordPolicyOptions';\nimport { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';\n\nimport { KdfType } from 'jslib-common/enums/kdfType';\n\n@Directive()\nexport class ChangePasswordComponent implements OnInit {\n masterPassword: string;\n masterPasswordRetype: string;\n formPromise: Promise;\n masterPasswordScore: number;\n enforcedPolicyOptions: MasterPasswordPolicyOptions;\n\n protected email: string;\n protected kdf: KdfType;\n protected kdfIterations: number;\n\n private masterPasswordStrengthTimeout: any;\n\n constructor(protected i18nService: I18nService, protected cryptoService: CryptoService,\n protected messagingService: MessagingService, protected userService: UserService,\n protected passwordGenerationService: PasswordGenerationService,\n protected platformUtilsService: PlatformUtilsService, protected policyService: PolicyService) { }\n\n async ngOnInit() {\n this.email = await this.userService.getEmail();\n this.enforcedPolicyOptions ??= await this.policyService.getMasterPasswordPolicyOptions();\n }\n\n async submit() {\n if (!await this.strongPassword()) {\n return;\n }\n\n if (!await this.setupSubmitActions()) {\n return;\n }\n\n const email = await this.userService.getEmail();\n if (this.kdf == null) {\n this.kdf = await this.userService.getKdf();\n }\n if (this.kdfIterations == null) {\n this.kdfIterations = await this.userService.getKdfIterations();\n }\n const key = await this.cryptoService.makeKey(this.masterPassword, email.trim().toLowerCase(),\n this.kdf, this.kdfIterations);\n const masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, key);\n\n let encKey: [SymmetricCryptoKey, EncString] = null;\n const existingEncKey = await this.cryptoService.getEncKey();\n if (existingEncKey == null) {\n encKey = await this.cryptoService.makeEncKey(key);\n } else {\n encKey = await this.cryptoService.remakeEncKey(key);\n }\n\n await this.performSubmitActions(masterPasswordHash, key, encKey);\n }\n\n async setupSubmitActions(): Promise {\n // Override in sub-class\n // Can be used for additional validation and/or other processes the should occur before changing passwords\n return true;\n }\n\n async performSubmitActions(masterPasswordHash: string, key: SymmetricCryptoKey,\n encKey: [SymmetricCryptoKey, EncString]) {\n // Override in sub-class\n }\n\n async strongPassword(): Promise {\n if (this.masterPassword == null || this.masterPassword === '') {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPassRequired'));\n return false;\n }\n if (this.masterPassword.length < 8) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPassLength'));\n return false;\n }\n if (this.masterPassword !== this.masterPasswordRetype) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPassDoesntMatch'));\n return false;\n }\n\n const strengthResult = this.passwordGenerationService.passwordStrength(this.masterPassword,\n this.getPasswordStrengthUserInput());\n\n if (this.enforcedPolicyOptions != null &&\n !this.policyService.evaluateMasterPassword(\n strengthResult.score,\n this.masterPassword,\n this.enforcedPolicyOptions)) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPasswordPolicyRequirementsNotMet'));\n return false;\n }\n\n if (strengthResult != null && strengthResult.score < 3) {\n const result = await this.platformUtilsService.showDialog(this.i18nService.t('weakMasterPasswordDesc'),\n this.i18nService.t('weakMasterPassword'), this.i18nService.t('yes'), this.i18nService.t('no'),\n 'warning');\n if (!result) {\n return false;\n }\n }\n\n return true;\n }\n\n updatePasswordStrength() {\n if (this.masterPasswordStrengthTimeout != null) {\n clearTimeout(this.masterPasswordStrengthTimeout);\n }\n this.masterPasswordStrengthTimeout = setTimeout(() => {\n const strengthResult = this.passwordGenerationService.passwordStrength(this.masterPassword,\n this.getPasswordStrengthUserInput());\n this.masterPasswordScore = strengthResult == null ? null : strengthResult.score;\n }, 300);\n }\n\n async logOut() {\n const confirmed = await this.platformUtilsService.showDialog(this.i18nService.t('logOutConfirmation'),\n this.i18nService.t('logOut'), this.i18nService.t('logOut'), this.i18nService.t('cancel'));\n if (confirmed) {\n this.messagingService.send('logout');\n }\n }\n\n private getPasswordStrengthUserInput() {\n let userInput: string[] = [];\n const atPosition = this.email.indexOf('@');\n if (atPosition > -1) {\n userInput = userInput.concat(this.email.substr(0, atPosition).trim().toLowerCase().split(/[^A-Za-z0-9]/));\n }\n return userInput;\n }\n}\n","export class SelectionReadOnlyRequest {\n id: string;\n readOnly: boolean;\n hidePasswords: boolean;\n\n constructor(id: string, readOnly: boolean, hidePasswords: boolean) {\n this.id = id;\n this.readOnly = readOnly;\n this.hidePasswords = hidePasswords;\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nimport { PolicyType } from '../../enums/policyType';\n\nexport class PolicyResponse extends BaseResponse {\n id: string;\n organizationId: string;\n type: PolicyType;\n data: any;\n enabled: boolean;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.organizationId = this.getResponseProperty('OrganizationId');\n this.type = this.getResponseProperty('Type');\n this.data = this.getResponseProperty('Data');\n this.enabled = this.getResponseProperty('Enabled');\n }\n}\n","import { View } from './view';\n\nimport { LinkedMetadata } from '../../misc/linkedFieldOption.decorator';\n\nexport abstract class ItemView implements View {\n linkedFieldOptions: Map;\n abstract get subTitle(): string;\n}\n","import { UriMatchType } from '../../enums/uriMatchType';\n\nimport { View } from './view';\n\nimport { LoginUri } from '../domain/loginUri';\n\nimport { Utils } from '../../misc/utils';\n\nconst CanLaunchWhitelist = [\n 'https://',\n 'http://',\n 'ssh://',\n 'ftp://',\n 'sftp://',\n 'irc://',\n 'vnc://',\n // https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-uri\n 'rdp://', // Legacy RDP URI scheme\n 'ms-rd:', // Preferred RDP URI scheme\n 'chrome://',\n 'iosapp://',\n 'androidapp://',\n];\n\nexport class LoginUriView implements View {\n match: UriMatchType = null;\n\n // tslint:disable\n private _uri: string = null;\n private _domain: string = null;\n private _hostname: string = null;\n private _host: string = null;\n private _canLaunch: boolean = null;\n // tslint:enable\n\n constructor(u?: LoginUri) {\n if (!u) {\n return;\n }\n\n this.match = u.match;\n }\n\n get uri(): string {\n return this._uri;\n }\n set uri(value: string) {\n this._uri = value;\n this._domain = null;\n this._canLaunch = null;\n }\n\n get domain(): string {\n if (this._domain == null && this.uri != null) {\n this._domain = Utils.getDomain(this.uri);\n if (this._domain === '') {\n this._domain = null;\n }\n }\n\n return this._domain;\n }\n\n get hostname(): string {\n if (this.match === UriMatchType.RegularExpression) {\n return null;\n }\n if (this._hostname == null && this.uri != null) {\n this._hostname = Utils.getHostname(this.uri);\n if (this._hostname === '') {\n this._hostname = null;\n }\n }\n\n return this._hostname;\n }\n\n get host(): string {\n if (this.match === UriMatchType.RegularExpression) {\n return null;\n }\n if (this._host == null && this.uri != null) {\n this._host = Utils.getHost(this.uri);\n if (this._host === '') {\n this._host = null;\n }\n }\n\n return this._host;\n }\n\n get hostnameOrUri(): string {\n return this.hostname != null ? this.hostname : this.uri;\n }\n\n get hostOrUri(): string {\n return this.host != null ? this.host : this.uri;\n }\n\n get isWebsite(): boolean {\n return this.uri != null && (this.uri.indexOf('http://') === 0 || this.uri.indexOf('https://') === 0 ||\n (this.uri.indexOf('://') < 0 && Utils.tldEndingRegex.test(this.uri)));\n }\n\n get canLaunch(): boolean {\n if (this._canLaunch != null) {\n return this._canLaunch;\n }\n if (this.uri != null && this.match !== UriMatchType.RegularExpression) {\n const uri = this.launchUri;\n for (let i = 0; i < CanLaunchWhitelist.length; i++) {\n if (uri.indexOf(CanLaunchWhitelist[i]) === 0) {\n this._canLaunch = true;\n return this._canLaunch;\n }\n }\n }\n this._canLaunch = false;\n return this._canLaunch;\n }\n\n get launchUri(): string {\n return this.uri.indexOf('://') < 0 && Utils.tldEndingRegex.test(this.uri) ? ('http://' + this.uri) : this.uri;\n }\n}\n","export enum UriMatchType {\n Domain = 0,\n Host = 1,\n StartsWith = 2,\n Exact = 3,\n RegularExpression = 4,\n Never = 5,\n}\n","import {\n Component,\n Input,\n} from '@angular/core';\n\nimport {\n AddEditCustomFieldsComponent as BaseAddEditCustomFieldsComponent\n} from 'jslib-angular/components/add-edit-custom-fields.component';\n\nimport { EventService } from 'jslib-common/abstractions/event.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\n@Component({\n selector: 'app-vault-add-edit-custom-fields',\n templateUrl: 'add-edit-custom-fields.component.html',\n})\nexport class AddEditCustomFieldsComponent extends BaseAddEditCustomFieldsComponent {\n @Input() viewOnly: boolean;\n @Input() copy: (value: string, typeI18nKey: string, aType: string) => void;\n\n constructor(i18nService: I18nService, eventService: EventService) {\n super(i18nService, eventService);\n }\n}\n","

{{'customFields' | i18n}}

{{'newCustomField' | i18n}}
","import {\n Component,\n EventEmitter,\n Output,\n} from '@angular/core';\n\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { FolderService } from 'jslib-common/abstractions/folder.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { GroupingsComponent as BaseGroupingsComponent } from 'jslib-angular/components/groupings.component';\n\n@Component({\n selector: 'app-vault-groupings',\n templateUrl: 'groupings.component.html',\n})\nexport class GroupingsComponent extends BaseGroupingsComponent {\n @Output() onSearchTextChanged = new EventEmitter();\n\n searchText: string = '';\n searchPlaceholder: string = null;\n\n constructor(collectionService: CollectionService, folderService: FolderService,\n storageService: StorageService, userService: UserService) {\n super(collectionService, folderService, storageService, userService);\n }\n\n searchTextChanged() {\n this.onSearchTextChanged.emit(this.searchText);\n }\n}\n"," ","import { View } from './view';\n\nimport { SendFile } from '../domain/sendFile';\n\nexport class SendFileView implements View {\n id: string = null;\n size: string = null;\n sizeName: string = null;\n fileName: string = null;\n\n constructor(f?: SendFile) {\n if (!f) {\n return;\n }\n\n this.id = f.id;\n this.size = f.size;\n this.sizeName = f.sizeName;\n }\n\n get fileSize(): number {\n try {\n if (this.size != null) {\n return parseInt(this.size, null);\n }\n } catch {\n // Invalid file size.\n }\n return 0;\n }\n}\n","import { View } from './view';\n\nimport { SendText } from '../domain/sendText';\n\nexport class SendTextView implements View {\n text: string = null;\n hidden: boolean;\n\n constructor(t?: SendText) {\n if (!t) {\n return;\n }\n\n this.hidden = t.hidden;\n }\n\n get maskedText(): string {\n return this.text != null ? '••••••••' : null;\n }\n}\n","import { AttachmentResponse } from './attachmentResponse';\nimport { BaseResponse } from './baseResponse';\nimport { PasswordHistoryResponse } from './passwordHistoryResponse';\n\nimport { CipherRepromptType } from '../../enums/cipherRepromptType';\nimport { CardApi } from '../api/cardApi';\nimport { FieldApi } from '../api/fieldApi';\nimport { IdentityApi } from '../api/identityApi';\nimport { LoginApi } from '../api/loginApi';\nimport { SecureNoteApi } from '../api/secureNoteApi';\n\nexport class CipherResponse extends BaseResponse {\n id: string;\n organizationId: string;\n folderId: string;\n type: number;\n name: string;\n notes: string;\n fields: FieldApi[];\n login: LoginApi;\n card: CardApi;\n identity: IdentityApi;\n secureNote: SecureNoteApi;\n favorite: boolean;\n edit: boolean;\n viewPassword: boolean;\n organizationUseTotp: boolean;\n revisionDate: string;\n attachments: AttachmentResponse[];\n passwordHistory: PasswordHistoryResponse[];\n collectionIds: string[];\n deletedDate: string;\n reprompt: CipherRepromptType;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.organizationId = this.getResponseProperty('OrganizationId');\n this.folderId = this.getResponseProperty('FolderId') || null;\n this.type = this.getResponseProperty('Type');\n this.name = this.getResponseProperty('Name');\n this.notes = this.getResponseProperty('Notes');\n this.favorite = this.getResponseProperty('Favorite') || false;\n this.edit = !!this.getResponseProperty('Edit');\n if (this.getResponseProperty('ViewPassword') == null) {\n this.viewPassword = true;\n } else {\n this.viewPassword = this.getResponseProperty('ViewPassword');\n }\n this.organizationUseTotp = this.getResponseProperty('OrganizationUseTotp');\n this.revisionDate = this.getResponseProperty('RevisionDate');\n this.collectionIds = this.getResponseProperty('CollectionIds');\n this.deletedDate = this.getResponseProperty('DeletedDate');\n\n const login = this.getResponseProperty('Login');\n if (login != null) {\n this.login = new LoginApi(login);\n }\n\n const card = this.getResponseProperty('Card');\n if (card != null) {\n this.card = new CardApi(card);\n }\n\n const identity = this.getResponseProperty('Identity');\n if (identity != null) {\n this.identity = new IdentityApi(identity);\n }\n\n const secureNote = this.getResponseProperty('SecureNote');\n if (secureNote != null) {\n this.secureNote = new SecureNoteApi(secureNote);\n }\n\n const fields = this.getResponseProperty('Fields');\n if (fields != null) {\n this.fields = fields.map((f: any) => new FieldApi(f));\n }\n\n const attachments = this.getResponseProperty('Attachments');\n if (attachments != null) {\n this.attachments = attachments.map((a: any) => new AttachmentResponse(a));\n }\n\n const passwordHistory = this.getResponseProperty('PasswordHistory');\n if (passwordHistory != null) {\n this.passwordHistory = passwordHistory.map((h: any) => new PasswordHistoryResponse(h));\n }\n\n this.reprompt = this.getResponseProperty('Reprompt') || CipherRepromptType.None;\n }\n}\n","import {\n Component,\n Input,\n OnInit,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport { Policy } from 'jslib-common/models/domain/policy';\n\nimport { OrganizationUserResetPasswordEnrollmentRequest } from 'jslib-common/models/request/organizationUserResetPasswordEnrollmentRequest';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\n@Component({\n selector: 'app-organizations',\n templateUrl: 'organizations.component.html',\n})\nexport class OrganizationsComponent implements OnInit {\n @Input() vault = false;\n\n organizations: Organization[];\n policies: Policy[];\n loaded: boolean = false;\n actionPromise: Promise;\n\n constructor(private userService: UserService, private platformUtilsService: PlatformUtilsService,\n private i18nService: I18nService, private apiService: ApiService,\n private toasterService: ToasterService, private syncService: SyncService,\n private cryptoService: CryptoService, private policyService: PolicyService,\n private logService: LogService) { }\n\n async ngOnInit() {\n if (!this.vault) {\n await this.syncService.fullSync(true);\n await this.load();\n }\n }\n\n async load() {\n const orgs = await this.userService.getAllOrganizations();\n orgs.sort(Utils.getSortFunction(this.i18nService, 'name'));\n this.organizations = orgs;\n this.policies = await this.policyService.getAll(PolicyType.ResetPassword);\n this.loaded = true;\n }\n\n allowEnrollmentChanges(org: Organization): boolean {\n if (org.usePolicies && org.useResetPassword && org.hasPublicAndPrivateKeys) {\n const policy = this.policies.find(p => p.organizationId === org.id);\n if (policy != null && policy.enabled) {\n return org.resetPasswordEnrolled && policy.data.autoEnrollEnabled ? false : true;\n }\n }\n\n return false;\n }\n\n showEnrolledStatus(org: Organization): boolean {\n return org.useResetPassword && org.resetPasswordEnrolled && this.policies.some(p => p.organizationId === org.id && p.enabled);\n }\n\n async unlinkSso(org: Organization) {\n const confirmed = await this.platformUtilsService.showDialog(\n 'Are you sure you want to unlink SSO for this organization?', org.name,\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.actionPromise = this.apiService.deleteSsoUser(org.id).then(() => {\n return this.syncService.fullSync(true);\n });\n await this.actionPromise;\n this.toasterService.popAsync('success', null, 'Unlinked SSO');\n await this.load();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async leave(org: Organization) {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('leaveOrganizationConfirmation'), org.name,\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.actionPromise = this.apiService.postLeaveOrganization(org.id).then(() => {\n return this.syncService.fullSync(true);\n });\n await this.actionPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('leftOrganization'));\n await this.load();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async toggleResetPasswordEnrollment(org: Organization) {\n // Set variables\n let keyString: string = null;\n let toastStringRef = 'withdrawPasswordResetSuccess';\n\n // Enrolling\n if (!org.resetPasswordEnrolled) {\n // Alert user about enrollment\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('resetPasswordEnrollmentWarning'), null,\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return;\n }\n\n // Retrieve Public Key\n this.actionPromise = this.apiService.getOrganizationKeys(org.id)\n .then(async response => {\n if (response == null) {\n throw new Error(this.i18nService.t('resetPasswordOrgKeysError'));\n }\n\n const publicKey = Utils.fromB64ToArray(response.publicKey);\n\n // RSA Encrypt user's encKey.key with organization public key\n const encKey = await this.cryptoService.getEncKey();\n const encryptedKey = await this.cryptoService.rsaEncrypt(encKey.key, publicKey.buffer);\n keyString = encryptedKey.encryptedString;\n toastStringRef = 'enrollPasswordResetSuccess';\n\n // Create request and execute enrollment\n const request = new OrganizationUserResetPasswordEnrollmentRequest();\n request.resetPasswordKey = keyString;\n return this.apiService.putOrganizationUserResetPasswordEnrollment(org.id, org.userId, request);\n })\n .then(() => {\n return this.syncService.fullSync(true);\n });\n } else {\n // Withdrawal\n const request = new OrganizationUserResetPasswordEnrollmentRequest();\n request.resetPasswordKey = keyString;\n this.actionPromise = this.apiService.putOrganizationUserResetPasswordEnrollment(org.id, org.userId, request)\n .then(() => {\n return this.syncService.fullSync(true);\n });\n }\n\n try {\n await this.actionPromise;\n this.platformUtilsService.showToast('success', null, this.i18nService.t(toastStringRef));\n await this.load();\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{'loading' | i18n}}

{{'noOrganizationsList' | i18n}}

{{'newOrganization' | i18n}}

{{'organizations' | i18n}} {{'loading' | i18n}}

{{'newOrganization' | i18n}}
{{'loading' | i18n}}

{{'noOrganizationsList' | i18n}}

{{'newOrganization' | i18n}}
{{o.name}} {{'organizationIsDisabled' | i18n}} {{'enrolledPasswordReset' | i18n}}
","import { BaseResponse } from './baseResponse';\n\nexport class SelectionReadOnlyResponse extends BaseResponse {\n id: string;\n readOnly: boolean;\n hidePasswords: boolean;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.readOnly = this.getResponseProperty('ReadOnly');\n this.hidePasswords = this.getResponseProperty('HidePasswords');\n }\n}\n","export enum EncryptionType {\n AesCbc256_B64 = 0,\n AesCbc128_HmacSha256_B64 = 1,\n AesCbc256_HmacSha256_B64 = 2,\n Rsa2048_OaepSha256_B64 = 3,\n Rsa2048_OaepSha1_B64 = 4,\n Rsa2048_OaepSha256_HmacSha256_B64 = 5,\n Rsa2048_OaepSha1_HmacSha256_B64 = 6,\n}\n","import { KeysRequest } from './keysRequest';\n\nexport class OrganizationKeysRequest extends KeysRequest {\n constructor(publicKey: string, encryptedPrivateKey: string) {\n super(publicKey, encryptedPrivateKey);\n }\n}\n","export enum DeviceType {\n Android = 0,\n iOS = 1,\n ChromeExtension = 2,\n FirefoxExtension = 3,\n OperaExtension = 4,\n EdgeExtension = 5,\n WindowsDesktop = 6,\n MacOsDesktop = 7,\n LinuxDesktop = 8,\n ChromeBrowser = 9,\n FirefoxBrowser = 10,\n OperaBrowser = 11,\n EdgeBrowser = 12,\n IEBrowser = 13,\n UnknownBrowser = 14,\n AndroidAmazon = 15,\n UWP = 16,\n SafariBrowser = 17,\n VivaldiBrowser = 18,\n VivaldiExtension = 19,\n SafariExtension = 20,\n}\n","export enum ProviderUserStatusType {\n Invited = 0,\n Accepted = 1,\n Confirmed = 2,\n}\n","export class ProviderUserBulkRequest {\n ids: string[];\n\n constructor(ids: string[]) {\n this.ids = ids == null ? [] : ids;\n }\n}\n","import { Component } from '@angular/core';\nimport { OrganizationUserStatusType } from 'jslib-common/enums/organizationUserStatusType';\nimport { ProviderUserStatusType } from 'jslib-common/enums/providerUserStatusType';\n\nexport interface BulkUserDetails {\n id: string;\n name: string;\n email: string;\n status: OrganizationUserStatusType | ProviderUserStatusType;\n}\n\ntype BulkStatusEntry = {\n user: BulkUserDetails,\n error: boolean,\n message: string,\n};\n\n@Component({\n selector: 'app-bulk-status',\n templateUrl: 'bulk-status.component.html',\n})\nexport class BulkStatusComponent {\n\n users: BulkStatusEntry[];\n loading: boolean = false;\n\n}\n","

{{'bulkConfirmStatus' | i18n}}

{{'loading' | i18n}}
{{'user' | i18n}} {{'status' | i18n}}
{{item.user.email}} {{item.user.name}} {{item.message}} {{item.message}}
","import {\n Component,\n Input,\n OnInit,\n} from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\nimport { OrganizationUserBulkConfirmRequest } from 'jslib-common/models/request/organizationUserBulkConfirmRequest';\nimport { OrganizationUserBulkRequest } from 'jslib-common/models/request/organizationUserBulkRequest';\n\nimport { OrganizationUserStatusType } from 'jslib-common/enums/organizationUserStatusType';\n\nimport { Utils } from 'jslib-common/misc/utils';\nimport { BulkUserDetails } from './bulk-status.component';\n\n@Component({\n selector: 'app-bulk-confirm',\n templateUrl: 'bulk-confirm.component.html',\n})\nexport class BulkConfirmComponent implements OnInit {\n\n @Input() organizationId: string;\n @Input() users: BulkUserDetails[];\n\n excludedUsers: BulkUserDetails[];\n filteredUsers: BulkUserDetails[];\n publicKeys: Map = new Map();\n fingerprints: Map = new Map();\n statuses: Map = new Map();\n\n loading: boolean = true;\n done: boolean = false;\n error: string;\n\n constructor(protected cryptoService: CryptoService, protected apiService: ApiService,\n private i18nService: I18nService) { }\n\n async ngOnInit() {\n this.excludedUsers = this.users.filter(u => !this.isAccepted(u));\n this.filteredUsers = this.users.filter(u => this.isAccepted(u));\n\n if (this.filteredUsers.length <= 0) {\n this.done = true;\n }\n\n const response = await this.getPublicKeys();\n\n for (const entry of response.data) {\n const publicKey = Utils.fromB64ToArray(entry.key);\n const fingerprint = await this.cryptoService.getFingerprint(entry.userId, publicKey.buffer);\n if (fingerprint != null) {\n this.publicKeys.set(entry.id, publicKey);\n this.fingerprints.set(entry.id, fingerprint.join('-'));\n }\n }\n\n this.loading = false;\n }\n\n async submit() {\n this.loading = true;\n try {\n const key = await this.getCryptoKey();\n const userIdsWithKeys: any[] = [];\n for (const user of this.filteredUsers) {\n const publicKey = this.publicKeys.get(user.id);\n if (publicKey == null) {\n continue;\n }\n const encryptedKey = await this.cryptoService.rsaEncrypt(key.key, publicKey.buffer);\n userIdsWithKeys.push({\n id: user.id,\n key: encryptedKey.encryptedString,\n });\n }\n const response = await this.postConfirmRequest(userIdsWithKeys);\n\n response.data.forEach(entry => {\n const error = entry.error !== '' ? entry.error : this.i18nService.t('bulkConfirmMessage');\n this.statuses.set(entry.id, error);\n });\n\n this.done = true;\n } catch (e) {\n this.error = e.message;\n }\n this.loading = false;\n }\n\n protected isAccepted(user: BulkUserDetails) {\n return user.status === OrganizationUserStatusType.Accepted;\n }\n\n protected async getPublicKeys() {\n const request = new OrganizationUserBulkRequest(this.filteredUsers.map(user => user.id));\n return await this.apiService.postOrganizationUsersPublicKey(this.organizationId, request);\n }\n\n protected getCryptoKey() {\n return this.cryptoService.getOrgKey(this.organizationId);\n }\n\n protected async postConfirmRequest(userIdsWithKeys: any[]) {\n const request = new OrganizationUserBulkConfirmRequest(userIdsWithKeys);\n return await this.apiService.postOrganizationUserBulkConfirm(this.organizationId, request);\n }\n}\n","

{{'confirmUsers' | i18n}}

{{'loading' | i18n}}
{{'noSelectedUsersApplicable' | i18n}} {{error}}

{{'fingerprintEnsureIntegrityVerify' | i18n}} {{'learnMore' | i18n}}

{{'user' | i18n}} {{'fingerprint' | i18n}}
{{user.email}} {{user.name}} {{fingerprints.get(user.id)}}
{{user.email}} {{user.name}} {{'bulkFilteredMessage' | i18n}}
{{'user' | i18n}} {{'status' | i18n}}
{{user.email}} {{user.name}} {{statuses.get(user.id)}} {{'bulkFilteredMessage' | i18n}}
","export class OrganizationUserBulkRequest {\n ids: string[];\n\n constructor(ids: string[]) {\n this.ids = ids == null ? [] : ids;\n }\n}\n","import {\n Component,\n Input,\n} from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { OrganizationUserBulkRequest } from 'jslib-common/models/request/organizationUserBulkRequest';\n\nimport { BulkUserDetails } from './bulk-status.component';\n\n@Component({\n selector: 'app-bulk-remove',\n templateUrl: 'bulk-remove.component.html',\n})\nexport class BulkRemoveComponent {\n\n @Input() organizationId: string;\n @Input() users: BulkUserDetails[];\n\n statuses: Map = new Map();\n\n loading: boolean = false;\n done: boolean = false;\n error: string;\n\n constructor(protected apiService: ApiService, protected i18nService: I18nService) { }\n\n async submit() {\n this.loading = true;\n try {\n const response = await this.deleteUsers();\n\n response.data.forEach(entry => {\n const error = entry.error !== '' ? entry.error : this.i18nService.t('bulkRemovedMessage');\n this.statuses.set(entry.id, error);\n });\n this.done = true;\n } catch (e) {\n this.error = e.message;\n }\n\n this.loading = false;\n }\n\n protected async deleteUsers() {\n const request = new OrganizationUserBulkRequest(this.users.map(user => user.id));\n return await this.apiService.deleteManyOrganizationUsers(this.organizationId, request);\n }\n}\n","

{{'removeUsers' | i18n}}

{{'noSelectedUsersApplicable' | i18n}} {{error}} 0 && !error\"> {{'removeUsersWarning' | i18n}}
{{'user' | i18n}}
{{user.email}} {{user.name}}
{{'user' | i18n}} {{'status' | i18n}}
{{user.email}} {{user.name}} {{statuses.get(user.id)}} {{'bulkFilteredMessage' | i18n}}
","import {\n Component,\n OnDestroy,\n OnInit,\n} from '@angular/core';\n\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\n@Component({\n selector: 'app-frontend-layout',\n templateUrl: 'frontend-layout.component.html',\n})\nexport class FrontendLayoutComponent implements OnInit, OnDestroy {\n version: string;\n year: string = '2015';\n\n constructor(private platformUtilsService: PlatformUtilsService) { }\n\n async ngOnInit() {\n this.year = new Date().getFullYear().toString();\n this.version = await this.platformUtilsService.getApplicationVersion();\n document.body.classList.add('layout_frontend');\n }\n\n ngOnDestroy() {\n document.body.classList.remove('layout_frontend');\n }\n}\n","
© {{year}}, Bitwarden Inc.
{{'versionNumber' | i18n : version}}
","import {\n Component,\n Input,\n OnInit,\n} from '@angular/core';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Provider } from 'jslib-common/models/domain/provider';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\n@Component({\n selector: 'app-providers',\n templateUrl: 'providers.component.html',\n})\nexport class ProvidersComponent implements OnInit {\n @Input() vault = false;\n\n providers: Provider[];\n loaded: boolean = false;\n actionPromise: Promise;\n\n constructor(private userService: UserService, private i18nService: I18nService) { }\n\n async ngOnInit() {\n document.body.classList.remove('layout_frontend');\n await this.load();\n }\n\n async load() {\n const providers = await this.userService.getAllProviders();\n providers.sort(Utils.getSortFunction(this.i18nService, 'name'));\n this.providers = providers;\n this.loaded = true;\n }\n}\n","

{{'loading' | i18n}}

{{'providers' | i18n}}

{{'loading' | i18n}}

{{p.name}} {{'providerIsDisabled' | i18n}}
","import { DragDropModule } from '@angular/cdk/drag-drop';\nimport {\n DatePipe,\n registerLocaleData,\n} from '@angular/common';\nimport { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { RouterModule } from '@angular/router';\n\nimport { ToasterModule } from 'angular2-toaster';\nimport { InfiniteScrollModule } from 'ngx-infinite-scroll';\n\nimport { NestedCheckboxComponent } from './components/nested-checkbox.component';\nimport { PasswordRepromptComponent } from './components/password-reprompt.component';\nimport { PasswordStrengthComponent } from './components/password-strength.component';\n\nimport { FooterComponent } from './layouts/footer.component';\nimport { FrontendLayoutComponent } from './layouts/frontend-layout.component';\nimport { NavbarComponent } from './layouts/navbar.component';\nimport { OrganizationLayoutComponent } from './layouts/organization-layout.component';\nimport { UserLayoutComponent } from './layouts/user-layout.component';\n\nimport { AcceptEmergencyComponent } from './accounts/accept-emergency.component';\nimport { AcceptOrganizationComponent } from './accounts/accept-organization.component';\nimport { HintComponent } from './accounts/hint.component';\nimport { LockComponent } from './accounts/lock.component';\nimport { LoginComponent } from './accounts/login.component';\nimport { RecoverDeleteComponent } from './accounts/recover-delete.component';\nimport { RecoverTwoFactorComponent } from './accounts/recover-two-factor.component';\nimport { RegisterComponent } from './accounts/register.component';\nimport { RemovePasswordComponent } from './accounts/remove-password.component';\nimport { SetPasswordComponent } from './accounts/set-password.component';\nimport { SsoComponent } from './accounts/sso.component';\nimport { TwoFactorOptionsComponent } from './accounts/two-factor-options.component';\nimport { TwoFactorComponent } from './accounts/two-factor.component';\nimport { UpdateTempPasswordComponent } from './accounts/update-temp-password.component';\nimport { VerifyEmailTokenComponent } from './accounts/verify-email-token.component';\nimport { VerifyRecoverDeleteComponent } from './accounts/verify-recover-delete.component';\n\nimport { BulkConfirmComponent as OrgBulkConfirmComponent } from './organizations/manage/bulk/bulk-confirm.component';\nimport { BulkRemoveComponent as OrgBulkRemoveComponent } from './organizations/manage/bulk/bulk-remove.component';\nimport { BulkStatusComponent as OrgBulkStatusComponent } from './organizations/manage/bulk/bulk-status.component';\nimport {\n CollectionAddEditComponent as OrgCollectionAddEditComponent,\n} from './organizations/manage/collection-add-edit.component';\nimport { CollectionsComponent as OrgManageCollectionsComponent } from './organizations/manage/collections.component';\nimport { EntityEventsComponent as OrgEntityEventsComponent } from './organizations/manage/entity-events.component';\nimport { EntityUsersComponent as OrgEntityUsersComponent } from './organizations/manage/entity-users.component';\nimport { EventsComponent as OrgEventsComponent } from './organizations/manage/events.component';\nimport { GroupAddEditComponent as OrgGroupAddEditComponent } from './organizations/manage/group-add-edit.component';\nimport { GroupsComponent as OrgGroupsComponent } from './organizations/manage/groups.component';\nimport { ManageComponent as OrgManageComponent } from './organizations/manage/manage.component';\nimport { PeopleComponent as OrgPeopleComponent } from './organizations/manage/people.component';\nimport { PoliciesComponent as OrgPoliciesComponent } from './organizations/manage/policies.component';\nimport { PolicyEditComponent as OrgPolicyEditComponent } from './organizations/manage/policy-edit.component';\nimport { ResetPasswordComponent as OrgResetPasswordComponent } from './organizations/manage/reset-password.component';\nimport { UserAddEditComponent as OrgUserAddEditComponent } from './organizations/manage/user-add-edit.component';\nimport { UserConfirmComponent as OrgUserConfirmComponent } from './organizations/manage/user-confirm.component';\nimport { UserGroupsComponent as OrgUserGroupsComponent } from './organizations/manage/user-groups.component';\n\nimport { AccountComponent as OrgAccountComponent } from './organizations/settings/account.component';\nimport { AdjustSubscription } from './organizations/settings/adjust-subscription.component';\nimport { ChangePlanComponent } from './organizations/settings/change-plan.component';\nimport { DeleteOrganizationComponent } from './organizations/settings/delete-organization.component';\nimport { DownloadLicenseComponent } from './organizations/settings/download-license.component';\nimport { OrganizationBillingComponent } from './organizations/settings/organization-billing.component';\nimport { OrganizationSubscriptionComponent } from './organizations/settings/organization-subscription.component';\nimport { SettingsComponent as OrgSettingComponent } from './organizations/settings/settings.component';\nimport {\n TwoFactorSetupComponent as OrgTwoFactorSetupComponent,\n} from './organizations/settings/two-factor-setup.component';\n\nimport { ExportComponent as OrgExportComponent } from './organizations/tools/export.component';\nimport {\n ExposedPasswordsReportComponent as OrgExposedPasswordsReportComponent,\n} from './organizations/tools/exposed-passwords-report.component';\nimport { ImportComponent as OrgImportComponent } from './organizations/tools/import.component';\nimport {\n InactiveTwoFactorReportComponent as OrgInactiveTwoFactorReportComponent,\n} from './organizations/tools/inactive-two-factor-report.component';\nimport {\n ReusedPasswordsReportComponent as OrgReusedPasswordsReportComponent,\n} from './organizations/tools/reused-passwords-report.component';\nimport { ToolsComponent as OrgToolsComponent } from './organizations/tools/tools.component';\nimport {\n UnsecuredWebsitesReportComponent as OrgUnsecuredWebsitesReportComponent,\n} from './organizations/tools/unsecured-websites-report.component';\nimport {\n WeakPasswordsReportComponent as OrgWeakPasswordsReportComponent,\n} from './organizations/tools/weak-passwords-report.component';\n\nimport { FamiliesForEnterpriseSetupComponent } from './organizations/sponsorships/families-for-enterprise-setup.component';\nimport { AddEditComponent as OrgAddEditComponent } from './organizations/vault/add-edit.component';\nimport { AttachmentsComponent as OrgAttachmentsComponent } from './organizations/vault/attachments.component';\nimport { CiphersComponent as OrgCiphersComponent } from './organizations/vault/ciphers.component';\nimport { CollectionsComponent as OrgCollectionsComponent } from './organizations/vault/collections.component';\nimport { GroupingsComponent as OrgGroupingsComponent } from './organizations/vault/groupings.component';\nimport { VaultComponent as OrgVaultComponent } from './organizations/vault/vault.component';\n\nimport { AccessComponent } from './send/access.component';\nimport { AddEditComponent as SendAddEditComponent } from './send/add-edit.component';\nimport { EffluxDatesComponent as SendEffluxDatesComponent } from './send/efflux-dates.component';\nimport { SendComponent } from './send/send.component';\n\nimport { AccountComponent } from './settings/account.component';\nimport { AddCreditComponent } from './settings/add-credit.component';\nimport { AdjustPaymentComponent } from './settings/adjust-payment.component';\nimport { AdjustStorageComponent } from './settings/adjust-storage.component';\nimport { ApiKeyComponent } from './settings/api-key.component';\nimport { ChangeEmailComponent } from './settings/change-email.component';\nimport { ChangeKdfComponent } from './settings/change-kdf.component';\nimport { ChangePasswordComponent } from './settings/change-password.component';\nimport { CreateOrganizationComponent } from './settings/create-organization.component';\nimport { DeauthorizeSessionsComponent } from './settings/deauthorize-sessions.component';\nimport { DeleteAccountComponent } from './settings/delete-account.component';\nimport { DomainRulesComponent } from './settings/domain-rules.component';\nimport { EmergencyAccessAddEditComponent } from './settings/emergency-access-add-edit.component';\nimport { EmergencyAccessAttachmentsComponent } from './settings/emergency-access-attachments.component';\nimport { EmergencyAccessConfirmComponent } from './settings/emergency-access-confirm.component';\nimport { EmergencyAccessTakeoverComponent } from './settings/emergency-access-takeover.component';\nimport { EmergencyAccessViewComponent } from './settings/emergency-access-view.component';\nimport { EmergencyAccessComponent } from './settings/emergency-access.component';\nimport { EmergencyAddEditComponent } from './settings/emergency-add-edit.component';\nimport { LinkSsoComponent } from './settings/link-sso.component';\nimport { OptionsComponent } from './settings/options.component';\nimport { OrganizationPlansComponent } from './settings/organization-plans.component';\nimport { OrganizationsComponent } from './settings/organizations.component';\nimport { PaymentComponent } from './settings/payment.component';\nimport { PremiumComponent } from './settings/premium.component';\nimport { ProfileComponent } from './settings/profile.component';\nimport { PurgeVaultComponent } from './settings/purge-vault.component';\nimport { SettingsComponent } from './settings/settings.component';\nimport { SponsoredFamiliesComponent } from './settings/sponsored-families.component';\nimport { SponsoringOrgRowComponent } from './settings/sponsoring-org-row.component';\nimport { TaxInfoComponent } from './settings/tax-info.component';\nimport { TwoFactorAuthenticatorComponent } from './settings/two-factor-authenticator.component';\nimport { TwoFactorDuoComponent } from './settings/two-factor-duo.component';\nimport { TwoFactorEmailComponent } from './settings/two-factor-email.component';\nimport { TwoFactorRecoveryComponent } from './settings/two-factor-recovery.component';\nimport { TwoFactorSetupComponent } from './settings/two-factor-setup.component';\nimport { TwoFactorVerifyComponent } from './settings/two-factor-verify.component';\nimport { TwoFactorWebAuthnComponent } from './settings/two-factor-webauthn.component';\nimport { TwoFactorYubiKeyComponent } from './settings/two-factor-yubikey.component';\nimport { UpdateKeyComponent } from './settings/update-key.component';\nimport { UpdateLicenseComponent } from './settings/update-license.component';\nimport { UserBillingComponent } from './settings/user-billing.component';\nimport { UserSubscriptionComponent } from './settings/user-subscription.component';\nimport { VaultTimeoutInputComponent } from './settings/vault-timeout-input.component';\nimport { VerifyEmailComponent } from './settings/verify-email.component';\n\nimport { BreachReportComponent } from './tools/breach-report.component';\nimport { ExportComponent } from './tools/export.component';\nimport { ExposedPasswordsReportComponent } from './tools/exposed-passwords-report.component';\nimport { ImportComponent } from './tools/import.component';\nimport { InactiveTwoFactorReportComponent } from './tools/inactive-two-factor-report.component';\nimport { PasswordGeneratorHistoryComponent } from './tools/password-generator-history.component';\nimport { PasswordGeneratorComponent } from './tools/password-generator.component';\nimport { ReusedPasswordsReportComponent } from './tools/reused-passwords-report.component';\nimport { ToolsComponent } from './tools/tools.component';\nimport { UnsecuredWebsitesReportComponent } from './tools/unsecured-websites-report.component';\nimport { WeakPasswordsReportComponent } from './tools/weak-passwords-report.component';\n\nimport { AddEditCustomFieldsComponent } from './vault/add-edit-custom-fields.component';\nimport { AddEditComponent } from './vault/add-edit.component';\nimport { AttachmentsComponent } from './vault/attachments.component';\nimport { BulkActionsComponent } from './vault/bulk-actions.component';\nimport { BulkDeleteComponent } from './vault/bulk-delete.component';\nimport { BulkMoveComponent } from './vault/bulk-move.component';\nimport { BulkRestoreComponent } from './vault/bulk-restore.component';\nimport { BulkShareComponent } from './vault/bulk-share.component';\nimport { CiphersComponent } from './vault/ciphers.component';\nimport { CollectionsComponent } from './vault/collections.component';\nimport { FolderAddEditComponent } from './vault/folder-add-edit.component';\nimport { GroupingsComponent } from './vault/groupings.component';\nimport { ShareComponent } from './vault/share.component';\nimport { VaultComponent } from './vault/vault.component';\n\nimport { ProvidersComponent } from './providers/providers.component';\n\nimport { AvatarComponent } from 'jslib-angular/components/avatar.component';\nimport { CalloutComponent } from 'jslib-angular/components/callout.component';\nimport { IconComponent } from 'jslib-angular/components/icon.component';\nimport { VerifyMasterPasswordComponent } from 'jslib-angular/components/verify-master-password.component';\n\nimport { A11yTitleDirective } from 'jslib-angular/directives/a11y-title.directive';\nimport { ApiActionDirective } from 'jslib-angular/directives/api-action.directive';\nimport { AutofocusDirective } from 'jslib-angular/directives/autofocus.directive';\nimport { BlurClickDirective } from 'jslib-angular/directives/blur-click.directive';\nimport { BoxRowDirective } from 'jslib-angular/directives/box-row.directive';\nimport { FallbackSrcDirective } from 'jslib-angular/directives/fallback-src.directive';\nimport { InputVerbatimDirective } from 'jslib-angular/directives/input-verbatim.directive';\nimport { SelectCopyDirective } from 'jslib-angular/directives/select-copy.directive';\nimport { StopClickDirective } from 'jslib-angular/directives/stop-click.directive';\nimport { StopPropDirective } from 'jslib-angular/directives/stop-prop.directive';\nimport { TrueFalseValueDirective } from 'jslib-angular/directives/true-false-value.directive';\n\nimport { ColorPasswordPipe } from 'jslib-angular/pipes/color-password.pipe';\nimport { I18nPipe } from 'jslib-angular/pipes/i18n.pipe';\nimport { SearchCiphersPipe } from 'jslib-angular/pipes/search-ciphers.pipe';\nimport { SearchPipe } from 'jslib-angular/pipes/search.pipe';\nimport { UserNamePipe } from 'jslib-angular/pipes/user-name.pipe';\n\nimport localeAz from '@angular/common/locales/az';\nimport localeBg from '@angular/common/locales/bg';\nimport localeCa from '@angular/common/locales/ca';\nimport localeCs from '@angular/common/locales/cs';\nimport localeDa from '@angular/common/locales/da';\nimport localeDe from '@angular/common/locales/de';\nimport localeEl from '@angular/common/locales/el';\nimport localeEnGb from '@angular/common/locales/en-GB';\nimport localeEnIn from '@angular/common/locales/en-IN';\nimport localeEo from '@angular/common/locales/eo';\nimport localeEs from '@angular/common/locales/es';\nimport localeEt from '@angular/common/locales/et';\nimport localeFi from '@angular/common/locales/fi';\nimport localeFr from '@angular/common/locales/fr';\nimport localeHe from '@angular/common/locales/he';\nimport localeHr from '@angular/common/locales/hr';\nimport localeHu from '@angular/common/locales/hu';\nimport localeId from '@angular/common/locales/id';\nimport localeIt from '@angular/common/locales/it';\nimport localeJa from '@angular/common/locales/ja';\nimport localeKn from '@angular/common/locales/kn';\nimport localeKo from '@angular/common/locales/ko';\nimport localeLv from '@angular/common/locales/lv';\nimport localeMl from '@angular/common/locales/ml';\nimport localeNb from '@angular/common/locales/nb';\nimport localeNl from '@angular/common/locales/nl';\nimport localePl from '@angular/common/locales/pl';\nimport localePtBr from '@angular/common/locales/pt';\nimport localePtPt from '@angular/common/locales/pt-PT';\nimport localeRo from '@angular/common/locales/ro';\nimport localeRu from '@angular/common/locales/ru';\nimport localeSk from '@angular/common/locales/sk';\nimport localeSr from '@angular/common/locales/sr';\nimport localeSv from '@angular/common/locales/sv';\nimport localeTr from '@angular/common/locales/tr';\nimport localeUk from '@angular/common/locales/uk';\nimport localeZhCn from '@angular/common/locales/zh-Hans';\nimport localeZhTw from '@angular/common/locales/zh-Hant';\n\nimport { DisableSendPolicyComponent } from './organizations/policies/disable-send.component';\nimport { MasterPasswordPolicyComponent } from './organizations/policies/master-password.component';\nimport { PasswordGeneratorPolicyComponent } from './organizations/policies/password-generator.component';\nimport { PersonalOwnershipPolicyComponent } from './organizations/policies/personal-ownership.component';\nimport { RequireSsoPolicyComponent } from './organizations/policies/require-sso.component';\nimport { ResetPasswordPolicyComponent } from './organizations/policies/reset-password.component';\nimport { SendOptionsPolicyComponent } from './organizations/policies/send-options.component';\nimport { SingleOrgPolicyComponent } from './organizations/policies/single-org.component';\nimport { TwoFactorAuthenticationPolicyComponent } from './organizations/policies/two-factor-authentication.component';\n\nregisterLocaleData(localeAz, 'az');\nregisterLocaleData(localeBg, 'bg');\nregisterLocaleData(localeCa, 'ca');\nregisterLocaleData(localeCs, 'cs');\nregisterLocaleData(localeDa, 'da');\nregisterLocaleData(localeDe, 'de');\nregisterLocaleData(localeEl, 'el');\nregisterLocaleData(localeEnGb, 'en-GB');\nregisterLocaleData(localeEnIn, 'en-IN');\nregisterLocaleData(localeEs, 'es');\nregisterLocaleData(localeEt, 'et');\nregisterLocaleData(localeEo, 'eo');\nregisterLocaleData(localeFi, 'fi');\nregisterLocaleData(localeFr, 'fr');\nregisterLocaleData(localeHe, 'he');\nregisterLocaleData(localeHr, 'hr');\nregisterLocaleData(localeHu, 'hu');\nregisterLocaleData(localeId, 'id');\nregisterLocaleData(localeIt, 'it');\nregisterLocaleData(localeJa, 'ja');\nregisterLocaleData(localeKn, 'kn');\nregisterLocaleData(localeKo, 'ko');\nregisterLocaleData(localeLv, 'lv');\nregisterLocaleData(localeMl, 'ml');\nregisterLocaleData(localeNb, 'nb');\nregisterLocaleData(localeNl, 'nl');\nregisterLocaleData(localePl, 'pl');\nregisterLocaleData(localePtBr, 'pt-BR');\nregisterLocaleData(localePtPt, 'pt-PT');\nregisterLocaleData(localeRo, 'ro');\nregisterLocaleData(localeRu, 'ru');\nregisterLocaleData(localeSk, 'sk');\nregisterLocaleData(localeSr, 'sr');\nregisterLocaleData(localeSv, 'sv');\nregisterLocaleData(localeTr, 'tr');\nregisterLocaleData(localeUk, 'uk');\nregisterLocaleData(localeZhCn, 'zh-CN');\nregisterLocaleData(localeZhTw, 'zh-TW');\n\n@NgModule({\n imports: [\n CommonModule,\n FormsModule,\n InfiniteScrollModule,\n DragDropModule,\n ToasterModule.forChild(),\n ReactiveFormsModule,\n RouterModule,\n ],\n declarations: [\n A11yTitleDirective,\n AcceptEmergencyComponent,\n AccessComponent,\n AcceptOrganizationComponent,\n AccountComponent,\n SetPasswordComponent,\n AddCreditComponent,\n AddEditComponent,\n AddEditCustomFieldsComponent,\n AdjustPaymentComponent,\n AdjustSubscription,\n AdjustStorageComponent,\n ApiActionDirective,\n ApiKeyComponent,\n AttachmentsComponent,\n AutofocusDirective,\n AvatarComponent,\n BlurClickDirective,\n BoxRowDirective,\n BreachReportComponent,\n BulkActionsComponent,\n BulkDeleteComponent,\n BulkMoveComponent,\n BulkRestoreComponent,\n BulkShareComponent,\n CalloutComponent,\n ChangeEmailComponent,\n ChangeKdfComponent,\n ChangePasswordComponent,\n ChangePlanComponent,\n CiphersComponent,\n CollectionsComponent,\n ColorPasswordPipe,\n CreateOrganizationComponent,\n DeauthorizeSessionsComponent,\n DeleteAccountComponent,\n DeleteOrganizationComponent,\n DomainRulesComponent,\n DownloadLicenseComponent,\n EmergencyAccessAddEditComponent,\n EmergencyAccessAttachmentsComponent,\n EmergencyAccessComponent,\n EmergencyAccessConfirmComponent,\n EmergencyAccessTakeoverComponent,\n EmergencyAccessViewComponent,\n EmergencyAddEditComponent,\n ExportComponent,\n ExposedPasswordsReportComponent,\n FallbackSrcDirective,\n FamiliesForEnterpriseSetupComponent,\n FolderAddEditComponent,\n FooterComponent,\n FrontendLayoutComponent,\n GroupingsComponent,\n HintComponent,\n I18nPipe,\n IconComponent,\n ImportComponent,\n InactiveTwoFactorReportComponent,\n InputVerbatimDirective,\n LinkSsoComponent,\n LockComponent,\n LoginComponent,\n NavbarComponent,\n NestedCheckboxComponent,\n OptionsComponent,\n OrgAccountComponent,\n OrgAddEditComponent,\n OrganizationBillingComponent,\n OrganizationPlansComponent,\n OrganizationSubscriptionComponent,\n OrgAttachmentsComponent,\n OrgBulkStatusComponent,\n OrgBulkConfirmComponent,\n OrgBulkRemoveComponent,\n OrgCiphersComponent,\n OrgCollectionAddEditComponent,\n OrgCollectionsComponent,\n OrgEntityEventsComponent,\n OrgEntityUsersComponent,\n OrgEventsComponent,\n OrgExportComponent,\n OrgExposedPasswordsReportComponent,\n OrgImportComponent,\n OrgInactiveTwoFactorReportComponent,\n OrgGroupAddEditComponent,\n OrgGroupingsComponent,\n OrgGroupsComponent,\n OrgManageCollectionsComponent,\n OrgManageComponent,\n OrgPeopleComponent,\n OrgPolicyEditComponent,\n OrgPoliciesComponent,\n OrgResetPasswordComponent,\n OrgReusedPasswordsReportComponent,\n OrgSettingComponent,\n OrgToolsComponent,\n OrgTwoFactorSetupComponent,\n OrgUserAddEditComponent,\n OrgUserConfirmComponent,\n OrgUserGroupsComponent,\n OrganizationsComponent,\n OrganizationLayoutComponent,\n OrgUnsecuredWebsitesReportComponent,\n OrgVaultComponent,\n OrgWeakPasswordsReportComponent,\n PasswordGeneratorComponent,\n PasswordGeneratorHistoryComponent,\n PasswordStrengthComponent,\n PasswordRepromptComponent,\n PaymentComponent,\n PremiumComponent,\n ProfileComponent,\n PurgeVaultComponent,\n RecoverDeleteComponent,\n RecoverTwoFactorComponent,\n RegisterComponent,\n ReusedPasswordsReportComponent,\n SearchCiphersPipe,\n SearchPipe,\n SelectCopyDirective,\n SendAddEditComponent,\n SendEffluxDatesComponent,\n SendComponent,\n SettingsComponent,\n ShareComponent,\n SponsoredFamiliesComponent,\n SponsoringOrgRowComponent,\n SsoComponent,\n StopClickDirective,\n StopPropDirective,\n TaxInfoComponent,\n ToolsComponent,\n TrueFalseValueDirective,\n TwoFactorAuthenticatorComponent,\n TwoFactorComponent,\n TwoFactorDuoComponent,\n TwoFactorEmailComponent,\n TwoFactorOptionsComponent,\n TwoFactorRecoveryComponent,\n TwoFactorSetupComponent,\n TwoFactorVerifyComponent,\n TwoFactorWebAuthnComponent,\n TwoFactorYubiKeyComponent,\n UnsecuredWebsitesReportComponent,\n UpdateKeyComponent,\n UpdateLicenseComponent,\n UpdateTempPasswordComponent,\n UserBillingComponent,\n UserLayoutComponent,\n UserSubscriptionComponent,\n UserNamePipe,\n VaultComponent,\n VerifyEmailComponent,\n VerifyEmailTokenComponent,\n VerifyRecoverDeleteComponent,\n WeakPasswordsReportComponent,\n ProvidersComponent,\n TwoFactorAuthenticationPolicyComponent,\n MasterPasswordPolicyComponent,\n SingleOrgPolicyComponent,\n PasswordGeneratorPolicyComponent,\n RequireSsoPolicyComponent,\n PersonalOwnershipPolicyComponent,\n DisableSendPolicyComponent,\n SendOptionsPolicyComponent,\n ResetPasswordPolicyComponent,\n VaultTimeoutInputComponent,\n AddEditCustomFieldsComponent,\n VerifyMasterPasswordComponent,\n RemovePasswordComponent,\n ],\n exports: [\n A11yTitleDirective,\n AvatarComponent,\n CalloutComponent,\n ApiActionDirective,\n StopClickDirective,\n StopPropDirective,\n I18nPipe,\n SearchPipe,\n UserNamePipe,\n NavbarComponent,\n FooterComponent,\n OrganizationPlansComponent,\n ],\n providers: [DatePipe, SearchPipe, UserNamePipe],\n bootstrap: [],\n})\nexport class OssModule { }\n","import {\n Component,\n NgZone,\n OnDestroy,\n OnInit,\n} from '@angular/core';\n\nimport { ActivatedRoute } from '@angular/router';\n\nimport { BroadcasterService } from 'jslib-angular/services/broadcaster.service';\n\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\n\nconst BroadcasterSubscriptionId = 'OrganizationLayoutComponent';\n\n@Component({\n selector: 'app-organization-layout',\n templateUrl: 'organization-layout.component.html',\n})\nexport class OrganizationLayoutComponent implements OnInit, OnDestroy {\n organization: Organization;\n businessTokenPromise: Promise;\n private organizationId: string;\n\n constructor(private route: ActivatedRoute, private userService: UserService,\n private broadcasterService: BroadcasterService, private ngZone: NgZone) { }\n\n ngOnInit() {\n document.body.classList.remove('layout_frontend');\n this.route.params.subscribe(async params => {\n this.organizationId = params.organizationId;\n await this.load();\n });\n this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {\n this.ngZone.run(async () => {\n switch (message.command) {\n case 'updatedOrgLicense':\n await this.load();\n break;\n }\n });\n });\n }\n\n ngOnDestroy() {\n this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);\n }\n\n async load() {\n this.organization = await this.userService.getOrganization(this.organizationId);\n }\n\n get showMenuBar() {\n return this.showManageTab || this.showToolsTab || this.organization.isOwner;\n }\n\n get showManageTab(): boolean {\n return this.organization.canManageUsers ||\n this.organization.canViewAllCollections ||\n this.organization.canViewAssignedCollections ||\n this.organization.canManageGroups ||\n this.organization.canManagePolicies ||\n this.organization.canAccessEventLogs;\n }\n\n get showToolsTab(): boolean {\n return this.organization.canAccessImportExport || this.organization.canAccessReports;\n }\n\n get toolsRoute(): string {\n return this.organization.canAccessImportExport ?\n 'tools/import' :\n 'tools/exposed-passwords-report';\n }\n\n get manageRoute(): string {\n let route: string;\n switch (true) {\n case this.organization.canManageUsers:\n route = 'manage/people';\n break;\n case this.organization.canViewAssignedCollections || this.organization.canViewAllCollections:\n route = 'manage/collections';\n break;\n case this.organization.canManageGroups:\n route = 'manage/groups';\n break;\n case this.organization.canManagePolicies:\n route = 'manage/policies';\n break;\n case this.organization.canAccessEventLogs:\n route = 'manage/events';\n break;\n }\n return route;\n }\n}\n","
{{organization.name}} {{'organization' | i18n}}
{{'organizationIsDisabled' | i18n}}
{{'accessingUsingProvider' | i18n : organization.providerName}}
","import { PolicyData } from '../data/policyData';\n\nimport Domain from './domainBase';\n\nimport { PolicyType } from '../../enums/policyType';\n\nexport class Policy extends Domain {\n id: string;\n organizationId: string;\n type: PolicyType;\n data: any;\n enabled: boolean;\n\n constructor(obj?: PolicyData) {\n super();\n if (obj == null) {\n return;\n }\n\n this.id = obj.id;\n this.organizationId = obj.organizationId;\n this.type = obj.type;\n this.data = obj.data;\n this.enabled = obj.enabled;\n }\n}\n","import { HashPurpose } from '../enums/hashPurpose';\nimport { KdfType } from '../enums/kdfType';\nimport { TwoFactorProviderType } from '../enums/twoFactorProviderType';\n\nimport { AuthResult } from '../models/domain/authResult';\nimport { SymmetricCryptoKey } from '../models/domain/symmetricCryptoKey';\n\nimport { SetKeyConnectorKeyRequest } from '../models/request/account/setKeyConnectorKeyRequest';\nimport { DeviceRequest } from '../models/request/deviceRequest';\nimport { KeyConnectorUserKeyRequest } from '../models/request/keyConnectorUserKeyRequest';\nimport { KeysRequest } from '../models/request/keysRequest';\nimport { PreloginRequest } from '../models/request/preloginRequest';\nimport { TokenRequest } from '../models/request/tokenRequest';\n\nimport { IdentityTokenResponse } from '../models/response/identityTokenResponse';\nimport { IdentityTwoFactorResponse } from '../models/response/identityTwoFactorResponse';\n\nimport { ApiService } from '../abstractions/api.service';\nimport { AppIdService } from '../abstractions/appId.service';\nimport { AuthService as AuthServiceAbstraction } from '../abstractions/auth.service';\nimport { CryptoService } from '../abstractions/crypto.service';\nimport { CryptoFunctionService } from '../abstractions/cryptoFunction.service';\nimport { EnvironmentService } from '../abstractions/environment.service';\nimport { I18nService } from '../abstractions/i18n.service';\nimport { KeyConnectorService } from '../abstractions/keyConnector.service';\nimport { LogService } from '../abstractions/log.service';\nimport { MessagingService } from '../abstractions/messaging.service';\nimport { PlatformUtilsService } from '../abstractions/platformUtils.service';\nimport { TokenService } from '../abstractions/token.service';\nimport { UserService } from '../abstractions/user.service';\nimport { VaultTimeoutService } from '../abstractions/vaultTimeout.service';\n\nimport { Utils } from '../misc/utils';\n\nexport const TwoFactorProviders = {\n [TwoFactorProviderType.Authenticator]: {\n type: TwoFactorProviderType.Authenticator,\n name: null as string,\n description: null as string,\n priority: 1,\n sort: 1,\n premium: false,\n },\n [TwoFactorProviderType.Yubikey]: {\n type: TwoFactorProviderType.Yubikey,\n name: null as string,\n description: null as string,\n priority: 3,\n sort: 2,\n premium: true,\n },\n [TwoFactorProviderType.Duo]: {\n type: TwoFactorProviderType.Duo,\n name: 'Duo',\n description: null as string,\n priority: 2,\n sort: 3,\n premium: true,\n },\n [TwoFactorProviderType.OrganizationDuo]: {\n type: TwoFactorProviderType.OrganizationDuo,\n name: 'Duo (Organization)',\n description: null as string,\n priority: 10,\n sort: 4,\n premium: false,\n },\n [TwoFactorProviderType.Email]: {\n type: TwoFactorProviderType.Email,\n name: null as string,\n description: null as string,\n priority: 0,\n sort: 6,\n premium: false,\n },\n [TwoFactorProviderType.WebAuthn]: {\n type: TwoFactorProviderType.WebAuthn,\n name: null as string,\n description: null as string,\n priority: 4,\n sort: 5,\n premium: true,\n },\n};\n\nexport class AuthService implements AuthServiceAbstraction {\n email: string;\n masterPasswordHash: string;\n localMasterPasswordHash: string;\n code: string;\n codeVerifier: string;\n ssoRedirectUrl: string;\n clientId: string;\n clientSecret: string;\n twoFactorProvidersData: Map;\n selectedTwoFactorProviderType: TwoFactorProviderType = null;\n captchaToken: string;\n\n private key: SymmetricCryptoKey;\n\n constructor(private cryptoService: CryptoService, protected apiService: ApiService,\n private userService: UserService, protected tokenService: TokenService,\n protected appIdService: AppIdService, private i18nService: I18nService,\n protected platformUtilsService: PlatformUtilsService, private messagingService: MessagingService,\n private vaultTimeoutService: VaultTimeoutService, private logService: LogService,\n private cryptoFunctionService: CryptoFunctionService, private environmentService: EnvironmentService,\n private keyConnectorService: KeyConnectorService, private setCryptoKeys = true) {\n }\n\n init() {\n TwoFactorProviders[TwoFactorProviderType.Email].name = this.i18nService.t('emailTitle');\n TwoFactorProviders[TwoFactorProviderType.Email].description = this.i18nService.t('emailDesc');\n\n TwoFactorProviders[TwoFactorProviderType.Authenticator].name = this.i18nService.t('authenticatorAppTitle');\n TwoFactorProviders[TwoFactorProviderType.Authenticator].description =\n this.i18nService.t('authenticatorAppDesc');\n\n TwoFactorProviders[TwoFactorProviderType.Duo].description = this.i18nService.t('duoDesc');\n\n TwoFactorProviders[TwoFactorProviderType.OrganizationDuo].name =\n 'Duo (' + this.i18nService.t('organization') + ')';\n TwoFactorProviders[TwoFactorProviderType.OrganizationDuo].description =\n this.i18nService.t('duoOrganizationDesc');\n\n TwoFactorProviders[TwoFactorProviderType.WebAuthn].name = this.i18nService.t('webAuthnTitle');\n TwoFactorProviders[TwoFactorProviderType.WebAuthn].description = this.i18nService.t('webAuthnDesc');\n\n TwoFactorProviders[TwoFactorProviderType.Yubikey].name = this.i18nService.t('yubiKeyTitle');\n TwoFactorProviders[TwoFactorProviderType.Yubikey].description = this.i18nService.t('yubiKeyDesc');\n }\n\n async logIn(email: string, masterPassword: string, captchaToken?: string): Promise {\n this.selectedTwoFactorProviderType = null;\n const key = await this.makePreloginKey(masterPassword, email);\n const hashedPassword = await this.cryptoService.hashPassword(masterPassword, key);\n const localHashedPassword = await this.cryptoService.hashPassword(masterPassword, key,\n HashPurpose.LocalAuthorization);\n return await this.logInHelper(email, hashedPassword, localHashedPassword, null, null, null, null, null,\n key, null, null, null, captchaToken, null);\n }\n\n async logInSso(code: string, codeVerifier: string, redirectUrl: string, orgId: string): Promise {\n this.selectedTwoFactorProviderType = null;\n return await this.logInHelper(null, null, null, code, codeVerifier, redirectUrl, null, null,\n null, null, null, null, null, orgId);\n }\n\n async logInApiKey(clientId: string, clientSecret: string): Promise {\n this.selectedTwoFactorProviderType = null;\n return await this.logInHelper(null, null, null, null, null, null, clientId, clientSecret,\n null, null, null, null, null, null);\n }\n\n async logInTwoFactor(twoFactorProvider: TwoFactorProviderType, twoFactorToken: string,\n remember?: boolean): Promise {\n return await this.logInHelper(this.email, this.masterPasswordHash, this.localMasterPasswordHash, this.code,\n this.codeVerifier, this.ssoRedirectUrl, this.clientId, this.clientSecret, this.key, twoFactorProvider,\n twoFactorToken, remember, this.captchaToken, null);\n }\n\n async logInComplete(email: string, masterPassword: string, twoFactorProvider: TwoFactorProviderType,\n twoFactorToken: string, remember?: boolean, captchaToken?: string): Promise {\n this.selectedTwoFactorProviderType = null;\n const key = await this.makePreloginKey(masterPassword, email);\n const hashedPassword = await this.cryptoService.hashPassword(masterPassword, key);\n const localHashedPassword = await this.cryptoService.hashPassword(masterPassword, key,\n HashPurpose.LocalAuthorization);\n return await this.logInHelper(email, hashedPassword, localHashedPassword, null, null, null, null, null, key,\n twoFactorProvider, twoFactorToken, remember, captchaToken, null);\n }\n\n async logInSsoComplete(code: string, codeVerifier: string, redirectUrl: string,\n twoFactorProvider: TwoFactorProviderType, twoFactorToken: string, remember?: boolean): Promise {\n this.selectedTwoFactorProviderType = null;\n return await this.logInHelper(null, null, null, code, codeVerifier, redirectUrl, null,\n null, null, twoFactorProvider, twoFactorToken, remember, null, null);\n }\n\n async logInApiKeyComplete(clientId: string, clientSecret: string, twoFactorProvider: TwoFactorProviderType,\n twoFactorToken: string, remember?: boolean): Promise {\n this.selectedTwoFactorProviderType = null;\n return await this.logInHelper(null, null, null, null, null, null, clientId, clientSecret, null,\n twoFactorProvider, twoFactorToken, remember, null, null);\n }\n\n logOut(callback: Function) {\n callback();\n this.messagingService.send('loggedOut');\n }\n\n getSupportedTwoFactorProviders(win: Window): any[] {\n const providers: any[] = [];\n if (this.twoFactorProvidersData == null) {\n return providers;\n }\n\n if (this.twoFactorProvidersData.has(TwoFactorProviderType.OrganizationDuo) &&\n this.platformUtilsService.supportsDuo()) {\n providers.push(TwoFactorProviders[TwoFactorProviderType.OrganizationDuo]);\n }\n\n if (this.twoFactorProvidersData.has(TwoFactorProviderType.Authenticator)) {\n providers.push(TwoFactorProviders[TwoFactorProviderType.Authenticator]);\n }\n\n if (this.twoFactorProvidersData.has(TwoFactorProviderType.Yubikey)) {\n providers.push(TwoFactorProviders[TwoFactorProviderType.Yubikey]);\n }\n\n if (this.twoFactorProvidersData.has(TwoFactorProviderType.Duo) && this.platformUtilsService.supportsDuo()) {\n providers.push(TwoFactorProviders[TwoFactorProviderType.Duo]);\n }\n\n if (this.twoFactorProvidersData.has(TwoFactorProviderType.WebAuthn) && this.platformUtilsService.supportsWebAuthn(win)) {\n providers.push(TwoFactorProviders[TwoFactorProviderType.WebAuthn]);\n }\n\n if (this.twoFactorProvidersData.has(TwoFactorProviderType.Email)) {\n providers.push(TwoFactorProviders[TwoFactorProviderType.Email]);\n }\n\n return providers;\n }\n\n getDefaultTwoFactorProvider(webAuthnSupported: boolean): TwoFactorProviderType {\n if (this.twoFactorProvidersData == null) {\n return null;\n }\n\n if (this.selectedTwoFactorProviderType != null &&\n this.twoFactorProvidersData.has(this.selectedTwoFactorProviderType)) {\n return this.selectedTwoFactorProviderType;\n }\n\n let providerType: TwoFactorProviderType = null;\n let providerPriority = -1;\n this.twoFactorProvidersData.forEach((value, type) => {\n const provider = (TwoFactorProviders as any)[type];\n if (provider != null && provider.priority > providerPriority) {\n if (type === TwoFactorProviderType.WebAuthn && !webAuthnSupported) {\n return;\n }\n\n providerType = type;\n providerPriority = provider.priority;\n }\n });\n\n return providerType;\n }\n\n async makePreloginKey(masterPassword: string, email: string): Promise {\n email = email.trim().toLowerCase();\n let kdf: KdfType = null;\n let kdfIterations: number = null;\n try {\n const preloginResponse = await this.apiService.postPrelogin(new PreloginRequest(email));\n if (preloginResponse != null) {\n kdf = preloginResponse.kdf;\n kdfIterations = preloginResponse.kdfIterations;\n }\n } catch (e) {\n if (e == null || e.statusCode !== 404) {\n throw e;\n }\n }\n return this.cryptoService.makeKey(masterPassword, email, kdf, kdfIterations);\n }\n\n authingWithApiKey(): boolean {\n return this.clientId != null && this.clientSecret != null;\n }\n\n authingWithSso(): boolean {\n return this.code != null && this.codeVerifier != null && this.ssoRedirectUrl != null;\n }\n\n authingWithPassword(): boolean {\n return this.email != null && this.masterPasswordHash != null;\n }\n\n private async logInHelper(email: string, hashedPassword: string, localHashedPassword: string, code: string,\n codeVerifier: string, redirectUrl: string, clientId: string, clientSecret: string, key: SymmetricCryptoKey,\n twoFactorProvider?: TwoFactorProviderType, twoFactorToken?: string, remember?: boolean, captchaToken?: string,\n orgId?: string): Promise {\n const storedTwoFactorToken = await this.tokenService.getTwoFactorToken(email);\n const appId = await this.appIdService.getAppId();\n const deviceRequest = new DeviceRequest(appId, this.platformUtilsService);\n\n let emailPassword: string[] = [];\n let codeCodeVerifier: string[] = [];\n let clientIdClientSecret: [string, string] = [null, null];\n\n if (email != null && hashedPassword != null) {\n emailPassword = [email, hashedPassword];\n } else {\n emailPassword = null;\n }\n if (code != null && codeVerifier != null && redirectUrl != null) {\n codeCodeVerifier = [code, codeVerifier, redirectUrl];\n } else {\n codeCodeVerifier = null;\n }\n if (clientId != null && clientSecret != null) {\n clientIdClientSecret = [clientId, clientSecret];\n } else {\n clientIdClientSecret = null;\n }\n\n let request: TokenRequest;\n if (twoFactorToken != null && twoFactorProvider != null) {\n request = new TokenRequest(emailPassword, codeCodeVerifier, clientIdClientSecret, twoFactorProvider,\n twoFactorToken, remember, captchaToken, deviceRequest);\n } else if (storedTwoFactorToken != null) {\n request = new TokenRequest(emailPassword, codeCodeVerifier, clientIdClientSecret,\n TwoFactorProviderType.Remember, storedTwoFactorToken, false, captchaToken, deviceRequest);\n } else {\n request = new TokenRequest(emailPassword, codeCodeVerifier, clientIdClientSecret, null,\n null, false, captchaToken, deviceRequest);\n }\n\n const response = await this.apiService.postIdentityToken(request);\n\n this.clearState();\n const result = new AuthResult();\n result.captchaSiteKey = (response as any).siteKey;\n if (!!result.captchaSiteKey) {\n return result;\n }\n result.twoFactor = !!(response as any).twoFactorProviders2;\n\n if (result.twoFactor) {\n // two factor required\n this.email = email;\n this.masterPasswordHash = hashedPassword;\n this.localMasterPasswordHash = localHashedPassword;\n this.code = code;\n this.codeVerifier = codeVerifier;\n this.ssoRedirectUrl = redirectUrl;\n this.clientId = clientId;\n this.clientSecret = clientSecret;\n this.key = this.setCryptoKeys ? key : null;\n const twoFactorResponse = response as IdentityTwoFactorResponse;\n this.twoFactorProvidersData = twoFactorResponse.twoFactorProviders2;\n result.twoFactorProviders = twoFactorResponse.twoFactorProviders2;\n this.captchaToken = twoFactorResponse.captchaToken;\n return result;\n }\n\n const tokenResponse = response as IdentityTokenResponse;\n result.resetMasterPassword = tokenResponse.resetMasterPassword;\n result.forcePasswordReset = tokenResponse.forcePasswordReset;\n if (tokenResponse.twoFactorToken != null) {\n await this.tokenService.setTwoFactorToken(tokenResponse.twoFactorToken, email);\n }\n\n await this.tokenService.setTokens(tokenResponse.accessToken, tokenResponse.refreshToken, clientIdClientSecret);\n await this.userService.setInformation(this.tokenService.getUserId(), this.tokenService.getEmail(),\n tokenResponse.kdf, tokenResponse.kdfIterations);\n if (this.setCryptoKeys) {\n if (key != null) {\n await this.cryptoService.setKey(key);\n }\n if (localHashedPassword != null) {\n await this.cryptoService.setKeyHash(localHashedPassword);\n }\n\n // Skip this step during SSO new user flow. No key is returned from server.\n if (code == null || tokenResponse.key != null) {\n\n if (tokenResponse.keyConnectorUrl != null) {\n await this.keyConnectorService.getAndSetKey(tokenResponse.keyConnectorUrl);\n } else if (tokenResponse.apiUseKeyConnector) {\n const keyConnectorUrl = this.environmentService.getKeyConnectorUrl();\n await this.keyConnectorService.getAndSetKey(keyConnectorUrl);\n }\n\n await this.cryptoService.setEncKey(tokenResponse.key);\n\n // User doesn't have a key pair yet (old account), let's generate one for them\n if (tokenResponse.privateKey == null) {\n try {\n const keyPair = await this.cryptoService.makeKeyPair();\n await this.apiService.postAccountKeys(new KeysRequest(keyPair[0], keyPair[1].encryptedString));\n tokenResponse.privateKey = keyPair[1].encryptedString;\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n await this.cryptoService.setEncPrivateKey(tokenResponse.privateKey);\n } else if (tokenResponse.keyConnectorUrl != null) {\n const password = await this.cryptoFunctionService.randomBytes(64);\n\n const k = await this.cryptoService.makeKey(Utils.fromBufferToB64(password), this.tokenService.getEmail(), tokenResponse.kdf, tokenResponse.kdfIterations);\n const keyConnectorRequest = new KeyConnectorUserKeyRequest(k.encKeyB64);\n await this.cryptoService.setKey(k);\n\n const encKey = await this.cryptoService.makeEncKey(k);\n await this.cryptoService.setEncKey(encKey[1].encryptedString);\n\n const [pubKey, privKey] = await this.cryptoService.makeKeyPair();\n\n try {\n await this.apiService.postUserKeyToKeyConnector(tokenResponse.keyConnectorUrl, keyConnectorRequest);\n } catch (e) {\n throw new Error('Unable to reach key connector');\n }\n\n const keys = new KeysRequest(pubKey, privKey.encryptedString);\n const setPasswordRequest = new SetKeyConnectorKeyRequest(\n encKey[1].encryptedString, tokenResponse.kdf, tokenResponse.kdfIterations, orgId, keys\n );\n await this.apiService.postSetKeyConnectorKey(setPasswordRequest);\n }\n }\n\n if (this.vaultTimeoutService != null) {\n this.vaultTimeoutService.biometricLocked = false;\n }\n this.messagingService.send('loggedIn');\n return result;\n }\n\n private clearState(): void {\n this.key = null;\n this.email = null;\n this.masterPasswordHash = null;\n this.localMasterPasswordHash = null;\n this.code = null;\n this.codeVerifier = null;\n this.ssoRedirectUrl = null;\n this.clientId = null;\n this.clientSecret = null;\n this.twoFactorProvidersData = null;\n this.selectedTwoFactorProviderType = null;\n }\n}\n","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\nimport { OrganizationUserStatusType } from 'jslib-common/enums/organizationUserStatusType';\nimport { OrganizationUserType } from 'jslib-common/enums/organizationUserType';\nimport { SelectionReadOnlyRequest } from 'jslib-common/models/request/selectionReadOnlyRequest';\nimport { OrganizationUserUserDetailsResponse } from 'jslib-common/models/response/organizationUserResponse';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\n@Component({\n selector: 'app-entity-users',\n templateUrl: 'entity-users.component.html',\n})\nexport class EntityUsersComponent implements OnInit {\n @Input() entity: 'group' | 'collection';\n @Input() entityId: string;\n @Input() entityName: string;\n @Input() organizationId: string;\n @Output() onEditedUsers = new EventEmitter();\n\n organizationUserType = OrganizationUserType;\n organizationUserStatusType = OrganizationUserStatusType;\n\n showSelected = false;\n loading = true;\n formPromise: Promise;\n selectedCount = 0;\n searchText: string;\n\n private allUsers: OrganizationUserUserDetailsResponse[] = [];\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private logService: LogService) { }\n\n async ngOnInit() {\n await this.loadUsers();\n this.loading = false;\n }\n\n get users() {\n if (this.showSelected) {\n return this.allUsers.filter(u => (u as any).checked);\n } else {\n return this.allUsers;\n }\n }\n\n async loadUsers() {\n const users = await this.apiService.getOrganizationUsers(this.organizationId);\n this.allUsers = users.data.map(r => r).sort(Utils.getSortFunction(this.i18nService, 'email'));\n if (this.entity === 'group') {\n const response = await this.apiService.getGroupUsers(this.organizationId, this.entityId);\n if (response != null && users.data.length > 0) {\n response.forEach(s => {\n const user = users.data.filter(u => u.id === s);\n if (user != null && user.length > 0) {\n (user[0] as any).checked = true;\n }\n });\n }\n } else if (this.entity === 'collection') {\n const response = await this.apiService.getCollectionUsers(this.organizationId, this.entityId);\n if (response != null && users.data.length > 0) {\n response.forEach(s => {\n const user = users.data.filter(u => !u.accessAll && u.id === s.id);\n if (user != null && user.length > 0) {\n (user[0] as any).checked = true;\n (user[0] as any).readOnly = s.readOnly;\n (user[0] as any).hidePasswords = s.hidePasswords;\n }\n });\n }\n }\n\n this.allUsers.forEach(u => {\n if (this.entity === 'collection' && u.accessAll) {\n (u as any).checked = true;\n }\n if ((u as any).checked) {\n this.selectedCount++;\n }\n });\n }\n\n check(u: OrganizationUserUserDetailsResponse) {\n if (this.entity === 'collection' && u.accessAll) {\n return;\n }\n (u as any).checked = !(u as any).checked;\n this.selectedChanged(u);\n }\n\n selectedChanged(u: OrganizationUserUserDetailsResponse) {\n if ((u as any).checked) {\n this.selectedCount++;\n } else {\n if (this.entity === 'collection') {\n (u as any).readOnly = false;\n (u as any).hidePasswords = false;\n }\n this.selectedCount--;\n }\n }\n\n filterSelected(showSelected: boolean) {\n this.showSelected = showSelected;\n }\n\n async submit() {\n try {\n if (this.entity === 'group') {\n const selections = this.users.filter(u => (u as any).checked).map(u => u.id);\n this.formPromise = this.apiService.putGroupUsers(this.organizationId, this.entityId, selections);\n } else {\n const selections = this.users.filter(u => (u as any).checked && !u.accessAll)\n .map(u => new SelectionReadOnlyRequest(u.id, !!(u as any).readOnly, !!(u as any).hidePasswords));\n this.formPromise = this.apiService.putCollectionUsers(this.organizationId, this.entityId, selections);\n }\n await this.formPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('updatedUsers'));\n this.onEditedUsers.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{'userAccess' | i18n}} {{entityName}}

{{'loading' | i18n}}

{{'noUsersInList' | i18n}}
    {{'name' | i18n}}   {{'userType' | i18n}} {{'hidePasswords' | i18n}} {{'readOnly' | i18n}}
{{u.email}} {{'invited' | i18n}} {{'accepted' | i18n}} {{u.name}} {{'userAccessAllItems' | i18n}} {{'owner' | i18n}} {{'admin' | i18n}} {{'manager' | i18n}} {{'user' | i18n}} {{'custom' | i18n}}
","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\n\n@Component({\n selector: 'app-org-manage',\n templateUrl: 'manage.component.html',\n})\nexport class ManageComponent implements OnInit {\n organization: Organization;\n accessPolicies: boolean = false;\n accessGroups: boolean = false;\n accessEvents: boolean = false;\n accessSso: boolean = false;\n\n constructor(private route: ActivatedRoute, private userService: UserService) {}\n\n ngOnInit() {\n this.route.parent.params.subscribe(async params => {\n this.organization = await this.userService.getOrganization(params.organizationId);\n this.accessPolicies = this.organization.usePolicies;\n this.accessSso = this.organization.useSso;\n this.accessEvents = this.organization.useEvents;\n this.accessGroups = this.organization.useGroups;\n });\n }\n}\n"," ","import { Component } from '@angular/core';\n\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { SecretVerificationRequest } from 'jslib-common/models/request/secretVerificationRequest';\n\nimport { ApiKeyResponse } from 'jslib-common/models/response/apiKeyResponse';\n\nimport { Verification } from 'jslib-common/types/verification';\n\n@Component({\n selector: 'app-api-key',\n templateUrl: 'api-key.component.html',\n})\nexport class ApiKeyComponent {\n keyType: string;\n isRotation: boolean;\n postKey: (entityId: string, request: SecretVerificationRequest) => Promise;\n entityId: string;\n scope: string;\n grantType: string;\n apiKeyTitle: string;\n apiKeyWarning: string;\n apiKeyDescription: string;\n\n masterPassword: Verification;\n formPromise: Promise;\n clientId: string;\n clientSecret: string;\n\n constructor(private userVerificationService: UserVerificationService, private logService: LogService) { }\n\n async submit() {\n try {\n this.formPromise = this.userVerificationService.buildRequest(this.masterPassword)\n .then(request => this.postKey(this.entityId, request));\n const response = await this.formPromise;\n this.clientSecret = response.apiKey;\n this.clientId = `${this.keyType}.${this.entityId}`;\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{apiKeyTitle | i18n}}

{{apiKeyDescription | i18n}}

{{apiKeyWarning | i18n}}

client_id:
{{clientId}}

client_secret:
{{clientSecret}}

scope:
{{scope}}

grant_type:
{{grantType}}

","export enum VerificationType {\n MasterPassword = 0,\n OTP = 1,\n}\n","import {\n Component,\n Input,\n} from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { Verification } from 'jslib-common/types/verification';\n\n@Component({\n selector: 'app-purge-vault',\n templateUrl: 'purge-vault.component.html',\n})\nexport class PurgeVaultComponent {\n @Input() organizationId?: string = null;\n\n masterPassword: Verification;\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private userVerificationService: UserVerificationService,\n private router: Router, private logService: LogService) { }\n\n async submit() {\n try {\n this.formPromise = this.userVerificationService.buildRequest(this.masterPassword)\n .then(request => this.apiService.postPurgeCiphers(request, this.organizationId));\n await this.formPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('vaultPurged'));\n if (this.organizationId != null) {\n this.router.navigate(['organizations', this.organizationId, 'vault']);\n } else {\n this.router.navigate(['vault']);\n }\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{'purgeVault' | i18n}}

{{(organizationId ? 'purgeOrgVaultDesc' : 'purgeVaultDesc') | i18n}}

{{'purgeVaultWarning' | i18n}}
","import {\n Component,\n EventEmitter,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { Verification } from 'jslib-common/types/verification';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\n@Component({\n selector: 'app-delete-organization',\n templateUrl: 'delete-organization.component.html',\n})\nexport class DeleteOrganizationComponent {\n organizationId: string;\n descriptionKey = 'deleteOrganizationDesc';\n @Output() onSuccess: EventEmitter = new EventEmitter();\n\n masterPassword: Verification;\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private userVerificationService: UserVerificationService,\n private logService: LogService) { }\n\n async submit() {\n try {\n this.formPromise = this.userVerificationService.buildRequest(this.masterPassword)\n .then(request => this.apiService.deleteOrganization(this.organizationId, request));\n await this.formPromise;\n this.toasterService.popAsync('success', this.i18nService.t('organizationDeleted'),\n this.i18nService.t('organizationDeletedDesc'));\n this.onSuccess.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{'deleteOrganization' | i18n}}

{{descriptionKey | i18n}}

{{'deleteOrganizationWarning' | i18n}}
","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { BillingResponse } from 'jslib-common/models/response/billingResponse';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { PaymentMethodType } from 'jslib-common/enums/paymentMethodType';\nimport { TransactionType } from 'jslib-common/enums/transactionType';\nimport { VerifyBankRequest } from 'jslib-common/models/request/verifyBankRequest';\n\n@Component({\n selector: 'app-user-billing',\n templateUrl: 'user-billing.component.html',\n})\nexport class UserBillingComponent implements OnInit {\n loading = false;\n firstLoaded = false;\n showAdjustPayment = false;\n showAddCredit = false;\n billing: BillingResponse;\n paymentMethodType = PaymentMethodType;\n transactionType = TransactionType;\n organizationId: string;\n verifyAmount1: number;\n verifyAmount2: number;\n\n verifyBankPromise: Promise;\n\n constructor(protected apiService: ApiService, protected i18nService: I18nService,\n protected toasterService: ToasterService, protected platformUtilsService: PlatformUtilsService,\n private logService: LogService) { }\n\n async ngOnInit() {\n await this.load();\n this.firstLoaded = true;\n }\n\n async load() {\n if (this.loading) {\n return;\n }\n this.loading = true;\n if (this.organizationId != null) {\n this.billing = await this.apiService.getOrganizationBilling(this.organizationId);\n } else {\n this.billing = await this.apiService.getUserBilling();\n }\n this.loading = false;\n }\n\n async verifyBank() {\n if (this.loading) {\n return;\n }\n\n try {\n const request = new VerifyBankRequest();\n request.amount1 = this.verifyAmount1;\n request.amount2 = this.verifyAmount2;\n this.verifyBankPromise = this.apiService.postOrganizationVerifyBank(this.organizationId, request);\n await this.verifyBankPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('verifiedBankAccount'));\n this.load();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n addCredit() {\n if (this.paymentSourceInApp) {\n this.platformUtilsService.showDialog(this.i18nService.t('cannotPerformInAppPurchase'),\n this.i18nService.t('addCredit'), null, null, 'warning');\n return;\n }\n this.showAddCredit = true;\n }\n\n closeAddCredit(load: boolean) {\n this.showAddCredit = false;\n if (load) {\n this.load();\n }\n }\n\n changePayment() {\n if (this.paymentSourceInApp) {\n this.platformUtilsService.showDialog(this.i18nService.t('cannotPerformInAppPurchase'),\n this.i18nService.t('changePaymentMethod'), null, null, 'warning');\n return;\n }\n this.showAdjustPayment = true;\n }\n\n closePayment(load: boolean) {\n this.showAdjustPayment = false;\n if (load) {\n this.load();\n }\n }\n\n get isCreditBalance() {\n return this.billing == null || this.billing.balance <= 0;\n }\n\n get creditOrBalance() {\n return Math.abs(this.billing != null ? this.billing.balance : 0);\n }\n\n get paymentSource() {\n return this.billing != null ? this.billing.paymentSource : null;\n }\n\n get paymentSourceInApp() {\n return this.paymentSource != null &&\n (this.paymentSource.type === PaymentMethodType.AppleInApp ||\n this.paymentSource.type === PaymentMethodType.GoogleInApp);\n }\n\n get invoices() {\n return this.billing != null ? this.billing.invoices : null;\n }\n\n get transactions() {\n return this.billing != null ? this.billing.transactions : null;\n }\n}\n","

{{'billing' | i18n}}

{{'loading' | i18n}}

{{(isCreditBalance ? 'accountCredit' : 'accountBalance') | i18n}}

{{creditOrBalance | currency:'$'}}

{{'creditAppliedDesc' | i18n}}

{{'paymentMethod' | i18n}}

{{'noPaymentMethod' | i18n}}

{{'verifyBankAccountDesc' | i18n}} {{'verifyBankAccountFailureWarning' | i18n}}

$0.
$0.

{{'inAppPurchase' | i18n}} {{paymentSource.description}}

{{'invoices' | i18n}}

{{'noInvoices' | i18n}}

{{i.date | date:'mediumDate'}} {{'invoiceNumber' | i18n : i.number}} {{i.amount | currency:'$'}} {{'paid' | i18n}} {{'unpaid' | i18n}}

{{'transactions' | i18n}}

{{'noTransactions' | i18n}}

{{t.createdDate | date:'mediumDate'}} {{'chargeNoun' | i18n}} {{'refundNoun' | i18n}} {{t.details}} {{t.amount | currency:'$'}}
* {{'chargesStatement' | i18n : 'BITWARDEN'}}
","import {\n Component,\n ElementRef,\n EventEmitter,\n Input,\n OnInit,\n Output,\n ViewChild,\n} from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { PayPalConfig } from 'jslib-common/abstractions/environment.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { PaymentMethodType } from 'jslib-common/enums/paymentMethodType';\n\nimport { BitPayInvoiceRequest } from 'jslib-common/models/request/bitPayInvoiceRequest';\n\n@Component({\n selector: 'app-add-credit',\n templateUrl: 'add-credit.component.html',\n})\nexport class AddCreditComponent implements OnInit {\n @Input() creditAmount: string;\n @Input() showOptions = true;\n @Input() method = PaymentMethodType.PayPal;\n @Input() organizationId: string;\n @Output() onAdded = new EventEmitter();\n @Output() onCanceled = new EventEmitter();\n\n @ViewChild('ppButtonForm', { read: ElementRef, static: true }) ppButtonFormRef: ElementRef;\n\n paymentMethodType = PaymentMethodType;\n ppButtonFormAction: string;\n ppButtonBusinessId: string;\n ppButtonCustomField: string;\n ppLoading = false;\n subject: string;\n returnUrl: string;\n formPromise: Promise;\n\n private userId: string;\n private name: string;\n private email: string;\n\n constructor(private userService: UserService, private apiService: ApiService,\n private platformUtilsService: PlatformUtilsService, private logService: LogService) {\n const payPalConfig = process.env.PAYPAL_CONFIG as PayPalConfig;\n this.ppButtonFormAction = payPalConfig.buttonAction;\n this.ppButtonBusinessId = payPalConfig.businessId;\n }\n\n async ngOnInit() {\n if (this.organizationId != null) {\n if (this.creditAmount == null) {\n this.creditAmount = '20.00';\n }\n this.ppButtonCustomField = 'organization_id:' + this.organizationId;\n const org = await this.userService.getOrganization(this.organizationId);\n if (org != null) {\n this.subject = org.name;\n this.name = org.name;\n }\n } else {\n if (this.creditAmount == null) {\n this.creditAmount = '10.00';\n }\n this.userId = await this.userService.getUserId();\n this.subject = await this.userService.getEmail();\n this.email = this.subject;\n this.ppButtonCustomField = 'user_id:' + this.userId;\n }\n this.ppButtonCustomField += ',account_credit:1';\n this.returnUrl = window.location.href;\n }\n\n async submit() {\n if (this.creditAmount == null || this.creditAmount === '') {\n return;\n }\n\n if (this.method === PaymentMethodType.PayPal) {\n this.ppButtonFormRef.nativeElement.submit();\n this.ppLoading = true;\n return;\n }\n if (this.method === PaymentMethodType.BitPay) {\n try {\n const req = new BitPayInvoiceRequest();\n req.email = this.email;\n req.name = this.name;\n req.credit = true;\n req.amount = this.creditAmountNumber;\n req.organizationId = this.organizationId;\n req.userId = this.userId;\n req.returnUrl = this.returnUrl;\n this.formPromise = this.apiService.postBitPayInvoice(req);\n const bitPayUrl: string = await this.formPromise;\n this.platformUtilsService.launchUri(bitPayUrl);\n } catch (e) {\n this.logService.error(e);\n }\n return;\n }\n try {\n this.onAdded.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n cancel() {\n this.onCanceled.emit();\n }\n\n formatAmount() {\n try {\n if (this.creditAmount != null && this.creditAmount !== '') {\n const floatAmount = Math.abs(parseFloat(this.creditAmount));\n if (floatAmount > 0) {\n this.creditAmount = parseFloat((Math.round(floatAmount * 100) / 100).toString())\n .toFixed(2).toString();\n return;\n }\n }\n } catch (e) {\n this.logService.error(e);\n }\n this.creditAmount = '';\n }\n\n get creditAmountNumber(): number {\n if (this.creditAmount != null && this.creditAmount !== '') {\n try {\n return parseFloat(this.creditAmount);\n } catch (e) {\n this.logService.error(e);\n }\n }\n return null;\n }\n}\n","

{{'addCredit' | i18n}}

$USD
{{'creditDelayed' | i18n}}
","import {\n Component,\n EventEmitter,\n Input,\n Output,\n ViewChild,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\nimport { PaymentRequest } from 'jslib-common/models/request/paymentRequest';\n\nimport { PaymentMethodType } from 'jslib-common/enums/paymentMethodType';\n\nimport { PaymentComponent } from './payment.component';\nimport { TaxInfoComponent } from './tax-info.component';\n\n@Component({\n selector: 'app-adjust-payment',\n templateUrl: 'adjust-payment.component.html',\n})\nexport class AdjustPaymentComponent {\n @ViewChild(PaymentComponent, { static: true }) paymentComponent: PaymentComponent;\n @ViewChild(TaxInfoComponent, { static: true }) taxInfoComponent: TaxInfoComponent;\n\n @Input() currentType?: PaymentMethodType;\n @Input() organizationId: string;\n @Output() onAdjusted = new EventEmitter();\n @Output() onCanceled = new EventEmitter();\n\n paymentMethodType = PaymentMethodType;\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private logService: LogService) { }\n\n async submit() {\n try {\n const request = new PaymentRequest();\n this.formPromise = this.paymentComponent.createPaymentToken().then(result => {\n request.paymentToken = result[0];\n request.paymentMethodType = result[1];\n request.postalCode = this.taxInfoComponent.taxInfo.postalCode;\n request.country = this.taxInfoComponent.taxInfo.country;\n if (this.organizationId == null) {\n return this.apiService.postAccountPayment(request);\n } else {\n request.taxId = this.taxInfoComponent.taxInfo.taxId;\n request.state = this.taxInfoComponent.taxInfo.state;\n request.line1 = this.taxInfoComponent.taxInfo.line1;\n request.line2 = this.taxInfoComponent.taxInfo.line2;\n request.city = this.taxInfoComponent.taxInfo.city;\n request.state = this.taxInfoComponent.taxInfo.state;\n return this.apiService.postOrganizationPayment(this.organizationId, request);\n }\n });\n await this.formPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('updatedPaymentMethod'));\n this.onAdjusted.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n cancel() {\n this.onCanceled.emit();\n }\n\n changeCountry() {\n if (this.taxInfoComponent.taxInfo.country === 'US') {\n this.paymentComponent.hideBank = !this.organizationId;\n } else {\n this.paymentComponent.hideBank = true;\n if (this.paymentComponent.method === PaymentMethodType.BankAccount) {\n this.paymentComponent.method = PaymentMethodType.Card;\n this.paymentComponent.changeMethod();\n }\n }\n }\n}\n","

{{(currentType != null ? 'changePaymentMethod' : 'addPaymentMethod') | i18n}}

","import {\n Component,\n EventEmitter,\n Input,\n Output,\n ViewChild,\n} from '@angular/core';\n\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\nimport { StorageRequest } from 'jslib-common/models/request/storageRequest';\n\nimport { PaymentResponse } from 'jslib-common/models/response/paymentResponse';\n\nimport { PaymentComponent } from './payment.component';\n\n@Component({\n selector: 'app-adjust-storage',\n templateUrl: 'adjust-storage.component.html',\n})\nexport class AdjustStorageComponent {\n @Input() storageGbPrice = 0;\n @Input() add = true;\n @Input() organizationId: string;\n @Input() interval = 'year';\n @Output() onAdjusted = new EventEmitter();\n @Output() onCanceled = new EventEmitter();\n\n @ViewChild(PaymentComponent, { static: true }) paymentComponent: PaymentComponent;\n\n storageAdjustment = 0;\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private router: Router,\n private activatedRoute: ActivatedRoute, private logService: LogService) { }\n\n async submit() {\n try {\n const request = new StorageRequest();\n request.storageGbAdjustment = this.storageAdjustment;\n if (!this.add) {\n request.storageGbAdjustment *= -1;\n }\n\n let paymentFailed = false;\n const action = async () => {\n let response: Promise;\n if (this.organizationId == null) {\n response = this.formPromise = this.apiService.postAccountStorage(request);\n } else {\n response = this.formPromise = this.apiService.postOrganizationStorage(this.organizationId, request);\n }\n const result = await response;\n if (result != null && result.paymentIntentClientSecret != null) {\n try {\n await this.paymentComponent.handleStripeCardPayment(result.paymentIntentClientSecret, null);\n } catch {\n paymentFailed = true;\n }\n }\n };\n this.formPromise = action();\n await this.formPromise;\n this.onAdjusted.emit(this.storageAdjustment);\n if (paymentFailed) {\n this.toasterService.popAsync({\n body: this.i18nService.t('couldNotChargeCardPayInvoice'),\n type: 'warning',\n timeout: 10000,\n });\n this.router.navigate(['../billing'], { relativeTo: this.activatedRoute });\n } else {\n this.toasterService.popAsync('success', null,\n this.i18nService.t('adjustedStorage', request.storageGbAdjustment.toString()));\n }\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n cancel() {\n this.onCanceled.emit();\n }\n\n get adjustedStorageTotal(): number {\n return this.storageGbPrice * this.storageAdjustment;\n }\n}\n","

{{(add ? 'addStorage' : 'removeStorage') | i18n}}

{{'total' | i18n}}: {{storageAdjustment || 0}} GB × {{storageGbPrice | currency:'$'}} = {{adjustedStorageTotal | currency:'$'}} /{{interval | i18n}}
{{(add ? 'storageAddNote' : 'storageRemoveNote') | i18n}}
","import {\n Component,\n EventEmitter,\n Input,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\n@Component({\n selector: 'app-update-license',\n templateUrl: 'update-license.component.html',\n})\nexport class UpdateLicenseComponent {\n @Input() organizationId: string;\n @Output() onUpdated = new EventEmitter();\n @Output() onCanceled = new EventEmitter();\n\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private logService: LogService) { }\n\n async submit() {\n const fileEl = document.getElementById('file') as HTMLInputElement;\n const files = fileEl.files;\n if (files == null || files.length === 0) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('selectFile'));\n return;\n }\n\n try {\n const fd = new FormData();\n fd.append('license', files[0]);\n\n let updatePromise: Promise = null;\n if (this.organizationId == null) {\n updatePromise = this.apiService.postAccountLicense(fd);\n } else {\n updatePromise = this.apiService.postOrganizationLicenseUpdate(this.organizationId, fd);\n }\n\n this.formPromise = updatePromise.then(() => {\n return this.apiService.refreshIdentityToken();\n });\n\n await this.formPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('updatedLicense'));\n this.onUpdated.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n cancel() {\n this.onCanceled.emit();\n }\n}\n","
{{'licenseFileDesc' | i18n : (!organizationId ? 'bitwarden_premium_license.json' : 'bitwarden_organization_license.json')}}
","import { Component } from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\nimport { UpdateTwoFactorDuoRequest } from 'jslib-common/models/request/updateTwoFactorDuoRequest';\nimport { TwoFactorDuoResponse } from 'jslib-common/models/response/twoFactorDuoResponse';\n\nimport { TwoFactorBaseComponent } from './two-factor-base.component';\n\n@Component({\n selector: 'app-two-factor-duo',\n templateUrl: 'two-factor-duo.component.html',\n})\nexport class TwoFactorDuoComponent extends TwoFactorBaseComponent {\n type = TwoFactorProviderType.Duo;\n ikey: string;\n skey: string;\n host: string;\n formPromise: Promise;\n\n constructor(apiService: ApiService, i18nService: I18nService,\n toasterService: ToasterService, platformUtilsService: PlatformUtilsService,\n logService: LogService, userVerificationService: UserVerificationService) {\n super(apiService, i18nService, toasterService, platformUtilsService, logService, userVerificationService);\n }\n\n auth(authResponse: any) {\n super.auth(authResponse);\n this.processResponse(authResponse.response);\n }\n\n submit() {\n if (this.enabled) {\n return super.disable(this.formPromise);\n } else {\n return this.enable();\n }\n }\n\n protected async enable() {\n const request = await this.buildRequestModel(UpdateTwoFactorDuoRequest);\n request.integrationKey = this.ikey;\n request.secretKey = this.skey;\n request.host = this.host;\n\n return super.enable(async () => {\n if (this.organizationId != null) {\n this.formPromise = this.apiService.putTwoFactorOrganizationDuo(this.organizationId, request);\n } else {\n this.formPromise = this.apiService.putTwoFactorDuo(request);\n }\n const response = await this.formPromise;\n await this.processResponse(response);\n });\n }\n\n private processResponse(response: TwoFactorDuoResponse) {\n this.ikey = response.integrationKey;\n this.skey = response.secretKey;\n this.host = response.host;\n this.enabled = response.enabled;\n }\n}\n","

{{'twoStepLogin' | i18n}} Duo

{{'twoStepLoginProviderEnabled' | i18n}} \"Duo {{'twoFactorDuoIntegrationKey' | i18n}}: {{ikey}}
{{'twoFactorDuoSecretKey' | i18n}}: {{skey}}
{{'twoFactorDuoApiHostname' | i18n}}: {{host}}
\"Duo

{{'twoFactorDuoDesc' | i18n}}

","import {\n Component,\n OnInit,\n Type,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { TwoFactorProviders } from 'jslib-common/services/auth.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { ModalRef } from 'jslib-angular/components/modal/modal.ref';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\n\nimport { TwoFactorAuthenticatorComponent } from './two-factor-authenticator.component';\nimport { TwoFactorDuoComponent } from './two-factor-duo.component';\nimport { TwoFactorEmailComponent } from './two-factor-email.component';\nimport { TwoFactorRecoveryComponent } from './two-factor-recovery.component';\nimport { TwoFactorWebAuthnComponent } from './two-factor-webauthn.component';\nimport { TwoFactorYubiKeyComponent } from './two-factor-yubikey.component';\n\n@Component({\n selector: 'app-two-factor-setup',\n templateUrl: 'two-factor-setup.component.html',\n})\nexport class TwoFactorSetupComponent implements OnInit {\n @ViewChild('recoveryTemplate', { read: ViewContainerRef, static: true }) recoveryModalRef: ViewContainerRef;\n @ViewChild('authenticatorTemplate', { read: ViewContainerRef, static: true }) authenticatorModalRef: ViewContainerRef;\n @ViewChild('yubikeyTemplate', { read: ViewContainerRef, static: true }) yubikeyModalRef: ViewContainerRef;\n @ViewChild('duoTemplate', { read: ViewContainerRef, static: true }) duoModalRef: ViewContainerRef;\n @ViewChild('emailTemplate', { read: ViewContainerRef, static: true }) emailModalRef: ViewContainerRef;\n @ViewChild('webAuthnTemplate', { read: ViewContainerRef, static: true }) webAuthnModalRef: ViewContainerRef;\n\n organizationId: string;\n providers: any[] = [];\n canAccessPremium: boolean;\n showPolicyWarning = false;\n loading = true;\n modal: ModalRef;\n\n constructor(protected apiService: ApiService, protected userService: UserService,\n protected modalService: ModalService, protected messagingService: MessagingService,\n protected policyService: PolicyService) { }\n\n async ngOnInit() {\n this.canAccessPremium = await this.userService.canAccessPremium();\n\n for (const key in TwoFactorProviders) {\n if (!TwoFactorProviders.hasOwnProperty(key)) {\n continue;\n }\n\n const p = (TwoFactorProviders as any)[key];\n if (this.filterProvider(p.type)) {\n continue;\n }\n\n this.providers.push({\n type: p.type,\n name: p.name,\n description: p.description,\n enabled: false,\n premium: p.premium,\n sort: p.sort,\n });\n }\n\n this.providers.sort((a: any, b: any) => a.sort - b.sort);\n await this.load();\n }\n\n async load() {\n this.loading = true;\n const providerList = await this.getTwoFactorProviders();\n providerList.data.forEach(p => {\n this.providers.forEach(p2 => {\n if (p.type === p2.type) {\n p2.enabled = p.enabled;\n }\n });\n });\n this.evaluatePolicies();\n this.loading = false;\n }\n\n async manage(type: TwoFactorProviderType) {\n switch (type) {\n case TwoFactorProviderType.Authenticator:\n const authComp = await this.openModal(this.authenticatorModalRef, TwoFactorAuthenticatorComponent);\n authComp.onUpdated.subscribe((enabled: boolean) => {\n this.updateStatus(enabled, TwoFactorProviderType.Authenticator);\n });\n break;\n case TwoFactorProviderType.Yubikey:\n const yubiComp = await this.openModal(this.yubikeyModalRef, TwoFactorYubiKeyComponent);\n yubiComp.onUpdated.subscribe((enabled: boolean) => {\n this.updateStatus(enabled, TwoFactorProviderType.Yubikey);\n });\n break;\n case TwoFactorProviderType.Duo:\n const duoComp = await this.openModal(this.duoModalRef, TwoFactorDuoComponent);\n duoComp.onUpdated.subscribe((enabled: boolean) => {\n this.updateStatus(enabled, TwoFactorProviderType.Duo);\n });\n break;\n case TwoFactorProviderType.Email:\n const emailComp = await this.openModal(this.emailModalRef, TwoFactorEmailComponent);\n emailComp.onUpdated.subscribe((enabled: boolean) => {\n this.updateStatus(enabled, TwoFactorProviderType.Email);\n });\n break;\n case TwoFactorProviderType.WebAuthn:\n const webAuthnComp = await this.openModal(this.webAuthnModalRef, TwoFactorWebAuthnComponent);\n webAuthnComp.onUpdated.subscribe((enabled: boolean) => {\n this.updateStatus(enabled, TwoFactorProviderType.WebAuthn);\n });\n break;\n default:\n break;\n }\n }\n\n recoveryCode() {\n this.openModal(this.recoveryModalRef, TwoFactorRecoveryComponent);\n }\n\n async premiumRequired() {\n if (!this.canAccessPremium) {\n this.messagingService.send('premiumRequired');\n return;\n }\n }\n\n protected getTwoFactorProviders() {\n return this.apiService.getTwoFactorProviders();\n }\n\n protected filterProvider(type: TwoFactorProviderType) {\n return type === TwoFactorProviderType.OrganizationDuo;\n }\n\n protected async openModal(ref: ViewContainerRef, type: Type): Promise {\n const [modal, childComponent] = await this.modalService.openViewRef(type, ref);\n this.modal = modal;\n\n return childComponent;\n }\n\n protected updateStatus(enabled: boolean, type: TwoFactorProviderType) {\n if (!enabled && this.modal != null) {\n this.modal.close();\n }\n this.providers.forEach(p => {\n if (p.type === type) {\n p.enabled = enabled;\n }\n });\n this.evaluatePolicies();\n }\n\n private async evaluatePolicies() {\n if (this.organizationId == null && this.providers.filter(p => p.enabled).length === 1) {\n this.showPolicyWarning = await this.policyService.policyAppliesToUser(PolicyType.TwoFactorAuthentication);\n } else {\n this.showPolicyWarning = false;\n }\n }\n}\n","

{{'twoStepLogin' | i18n}}

{{'twoStepLoginDesc' | i18n}}

{{'twoStepLoginOrganizationDesc' | i18n}}

{{'twoStepLoginRecoveryWarning' | i18n}}

{{'providers' | i18n}} {{'loading' | i18n}}

{{'twoStepLoginPolicyUserWarning' | i18n}} ","import { Component } from '@angular/core';\nimport { FormBuilder } from '@angular/forms';\n\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { EventService } from 'jslib-common/abstractions/event.service';\nimport { ExportService } from 'jslib-common/abstractions/export.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { ExportComponent as BaseExportComponent } from 'jslib-angular/components/export.component';\n\n@Component({\n selector: 'app-export',\n templateUrl: 'export.component.html',\n})\nexport class ExportComponent extends BaseExportComponent {\n organizationId: string;\n\n constructor(cryptoService: CryptoService, i18nService: I18nService,\n platformUtilsService: PlatformUtilsService, exportService: ExportService,\n eventService: EventService, policyService: PolicyService, logService: LogService,\n userVerificationService: UserVerificationService, fb: FormBuilder) {\n super(cryptoService, i18nService, platformUtilsService, exportService, eventService,\n policyService, window, logService, userVerificationService, fb);\n }\n\n protected saved() {\n super.saved();\n this.platformUtilsService.showToast('success', null, this.i18nService.t('exportSuccess'));\n }\n}\n","

{{'exportVault' | i18n}}

{{'personalVaultExportPolicyInEffect' | i18n}}
","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { AuditService } from 'jslib-common/abstractions/audit.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\nimport { CipherType } from 'jslib-common/enums/cipherType';\n\nimport { CipherReportComponent } from './cipher-report.component';\n\n@Component({\n selector: 'app-exposed-passwords-report',\n templateUrl: 'exposed-passwords-report.component.html',\n})\nexport class ExposedPasswordsReportComponent extends CipherReportComponent implements OnInit {\n exposedPasswordMap = new Map();\n\n constructor(protected cipherService: CipherService, protected auditService: AuditService,\n modalService: ModalService, messagingService: MessagingService,\n userService: UserService, passwordRepromptService: PasswordRepromptService) {\n super(modalService, userService, messagingService, passwordRepromptService, true);\n }\n\n ngOnInit() {\n this.checkAccess();\n }\n\n async load() {\n if (await this.checkAccess()) {\n super.load();\n }\n }\n\n async setCiphers() {\n const allCiphers = await this.getAllCiphers();\n const exposedPasswordCiphers: CipherView[] = [];\n const promises: Promise[] = [];\n allCiphers.forEach(c => {\n if (c.type !== CipherType.Login || c.login.password == null || c.login.password === '' || c.isDeleted) {\n return;\n }\n const promise = this.auditService.passwordLeaked(c.login.password).then(exposedCount => {\n if (exposedCount > 0) {\n exposedPasswordCiphers.push(c);\n this.exposedPasswordMap.set(c.id, exposedCount);\n }\n });\n promises.push(promise);\n });\n await Promise.all(promises);\n this.ciphers = exposedPasswordCiphers;\n }\n\n protected getAllCiphers(): Promise {\n return this.cipherService.getAllDecrypted();\n }\n\n protected canManageCipher(c: CipherView): boolean {\n // this will only ever be false from the org view;\n return true;\n }\n}\n","

{{'exposedPasswordsReport' | i18n}}

{{'exposedPasswordsReportDesc' | i18n}}

{{'noExposedPasswords' | i18n}} {{'exposedPasswordsFoundDesc' | i18n : (ciphers.length | number)}}
{{c.name}} {{c.name}} {{'shared' | i18n}} {{'attachments' | i18n}}
{{c.subTitle}}
{{'exposedXTimes' | i18n : (exposedPasswordMap.get(c.id) | number)}}
","import { Component } from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { AuditService } from 'jslib-common/abstractions/audit.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { EventService } from 'jslib-common/abstractions/event.service';\nimport { FolderService } from 'jslib-common/abstractions/folder.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { TotpService } from 'jslib-common/abstractions/totp.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { CipherData } from 'jslib-common/models/data/cipherData';\nimport { Cipher } from 'jslib-common/models/domain/cipher';\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport { CipherCreateRequest } from 'jslib-common/models/request/cipherCreateRequest';\nimport { CipherRequest } from 'jslib-common/models/request/cipherRequest';\n\nimport { AddEditComponent as BaseAddEditComponent } from '../../vault/add-edit.component';\n\n@Component({\n selector: 'app-org-vault-add-edit',\n templateUrl: '../../vault/add-edit.component.html',\n})\nexport class AddEditComponent extends BaseAddEditComponent {\n organization: Organization;\n originalCipher: Cipher = null;\n\n constructor(cipherService: CipherService, folderService: FolderService,\n i18nService: I18nService, platformUtilsService: PlatformUtilsService,\n auditService: AuditService, stateService: StateService,\n userService: UserService, collectionService: CollectionService,\n totpService: TotpService, passwordGenerationService: PasswordGenerationService,\n private apiService: ApiService, messagingService: MessagingService,\n eventService: EventService, policyService: PolicyService, logService: LogService,\n passwordRepromptService: PasswordRepromptService) {\n super(cipherService, folderService, i18nService, platformUtilsService, auditService, stateService,\n userService, collectionService, totpService, passwordGenerationService, messagingService,\n eventService, policyService, passwordRepromptService, logService);\n }\n\n protected allowOwnershipAssignment() {\n if (this.ownershipOptions != null && (this.ownershipOptions.length > 1 || !this.allowPersonal)) {\n if (this.organization != null) {\n return this.cloneMode && this.organization.canEditAnyCollection;\n } else {\n return !this.editMode || this.cloneMode;\n }\n }\n return false;\n }\n\n protected loadCollections() {\n if (!this.organization.canEditAnyCollection) {\n return super.loadCollections();\n }\n return Promise.resolve(this.collections);\n }\n\n protected async loadCipher() {\n if (!this.organization.canEditAnyCollection) {\n return await super.loadCipher();\n }\n const response = await this.apiService.getCipherAdmin(this.cipherId);\n const data = new CipherData(response);\n this.originalCipher = new Cipher(data);\n return new Cipher(data);\n }\n\n protected encryptCipher() {\n if (!this.organization.canEditAnyCollection) {\n return super.encryptCipher();\n }\n return this.cipherService.encrypt(this.cipher, null, this.originalCipher);\n }\n\n protected async saveCipher(cipher: Cipher) {\n if (!this.organization.canEditAnyCollection || cipher.organizationId == null) {\n return super.saveCipher(cipher);\n }\n if (this.editMode && !this.cloneMode) {\n const request = new CipherRequest(cipher);\n return this.apiService.putCipherAdmin(this.cipherId, request);\n } else {\n const request = new CipherCreateRequest(cipher);\n return this.apiService.postCipherAdmin(request);\n }\n }\n\n protected async deleteCipher() {\n if (!this.organization.canEditAnyCollection) {\n return super.deleteCipher();\n }\n return this.cipher.isDeleted ? this.apiService.deleteCipherAdmin(this.cipherId)\n : this.apiService.putDeleteCipherAdmin(this.cipherId);\n }\n}\n","export type LinkedIdType = LoginLinkedId | CardLinkedId | IdentityLinkedId;\n\n// LoginView\nexport enum LoginLinkedId {\n Username = 100,\n Password = 101,\n}\n\n// CardView\nexport enum CardLinkedId {\n CardholderName = 300,\n ExpMonth = 301,\n ExpYear = 302,\n Code = 303,\n Brand = 304,\n Number = 305,\n}\n\n// IdentityView\nexport enum IdentityLinkedId {\n Title = 400,\n MiddleName = 401,\n Address1 = 402,\n Address2 = 403,\n Address3 = 404,\n City = 405,\n State = 406,\n PostalCode = 407,\n Country = 408,\n Company = 409,\n Email = 410,\n Phone = 411,\n Ssn = 412,\n Username = 413,\n PassportNumber = 414,\n LicenseNumber = 415,\n FirstName = 416,\n LastName = 417,\n FullName = 418,\n}\n","import { ItemView } from '../models/view/itemView';\n\nimport { LinkedIdType } from '../enums/linkedIdType';\n\nexport class LinkedMetadata {\n constructor(readonly propertyKey: string, private readonly _i18nKey?: string) { }\n\n get i18nKey() {\n return this._i18nKey ?? this.propertyKey;\n }\n}\n\n/**\n * A decorator used to set metadata used by Linked custom fields. Apply it to a class property or getter to make it\n * available as a Linked custom field option.\n * @param id - A unique value that is saved in the Field model. It is used to look up the decorated class property.\n * @param i18nKey - The i18n key used to describe the decorated class property in the UI. If it is null, then the name\n * of the class property will be used as the i18n key.\n */\nexport function linkedFieldOption(id: LinkedIdType, i18nKey?: string) {\n return (prototype: ItemView, propertyKey: string) => {\n if (prototype.linkedFieldOptions == null) {\n prototype.linkedFieldOptions = new Map();\n }\n\n prototype.linkedFieldOptions.set(id, new LinkedMetadata(propertyKey, i18nKey));\n };\n}\n","import { CardData } from '../data/cardData';\n\nimport Domain from './domainBase';\nimport { EncString } from './encString';\n\nimport { CardView } from '../view/cardView';\nimport { SymmetricCryptoKey } from './symmetricCryptoKey';\n\nexport class Card extends Domain {\n cardholderName: EncString;\n brand: EncString;\n number: EncString;\n expMonth: EncString;\n expYear: EncString;\n code: EncString;\n\n constructor(obj?: CardData, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.buildDomainModel(this, obj, {\n cardholderName: null,\n brand: null,\n number: null,\n expMonth: null,\n expYear: null,\n code: null,\n }, alreadyEncrypted, []);\n }\n\n decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise {\n return this.decryptObj(new CardView(this), {\n cardholderName: null,\n brand: null,\n number: null,\n expMonth: null,\n expYear: null,\n code: null,\n }, orgId, encKey);\n }\n\n toCardData(): CardData {\n const c = new CardData();\n this.buildDataModel(this, c, {\n cardholderName: null,\n brand: null,\n number: null,\n expMonth: null,\n expYear: null,\n code: null,\n });\n return c;\n }\n}\n","import { FieldType } from '../../enums/fieldType';\nimport { LinkedIdType } from '../../enums/linkedIdType';\n\nimport { FieldData } from '../data/fieldData';\n\nimport Domain from './domainBase';\nimport { EncString } from './encString';\n\nimport { FieldView } from '../view/fieldView';\nimport { SymmetricCryptoKey } from './symmetricCryptoKey';\n\nexport class Field extends Domain {\n name: EncString;\n value: EncString;\n type: FieldType;\n linkedId: LinkedIdType;\n\n constructor(obj?: FieldData, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.type = obj.type;\n this.linkedId = obj.linkedId;\n this.buildDomainModel(this, obj, {\n name: null,\n value: null,\n }, alreadyEncrypted, []);\n }\n\n decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise {\n return this.decryptObj(new FieldView(this), {\n name: null,\n value: null,\n }, orgId, encKey);\n }\n\n toFieldData(): FieldData {\n const f = new FieldData();\n this.buildDataModel(this, f, {\n name: null,\n value: null,\n type: null,\n linkedId: null,\n }, ['type', 'linkedId']);\n return f;\n }\n}\n","import { IdentityData } from '../data/identityData';\n\nimport Domain from './domainBase';\nimport { EncString } from './encString';\nimport { SymmetricCryptoKey } from './symmetricCryptoKey';\n\nimport { IdentityView } from '../view/identityView';\n\nexport class Identity extends Domain {\n title: EncString;\n firstName: EncString;\n middleName: EncString;\n lastName: EncString;\n address1: EncString;\n address2: EncString;\n address3: EncString;\n city: EncString;\n state: EncString;\n postalCode: EncString;\n country: EncString;\n company: EncString;\n email: EncString;\n phone: EncString;\n ssn: EncString;\n username: EncString;\n passportNumber: EncString;\n licenseNumber: EncString;\n\n constructor(obj?: IdentityData, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.buildDomainModel(this, obj, {\n title: null,\n firstName: null,\n middleName: null,\n lastName: null,\n address1: null,\n address2: null,\n address3: null,\n city: null,\n state: null,\n postalCode: null,\n country: null,\n company: null,\n email: null,\n phone: null,\n ssn: null,\n username: null,\n passportNumber: null,\n licenseNumber: null,\n }, alreadyEncrypted, []);\n }\n\n decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise {\n return this.decryptObj(new IdentityView(this), {\n title: null,\n firstName: null,\n middleName: null,\n lastName: null,\n address1: null,\n address2: null,\n address3: null,\n city: null,\n state: null,\n postalCode: null,\n country: null,\n company: null,\n email: null,\n phone: null,\n ssn: null,\n username: null,\n passportNumber: null,\n licenseNumber: null,\n }, orgId, encKey);\n }\n\n toIdentityData(): IdentityData {\n const i = new IdentityData();\n this.buildDataModel(this, i, {\n title: null,\n firstName: null,\n middleName: null,\n lastName: null,\n address1: null,\n address2: null,\n address3: null,\n city: null,\n state: null,\n postalCode: null,\n country: null,\n company: null,\n email: null,\n phone: null,\n ssn: null,\n username: null,\n passportNumber: null,\n licenseNumber: null,\n });\n return i;\n }\n}\n","import { LoginUri } from './loginUri';\n\nimport { LoginData } from '../data/loginData';\n\nimport { LoginView } from '../view/loginView';\n\nimport Domain from './domainBase';\nimport { EncString } from './encString';\nimport { SymmetricCryptoKey } from './symmetricCryptoKey';\n\nexport class Login extends Domain {\n uris: LoginUri[];\n username: EncString;\n password: EncString;\n passwordRevisionDate?: Date;\n totp: EncString;\n autofillOnPageLoad: boolean;\n\n constructor(obj?: LoginData, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.passwordRevisionDate = obj.passwordRevisionDate != null ? new Date(obj.passwordRevisionDate) : null;\n this.autofillOnPageLoad = obj.autofillOnPageLoad;\n this.buildDomainModel(this, obj, {\n username: null,\n password: null,\n totp: null,\n }, alreadyEncrypted, []);\n\n if (obj.uris) {\n this.uris = [];\n obj.uris.forEach(u => {\n this.uris.push(new LoginUri(u, alreadyEncrypted));\n });\n }\n }\n\n async decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise {\n const view = await this.decryptObj(new LoginView(this), {\n username: null,\n password: null,\n totp: null,\n }, orgId, encKey);\n\n if (this.uris != null) {\n view.uris = [];\n for (let i = 0; i < this.uris.length; i++) {\n const uri = await this.uris[i].decrypt(orgId, encKey);\n view.uris.push(uri);\n }\n }\n\n return view;\n }\n\n toLoginData(): LoginData {\n const l = new LoginData();\n l.passwordRevisionDate = this.passwordRevisionDate != null ? this.passwordRevisionDate.toISOString() : null;\n l.autofillOnPageLoad = this.autofillOnPageLoad;\n this.buildDataModel(this, l, {\n username: null,\n password: null,\n totp: null,\n });\n\n if (this.uris != null && this.uris.length > 0) {\n l.uris = [];\n this.uris.forEach(u => {\n l.uris.push(u.toLoginUriData());\n });\n }\n\n return l;\n }\n}\n","import { UriMatchType } from '../../enums/uriMatchType';\n\nimport { LoginUriData } from '../data/loginUriData';\n\nimport { LoginUriView } from '../view/loginUriView';\n\nimport Domain from './domainBase';\nimport { EncString } from './encString';\nimport { SymmetricCryptoKey } from './symmetricCryptoKey';\n\nexport class LoginUri extends Domain {\n uri: EncString;\n match: UriMatchType;\n\n constructor(obj?: LoginUriData, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.match = obj.match;\n this.buildDomainModel(this, obj, {\n uri: null,\n }, alreadyEncrypted, []);\n }\n\n decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise {\n return this.decryptObj(new LoginUriView(this), {\n uri: null,\n }, orgId, encKey);\n }\n\n toLoginUriData(): LoginUriData {\n const u = new LoginUriData();\n this.buildDataModel(this, u, {\n uri: null,\n }, ['match']);\n return u;\n }\n}\n","import { View } from './view';\n\nimport { Password } from '../domain/password';\n\nexport class PasswordHistoryView implements View {\n password: string = null;\n lastUsedDate: Date = null;\n\n constructor(ph?: Password) {\n if (!ph) {\n return;\n }\n\n this.lastUsedDate = ph.lastUsedDate;\n }\n}\n","import { SecureNoteType } from '../../enums/secureNoteType';\n\nimport { SecureNoteData } from '../data/secureNoteData';\n\nimport Domain from './domainBase';\n\nimport { SecureNoteView } from '../view/secureNoteView';\nimport { SymmetricCryptoKey } from './symmetricCryptoKey';\n\nexport class SecureNote extends Domain {\n type: SecureNoteType;\n\n constructor(obj?: SecureNoteData, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.type = obj.type;\n }\n\n decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise {\n return Promise.resolve(new SecureNoteView(this));\n }\n\n toSecureNoteData(): SecureNoteData {\n const n = new SecureNoteData();\n n.type = this.type;\n return n;\n }\n}\n","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { ImportOption, ImportService } from 'jslib-common/abstractions/import.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport Swal, { SweetAlertIcon } from 'sweetalert2';\n\n@Component({\n selector: 'app-import',\n templateUrl: 'import.component.html',\n})\nexport class ImportComponent implements OnInit {\n featuredImportOptions: ImportOption[];\n importOptions: ImportOption[];\n format: string = null;\n fileContents: string;\n formPromise: Promise;\n loading: boolean = false;\n importBlockedByPolicy: boolean = false;\n\n protected organizationId: string = null;\n protected successNavigate: any[] = ['vault'];\n\n constructor(protected i18nService: I18nService, protected toasterService: ToasterService,\n protected importService: ImportService, protected router: Router,\n protected platformUtilsService: PlatformUtilsService, protected policyService: PolicyService,\n private logService: LogService) { }\n\n async ngOnInit() {\n this.setImportOptions();\n this.importOptions.sort((a, b) => {\n if (a.name == null && b.name != null) {\n return -1;\n }\n if (a.name != null && b.name == null) {\n return 1;\n }\n if (a.name == null && b.name == null) {\n return 0;\n }\n\n return this.i18nService.collator ? this.i18nService.collator.compare(a.name, b.name) :\n a.name.localeCompare(b.name);\n });\n\n this.importBlockedByPolicy = await this.policyService.policyAppliesToUser(PolicyType.PersonalOwnership);\n }\n\n async submit() {\n if (this.importBlockedByPolicy) {\n this.platformUtilsService.showToast('error', null,\n this.i18nService.t('personalOwnershipPolicyInEffectImports'));\n return;\n }\n\n this.loading = true;\n\n const importer = this.importService.getImporter(this.format, this.organizationId);\n if (importer === null) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('selectFormat'));\n this.loading = false;\n return;\n }\n\n const fileEl = document.getElementById('file') as HTMLInputElement;\n const files = fileEl.files;\n if ((files == null || files.length === 0) && (this.fileContents == null || this.fileContents === '')) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('selectFile'));\n this.loading = false;\n return;\n }\n\n let fileContents = this.fileContents;\n if (files != null && files.length > 0) {\n try {\n const content = await this.getFileContents(files[0]);\n if (content != null) {\n fileContents = content;\n }\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n if (fileContents == null || fileContents === '') {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('selectFile'));\n this.loading = false;\n return;\n }\n\n try {\n this.formPromise = this.importService.import(importer, fileContents, this.organizationId);\n const error = await this.formPromise;\n if (error != null) {\n this.error(error);\n this.loading = false;\n return;\n }\n this.toasterService.popAsync('success', null, this.i18nService.t('importSuccess'));\n this.router.navigate(this.successNavigate);\n } catch (e) {\n this.logService.error(e);\n }\n\n this.loading = false;\n }\n\n getFormatInstructionTitle() {\n if (this.format == null) {\n return null;\n }\n\n const results = this.featuredImportOptions.concat(this.importOptions).filter(o => o.id === this.format);\n if (results.length > 0) {\n return this.i18nService.t('instructionsFor', results[0].name);\n }\n return null;\n }\n\n protected setImportOptions() {\n this.featuredImportOptions = [{\n id: null,\n name: '-- ' + this.i18nService.t('select') + ' --',\n }, ...this.importService.featuredImportOptions];\n this.importOptions = this.importService.regularImportOptions;\n }\n\n private async error(error: Error) {\n await Swal.fire({\n heightAuto: false,\n buttonsStyling: false,\n icon: 'error' as SweetAlertIcon,\n iconHtml: ``,\n input: 'textarea',\n inputValue: error.message,\n inputAttributes: {\n 'readonly': 'true',\n },\n titleText: this.i18nService.t('importError'),\n text: this.i18nService.t('importErrorDesc'),\n showConfirmButton: true,\n confirmButtonText: this.i18nService.t('ok'),\n onOpen: popupEl => {\n popupEl.querySelector('.swal2-textarea').scrollTo(0, 0);\n },\n });\n }\n\n private getFileContents(file: File): Promise {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.readAsText(file, 'utf-8');\n reader.onload = evt => {\n if (this.format === 'lastpasscsv' && file.type === 'text/html') {\n const parser = new DOMParser();\n const doc = parser.parseFromString((evt.target as any).result, 'text/html');\n const pre = doc.querySelector('pre');\n if (pre != null) {\n resolve(pre.textContent);\n return;\n }\n reject();\n return;\n }\n\n resolve((evt.target as any).result);\n };\n reader.onerror = () => {\n reject();\n };\n });\n }\n}\n","

{{'importData' | i18n}}

{{'personalOwnershipPolicyInEffectImports' | i18n}}
See detailed instructions on our help site at https://help.bitwarden.com/article/export-your-data/ See detailed instructions on our help site at https://help.bitwarden.com/article/import-from-lastpass/ Using the KeePassX desktop application, navigate to \"Database\" → \"Export to CSV file\" and save the CSV file. In the Avira web vault, go to \"Settings\" → \"My Data\" → \"Export data\" and save the CSV file. In the Blur web vault, click your username at the top and go to \"Settings\" → \"Export Data\", then click \"Export CSV\" for your \"Accounts\". Using the SaveInCloud desktop application, navigate to \"File\" → \"Export\" → \"As XML\" and save the XML file. Using the Padlock desktop application, click the hamburger icon in the top left corner and navigate to \"Settings\" → \"Export\" button and save the file \"As CSV\". Using the KeePass 2 desktop application, navigate to \"File\" → \"Export\" and select the \"KeePass XML (2.x)\" option. Using the Universal Password Manager desktop application, navigate to \"Database\" → \"Export\" and save the CSV file. Using the SaferPass browser extension, click the hamburger icon in the top left corner and navigate to \"Settings\". Click the \"Export accounts\" button to save the CSV file. Using the Meldium web vault, navigate to \"Settings\". Locate the \"Export data\" function and click \"Show me my data\" to save the CSV file. Log into the Keeper web vault (keepersecurity.com/vault). Navigate to \"Backup\" (top right) and find the \"Export to .csv File\" option. Click \"Export Now\" to save the CSV file. The process is exactly the same as importing from Google Chrome. See detailed instructions on our help site at https://help.bitwarden.com/article/import-from-chrome/ See detailed instructions on our help site at https://bitwarden.com/help/article/import-from-firefox/. See detailed instructions on our help site at https://bitwarden.com/help/article/import-from-safari/. See detailed instructions on our help site at https://help.bitwarden.com/article/import-from-1password/. Using the Password Dragon desktop application, navigate to \"File\" → \"Export\" → \"To XML\". In the dialog that pops up select \"All Rows\" and check all fields. Click the \"Export\" button and save the XML file. Using the Enpass desktop application, navigate to \"File\" → \"Export\" → \"As CSV\". Select \"OK\" to the warning alert and save the CSV file. Note that the importer only supports files exported while Enpass is set to the English language, so adjust your settings accordingly. Using the Enpass 6 desktop application, click the menu button and navigate to \"File\" → \"Export\". Select the \".json\" file format option and save the JSON file. Using the Password Safe desktop application, navigate to \"File\" → \"Export To\" → \"XML format...\" and save the XML file. Using the Dashlane desktop application, navigate to \"File\" → \"Export\" → \"Unsecured archive (readable) in JSON format\" and save the JSON file. Using the mSecure desktop application, navigate to \"File\" → \"Export\" → \"CSV File...\" and save the CSV file. Using the Sticky Password desktop application, navigate to \"Menu\" (top right) → \"Export\" → \"Export all\". Select the unencrypted format XML option and save the XML file. Using the True Key desktop application, click the gear icon (top right) and then navigate to \"App Settings\". Click the \"Export\" button, enter your password and save the CSV file. Log into the Clipperz web application (clipperz.is/app). Click the hamburger menu icon in the top right to expand the navigation bar. Navigate to \"Data\" → \"Export\". Click the \"download HTML+JSON\" button to save the HTML file. Using the RoboForm Editor desktop application, navigate to \"RoboForm\" (top left) → \"Options\" → \"Account & Data\" and click the \"Export\" button. Select all of your data, change the \"Format\" to \"CSV file\" and then click the \"Export\" button to save the CSV file. Note: RoboForm only allows you to export Logins. Other items will not be exported. Log into the Passbolt web vault and navigate to the \"Passwords\" listing. Select all of the passwords you would like to export and click the \"Export\" button at the top of the listing. Choose the \"csv (lastpass)\" export format and click the \"Export\" button. Using the Ascendo DataVault desktop application, navigate to \"Tools\" → \"Export\". In the dialog that pops up, select the \"All Items (DVX, CSV)\" option. Click the \"Ok\" button to save the CSV file. Using the Password Boss desktop application, navigate to \"File\" → \"Export data\" → \"Password Boss JSON - not encrypted\" and save the JSON file. Log into the Zoho web vault (vault.zoho.com). Navigate to \"Tools\" → \"Export Secrets\". Select \"All Secrets\" and click the \"Zoho Vault Format CSV\" button. Highlight and copy the data from the textarea. Open a text editor like Notepad and paste the data. Save the data from the text editor as zoho_export.csv. Using the SplashID Safe desktop application, click on the SplashID blue lock logo in the top right corner. Navigate to \"Export\" → \"Export as CSV\" and save the CSV file. Using the PassKeep mobile app, navigate to \"Backup/Restore\". Locate the \"CSV Backup/Restore\" section and click \"Backup to CSV\" to save the CSV file. Make sure you have python-keyring and python-gnomekeyring installed. Save the GNOME Keyring Import/Export python script to your desktop as pw_helper.py. Open terminal and run chmod +rx Desktop/pw_helper.py and then python Desktop/pw_helper.py export Desktop/my_passwords.json. Then upload the resulting my_passwords.json file here to Bitwarden. Using the Password Agent desktop application navigate to \"File\" → \"Export\", select the \"Fields to export\" button and check all of the fields, change the \"Output format\" to \"CSV\", and then click the \"Start\" button to save the CSV file. Log into the Passpack website vault and navigate to \"Settings\" → \"Export\", then click the \"Download\" button to save the CSV file. Open your Passman vault and click on \"Settings\" in the bottom left corner. In the \"Settings\" window switch to the \"Export credentials\" tab and choose \"JSON\" as the export type. Enter your vault's passphrase and click the \"Export\" button to save the JSON file. Open the Avast Passwords desktop application and navigate to \"Settings\" → \"Import/export data\". Select the \"Export\" button for the \"Export to CSV file\" option to save the CSV file. Open the Avast Passwords desktop application and navigate to \"Settings\" → \"Import/export data\". Select the \"Export\" button for the \"Export to JSON file\" option to save the JSON file. Open the F-Secure KEY desktop application and navigate to \"Settings\" → \"Export Passwords\". Select the \"Export\" button, enter your master password, and save the FSK file. Open the Kaspersky Password Manager desktop application and navigate to \"Settings\" → \"Import/Export\". Locate the \"Export to text file\" section and select the \"Export\" button to save the TXT file. Open the RememBear desktop application and navigate to \"Settings\" → \"Account\" → \"Export\". Enter your master password and select the \"Export Anyway\" button to save the CSV file. Open the PasswordWallet desktop application and navigate to \"File\" → \"Export\" → \"Visible entries to text file\". Enter your password and select the \"Ok\" button to save the TXT file. Open the Myki desktop browser extension and navigate to \"Advanced\" → \"Export Accounts\" and then scan the QR code with your mobile device. Various CSV files will then be saved to your computer's downloads folder. Export your SecureSafe password safe to a CSV file with a comma delimiter. Open the LogMeOnce browser extension, then navigate to \"Open Menu\" → \"Export To\" and select \"CSV File\" to save the CSV file. Open the BlackBerry Password Keeper application, then navigate to \"Settings\" → \"Import/Export\". Select \"Export Passwords\" and follow the instructions on screen to save the unencrypted CSV file. Open the Buttercup desktop application and unlock your vault. Right click on your vault's icon and select \"Export\" to save the CSV file. Open the Codebook desktop application and log in. Navigate to \"File\" → \"Export all\", then click \"Yes\" on the dialog and save the CSV file. Open the newest version of the Encryptr desktop application and allow all of your data to sync. Once syncing of your data is complete, the download icon in the top right corner will turn pink. Click the download icon and save the CSV file. From the Yoti browser extension, click on \"Settings\", then \"Export Saved Logins\" and save the CSV file.
","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\nimport { CipherType } from 'jslib-common/enums/cipherType';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\nimport { CipherReportComponent } from './cipher-report.component';\n\n@Component({\n selector: 'app-inactive-two-factor-report',\n templateUrl: 'inactive-two-factor-report.component.html',\n})\nexport class InactiveTwoFactorReportComponent extends CipherReportComponent implements OnInit {\n services = new Map();\n cipherDocs = new Map();\n\n constructor(protected cipherService: CipherService, modalService: ModalService,\n messagingService: MessagingService, userService: UserService, private logService: LogService,\n passwordRepromptService: PasswordRepromptService) {\n super(modalService, userService, messagingService, passwordRepromptService, true);\n }\n\n async ngOnInit() {\n if (await this.checkAccess()) {\n await super.load();\n }\n }\n\n async setCiphers() {\n try {\n await this.load2fa();\n } catch (e) {\n this.logService.error(e);\n }\n\n if (this.services.size > 0) {\n const allCiphers = await this.getAllCiphers();\n const inactive2faCiphers: CipherView[] = [];\n const promises: Promise[] = [];\n const docs = new Map();\n allCiphers.forEach(c => {\n if (c.type !== CipherType.Login || (c.login.totp != null && c.login.totp !== '') || !c.login.hasUris ||\n c.isDeleted) {\n return;\n }\n for (let i = 0; i < c.login.uris.length; i++) {\n const u = c.login.uris[i];\n if (u.uri != null && u.uri !== '') {\n const hostname = Utils.getHostname(u.uri);\n if (hostname != null && this.services.has(hostname)) {\n if (this.services.get(hostname) != null) {\n docs.set(c.id, this.services.get(hostname));\n }\n inactive2faCiphers.push(c);\n break;\n }\n }\n }\n });\n await Promise.all(promises);\n this.ciphers = inactive2faCiphers;\n this.cipherDocs = docs;\n }\n }\n\n protected getAllCiphers(): Promise {\n return this.cipherService.getAllDecrypted();\n }\n\n private async load2fa() {\n if (this.services.size > 0) {\n return;\n }\n const response = await fetch(new Request('https://2fa.directory/api/v2/totp.json'));\n if (response.status !== 200) {\n throw new Error();\n }\n const responseJson = await response.json();\n for (const categoryName in responseJson) {\n if (responseJson.hasOwnProperty(categoryName)) {\n const category = responseJson[categoryName];\n for (const serviceName in category) {\n if (category.hasOwnProperty(serviceName)) {\n const service = category[serviceName];\n if (service.url != null) {\n const hostname = Utils.getHostname(service.url);\n if (hostname != null) {\n this.services.set(hostname, service.doc);\n }\n }\n }\n }\n }\n }\n }\n}\n","

{{'inactive2faReport' | i18n}} {{'loading' | i18n}}

{{'inactive2faReportDesc' | i18n}}

{{'loading' | i18n}}
{{'noInactive2fa' | i18n}} {{'inactive2faFoundDesc' | i18n : (ciphers.length | number)}}
{{c.name}} {{'shared' | i18n}} {{'attachments' | i18n}}
{{c.subTitle}}
{{'instructions' | i18n}}
","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\nimport { CipherType } from 'jslib-common/enums/cipherType';\n\nimport { CipherReportComponent } from './cipher-report.component';\n\n@Component({\n selector: 'app-reused-passwords-report',\n templateUrl: 'reused-passwords-report.component.html',\n})\nexport class ReusedPasswordsReportComponent extends CipherReportComponent implements OnInit {\n passwordUseMap: Map;\n\n constructor(protected cipherService: CipherService, modalService: ModalService,\n messagingService: MessagingService, userService: UserService,\n passwordRepromptService: PasswordRepromptService) {\n super(modalService, userService, messagingService, passwordRepromptService, true);\n }\n\n async ngOnInit() {\n if (await this.checkAccess()) {\n await super.load();\n }\n }\n\n async setCiphers() {\n const allCiphers = await this.getAllCiphers();\n const ciphersWithPasswords: CipherView[] = [];\n this.passwordUseMap = new Map();\n allCiphers.forEach(c => {\n if (c.type !== CipherType.Login || c.login.password == null || c.login.password === '' || c.isDeleted) {\n return;\n }\n ciphersWithPasswords.push(c);\n if (this.passwordUseMap.has(c.login.password)) {\n this.passwordUseMap.set(c.login.password, this.passwordUseMap.get(c.login.password) + 1);\n } else {\n this.passwordUseMap.set(c.login.password, 1);\n }\n });\n const reusedPasswordCiphers = ciphersWithPasswords.filter(c =>\n this.passwordUseMap.has(c.login.password) && this.passwordUseMap.get(c.login.password) > 1);\n this.ciphers = reusedPasswordCiphers;\n }\n\n protected getAllCiphers(): Promise {\n return this.cipherService.getAllDecrypted();\n }\n\n protected canManageCipher(c: CipherView): boolean {\n // this will only ever be false from an organization view\n return true;\n }\n}\n","

{{'reusedPasswordsReport' | i18n}} {{'loading' | i18n}}

{{'reusedPasswordsReportDesc' | i18n}}

{{'loading' | i18n}}
{{'noReusedPasswords' | i18n}} {{'reusedPasswordsFoundDesc' | i18n : (ciphers.length | number)}}
{{c.name}} {{c.name}} {{'shared' | i18n}} {{'attachments' | i18n}}
{{c.subTitle}}
{{'reusedXTimes' | i18n : passwordUseMap.get(c.login.password)}}
","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { CipherType } from 'jslib-common/enums/cipherType';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\nimport { CipherReportComponent } from './cipher-report.component';\n\n@Component({\n selector: 'app-unsecured-websites-report',\n templateUrl: 'unsecured-websites-report.component.html',\n})\nexport class UnsecuredWebsitesReportComponent extends CipherReportComponent implements OnInit {\n constructor(protected cipherService: CipherService, modalService: ModalService,\n messagingService: MessagingService, userService: UserService, passwordRepromptService: PasswordRepromptService) {\n super(modalService, userService, messagingService, passwordRepromptService, true);\n }\n\n async ngOnInit() {\n if (await this.checkAccess()) {\n await super.load();\n }\n }\n\n async setCiphers() {\n const allCiphers = await this.getAllCiphers();\n const unsecuredCiphers = allCiphers.filter(c => {\n if (c.type !== CipherType.Login || !c.login.hasUris || c.isDeleted) {\n return false;\n }\n return c.login.uris.some(u => u.uri != null && u.uri.indexOf('http://') === 0);\n });\n this.ciphers = unsecuredCiphers;\n }\n\n protected getAllCiphers(): Promise {\n return this.cipherService.getAllDecrypted();\n }\n}\n","

{{'unsecuredWebsitesReport' | i18n}} {{'loading' | i18n}}

{{'unsecuredWebsitesReportDesc' | i18n}}

{{'loading' | i18n}}
{{'noUnsecuredWebsites' | i18n}} {{'unsecuredWebsitesFoundDesc' | i18n : (ciphers.length | number)}}
{{c.name}} {{'shared' | i18n}} {{'attachments' | i18n}}
{{c.subTitle}}
","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\nimport { CipherType } from 'jslib-common/enums/cipherType';\n\nimport { CipherReportComponent } from './cipher-report.component';\n\n@Component({\n selector: 'app-weak-passwords-report',\n templateUrl: 'weak-passwords-report.component.html',\n})\nexport class WeakPasswordsReportComponent extends CipherReportComponent implements OnInit {\n\n passwordStrengthMap = new Map();\n\n private passwordStrengthCache = new Map();\n\n constructor(protected cipherService: CipherService, protected passwordGenerationService: PasswordGenerationService,\n modalService: ModalService, messagingService: MessagingService, userService: UserService,\n passwordRepromptService: PasswordRepromptService) {\n super(modalService, userService, messagingService, passwordRepromptService, true);\n }\n\n async ngOnInit() {\n if (await this.checkAccess()) {\n await super.load();\n }\n }\n\n async setCiphers() {\n const allCiphers = await this.getAllCiphers();\n const weakPasswordCiphers: CipherView[] = [];\n const isUserNameNotEmpty = (c: CipherView): boolean => {\n return c.login.username != null && c.login.username.trim() !== '';\n };\n const getCacheKey = (c: CipherView): string => {\n return c.login.password + '_____' + (isUserNameNotEmpty(c) ? c.login.username : '');\n };\n\n allCiphers.forEach(c => {\n if (c.type !== CipherType.Login || c.login.password == null || c.login.password === '' || c.isDeleted) {\n return;\n }\n const hasUserName = isUserNameNotEmpty(c);\n const cacheKey = getCacheKey(c);\n if (!this.passwordStrengthCache.has(cacheKey)) {\n let userInput: string[] = [];\n if (hasUserName) {\n const atPosition = c.login.username.indexOf('@');\n if (atPosition > -1) {\n userInput = userInput.concat(\n c.login.username.substr(0, atPosition).trim().toLowerCase().split(/[^A-Za-z0-9]/))\n .filter(i => i.length >= 3);\n } else {\n userInput = c.login.username.trim().toLowerCase().split(/[^A-Za-z0-9]/)\n .filter(i => i.length >= 3);\n }\n }\n const result = this.passwordGenerationService.passwordStrength(c.login.password,\n userInput.length > 0 ? userInput : null);\n this.passwordStrengthCache.set(cacheKey, result.score);\n }\n const score = this.passwordStrengthCache.get(cacheKey);\n if (score != null && score <= 2) {\n this.passwordStrengthMap.set(c.id, this.scoreKey(score));\n weakPasswordCiphers.push(c);\n }\n });\n weakPasswordCiphers.sort((a, b) => {\n return this.passwordStrengthCache.get(getCacheKey(a)) -\n this.passwordStrengthCache.get(getCacheKey(b));\n });\n this.ciphers = weakPasswordCiphers;\n }\n\n protected getAllCiphers(): Promise {\n return this.cipherService.getAllDecrypted();\n }\n\n protected canManageCipher(c: CipherView): boolean {\n // this will only ever be false from the org view;\n return true;\n }\n\n private scoreKey(score: number): [string, string] {\n switch (score) {\n case 4:\n return ['strong', 'success'];\n case 3:\n return ['good', 'primary'];\n case 2:\n return ['weak', 'warning'];\n default:\n return ['veryWeak', 'danger'];\n }\n }\n}\n","

{{'weakPasswordsReport' | i18n}} {{'loading' | i18n}}

{{'weakPasswordsReportDesc' | i18n}}

{{'loading' | i18n}}
{{'noWeakPasswords' | i18n}} {{'weakPasswordsFoundDesc' | i18n : (ciphers.length | number)}}
{{c.name}} {{c.name}} {{'shared' | i18n}} {{'attachments' | i18n}}
{{c.subTitle}}
{{passwordStrengthMap.get(c.id)[0] | i18n}}
","import { Component } from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { AttachmentView } from 'jslib-common/models/view/attachmentView';\n\nimport { AttachmentsComponent as BaseAttachmentsComponent } from 'jslib-angular/components/attachments.component';\n\n@Component({\n selector: 'app-vault-attachments',\n templateUrl: 'attachments.component.html',\n})\nexport class AttachmentsComponent extends BaseAttachmentsComponent {\n viewOnly = false;\n\n constructor(cipherService: CipherService, i18nService: I18nService,\n cryptoService: CryptoService, userService: UserService,\n platformUtilsService: PlatformUtilsService, apiService: ApiService,\n logService: LogService) {\n super(cipherService, i18nService, cryptoService, userService, platformUtilsService, apiService, window,\n logService);\n }\n\n protected async reupload(attachment: AttachmentView) {\n if (this.showFixOldAttachments(attachment)) {\n await this.reuploadCipherAttachment(attachment, false);\n }\n }\n\n protected showFixOldAttachments(attachment: AttachmentView) {\n return attachment.key == null && this.cipher.organizationId == null;\n }\n}\n","

{{'attachments' | i18n}} {{cipher.name}}

{{a.sizeName}}

{{'newAttachment' | i18n}}

{{'maxFileSize' | i18n}}
","import {\n Component,\n EventEmitter,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { EventService } from 'jslib-common/abstractions/event.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { SearchService } from 'jslib-common/abstractions/search.service';\nimport { TotpService } from 'jslib-common/abstractions/totp.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\nimport { CiphersComponent as BaseCiphersComponent } from '../../vault/ciphers.component';\n\n@Component({\n selector: 'app-org-vault-ciphers',\n templateUrl: '../../vault/ciphers.component.html',\n})\nexport class CiphersComponent extends BaseCiphersComponent {\n @Output() onEventsClicked = new EventEmitter();\n\n organization: Organization;\n accessEvents = false;\n\n protected allCiphers: CipherView[] = [];\n\n constructor(searchService: SearchService, toasterService: ToasterService, i18nService: I18nService,\n platformUtilsService: PlatformUtilsService, cipherService: CipherService,\n private apiService: ApiService, eventService: EventService, totpService: TotpService,\n userService: UserService, passwordRepromptService: PasswordRepromptService,\n logService: LogService) {\n super(searchService, toasterService, i18nService, platformUtilsService, cipherService,\n eventService, totpService, userService, passwordRepromptService, logService);\n }\n\n async load(filter: (cipher: CipherView) => boolean = null) {\n if (this.organization.canEditAnyCollection) {\n this.accessEvents = this.organization.useEvents;\n this.allCiphers = await this.cipherService.getAllFromApiForOrganization(this.organization.id);\n } else {\n this.allCiphers = (await this.cipherService.getAllDecrypted()).filter(c => c.organizationId === this.organization.id);\n }\n await this.searchService.indexCiphers(this.organization.id, this.allCiphers);\n await this.applyFilter(filter);\n this.loaded = true;\n }\n\n async applyFilter(filter: (cipher: CipherView) => boolean = null) {\n if (this.organization.canViewAllCollections) {\n await super.applyFilter(filter);\n } else {\n const f = (c: CipherView) => c.organizationId === this.organization.id && (filter == null || filter(c));\n await super.applyFilter(f);\n }\n }\n\n async search(timeout: number = null) {\n await super.search(timeout, this.allCiphers);\n }\n events(c: CipherView) {\n this.onEventsClicked.emit(c);\n }\n\n protected deleteCipher(id: string) {\n if (!this.organization.canEditAnyCollection) {\n return super.deleteCipher(id, this.deleted);\n }\n return this.deleted ? this.apiService.deleteCipherAdmin(id) : this.apiService.putDeleteCipherAdmin(id);\n }\n\n protected showFixOldAttachments(c: CipherView) {\n return this.organization.canEditAnyCollection && c.hasOldAttachments;\n }\n}\n","import {\n Component,\n OnDestroy,\n} from '@angular/core';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { CollectionView } from 'jslib-common/models/view/collectionView';\n\nimport { CollectionsComponent as BaseCollectionsComponent } from 'jslib-angular/components/collections.component';\n\n@Component({\n selector: 'app-vault-collections',\n templateUrl: 'collections.component.html',\n})\nexport class CollectionsComponent extends BaseCollectionsComponent implements OnDestroy {\n constructor(collectionService: CollectionService, platformUtilsService: PlatformUtilsService,\n i18nService: I18nService, cipherService: CipherService, logService: LogService) {\n super(collectionService, platformUtilsService, i18nService, cipherService, logService);\n }\n\n ngOnDestroy() {\n this.selectAll(false);\n }\n\n check(c: CollectionView, select?: boolean) {\n (c as any).checked = select == null ? !(c as any).checked : select;\n }\n\n selectAll(select: boolean) {\n this.collections.forEach(c => this.check(c, select));\n }\n}\n","

{{'collections' | i18n}} {{cipher.name}}

{{'collectionsDesc' | i18n}}

{{'collections' | i18n}}

{{'noCollectionsInList' | i18n}}
{{c.name}}
","import { Component } from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { FolderService } from 'jslib-common/abstractions/folder.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { CollectionData } from 'jslib-common/models/data/collectionData';\nimport { Collection } from 'jslib-common/models/domain/collection';\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport { CollectionDetailsResponse } from 'jslib-common/models/response/collectionResponse';\nimport { CollectionView } from 'jslib-common/models/view/collectionView';\n\nimport { GroupingsComponent as BaseGroupingsComponent } from '../../vault/groupings.component';\n\n@Component({\n selector: 'app-org-vault-groupings',\n templateUrl: '../../vault/groupings.component.html',\n})\nexport class GroupingsComponent extends BaseGroupingsComponent {\n organization: Organization;\n\n constructor(collectionService: CollectionService, folderService: FolderService,\n storageService: StorageService, userService: UserService,\n private apiService: ApiService, private i18nService: I18nService) {\n super(collectionService, folderService, storageService, userService);\n }\n\n async loadCollections() {\n if (!this.organization.canEditAnyCollection) {\n await super.loadCollections(this.organization.id);\n return;\n }\n\n const collections = await this.apiService.getCollections(this.organization.id);\n if (collections != null && collections.data != null && collections.data.length) {\n const collectionDomains = collections.data.map(r =>\n new Collection(new CollectionData(r as CollectionDetailsResponse)));\n this.collections = await this.collectionService.decryptMany(collectionDomains);\n } else {\n this.collections = [];\n }\n\n const unassignedCollection = new CollectionView();\n unassignedCollection.name = this.i18nService.t('unassigned');\n unassignedCollection.id = 'unassigned';\n unassignedCollection.organizationId = this.organization.id;\n unassignedCollection.readOnly = true;\n this.collections.push(unassignedCollection);\n this.nestedCollections = await this.collectionService.getAllNested(this.collections);\n }\n\n collapse(grouping: CollectionView) {\n super.collapse(grouping, 'org_');\n }\n\n isCollapsed(grouping: CollectionView) {\n return super.isCollapsed(grouping, 'org_');\n }\n}\n","import {\n Component,\n Input,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport { ToasterService } from 'angular2-toaster';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { CipherRepromptType } from 'jslib-common/enums/cipherRepromptType';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\n\nimport { BulkDeleteComponent } from './bulk-delete.component';\nimport { BulkMoveComponent } from './bulk-move.component';\nimport { BulkRestoreComponent } from './bulk-restore.component';\nimport { BulkShareComponent } from './bulk-share.component';\nimport { CiphersComponent } from './ciphers.component';\n\n@Component({\n selector: 'app-vault-bulk-actions',\n templateUrl: 'bulk-actions.component.html',\n})\nexport class BulkActionsComponent {\n @Input() ciphersComponent: CiphersComponent;\n @Input() deleted: boolean;\n @Input() organization: Organization;\n\n @ViewChild('bulkDeleteTemplate', { read: ViewContainerRef, static: true }) bulkDeleteModalRef: ViewContainerRef;\n @ViewChild('bulkRestoreTemplate', { read: ViewContainerRef, static: true }) bulkRestoreModalRef: ViewContainerRef;\n @ViewChild('bulkMoveTemplate', { read: ViewContainerRef, static: true }) bulkMoveModalRef: ViewContainerRef;\n @ViewChild('bulkShareTemplate', { read: ViewContainerRef, static: true }) bulkShareModalRef: ViewContainerRef;\n\n constructor(private toasterService: ToasterService, private i18nService: I18nService,\n private modalService: ModalService, private passwordRepromptService: PasswordRepromptService) { }\n\n async bulkDelete() {\n if (!await this.promptPassword()) {\n return;\n }\n\n const selectedIds = this.ciphersComponent.getSelectedIds();\n if (selectedIds.length === 0) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('nothingSelected'));\n return;\n }\n\n const [modal] = await this.modalService.openViewRef(BulkDeleteComponent, this.bulkDeleteModalRef, comp => {\n comp.permanent = this.deleted;\n comp.cipherIds = selectedIds;\n comp.organization = this.organization;\n comp.onDeleted.subscribe(async () => {\n modal.close();\n await this.ciphersComponent.refresh();\n });\n });\n }\n\n async bulkRestore() {\n if (!await this.promptPassword()) {\n return;\n }\n\n const selectedIds = this.ciphersComponent.getSelectedIds();\n if (selectedIds.length === 0) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('nothingSelected'));\n return;\n }\n\n const [modal] = await this.modalService.openViewRef(BulkRestoreComponent, this.bulkRestoreModalRef, comp => {\n comp.cipherIds = selectedIds;\n comp.onRestored.subscribe(async () => {\n modal.close();\n await this.ciphersComponent.refresh();\n });\n });\n }\n\n async bulkShare() {\n if (!await this.promptPassword()) {\n return;\n }\n\n const selectedCiphers = this.ciphersComponent.getSelected();\n if (selectedCiphers.length === 0) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('nothingSelected'));\n return;\n }\n\n const [modal] = await this.modalService.openViewRef(BulkShareComponent, this.bulkShareModalRef, comp => {\n comp.ciphers = selectedCiphers;\n comp.onShared.subscribe(async () => {\n modal.close();\n await this.ciphersComponent.refresh();\n });\n });\n }\n\n async bulkMove() {\n if (!await this.promptPassword()) {\n return;\n }\n\n const selectedIds = this.ciphersComponent.getSelectedIds();\n if (selectedIds.length === 0) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('nothingSelected'));\n return;\n }\n\n const [modal] = await this.modalService.openViewRef(BulkMoveComponent, this.bulkMoveModalRef, comp => {\n comp.cipherIds = selectedIds;\n comp.onMoved.subscribe(async () => {\n modal.close();\n await this.ciphersComponent.refresh();\n });\n });\n }\n\n selectAll(select: boolean) {\n this.ciphersComponent.selectAll(select);\n }\n\n private async promptPassword() {\n const selectedCiphers = this.ciphersComponent.getSelected();\n const notProtected = !selectedCiphers.find(cipher => cipher.reprompt !== CipherRepromptType.None);\n\n return notProtected || await this.passwordRepromptService.showPasswordPrompt();\n }\n}\n","
","import Domain from './domainBase';\nimport { EncString } from './encString';\nimport { SymmetricCryptoKey } from './symmetricCryptoKey';\n\nimport { SendFileData } from '../data/sendFileData';\n\nimport { SendFileView } from '../view/sendFileView';\n\nexport class SendFile extends Domain {\n id: string;\n size: string;\n sizeName: string;\n fileName: EncString;\n\n constructor(obj?: SendFileData, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.size = obj.size;\n this.buildDomainModel(this, obj, {\n id: null,\n sizeName: null,\n fileName: null,\n }, alreadyEncrypted, ['id', 'sizeName']);\n }\n\n async decrypt(key: SymmetricCryptoKey): Promise {\n const view = await this.decryptObj(new SendFileView(this), {\n fileName: null,\n }, null, key);\n return view;\n }\n}\n","import Domain from './domainBase';\nimport { EncString } from './encString';\nimport { SymmetricCryptoKey } from './symmetricCryptoKey';\n\nimport { SendTextData } from '../data/sendTextData';\n\nimport { SendTextView } from '../view/sendTextView';\n\nexport class SendText extends Domain {\n text: EncString;\n hidden: boolean;\n\n constructor(obj?: SendTextData, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.hidden = obj.hidden;\n this.buildDomainModel(this, obj, {\n text: null,\n }, alreadyEncrypted, []);\n }\n\n decrypt(key: SymmetricCryptoKey): Promise {\n return this.decryptObj(new SendTextView(this), {\n text: null,\n }, null, key);\n }\n}\n","import { CipherRequest } from './cipherRequest';\n\nimport { Cipher } from '../domain/cipher';\n\nexport class CipherWithIdRequest extends CipherRequest {\n id: string;\n\n constructor(cipher: Cipher) {\n super(cipher);\n this.id = cipher.id;\n }\n}\n","import { Folder } from '../domain/folder';\n\nexport class FolderRequest {\n name: string;\n\n constructor(folder: Folder) {\n this.name = folder.name ? folder.name.encryptedString : null;\n }\n}\n","import { BaseResponse } from '../response/baseResponse';\n\nexport class SendFileApi extends BaseResponse {\n id: string;\n fileName: string;\n key: string;\n size: string;\n sizeName: string;\n\n constructor(data: any = null) {\n super(data);\n if (data == null) {\n return;\n }\n this.id = this.getResponseProperty('Id');\n this.fileName = this.getResponseProperty('FileName');\n this.key = this.getResponseProperty('Key');\n this.size = this.getResponseProperty('Size');\n this.sizeName = this.getResponseProperty('SizeName');\n }\n}\n","import { BaseResponse } from '../response/baseResponse';\n\nexport class SendTextApi extends BaseResponse {\n text: string;\n hidden: boolean;\n\n constructor(data: any = null) {\n super(data);\n if (data == null) {\n return;\n }\n this.text = this.getResponseProperty('Text');\n this.hidden = this.getResponseProperty('Hidden') || false;\n }\n}\n","import {\n Directive,\n ElementRef,\n HostListener,\n} from '@angular/core';\n\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\n@Directive({\n selector: '[appSelectCopy]',\n})\nexport class SelectCopyDirective {\n constructor(private el: ElementRef, private platformUtilsService: PlatformUtilsService) { }\n\n @HostListener('copy') onCopy() {\n if (window == null) {\n return;\n }\n let copyText = '';\n const selection = window.getSelection();\n for (let i = 0; i < selection.rangeCount; i++) {\n const range = selection.getRangeAt(i);\n const text = range.toString();\n\n // The selection should only contain one line of text. In some cases however, the\n // selection contains newlines and space characters from the indentation of following\n // sibling nodes. To avoid copying passwords containing trailing newlines and spaces\n // that aren't part of the password, the selection has to be trimmed.\n let stringEndPos = text.length;\n const newLinePos = text.search(/(?:\\r\\n|\\r|\\n)/);\n if (newLinePos > -1) {\n const otherPart = text.substr(newLinePos).trim();\n if (otherPart === '') {\n stringEndPos = newLinePos;\n }\n }\n copyText += text.substring(0, stringEndPos);\n }\n this.platformUtilsService.copyToClipboard(copyText, { window: window });\n }\n}\n","import {\n Pipe,\n PipeTransform,\n} from '@angular/core';\nimport { Utils } from 'jslib-common/misc/utils';\n\n/*\n An updated pipe that sanitizes HTML, highlights numbers and special characters (in different colors each)\n and handles Unicode / Emoji characters correctly.\n*/\n@Pipe({ name: 'colorPassword' })\nexport class ColorPasswordPipe implements PipeTransform {\n transform(password: string) {\n // Convert to an array to handle cases that stings have special characters, ie: emoji.\n const passwordArray = Array.from(password);\n let colorizedPassword = '';\n for (let i = 0; i < passwordArray.length; i++) {\n let character = passwordArray[i];\n let isSpecial = false;\n // Sanitize HTML first.\n switch (character) {\n case '&':\n character = '&';\n isSpecial = true;\n break;\n case '<':\n character = '<';\n isSpecial = true;\n break;\n case '>':\n character = '>';\n isSpecial = true;\n break;\n case ' ':\n character = ' ';\n isSpecial = true;\n break;\n default:\n break;\n }\n let type = 'letter';\n if (character.match(Utils.regexpEmojiPresentation)) {\n type = 'emoji';\n } else if (isSpecial || character.match(/[^\\w ]/)) {\n type = 'special';\n } else if (character.match(/\\d/)) {\n type = 'number';\n }\n colorizedPassword += '' + character + '';\n }\n return colorizedPassword;\n }\n}\n","export abstract class NotificationsService {\n init: () => Promise;\n updateConnection: (sync?: boolean) => Promise;\n reconnectFromActivity: () => Promise;\n disconnectFromInactivity: () => Promise;\n}\n","export abstract class SettingsService {\n clearCache: () => void;\n getEquivalentDomains: () => Promise;\n setEquivalentDomains: (equivalentDomains: string[][]) => Promise;\n clear: (userId: string) => Promise;\n}\n","import { Injectable } from '@angular/core';\nimport {\n ActivatedRouteSnapshot,\n CanActivate,\n Router,\n} from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\n@Injectable()\nexport class OrganizationGuardService implements CanActivate {\n constructor(private userService: UserService, private router: Router,\n private toasterService: ToasterService, private i18nService: I18nService) { }\n\n async canActivate(route: ActivatedRouteSnapshot) {\n const org = await this.userService.getOrganization(route.params.organizationId);\n if (org == null) {\n this.router.navigate(['/']);\n return false;\n }\n if (!org.isOwner && !org.enabled) {\n this.toasterService.popAsync('error', null, this.i18nService.t('organizationIsDisabled'));\n this.router.navigate(['/']);\n return false;\n }\n\n return true;\n }\n}\n","import { Injectable } from '@angular/core';\nimport {\n ActivatedRouteSnapshot,\n CanActivate,\n Router,\n} from '@angular/router';\n\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Permissions } from 'jslib-common/enums/permissions';\n\n@Injectable()\nexport class OrganizationTypeGuardService implements CanActivate {\n constructor(private userService: UserService, private router: Router) { }\n\n async canActivate(route: ActivatedRouteSnapshot) {\n const org = await this.userService.getOrganization(route.params.organizationId);\n const permissions = route.data == null ? null : route.data.permissions as Permissions[];\n\n if (\n (permissions.indexOf(Permissions.AccessEventLogs) !== -1 && org.canAccessEventLogs) ||\n (permissions.indexOf(Permissions.AccessImportExport) !== -1 && org.canAccessImportExport) ||\n (permissions.indexOf(Permissions.AccessReports) !== -1 && org.canAccessReports) ||\n (permissions.indexOf(Permissions.CreateNewCollections) !== -1 && org.canCreateNewCollections) ||\n (permissions.indexOf(Permissions.EditAnyCollection) !== -1 && org.canEditAnyCollection) ||\n (permissions.indexOf(Permissions.DeleteAnyCollection) !== -1 && org.canDeleteAnyCollection) ||\n (permissions.indexOf(Permissions.EditAssignedCollections) !== -1 && org.canEditAssignedCollections) ||\n (permissions.indexOf(Permissions.DeleteAssignedCollections) !== -1 && org.canDeleteAssignedCollections) ||\n (permissions.indexOf(Permissions.ManageGroups) !== -1 && org.canManageGroups) ||\n (permissions.indexOf(Permissions.ManageOrganization) !== -1 && org.isOwner) ||\n (permissions.indexOf(Permissions.ManagePolicies) !== -1 && org.canManagePolicies) ||\n (permissions.indexOf(Permissions.ManageUsers) !== -1 && org.canManageUsers) ||\n (permissions.indexOf(Permissions.ManageUsersPassword) !== -1 && org.canManageUsersPassword) ||\n (permissions.indexOf(Permissions.ManageSso) !== -1 && org.canManageSso)\n ) {\n return true;\n }\n\n this.router.navigate(['/organizations', org.id]);\n return false;\n }\n}\n","import { BaseResponse } from './baseResponse';\nimport { ProfileOrganizationResponse } from './profileOrganizationResponse';\nimport { ProfileProviderOrganizationResponse } from './profileProviderOrganizationResponse';\nimport { ProfileProviderResponse } from './profileProviderResponse';\n\nexport class ProfileResponse extends BaseResponse {\n id: string;\n name: string;\n email: string;\n emailVerified: boolean;\n masterPasswordHint: string;\n premium: boolean;\n culture: string;\n twoFactorEnabled: boolean;\n key: string;\n privateKey: string;\n securityStamp: string;\n forcePasswordReset: boolean;\n usesKeyConnector: boolean;\n organizations: ProfileOrganizationResponse[] = [];\n providers: ProfileProviderResponse[] = [];\n providerOrganizations: ProfileProviderOrganizationResponse[] = [];\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.name = this.getResponseProperty('Name');\n this.email = this.getResponseProperty('Email');\n this.emailVerified = this.getResponseProperty('EmailVerified');\n this.masterPasswordHint = this.getResponseProperty('MasterPasswordHint');\n this.premium = this.getResponseProperty('Premium');\n this.culture = this.getResponseProperty('Culture');\n this.twoFactorEnabled = this.getResponseProperty('TwoFactorEnabled');\n this.key = this.getResponseProperty('Key');\n this.privateKey = this.getResponseProperty('PrivateKey');\n this.securityStamp = this.getResponseProperty('SecurityStamp');\n this.forcePasswordReset = this.getResponseProperty('ForcePasswordReset') ?? false;\n this.usesKeyConnector = this.getResponseProperty('UsesKeyConnector') ?? false;\n\n const organizations = this.getResponseProperty('Organizations');\n if (organizations != null) {\n this.organizations = organizations.map((o: any) => new ProfileOrganizationResponse(o));\n }\n const providers = this.getResponseProperty('Providers');\n if (providers != null) {\n this.providers = providers.map((o: any) => new ProfileProviderResponse(o));\n }\n const providerOrganizations = this.getResponseProperty('ProviderOrganizations');\n if (providerOrganizations != null) {\n this.providerOrganizations = providerOrganizations.map((o: any) => new ProfileProviderOrganizationResponse(o));\n }\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nimport { SendType } from '../../enums/sendType';\n\nimport { SendFileApi } from '../api/sendFileApi';\nimport { SendTextApi } from '../api/sendTextApi';\n\nexport class SendResponse extends BaseResponse {\n id: string;\n accessId: string;\n type: SendType;\n name: string;\n notes: string;\n file: SendFileApi;\n text: SendTextApi;\n key: string;\n maxAccessCount?: number;\n accessCount: number;\n revisionDate: string;\n expirationDate: string;\n deletionDate: string;\n password: string;\n disable: boolean;\n hideEmail: boolean;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.accessId = this.getResponseProperty('AccessId');\n this.type = this.getResponseProperty('Type');\n this.name = this.getResponseProperty('Name');\n this.notes = this.getResponseProperty('Notes');\n this.key = this.getResponseProperty('Key');\n this.maxAccessCount = this.getResponseProperty('MaxAccessCount');\n this.accessCount = this.getResponseProperty('AccessCount');\n this.revisionDate = this.getResponseProperty('RevisionDate');\n this.expirationDate = this.getResponseProperty('ExpirationDate');\n this.deletionDate = this.getResponseProperty('DeletionDate');\n this.password = this.getResponseProperty('Password');\n this.disable = this.getResponseProperty('Disabled') || false;\n this.hideEmail = this.getResponseProperty('HideEmail') || false;\n\n const text = this.getResponseProperty('Text');\n if (text != null) {\n this.text = new SendTextApi(text);\n }\n\n const file = this.getResponseProperty('File');\n if (file != null) {\n this.file = new SendFileApi(file);\n }\n }\n}\n","function webpackEmptyAsyncContext(req) {\n\t// Here Promise.resolve().then() is used instead of new Promise() to prevent\n\t// uncaught exception popping up in devtools\n\treturn Promise.resolve().then(function() {\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t});\n}\nwebpackEmptyAsyncContext.keys = function() { return []; };\nwebpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;\nmodule.exports = webpackEmptyAsyncContext;\nwebpackEmptyAsyncContext.id = 506;","import { Injectable } from '@angular/core';\nimport {\n ActivatedRouteSnapshot,\n CanActivate,\n Router,\n} from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\n@Injectable()\nexport class ProviderGuardService implements CanActivate {\n constructor(private userService: UserService, private router: Router,\n private toasterService: ToasterService, private i18nService: I18nService) { }\n\n async canActivate(route: ActivatedRouteSnapshot) {\n const provider = await this.userService.getProvider(route.params.providerId);\n if (provider == null) {\n this.router.navigate(['/']);\n return false;\n }\n if (!provider.isProviderAdmin && !provider.enabled) {\n this.toasterService.popAsync('error', null, this.i18nService.t('providerIsDisabled'));\n this.router.navigate(['/']);\n return false;\n }\n\n return true;\n }\n}\n","import { Injectable } from '@angular/core';\nimport {\n ActivatedRouteSnapshot,\n CanActivate,\n Router,\n} from '@angular/router';\n\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Permissions } from 'jslib-common/enums/permissions';\n\n@Injectable()\nexport class ProviderTypeGuardService implements CanActivate {\n constructor(private userService: UserService, private router: Router) { }\n\n async canActivate(route: ActivatedRouteSnapshot) {\n const provider = await this.userService.getProvider(route.params.providerId);\n const permissions = route.data == null ? null : route.data.permissions as Permissions[];\n\n if (\n (permissions.indexOf(Permissions.AccessEventLogs) !== -1 && provider.canAccessEventLogs) ||\n (permissions.indexOf(Permissions.ManageProvider) !== -1 && provider.isProviderAdmin) ||\n (permissions.indexOf(Permissions.ManageUsers) !== -1 && provider.canManageUsers)\n ) {\n return true;\n }\n\n this.router.navigate(['/providers', provider.id]);\n return false;\n }\n}\n","import { Component } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Provider } from 'jslib-common/models/domain/provider';\n\n@Component({\n selector: 'providers-layout',\n templateUrl: 'providers-layout.component.html',\n})\nexport class ProvidersLayoutComponent {\n\n provider: Provider;\n private providerId: string;\n\n constructor(private route: ActivatedRoute, private userService: UserService) { }\n\n ngOnInit() {\n document.body.classList.remove('layout_frontend');\n this.route.params.subscribe(async params => {\n this.providerId = params.providerId;\n await this.load();\n });\n }\n\n async load() {\n this.provider = await this.userService.getProvider(this.providerId);\n }\n\n get showMenuBar() {\n return this.showManageTab || this.showSettingsTab;\n }\n\n get showManageTab() {\n return this.provider.canManageUsers || this.provider.canAccessEventLogs;\n }\n\n get showSettingsTab() {\n return this.provider.isProviderAdmin;\n }\n\n get manageRoute(): string {\n switch (true) {\n case this.provider.canManageUsers:\n return 'manage/people';\n case this.provider.canAccessEventLogs:\n return 'manage/events';\n }\n }\n}\n","
{{provider.name}} {{'provider' | i18n}}
{{'providerIsDisabled' | i18n}}
","import {\n Component,\n OnInit,\n ViewChild,\n ViewContainerRef\n} from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { ToasterService } from 'angular2-toaster';\n\nimport { first } from 'rxjs/operators';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { SearchService } from 'jslib-common/abstractions/search.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\nimport { ValidationService } from 'jslib-angular/services/validation.service';\n\nimport { PlanType } from 'jslib-common/enums/planType';\nimport { ProviderUserType } from 'jslib-common/enums/providerUserType';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport {\n ProviderOrganizationOrganizationDetailsResponse\n} from 'jslib-common/models/response/provider/providerOrganizationResponse';\n\nimport { ProviderService } from '../services/provider.service';\n\nimport { AddOrganizationComponent } from './add-organization.component';\n\nconst DisallowedPlanTypes = [PlanType.Free, PlanType.FamiliesAnnually2019, PlanType.FamiliesAnnually];\n\n@Component({\n templateUrl: 'clients.component.html',\n})\nexport class ClientsComponent implements OnInit {\n\n @ViewChild('add', { read: ViewContainerRef, static: true }) addModalRef: ViewContainerRef;\n\n providerId: any;\n searchText: string;\n addableOrganizations: Organization[];\n loading = true;\n manageOrganizations = false;\n showAddExisting = false;\n\n clients: ProviderOrganizationOrganizationDetailsResponse[];\n pagedClients: ProviderOrganizationOrganizationDetailsResponse[];\n\n protected didScroll = false;\n protected pageSize = 100;\n protected actionPromise: Promise;\n private pagedClientsCount = 0;\n\n constructor(private route: ActivatedRoute, private userService: UserService,\n private apiService: ApiService, private searchService: SearchService,\n private platformUtilsService: PlatformUtilsService, private i18nService: I18nService,\n private toasterService: ToasterService, private validationService: ValidationService,\n private providerService: ProviderService, private logService: LogService,\n private modalService: ModalService) { }\n\n async ngOnInit() {\n this.route.parent.params.subscribe(async params => {\n this.providerId = params.providerId;\n\n await this.load();\n\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n this.searchText = qParams.search;\n });\n });\n }\n\n async load() {\n const response = await this.apiService.getProviderClients(this.providerId);\n this.clients = response.data != null && response.data.length > 0 ? response.data : [];\n this.manageOrganizations = (await this.userService.getProvider(this.providerId)).type === ProviderUserType.ProviderAdmin;\n const candidateOrgs = (await this.userService.getAllOrganizations()).filter(o => o.isOwner && o.providerId == null);\n const allowedOrgsIds = await Promise.all(candidateOrgs.map(o => this.apiService.getOrganization(o.id))).then(orgs =>\n orgs.filter(o => !DisallowedPlanTypes.includes(o.planType))\n .map(o => o.id));\n this.addableOrganizations = candidateOrgs.filter(o => allowedOrgsIds.includes(o.id));\n\n this.showAddExisting = this.addableOrganizations.length !== 0;\n this.loading = false;\n }\n\n isPaging() {\n const searching = this.isSearching();\n if (searching && this.didScroll) {\n this.resetPaging();\n }\n return !searching && this.clients && this.clients.length > this.pageSize;\n }\n\n isSearching() {\n return this.searchService.isSearchable(this.searchText);\n }\n\n async resetPaging() {\n this.pagedClients = [];\n this.loadMore();\n }\n\n\n loadMore() {\n if (!this.clients || this.clients.length <= this.pageSize) {\n return;\n }\n const pagedLength = this.pagedClients.length;\n let pagedSize = this.pageSize;\n if (pagedLength === 0 && this.pagedClientsCount > this.pageSize) {\n pagedSize = this.pagedClientsCount;\n }\n if (this.clients.length > pagedLength) {\n this.pagedClients = this.pagedClients.concat(this.clients.slice(pagedLength, pagedLength + pagedSize));\n }\n this.pagedClientsCount = this.pagedClients.length;\n this.didScroll = this.pagedClients.length > this.pageSize;\n }\n\n async addExistingOrganization() {\n const [modal] = await this.modalService.openViewRef(AddOrganizationComponent, this.addModalRef, comp => {\n comp.providerId = this.providerId;\n comp.organizations = this.addableOrganizations;\n comp.onAddedOrganization.subscribe(async () => {\n try {\n await this.load();\n modal.close();\n } catch (e) {\n this.logService.error(`Handled exception: ${e}`);\n }\n });\n });\n }\n\n async remove(organization: ProviderOrganizationOrganizationDetailsResponse) {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('detachOrganizationConfirmation'), organization.organizationName,\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n\n if (!confirmed) {\n return false;\n }\n\n this.actionPromise = this.providerService.detachOrganizastion(this.providerId, organization.id);\n try {\n await this.actionPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('detachedOrganization', organization.organizationName));\n await this.load();\n } catch (e) {\n this.validationService.showError(e);\n }\n this.actionPromise = null;\n }\n}\n","

{{'clients' | i18n}}

{{'newClientOrganization' | i18n}}
{{'loading' | i18n}}

{{'noClientsInList' | i18n}}

{{o.organizationName}}
","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output\n} from '@angular/core';\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ValidationService } from 'jslib-angular/services/validation.service';\n\nimport { ProviderService } from '../services/provider.service';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport { Provider } from 'jslib-common/models/domain/provider';\n\nimport { PlanType } from 'jslib-common/enums/planType';\n\n@Component({\n selector: 'provider-add-organization',\n templateUrl: 'add-organization.component.html',\n})\nexport class AddOrganizationComponent implements OnInit {\n\n @Input() providerId: string;\n @Input() organizations: Organization[];\n @Output() onAddedOrganization = new EventEmitter();\n\n provider: Provider;\n formPromise: Promise;\n loading = true;\n\n constructor(private userService: UserService, private providerService: ProviderService,\n private toasterService: ToasterService, private i18nService: I18nService,\n private platformUtilsService: PlatformUtilsService, private validationService: ValidationService,\n private apiService: ApiService) { }\n\n async ngOnInit() {\n await this.load();\n }\n\n async load() {\n if (this.providerId == null) {\n return;\n }\n\n this.provider = await this.userService.getProvider(this.providerId);\n\n this.loading = false;\n }\n\n async add(organization: Organization) {\n if (this.formPromise) {\n return;\n }\n\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('addOrganizationConfirmation', organization.name, this.provider.name), organization.name,\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n\n if (!confirmed) {\n return false;\n }\n\n try {\n this.formPromise = this.providerService.addOrganizationToProvider(this.providerId, organization.id);\n await this.formPromise;\n } catch (e) {\n this.validationService.showError(e);\n return;\n } finally {\n this.formPromise = null;\n }\n\n this.toasterService.popAsync('success', null, this.i18nService.t('organizationJoinedProvider'));\n this.onAddedOrganization.emit();\n }\n}\n","

{{'addExistingOrganization' | i18n}}

{{'loading' | i18n}}
{{o.name}}
","import {\n Component,\n OnInit,\n ViewChild,\n} from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { OrganizationPlansComponent } from 'src/app/settings/organization-plans.component';\n\n@Component({\n selector: 'app-create-organization',\n templateUrl: 'create-organization.component.html',\n})\nexport class CreateOrganizationComponent implements OnInit {\n @ViewChild(OrganizationPlansComponent, { static: true }) orgPlansComponent: OrganizationPlansComponent;\n\n providerId: string;\n\n constructor(private route: ActivatedRoute) { }\n\n ngOnInit() {\n this.route.parent.params.subscribe(async params => {\n this.providerId = params.providerId;\n });\n }\n}\n","

{{'newClientOrganization' | i18n}}

{{'newClientOrganizationDesc' | i18n}}

","import Domain from './domainBase';\n\nexport class MasterPasswordPolicyOptions extends Domain {\n minComplexity: number = 0;\n minLength: number = 0;\n requireUpper: boolean = false;\n requireLower: boolean = false;\n requireNumbers: boolean = false;\n requireSpecial: boolean = false;\n}\n","import { TaxInfoUpdateRequest } from './taxInfoUpdateRequest';\n\nexport class OrganizationTaxInfoUpdateRequest extends TaxInfoUpdateRequest {\n taxId: string;\n line1: string;\n line2: string;\n city: string;\n state: string;\n}\n","export class TaxInfoUpdateRequest {\n country: string;\n postalCode: string;\n}\n","import { Component } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { Toast, ToasterService } from 'angular2-toaster';\n\nimport { BaseAcceptComponent } from 'src/app/common/base.accept.component';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\nimport { ProviderUserAcceptRequest } from 'jslib-common/models/request/provider/providerUserAcceptRequest';\n\n@Component({\n selector: 'app-accept-provider',\n templateUrl: 'accept-provider.component.html',\n})\nexport class AcceptProviderComponent extends BaseAcceptComponent {\n providerName: string;\n\n failedMessage = 'providerInviteAcceptFailed';\n\n requiredParameters = ['providerId', 'providerUserId', 'token'];\n\n constructor(router: Router, toasterService: ToasterService, i18nService: I18nService, route: ActivatedRoute,\n userService: UserService, stateService: StateService, private apiService: ApiService) {\n super(router, toasterService, i18nService, route, userService, stateService);\n }\n\n async authedHandler(qParams: any) {\n const request = new ProviderUserAcceptRequest();\n request.token = qParams.token;\n\n await this.apiService.postProviderUserAccept(qParams.providerId, qParams.providerUserId, request);\n const toast: Toast = {\n type: 'success',\n title: this.i18nService.t('inviteAccepted'),\n body: this.i18nService.t('providerInviteAcceptedDesc'),\n timeout: 10000,\n };\n this.toasterService.popAsync(toast);\n this.router.navigate(['/vault']);\n }\n\n async unauthedHandler(qParams: any) {\n this.providerName = qParams.providerName;\n }\n}\n","
\"Bitwarden\"

{{'loading' | i18n}}

{{'joinProvider' | i18n}}

{{providerName}} {{email}}

{{'joinProviderDesc' | i18n}}


","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { ExportService } from 'jslib-common/abstractions/export.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { UserNamePipe } from 'jslib-angular/pipes/user-name.pipe';\n\nimport { EventResponse } from 'jslib-common/models/response/eventResponse';\n\nimport { EventService } from 'src/app/services/event.service';\n\nimport { BaseEventsComponent } from 'src/app/common/base.events.component';\n\n@Component({\n selector: 'provider-events',\n templateUrl: 'events.component.html',\n})\nexport class EventsComponent extends BaseEventsComponent implements OnInit {\n exportFileName: string = 'provider-events';\n providerId: string;\n\n private providerUsersUserIdMap = new Map();\n private providerUsersIdMap = new Map();\n\n constructor(private apiService: ApiService, private route: ActivatedRoute, eventService: EventService,\n i18nService: I18nService, toasterService: ToasterService, private userService: UserService,\n exportService: ExportService, platformUtilsService: PlatformUtilsService, private router: Router,\n logService: LogService, private userNamePipe: UserNamePipe) {\n super(eventService, i18nService, toasterService, exportService, platformUtilsService, logService);\n }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.providerId = params.providerId;\n const provider = await this.userService.getProvider(this.providerId);\n if (provider == null || !provider.useEvents) {\n this.router.navigate(['/providers', this.providerId]);\n return;\n }\n await this.load();\n });\n }\n\n async load() {\n const response = await this.apiService.getProviderUsers(this.providerId);\n response.data.forEach(u => {\n const name = this.userNamePipe.transform(u);\n this.providerUsersIdMap.set(u.id, { name: name, email: u.email });\n this.providerUsersUserIdMap.set(u.userId, { name: name, email: u.email });\n });\n await this.loadEvents(true);\n this.loaded = true;\n }\n\n protected requestEvents(startDate: string, endDate: string, continuationToken: string) {\n return this.apiService.getEventsProvider(this.providerId, startDate, endDate, continuationToken);\n }\n\n protected getUserName(r: EventResponse, userId: string) {\n return userId != null && this.providerUsersUserIdMap.has(userId) ? this.providerUsersUserIdMap.get(userId) : null;\n }\n}\n","

{{'eventLogs' | i18n}}

-
{{'loading' | i18n}}

{{'noEventsInList' | i18n}}

{{'timestamp' | i18n}} {{'device' | i18n}} {{'user' | i18n}} {{'event' | i18n}}
{{e.date | date:'medium'}} {{e.appName}}, {{e.ip}} {{e.userName}}
","import { Directive } from '@angular/core';\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ExportService } from 'jslib-common/abstractions/export.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { EventView } from 'jslib-common/models/view/eventView';\n\nimport { EventResponse } from 'jslib-common/models/response/eventResponse';\nimport { ListResponse } from 'jslib-common/models/response/listResponse';\n\nimport { EventService } from 'src/app/services/event.service';\n\n@Directive()\nexport abstract class BaseEventsComponent {\n loading = true;\n loaded = false;\n events: EventView[];\n start: string;\n end: string;\n dirtyDates: boolean = true;\n continuationToken: string;\n refreshPromise: Promise;\n exportPromise: Promise;\n morePromise: Promise;\n\n abstract readonly exportFileName: string;\n\n constructor(protected eventService: EventService, protected i18nService: I18nService,\n protected toasterService: ToasterService, protected exportService: ExportService,\n protected platformUtilsService: PlatformUtilsService, protected logService: LogService) {\n const defaultDates = this.eventService.getDefaultDateFilters();\n this.start = defaultDates[0];\n this.end = defaultDates[1];\n }\n\n async exportEvents() {\n if (this.appApiPromiseUnfulfilled() || this.dirtyDates) {\n return;\n }\n\n this.loading = true;\n\n const dates = this.parseDates();\n if (dates == null) {\n return;\n }\n\n try {\n this.exportPromise = this.export(dates[0], dates[1]);\n\n await this.exportPromise;\n } catch (e) {\n this.logService.error(`Handled exception: ${e}`);\n }\n\n this.exportPromise = null;\n this.loading = false;\n }\n\n async loadEvents(clearExisting: boolean) {\n if (this.appApiPromiseUnfulfilled()) {\n return;\n }\n\n const dates = this.parseDates();\n if (dates == null) {\n return;\n }\n\n this.loading = true;\n let events: EventView[] = [];\n try {\n const promise = this.loadAndParseEvents(dates[0], dates[1], clearExisting ? null : this.continuationToken);\n if (clearExisting) {\n this.refreshPromise = promise;\n } else {\n this.morePromise = promise;\n }\n const result = await promise;\n this.continuationToken = result.continuationToken;\n events = result.events;\n } catch (e) {\n this.logService.error(`Handled exception: ${e}`);\n }\n\n if (!clearExisting && this.events != null && this.events.length > 0) {\n this.events = this.events.concat(events);\n } else {\n this.events = events;\n }\n\n this.dirtyDates = false;\n this.loading = false;\n this.morePromise = null;\n this.refreshPromise = null;\n }\n\n protected abstract requestEvents(startDate: string, endDate: string, continuationToken: string): Promise>;\n protected abstract getUserName(r: EventResponse, userId: string): { name: string, email: string };\n\n protected async loadAndParseEvents(startDate: string, endDate: string, continuationToken: string) {\n const response = await this.requestEvents(startDate, endDate, continuationToken);\n\n const events = await Promise.all(response.data.map(async r => {\n const userId = r.actingUserId == null ? r.userId : r.actingUserId;\n const eventInfo = await this.eventService.getEventInfo(r);\n const user = this.getUserName(r, userId);\n return new EventView({\n message: eventInfo.message,\n humanReadableMessage: eventInfo.humanReadableMessage,\n appIcon: eventInfo.appIcon,\n appName: eventInfo.appName,\n userId: userId,\n userName: user != null ? user.name : this.i18nService.t('unknown'),\n userEmail: user != null ? user.email : '',\n date: r.date,\n ip: r.ipAddress,\n type: r.type,\n });\n }));\n return { continuationToken: response.continuationToken, events: events };\n }\n\n protected parseDates() {\n let dates: string[] = null;\n try {\n dates = this.eventService.formatDateFilters(this.start, this.end);\n } catch (e) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('invalidDateRange'));\n return null;\n }\n return dates;\n }\n\n protected appApiPromiseUnfulfilled() {\n return this.refreshPromise != null || this.morePromise != null || this.exportPromise != null;\n }\n\n private async export(start: string, end: string) {\n let continuationToken = this.continuationToken;\n let events = [].concat(this.events);\n\n while (continuationToken != null) {\n const result = await this.loadAndParseEvents(start, end, continuationToken);\n continuationToken = result.continuationToken;\n events = events.concat(result.events);\n }\n\n const data = await this.exportService.getEventExport(events);\n const fileName = this.exportService.getFileName(this.exportFileName, 'csv');\n this.platformUtilsService.saveFile(window, data, { type: 'text/plain' }, fileName);\n }\n}\n","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Provider } from 'jslib-common/models/domain/provider';\n\n@Component({\n selector: 'provider-manage',\n templateUrl: 'manage.component.html',\n})\nexport class ManageComponent implements OnInit {\n provider: Provider;\n accessEvents = false;\n\n constructor(private route: ActivatedRoute, private userService: UserService) { }\n\n ngOnInit() {\n this.route.parent.params.subscribe(async params => {\n this.provider = await this.userService.getProvider(params.providerId);\n this.accessEvents = this.provider.useEvents;\n });\n }\n}\n"," ","import {\n Component,\n OnInit,\n ViewChild,\n ViewContainerRef\n} from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { ToasterService } from 'angular2-toaster';\n\nimport { first } from 'rxjs/operators';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { SearchService } from 'jslib-common/abstractions/search.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\nimport { ValidationService } from 'jslib-angular/services/validation.service';\n\nimport { ProviderUserStatusType } from 'jslib-common/enums/providerUserStatusType';\nimport { ProviderUserType } from 'jslib-common/enums/providerUserType';\n\nimport { SearchPipe } from 'jslib-angular/pipes/search.pipe';\nimport { UserNamePipe } from 'jslib-angular/pipes/user-name.pipe';\n\nimport { ListResponse } from 'jslib-common/models/response/listResponse';\nimport { ProviderUserUserDetailsResponse } from 'jslib-common/models/response/provider/providerUserResponse';\n\nimport { ProviderUserBulkRequest } from 'jslib-common/models/request/provider/providerUserBulkRequest';\nimport { ProviderUserConfirmRequest } from 'jslib-common/models/request/provider/providerUserConfirmRequest';\nimport { ProviderUserBulkResponse } from 'jslib-common/models/response/provider/providerUserBulkResponse';\n\nimport { BasePeopleComponent } from 'src/app/common/base.people.component';\nimport { BulkStatusComponent } from 'src/app/organizations/manage/bulk/bulk-status.component';\nimport { EntityEventsComponent } from 'src/app/organizations/manage/entity-events.component';\nimport { BulkConfirmComponent } from './bulk/bulk-confirm.component';\nimport { BulkRemoveComponent } from './bulk/bulk-remove.component';\nimport { UserAddEditComponent } from './user-add-edit.component';\n\n@Component({\n selector: 'provider-people',\n templateUrl: 'people.component.html',\n})\nexport class PeopleComponent extends BasePeopleComponent implements OnInit {\n\n @ViewChild('addEdit', { read: ViewContainerRef, static: true }) addEditModalRef: ViewContainerRef;\n @ViewChild('groupsTemplate', { read: ViewContainerRef, static: true }) groupsModalRef: ViewContainerRef;\n @ViewChild('eventsTemplate', { read: ViewContainerRef, static: true }) eventsModalRef: ViewContainerRef;\n @ViewChild('bulkStatusTemplate', { read: ViewContainerRef, static: true }) bulkStatusModalRef: ViewContainerRef;\n @ViewChild('bulkConfirmTemplate', { read: ViewContainerRef, static: true }) bulkConfirmModalRef: ViewContainerRef;\n @ViewChild('bulkRemoveTemplate', { read: ViewContainerRef, static: true }) bulkRemoveModalRef: ViewContainerRef;\n\n userType = ProviderUserType;\n userStatusType = ProviderUserStatusType;\n providerId: string;\n accessEvents = false;\n\n constructor(apiService: ApiService, private route: ActivatedRoute,\n i18nService: I18nService, modalService: ModalService,\n platformUtilsService: PlatformUtilsService, toasterService: ToasterService,\n cryptoService: CryptoService, private userService: UserService, private router: Router,\n storageService: StorageService, searchService: SearchService, validationService: ValidationService,\n logService: LogService, searchPipe: SearchPipe, userNamePipe: UserNamePipe) {\n super(apiService, searchService, i18nService, platformUtilsService, toasterService, cryptoService,\n storageService, validationService, modalService, logService, searchPipe, userNamePipe);\n }\n\n ngOnInit() {\n this.route.parent.params.subscribe(async params => {\n this.providerId = params.providerId;\n const provider = await this.userService.getProvider(this.providerId);\n\n if (!provider.canManageUsers) {\n this.router.navigate(['../'], { relativeTo: this.route });\n return;\n }\n\n this.accessEvents = provider.useEvents;\n\n await this.load();\n\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n this.searchText = qParams.search;\n if (qParams.viewEvents != null) {\n const user = this.users.filter(u => u.id === qParams.viewEvents);\n if (user.length > 0 && user[0].status === ProviderUserStatusType.Confirmed) {\n this.events(user[0]);\n }\n }\n });\n });\n }\n\n getUsers(): Promise> {\n return this.apiService.getProviderUsers(this.providerId);\n }\n\n deleteUser(id: string): Promise {\n return this.apiService.deleteProviderUser(this.providerId, id);\n }\n\n reinviteUser(id: string): Promise {\n return this.apiService.postProviderUserReinvite(this.providerId, id);\n }\n\n async confirmUser(user: ProviderUserUserDetailsResponse, publicKey: Uint8Array): Promise {\n const providerKey = await this.cryptoService.getProviderKey(this.providerId);\n const key = await this.cryptoService.rsaEncrypt(providerKey.key, publicKey.buffer);\n const request = new ProviderUserConfirmRequest();\n request.key = key.encryptedString;\n await this.apiService.postProviderUserConfirm(this.providerId, user.id, request);\n }\n\n async edit(user: ProviderUserUserDetailsResponse) {\n const [modal] = await this.modalService.openViewRef(UserAddEditComponent, this.addEditModalRef, comp => {\n comp.name = this.userNamePipe.transform(user);\n comp.providerId = this.providerId;\n comp.providerUserId = user != null ? user.id : null;\n comp.onSavedUser.subscribe(() => {\n modal.close();\n this.load();\n });\n comp.onDeletedUser.subscribe(() => {\n modal.close();\n this.removeUser(user);\n });\n });\n }\n\n async events(user: ProviderUserUserDetailsResponse) {\n const [modal] = await this.modalService.openViewRef(EntityEventsComponent, this.eventsModalRef, comp => {\n comp.name = this.userNamePipe.transform(user);\n comp.providerId = this.providerId;\n comp.entityId = user.id;\n comp.showUser = false;\n comp.entity = 'user';\n });\n }\n\n async bulkRemove() {\n if (this.actionPromise != null) {\n return;\n }\n\n const [modal] = await this.modalService.openViewRef(BulkRemoveComponent, this.bulkRemoveModalRef, comp => {\n comp.providerId = this.providerId;\n comp.users = this.getCheckedUsers();\n });\n\n await modal.onClosedPromise();\n await this.load();\n }\n\n async bulkReinvite() {\n if (this.actionPromise != null) {\n return;\n }\n\n const users = this.getCheckedUsers();\n const filteredUsers = users.filter(u => u.status === ProviderUserStatusType.Invited);\n\n if (filteredUsers.length <= 0) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('noSelectedUsersApplicable'));\n return;\n }\n\n try {\n const request = new ProviderUserBulkRequest(filteredUsers.map(user => user.id));\n const response = this.apiService.postManyProviderUserReinvite(this.providerId, request);\n this.showBulkStatus(users, filteredUsers, response, this.i18nService.t('bulkReinviteMessage'));\n } catch (e) {\n this.validationService.showError(e);\n }\n this.actionPromise = null;\n }\n\n async bulkConfirm() {\n if (this.actionPromise != null) {\n return;\n }\n\n const [modal] = await this.modalService.openViewRef(BulkConfirmComponent, this.bulkConfirmModalRef, comp => {\n comp.providerId = this.providerId;\n comp.users = this.getCheckedUsers();\n });\n\n await modal.onClosedPromise();\n await this.load();\n }\n\n private async showBulkStatus(users: ProviderUserUserDetailsResponse[], filteredUsers: ProviderUserUserDetailsResponse[],\n request: Promise>, successfullMessage: string) {\n\n const [modal, childComponent] = await this.modalService.openViewRef(BulkStatusComponent, this.bulkStatusModalRef, comp => {\n comp.loading = true;\n });\n\n // Workaround to handle closing the modal shortly after it has been opened\n let close = false;\n modal.onShown.subscribe(() => {\n if (close) {\n modal.close();\n }\n });\n\n try {\n const response = await request;\n\n if (modal) {\n const keyedErrors: any = response.data.filter(r => r.error !== '').reduce((a, x) => ({ ...a, [x.id]: x.error }), {});\n const keyedFilteredUsers: any = filteredUsers.reduce((a, x) => ({ ...a, [x.id]: x }), {});\n\n childComponent.users = users.map(user => {\n let message = keyedErrors[user.id] ?? successfullMessage;\n if (!keyedFilteredUsers.hasOwnProperty(user.id)) {\n message = this.i18nService.t('bulkFilteredMessage');\n }\n\n return {\n user: user,\n error: keyedErrors.hasOwnProperty(user.id),\n message: message,\n };\n });\n childComponent.loading = false;\n }\n } catch {\n close = true;\n modal.close();\n }\n }\n}\n","

{{'people' | i18n}}

{{'loading' | i18n}}

{{'noUsersInList' | i18n}}

{{'providerUsersNeedConfirmed' | i18n}}
{{u.email}} {{'invited' | i18n}} {{'accepted' | i18n}} {{u.name}} {{'userUsingTwoStep' | i18n}} {{'providerAdmin' | i18n}} {{'serviceUser' | i18n}} {{'custom' | i18n}}
","import {\n Directive,\n ViewChild,\n ViewContainerRef\n} from '@angular/core';\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ValidationService } from 'jslib-angular/services/validation.service';\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { SearchService } from 'jslib-common/abstractions/search.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\n\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { SearchPipe } from 'jslib-angular/pipes/search.pipe';\nimport { UserNamePipe } from 'jslib-angular/pipes/user-name.pipe';\n\nimport { OrganizationUserStatusType } from 'jslib-common/enums/organizationUserStatusType';\nimport { OrganizationUserType } from 'jslib-common/enums/organizationUserType';\nimport { ProviderUserStatusType } from 'jslib-common/enums/providerUserStatusType';\nimport { ProviderUserType } from 'jslib-common/enums/providerUserType';\n\nimport { ListResponse } from 'jslib-common/models/response/listResponse';\nimport { OrganizationUserUserDetailsResponse } from 'jslib-common/models/response/organizationUserResponse';\nimport { ProviderUserUserDetailsResponse } from 'jslib-common/models/response/provider/providerUserResponse';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\nimport { UserConfirmComponent } from '../organizations/manage/user-confirm.component';\n\ntype StatusType = OrganizationUserStatusType | ProviderUserStatusType;\n\nconst MaxCheckedCount = 500;\n\n@Directive()\nexport abstract class BasePeopleComponent {\n\n @ViewChild('confirmTemplate', { read: ViewContainerRef, static: true }) confirmModalRef: ViewContainerRef;\n\n get allCount() {\n return this.allUsers != null ? this.allUsers.length : 0;\n }\n\n get invitedCount() {\n return this.statusMap.has(this.userStatusType.Invited) ?\n this.statusMap.get(this.userStatusType.Invited).length : 0;\n }\n\n get acceptedCount() {\n return this.statusMap.has(this.userStatusType.Accepted) ?\n this.statusMap.get(this.userStatusType.Accepted).length : 0;\n }\n\n get confirmedCount() {\n return this.statusMap.has(this.userStatusType.Confirmed) ?\n this.statusMap.get(this.userStatusType.Confirmed).length : 0;\n }\n\n get showConfirmUsers(): boolean {\n return this.allUsers != null && this.statusMap != null && this.allUsers.length > 1 &&\n this.confirmedCount > 0 && this.confirmedCount < 3 && this.acceptedCount > 0;\n }\n\n get showBulkConfirmUsers(): boolean {\n return this.acceptedCount > 0;\n }\n\n abstract userType: typeof OrganizationUserType | typeof ProviderUserType;\n abstract userStatusType: typeof OrganizationUserStatusType | typeof ProviderUserStatusType;\n\n loading = true;\n statusMap = new Map();\n status: StatusType;\n users: UserType[] = [];\n pagedUsers: UserType[] = [];\n searchText: string;\n actionPromise: Promise;\n\n protected allUsers: UserType[] = [];\n\n protected didScroll = false;\n protected pageSize = 100;\n\n private pagedUsersCount = 0;\n\n constructor(protected apiService: ApiService, private searchService: SearchService,\n protected i18nService: I18nService, private platformUtilsService: PlatformUtilsService,\n protected toasterService: ToasterService, protected cryptoService: CryptoService,\n private storageService: StorageService, protected validationService: ValidationService,\n protected modalService: ModalService, private logService: LogService,\n private searchPipe: SearchPipe, protected userNamePipe: UserNamePipe ) { }\n\n abstract edit(user: UserType): void;\n abstract getUsers(): Promise>;\n abstract deleteUser(id: string): Promise;\n abstract reinviteUser(id: string): Promise;\n abstract confirmUser(user: UserType, publicKey: Uint8Array): Promise;\n\n async load() {\n const response = await this.getUsers();\n this.statusMap.clear();\n for (const status of Utils.iterateEnum(this.userStatusType)) {\n this.statusMap.set(status, []);\n }\n\n this.allUsers = response.data != null && response.data.length > 0 ? response.data : [];\n this.allUsers.sort(Utils.getSortFunction(this.i18nService, 'email'));\n this.allUsers.forEach(u => {\n if (!this.statusMap.has(u.status)) {\n this.statusMap.set(u.status, [u]);\n } else {\n this.statusMap.get(u.status).push(u);\n }\n });\n this.filter(this.status);\n this.loading = false;\n }\n\n filter(status: StatusType) {\n this.status = status;\n if (this.status != null) {\n this.users = this.statusMap.get(this.status);\n } else {\n this.users = this.allUsers;\n }\n // Reset checkbox selecton\n this.selectAll(false);\n this.resetPaging();\n }\n\n loadMore() {\n if (!this.users || this.users.length <= this.pageSize) {\n return;\n }\n const pagedLength = this.pagedUsers.length;\n let pagedSize = this.pageSize;\n if (pagedLength === 0 && this.pagedUsersCount > this.pageSize) {\n pagedSize = this.pagedUsersCount;\n }\n if (this.users.length > pagedLength) {\n this.pagedUsers = this.pagedUsers.concat(this.users.slice(pagedLength, pagedLength + pagedSize));\n }\n this.pagedUsersCount = this.pagedUsers.length;\n this.didScroll = this.pagedUsers.length > this.pageSize;\n }\n\n checkUser(user: OrganizationUserUserDetailsResponse, select?: boolean) {\n (user as any).checked = select == null ? !(user as any).checked : select;\n }\n\n selectAll(select: boolean) {\n if (select) {\n this.selectAll(false);\n }\n\n const filteredUsers = this.searchPipe.transform(this.users, this.searchText, 'name', 'email', 'id');\n\n const selectCount = select && filteredUsers.length > MaxCheckedCount\n ? MaxCheckedCount\n : filteredUsers.length;\n for (let i = 0; i < selectCount; i++) {\n this.checkUser(filteredUsers[i], select);\n }\n }\n\n async resetPaging() {\n this.pagedUsers = [];\n this.loadMore();\n }\n\n invite() {\n this.edit(null);\n }\n\n async remove(user: UserType) {\n const confirmed = await this.platformUtilsService.showDialog(\n this.deleteWarningMessage(user), this.userNamePipe.transform(user),\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n\n if (!confirmed) {\n return false;\n }\n\n this.actionPromise = this.deleteUser(user.id);\n try {\n await this.actionPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('removedUserId', this.userNamePipe.transform(user)));\n this.removeUser(user);\n } catch (e) {\n this.validationService.showError(e);\n }\n this.actionPromise = null;\n }\n\n async reinvite(user: UserType) {\n if (this.actionPromise != null) {\n return;\n }\n\n this.actionPromise = this.reinviteUser(user.id);\n try {\n await this.actionPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('hasBeenReinvited', this.userNamePipe.transform(user)));\n } catch (e) {\n this.validationService.showError(e);\n }\n this.actionPromise = null;\n }\n\n async confirm(user: UserType) {\n function updateUser(self: BasePeopleComponent) {\n user.status = self.userStatusType.Confirmed;\n const mapIndex = self.statusMap.get(self.userStatusType.Accepted).indexOf(user);\n if (mapIndex > -1) {\n self.statusMap.get(self.userStatusType.Accepted).splice(mapIndex, 1);\n self.statusMap.get(self.userStatusType.Confirmed).push(user);\n }\n }\n\n const confirmUser = async (publicKey: Uint8Array) => {\n try {\n this.actionPromise = this.confirmUser(user, publicKey);\n await this.actionPromise;\n updateUser(this);\n this.toasterService.popAsync('success', null, this.i18nService.t('hasBeenConfirmed', this.userNamePipe.transform(user)));\n } catch (e) {\n this.validationService.showError(e);\n throw e;\n } finally {\n this.actionPromise = null;\n }\n };\n\n if (this.actionPromise != null) {\n return;\n }\n\n try {\n const publicKeyResponse = await this.apiService.getUserPublicKey(user.userId);\n const publicKey = Utils.fromB64ToArray(publicKeyResponse.publicKey);\n\n const autoConfirm = await this.storageService.get(ConstantsService.autoConfirmFingerprints);\n if (autoConfirm == null || !autoConfirm) {\n const [modal] = await this.modalService.openViewRef(UserConfirmComponent, this.confirmModalRef, comp => {\n comp.name = this.userNamePipe.transform(user);\n comp.userId = user != null ? user.userId : null;\n comp.publicKey = publicKey;\n comp.onConfirmedUser.subscribe(async () => {\n try {\n comp.formPromise = confirmUser(publicKey);\n await comp.formPromise;\n modal.close();\n } catch (e) {\n this.logService.error(e);\n }\n });\n });\n return;\n }\n\n try {\n const fingerprint = await this.cryptoService.getFingerprint(user.userId, publicKey.buffer);\n this.logService.info(`User's fingerprint: ${fingerprint.join('-')}`);\n } catch (e) {\n this.logService.error(e);\n }\n await confirmUser(publicKey);\n } catch (e) {\n this.logService.error(`Handled exception: ${e}`);\n }\n }\n\n isSearching() {\n return this.searchService.isSearchable(this.searchText);\n }\n\n isPaging() {\n const searching = this.isSearching();\n if (searching && this.didScroll) {\n this.resetPaging();\n }\n return !searching && this.users && this.users.length > this.pageSize;\n }\n\n protected deleteWarningMessage(user: UserType): string {\n return this.i18nService.t('removeUserConfirmation');\n }\n\n protected getCheckedUsers() {\n return this.users.filter(u => (u as any).checked);\n }\n\n protected removeUser(user: UserType) {\n let index = this.users.indexOf(user);\n if (index > -1) {\n this.users.splice(index, 1);\n this.resetPaging();\n }\n if (this.statusMap.has(user.status)) {\n index = this.statusMap.get(user.status).indexOf(user);\n if (index > -1) {\n this.statusMap.get(user.status).splice(index, 1);\n }\n }\n }\n\n}\n","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\n\n@Component({\n selector: 'app-user-confirm',\n templateUrl: 'user-confirm.component.html',\n})\nexport class UserConfirmComponent implements OnInit {\n @Input() name: string;\n @Input() userId: string;\n @Input() publicKey: Uint8Array;\n @Output() onConfirmedUser = new EventEmitter();\n\n dontAskAgain = false;\n loading = true;\n fingerprint: string;\n formPromise: Promise;\n\n constructor(private cryptoService: CryptoService, private storageService: StorageService,\n private logService: LogService) { }\n\n async ngOnInit() {\n try {\n if (this.publicKey != null) {\n const fingerprint = await this.cryptoService.getFingerprint(this.userId, this.publicKey.buffer);\n if (fingerprint != null) {\n this.fingerprint = fingerprint.join('-');\n }\n }\n } catch (e) {\n this.logService.error(e);\n }\n this.loading = false;\n }\n\n async submit() {\n if (this.loading) {\n return;\n }\n\n if (this.dontAskAgain) {\n await this.storageService.save(ConstantsService.autoConfirmFingerprints, true);\n }\n\n this.onConfirmedUser.emit();\n }\n}\n","

{{'confirmUser' | i18n}} {{name}}

{{'fingerprintEnsureIntegrityVerify' | i18n}} {{'learnMore' | i18n}}

{{fingerprint}}

","import {\n Component,\n Input,\n} from '@angular/core';\n\nimport { ProviderUserBulkConfirmRequest } from 'jslib-common/models/request/provider/providerUserBulkConfirmRequest';\nimport { ProviderUserBulkRequest } from 'jslib-common/models/request/provider/providerUserBulkRequest';\n\nimport { ProviderUserStatusType } from 'jslib-common/enums/providerUserStatusType';\n\nimport { BulkConfirmComponent as OrganizationBulkConfirmComponent } from 'src/app/organizations/manage/bulk/bulk-confirm.component';\nimport { BulkUserDetails } from 'src/app/organizations/manage/bulk/bulk-status.component';\n\n@Component({\n templateUrl: '/src/app/organizations/manage/bulk/bulk-confirm.component.html',\n})\nexport class BulkConfirmComponent extends OrganizationBulkConfirmComponent {\n\n @Input() providerId: string;\n\n protected isAccepted(user: BulkUserDetails) {\n return user.status === ProviderUserStatusType.Accepted;\n }\n\n protected async getPublicKeys() {\n const request = new ProviderUserBulkRequest(this.filteredUsers.map(user => user.id));\n return await this.apiService.postProviderUsersPublicKey(this.providerId, request);\n }\n\n protected getCryptoKey() {\n return this.cryptoService.getProviderKey(this.providerId);\n }\n\n protected async postConfirmRequest(userIdsWithKeys: any[]) {\n const request = new ProviderUserBulkConfirmRequest(userIdsWithKeys);\n return await this.apiService.postProviderUserBulkConfirm(this.providerId, request);\n }\n}\n","import {\n Component,\n Input,\n} from '@angular/core';\n\nimport { ProviderUserBulkRequest } from 'jslib-common/models/request/provider/providerUserBulkRequest';\n\nimport { BulkRemoveComponent as OrganizationBulkRemoveComponent } from 'src/app/organizations/manage/bulk/bulk-remove.component';\n\n@Component({\n templateUrl: '/src/app/organizations/manage/bulk/bulk-remove.component.html',\n})\nexport class BulkRemoveComponent extends OrganizationBulkRemoveComponent {\n\n @Input() providerId: string;\n\n async deleteUsers() {\n const request = new ProviderUserBulkRequest(this.users.map(user => user.id));\n return await this.apiService.deleteManyProviderUsers(this.providerId, request);\n }\n}\n","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { ProviderUserInviteRequest } from 'jslib-common/models/request/provider/providerUserInviteRequest';\n\nimport { PermissionsApi } from 'jslib-common/models/api/permissionsApi';\n\nimport { ProviderUserType } from 'jslib-common/enums/providerUserType';\nimport { ProviderUserUpdateRequest } from 'jslib-common/models/request/provider/providerUserUpdateRequest';\n\n@Component({\n selector: 'provider-user-add-edit',\n templateUrl: 'user-add-edit.component.html',\n})\nexport class UserAddEditComponent implements OnInit {\n @Input() name: string;\n @Input() providerUserId: string;\n @Input() providerId: string;\n @Output() onSavedUser = new EventEmitter();\n @Output() onDeletedUser = new EventEmitter();\n\n loading = true;\n editMode: boolean = false;\n title: string;\n emails: string;\n type: ProviderUserType = ProviderUserType.ServiceUser;\n permissions = new PermissionsApi();\n showCustom = false;\n access: 'all' | 'selected' = 'selected';\n formPromise: Promise;\n deletePromise: Promise;\n userType = ProviderUserType;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private platformUtilsService: PlatformUtilsService,\n private logService: LogService) { }\n\n async ngOnInit() {\n this.editMode = this.loading = this.providerUserId != null;\n\n if (this.editMode) {\n this.editMode = true;\n this.title = this.i18nService.t('editUser');\n try {\n const user = await this.apiService.getProviderUser(this.providerId, this.providerUserId);\n this.type = user.type;\n } catch (e) {\n this.logService.error(e);\n }\n } else {\n this.title = this.i18nService.t('inviteUser');\n }\n\n this.loading = false;\n }\n\n async submit() {\n try {\n if (this.editMode) {\n const request = new ProviderUserUpdateRequest();\n request.type = this.type;\n this.formPromise = this.apiService.putProviderUser(this.providerId, this.providerUserId, request);\n } else {\n const request = new ProviderUserInviteRequest();\n request.emails = this.emails.trim().split(/\\s*,\\s*/);\n request.type = this.type;\n this.formPromise = this.apiService.postProviderUserInvite(this.providerId, request);\n }\n await this.formPromise;\n this.toasterService.popAsync('success', null,\n this.i18nService.t(this.editMode ? 'editedUserId' : 'invitedUsers', this.name));\n this.onSavedUser.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async delete() {\n if (!this.editMode) {\n return;\n }\n\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('removeUserConfirmation'), this.name,\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.deletePromise = this.apiService.deleteProviderUser(this.providerId, this.providerUserId);\n await this.deletePromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('removedUserId', this.name));\n this.onDeletedUser.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n}\n","

{{title}} {{name}}

{{'loading' | i18n}}

{{'providerInviteUserDesc' | i18n}}

{{'inviteMultipleEmailDesc' | i18n : '20'}}

{{'userType' | i18n}}

","import { Component } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\n@Component({\n selector: 'provider-settings',\n templateUrl: 'settings.component.html',\n})\nexport class SettingsComponent {\n constructor(private route: ActivatedRoute, private userService: UserService,\n private platformUtilsService: PlatformUtilsService) { }\n\n ngOnInit() {\n this.route.parent.params.subscribe(async params => {\n const provider = await this.userService.getProvider(params.providerId);\n });\n }\n}\n","
{{'settings' | i18n}}
","import { Component } from '@angular/core';\n\nimport { BaseAcceptComponent } from 'src/app/common/base.accept.component';\n\n@Component({\n selector: 'app-setup-provider',\n templateUrl: 'setup-provider.component.html',\n})\nexport class SetupProviderComponent extends BaseAcceptComponent {\n\n failedShortMessage = 'inviteAcceptFailedShort';\n failedMessage = 'inviteAcceptFailed';\n\n requiredParameters = ['providerId', 'email', 'token'];\n\n async authedHandler(qParams: any) {\n this.router.navigate(['/providers/setup'], {queryParams: qParams});\n }\n\n // tslint:disable-next-line\n async unauthedHandler(qParams: any) {}\n}\n","
\"Bitwarden\"

{{'loading' | i18n}}

{{'setupProvider' | i18n}}

{{'setupProviderLoginDesc' | i18n}}


","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\nimport {\n Toast,\n ToasterService,\n} from 'angular2-toaster';\n\nimport { first } from 'rxjs/operators';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\n\nimport { ValidationService } from 'jslib-angular/services/validation.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { ProviderSetupRequest } from 'jslib-common/models/request/provider/providerSetupRequest';\n\n@Component({\n selector: 'provider-setup',\n templateUrl: 'setup.component.html',\n})\nexport class SetupComponent implements OnInit {\n loading = true;\n authed = false;\n email: string;\n formPromise: Promise;\n\n providerId: string;\n token: string;\n name: string;\n billingEmail: string;\n\n constructor(private router: Router, private toasterService: ToasterService,\n private i18nService: I18nService, private route: ActivatedRoute,\n private cryptoService: CryptoService, private apiService: ApiService,\n private syncService: SyncService, private validationService: ValidationService) { }\n\n ngOnInit() {\n document.body.classList.remove('layout_frontend');\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n const error = qParams.providerId == null || qParams.email == null || qParams.token == null;\n\n if (error) {\n const toast: Toast = {\n type: 'error',\n title: null,\n body: this.i18nService.t('emergencyInviteAcceptFailed'),\n timeout: 10000,\n };\n this.toasterService.popAsync(toast);\n this.router.navigate(['/']);\n return;\n }\n\n this.providerId = qParams.providerId;\n this.token = qParams.token;\n\n // Check if provider exists, redirect if it does\n try {\n const provider = await this.apiService.getProvider(this.providerId);\n if (provider.name != null) {\n this.router.navigate(['/providers', provider.id], { replaceUrl: true });\n }\n } catch (e) {\n this.validationService.showError(e);\n this.router.navigate(['/']);\n }\n });\n }\n\n async submit() {\n this.formPromise = this.doSubmit();\n await this.formPromise;\n this.formPromise = null;\n }\n\n async doSubmit() {\n try {\n const shareKey = await this.cryptoService.makeShareKey();\n const key = shareKey[0].encryptedString;\n\n const request = new ProviderSetupRequest();\n request.name = this.name;\n request.billingEmail = this.billingEmail;\n request.token = this.token;\n request.key = key;\n\n const provider = await this.apiService.postProviderSetup(this.providerId, request);\n this.toasterService.popAsync('success', null, this.i18nService.t('providerSetup'));\n await this.syncService.fullSync(true);\n\n this.router.navigate(['/providers', provider.id]);\n } catch (e) {\n this.validationService.showError(e);\n }\n }\n}\n","

{{'setupProvider' | i18n}}

{{'setupProviderDesc' | i18n}}

{{'generalInformation' | i18n}}

","import { Component } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\n\nimport { ProviderUpdateRequest } from 'jslib-common/models/request/provider/providerUpdateRequest';\n\nimport { ProviderResponse } from 'jslib-common/models/response/provider/providerResponse';\n\n@Component({\n selector: 'provider-account',\n templateUrl: 'account.component.html',\n})\nexport class AccountComponent {\n selfHosted = false;\n loading = true;\n provider: ProviderResponse;\n formPromise: Promise;\n taxFormPromise: Promise;\n\n private providerId: string;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private route: ActivatedRoute,\n private syncService: SyncService, private platformUtilsService: PlatformUtilsService,\n private logService: LogService) { }\n\n async ngOnInit() {\n this.selfHosted = this.platformUtilsService.isSelfHost();\n this.route.parent.parent.params.subscribe(async params => {\n this.providerId = params.providerId;\n try {\n this.provider = await this.apiService.getProvider(this.providerId);\n } catch (e) {\n this.logService.error(`Handled exception: ${e}`);\n }\n });\n this.loading = false;\n }\n\n async submit() {\n try {\n const request = new ProviderUpdateRequest();\n request.name = this.provider.name;\n request.businessName = this.provider.businessName;\n request.billingEmail = this.provider.billingEmail;\n\n this.formPromise = this.apiService.putProvider(this.providerId, request).then(() => {\n return this.syncService.fullSync(true);\n });\n await this.formPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('providerUpdated'));\n } catch (e) {\n this.logService.error(`Handled exception: ${e}`);\n }\n }\n}\n","

{{'myProvider' | i18n}}

{{'loading' | i18n}}
","import {\n Component,\n EventEmitter,\n Input,\n Output,\n} from '@angular/core';\nimport { Utils } from 'jslib-common/misc/utils';\n\n@Component({\n selector: 'app-nested-checkbox',\n templateUrl: 'nested-checkbox.component.html',\n})\nexport class NestedCheckboxComponent {\n @Input() parentId: string;\n @Input() checkboxes: { id: string, get: () => boolean, set: (v: boolean) => void; }[];\n @Output() onSavedUser = new EventEmitter();\n @Output() onDeletedUser = new EventEmitter();\n\n get parentIndeterminate() {\n return !this.parentChecked &&\n this.checkboxes.some(c => c.get());\n }\n\n get parentChecked() {\n return this.checkboxes.every(c => c.get());\n }\n\n set parentChecked(value: boolean) {\n this.checkboxes.forEach(c => {\n c.set(value);\n });\n }\n\n pascalize(s: string) {\n return Utils.camelToPascalCase(s);\n }\n}\n","
","import { Component } from '@angular/core';\n\nimport { PasswordRepromptComponent as BasePasswordRepromptComponent } from 'jslib-angular/components/password-reprompt.component';\n\n@Component({\n templateUrl: 'password-reprompt.component.html',\n})\nexport class PasswordRepromptComponent extends BasePasswordRepromptComponent {}\n","

{{'passwordConfirmation' | i18n}}

{{'passwordConfirmationDesc' | i18n}}
","import { Directive } from '@angular/core';\n\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { ModalRef } from './modal/modal.ref';\n\n@Directive()\nexport class PasswordRepromptComponent {\n\n showPassword = false;\n masterPassword = '';\n\n constructor(private modalRef: ModalRef, private cryptoService: CryptoService, private platformUtilsService: PlatformUtilsService,\n private i18nService: I18nService) {}\n\n togglePassword() {\n this.showPassword = !this.showPassword;\n }\n\n async submit() {\n if (!await this.cryptoService.compareAndUpdateKeyHash(this.masterPassword, null)) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('invalidMasterPassword'));\n return;\n }\n\n this.modalRef.close(true);\n }\n}\n","import {\n Directive,\n ElementRef,\n HostListener,\n} from '@angular/core';\n\n@Directive({\n selector: '[appBlurClick]',\n})\nexport class BlurClickDirective {\n constructor(private el: ElementRef) {\n }\n\n @HostListener('click') onClick() {\n this.el.nativeElement.blur();\n }\n}\n","import {\n Component,\n OnInit,\n} from '@angular/core';\n\n@Component({\n selector: 'app-user-layout',\n templateUrl: 'user-layout.component.html',\n})\nexport class UserLayoutComponent implements OnInit {\n ngOnInit() {\n document.body.classList.remove('layout_frontend');\n }\n}\n"," ","import { Component } from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport {\n Toast,\n ToasterService,\n} from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\nimport { EmergencyAccessAcceptRequest } from 'jslib-common/models/request/emergencyAccessAcceptRequest';\nimport { BaseAcceptComponent } from '../common/base.accept.component';\n\n@Component({\n selector: 'app-accept-emergency',\n templateUrl: 'accept-emergency.component.html',\n})\nexport class AcceptEmergencyComponent extends BaseAcceptComponent {\n\n name: string;\n\n protected requiredParameters: string[] = ['id', 'name', 'email', 'token'];\n protected failedShortMessage = 'emergencyInviteAcceptFailedShort';\n protected failedMessage = 'emergencyInviteAcceptFailed';\n\n constructor(router: Router, toasterService: ToasterService,\n i18nService: I18nService, route: ActivatedRoute,\n private apiService: ApiService, userService: UserService,\n stateService: StateService) {\n super(router, toasterService, i18nService, route, userService, stateService);\n }\n\n async authedHandler(qParams: any): Promise {\n const request = new EmergencyAccessAcceptRequest();\n request.token = qParams.token;\n this.actionPromise = this.apiService.postEmergencyAccessAccept(qParams.id, request);\n await this.actionPromise;\n const toast: Toast = {\n type: 'success',\n title: this.i18nService.t('inviteAccepted'),\n body: this.i18nService.t('emergencyInviteAcceptedDesc'),\n timeout: 10000,\n };\n this.toasterService.popAsync(toast);\n this.router.navigate(['/vault']);\n }\n\n async unauthedHandler(qParams: any): Promise {\n this.name = qParams.name;\n if (this.name != null) {\n // Fix URL encoding of space issue with Angular\n this.name = this.name.replace(/\\+/g, ' ');\n }\n }\n}\n","
\"Bitwarden\"

{{'loading' | i18n}}

{{'emergencyAccess' | i18n}}

{{name}}

{{'acceptEmergencyAccess' | i18n}}


","import { Component } from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport {\n Toast,\n ToasterService,\n} from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { OrganizationUserAcceptRequest } from 'jslib-common/models/request/organizationUserAcceptRequest';\nimport { OrganizationUserResetPasswordEnrollmentRequest } from 'jslib-common/models/request/organizationUserResetPasswordEnrollmentRequest';\n\nimport { Utils } from 'jslib-common/misc/utils';\nimport { Policy } from 'jslib-common/models/domain/policy';\nimport { BaseAcceptComponent } from '../common/base.accept.component';\n\n@Component({\n selector: 'app-accept-organization',\n templateUrl: 'accept-organization.component.html',\n})\nexport class AcceptOrganizationComponent extends BaseAcceptComponent {\n orgName: string;\n\n protected requiredParameters: string[] = ['organizationId', 'organizationUserId', 'token'];\n\n constructor(router: Router, toasterService: ToasterService,\n i18nService: I18nService, route: ActivatedRoute,\n private apiService: ApiService, userService: UserService,\n stateService: StateService, private cryptoService: CryptoService,\n private policyService: PolicyService, private logService: LogService) {\n super(router, toasterService, i18nService, route, userService, stateService);\n }\n\n async authedHandler(qParams: any): Promise {\n const request = new OrganizationUserAcceptRequest();\n request.token = qParams.token;\n if (await this.performResetPasswordAutoEnroll(qParams)) {\n this.actionPromise = this.apiService.postOrganizationUserAccept(qParams.organizationId,\n qParams.organizationUserId, request).then(() => {\n // Retrieve Public Key\n return this.apiService.getOrganizationKeys(qParams.organizationId);\n }).then(async response => {\n if (response == null) {\n throw new Error(this.i18nService.t('resetPasswordOrgKeysError'));\n }\n\n const publicKey = Utils.fromB64ToArray(response.publicKey);\n\n // RSA Encrypt user's encKey.key with organization public key\n const encKey = await this.cryptoService.getEncKey();\n const encryptedKey = await this.cryptoService.rsaEncrypt(encKey.key, publicKey.buffer);\n\n // Create request and execute enrollment\n const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest();\n resetRequest.resetPasswordKey = encryptedKey.encryptedString;\n\n // Get User Id\n const userId = await this.userService.getUserId();\n\n return this.apiService.putOrganizationUserResetPasswordEnrollment(qParams.organizationId, userId, resetRequest);\n });\n } else {\n this.actionPromise = this.apiService.postOrganizationUserAccept(qParams.organizationId,\n qParams.organizationUserId, request);\n }\n\n await this.actionPromise;\n const toast: Toast = {\n type: 'success',\n title: this.i18nService.t('inviteAccepted'),\n body: this.i18nService.t('inviteAcceptedDesc'),\n timeout: 10000,\n };\n this.toasterService.popAsync(toast);\n\n await this.stateService.remove('orgInvitation');\n this.router.navigate(['/vault']);\n }\n\n async unauthedHandler(qParams: any): Promise {\n this.orgName = qParams.organizationName;\n if (this.orgName != null) {\n // Fix URL encoding of space issue with Angular\n this.orgName = this.orgName.replace(/\\+/g, ' ');\n }\n await this.stateService.save('orgInvitation', qParams);\n }\n\n private async performResetPasswordAutoEnroll(qParams: any): Promise {\n let policyList: Policy[] = null;\n try {\n const policies = await this.apiService.getPoliciesByToken(qParams.organizationId, qParams.token,\n qParams.email, qParams.organizationUserId);\n policyList = this.policyService.mapPoliciesFromToken(policies);\n } catch (e) {\n this.logService.error(e);\n }\n\n if (policyList != null) {\n const result = this.policyService.getResetPasswordPolicyOptions(policyList, qParams.organizationId);\n // Return true if policy enabled and auto-enroll enabled\n return result[1] && result[0].autoEnrollEnabled;\n }\n\n return false;\n }\n}\n","
\"Bitwarden\"

{{'loading' | i18n}}

{{'joinOrganization' | i18n}}

{{orgName}} {{email}}

{{'joinOrganizationDesc' | i18n}}


","import { Component } from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { HintComponent as BaseHintComponent } from 'jslib-angular/components/hint.component';\n\n@Component({\n selector: 'app-hint',\n templateUrl: 'hint.component.html',\n})\nexport class HintComponent extends BaseHintComponent {\n constructor(router: Router, i18nService: I18nService,\n apiService: ApiService, platformUtilsService: PlatformUtilsService,\n logService: LogService) {\n super(router, i18nService, apiService, platformUtilsService, logService);\n }\n}\n","

{{'passwordHint' | i18n}}

{{'enterEmailToGetHint' | i18n}}

{{'cancel' | i18n}}
","import { Component } from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\nimport { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';\n\nimport { RouterService } from '../services/router.service';\n\nimport { LockComponent as BaseLockComponent } from 'jslib-angular/components/lock.component';\n\n@Component({\n selector: 'app-lock',\n templateUrl: 'lock.component.html',\n})\nexport class LockComponent extends BaseLockComponent {\n constructor(router: Router, i18nService: I18nService,\n platformUtilsService: PlatformUtilsService, messagingService: MessagingService,\n userService: UserService, cryptoService: CryptoService,\n storageService: StorageService, vaultTimeoutService: VaultTimeoutService,\n environmentService: EnvironmentService, private routerService: RouterService,\n stateService: StateService, apiService: ApiService, logService: LogService,\n keyConnectorService: KeyConnectorService) {\n super(router, i18nService, platformUtilsService, messagingService, userService, cryptoService,\n storageService, vaultTimeoutService, environmentService, stateService, apiService, logService,\n keyConnectorService);\n }\n\n async ngOnInit() {\n await super.ngOnInit();\n this.onSuccessfulSubmit = () => {\n const previousUrl = this.routerService.getPreviousUrl();\n if (previousUrl !== '/' && previousUrl.indexOf('lock') === -1) {\n this.successRoute = previousUrl;\n }\n this.router.navigate([this.successRoute]);\n };\n }\n}\n","

{{'yourVaultIsLocked' | i18n}}

{{'loggedInAsEmailOn' | i18n : email : webVaultHostname}}

","import { Component } from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { first } from 'rxjs/operators';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { AuthService } from 'jslib-common/abstractions/auth.service';\nimport { CryptoFunctionService } from 'jslib-common/abstractions/cryptoFunction.service';\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\n\nimport { LoginComponent as BaseLoginComponent } from 'jslib-angular/components/login.component';\n\nimport { Policy } from 'jslib-common/models/domain/policy';\n\n@Component({\n selector: 'app-login',\n templateUrl: 'login.component.html',\n})\nexport class LoginComponent extends BaseLoginComponent {\n\n showResetPasswordAutoEnrollWarning = false;\n\n constructor(authService: AuthService, router: Router,\n i18nService: I18nService, private route: ActivatedRoute,\n storageService: StorageService, stateService: StateService,\n platformUtilsService: PlatformUtilsService, environmentService: EnvironmentService,\n passwordGenerationService: PasswordGenerationService, cryptoFunctionService: CryptoFunctionService,\n private apiService: ApiService, private policyService: PolicyService, logService: LogService) {\n super(authService, router,\n platformUtilsService, i18nService,\n stateService, environmentService,\n passwordGenerationService, cryptoFunctionService,\n storageService, logService);\n this.onSuccessfulLoginNavigate = this.goAfterLogIn;\n }\n\n async ngOnInit() {\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n if (qParams.email != null && qParams.email.indexOf('@') > -1) {\n this.email = qParams.email;\n }\n if (qParams.premium != null) {\n this.stateService.save('loginRedirect', { route: '/settings/premium' });\n } else if (qParams.org != null) {\n this.stateService.save('loginRedirect',\n { route: '/settings/create-organization', qParams: { plan: qParams.org } });\n }\n\n // Are they coming from an email for sponsoring a families organization\n if (qParams.sponsorshipToken != null) {\n // After logging in redirect them to setup the families sponsorship\n this.stateService.save('loginRedirect', {\n route: '/setup/families-for-enterprise',\n qParams: { token: qParams.sponsorshipToken },\n });\n }\n await super.ngOnInit();\n });\n\n const invite = await this.stateService.get('orgInvitation');\n if (invite != null) {\n let policyList: Policy[] = null;\n try {\n const policies = await this.apiService.getPoliciesByToken(invite.organizationId, invite.token,\n invite.email, invite.organizationUserId);\n policyList = this.policyService.mapPoliciesFromToken(policies);\n } catch (e) {\n this.logService.error(e);\n }\n\n if (policyList != null) {\n const result = this.policyService.getResetPasswordPolicyOptions(policyList, invite.organizationId);\n // Set to true if policy enabled and auto-enroll enabled\n this.showResetPasswordAutoEnrollWarning = result[1] && result[0].autoEnrollEnabled;\n }\n }\n }\n\n async goAfterLogIn() {\n const loginRedirect = await this.stateService.get('loginRedirect');\n if (loginRedirect != null) {\n this.router.navigate([loginRedirect.route], { queryParams: loginRedirect.qParams });\n await this.stateService.remove('loginRedirect');\n } else {\n this.router.navigate([this.successRoute]);\n }\n }\n}\n","
\"Bitwarden\"

{{'loginOrCreateNewAccount' | i18n}}

{{'resetPasswordAutoEnrollInviteWarning' | i18n}}
{{'getMasterPasswordHint' | i18n}}

{{'createAccount' | i18n}}
","import { Directive, Input } from '@angular/core';\n\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { CaptchaIFrame } from 'jslib-common/misc/captcha_iframe';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\n@Directive()\nexport abstract class CaptchaProtectedComponent {\n @Input() captchaSiteKey: string = null;\n captchaToken: string = null;\n captcha: CaptchaIFrame;\n\n constructor(protected environmentService: EnvironmentService, protected i18nService: I18nService,\n protected platformUtilsService: PlatformUtilsService) { }\n\n async setupCaptcha() {\n const webVaultUrl = this.environmentService.getWebVaultUrl();\n\n this.captcha = new CaptchaIFrame(window, webVaultUrl,\n this.i18nService, (token: string) => {\n this.captchaToken = token;\n }, (error: string) => {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), error);\n }, (info: string) => {\n this.platformUtilsService.showToast('info', this.i18nService.t('info'), info);\n }\n );\n }\n\n showCaptcha() {\n return !Utils.isNullOrWhitespace(this.captchaSiteKey);\n }\n\n protected handleCaptchaRequired(response: { captchaSiteKey: string; }): boolean {\n if (Utils.isNullOrWhitespace(response.captchaSiteKey)) {\n return false;\n }\n\n this.captchaSiteKey = response.captchaSiteKey;\n this.captcha.init(response.captchaSiteKey);\n return true;\n }\n}\n","import { Component } from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\nimport { DeleteRecoverRequest } from 'jslib-common/models/request/deleteRecoverRequest';\n\n@Component({\n selector: 'app-recover-delete',\n templateUrl: 'recover-delete.component.html',\n})\nexport class RecoverDeleteComponent {\n email: string;\n formPromise: Promise;\n\n constructor(private router: Router, private apiService: ApiService,\n private toasterService: ToasterService, private i18nService: I18nService,\n private logService: LogService) {\n }\n\n async submit() {\n try {\n const request = new DeleteRecoverRequest();\n request.email = this.email.trim().toLowerCase();\n this.formPromise = this.apiService.postAccountRecoverDelete(request);\n await this.formPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('deleteRecoverEmailSent'));\n this.router.navigate(['/']);\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{'deleteAccount' | i18n}}

{{'deleteRecoverDesc' | i18n}}


{{'cancel' | i18n}}
","import { Component } from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { AuthService } from 'jslib-common/abstractions/auth.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\nimport { TwoFactorRecoveryRequest } from 'jslib-common/models/request/twoFactorRecoveryRequest';\n\n@Component({\n selector: 'app-recover-two-factor',\n templateUrl: 'recover-two-factor.component.html',\n})\nexport class RecoverTwoFactorComponent {\n email: string;\n masterPassword: string;\n recoveryCode: string;\n formPromise: Promise;\n\n constructor(private router: Router, private apiService: ApiService,\n private toasterService: ToasterService, private i18nService: I18nService,\n private cryptoService: CryptoService, private authService: AuthService,\n private logService: LogService) { }\n\n async submit() {\n try {\n const request = new TwoFactorRecoveryRequest();\n request.recoveryCode = this.recoveryCode.replace(/\\s/g, '').toLowerCase();\n request.email = this.email.trim().toLowerCase();\n const key = await this.authService.makePreloginKey(this.masterPassword, request.email);\n request.masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, key);\n this.formPromise = this.apiService.postTwoFactorRecover(request);\n await this.formPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('twoStepRecoverDisabled'));\n this.router.navigate(['/']);\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{'recoverAccountTwoStep' | i18n}}

{{'recoverAccountTwoStepDesc' | i18n}} {{'learnMore' | i18n}}


{{'cancel' | i18n}}
","import { Component } from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { first } from 'rxjs/operators';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { AuthService } from 'jslib-common/abstractions/auth.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\n\nimport { RegisterComponent as BaseRegisterComponent } from 'jslib-angular/components/register.component';\n\nimport { MasterPasswordPolicyOptions } from 'jslib-common/models/domain/masterPasswordPolicyOptions';\nimport { Policy } from 'jslib-common/models/domain/policy';\n\nimport { PolicyData } from 'jslib-common/models/data/policyData';\nimport { ReferenceEventRequest } from 'jslib-common/models/request/referenceEventRequest';\n\n@Component({\n selector: 'app-register',\n templateUrl: 'register.component.html',\n})\nexport class RegisterComponent extends BaseRegisterComponent {\n showCreateOrgMessage = false;\n layout = '';\n enforcedPolicyOptions: MasterPasswordPolicyOptions;\n\n private policies: Policy[];\n\n constructor(authService: AuthService, router: Router,\n i18nService: I18nService, cryptoService: CryptoService,\n apiService: ApiService, private route: ActivatedRoute,\n stateService: StateService, platformUtilsService: PlatformUtilsService,\n passwordGenerationService: PasswordGenerationService, private policyService: PolicyService,\n environmentService: EnvironmentService, logService: LogService) {\n super(authService, router, i18nService, cryptoService, apiService, stateService, platformUtilsService,\n passwordGenerationService, environmentService, logService);\n }\n\n async ngOnInit() {\n this.route.queryParams.pipe(first()).subscribe(qParams => {\n this.referenceData = new ReferenceEventRequest();\n if (qParams.email != null && qParams.email.indexOf('@') > -1) {\n this.email = qParams.email;\n }\n if (qParams.premium != null) {\n this.stateService.save('loginRedirect', { route: '/settings/premium' });\n } else if (qParams.org != null) {\n this.showCreateOrgMessage = true;\n this.referenceData.flow = qParams.org;\n this.stateService.save('loginRedirect',\n { route: '/settings/create-organization', qParams: { plan: qParams.org } });\n }\n if (qParams.layout != null) {\n this.layout = this.referenceData.layout = qParams.layout;\n }\n if (qParams.reference != null) {\n this.referenceData.id = qParams.reference;\n } else {\n this.referenceData.id = ('; ' + document.cookie).split('; reference=').pop().split(';').shift();\n }\n // Are they coming from an email for sponsoring a families organization\n if (qParams.sponsorshipToken != null) {\n // After logging in redirect them to setup the families sponsorship\n this.stateService.save('loginRedirect', {\n route: '/setup/families-for-enterprise',\n qParams: { token: qParams.sponsorshipToken },\n });\n }\n if (this.referenceData.id === '') {\n this.referenceData.id = null;\n }\n });\n const invite = await this.stateService.get('orgInvitation');\n if (invite != null) {\n try {\n const policies = await this.apiService.getPoliciesByToken(invite.organizationId, invite.token,\n invite.email, invite.organizationUserId);\n if (policies.data != null) {\n const policiesData = policies.data.map(p => new PolicyData(p));\n this.policies = policiesData.map(p => new Policy(p));\n }\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n if (this.policies != null) {\n this.enforcedPolicyOptions = await this.policyService.getMasterPasswordPolicyOptions(this.policies);\n }\n\n await super.ngOnInit();\n }\n\n async submit() {\n if (this.enforcedPolicyOptions != null &&\n !this.policyService.evaluateMasterPassword(this.masterPasswordScore, this.masterPassword,\n this.enforcedPolicyOptions)) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPasswordPolicyRequirementsNotMet'));\n return;\n }\n\n await super.submit();\n }\n}\n","

Companies globally trust Bitwarden for password management.

Start your 7-day free trial!

Quickly deploy your organization

Use Bitwarden across all platforms

Collaborate and share securely

\"Wired\"
\"Bitwarden has become a popular choice among open-source software advocates. After using it for a few months, I can see why.\" - February 2020

Enterprise 3 layout

Enterprise 4 layout

{{'createAccount' | i18n}}

{{'createOrganizationCreatePersonalAccount' | i18n}}
{{'emailAddressDesc' | i18n}}
{{'yourNameDesc' | i18n}}
{{'masterPassDesc' | i18n}}
{{'masterPassHintDesc' | i18n}}

{{'cancel' | i18n}}
","import { Component } from '@angular/core';\n\nimport { RemovePasswordComponent as BaseRemovePasswordComponent } from 'jslib-angular/components/remove-password.component';\n\n@Component({\n selector: 'app-remove-password',\n templateUrl: 'remove-password.component.html',\n})\nexport class RemovePasswordComponent extends BaseRemovePasswordComponent {\n}\n","
\"Bitwarden\"

{{'loading' | i18n}}

{{'removeMasterPassword' | i18n}}


{{'convertOrganizationEncryptionDesc' | i18n : organization.name}}

","import { Component } from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport {\n SetPasswordComponent as BaseSetPasswordComponent,\n} from 'jslib-angular/components/set-password.component';\n\n@Component({\n selector: 'app-set-password',\n templateUrl: 'set-password.component.html',\n})\nexport class SetPasswordComponent extends BaseSetPasswordComponent {\n constructor(apiService: ApiService, i18nService: I18nService,\n cryptoService: CryptoService, messagingService: MessagingService,\n userService: UserService, passwordGenerationService: PasswordGenerationService,\n platformUtilsService: PlatformUtilsService, policyService: PolicyService, router: Router,\n syncService: SyncService, route: ActivatedRoute) {\n super(i18nService, cryptoService, messagingService, userService, passwordGenerationService,\n platformUtilsService, policyService, router, apiService, syncService, route);\n }\n}\n","

{{'setMasterPassword' | i18n}}

{{'loading' | i18n}}
{{'ssoCompleteRegistration' | i18n}} {{'resetPasswordAutoEnrollInviteWarning' | i18n}}
{{'masterPassDesc' | i18n}}
{{'masterPassHintDesc' | i18n}}

","import { Component } from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { first } from 'rxjs/operators';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { AuthService } from 'jslib-common/abstractions/auth.service';\nimport { CryptoFunctionService } from 'jslib-common/abstractions/cryptoFunction.service';\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\n\nimport { SsoComponent as BaseSsoComponent } from 'jslib-angular/components/sso.component';\n\nconst IdentifierStorageKey = 'ssoOrgIdentifier';\n\n@Component({\n selector: 'app-sso',\n templateUrl: 'sso.component.html',\n})\nexport class SsoComponent extends BaseSsoComponent {\n constructor(authService: AuthService, router: Router,\n i18nService: I18nService, route: ActivatedRoute,\n storageService: StorageService, stateService: StateService,\n platformUtilsService: PlatformUtilsService, apiService: ApiService,\n cryptoFunctionService: CryptoFunctionService, environmentService: EnvironmentService,\n passwordGenerationService: PasswordGenerationService, logService: LogService) {\n super(authService, router, i18nService, route, storageService, stateService, platformUtilsService,\n apiService, cryptoFunctionService, environmentService, passwordGenerationService, logService);\n this.redirectUri = window.location.origin + '/sso-connector.html';\n this.clientId = 'web';\n }\n\n async ngOnInit() {\n super.ngOnInit();\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n if (qParams.identifier != null) {\n this.identifier = qParams.identifier;\n } else {\n const storedIdentifier = await this.storageService.get(IdentifierStorageKey);\n if (storedIdentifier != null) {\n this.identifier = storedIdentifier;\n }\n }\n });\n }\n\n async submit() {\n await this.storageService.save(IdentifierStorageKey, this.identifier);\n if (this.clientId === 'browser') {\n document.cookie = `ssoHandOffMessage=${this.i18nService.t('ssoHandOff')};SameSite=strict`;\n }\n super.submit();\n }\n}\n","
{{'loading' | i18n}}

{{'ssoLogInWithOrgIdentifier' | i18n}}


{{'cancel' | i18n}}
","import { Directive } from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { first } from 'rxjs/operators';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { AuthService } from 'jslib-common/abstractions/auth.service';\nimport { CryptoFunctionService } from 'jslib-common/abstractions/cryptoFunction.service';\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\n\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\nimport { AuthResult } from 'jslib-common/models/domain/authResult';\n\n@Directive()\nexport class SsoComponent {\n identifier: string;\n loggingIn = false;\n\n formPromise: Promise;\n initiateSsoFormPromise: Promise;\n onSuccessfulLogin: () => Promise;\n onSuccessfulLoginNavigate: () => Promise;\n onSuccessfulLoginTwoFactorNavigate: () => Promise;\n onSuccessfulLoginChangePasswordNavigate: () => Promise;\n onSuccessfulLoginForceResetNavigate: () => Promise;\n\n protected twoFactorRoute = '2fa';\n protected successRoute = 'lock';\n protected changePasswordRoute = 'set-password';\n protected forcePasswordResetRoute = 'update-temp-password';\n protected clientId: string;\n protected redirectUri: string;\n protected state: string;\n protected codeChallenge: string;\n\n constructor(protected authService: AuthService, protected router: Router,\n protected i18nService: I18nService, protected route: ActivatedRoute,\n protected storageService: StorageService, protected stateService: StateService,\n protected platformUtilsService: PlatformUtilsService, protected apiService: ApiService,\n protected cryptoFunctionService: CryptoFunctionService, protected environmentService: EnvironmentService,\n protected passwordGenerationService: PasswordGenerationService, protected logService: LogService) { }\n\n async ngOnInit() {\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n if (qParams.code != null && qParams.state != null) {\n const codeVerifier = await this.storageService.get(ConstantsService.ssoCodeVerifierKey);\n const state = await this.storageService.get(ConstantsService.ssoStateKey);\n await this.storageService.remove(ConstantsService.ssoCodeVerifierKey);\n await this.storageService.remove(ConstantsService.ssoStateKey);\n if (qParams.code != null && codeVerifier != null && state != null && this.checkState(state, qParams.state)) {\n await this.logIn(qParams.code, codeVerifier, this.getOrgIdentifierFromState(qParams.state));\n }\n } else if (qParams.clientId != null && qParams.redirectUri != null && qParams.state != null &&\n qParams.codeChallenge != null) {\n this.redirectUri = qParams.redirectUri;\n this.state = qParams.state;\n this.codeChallenge = qParams.codeChallenge;\n this.clientId = qParams.clientId;\n }\n });\n }\n\n async submit(returnUri?: string, includeUserIdentifier?: boolean) {\n this.initiateSsoFormPromise = this.preValidate();\n if (await this.initiateSsoFormPromise) {\n const authorizeUrl = await this.buildAuthorizeUrl(returnUri, includeUserIdentifier);\n this.platformUtilsService.launchUri(authorizeUrl, { sameWindow: true });\n }\n }\n\n async preValidate(): Promise {\n if (this.identifier == null || this.identifier === '') {\n this.platformUtilsService.showToast('error', this.i18nService.t('ssoValidationFailed'),\n this.i18nService.t('ssoIdentifierRequired'));\n return false;\n }\n return await this.apiService.preValidateSso(this.identifier);\n }\n\n protected async buildAuthorizeUrl(returnUri?: string, includeUserIdentifier?: boolean): Promise {\n let codeChallenge = this.codeChallenge;\n let state = this.state;\n\n const passwordOptions: any = {\n type: 'password',\n length: 64,\n uppercase: true,\n lowercase: true,\n numbers: true,\n special: false,\n };\n\n if (codeChallenge == null) {\n const codeVerifier = await this.passwordGenerationService.generatePassword(passwordOptions);\n const codeVerifierHash = await this.cryptoFunctionService.hash(codeVerifier, 'sha256');\n codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);\n await this.storageService.save(ConstantsService.ssoCodeVerifierKey, codeVerifier);\n }\n\n if (state == null) {\n state = await this.passwordGenerationService.generatePassword(passwordOptions);\n if (returnUri) {\n state += `_returnUri='${returnUri}'`;\n }\n }\n\n // Add Organization Identifier to state\n state += `_identifier=${this.identifier}`;\n\n // Save state (regardless of new or existing)\n await this.storageService.save(ConstantsService.ssoStateKey, state);\n\n let authorizeUrl = this.environmentService.getIdentityUrl() + '/connect/authorize?' +\n 'client_id=' + this.clientId + '&redirect_uri=' + encodeURIComponent(this.redirectUri) + '&' +\n 'response_type=code&scope=api offline_access&' +\n 'state=' + state + '&code_challenge=' + codeChallenge + '&' +\n 'code_challenge_method=S256&response_mode=query&' +\n 'domain_hint=' + encodeURIComponent(this.identifier);\n\n if (includeUserIdentifier) {\n const userIdentifier = await this.apiService.getSsoUserIdentifier();\n authorizeUrl += `&user_identifier=${encodeURIComponent(userIdentifier)}`;\n }\n\n return authorizeUrl;\n }\n\n private async logIn(code: string, codeVerifier: string, orgIdFromState: string) {\n this.loggingIn = true;\n try {\n this.formPromise = this.authService.logInSso(code, codeVerifier, this.redirectUri, orgIdFromState);\n const response = await this.formPromise;\n if (response.twoFactor) {\n if (this.onSuccessfulLoginTwoFactorNavigate != null) {\n this.onSuccessfulLoginTwoFactorNavigate();\n } else {\n this.router.navigate([this.twoFactorRoute], {\n queryParams: {\n identifier: orgIdFromState,\n sso: 'true',\n },\n });\n }\n } else if (response.resetMasterPassword) {\n if (this.onSuccessfulLoginChangePasswordNavigate != null) {\n this.onSuccessfulLoginChangePasswordNavigate();\n } else {\n this.router.navigate([this.changePasswordRoute], {\n queryParams: {\n identifier: orgIdFromState,\n },\n });\n }\n } else if (response.forcePasswordReset) {\n if (this.onSuccessfulLoginForceResetNavigate != null) {\n this.onSuccessfulLoginForceResetNavigate();\n } else {\n this.router.navigate([this.forcePasswordResetRoute]);\n }\n } else {\n const disableFavicon = await this.storageService.get(ConstantsService.disableFaviconKey);\n await this.stateService.save(ConstantsService.disableFaviconKey, !!disableFavicon);\n if (this.onSuccessfulLogin != null) {\n this.onSuccessfulLogin();\n }\n if (this.onSuccessfulLoginNavigate != null) {\n this.onSuccessfulLoginNavigate();\n } else {\n this.router.navigate([this.successRoute]);\n }\n }\n } catch (e) {\n this.logService.error(e);\n if (e.message === 'Unable to reach key connector') {\n this.platformUtilsService.showToast('error', null, this.i18nService.t('ssoKeyConnectorUnavailable'));\n }\n }\n this.loggingIn = false;\n }\n\n private getOrgIdentifierFromState(state: string): string {\n if (state === null || state === undefined) {\n return null;\n }\n\n const stateSplit = state.split('_identifier=');\n return stateSplit.length > 1 ? stateSplit[1] : null;\n }\n\n private checkState(state: string, checkState: string): boolean {\n if (state === null || state === undefined) {\n return false;\n }\n if (checkState === null || checkState === undefined) {\n return false;\n }\n\n const stateSplit = state.split('_identifier=');\n const checkStateSplit = checkState.split('_identifier=');\n return stateSplit[0] === checkStateSplit[0];\n }\n}\n","import { Component } from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { AuthService } from 'jslib-common/abstractions/auth.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport {\n TwoFactorOptionsComponent as BaseTwoFactorOptionsComponent,\n} from 'jslib-angular/components/two-factor-options.component';\n\n@Component({\n selector: 'app-two-factor-options',\n templateUrl: 'two-factor-options.component.html',\n})\nexport class TwoFactorOptionsComponent extends BaseTwoFactorOptionsComponent {\n constructor(authService: AuthService, router: Router,\n i18nService: I18nService, platformUtilsService: PlatformUtilsService) {\n super(authService, router, i18nService, platformUtilsService, window);\n }\n}\n","

{{'twoStepOptions' | i18n}}

{{p.name}}

{{p.description}}
\"rc

{{'recoveryCodeTitle' | i18n}}

{{'recoveryCodeDesc' | i18n}}
","import {\n Component,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\n\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { AuthService } from 'jslib-common/abstractions/auth.service';\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\n\nimport { TwoFactorComponent as BaseTwoFactorComponent } from 'jslib-angular/components/two-factor.component';\n\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { TwoFactorOptionsComponent } from './two-factor-options.component';\n\n@Component({\n selector: 'app-two-factor',\n templateUrl: 'two-factor.component.html',\n})\nexport class TwoFactorComponent extends BaseTwoFactorComponent {\n @ViewChild('twoFactorOptions', { read: ViewContainerRef, static: true }) twoFactorOptionsModal: ViewContainerRef;\n\n constructor(authService: AuthService, router: Router,\n i18nService: I18nService, apiService: ApiService,\n platformUtilsService: PlatformUtilsService, stateService: StateService,\n environmentService: EnvironmentService, private modalService: ModalService,\n storageService: StorageService, route: ActivatedRoute, logService: LogService) {\n super(authService, router, i18nService, apiService, platformUtilsService, window, environmentService,\n stateService, storageService, route, logService);\n this.onSuccessfulLoginNavigate = this.goAfterLogIn;\n }\n\n async anotherMethod() {\n const [modal] = await this.modalService.openViewRef(TwoFactorOptionsComponent, this.twoFactorOptionsModal, comp => {\n comp.onProviderSelected.subscribe(async (provider: TwoFactorProviderType) => {\n modal.close();\n this.selectedProviderType = provider;\n await this.init();\n });\n comp.onRecoverSelected.subscribe(() => {\n modal.close();\n });\n });\n }\n\n async goAfterLogIn() {\n const loginRedirect = await this.stateService.get('loginRedirect');\n if (loginRedirect != null) {\n this.router.navigate([loginRedirect.route], { queryParams: loginRedirect.qParams });\n await this.stateService.remove('loginRedirect');\n } else {\n this.router.navigate([this.successRoute], {\n queryParams: {\n identifier: this.identifier,\n },\n });\n }\n }\n}\n","

{{title}}

{{'enterVerificationCodeApp' | i18n}}

{{'enterVerificationCodeEmail' | i18n : twoFactorEmail}}

{{'sendVerificationCodeEmailAgain' | i18n}}

{{'insertYubiKey' | i18n}}

\"\"

{{'noTwoStepProviders' | i18n}}

{{'noTwoStepProviders2' | i18n}}


{{'cancel' | i18n}}
","import { SecretVerificationRequest } from './secretVerificationRequest';\n\nexport class TwoFactorEmailRequest extends SecretVerificationRequest {\n email: string;\n}\n","export class KeyConnectorUserKeyRequest {\n key: string;\n\n constructor(key: string) {\n this.key = key;\n }\n}\n","import { Component } from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { UpdateTempPasswordComponent as BaseUpdateTempPasswordComponent } from 'jslib-angular/components/update-temp-password.component';\n\n@Component({\n selector: 'app-update-temp-password',\n templateUrl: 'update-temp-password.component.html',\n})\n\nexport class UpdateTempPasswordComponent extends BaseUpdateTempPasswordComponent {\n constructor(i18nService: I18nService, platformUtilsService: PlatformUtilsService,\n passwordGenerationService: PasswordGenerationService, policyService: PolicyService,\n cryptoService: CryptoService, userService: UserService,\n messagingService: MessagingService, apiService: ApiService,\n syncService: SyncService, logService: LogService) {\n super(i18nService, platformUtilsService, passwordGenerationService, policyService, cryptoService,\n userService, messagingService, apiService, syncService, logService);\n }\n}\n","

{{'updateMasterPassword' | i18n}}

{{'updateMasterPasswordWarning' | i18n}}
{{'masterPassHintDesc' | i18n}}

","export class OrganizationUserResetPasswordRequest {\n newMasterPasswordHash: string;\n key: string;\n}\n","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { first } from 'rxjs/operators';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { VerifyEmailRequest } from 'jslib-common/models/request/verifyEmailRequest';\n\n@Component({\n selector: 'app-verify-email-token',\n templateUrl: 'verify-email-token.component.html',\n})\nexport class VerifyEmailTokenComponent implements OnInit {\n constructor(private router: Router, private toasterService: ToasterService,\n private i18nService: I18nService, private route: ActivatedRoute,\n private apiService: ApiService, private userService: UserService,\n private logService: LogService) { }\n\n ngOnInit() {\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n if (qParams.userId != null && qParams.token != null) {\n try {\n await this.apiService.postAccountVerifyEmailToken(\n new VerifyEmailRequest(qParams.userId, qParams.token));\n const authed = await this.userService.isAuthenticated();\n if (authed) {\n await this.apiService.refreshIdentityToken();\n }\n this.toasterService.popAsync('success', null, this.i18nService.t('emailVerified'));\n this.router.navigate(['/']);\n return;\n } catch (e) {\n this.logService.error(e);\n }\n }\n this.toasterService.popAsync('error', null, this.i18nService.t('emailVerifiedFailed'));\n this.router.navigate(['/']);\n });\n }\n}\n","
\"Bitwarden\"

{{'loading' | i18n}}

","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { first } from 'rxjs/operators';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\nimport { VerifyDeleteRecoverRequest } from 'jslib-common/models/request/verifyDeleteRecoverRequest';\n\n@Component({\n selector: 'app-verify-recover-delete',\n templateUrl: 'verify-recover-delete.component.html',\n})\nexport class VerifyRecoverDeleteComponent implements OnInit {\n email: string;\n formPromise: Promise;\n\n private userId: string;\n private token: string;\n\n constructor(private router: Router, private apiService: ApiService,\n private toasterService: ToasterService, private i18nService: I18nService,\n private route: ActivatedRoute, private logService: LogService) {\n }\n\n ngOnInit() {\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n if (qParams.userId != null && qParams.token != null && qParams.email != null) {\n this.userId = qParams.userId;\n this.token = qParams.token;\n this.email = qParams.email;\n } else {\n this.router.navigate(['/']);\n }\n });\n }\n\n async submit() {\n try {\n const request = new VerifyDeleteRecoverRequest(this.userId, this.token);\n this.formPromise = this.apiService.postAccountRecoverDeleteToken(request);\n await this.formPromise;\n this.toasterService.popAsync('success', this.i18nService.t('accountDeleted'),\n this.i18nService.t('accountDeletedDesc'));\n this.router.navigate(['/']);\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{'deleteAccount' | i18n}}

{{'deleteAccountWarning' | i18n}}

{{email}}

{{'deleteRecoverConfirmDesc' | i18n}}


{{'cancel' | i18n}}
","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { EncString } from 'jslib-common/models/domain/encString';\nimport { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';\nimport { CollectionRequest } from 'jslib-common/models/request/collectionRequest';\nimport { SelectionReadOnlyRequest } from 'jslib-common/models/request/selectionReadOnlyRequest';\nimport { GroupResponse } from 'jslib-common/models/response/groupResponse';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\n@Component({\n selector: 'app-collection-add-edit',\n templateUrl: 'collection-add-edit.component.html',\n})\nexport class CollectionAddEditComponent implements OnInit {\n @Input() collectionId: string;\n @Input() organizationId: string;\n @Input() canSave: boolean;\n @Input() canDelete: boolean;\n @Output() onSavedCollection = new EventEmitter();\n @Output() onDeletedCollection = new EventEmitter();\n\n loading = true;\n editMode: boolean = false;\n accessGroups: boolean = false;\n title: string;\n name: string;\n externalId: string;\n groups: GroupResponse[] = [];\n formPromise: Promise;\n deletePromise: Promise;\n\n private orgKey: SymmetricCryptoKey;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private platformUtilsService: PlatformUtilsService,\n private cryptoService: CryptoService, private userService: UserService,\n private logService: LogService) { }\n\n async ngOnInit() {\n const organization = await this.userService.getOrganization(this.organizationId);\n this.accessGroups = organization.useGroups;\n this.editMode = this.loading = this.collectionId != null;\n if (this.accessGroups) {\n const groupsResponse = await this.apiService.getGroups(this.organizationId);\n this.groups = groupsResponse.data.map(r => r).sort(Utils.getSortFunction(this.i18nService, 'name'));\n }\n this.orgKey = await this.cryptoService.getOrgKey(this.organizationId);\n\n if (this.editMode) {\n this.editMode = true;\n this.title = this.i18nService.t('editCollection');\n try {\n const collection = await this.apiService.getCollectionDetails(this.organizationId, this.collectionId);\n this.name = await this.cryptoService.decryptToUtf8(new EncString(collection.name), this.orgKey);\n this.externalId = collection.externalId;\n if (collection.groups != null && this.groups.length > 0) {\n collection.groups.forEach(s => {\n const group = this.groups.filter(g => !g.accessAll && g.id === s.id);\n if (group != null && group.length > 0) {\n (group[0] as any).checked = true;\n (group[0] as any).readOnly = s.readOnly;\n (group[0] as any).hidePasswords = s.hidePasswords;\n }\n });\n }\n } catch (e) {\n this.logService.error(e);\n }\n } else {\n this.title = this.i18nService.t('addCollection');\n }\n\n this.groups.forEach(g => {\n if (g.accessAll) {\n (g as any).checked = true;\n }\n });\n\n this.loading = false;\n }\n\n check(g: GroupResponse, select?: boolean) {\n if (g.accessAll) {\n return;\n }\n (g as any).checked = select == null ? !(g as any).checked : select;\n if (!(g as any).checked) {\n (g as any).readOnly = false;\n (g as any).hidePasswords = false;\n }\n }\n\n selectAll(select: boolean) {\n this.groups.forEach(g => this.check(g, select));\n }\n\n async submit() {\n if (this.orgKey == null) {\n throw new Error('No encryption key for this organization.');\n }\n\n const request = new CollectionRequest();\n request.name = (await this.cryptoService.encrypt(this.name, this.orgKey)).encryptedString;\n request.externalId = this.externalId;\n request.groups = this.groups.filter(g => (g as any).checked && !g.accessAll)\n .map(g => new SelectionReadOnlyRequest(g.id, !!(g as any).readOnly, !!(g as any).hidePasswords));\n\n try {\n if (this.editMode) {\n this.formPromise = this.apiService.putCollection(this.organizationId, this.collectionId, request);\n } else {\n this.formPromise = this.apiService.postCollection(this.organizationId, request);\n }\n await this.formPromise;\n this.toasterService.popAsync('success', null,\n this.i18nService.t(this.editMode ? 'editedCollectionId' : 'createdCollectionId', this.name));\n this.onSavedCollection.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async delete() {\n if (!this.editMode) {\n return;\n }\n\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('deleteCollectionConfirmation'), this.name,\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.deletePromise = this.apiService.deleteCollection(this.organizationId, this.collectionId);\n await this.deletePromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('deletedCollectionId', this.name));\n this.onDeletedCollection.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{title}}

{{'loading' | i18n}}
{{'externalIdDesc' | i18n}}

{{'groupAccess' | i18n}}

{{'noGroupsInList' | i18n}}
  {{'name' | i18n}} {{'hidePasswords' | i18n}} {{'readOnly' | i18n}}
{{g.name}} {{'groupAccessAllItems' | i18n}}
","import { Collection } from '../domain/collection';\n\nimport { SelectionReadOnlyRequest } from './selectionReadOnlyRequest';\n\nexport class CollectionRequest {\n name: string;\n externalId: string;\n groups: SelectionReadOnlyRequest[] = [];\n\n constructor(collection?: Collection) {\n if (collection == null) {\n return;\n }\n this.name = collection.name ? collection.name.encryptedString : null;\n this.externalId = collection.externalId;\n }\n}\n","import {\n Component,\n OnInit,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { ToasterService } from 'angular2-toaster';\n\nimport { first } from 'rxjs/operators';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { SearchService } from 'jslib-common/abstractions/search.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { CollectionData } from 'jslib-common/models/data/collectionData';\nimport { Collection } from 'jslib-common/models/domain/collection';\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport {\n CollectionDetailsResponse,\n CollectionResponse,\n} from 'jslib-common/models/response/collectionResponse';\nimport { ListResponse } from 'jslib-common/models/response/listResponse';\nimport { CollectionView } from 'jslib-common/models/view/collectionView';\n\nimport { CollectionAddEditComponent } from './collection-add-edit.component';\nimport { EntityUsersComponent } from './entity-users.component';\n\n@Component({\n selector: 'app-org-manage-collections',\n templateUrl: 'collections.component.html',\n})\nexport class CollectionsComponent implements OnInit {\n @ViewChild('addEdit', { read: ViewContainerRef, static: true }) addEditModalRef: ViewContainerRef;\n @ViewChild('usersTemplate', { read: ViewContainerRef, static: true }) usersModalRef: ViewContainerRef;\n\n loading = true;\n organization: Organization;\n canCreate: boolean = false;\n organizationId: string;\n collections: CollectionView[];\n assignedCollections: CollectionView[];\n pagedCollections: CollectionView[];\n searchText: string;\n\n protected didScroll = false;\n protected pageSize = 100;\n\n private pagedCollectionsCount = 0;\n\n constructor(private apiService: ApiService, private route: ActivatedRoute,\n private collectionService: CollectionService, private modalService: ModalService,\n private toasterService: ToasterService, private i18nService: I18nService,\n private platformUtilsService: PlatformUtilsService, private userService: UserService,\n private searchService: SearchService, private logService: LogService) { }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organizationId = params.organizationId;\n await this.load();\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n this.searchText = qParams.search;\n });\n });\n }\n\n async load() {\n this.organization = await this.userService.getOrganization(this.organizationId);\n this.canCreate = this.organization.canCreateNewCollections;\n\n const decryptCollections = async (r: ListResponse) => {\n const collections = r.data.filter(c => c.organizationId === this.organizationId).map(d =>\n new Collection(new CollectionData(d as CollectionDetailsResponse)));\n return await this.collectionService.decryptMany(collections);\n };\n\n if (this.organization.canViewAssignedCollections) {\n const response = await this.apiService.getUserCollections();\n this.assignedCollections = await decryptCollections(response);\n }\n\n if (this.organization.canViewAllCollections) {\n const response = await this.apiService.getCollections(this.organizationId);\n this.collections = await decryptCollections(response);\n } else {\n this.collections = this.assignedCollections;\n }\n\n this.resetPaging();\n this.loading = false;\n }\n\n loadMore() {\n if (!this.collections || this.collections.length <= this.pageSize) {\n return;\n }\n const pagedLength = this.pagedCollections.length;\n let pagedSize = this.pageSize;\n if (pagedLength === 0 && this.pagedCollectionsCount > this.pageSize) {\n pagedSize = this.pagedCollectionsCount;\n }\n if (this.collections.length > pagedLength) {\n this.pagedCollections =\n this.pagedCollections.concat(this.collections.slice(pagedLength, pagedLength + pagedSize));\n }\n this.pagedCollectionsCount = this.pagedCollections.length;\n this.didScroll = this.pagedCollections.length > this.pageSize;\n }\n\n async edit(collection: CollectionView) {\n const canCreate = collection == null && this.canCreate;\n const canEdit = collection != null && this.canEdit(collection);\n const canDelete = collection != null && this.canDelete(collection);\n\n if (!(canCreate || canEdit || canDelete)) {\n this.toasterService.popAsync('error', null, this.i18nService.t('missingPermissions'));\n return;\n }\n\n const [modal] = await this.modalService.openViewRef(CollectionAddEditComponent, this.addEditModalRef, comp => {\n comp.organizationId = this.organizationId;\n comp.collectionId = collection != null ? collection.id : null;\n comp.canSave = canCreate || canEdit;\n comp.canDelete = canDelete;\n comp.onSavedCollection.subscribe(() => {\n modal.close();\n this.load();\n });\n comp.onDeletedCollection.subscribe(() => {\n modal.close();\n this.removeCollection(collection);\n });\n });\n }\n\n add() {\n this.edit(null);\n }\n\n async delete(collection: CollectionView) {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('deleteCollectionConfirmation'), collection.name,\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n await this.apiService.deleteCollection(this.organizationId, collection.id);\n this.toasterService.popAsync('success', null, this.i18nService.t('deletedCollectionId', collection.name));\n this.removeCollection(collection);\n } catch (e) {\n this.logService.error(e);\n this.toasterService.popAsync('error', null, this.i18nService.t('missingPermissions'));\n }\n }\n\n async users(collection: CollectionView) {\n const [modal] = await this.modalService.openViewRef(EntityUsersComponent, this.usersModalRef, comp => {\n comp.organizationId = this.organizationId;\n comp.entity = 'collection';\n comp.entityId = collection.id;\n comp.entityName = collection.name;\n\n comp.onEditedUsers.subscribe(() => {\n this.load();\n modal.close();\n });\n });\n }\n\n async resetPaging() {\n this.pagedCollections = [];\n this.loadMore();\n }\n\n isSearching() {\n return this.searchService.isSearchable(this.searchText);\n }\n\n isPaging() {\n const searching = this.isSearching();\n if (searching && this.didScroll) {\n this.resetPaging();\n }\n return !searching && this.collections && this.collections.length > this.pageSize;\n }\n\n canEdit(collection: CollectionView) {\n if (this.organization.canEditAnyCollection) {\n return true;\n }\n\n if (this.organization.canEditAssignedCollections && this.assignedCollections.some(c => c.id === collection.id)) {\n return true;\n }\n return false;\n }\n\n canDelete(collection: CollectionView) {\n if (this.organization.canDeleteAnyCollection) {\n return true;\n }\n\n if (this.organization.canDeleteAssignedCollections && this.assignedCollections.some(c => c.id === collection.id)) {\n return true;\n }\n return false;\n }\n\n private removeCollection(collection: CollectionView) {\n const index = this.collections.indexOf(collection);\n if (index > -1) {\n this.collections.splice(index, 1);\n this.resetPaging();\n }\n }\n}\n","

{{'collections' | i18n}}

{{'loading' | i18n}}

{{'noCollectionsInList' | i18n}}

{{c.name}}
","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { ToasterService } from 'angular2-toaster';\n\nimport { UserNamePipe } from 'jslib-angular/pipes/user-name.pipe';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { ExportService } from 'jslib-common/abstractions/export.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport { EventResponse } from 'jslib-common/models/response/eventResponse';\n\nimport { EventService } from '../../services/event.service';\n\nimport { BaseEventsComponent } from '../../common/base.events.component';\n\n@Component({\n selector: 'app-org-events',\n templateUrl: 'events.component.html',\n})\nexport class EventsComponent extends BaseEventsComponent implements OnInit {\n exportFileName: string = 'org-events';\n organizationId: string;\n organization: Organization;\n\n private orgUsersUserIdMap = new Map();\n\n constructor(private apiService: ApiService, private route: ActivatedRoute, eventService: EventService,\n i18nService: I18nService, toasterService: ToasterService, private userService: UserService,\n exportService: ExportService, platformUtilsService: PlatformUtilsService, private router: Router,\n logService: LogService, private userNamePipe: UserNamePipe) {\n super(eventService, i18nService, toasterService, exportService, platformUtilsService, logService);\n }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organizationId = params.organizationId;\n this.organization = await this.userService.getOrganization(this.organizationId);\n if (this.organization == null || !this.organization.useEvents) {\n this.router.navigate(['/organizations', this.organizationId]);\n return;\n }\n\n await this.load();\n });\n }\n\n async load() {\n const response = await this.apiService.getOrganizationUsers(this.organizationId);\n response.data.forEach(u => {\n const name = this.userNamePipe.transform(u);\n this.orgUsersUserIdMap.set(u.userId, { name: name, email: u.email });\n });\n\n if (this.organization.providerId != null) {\n try {\n const provider = await this.userService.getProvider(this.organization.providerId);\n if (provider != null && (await this.userService.getProvider(this.organization.providerId)).canManageUsers) {\n const providerUsersResponse = await this.apiService.getProviderUsers(this.organization.providerId);\n providerUsersResponse.data.forEach(u => {\n const name = this.userNamePipe.transform(u);\n this.orgUsersUserIdMap.set(u.userId, { name: `${name} (${this.organization.providerName})`, email: u.email });\n });\n }\n } catch (e) {\n this.logService.warning(e);\n }\n }\n\n await this.loadEvents(true);\n this.loaded = true;\n }\n\n protected requestEvents(startDate: string, endDate: string, continuationToken: string) {\n return this.apiService.getEventsOrganization(this.organizationId, startDate, endDate, continuationToken);\n }\n\n protected getUserName(r: EventResponse, userId: string) {\n if (userId == null) {\n return null;\n }\n\n if (this.orgUsersUserIdMap.has(userId)) {\n return this.orgUsersUserIdMap.get(userId);\n }\n\n if (r.providerId != null && r.providerId === this.organization.providerId) {\n return {\n 'name': this.organization.providerName,\n };\n }\n\n return null;\n }\n}\n","

{{'eventLogs' | i18n}}

-
{{'loading' | i18n}}

{{'noEventsInList' | i18n}}

{{'timestamp' | i18n}} {{'device' | i18n}} {{'user' | i18n}} {{'event' | i18n}}
{{e.date | date:'medium'}} {{e.appName}}, {{e.ip}} {{e.userName}}
","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { CollectionData } from 'jslib-common/models/data/collectionData';\nimport { Collection } from 'jslib-common/models/domain/collection';\nimport { GroupRequest } from 'jslib-common/models/request/groupRequest';\nimport { SelectionReadOnlyRequest } from 'jslib-common/models/request/selectionReadOnlyRequest';\nimport { CollectionDetailsResponse } from 'jslib-common/models/response/collectionResponse';\nimport { CollectionView } from 'jslib-common/models/view/collectionView';\n\n@Component({\n selector: 'app-group-add-edit',\n templateUrl: 'group-add-edit.component.html',\n})\nexport class GroupAddEditComponent implements OnInit {\n @Input() groupId: string;\n @Input() organizationId: string;\n @Output() onSavedGroup = new EventEmitter();\n @Output() onDeletedGroup = new EventEmitter();\n\n loading = true;\n editMode: boolean = false;\n title: string;\n name: string;\n externalId: string;\n access: 'all' | 'selected' = 'selected';\n collections: CollectionView[] = [];\n formPromise: Promise;\n deletePromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private collectionService: CollectionService,\n private platformUtilsService: PlatformUtilsService, private logService: LogService) { }\n\n async ngOnInit() {\n this.editMode = this.loading = this.groupId != null;\n await this.loadCollections();\n\n if (this.editMode) {\n this.editMode = true;\n this.title = this.i18nService.t('editGroup');\n try {\n const group = await this.apiService.getGroupDetails(this.organizationId, this.groupId);\n this.access = group.accessAll ? 'all' : 'selected';\n this.name = group.name;\n this.externalId = group.externalId;\n if (group.collections != null && this.collections != null) {\n group.collections.forEach(s => {\n const collection = this.collections.filter(c => c.id === s.id);\n if (collection != null && collection.length > 0) {\n (collection[0] as any).checked = true;\n collection[0].readOnly = s.readOnly;\n collection[0].hidePasswords = s.hidePasswords;\n }\n });\n }\n } catch (e) {\n this.logService.error(e);\n }\n } else {\n this.title = this.i18nService.t('addGroup');\n }\n\n this.loading = false;\n }\n\n async loadCollections() {\n const response = await this.apiService.getCollections(this.organizationId);\n const collections = response.data.map(r =>\n new Collection(new CollectionData(r as CollectionDetailsResponse)));\n this.collections = await this.collectionService.decryptMany(collections);\n }\n\n check(c: CollectionView, select?: boolean) {\n (c as any).checked = select == null ? !(c as any).checked : select;\n if (!(c as any).checked) {\n c.readOnly = false;\n }\n }\n\n selectAll(select: boolean) {\n this.collections.forEach(c => this.check(c, select));\n }\n\n async submit() {\n const request = new GroupRequest();\n request.name = this.name;\n request.externalId = this.externalId;\n request.accessAll = this.access === 'all';\n if (!request.accessAll) {\n request.collections = this.collections.filter(c => (c as any).checked)\n .map(c => new SelectionReadOnlyRequest(c.id, !!c.readOnly, !!c.hidePasswords));\n }\n\n try {\n if (this.editMode) {\n this.formPromise = this.apiService.putGroup(this.organizationId, this.groupId, request);\n } else {\n this.formPromise = this.apiService.postGroup(this.organizationId, request);\n }\n await this.formPromise;\n this.toasterService.popAsync('success', null,\n this.i18nService.t(this.editMode ? 'editedGroupId' : 'createdGroupId', this.name));\n this.onSavedGroup.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async delete() {\n if (!this.editMode) {\n return;\n }\n\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('deleteGroupConfirmation'), this.name,\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.deletePromise = this.apiService.deleteGroup(this.organizationId, this.groupId);\n await this.deletePromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('deletedGroupId', this.name));\n this.onDeletedGroup.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{title}}

{{'loading' | i18n}}
{{'externalIdDesc' | i18n}}

{{'accessControl' | i18n}}

{{'noCollectionsInList' | i18n}}
  {{'name' | i18n}} {{'hidePasswords' | i18n}} {{'readOnly' | i18n}}
{{c.name}}
","import {\n Component,\n OnInit,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { first } from 'rxjs/operators';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { SearchService } from 'jslib-common/abstractions/search.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { GroupResponse } from 'jslib-common/models/response/groupResponse';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\nimport { EntityUsersComponent } from './entity-users.component';\nimport { GroupAddEditComponent } from './group-add-edit.component';\n\n@Component({\n selector: 'app-org-groups',\n templateUrl: 'groups.component.html',\n})\nexport class GroupsComponent implements OnInit {\n @ViewChild('addEdit', { read: ViewContainerRef, static: true }) addEditModalRef: ViewContainerRef;\n @ViewChild('usersTemplate', { read: ViewContainerRef, static: true }) usersModalRef: ViewContainerRef;\n\n loading = true;\n organizationId: string;\n groups: GroupResponse[];\n pagedGroups: GroupResponse[];\n searchText: string;\n\n protected didScroll = false;\n protected pageSize = 100;\n\n private pagedGroupsCount = 0;\n\n constructor(private apiService: ApiService, private route: ActivatedRoute,\n private i18nService: I18nService, private modalService: ModalService,\n private toasterService: ToasterService, private platformUtilsService: PlatformUtilsService,\n private userService: UserService, private router: Router,\n private searchService: SearchService, private logService: LogService) { }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organizationId = params.organizationId;\n const organization = await this.userService.getOrganization(this.organizationId);\n if (organization == null || !organization.useGroups) {\n this.router.navigate(['/organizations', this.organizationId]);\n return;\n }\n await this.load();\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n this.searchText = qParams.search;\n });\n });\n }\n\n async load() {\n const response = await this.apiService.getGroups(this.organizationId);\n const groups = response.data != null && response.data.length > 0 ? response.data : [];\n groups.sort(Utils.getSortFunction(this.i18nService, 'name'));\n this.groups = groups;\n this.resetPaging();\n this.loading = false;\n }\n\n loadMore() {\n if (!this.groups || this.groups.length <= this.pageSize) {\n return;\n }\n const pagedLength = this.pagedGroups.length;\n let pagedSize = this.pageSize;\n if (pagedLength === 0 && this.pagedGroupsCount > this.pageSize) {\n pagedSize = this.pagedGroupsCount;\n }\n if (this.groups.length > pagedLength) {\n this.pagedGroups = this.pagedGroups.concat(this.groups.slice(pagedLength, pagedLength + pagedSize));\n }\n this.pagedGroupsCount = this.pagedGroups.length;\n this.didScroll = this.pagedGroups.length > this.pageSize;\n }\n\n async edit(group: GroupResponse) {\n const [modal] = await this.modalService.openViewRef(GroupAddEditComponent, this.addEditModalRef, comp => {\n comp.organizationId = this.organizationId;\n comp.groupId = group != null ? group.id : null;\n comp.onSavedGroup.subscribe(() => {\n modal.close();\n this.load();\n });\n comp.onDeletedGroup.subscribe(() => {\n modal.close();\n this.removeGroup(group);\n });\n });\n }\n\n add() {\n this.edit(null);\n }\n\n async delete(group: GroupResponse) {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('deleteGroupConfirmation'), group.name,\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n await this.apiService.deleteGroup(this.organizationId, group.id);\n this.toasterService.popAsync('success', null, this.i18nService.t('deletedGroupId', group.name));\n this.removeGroup(group);\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async users(group: GroupResponse) {\n const [modal] = await this.modalService.openViewRef(EntityUsersComponent, this.usersModalRef, comp => {\n comp.organizationId = this.organizationId;\n comp.entity = 'group';\n comp.entityId = group.id;\n comp.entityName = group.name;\n\n comp.onEditedUsers.subscribe(() => {\n modal.close();\n });\n });\n }\n\n async resetPaging() {\n this.pagedGroups = [];\n this.loadMore();\n }\n\n isSearching() {\n return this.searchService.isSearchable(this.searchText);\n }\n\n isPaging() {\n const searching = this.isSearching();\n if (searching && this.didScroll) {\n this.resetPaging();\n }\n return !searching && this.groups && this.groups.length > this.pageSize;\n }\n\n private removeGroup(group: GroupResponse) {\n const index = this.groups.indexOf(group);\n if (index > -1) {\n this.groups.splice(index, 1);\n this.resetPaging();\n }\n }\n}\n","

{{'groups' | i18n}}

{{'loading' | i18n}}

{{'noGroupsInList' | i18n}}

{{g.name}}
","import {\n Component,\n OnInit,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\n\nimport { first } from 'rxjs/operators';\n\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ValidationService } from 'jslib-angular/services/validation.service';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { SearchService } from 'jslib-common/abstractions/search.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { OrganizationKeysRequest } from 'jslib-common/models/request/organizationKeysRequest';\nimport { OrganizationUserBulkRequest } from 'jslib-common/models/request/organizationUserBulkRequest';\nimport { OrganizationUserConfirmRequest } from 'jslib-common/models/request/organizationUserConfirmRequest';\n\nimport { ListResponse } from 'jslib-common/models/response/listResponse';\nimport { OrganizationUserBulkResponse } from 'jslib-common/models/response/organizationUserBulkResponse';\nimport { OrganizationUserUserDetailsResponse } from 'jslib-common/models/response/organizationUserResponse';\n\nimport { OrganizationUserStatusType } from 'jslib-common/enums/organizationUserStatusType';\nimport { OrganizationUserType } from 'jslib-common/enums/organizationUserType';\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { SearchPipe } from 'jslib-angular/pipes/search.pipe';\nimport { UserNamePipe } from 'jslib-angular/pipes/user-name.pipe';\n\nimport { BasePeopleComponent } from '../../common/base.people.component';\nimport { BulkConfirmComponent } from './bulk/bulk-confirm.component';\nimport { BulkRemoveComponent } from './bulk/bulk-remove.component';\nimport { BulkStatusComponent } from './bulk/bulk-status.component';\nimport { EntityEventsComponent } from './entity-events.component';\nimport { ResetPasswordComponent } from './reset-password.component';\nimport { UserAddEditComponent } from './user-add-edit.component';\nimport { UserGroupsComponent } from './user-groups.component';\n\n@Component({\n selector: 'app-org-people',\n templateUrl: 'people.component.html',\n})\nexport class PeopleComponent extends BasePeopleComponent implements OnInit {\n @ViewChild('addEdit', { read: ViewContainerRef, static: true }) addEditModalRef: ViewContainerRef;\n @ViewChild('groupsTemplate', { read: ViewContainerRef, static: true }) groupsModalRef: ViewContainerRef;\n @ViewChild('eventsTemplate', { read: ViewContainerRef, static: true }) eventsModalRef: ViewContainerRef;\n @ViewChild('confirmTemplate', { read: ViewContainerRef, static: true }) confirmModalRef: ViewContainerRef;\n @ViewChild('resetPasswordTemplate', { read: ViewContainerRef, static: true }) resetPasswordModalRef: ViewContainerRef;\n @ViewChild('bulkStatusTemplate', { read: ViewContainerRef, static: true }) bulkStatusModalRef: ViewContainerRef;\n @ViewChild('bulkConfirmTemplate', { read: ViewContainerRef, static: true }) bulkConfirmModalRef: ViewContainerRef;\n @ViewChild('bulkRemoveTemplate', { read: ViewContainerRef, static: true }) bulkRemoveModalRef: ViewContainerRef;\n\n userType = OrganizationUserType;\n userStatusType = OrganizationUserStatusType;\n\n organizationId: string;\n status: OrganizationUserStatusType = null;\n accessEvents = false;\n accessGroups = false;\n canResetPassword = false; // User permission (admin/custom)\n orgUseResetPassword = false; // Org plan ability\n orgHasKeys = false; // Org public/private keys\n orgResetPasswordPolicyEnabled = false;\n callingUserType: OrganizationUserType = null;\n\n constructor(apiService: ApiService, private route: ActivatedRoute,\n i18nService: I18nService, modalService: ModalService,\n platformUtilsService: PlatformUtilsService, toasterService: ToasterService,\n cryptoService: CryptoService, private userService: UserService, private router: Router,\n storageService: StorageService, searchService: SearchService,\n validationService: ValidationService, private policyService: PolicyService,\n logService: LogService, searchPipe: SearchPipe, userNamePipe: UserNamePipe, private syncService: SyncService) {\n super(apiService, searchService, i18nService, platformUtilsService, toasterService, cryptoService,\n storageService, validationService, modalService, logService, searchPipe, userNamePipe);\n }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organizationId = params.organizationId;\n const organization = await this.userService.getOrganization(this.organizationId);\n if (!organization.canManageUsers) {\n this.router.navigate(['../collections'], { relativeTo: this.route });\n return;\n }\n this.accessEvents = organization.useEvents;\n this.accessGroups = organization.useGroups;\n this.canResetPassword = organization.canManageUsersPassword;\n this.orgUseResetPassword = organization.useResetPassword;\n this.callingUserType = organization.type;\n this.orgHasKeys = organization.hasPublicAndPrivateKeys;\n\n // Backfill pub/priv key if necessary\n if (this.canResetPassword && !this.orgHasKeys) {\n const orgShareKey = await this.cryptoService.getOrgKey(this.organizationId);\n const orgKeys = await this.cryptoService.makeKeyPair(orgShareKey);\n const request = new OrganizationKeysRequest(orgKeys[0], orgKeys[1].encryptedString);\n const response = await this.apiService.postOrganizationKeys(this.organizationId, request);\n if (response != null) {\n this.orgHasKeys = response.publicKey != null && response.privateKey != null;\n await this.syncService.fullSync(true); // Replace oganizations with new data\n } else {\n throw new Error(this.i18nService.t('resetPasswordOrgKeysError'));\n }\n }\n\n await this.load();\n\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n this.searchText = qParams.search;\n if (qParams.viewEvents != null) {\n const user = this.users.filter(u => u.id === qParams.viewEvents);\n if (user.length > 0 && user[0].status === OrganizationUserStatusType.Confirmed) {\n this.events(user[0]);\n }\n }\n });\n });\n }\n\n async load() {\n const resetPasswordPolicy = await this.policyService.getPolicyForOrganization(PolicyType.ResetPassword,\n this.organizationId);\n this.orgResetPasswordPolicyEnabled = resetPasswordPolicy?.enabled;\n super.load();\n }\n\n getUsers(): Promise> {\n return this.apiService.getOrganizationUsers(this.organizationId);\n }\n\n deleteUser(id: string): Promise {\n return this.apiService.deleteOrganizationUser(this.organizationId, id);\n }\n\n reinviteUser(id: string): Promise {\n return this.apiService.postOrganizationUserReinvite(this.organizationId, id);\n }\n\n async confirmUser(user: OrganizationUserUserDetailsResponse, publicKey: Uint8Array): Promise {\n const orgKey = await this.cryptoService.getOrgKey(this.organizationId);\n const key = await this.cryptoService.rsaEncrypt(orgKey.key, publicKey.buffer);\n const request = new OrganizationUserConfirmRequest();\n request.key = key.encryptedString;\n await this.apiService.postOrganizationUserConfirm(this.organizationId, user.id, request);\n }\n\n allowResetPassword(orgUser: OrganizationUserUserDetailsResponse): boolean {\n // Hierarchy check\n let callingUserHasPermission = false;\n\n switch (this.callingUserType) {\n case OrganizationUserType.Owner:\n callingUserHasPermission = true;\n break;\n case OrganizationUserType.Admin:\n callingUserHasPermission = orgUser.type !== OrganizationUserType.Owner;\n break;\n case OrganizationUserType.Custom:\n callingUserHasPermission = orgUser.type !== OrganizationUserType.Owner\n && orgUser.type !== OrganizationUserType.Admin;\n break;\n }\n\n // Final\n return this.canResetPassword && callingUserHasPermission && this.orgUseResetPassword && this.orgHasKeys\n && orgUser.resetPasswordEnrolled && this.orgResetPasswordPolicyEnabled\n && orgUser.status === OrganizationUserStatusType.Confirmed;\n }\n\n showEnrolledStatus(orgUser: OrganizationUserUserDetailsResponse): boolean {\n return this.orgUseResetPassword && orgUser.resetPasswordEnrolled && this.orgResetPasswordPolicyEnabled;\n }\n\n async edit(user: OrganizationUserUserDetailsResponse) {\n const [modal] = await this.modalService.openViewRef(UserAddEditComponent, this.addEditModalRef, comp => {\n comp.name = this.userNamePipe.transform(user);\n comp.organizationId = this.organizationId;\n comp.organizationUserId = user != null ? user.id : null;\n comp.usesKeyConnector = user?.usesKeyConnector;\n comp.onSavedUser.subscribe(() => {\n modal.close();\n this.load();\n });\n comp.onDeletedUser.subscribe(() => {\n modal.close();\n this.removeUser(user);\n });\n });\n }\n\n async groups(user: OrganizationUserUserDetailsResponse) {\n const [modal] = await this.modalService.openViewRef(UserGroupsComponent, this.groupsModalRef, comp => {\n comp.name = this.userNamePipe.transform(user);\n comp.organizationId = this.organizationId;\n comp.organizationUserId = user != null ? user.id : null;\n comp.onSavedUser.subscribe(() => {\n modal.close();\n });\n });\n }\n\n async bulkRemove() {\n if (this.actionPromise != null) {\n return;\n }\n\n const [modal] = await this.modalService.openViewRef(BulkRemoveComponent, this.bulkRemoveModalRef, comp => {\n comp.organizationId = this.organizationId;\n comp.users = this.getCheckedUsers();\n });\n\n await modal.onClosedPromise();\n await this.load();\n }\n\n async bulkReinvite() {\n if (this.actionPromise != null) {\n return;\n }\n\n const users = this.getCheckedUsers();\n const filteredUsers = users.filter(u => u.status === OrganizationUserStatusType.Invited);\n\n if (filteredUsers.length <= 0) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('noSelectedUsersApplicable'));\n return;\n }\n\n try {\n const request = new OrganizationUserBulkRequest(filteredUsers.map(user => user.id));\n const response = this.apiService.postManyOrganizationUserReinvite(this.organizationId, request);\n this.showBulkStatus(users, filteredUsers, response, this.i18nService.t('bulkReinviteMessage'));\n } catch (e) {\n this.validationService.showError(e);\n }\n this.actionPromise = null;\n }\n\n async bulkConfirm() {\n if (this.actionPromise != null) {\n return;\n }\n\n const [modal] = await this.modalService.openViewRef(BulkConfirmComponent, this.bulkConfirmModalRef, comp => {\n comp.organizationId = this.organizationId;\n comp.users = this.getCheckedUsers();\n });\n\n await modal.onClosedPromise();\n await this.load();\n }\n\n async events(user: OrganizationUserUserDetailsResponse) {\n const [modal] = await this.modalService.openViewRef(EntityEventsComponent, this.eventsModalRef, comp => {\n comp.name = this.userNamePipe.transform(user);\n comp.organizationId = this.organizationId;\n comp.entityId = user.id;\n comp.showUser = false;\n comp.entity = 'user';\n });\n }\n\n async resetPassword(user: OrganizationUserUserDetailsResponse) {\n const [modal] = await this.modalService.openViewRef(ResetPasswordComponent, this.resetPasswordModalRef, comp => {\n comp.name = this.userNamePipe.transform(user);\n comp.email = user != null ? user.email : null;\n comp.organizationId = this.organizationId;\n comp.id = user != null ? user.id : null;\n\n comp.onPasswordReset.subscribe(() => {\n modal.close();\n this.load();\n });\n });\n }\n\n protected deleteWarningMessage(user: OrganizationUserUserDetailsResponse): string {\n if (user.usesKeyConnector) {\n return this.i18nService.t('removeUserConfirmationKeyConnector');\n }\n\n return super.deleteWarningMessage(user);\n }\n\n private async showBulkStatus(users: OrganizationUserUserDetailsResponse[], filteredUsers: OrganizationUserUserDetailsResponse[],\n request: Promise>, successfullMessage: string) {\n\n const [modal, childComponent] = await this.modalService.openViewRef(BulkStatusComponent, this.bulkStatusModalRef, comp => {\n comp.loading = true;\n });\n\n // Workaround to handle closing the modal shortly after it has been opened\n let close = false;\n modal.onShown.subscribe(() => {\n if (close) {\n modal.close();\n }\n });\n\n try {\n const response = await request;\n\n if (modal) {\n const keyedErrors: any = response.data.filter(r => r.error !== '').reduce((a, x) => ({ ...a, [x.id]: x.error }), {});\n const keyedFilteredUsers: any = filteredUsers.reduce((a, x) => ({ ...a, [x.id]: x }), {});\n\n childComponent.users = users.map(user => {\n let message = keyedErrors[user.id] ?? successfullMessage;\n if (!keyedFilteredUsers.hasOwnProperty(user.id)) {\n message = this.i18nService.t('bulkFilteredMessage');\n }\n\n return {\n user: user,\n error: keyedErrors.hasOwnProperty(user.id),\n message: message,\n };\n });\n childComponent.loading = false;\n }\n } catch {\n close = true;\n modal.close();\n }\n }\n}\n","

{{'people' | i18n}}

{{'loading' | i18n}}

{{'noUsersInList' | i18n}}

{{'usersNeedConfirmed' | i18n}}
{{u.email}} {{'invited' | i18n}} {{'accepted' | i18n}} {{u.name}} {{'userUsingTwoStep' | i18n}} {{'enrolledPasswordReset' | i18n}} {{'owner' | i18n}} {{'admin' | i18n}} {{'manager' | i18n}} {{'user' | i18n}} {{'custom' | i18n}}
","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\n\nimport { EncString } from 'jslib-common/models/domain/encString';\nimport { MasterPasswordPolicyOptions } from 'jslib-common/models/domain/masterPasswordPolicyOptions';\nimport { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';\n\nimport { OrganizationUserResetPasswordRequest } from 'jslib-common/models/request/organizationUserResetPasswordRequest';\n\n@Component({\n selector: 'app-reset-password',\n templateUrl: 'reset-password.component.html',\n})\nexport class ResetPasswordComponent implements OnInit {\n @Input() name: string;\n @Input() email: string;\n @Input() id: string;\n @Input() organizationId: string;\n @Output() onPasswordReset = new EventEmitter();\n\n enforcedPolicyOptions: MasterPasswordPolicyOptions;\n newPassword: string = null;\n showPassword: boolean = false;\n masterPasswordScore: number;\n formPromise: Promise;\n private newPasswordStrengthTimeout: any;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private platformUtilsService: PlatformUtilsService, private passwordGenerationService: PasswordGenerationService,\n private policyService: PolicyService, private cryptoService: CryptoService, private logService: LogService) { }\n\n async ngOnInit() {\n // Get Enforced Policy Options\n this.enforcedPolicyOptions = await this.policyService.getMasterPasswordPolicyOptions();\n }\n\n get loggedOutWarningName() {\n return this.name != null ? this.name : this.i18nService.t('thisUser');\n }\n\n async generatePassword() {\n const options = (await this.passwordGenerationService.getOptions())[0];\n this.newPassword = await this.passwordGenerationService.generatePassword(options);\n this.updatePasswordStrength();\n }\n\n togglePassword() {\n this.showPassword = !this.showPassword;\n document.getElementById('newPassword').focus();\n }\n\n copy(value: string) {\n if (value == null) {\n return;\n }\n\n this.platformUtilsService.copyToClipboard(value, { window: window });\n this.platformUtilsService.showToast('info', null,\n this.i18nService.t('valueCopied', this.i18nService.t('password')));\n }\n\n async submit() {\n // Validation\n if (this.newPassword == null || this.newPassword === '') {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPassRequired'));\n return false;\n }\n\n if (this.newPassword.length < 8) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPassLength'));\n return false;\n }\n\n if (this.enforcedPolicyOptions != null &&\n !this.policyService.evaluateMasterPassword(this.masterPasswordScore, this.newPassword,\n this.enforcedPolicyOptions)) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPasswordPolicyRequirementsNotMet'));\n return;\n }\n\n if (this.masterPasswordScore < 3) {\n const result = await this.platformUtilsService.showDialog(this.i18nService.t('weakMasterPasswordDesc'),\n this.i18nService.t('weakMasterPassword'), this.i18nService.t('yes'), this.i18nService.t('no'),\n 'warning');\n if (!result) {\n return false;\n }\n }\n\n // Get user Information (kdf type, kdf iterations, resetPasswordKey, private key) and change password\n try {\n this.formPromise = this.apiService.getOrganizationUserResetPasswordDetails(this.organizationId, this.id)\n .then(async response => {\n if (response == null) {\n throw new Error(this.i18nService.t('resetPasswordDetailsError'));\n }\n\n const kdfType = response.kdf;\n const kdfIterations = response.kdfIterations;\n const resetPasswordKey = response.resetPasswordKey;\n const encryptedPrivateKey = response.encryptedPrivateKey;\n\n // Decrypt Organization's encrypted Private Key with org key\n const orgSymKey = await this.cryptoService.getOrgKey(this.organizationId);\n const decPrivateKey = await this.cryptoService.decryptToBytes(new EncString(encryptedPrivateKey), orgSymKey);\n\n // Decrypt User's Reset Password Key to get EncKey\n const decValue = await this.cryptoService.rsaDecrypt(resetPasswordKey, decPrivateKey);\n const userEncKey = new SymmetricCryptoKey(decValue);\n\n // Create new key and hash new password\n const newKey = await this.cryptoService.makeKey(this.newPassword, this.email.trim().toLowerCase(),\n kdfType, kdfIterations);\n const newPasswordHash = await this.cryptoService.hashPassword(this.newPassword, newKey);\n\n // Create new encKey for the User\n const newEncKey = await this.cryptoService.remakeEncKey(newKey, userEncKey);\n\n // Create request\n const request = new OrganizationUserResetPasswordRequest();\n request.key = newEncKey[1].encryptedString;\n request.newMasterPasswordHash = newPasswordHash;\n\n // Change user's password\n return this.apiService.putOrganizationUserResetPassword(this.organizationId, this.id, request);\n });\n\n await this.formPromise;\n this.platformUtilsService.showToast('success', null, this.i18nService.t('resetPasswordSuccess'));\n this.onPasswordReset.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n updatePasswordStrength() {\n if (this.newPasswordStrengthTimeout != null) {\n clearTimeout(this.newPasswordStrengthTimeout);\n }\n this.newPasswordStrengthTimeout = setTimeout(() => {\n const strengthResult = this.passwordGenerationService.passwordStrength(this.newPassword,\n this.getPasswordStrengthUserInput());\n this.masterPasswordScore = strengthResult == null ? null : strengthResult.score;\n }, 300);\n }\n\n private getPasswordStrengthUserInput() {\n let userInput: string[] = [];\n const atPosition = this.email.indexOf('@');\n if (atPosition > -1) {\n userInput = userInput.concat(this.email.substr(0, atPosition).trim().toLowerCase().split(/[^A-Za-z0-9]/));\n }\n if (this.name != null && this.name !== '') {\n userInput = userInput.concat(this.name.trim().toLowerCase().split(' '));\n }\n return userInput;\n }\n}\n","

{{'resetPassword' | i18n}} {{name}}

{{'resetPasswordLoggedOutWarning' | i18n: loggedOutWarningName}}
","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { CollectionData } from 'jslib-common/models/data/collectionData';\nimport { Collection } from 'jslib-common/models/domain/collection';\nimport { OrganizationUserInviteRequest } from 'jslib-common/models/request/organizationUserInviteRequest';\nimport { OrganizationUserUpdateRequest } from 'jslib-common/models/request/organizationUserUpdateRequest';\nimport { SelectionReadOnlyRequest } from 'jslib-common/models/request/selectionReadOnlyRequest';\nimport { CollectionDetailsResponse } from 'jslib-common/models/response/collectionResponse';\nimport { CollectionView } from 'jslib-common/models/view/collectionView';\n\nimport { OrganizationUserType } from 'jslib-common/enums/organizationUserType';\nimport { PermissionsApi } from 'jslib-common/models/api/permissionsApi';\n\n@Component({\n selector: 'app-user-add-edit',\n templateUrl: 'user-add-edit.component.html',\n})\nexport class UserAddEditComponent implements OnInit {\n @Input() name: string;\n @Input() organizationUserId: string;\n @Input() organizationId: string;\n @Input() usesKeyConnector: boolean = false;\n @Output() onSavedUser = new EventEmitter();\n @Output() onDeletedUser = new EventEmitter();\n\n loading = true;\n editMode: boolean = false;\n title: string;\n emails: string;\n type: OrganizationUserType = OrganizationUserType.User;\n permissions = new PermissionsApi();\n showCustom = false;\n access: 'all' | 'selected' = 'selected';\n collections: CollectionView[] = [];\n formPromise: Promise;\n deletePromise: Promise;\n organizationUserType = OrganizationUserType;\n\n manageAllCollectionsCheckboxes = [\n {\n id: 'createNewCollections',\n get: () => this.permissions.createNewCollections,\n set: (v: boolean) => this.permissions.createNewCollections = v,\n },\n {\n id: 'editAnyCollection',\n get: () => this.permissions.editAnyCollection,\n set: (v: boolean) => this.permissions.editAnyCollection = v,\n },\n {\n id: 'deleteAnyCollection',\n get: () => this.permissions.deleteAnyCollection,\n set: (v: boolean) => this.permissions.deleteAnyCollection = v,\n },\n ];\n\n manageAssignedCollectionsCheckboxes = [\n {\n id: 'editAssignedCollections',\n get: () => this.permissions.editAssignedCollections,\n set: (v: boolean) => this.permissions.editAssignedCollections = v,\n },\n {\n id: 'deleteAssignedCollections',\n get: () => this.permissions.deleteAssignedCollections,\n set: (v: boolean) => this.permissions.deleteAssignedCollections = v,\n },\n ];\n\n get customUserTypeSelected(): boolean {\n return this.type === OrganizationUserType.Custom;\n }\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private collectionService: CollectionService,\n private platformUtilsService: PlatformUtilsService, private logService: LogService) { }\n\n async ngOnInit() {\n this.editMode = this.loading = this.organizationUserId != null;\n await this.loadCollections();\n\n if (this.editMode) {\n this.editMode = true;\n this.title = this.i18nService.t('editUser');\n try {\n const user = await this.apiService.getOrganizationUser(this.organizationId, this.organizationUserId);\n this.access = user.accessAll ? 'all' : 'selected';\n this.type = user.type;\n if (user.type === OrganizationUserType.Custom) {\n this.permissions = user.permissions;\n }\n if (user.collections != null && this.collections != null) {\n user.collections.forEach(s => {\n const collection = this.collections.filter(c => c.id === s.id);\n if (collection != null && collection.length > 0) {\n (collection[0] as any).checked = true;\n collection[0].readOnly = s.readOnly;\n collection[0].hidePasswords = s.hidePasswords;\n }\n });\n }\n } catch (e) {\n this.logService.error(e);\n }\n } else {\n this.title = this.i18nService.t('inviteUser');\n }\n\n this.loading = false;\n }\n\n async loadCollections() {\n const response = await this.apiService.getCollections(this.organizationId);\n const collections = response.data.map(r =>\n new Collection(new CollectionData(r as CollectionDetailsResponse)));\n this.collections = await this.collectionService.decryptMany(collections);\n }\n\n check(c: CollectionView, select?: boolean) {\n (c as any).checked = select == null ? !(c as any).checked : select;\n if (!(c as any).checked) {\n c.readOnly = false;\n }\n }\n\n selectAll(select: boolean) {\n this.collections.forEach(c => this.check(c, select));\n }\n\n setRequestPermissions(p: PermissionsApi, clearPermissions: boolean) {\n Object.assign(p, clearPermissions ? new PermissionsApi() : this.permissions);\n return p;\n }\n\n handleDependentPermissions() {\n // Manage Password Reset must have Manage Users enabled\n if (this.permissions.manageResetPassword && !this.permissions.manageUsers) {\n this.permissions.manageUsers = true;\n (document.getElementById('manageUsers') as HTMLInputElement).checked = true;\n this.platformUtilsService.showToast('info', null, this.i18nService.t('resetPasswordManageUsers'));\n }\n }\n\n async submit() {\n let collections: SelectionReadOnlyRequest[] = null;\n if (this.access !== 'all') {\n collections = this.collections.filter(c => (c as any).checked)\n .map(c => new SelectionReadOnlyRequest(c.id, !!c.readOnly, !!c.hidePasswords));\n }\n\n try {\n if (this.editMode) {\n const request = new OrganizationUserUpdateRequest();\n request.accessAll = this.access === 'all';\n request.type = this.type;\n request.collections = collections;\n request.permissions = this.setRequestPermissions(request.permissions ?? new PermissionsApi(), request.type !== OrganizationUserType.Custom);\n this.formPromise = this.apiService.putOrganizationUser(this.organizationId, this.organizationUserId,\n request);\n } else {\n const request = new OrganizationUserInviteRequest();\n request.emails = this.emails.trim().split(/\\s*,\\s*/);\n request.accessAll = this.access === 'all';\n request.type = this.type;\n request.permissions = this.setRequestPermissions(request.permissions ?? new PermissionsApi(), request.type !== OrganizationUserType.Custom);\n request.collections = collections;\n this.formPromise = this.apiService.postOrganizationUserInvite(this.organizationId, request);\n }\n await this.formPromise;\n this.toasterService.popAsync('success', null,\n this.i18nService.t(this.editMode ? 'editedUserId' : 'invitedUsers', this.name));\n this.onSavedUser.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async delete() {\n if (!this.editMode) {\n return;\n }\n\n const message = this.usesKeyConnector ? 'removeUserConfirmationKeyConnector' : 'removeUserConfirmation';\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t(message), this.name, this.i18nService.t('yes'), this.i18nService.t('no'), 'warning'\n );\n if (!confirmed) {\n return false;\n }\n\n try {\n this.deletePromise = this.apiService.deleteOrganizationUser(this.organizationId, this.organizationUserId);\n await this.deletePromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('removedUserId', this.name));\n this.onDeletedUser.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{title}} {{name}}

{{'loading' | i18n}}

{{'inviteUserDesc' | i18n}}

{{'inviteMultipleEmailDesc' | i18n : '20'}}

{{'userType' | i18n}}

{{'permissions' | i18n}}



{{'accessControl' | i18n}}

{{'noCollectionsInList' | i18n}}
  {{'name' | i18n}} {{'hidePasswords' | i18n}} {{'readOnly' | i18n}}
{{c.name}}
","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\nimport { OrganizationUserUpdateGroupsRequest } from 'jslib-common/models/request/organizationUserUpdateGroupsRequest';\nimport { GroupResponse } from 'jslib-common/models/response/groupResponse';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\n@Component({\n selector: 'app-user-groups',\n templateUrl: 'user-groups.component.html',\n})\nexport class UserGroupsComponent implements OnInit {\n @Input() name: string;\n @Input() organizationUserId: string;\n @Input() organizationId: string;\n @Output() onSavedUser = new EventEmitter();\n\n loading = true;\n groups: GroupResponse[] = [];\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private logService: LogService) { }\n\n async ngOnInit() {\n const groupsResponse = await this.apiService.getGroups(this.organizationId);\n const groups = groupsResponse.data.map(r => r);\n groups.sort(Utils.getSortFunction(this.i18nService, 'name'));\n this.groups = groups;\n\n try {\n const userGroups = await this.apiService.getOrganizationUserGroups(\n this.organizationId, this.organizationUserId);\n if (userGroups != null && this.groups != null) {\n userGroups.forEach(ug => {\n const group = this.groups.filter(g => g.id === ug);\n if (group != null && group.length > 0) {\n (group[0] as any).checked = true;\n }\n });\n }\n } catch (e) {\n this.logService.error(e);\n }\n\n this.loading = false;\n }\n\n check(g: GroupResponse, select?: boolean) {\n (g as any).checked = select == null ? !(g as any).checked : select;\n if (!(g as any).checked) {\n (g as any).readOnly = false;\n }\n }\n\n selectAll(select: boolean) {\n this.groups.forEach(g => this.check(g, select));\n }\n\n async submit() {\n const request = new OrganizationUserUpdateGroupsRequest();\n request.groupIds = this.groups.filter(g => (g as any).checked).map(g => g.id);\n\n try {\n this.formPromise = this.apiService.putOrganizationUserGroups(this.organizationId, this.organizationUserId,\n request);\n await this.formPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('editedGroupsForUser', this.name));\n this.onSavedUser.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{'groupAccess' | i18n}} {{name}}

{{'loading' | i18n}}

{{'groupAccessUserDesc' | i18n}}

{{'noGroupsInList' | i18n}}
{{g.name}}
","import {\n Component,\n OnInit,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { first } from 'rxjs/operators';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { PolicyResponse } from 'jslib-common/models/response/policyResponse';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\n\nimport { PolicyEditComponent } from './policy-edit.component';\n\nimport { PolicyListService } from '../../services/policy-list.service';\nimport { BasePolicy } from '../policies/base-policy.component';\n\n@Component({\n selector: 'app-org-policies',\n templateUrl: 'policies.component.html',\n})\nexport class PoliciesComponent implements OnInit {\n @ViewChild('editTemplate', { read: ViewContainerRef, static: true }) editModalRef: ViewContainerRef;\n\n loading = true;\n organizationId: string;\n policies: BasePolicy[];\n organization: Organization;\n\n private orgPolicies: PolicyResponse[];\n private policiesEnabledMap: Map = new Map();\n\n constructor(private apiService: ApiService, private route: ActivatedRoute,\n private modalService: ModalService, private userService: UserService,\n private policyListService: PolicyListService, private router: Router) { }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organizationId = params.organizationId;\n this.organization = await this.userService.getOrganization(this.organizationId);\n if (this.organization == null || !this.organization.usePolicies) {\n this.router.navigate(['/organizations', this.organizationId]);\n return;\n }\n\n this.policies = this.policyListService.getPolicies();\n\n await this.load();\n\n // Handle policies component launch from Event message\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n if (qParams.policyId != null) {\n const policyIdFromEvents: string = qParams.policyId;\n for (const orgPolicy of this.orgPolicies) {\n if (orgPolicy.id === policyIdFromEvents) {\n for (let i = 0; i < this.policies.length; i++) {\n if (this.policies[i].type === orgPolicy.type) {\n this.edit(this.policies[i]);\n break;\n }\n }\n break;\n }\n }\n }\n });\n });\n }\n\n async load() {\n const response = await this.apiService.getPolicies(this.organizationId);\n this.orgPolicies = response.data != null && response.data.length > 0 ? response.data : [];\n this.orgPolicies.forEach(op => {\n this.policiesEnabledMap.set(op.type, op.enabled);\n });\n\n this.loading = false;\n }\n\n async edit(policy: BasePolicy) {\n const [modal] = await this.modalService.openViewRef(PolicyEditComponent, this.editModalRef, comp => {\n comp.policy = policy;\n comp.organizationId = this.organizationId;\n comp.policiesEnabledMap = this.policiesEnabledMap;\n comp.onSavedPolicy.subscribe(() => {\n modal.close();\n this.load();\n });\n });\n }\n}\n","

{{'policies' | i18n}}

{{'loading' | i18n}}
{{p.name | i18n}} {{'enabled' | i18n}} {{p.description | i18n}}
","import {\n ChangeDetectorRef,\n Component,\n ComponentFactoryResolver,\n EventEmitter,\n Input,\n Output,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { PolicyRequest } from 'jslib-common/models/request/policyRequest';\n\nimport { PolicyResponse } from 'jslib-common/models/response/policyResponse';\n\nimport { BasePolicy, BasePolicyComponent } from '../policies/base-policy.component';\n\n@Component({\n selector: 'app-policy-edit',\n templateUrl: 'policy-edit.component.html',\n})\nexport class PolicyEditComponent {\n @Input() policy: BasePolicy;\n @Input() organizationId: string;\n @Input() policiesEnabledMap: Map = new Map();\n @Output() onSavedPolicy = new EventEmitter();\n\n @ViewChild('policyForm', { read: ViewContainerRef, static: true }) policyFormRef: ViewContainerRef;\n\n policyType = PolicyType;\n loading = true;\n enabled = false;\n formPromise: Promise;\n defaultTypes: any[];\n policyComponent: BasePolicyComponent;\n\n private policyResponse: PolicyResponse;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private componentFactoryResolver: ComponentFactoryResolver,\n private cdr: ChangeDetectorRef, private logService: LogService) {\n }\n\n async ngAfterViewInit() {\n await this.load();\n this.loading = false;\n\n const factory = this.componentFactoryResolver.resolveComponentFactory(this.policy.component);\n this.policyComponent = this.policyFormRef.createComponent(factory).instance as BasePolicyComponent;\n this.policyComponent.policy = this.policy;\n this.policyComponent.policyResponse = this.policyResponse;\n\n this.cdr.detectChanges();\n }\n\n async load() {\n try {\n this.policyResponse = await this.apiService.getPolicy(this.organizationId, this.policy.type);\n } catch (e) {\n if (e.statusCode === 404) {\n this.policyResponse = new PolicyResponse({Enabled: false});\n } else {\n throw e;\n }\n }\n }\n\n async submit() {\n let request: PolicyRequest;\n try {\n request = await this.policyComponent.buildRequest(this.policiesEnabledMap);\n } catch (e) {\n this.toasterService.pop('error', null, e);\n return;\n }\n\n try {\n this.formPromise = this.apiService.putPolicy(this.organizationId, this.policy.type, request);\n await this.formPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('editedPolicyId', this.i18nService.t(this.policy.name)));\n this.onSavedPolicy.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{'editPolicy' | i18n}} - {{policy.name | i18n}}

{{'loading' | i18n}}

{{policy.description | i18n}}

","import {\n Component,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\n\nimport {\n ActivatedRoute,\n Router\n} from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\n\nimport { OrganizationKeysRequest } from 'jslib-common/models/request/organizationKeysRequest';\nimport { OrganizationUpdateRequest } from 'jslib-common/models/request/organizationUpdateRequest';\n\nimport { OrganizationResponse } from 'jslib-common/models/response/organizationResponse';\n\nimport { ApiKeyComponent } from '../../settings/api-key.component';\nimport { PurgeVaultComponent } from '../../settings/purge-vault.component';\nimport { TaxInfoComponent } from '../../settings/tax-info.component';\n\nimport { DeleteOrganizationComponent } from './delete-organization.component';\n\n@Component({\n selector: 'app-org-account',\n templateUrl: 'account.component.html',\n})\nexport class AccountComponent {\n @ViewChild('deleteOrganizationTemplate', { read: ViewContainerRef, static: true }) deleteModalRef: ViewContainerRef;\n @ViewChild('purgeOrganizationTemplate', { read: ViewContainerRef, static: true }) purgeModalRef: ViewContainerRef;\n @ViewChild('apiKeyTemplate', { read: ViewContainerRef, static: true }) apiKeyModalRef: ViewContainerRef;\n @ViewChild('rotateApiKeyTemplate', { read: ViewContainerRef, static: true }) rotateApiKeyModalRef: ViewContainerRef;\n @ViewChild(TaxInfoComponent) taxInfo: TaxInfoComponent;\n\n selfHosted = false;\n loading = true;\n canUseApi = false;\n org: OrganizationResponse;\n formPromise: Promise;\n taxFormPromise: Promise;\n\n private organizationId: string;\n\n constructor(private modalService: ModalService,\n private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private route: ActivatedRoute,\n private syncService: SyncService, private platformUtilsService: PlatformUtilsService,\n private cryptoService: CryptoService, private logService: LogService,\n private router: Router) { }\n\n async ngOnInit() {\n this.selfHosted = this.platformUtilsService.isSelfHost();\n this.route.parent.parent.params.subscribe(async params => {\n this.organizationId = params.organizationId;\n try {\n this.org = await this.apiService.getOrganization(this.organizationId);\n this.canUseApi = this.org.useApi;\n } catch (e) {\n this.logService.error(e);\n }\n });\n this.loading = false;\n }\n\n async submit() {\n try {\n const request = new OrganizationUpdateRequest();\n request.name = this.org.name;\n request.businessName = this.org.businessName;\n request.billingEmail = this.org.billingEmail;\n request.identifier = this.org.identifier;\n\n // Backfill pub/priv key if necessary\n if (!this.org.hasPublicAndPrivateKeys) {\n const orgShareKey = await this.cryptoService.getOrgKey(this.organizationId);\n const orgKeys = await this.cryptoService.makeKeyPair(orgShareKey);\n request.keys = new OrganizationKeysRequest(orgKeys[0], orgKeys[1].encryptedString);\n }\n\n this.formPromise = this.apiService.putOrganization(this.organizationId, request).then(() => {\n return this.syncService.fullSync(true);\n });\n await this.formPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('organizationUpdated'));\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async submitTaxInfo() {\n this.taxFormPromise = this.taxInfo.submitTaxInfo();\n await this.taxFormPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('taxInfoUpdated'));\n }\n\n async deleteOrganization() {\n await this.modalService.openViewRef(DeleteOrganizationComponent, this.deleteModalRef, comp => {\n comp.organizationId = this.organizationId;\n comp.onSuccess.subscribe(() => {\n this.router.navigate(['/']);\n });\n });\n }\n\n async purgeVault() {\n await this.modalService.openViewRef(PurgeVaultComponent, this.purgeModalRef, comp => {\n comp.organizationId = this.organizationId;\n });\n }\n\n async viewApiKey() {\n await this.modalService.openViewRef(ApiKeyComponent, this.apiKeyModalRef, comp => {\n comp.keyType = 'organization';\n comp.entityId = this.organizationId;\n comp.postKey = this.apiService.postOrganizationApiKey.bind(this.apiService);\n comp.scope = 'api.organization';\n comp.grantType = 'client_credentials';\n comp.apiKeyTitle = 'apiKey';\n comp.apiKeyWarning = 'apiKeyWarning';\n comp.apiKeyDescription = 'apiKeyDesc';\n });\n }\n\n async rotateApiKey() {\n await this.modalService.openViewRef(ApiKeyComponent, this.rotateApiKeyModalRef, comp => {\n comp.keyType = 'organization';\n comp.isRotation = true;\n comp.entityId = this.organizationId;\n comp.postKey = this.apiService.postOrganizationRotateApiKey.bind(this.apiService);\n comp.scope = 'api.organization';\n comp.grantType = 'client_credentials';\n comp.apiKeyTitle = 'apiKey';\n comp.apiKeyWarning = 'apiKeyWarning';\n comp.apiKeyDescription = 'apiKeyRotateDesc';\n });\n }\n}\n","

{{'myOrganization' | i18n}}

{{'loading' | i18n}}

{{'apiKey' | i18n}}

{{'apiKeyDesc' | i18n}} {{'learnMore' | i18n}}

{{'taxInformation' | i18n}}

{{'taxInformationDesc' | i18n}}

{{'loading' | i18n}}

{{'dangerZone' | i18n}}

{{'dangerZoneDesc' | i18n}}

","import {\n Component,\n EventEmitter,\n Input,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\nimport { OrganizationSubscriptionUpdateRequest } from 'jslib-common/models/request/organizationSubscriptionUpdateRequest';\n\n@Component({\n selector: 'app-adjust-subscription',\n templateUrl: 'adjust-subscription.component.html',\n})\nexport class AdjustSubscription {\n @Input() organizationId: string;\n @Input() maxAutoscaleSeats: number;\n @Input() currentSeatCount: number;\n @Input() seatPrice = 0;\n @Input() interval = 'year';\n @Output() onAdjusted = new EventEmitter();\n\n formPromise: Promise;\n limitSubscription: boolean;\n newSeatCount: number;\n newMaxSeats: number;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private logService: LogService) { }\n\n ngOnInit() {\n this.limitSubscription = this.maxAutoscaleSeats != null;\n this.newSeatCount = this.currentSeatCount;\n this.newMaxSeats = this.maxAutoscaleSeats;\n }\n\n async submit() {\n try {\n const seatAdjustment = this.newSeatCount - this.currentSeatCount;\n const request = new OrganizationSubscriptionUpdateRequest(seatAdjustment, this.newMaxSeats);\n this.formPromise = this.apiService.postOrganizationUpdateSubscription(this.organizationId, request);\n\n await this.formPromise;\n\n this.toasterService.popAsync('success', null, this.i18nService.t('subscriptionUpdated'));\n } catch (e) {\n this.logService.error(e);\n }\n this.onAdjusted.emit();\n }\n\n limitSubscriptionChanged() {\n if (!this.limitSubscription) {\n this.newMaxSeats = null;\n }\n }\n\n get adjustedSeatTotal(): number {\n return this.newSeatCount * this.seatPrice;\n }\n\n get maxSeatTotal(): number {\n return this.newMaxSeats * this.seatPrice;\n }\n}\n","
{{'total' | i18n}}: {{newSeatCount || 0}} × {{seatPrice | currency:'$'}} = {{adjustedSeatTotal | currency:'$'}} / {{interval | i18n}}
{{'limitSubscriptionDesc' | i18n}}
{{'maxSeatCost' | i18n}}: {{newMaxSeats || 0}} × {{seatPrice | currency:'$'}} = {{maxSeatTotal | currency:'$'}} / {{interval | i18n}}
","import {\n Component,\n EventEmitter,\n Input,\n Output,\n} from '@angular/core';\n\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\nimport { PlanType } from 'jslib-common/enums/planType';\nimport { ProductType } from 'jslib-common/enums/productType';\n\n@Component({\n selector: 'app-change-plan',\n templateUrl: 'change-plan.component.html',\n})\nexport class ChangePlanComponent {\n @Input() organizationId: string;\n @Output() onChanged = new EventEmitter();\n @Output() onCanceled = new EventEmitter();\n\n formPromise: Promise;\n defaultUpgradePlan: PlanType = PlanType.FamiliesAnnually;\n defaultUpgradeProduct: ProductType = ProductType.Families;\n\n constructor(private logService: LogService) { }\n\n async submit() {\n try {\n this.onChanged.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n cancel() {\n this.onCanceled.emit();\n }\n}\n","

{{'changeBillingPlan' | i18n}}

{{'changeBillingPlanUpgrade' | i18n}}

","import {\n Component,\n EventEmitter,\n Input,\n Output,\n} from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\n@Component({\n selector: 'app-download-license',\n templateUrl: 'download-license.component.html',\n})\nexport class DownloadLicenseComponent {\n @Input() organizationId: string;\n @Output() onDownloaded = new EventEmitter();\n @Output() onCanceled = new EventEmitter();\n\n installationId: string;\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private platformUtilsService: PlatformUtilsService,\n private logService: LogService) { }\n\n async submit() {\n if (this.installationId == null || this.installationId === '') {\n return;\n }\n\n try {\n this.formPromise = this.apiService.getOrganizationLicense(this.organizationId, this.installationId);\n const license = await this.formPromise;\n const licenseString = JSON.stringify(license, null, 2);\n this.platformUtilsService.saveFile(window, licenseString, null, 'bitwarden_organization_license.json');\n this.onDownloaded.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n cancel() {\n this.onCanceled.emit();\n }\n}\n","

{{'downloadLicense' | i18n}}

","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { UserBillingComponent } from '../../settings/user-billing.component';\n\n@Component({\n selector: 'app-org-billing',\n templateUrl: '../../settings/user-billing.component.html',\n})\nexport class OrganizationBillingComponent extends UserBillingComponent implements OnInit {\n constructor(apiService: ApiService, i18nService: I18nService, toasterService: ToasterService,\n private route: ActivatedRoute, platformUtilsService: PlatformUtilsService,\n logService: LogService) {\n super(apiService, i18nService, toasterService, platformUtilsService, logService);\n }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organizationId = params.organizationId;\n await this.load();\n this.firstLoaded = true;\n });\n }\n}\n","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { ToasterService } from 'angular2-toaster';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport { OrganizationSubscriptionResponse } from 'jslib-common/models/response/organizationSubscriptionResponse';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { PlanType } from 'jslib-common/enums/planType';\n\n@Component({\n selector: 'app-org-subscription',\n templateUrl: 'organization-subscription.component.html',\n})\nexport class OrganizationSubscriptionComponent implements OnInit {\n loading = false;\n firstLoaded = false;\n organizationId: string;\n adjustSeatsAdd = true;\n showAdjustSeats = false;\n showAdjustSeatAutoscale = false;\n adjustStorageAdd = true;\n showAdjustStorage = false;\n showUpdateLicense = false;\n showDownloadLicense = false;\n showChangePlan = false;\n sub: OrganizationSubscriptionResponse;\n selfHosted = false;\n\n userOrg: Organization;\n\n removeSponsorshipPromise: Promise;\n cancelPromise: Promise;\n reinstatePromise: Promise;\n\n constructor(private apiService: ApiService, private platformUtilsService: PlatformUtilsService,\n private i18nService: I18nService, private toasterService: ToasterService,\n private messagingService: MessagingService, private route: ActivatedRoute,\n private userService: UserService, private logService: LogService) {\n this.selfHosted = platformUtilsService.isSelfHost();\n }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organizationId = params.organizationId;\n await this.load();\n this.firstLoaded = true;\n });\n }\n\n async load() {\n if (this.loading) {\n return;\n }\n\n this.loading = true;\n this.userOrg = await this.userService.getOrganization(this.organizationId);\n this.sub = await this.apiService.getOrganizationSubscription(this.organizationId);\n this.loading = false;\n }\n\n async reinstate() {\n if (this.loading) {\n return;\n }\n\n const confirmed = await this.platformUtilsService.showDialog(this.i18nService.t('reinstateConfirmation'),\n this.i18nService.t('reinstateSubscription'), this.i18nService.t('yes'), this.i18nService.t('cancel'));\n if (!confirmed) {\n return;\n }\n\n try {\n this.reinstatePromise = this.apiService.postOrganizationReinstate(this.organizationId);\n await this.reinstatePromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('reinstated'));\n this.load();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async cancel() {\n if (this.loading) {\n return;\n }\n\n const confirmed = await this.platformUtilsService.showDialog(this.i18nService.t('cancelConfirmation'),\n this.i18nService.t('cancelSubscription'), this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return;\n }\n\n try {\n this.cancelPromise = this.apiService.postOrganizationCancel(this.organizationId);\n await this.cancelPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('canceledSubscription'));\n this.load();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async changePlan() {\n this.showChangePlan = !this.showChangePlan;\n }\n\n closeChangePlan(changed: boolean) {\n this.showChangePlan = false;\n }\n\n downloadLicense() {\n this.showDownloadLicense = !this.showDownloadLicense;\n }\n\n closeDownloadLicense() {\n this.showDownloadLicense = false;\n }\n\n updateLicense() {\n if (this.loading) {\n return;\n }\n this.showUpdateLicense = true;\n }\n\n closeUpdateLicense(updated: boolean) {\n this.showUpdateLicense = false;\n if (updated) {\n this.load();\n this.messagingService.send('updatedOrgLicense');\n }\n }\n\n subscriptionAdjusted() {\n this.load();\n }\n\n adjustStorage(add: boolean) {\n this.adjustStorageAdd = add;\n this.showAdjustStorage = true;\n }\n\n closeStorage(load: boolean) {\n this.showAdjustStorage = false;\n if (load) {\n this.load();\n }\n }\n\n async removeSponsorship() {\n const isConfirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('removeSponsorshipConfirmation'),\n this.i18nService.t('removeSponsorship'),\n this.i18nService.t('remove'), this.i18nService.t('cancel'), 'warning');\n\n if (!isConfirmed) {\n return;\n }\n\n try {\n this.removeSponsorshipPromise = this.apiService.deleteRemoveSponsorship(this.organizationId);\n await this.removeSponsorshipPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('removeSponsorshipSuccess'));\n await this.load();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n get isExpired() {\n return this.sub != null && this.sub.expiration != null &&\n new Date(this.sub.expiration) < new Date();\n }\n\n get subscriptionMarkedForCancel() {\n return this.subscription != null && !this.subscription.cancelled && this.subscription.cancelAtEndDate;\n }\n\n get subscription() {\n return this.sub != null ? this.sub.subscription : null;\n }\n\n get nextInvoice() {\n return this.sub != null ? this.sub.upcomingInvoice : null;\n }\n\n get storagePercentage() {\n return this.sub != null && this.sub.maxStorageGb ?\n +(100 * (this.sub.storageGb / this.sub.maxStorageGb)).toFixed(2) : 0;\n }\n\n get storageProgressWidth() {\n return this.storagePercentage < 5 ? 5 : 0;\n }\n\n get billingInterval() {\n const monthly = !this.sub.plan.isAnnual;\n return monthly ? 'month' : 'year';\n }\n\n get storageGbPrice() {\n return this.sub.plan.additionalStoragePricePerGb;\n }\n\n get seatPrice() {\n return this.sub.plan.seatPrice;\n }\n\n get seats() {\n return this.sub.seats;\n }\n\n get maxAutoscaleSeats() {\n return this.sub.maxAutoscaleSeats;\n }\n\n get canAdjustSeats() {\n return this.sub.plan.hasAdditionalSeatsOption;\n }\n\n get isSponsoredSubscription(): boolean {\n return this.sub.subscription?.items.some(i => i.sponsoredSubscriptionItem);\n }\n\n get canDownloadLicense() {\n return (this.sub.planType !== PlanType.Free && this.subscription == null) ||\n (this.subscription != null && !this.subscription.cancelled);\n }\n\n get subscriptionDesc() {\n if (this.sub.planType === PlanType.Free) {\n return this.i18nService.t('subscriptionFreePlan', this.sub.seats.toString());\n } else if (this.sub.planType === PlanType.FamiliesAnnually || this.sub.planType === PlanType.FamiliesAnnually2019) {\n if (this.isSponsoredSubscription) {\n return this.i18nService.t('subscriptionSponsoredFamiliesPlan', this.sub.seats.toString());\n } else {\n return this.i18nService.t('subscriptionFamiliesPlan', this.sub.seats.toString());\n }\n } else if (this.sub.maxAutoscaleSeats === this.sub.seats && this.sub.seats != null) {\n return this.i18nService.t('subscriptionMaxReached', this.sub.seats.toString());\n } else if (this.sub.maxAutoscaleSeats == null) {\n return this.i18nService.t('subscriptionUserSeatsUnlimitedAutoscale');\n } else {\n return this.i18nService.t('subscriptionUserSeatsLimitedAutoscale', this.sub.maxAutoscaleSeats.toString());\n }\n }\n\n get showChangePlanButton() {\n return this.subscription == null && this.sub.planType === PlanType.Free && !this.showChangePlan;\n }\n}\n","

{{'subscription' | i18n}} {{'loading' | i18n}}

{{'loading' | i18n}} {{'subscriptionCanceled' | i18n}}

{{'subscriptionPendingCanceled' | i18n}}

{{'billingPlan' | i18n}}
{{sub.plan.name}}
{{'status' | i18n}}
{{isSponsoredSubscription ? 'sponsored' : subscription.status || '-'}} {{'pendingCancellation' | i18n}}
{{'nextCharge' | i18n}}
{{nextInvoice ? ((nextInvoice.date | date: 'mediumDate') + ', ' + (nextInvoice.amount | currency:'$')) : '-'}}
{{'details' | i18n}}
{{i.name}} {{i.quantity > 1 ? '×' + i.quantity : ''}} @ {{i.amount | currency:'$'}} {{(i.quantity * i.amount) | currency:'$'}} /{{i.interval | i18n}}
{{'provider' | i18n}}
{{'yourProviderIs' | i18n : userOrg.providerName}}

{{'manageSubscription' | i18n}}

{{subscriptionDesc}}

{{'storage' | i18n}}

{{'subscriptionStorage' | i18n : sub.maxStorageGb || 0 : sub.storageName || '0 MB'}}

{{(storagePercentage / 100) | percent}}

{{'additionalOptions' | i18n}}

{{'additionalOptionsDesc' | i18n }}

{{'billingPlan' | i18n}}
{{sub.plan.name}}
{{'expiration' | i18n}}
{{sub.expiration | date:'mediumDate'}} {{'licenseIsExpired' | i18n}}
{{'neverExpires' | i18n}}
{{'manageSubscription' | i18n}}

{{'updateLicense' | i18n}}

","import { Component } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\n@Component({\n selector: 'app-org-settings',\n templateUrl: 'settings.component.html',\n})\nexport class SettingsComponent {\n access2fa = false;\n selfHosted: boolean;\n\n constructor(private route: ActivatedRoute, private userService: UserService,\n private platformUtilsService: PlatformUtilsService) { }\n\n ngOnInit() {\n this.route.parent.params.subscribe(async params => {\n this.selfHosted = await this.platformUtilsService.isSelfHost();\n const organization = await this.userService.getOrganization(params.organizationId);\n this.access2fa = organization.use2fa;\n });\n }\n}\n"," ","import { Component } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\n\nimport { TwoFactorDuoComponent } from '../../settings/two-factor-duo.component';\nimport { TwoFactorSetupComponent as BaseTwoFactorSetupComponent } from '../../settings/two-factor-setup.component';\n\n@Component({\n selector: 'app-two-factor-setup',\n templateUrl: '../../settings/two-factor-setup.component.html',\n})\nexport class TwoFactorSetupComponent extends BaseTwoFactorSetupComponent {\n constructor(apiService: ApiService, userService: UserService,\n modalService: ModalService, messagingService: MessagingService,\n policyService: PolicyService, private route: ActivatedRoute) {\n super(apiService, userService, modalService, messagingService, policyService);\n }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organizationId = params.organizationId;\n await super.ngOnInit();\n });\n }\n\n async manage(type: TwoFactorProviderType) {\n switch (type) {\n case TwoFactorProviderType.OrganizationDuo:\n const duoComp = await this.openModal(this.duoModalRef, TwoFactorDuoComponent);\n duoComp.type = TwoFactorProviderType.OrganizationDuo;\n duoComp.organizationId = this.organizationId;\n duoComp.onUpdated.subscribe((enabled: boolean) => {\n this.updateStatus(enabled, TwoFactorProviderType.OrganizationDuo);\n });\n break;\n default:\n break;\n }\n }\n\n protected getTwoFactorProviders() {\n return this.apiService.getTwoFactorOrganizationProviders(this.organizationId);\n }\n\n protected filterProvider(type: TwoFactorProviderType) {\n return type !== TwoFactorProviderType.OrganizationDuo;\n }\n}\n","import {\n Component,\n OnDestroy,\n OnInit,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { UpdateTwoFactorAuthenticatorRequest } from 'jslib-common/models/request/updateTwoFactorAuthenticatorRequest';\nimport { TwoFactorAuthenticatorResponse } from 'jslib-common/models/response/twoFactorAuthenticatorResponse';\n\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\n\nimport { TwoFactorBaseComponent } from './two-factor-base.component';\n\n@Component({\n selector: 'app-two-factor-authenticator',\n templateUrl: 'two-factor-authenticator.component.html',\n})\nexport class TwoFactorAuthenticatorComponent extends TwoFactorBaseComponent implements OnInit, OnDestroy {\n type = TwoFactorProviderType.Authenticator;\n key: string;\n token: string;\n formPromise: Promise;\n\n private qrScript: HTMLScriptElement;\n\n constructor(apiService: ApiService, i18nService: I18nService,\n toasterService: ToasterService, userVerificationService: UserVerificationService,\n platformUtilsService: PlatformUtilsService, logService: LogService,\n private userService: UserService) {\n super(apiService, i18nService, toasterService, platformUtilsService, logService, userVerificationService);\n this.qrScript = window.document.createElement('script');\n this.qrScript.src = 'scripts/qrious.min.js';\n this.qrScript.async = true;\n }\n\n ngOnInit() {\n window.document.body.appendChild(this.qrScript);\n }\n\n ngOnDestroy() {\n window.document.body.removeChild(this.qrScript);\n }\n\n auth(authResponse: any) {\n super.auth(authResponse);\n return this.processResponse(authResponse.response);\n }\n\n submit() {\n if (this.enabled) {\n return super.disable(this.formPromise);\n } else {\n return this.enable();\n }\n }\n\n protected async enable() {\n const request = await this.buildRequestModel(UpdateTwoFactorAuthenticatorRequest);\n request.token = this.token;\n request.key = this.key;\n\n return super.enable(async () => {\n this.formPromise = this.apiService.putTwoFactorAuthenticator(request);\n const response = await this.formPromise;\n await this.processResponse(response);\n });\n }\n\n private async processResponse(response: TwoFactorAuthenticatorResponse) {\n this.token = null;\n this.enabled = response.enabled;\n this.key = response.key;\n const email = await this.userService.getEmail();\n window.setTimeout(() => {\n const qr = new (window as any).QRious({\n element: document.getElementById('qr'),\n value: 'otpauth://totp/Bitwarden:' + encodeURIComponent(email) +\n '?secret=' + encodeURIComponent(this.key) + '&issuer=Bitwarden',\n size: 160,\n });\n }, 100);\n }\n}\n","

{{'twoStepLogin' | i18n}} {{'authenticatorAppTitle' | i18n}}

\"Authenticator

{{'twoStepAuthenticatorDesc' | i18n}}

1. {{'twoStepAuthenticatorDownloadApp' | i18n}}

{{'twoStepLoginProviderEnabled' | i18n}}

{{'twoStepAuthenticatorReaddDesc' | i18n}}
\"Authenticator

{{'twoStepAuthenticatorNeedApp' | i18n}}

{{'twoStepAuthenticatorAppsRecommended' | i18n}}

2. {{'twoStepAuthenticatorScanCode' | i18n}}



{{key}}

","import { Component } from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { TwoFactorEmailRequest } from 'jslib-common/models/request/twoFactorEmailRequest';\n\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\nimport { UpdateTwoFactorEmailRequest } from 'jslib-common/models/request/updateTwoFactorEmailRequest';\nimport { TwoFactorEmailResponse } from 'jslib-common/models/response/twoFactorEmailResponse';\n\nimport { TwoFactorBaseComponent } from './two-factor-base.component';\n\n@Component({\n selector: 'app-two-factor-email',\n templateUrl: 'two-factor-email.component.html',\n})\nexport class TwoFactorEmailComponent extends TwoFactorBaseComponent {\n type = TwoFactorProviderType.Email;\n email: string;\n token: string;\n sentEmail: string;\n formPromise: Promise;\n emailPromise: Promise;\n\n constructor(apiService: ApiService, i18nService: I18nService,\n toasterService: ToasterService, platformUtilsService: PlatformUtilsService,\n logService: LogService, userVerificationService: UserVerificationService,\n private userService: UserService) {\n super(apiService, i18nService, toasterService, platformUtilsService, logService, userVerificationService);\n }\n\n auth(authResponse: any) {\n super.auth(authResponse);\n return this.processResponse(authResponse.response);\n }\n\n submit() {\n if (this.enabled) {\n return super.disable(this.formPromise);\n } else {\n return this.enable();\n }\n }\n\n async sendEmail() {\n try {\n const request = await this.buildRequestModel(TwoFactorEmailRequest);\n request.email = this.email;\n this.emailPromise = this.apiService.postTwoFactorEmailSetup(request);\n await this.emailPromise;\n this.sentEmail = this.email;\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n protected async enable() {\n const request = await this.buildRequestModel(UpdateTwoFactorEmailRequest);\n request.email = this.email;\n request.token = this.token;\n\n return super.enable(async () => {\n this.formPromise = this.apiService.putTwoFactorEmail(request);\n const response = await this.formPromise;\n await this.processResponse(response);\n });\n }\n\n private async processResponse(response: TwoFactorEmailResponse) {\n this.token = null;\n this.email = response.email;\n this.enabled = response.enabled;\n if (!this.enabled && (this.email == null || this.email === '')) {\n this.email = await this.userService.getEmail();\n }\n }\n}\n","

{{'twoStepLogin' | i18n}} {{'emailTitle' | i18n}}

{{'twoStepLoginProviderEnabled' | i18n}} {{'email' | i18n}}: {{email}}

{{'twoFactorEmailDesc' | i18n}} \"Email

{{'verificationCodeEmailSent' | i18n : sentEmail}}
","import { Component } from '@angular/core';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\nimport { TwoFactorRecoverResponse } from 'jslib-common/models/response/twoFactorRescoverResponse';\n\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\n\n@Component({\n selector: 'app-two-factor-recovery',\n templateUrl: 'two-factor-recovery.component.html',\n})\nexport class TwoFactorRecoveryComponent {\n type = -1;\n code: string;\n authed: boolean;\n twoFactorProviderType = TwoFactorProviderType;\n\n constructor(private i18nService: I18nService) { }\n\n auth(authResponse: any) {\n this.authed = true;\n this.processResponse(authResponse.response);\n }\n\n print() {\n const w = window.open();\n w.document.write('
' +\n '

' + this.i18nService.t('twoFactorRecoveryYourCode') + ':

' +\n '' +\n this.code + '
' +\n '

' + new Date() + '

');\n w.onafterprint = () => w.close();\n w.print();\n }\n\n private formatString(s: string) {\n if (s == null) {\n return null;\n }\n return s.replace(/(.{4})/g, '$1 ').trim().toUpperCase();\n }\n\n private processResponse(response: TwoFactorRecoverResponse) {\n this.code = this.formatString(response.code);\n }\n}\n","

{{'twoStepLogin' | i18n}} {{'recoveryCodeTitle' | i18n}}

{{'twoFactorRecoveryYourCode' | i18n}}:

{{code}}
{{'twoFactorRecoveryNoCode' | i18n}}
","import {\n Component,\n NgZone,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\n\nimport { SecretVerificationRequest } from 'jslib-common/models/request/secretVerificationRequest';\nimport { UpdateTwoFactorWebAuthnDeleteRequest } from 'jslib-common/models/request/updateTwoFactorWebAuthnDeleteRequest';\nimport { UpdateTwoFactorWebAuthnRequest } from 'jslib-common/models/request/updateTwoFactorWebAuthnRequest';\nimport {\n ChallengeResponse,\n TwoFactorWebAuthnResponse,\n} from 'jslib-common/models/response/twoFactorWebAuthnResponse';\n\nimport { TwoFactorBaseComponent } from './two-factor-base.component';\n\n@Component({\n selector: 'app-two-factor-webauthn',\n templateUrl: 'two-factor-webauthn.component.html',\n})\nexport class TwoFactorWebAuthnComponent extends TwoFactorBaseComponent {\n type = TwoFactorProviderType.WebAuthn;\n name: string;\n keys: any[];\n keyIdAvailable: number = null;\n keysConfiguredCount = 0;\n webAuthnError: boolean;\n webAuthnListening: boolean;\n webAuthnResponse: PublicKeyCredential;\n challengePromise: Promise;\n formPromise: Promise;\n\n constructor(apiService: ApiService, i18nService: I18nService,\n toasterService: ToasterService, platformUtilsService: PlatformUtilsService,\n private ngZone: NgZone, logService: LogService, userVerificationService: UserVerificationService) {\n super(apiService, i18nService, toasterService, platformUtilsService, logService, userVerificationService);\n }\n\n auth(authResponse: any) {\n super.auth(authResponse);\n this.processResponse(authResponse.response);\n }\n\n async submit() {\n if (this.webAuthnResponse == null || this.keyIdAvailable == null) {\n // Should never happen.\n return Promise.reject();\n }\n const request = await this.buildRequestModel(UpdateTwoFactorWebAuthnRequest);\n request.deviceResponse = this.webAuthnResponse;\n request.id = this.keyIdAvailable;\n request.name = this.name;\n\n return super.enable(async () => {\n this.formPromise = this.apiService.putTwoFactorWebAuthn(request);\n const response = await this.formPromise;\n await this.processResponse(response);\n });\n }\n\n disable() {\n return super.disable(this.formPromise);\n }\n\n async remove(key: any) {\n if (this.keysConfiguredCount <= 1 || key.removePromise != null) {\n return;\n }\n const name = key.name != null ? key.name : this.i18nService.t('webAuthnkeyX', key.id);\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('removeU2fConfirmation'), name,\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return;\n }\n const request = await this.buildRequestModel(UpdateTwoFactorWebAuthnDeleteRequest);\n request.id = key.id;\n try {\n key.removePromise = this.apiService.deleteTwoFactorWebAuthn(request);\n const response = await key.removePromise;\n key.removePromise = null;\n await this.processResponse(response);\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async readKey() {\n if (this.keyIdAvailable == null) {\n return;\n }\n const request = await this.buildRequestModel(SecretVerificationRequest);\n try {\n this.challengePromise = this.apiService.getTwoFactorWebAuthnChallenge(request);\n const challenge = await this.challengePromise;\n this.readDevice(challenge);\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n private readDevice(webAuthnChallenge: ChallengeResponse) {\n // tslint:disable-next-line\n console.log('listening for key...');\n this.resetWebAuthn(true);\n\n navigator.credentials.create({\n publicKey: webAuthnChallenge,\n }).then((data: PublicKeyCredential) => {\n this.ngZone.run(() => {\n this.webAuthnListening = false;\n this.webAuthnResponse = data;\n });\n }).catch(err => {\n // tslint:disable-next-line\n console.error(err);\n this.resetWebAuthn(false);\n // TODO: Should we display the actual error?\n this.webAuthnError = true;\n });\n }\n\n private resetWebAuthn(listening = false) {\n this.webAuthnResponse = null;\n this.webAuthnError = false;\n this.webAuthnListening = listening;\n }\n\n private processResponse(response: TwoFactorWebAuthnResponse) {\n this.resetWebAuthn();\n this.keys = [];\n this.keyIdAvailable = null;\n this.name = null;\n this.keysConfiguredCount = 0;\n for (let i = 1; i <= 5; i++) {\n if (response.keys != null) {\n const key = response.keys.filter(k => k.id === i);\n if (key.length > 0) {\n this.keysConfiguredCount++;\n this.keys.push({\n id: i, name: key[0].name,\n configured: true,\n migrated: key[0].migrated,\n removePromise: null,\n });\n continue;\n }\n }\n this.keys.push({ id: i, name: null, configured: false, removePromise: null });\n if (this.keyIdAvailable == null) {\n this.keyIdAvailable = i;\n }\n }\n this.enabled = response.enabled;\n }\n}\n","

{{'twoStepLogin' | i18n}} {{'webAuthnTitle' | i18n}}

{{'twoStepLoginProviderEnabled' | i18n}}

{{'twoFactorWebAuthnWarning' | i18n}}

  • {{'twoFactorWebAuthnSupportWeb' | i18n}}
\"FIDO2
  • {{'webAuthnkeyX' | i18n : i + 1}} {{k.name}} {{'webAuthnMigrated' | i18n}} 1 && k.configured\"> - {{'remove' | i18n}}

{{'twoFactorWebAuthnAdd' | i18n}}:

  1. {{'twoFactorU2fGiveName' | i18n}}
  2. {{'twoFactorU2fPlugInReadKey' | i18n}}
  3. {{'twoFactorU2fTouchButton' | i18n}}
  4. {{'twoFactorU2fSaveForm' | i18n}}
{{'twoFactorU2fWaiting' | i18n}}... {{'twoFactorU2fClickSave' | i18n}} {{'twoFactorU2fProblemReadingTryAgain' | i18n}}
","import { Component } from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { UpdateTwoFactorYubioOtpRequest } from 'jslib-common/models/request/updateTwoFactorYubioOtpRequest';\nimport { TwoFactorYubiKeyResponse } from 'jslib-common/models/response/twoFactorYubiKeyResponse';\n\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\n\nimport { TwoFactorBaseComponent } from './two-factor-base.component';\n\n@Component({\n selector: 'app-two-factor-yubikey',\n templateUrl: 'two-factor-yubikey.component.html',\n})\nexport class TwoFactorYubiKeyComponent extends TwoFactorBaseComponent {\n type = TwoFactorProviderType.Yubikey;\n keys: any[];\n nfc = false;\n\n formPromise: Promise;\n disablePromise: Promise;\n\n constructor(apiService: ApiService, i18nService: I18nService,\n toasterService: ToasterService, platformUtilsService: PlatformUtilsService,\n logService: LogService, userVerificationService: UserVerificationService) {\n super(apiService, i18nService, toasterService, platformUtilsService, logService, userVerificationService);\n }\n\n auth(authResponse: any) {\n super.auth(authResponse);\n this.processResponse(authResponse.response);\n }\n\n async submit() {\n const request = await this.buildRequestModel(UpdateTwoFactorYubioOtpRequest);\n request.key1 = this.keys != null && this.keys.length > 0 ? this.keys[0].key : null;\n request.key2 = this.keys != null && this.keys.length > 1 ? this.keys[1].key : null;\n request.key3 = this.keys != null && this.keys.length > 2 ? this.keys[2].key : null;\n request.key4 = this.keys != null && this.keys.length > 3 ? this.keys[3].key : null;\n request.key5 = this.keys != null && this.keys.length > 4 ? this.keys[4].key : null;\n request.nfc = this.nfc;\n\n return super.enable(async () => {\n this.formPromise = this.apiService.putTwoFactorYubiKey(request);\n const response = await this.formPromise;\n await this.processResponse(response);\n this.toasterService.popAsync('success', null, this.i18nService.t('yubikeysUpdated'));\n });\n }\n\n disable() {\n return super.disable(this.disablePromise);\n }\n\n remove(key: any) {\n key.existingKey = null;\n key.key = null;\n }\n\n private processResponse(response: TwoFactorYubiKeyResponse) {\n this.enabled = response.enabled;\n this.keys = [\n { key: response.key1, existingKey: this.padRight(response.key1) },\n { key: response.key2, existingKey: this.padRight(response.key2) },\n { key: response.key3, existingKey: this.padRight(response.key3) },\n { key: response.key4, existingKey: this.padRight(response.key4) },\n { key: response.key5, existingKey: this.padRight(response.key5) },\n ];\n this.nfc = response.nfc || !response.enabled;\n }\n\n private padRight(str: string, character = '•', size = 44) {\n if (str == null || character == null || str.length >= size) {\n return str;\n }\n const max = (size - str.length) / character.length;\n for (let i = 0; i < max; i++) {\n str += character;\n }\n return str;\n }\n}\n","

{{'twoStepLogin' | i18n}} YubiKey

{{'twoStepLoginProviderEnabled' | i18n}}

{{'twoFactorYubikeyWarning' | i18n}}

  • {{'twoFactorYubikeySupportUsb' | i18n}}
  • {{'twoFactorYubikeySupportMobile' | i18n}}
\"YubiKey

{{'twoFactorYubikeyAdd' | i18n}}:

  1. {{'twoFactorYubikeyPlugIn' | i18n}}
  2. {{'twoFactorYubikeySelectKey' | i18n}}
  3. {{'twoFactorYubikeyTouchButton' | i18n}}
  4. {{'twoFactorYubikeySaveForm' | i18n}}

{{k.existingKey}}
{{'nfcSupport' | i18n}}
{{'twoFactorYubikeySupportsNfcDesc' | i18n}}
","import { Component } from '@angular/core';\nimport { FormBuilder } from '@angular/forms';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { EventService } from 'jslib-common/abstractions/event.service';\nimport { ExportService } from 'jslib-common/abstractions/export.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { ExportComponent as BaseExportComponent } from '../../tools/export.component';\n\n@Component({\n selector: 'app-org-export',\n templateUrl: '../../tools/export.component.html',\n})\nexport class ExportComponent extends BaseExportComponent {\n constructor(cryptoService: CryptoService, i18nService: I18nService,\n platformUtilsService: PlatformUtilsService, exportService: ExportService,\n eventService: EventService, private route: ActivatedRoute, policyService: PolicyService,\n logService: LogService, userVerificationService: UserVerificationService, fb: FormBuilder) {\n super(cryptoService, i18nService, platformUtilsService, exportService, eventService, policyService,\n logService, userVerificationService, fb);\n }\n\n async ngOnInit() {\n await super.ngOnInit();\n this.route.parent.parent.params.subscribe(async params => {\n this.organizationId = params.organizationId;\n });\n }\n\n async checkExportDisabled() {\n return;\n }\n\n getExportData() {\n return this.exportService.getOrganizationExport(this.organizationId, this.format);\n }\n\n getFileName() {\n return super.getFileName('org');\n }\n\n async collectEvent(): Promise {\n // TODO\n // await this.eventService.collect(EventType.Organization_ClientExportedVault);\n }\n}\n","import { Component } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { AuditService } from 'jslib-common/abstractions/audit.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport {\n ExposedPasswordsReportComponent as BaseExposedPasswordsReportComponent,\n} from '../../tools/exposed-passwords-report.component';\n\nimport { Cipher } from 'jslib-common/models/domain/cipher';\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\n@Component({\n selector: 'app-exposed-passwords-report',\n templateUrl: '../../tools/exposed-passwords-report.component.html',\n})\nexport class ExposedPasswordsReportComponent extends BaseExposedPasswordsReportComponent {\n manageableCiphers: Cipher[];\n\n constructor(cipherService: CipherService, auditService: AuditService,\n modalService: ModalService, messagingService: MessagingService,\n userService: UserService, passwordRepromptService: PasswordRepromptService, private route: ActivatedRoute) {\n super(cipherService, auditService, modalService, messagingService, userService, passwordRepromptService);\n }\n\n ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organization = await this.userService.getOrganization(params.organizationId);\n this.manageableCiphers = await this.cipherService.getAll();\n super.ngOnInit();\n });\n }\n\n getAllCiphers(): Promise {\n return this.cipherService.getAllFromApiForOrganization(this.organization.id);\n }\n\n canManageCipher(c: CipherView): boolean {\n return this.manageableCiphers.some(x => x.id === c.id);\n }\n}\n","import { AttachmentResponse } from '../response/attachmentResponse';\n\nexport class AttachmentData {\n id: string;\n url: string;\n fileName: string;\n key: string;\n size: string;\n sizeName: string;\n\n constructor(response?: AttachmentResponse) {\n if (response == null) {\n return;\n }\n this.id = response.id;\n this.url = response.url;\n this.fileName = response.fileName;\n this.key = response.key;\n this.size = response.size;\n this.sizeName = response.sizeName;\n }\n}\n","import { CardApi } from '../api/cardApi';\n\nexport class CardData {\n cardholderName: string;\n brand: string;\n number: string;\n expMonth: string;\n expYear: string;\n code: string;\n\n constructor(data?: CardApi) {\n if (data == null) {\n return;\n }\n\n this.cardholderName = data.cardholderName;\n this.brand = data.brand;\n this.number = data.number;\n this.expMonth = data.expMonth;\n this.expYear = data.expYear;\n this.code = data.code;\n }\n}\n","import { FieldType } from '../../enums/fieldType';\nimport { LinkedIdType } from '../../enums/linkedIdType';\n\nimport { FieldApi } from '../api/fieldApi';\n\nexport class FieldData {\n type: FieldType;\n name: string;\n value: string;\n linkedId: LinkedIdType;\n\n constructor(response?: FieldApi) {\n if (response == null) {\n return;\n }\n this.type = response.type;\n this.name = response.name;\n this.value = response.value;\n this.linkedId = response.linkedId;\n }\n}\n","import { IdentityApi } from '../api/identityApi';\n\nexport class IdentityData {\n title: string;\n firstName: string;\n middleName: string;\n lastName: string;\n address1: string;\n address2: string;\n address3: string;\n city: string;\n state: string;\n postalCode: string;\n country: string;\n company: string;\n email: string;\n phone: string;\n ssn: string;\n username: string;\n passportNumber: string;\n licenseNumber: string;\n\n constructor(data?: IdentityApi) {\n if (data == null) {\n return;\n }\n\n this.title = data.title;\n this.firstName = data.firstName;\n this.middleName = data.middleName;\n this.lastName = data.lastName;\n this.address1 = data.address1;\n this.address2 = data.address2;\n this.address3 = data.address3;\n this.city = data.city;\n this.state = data.state;\n this.postalCode = data.postalCode;\n this.country = data.country;\n this.company = data.company;\n this.email = data.email;\n this.phone = data.phone;\n this.ssn = data.ssn;\n this.username = data.username;\n this.passportNumber = data.passportNumber;\n this.licenseNumber = data.licenseNumber;\n }\n}\n","import { LoginApi } from '../api/loginApi';\n\nimport { LoginUriData } from './loginUriData';\n\nexport class LoginData {\n uris: LoginUriData[];\n username: string;\n password: string;\n passwordRevisionDate: string;\n totp: string;\n autofillOnPageLoad: boolean;\n\n constructor(data?: LoginApi) {\n if (data == null) {\n return;\n }\n\n this.username = data.username;\n this.password = data.password;\n this.passwordRevisionDate = data.passwordRevisionDate;\n this.totp = data.totp;\n this.autofillOnPageLoad = data.autofillOnPageLoad;\n\n if (data.uris) {\n this.uris = data.uris.map(u => new LoginUriData(u));\n }\n }\n}\n","import { UriMatchType } from '../../enums/uriMatchType';\n\nimport { LoginUriApi } from '../api/loginUriApi';\n\nexport class LoginUriData {\n uri: string;\n match: UriMatchType = null;\n\n constructor(data?: LoginUriApi) {\n if (data == null) {\n return;\n }\n this.uri = data.uri;\n this.match = data.match;\n }\n}\n","import { PasswordHistoryResponse } from '../response/passwordHistoryResponse';\n\nexport class PasswordHistoryData {\n password: string;\n lastUsedDate: string;\n\n constructor(response?: PasswordHistoryResponse) {\n if (response == null) {\n return;\n }\n\n this.password = response.password;\n this.lastUsedDate = response.lastUsedDate;\n }\n}\n","import { SecureNoteType } from '../../enums/secureNoteType';\n\nimport { SecureNoteApi } from '../api/secureNoteApi';\n\nexport class SecureNoteData {\n type: SecureNoteType;\n\n constructor(data?: SecureNoteApi) {\n if (data == null) {\n return;\n }\n\n this.type = data.type;\n }\n}\n","import { AttachmentData } from '../data/attachmentData';\n\nimport { AttachmentView } from '../view/attachmentView';\n\nimport Domain from './domainBase';\nimport { EncString } from './encString';\nimport { SymmetricCryptoKey } from './symmetricCryptoKey';\n\nimport { CryptoService } from '../../abstractions/crypto.service';\n\nimport { Utils } from '../../misc/utils';\n\nexport class Attachment extends Domain {\n id: string;\n url: string;\n size: string;\n sizeName: string;\n key: EncString;\n fileName: EncString;\n\n constructor(obj?: AttachmentData, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.size = obj.size;\n this.buildDomainModel(this, obj, {\n id: null,\n url: null,\n sizeName: null,\n fileName: null,\n key: null,\n }, alreadyEncrypted, ['id', 'url', 'sizeName']);\n }\n\n async decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise {\n const view = await this.decryptObj(new AttachmentView(this), {\n fileName: null,\n }, orgId, encKey);\n\n if (this.key != null) {\n let cryptoService: CryptoService;\n const containerService = (Utils.global as any).bitwardenContainerService;\n if (containerService) {\n cryptoService = containerService.getCryptoService();\n } else {\n throw new Error('global bitwardenContainerService not initialized.');\n }\n\n try {\n const orgKey = await cryptoService.getOrgKey(orgId);\n const decValue = await cryptoService.decryptToBytes(this.key, orgKey ?? encKey);\n view.key = new SymmetricCryptoKey(decValue);\n } catch (e) {\n // TODO: error?\n }\n }\n\n return view;\n }\n\n toAttachmentData(): AttachmentData {\n const a = new AttachmentData();\n a.size = this.size;\n this.buildDataModel(this, a, {\n id: null,\n url: null,\n sizeName: null,\n fileName: null,\n key: null,\n }, ['id', 'url', 'sizeName']);\n return a;\n }\n}\n","import { PasswordHistoryData } from '../data/passwordHistoryData';\n\nimport Domain from './domainBase';\nimport { EncString } from './encString';\n\nimport { PasswordHistoryView } from '../view/passwordHistoryView';\nimport { SymmetricCryptoKey } from './symmetricCryptoKey';\n\nexport class Password extends Domain {\n password: EncString;\n lastUsedDate: Date;\n\n constructor(obj?: PasswordHistoryData, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.buildDomainModel(this, obj, {\n password: null,\n }, alreadyEncrypted);\n this.lastUsedDate = new Date(obj.lastUsedDate);\n }\n\n decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise {\n return this.decryptObj(new PasswordHistoryView(this), {\n password: null,\n }, orgId, encKey);\n }\n\n toPasswordHistoryData(): PasswordHistoryData {\n const ph = new PasswordHistoryData();\n ph.lastUsedDate = this.lastUsedDate.toISOString();\n this.buildDataModel(this, ph, {\n password: null,\n });\n return ph;\n }\n}\n","import { CipherRequest } from './cipherRequest';\n\nimport { Cipher } from '../domain/cipher';\n\nexport class CipherCreateRequest {\n cipher: CipherRequest;\n collectionIds: string[];\n\n constructor(cipher: Cipher) {\n this.cipher = new CipherRequest(cipher);\n this.collectionIds = cipher.collectionIds;\n }\n}\n","import { BaseResponse } from '../response/baseResponse';\n\nexport class CardApi extends BaseResponse {\n cardholderName: string;\n brand: string;\n number: string;\n expMonth: string;\n expYear: string;\n code: string;\n\n constructor(data: any = null) {\n super(data);\n if (data == null) {\n return;\n }\n this.cardholderName = this.getResponseProperty('CardholderName');\n this.brand = this.getResponseProperty('Brand');\n this.number = this.getResponseProperty('Number');\n this.expMonth = this.getResponseProperty('ExpMonth');\n this.expYear = this.getResponseProperty('ExpYear');\n this.code = this.getResponseProperty('Code');\n }\n}\n","import { BaseResponse } from '../response/baseResponse';\n\nimport { FieldType } from '../../enums/fieldType';\nimport { LinkedIdType } from '../../enums/linkedIdType';\n\nexport class FieldApi extends BaseResponse {\n name: string;\n value: string;\n type: FieldType;\n linkedId: LinkedIdType;\n\n constructor(data: any = null) {\n super(data);\n if (data == null) {\n return;\n }\n this.type = this.getResponseProperty('Type');\n this.name = this.getResponseProperty('Name');\n this.value = this.getResponseProperty('Value');\n this.linkedId = this.getResponseProperty('linkedId');\n }\n}\n","import { BaseResponse } from '../response/baseResponse';\n\nexport class IdentityApi extends BaseResponse {\n title: string;\n firstName: string;\n middleName: string;\n lastName: string;\n address1: string;\n address2: string;\n address3: string;\n city: string;\n state: string;\n postalCode: string;\n country: string;\n company: string;\n email: string;\n phone: string;\n ssn: string;\n username: string;\n passportNumber: string;\n licenseNumber: string;\n\n constructor(data: any = null) {\n super(data);\n if (data == null) {\n return;\n }\n this.title = this.getResponseProperty('Title');\n this.firstName = this.getResponseProperty('FirstName');\n this.middleName = this.getResponseProperty('MiddleName');\n this.lastName = this.getResponseProperty('LastName');\n this.address1 = this.getResponseProperty('Address1');\n this.address2 = this.getResponseProperty('Address2');\n this.address3 = this.getResponseProperty('Address3');\n this.city = this.getResponseProperty('City');\n this.state = this.getResponseProperty('State');\n this.postalCode = this.getResponseProperty('PostalCode');\n this.country = this.getResponseProperty('Country');\n this.company = this.getResponseProperty('Company');\n this.email = this.getResponseProperty('Email');\n this.phone = this.getResponseProperty('Phone');\n this.ssn = this.getResponseProperty('SSN');\n this.username = this.getResponseProperty('Username');\n this.passportNumber = this.getResponseProperty('PassportNumber');\n this.licenseNumber = this.getResponseProperty('LicenseNumber');\n }\n}\n","import { BaseResponse } from '../response/baseResponse';\n\nimport { LoginUriApi } from './loginUriApi';\n\nexport class LoginApi extends BaseResponse {\n uris: LoginUriApi[];\n username: string;\n password: string;\n passwordRevisionDate: string;\n totp: string;\n autofillOnPageLoad: boolean;\n\n constructor(data: any = null) {\n super(data);\n if (data == null) {\n return;\n }\n this.username = this.getResponseProperty('Username');\n this.password = this.getResponseProperty('Password');\n this.passwordRevisionDate = this.getResponseProperty('PasswordRevisionDate');\n this.totp = this.getResponseProperty('Totp');\n this.autofillOnPageLoad = this.getResponseProperty('AutofillOnPageLoad');\n\n const uris = this.getResponseProperty('Uris');\n if (uris != null) {\n this.uris = uris.map((u: any) => new LoginUriApi(u));\n }\n }\n}\n","import { BaseResponse } from '../response/baseResponse';\n\nimport { UriMatchType } from '../../enums/uriMatchType';\n\nexport class LoginUriApi extends BaseResponse {\n uri: string;\n match: UriMatchType = null;\n\n constructor(data: any = null) {\n super(data);\n if (data == null) {\n return;\n }\n this.uri = this.getResponseProperty('Uri');\n const match = this.getResponseProperty('Match');\n this.match = match != null ? match : null;\n }\n}\n","import { BaseResponse } from '../response/baseResponse';\n\nimport { SecureNoteType } from '../../enums/secureNoteType';\n\nexport class SecureNoteApi extends BaseResponse {\n type: SecureNoteType;\n\n constructor(data: any = null) {\n super(data);\n if (data == null) {\n return;\n }\n this.type = this.getResponseProperty('Type');\n }\n}\n","import {\n Directive,\n ElementRef,\n forwardRef,\n HostListener,\n Input,\n Renderer2,\n} from '@angular/core';\nimport {\n ControlValueAccessor,\n NgControl,\n NG_VALUE_ACCESSOR,\n} from '@angular/forms';\n\n// ref: https://juristr.com/blog/2018/02/ng-true-value-directive/\n@Directive({\n selector: 'input[type=checkbox][appTrueFalseValue]',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => TrueFalseValueDirective),\n multi: true,\n },\n ],\n})\nexport class TrueFalseValueDirective implements ControlValueAccessor {\n @Input() trueValue = true;\n @Input() falseValue = false;\n\n constructor(private elementRef: ElementRef, private renderer: Renderer2) { }\n\n @HostListener('change', ['$event'])\n onHostChange(ev: any) {\n this.propagateChange(ev.target.checked ? this.trueValue : this.falseValue);\n }\n\n writeValue(obj: any): void {\n if (obj === this.trueValue) {\n this.renderer.setProperty(this.elementRef.nativeElement, 'checked', true);\n } else {\n this.renderer.setProperty(this.elementRef.nativeElement, 'checked', false);\n }\n }\n\n registerOnChange(fn: any): void {\n this.propagateChange = fn;\n }\n\n registerOnTouched(fn: any): void { /* nothing */ }\n\n setDisabledState?(isDisabled: boolean): void { /* nothing */ }\n\n private propagateChange = (_: any) => { /* nothing */ };\n}\n","import {\n Directive,\n ElementRef,\n HostListener,\n Input,\n} from '@angular/core';\n\n@Directive({\n selector: '[appFallbackSrc]',\n})\nexport class FallbackSrcDirective {\n @Input('appFallbackSrc') appFallbackSrc: string;\n\n constructor(private el: ElementRef) {\n }\n\n @HostListener('error') onError() {\n this.el.nativeElement.src = this.appFallbackSrc;\n }\n}\n","import { Component } from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { ImportService } from 'jslib-common/abstractions/import.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ImportComponent as BaseImportComponent } from '../../tools/import.component';\n\n@Component({\n selector: 'app-org-import',\n templateUrl: '../../tools/import.component.html',\n})\nexport class ImportComponent extends BaseImportComponent {\n organizationName: string;\n\n constructor(i18nService: I18nService, toasterService: ToasterService,\n importService: ImportService, router: Router, private route: ActivatedRoute,\n platformUtilsService: PlatformUtilsService, policyService: PolicyService,\n private userService: UserService, logService: LogService) {\n super(i18nService, toasterService, importService, router, platformUtilsService, policyService, logService);\n }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organizationId = params.organizationId;\n this.successNavigate = ['organizations', this.organizationId, 'vault'];\n await super.ngOnInit();\n this.importBlockedByPolicy = false;\n });\n const organization = await this.userService.getOrganization(this.organizationId);\n this.organizationName = organization.name;\n }\n\n async submit() {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('importWarning', this.organizationName),\n this.i18nService.t('warning'), this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return;\n }\n super.submit();\n }\n}\n","import { Component } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport {\n InactiveTwoFactorReportComponent as BaseInactiveTwoFactorReportComponent,\n} from '../../tools/inactive-two-factor-report.component';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\n@Component({\n selector: 'app-inactive-two-factor-report',\n templateUrl: '../../tools/inactive-two-factor-report.component.html',\n})\nexport class InactiveTwoFactorReportComponent extends BaseInactiveTwoFactorReportComponent {\n constructor(cipherService: CipherService, modalService: ModalService,\n messagingService: MessagingService, userService: UserService,\n private route: ActivatedRoute, logService: LogService, passwordRepromptService: PasswordRepromptService) {\n super(cipherService, modalService, messagingService, userService, logService, passwordRepromptService);\n }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organization = await this.userService.getOrganization(params.organizationId);\n await super.ngOnInit();\n });\n }\n\n getAllCiphers(): Promise {\n return this.cipherService.getAllFromApiForOrganization(this.organization.id);\n }\n}\n","import { Component } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { Cipher } from 'jslib-common/models/domain/cipher';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\nimport {\n ReusedPasswordsReportComponent as BaseReusedPasswordsReportComponent,\n} from '../../tools/reused-passwords-report.component';\n\n@Component({\n selector: 'app-reused-passwords-report',\n templateUrl: '../../tools/reused-passwords-report.component.html',\n})\nexport class ReusedPasswordsReportComponent extends BaseReusedPasswordsReportComponent {\n manageableCiphers: Cipher[];\n\n constructor(cipherService: CipherService, modalService: ModalService,\n messagingService: MessagingService, userService: UserService, passwordRepromptService: PasswordRepromptService,\n private route: ActivatedRoute) {\n super(cipherService, modalService, messagingService, userService, passwordRepromptService);\n }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organization = await this.userService.getOrganization(params.organizationId);\n this.manageableCiphers = await this.cipherService.getAll();\n await super.ngOnInit();\n });\n }\n\n getAllCiphers(): Promise {\n return this.cipherService.getAllFromApiForOrganization(this.organization.id);\n }\n\n canManageCipher(c: CipherView): boolean {\n return this.manageableCiphers.some(x => x.id === c.id);\n }\n}\n","import { Component } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\n\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\n@Component({\n selector: 'app-org-tools',\n templateUrl: 'tools.component.html',\n})\nexport class ToolsComponent {\n organization: Organization;\n accessReports = false;\n loading = true;\n\n constructor(private route: ActivatedRoute, private userService: UserService,\n private messagingService: MessagingService) { }\n\n ngOnInit() {\n this.route.parent.params.subscribe(async params => {\n this.organization = await this.userService.getOrganization(params.organizationId);\n // TODO: Maybe we want to just make sure they are not on a free plan? Just compare useTotp for now\n // since all paid plans include useTotp\n this.accessReports = this.organization.useTotp;\n this.loading = false;\n });\n }\n\n upgradeOrganization() {\n this.messagingService.send('upgradeOrganization', { organizationId: this.organization.id });\n }\n}\n"," ","import { Component } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport {\n UnsecuredWebsitesReportComponent as BaseUnsecuredWebsitesReportComponent,\n} from '../../tools/unsecured-websites-report.component';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\n@Component({\n selector: 'app-unsecured-websites-report',\n templateUrl: '../../tools/unsecured-websites-report.component.html',\n})\nexport class UnsecuredWebsitesReportComponent extends BaseUnsecuredWebsitesReportComponent {\n constructor(cipherService: CipherService, modalService: ModalService,\n messagingService: MessagingService, userService: UserService, passwordRepromptService: PasswordRepromptService,\n private route: ActivatedRoute) {\n super(cipherService, modalService, messagingService, userService, passwordRepromptService);\n }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organization = await this.userService.getOrganization(params.organizationId);\n await super.ngOnInit();\n });\n }\n\n getAllCiphers(): Promise {\n return this.cipherService.getAllFromApiForOrganization(this.organization.id);\n }\n}\n","import { Component } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { Cipher } from 'jslib-common/models/domain/cipher';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\nimport {\n WeakPasswordsReportComponent as BaseWeakPasswordsReportComponent,\n} from '../../tools/weak-passwords-report.component';\n\n@Component({\n selector: 'app-weak-passwords-report',\n templateUrl: '../../tools/weak-passwords-report.component.html',\n})\nexport class WeakPasswordsReportComponent extends BaseWeakPasswordsReportComponent {\n manageableCiphers: Cipher[];\n\n constructor(cipherService: CipherService, passwordGenerationService: PasswordGenerationService,\n modalService: ModalService, messagingService: MessagingService,\n userService: UserService, passwordRepromptService: PasswordRepromptService, private route: ActivatedRoute) {\n super(cipherService, passwordGenerationService, modalService, messagingService, userService,\n passwordRepromptService);\n }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organization = await this.userService.getOrganization(params.organizationId);\n this.manageableCiphers = await this.cipherService.getAll();\n await super.ngOnInit();\n });\n }\n\n getAllCiphers(): Promise {\n return this.cipherService.getAllFromApiForOrganization(this.organization.id);\n }\n\n canManageCipher(c: CipherView): boolean {\n return this.manageableCiphers.some(x => x.id === c.id);\n }\n}\n","import {\n Component,\n OnInit,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\nimport {\n Toast,\n ToasterService,\n} from 'angular2-toaster';\n\nimport { first } from 'rxjs/operators';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\nimport { ValidationService } from 'jslib-angular/services/validation.service';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { PlanSponsorshipType } from 'jslib-common/enums/planSponsorshipType';\nimport { PlanType } from 'jslib-common/enums/planType';\nimport { ProductType } from 'jslib-common/enums/productType';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\n\nimport { OrganizationSponsorshipRedeemRequest } from 'jslib-common/models/request/organization/organizationSponsorshipRedeemRequest';\n\nimport { DeleteOrganizationComponent } from 'src/app/organizations/settings/delete-organization.component';\n\nimport { OrganizationPlansComponent } from 'src/app/settings/organization-plans.component';\n\n@Component({\n selector: 'families-for-enterprise-setup',\n templateUrl: 'families-for-enterprise-setup.component.html',\n})\nexport class FamiliesForEnterpriseSetupComponent implements OnInit {\n @ViewChild(OrganizationPlansComponent, { static: false })\n set organizationPlansComponent(value: OrganizationPlansComponent) {\n if (!value) {\n return;\n }\n\n value.plan = PlanType.FamiliesAnnually;\n value.product = ProductType.Families;\n value.acceptingSponsorship = true;\n value.onSuccess.subscribe(this.onOrganizationCreateSuccess.bind(this));\n }\n\n @ViewChild('deleteOrganizationTemplate', { read: ViewContainerRef, static: true }) deleteModalRef: ViewContainerRef;\n\n loading = true;\n badToken = false;\n formPromise: Promise;\n\n token: string;\n existingFamilyOrganizations: Organization[];\n\n showNewOrganization: boolean = false;\n _organizationPlansComponent: OrganizationPlansComponent;\n _selectedFamilyOrganizationId: string = '';\n\n constructor(private router: Router, private toasterService: ToasterService,\n private i18nService: I18nService, private route: ActivatedRoute,\n private apiService: ApiService, private syncService: SyncService,\n private validationService: ValidationService, private userService: UserService,\n private modalService: ModalService) { }\n\n async ngOnInit() {\n document.body.classList.remove('layout_frontend');\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n const error = qParams.token == null;\n if (error) {\n const toast: Toast = {\n type: 'error',\n title: null,\n body: this.i18nService.t('sponsoredFamiliesAcceptFailed'),\n timeout: 10000,\n };\n this.toasterService.popAsync(toast);\n this.router.navigate(['/']);\n return;\n }\n\n this.token = qParams.token;\n\n await this.syncService.fullSync(true);\n this.badToken = !await this.apiService.postPreValidateSponsorshipToken(this.token);\n this.loading = false;\n\n this.existingFamilyOrganizations = (await this.userService.getAllOrganizations())\n .filter(o => o.planProductType === ProductType.Families);\n\n if (this.existingFamilyOrganizations.length === 0) {\n this.selectedFamilyOrganizationId = 'createNew';\n }\n });\n }\n\n async submit() {\n this.formPromise = this.doSubmit(this._selectedFamilyOrganizationId);\n await this.formPromise;\n this.formPromise = null;\n }\n\n get selectedFamilyOrganizationId() {\n return this._selectedFamilyOrganizationId;\n }\n\n set selectedFamilyOrganizationId(value: string) {\n this._selectedFamilyOrganizationId = value;\n this.showNewOrganization = value === 'createNew';\n }\n\n private async doSubmit(organizationId: string) {\n try {\n const request = new OrganizationSponsorshipRedeemRequest();\n request.planSponsorshipType = PlanSponsorshipType.FamiliesForEnterprise;\n request.sponsoredOrganizationId = organizationId;\n\n await this.apiService.postRedeemSponsorship(this.token, request);\n this.toasterService.popAsync('success', null, this.i18nService.t('sponsoredFamiliesOfferRedeemed'));\n await this.syncService.fullSync(true);\n\n this.router.navigate(['/']);\n } catch (e) {\n if (this.showNewOrganization) {\n await this.modalService.openViewRef(DeleteOrganizationComponent, this.deleteModalRef, comp => {\n comp.organizationId = organizationId;\n comp.descriptionKey = 'orgCreatedSponsorshipInvalid';\n comp.onSuccess.subscribe(() => {\n this.router.navigate(['/']);\n });\n });\n }\n this.validationService.showError(this.i18nService.t('sponsorshipTokenHasExpired'));\n }\n }\n\n private async onOrganizationCreateSuccess(value: any) {\n // Use newly created organization id\n await this.doSubmit(value.organizationId);\n }\n}\n","

{{'sponsoredFamiliesOffer' | i18n}}

{{'loading' | i18n}}
{{'badToken' | i18n}}

{{'acceptBitwardenFamiliesHelp' | i18n}}

","export enum PlanSponsorshipType {\n FamiliesForEnterprise = 0,\n}\n","import { Component } from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { CipherData } from 'jslib-common/models/data/cipherData';\nimport { Cipher } from 'jslib-common/models/domain/cipher';\nimport { Organization } from 'jslib-common/models/domain/organization';\n\nimport { AttachmentView } from 'jslib-common/models/view/attachmentView';\n\nimport { AttachmentsComponent as BaseAttachmentsComponent } from '../../vault/attachments.component';\n\n@Component({\n selector: 'app-org-vault-attachments',\n templateUrl: '../../vault/attachments.component.html',\n})\nexport class AttachmentsComponent extends BaseAttachmentsComponent {\n viewOnly = false;\n organization: Organization;\n\n constructor(cipherService: CipherService, i18nService: I18nService,\n cryptoService: CryptoService, userService: UserService,\n platformUtilsService: PlatformUtilsService, apiService: ApiService,\n logService: LogService) {\n super(cipherService, i18nService, cryptoService, userService, platformUtilsService, apiService,\n logService);\n }\n\n protected async reupload(attachment: AttachmentView) {\n if (this.organization.canEditAnyCollection && this.showFixOldAttachments(attachment)) {\n await super.reuploadCipherAttachment(attachment, true);\n }\n }\n\n protected async loadCipher() {\n if (!this.organization.canEditAnyCollection) {\n return await super.loadCipher();\n }\n const response = await this.apiService.getCipherAdmin(this.cipherId);\n return new Cipher(new CipherData(response));\n }\n\n protected saveCipherAttachment(file: File) {\n return this.cipherService.saveAttachmentWithServer(this.cipherDomain, file, this.organization.canEditAnyCollection);\n }\n\n protected deleteCipherAttachment(attachmentId: string) {\n if (!this.organization.canEditAnyCollection) {\n return super.deleteCipherAttachment(attachmentId);\n }\n return this.apiService.deleteCipherAttachmentAdmin(this.cipherId, attachmentId);\n }\n\n protected showFixOldAttachments(attachment: AttachmentView) {\n return attachment.key == null && this.organization.canEditAnyCollection;\n }\n}\n","import {\n Directive,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Cipher } from 'jslib-common/models/domain/cipher';\nimport { ErrorResponse } from 'jslib-common/models/response/errorResponse';\n\nimport { AttachmentView } from 'jslib-common/models/view/attachmentView';\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\n@Directive()\nexport class AttachmentsComponent implements OnInit {\n @Input() cipherId: string;\n @Output() onUploadedAttachment = new EventEmitter();\n @Output() onDeletedAttachment = new EventEmitter();\n @Output() onReuploadedAttachment = new EventEmitter();\n\n cipher: CipherView;\n cipherDomain: Cipher;\n hasUpdatedKey: boolean;\n canAccessAttachments: boolean;\n formPromise: Promise;\n deletePromises: { [id: string]: Promise; } = {};\n reuploadPromises: { [id: string]: Promise; } = {};\n emergencyAccessId?: string = null;\n\n constructor(protected cipherService: CipherService, protected i18nService: I18nService,\n protected cryptoService: CryptoService, protected userService: UserService,\n protected platformUtilsService: PlatformUtilsService, protected apiService: ApiService,\n protected win: Window, private logService: LogService) { }\n\n async ngOnInit() {\n await this.init();\n }\n\n async submit() {\n if (!this.hasUpdatedKey) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('updateKey'));\n return;\n }\n\n const fileEl = document.getElementById('file') as HTMLInputElement;\n const files = fileEl.files;\n if (files == null || files.length === 0) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('selectFile'));\n return;\n }\n\n if (files[0].size > 524288000) { // 500 MB\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('maxFileSize'));\n return;\n }\n\n try {\n this.formPromise = this.saveCipherAttachment(files[0]);\n this.cipherDomain = await this.formPromise;\n this.cipher = await this.cipherDomain.decrypt();\n this.platformUtilsService.showToast('success', null, this.i18nService.t('attachmentSaved'));\n this.onUploadedAttachment.emit();\n } catch (e) {\n this.logService.error(e);\n }\n\n // reset file input\n // ref: https://stackoverflow.com/a/20552042\n fileEl.type = '';\n fileEl.type = 'file';\n fileEl.value = '';\n }\n\n async delete(attachment: AttachmentView) {\n if (this.deletePromises[attachment.id] != null) {\n return;\n }\n\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('deleteAttachmentConfirmation'), this.i18nService.t('deleteAttachment'),\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return;\n }\n\n try {\n this.deletePromises[attachment.id] = this.deleteCipherAttachment(attachment.id);\n await this.deletePromises[attachment.id];\n this.platformUtilsService.showToast('success', null, this.i18nService.t('deletedAttachment'));\n const i = this.cipher.attachments.indexOf(attachment);\n if (i > -1) {\n this.cipher.attachments.splice(i, 1);\n }\n } catch (e) {\n this.logService.error(e);\n }\n\n this.deletePromises[attachment.id] = null;\n this.onDeletedAttachment.emit();\n }\n\n async download(attachment: AttachmentView) {\n const a = (attachment as any);\n if (a.downloading) {\n return;\n }\n\n if (!this.canAccessAttachments) {\n this.platformUtilsService.showToast('error', this.i18nService.t('premiumRequired'),\n this.i18nService.t('premiumRequiredDesc'));\n return;\n }\n\n let url: string;\n try {\n const attachmentDownloadResponse = await this.apiService.getAttachmentData(this.cipher.id, attachment.id,\n this.emergencyAccessId);\n url = attachmentDownloadResponse.url;\n } catch (e) {\n if (e instanceof ErrorResponse && (e as ErrorResponse).statusCode === 404) {\n url = attachment.url;\n } else if (e instanceof ErrorResponse) {\n throw new Error((e as ErrorResponse).getSingleMessage());\n } else {\n throw e;\n }\n }\n\n a.downloading = true;\n const response = await fetch(new Request(url, { cache: 'no-store' }));\n if (response.status !== 200) {\n this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred'));\n a.downloading = false;\n return;\n }\n\n try {\n const buf = await response.arrayBuffer();\n const key = attachment.key != null ? attachment.key :\n await this.cryptoService.getOrgKey(this.cipher.organizationId);\n const decBuf = await this.cryptoService.decryptFromBytes(buf, key);\n this.platformUtilsService.saveFile(this.win, decBuf, null, attachment.fileName);\n } catch (e) {\n this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred'));\n }\n\n a.downloading = false;\n }\n\n protected async init() {\n this.cipherDomain = await this.loadCipher();\n this.cipher = await this.cipherDomain.decrypt();\n\n this.hasUpdatedKey = await this.cryptoService.hasEncKey();\n const canAccessPremium = await this.userService.canAccessPremium();\n this.canAccessAttachments = canAccessPremium || this.cipher.organizationId != null;\n\n if (!this.canAccessAttachments) {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('premiumRequiredDesc'), this.i18nService.t('premiumRequired'),\n this.i18nService.t('learnMore'), this.i18nService.t('cancel'));\n if (confirmed) {\n this.platformUtilsService.launchUri('https://vault.bitwarden.com/#/?premium=purchase');\n }\n } else if (!this.hasUpdatedKey) {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('updateKey'), this.i18nService.t('featureUnavailable'),\n this.i18nService.t('learnMore'), this.i18nService.t('cancel'), 'warning');\n if (confirmed) {\n this.platformUtilsService.launchUri('https://help.bitwarden.com/article/update-encryption-key/');\n }\n }\n }\n\n protected async reuploadCipherAttachment(attachment: AttachmentView, admin: boolean) {\n const a = (attachment as any);\n if (attachment.key != null || a.downloading || this.reuploadPromises[attachment.id] != null) {\n return;\n }\n\n try {\n this.reuploadPromises[attachment.id] = Promise.resolve().then(async () => {\n // 1. Download\n a.downloading = true;\n const response = await fetch(new Request(attachment.url, { cache: 'no-store' }));\n if (response.status !== 200) {\n this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred'));\n a.downloading = false;\n return;\n }\n\n try {\n // 2. Resave\n const buf = await response.arrayBuffer();\n const key = attachment.key != null ? attachment.key :\n await this.cryptoService.getOrgKey(this.cipher.organizationId);\n const decBuf = await this.cryptoService.decryptFromBytes(buf, key);\n this.cipherDomain = await this.cipherService.saveAttachmentRawWithServer(\n this.cipherDomain, attachment.fileName, decBuf, admin);\n this.cipher = await this.cipherDomain.decrypt();\n\n // 3. Delete old\n this.deletePromises[attachment.id] = this.deleteCipherAttachment(attachment.id);\n await this.deletePromises[attachment.id];\n const foundAttachment = this.cipher.attachments.filter(a2 => a2.id === attachment.id);\n if (foundAttachment.length > 0) {\n const i = this.cipher.attachments.indexOf(foundAttachment[0]);\n if (i > -1) {\n this.cipher.attachments.splice(i, 1);\n }\n }\n\n this.platformUtilsService.showToast('success', null, this.i18nService.t('attachmentSaved'));\n this.onReuploadedAttachment.emit();\n } catch (e) {\n this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred'));\n }\n\n a.downloading = false;\n });\n await this.reuploadPromises[attachment.id];\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n protected loadCipher() {\n return this.cipherService.get(this.cipherId);\n }\n\n protected saveCipherAttachment(file: File) {\n return this.cipherService.saveAttachmentWithServer(this.cipherDomain, file);\n }\n\n protected deleteCipherAttachment(attachmentId: string) {\n return this.cipherService.deleteAttachmentWithServer(this.cipher.id, attachmentId);\n }\n}\n","import { Component } from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { CipherData } from 'jslib-common/models/data/cipherData';\nimport { Cipher } from 'jslib-common/models/domain/cipher';\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport { CipherCollectionsRequest } from 'jslib-common/models/request/cipherCollectionsRequest';\n\nimport { CollectionsComponent as BaseCollectionsComponent } from '../../vault/collections.component';\n\n@Component({\n selector: 'app-org-vault-collections',\n templateUrl: '../../vault/collections.component.html',\n})\nexport class CollectionsComponent extends BaseCollectionsComponent {\n organization: Organization;\n\n constructor(collectionService: CollectionService, platformUtilsService: PlatformUtilsService,\n i18nService: I18nService, cipherService: CipherService,\n private apiService: ApiService, logService: LogService) {\n super(collectionService, platformUtilsService, i18nService, cipherService, logService);\n this.allowSelectNone = true;\n }\n\n protected async loadCipher() {\n if (!this.organization.canViewAllCollections) {\n return await super.loadCipher();\n }\n const response = await this.apiService.getCipherAdmin(this.cipherId);\n return new Cipher(new CipherData(response));\n }\n\n protected loadCipherCollections() {\n if (!this.organization.canViewAllCollections) {\n return super.loadCipherCollections();\n }\n return this.collectionIds;\n }\n\n protected loadCollections() {\n if (!this.organization.canViewAllCollections) {\n return super.loadCollections();\n }\n return Promise.resolve(this.collections);\n }\n\n protected saveCollections() {\n if (this.organization.canEditAnyCollection) {\n const request = new CipherCollectionsRequest(this.cipherDomain.collectionIds);\n return this.apiService.putCipherCollectionsAdmin(this.cipherId, request);\n } else {\n return super.saveCollections();\n }\n }\n}\n","export class CipherCollectionsRequest {\n collectionIds: string[];\n\n constructor(collectionIds: string[]) {\n this.collectionIds = collectionIds == null ? [] : collectionIds;\n }\n}\n","import {\n ChangeDetectorRef,\n Component,\n NgZone,\n OnDestroy,\n OnInit,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { first } from 'rxjs/operators';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { BroadcasterService } from 'jslib-angular/services/broadcaster.service';\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\nimport { CipherType } from 'jslib-common/enums/cipherType';\n\nimport { EntityEventsComponent } from '../manage/entity-events.component';\nimport { AddEditComponent } from './add-edit.component';\nimport { AttachmentsComponent } from './attachments.component';\nimport { CiphersComponent } from './ciphers.component';\nimport { CollectionsComponent } from './collections.component';\nimport { GroupingsComponent } from './groupings.component';\n\nconst BroadcasterSubscriptionId = 'OrgVaultComponent';\n\n@Component({\n selector: 'app-org-vault',\n templateUrl: 'vault.component.html',\n})\nexport class VaultComponent implements OnInit, OnDestroy {\n @ViewChild(GroupingsComponent, { static: true }) groupingsComponent: GroupingsComponent;\n @ViewChild(CiphersComponent, { static: true }) ciphersComponent: CiphersComponent;\n @ViewChild('attachments', { read: ViewContainerRef, static: true }) attachmentsModalRef: ViewContainerRef;\n @ViewChild('cipherAddEdit', { read: ViewContainerRef, static: true }) cipherAddEditModalRef: ViewContainerRef;\n @ViewChild('collections', { read: ViewContainerRef, static: true }) collectionsModalRef: ViewContainerRef;\n @ViewChild('eventsTemplate', { read: ViewContainerRef, static: true }) eventsModalRef: ViewContainerRef;\n\n organization: Organization;\n collectionId: string = null;\n type: CipherType = null;\n deleted: boolean = false;\n trashCleanupWarning: string = null;\n\n constructor(private route: ActivatedRoute, private userService: UserService,\n private router: Router, private changeDetectorRef: ChangeDetectorRef,\n private syncService: SyncService, private i18nService: I18nService,\n private modalService: ModalService, private messagingService: MessagingService,\n private broadcasterService: BroadcasterService, private ngZone: NgZone,\n private platformUtilsService: PlatformUtilsService) { }\n\n ngOnInit() {\n this.trashCleanupWarning = this.i18nService.t(\n this.platformUtilsService.isSelfHost() ? 'trashCleanupWarningSelfHosted' : 'trashCleanupWarning'\n );\n\n this.route.parent.params.pipe(first()).subscribe(async params => {\n this.organization = await this.userService.getOrganization(params.organizationId);\n this.groupingsComponent.organization = this.organization;\n this.ciphersComponent.organization = this.organization;\n\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n this.ciphersComponent.searchText = this.groupingsComponent.searchText = qParams.search;\n if (!this.organization.canViewAllCollections) {\n await this.syncService.fullSync(false);\n this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {\n this.ngZone.run(async () => {\n switch (message.command) {\n case 'syncCompleted':\n if (message.successfully) {\n await Promise.all([\n this.groupingsComponent.load(),\n this.ciphersComponent.refresh(),\n ]);\n this.changeDetectorRef.detectChanges();\n }\n break;\n }\n });\n });\n }\n await this.groupingsComponent.load();\n\n if (qParams == null) {\n this.groupingsComponent.selectedAll = true;\n await this.ciphersComponent.reload();\n } else {\n if (qParams.deleted) {\n this.groupingsComponent.selectedTrash = true;\n await this.filterDeleted(true);\n } else if (qParams.type) {\n const t = parseInt(qParams.type, null);\n this.groupingsComponent.selectedType = t;\n await this.filterCipherType(t, true);\n } else if (qParams.collectionId) {\n this.groupingsComponent.selectedCollectionId = qParams.collectionId;\n await this.filterCollection(qParams.collectionId, true);\n } else {\n this.groupingsComponent.selectedAll = true;\n await this.ciphersComponent.reload();\n }\n }\n\n if (qParams.viewEvents != null) {\n const cipher = this.ciphersComponent.ciphers.filter(c => c.id === qParams.viewEvents);\n if (cipher.length > 0) {\n this.viewEvents(cipher[0]);\n }\n }\n });\n });\n }\n\n ngOnDestroy() {\n this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);\n }\n\n async clearGroupingFilters() {\n this.ciphersComponent.showAddNew = true;\n this.ciphersComponent.deleted = false;\n this.groupingsComponent.searchPlaceholder = this.i18nService.t('searchVault');\n await this.ciphersComponent.applyFilter();\n this.clearFilters();\n this.go();\n }\n\n async filterCipherType(type: CipherType, load = false) {\n this.ciphersComponent.showAddNew = true;\n this.ciphersComponent.deleted = false;\n this.groupingsComponent.searchPlaceholder = this.i18nService.t('searchType');\n const filter = (c: CipherView) => c.type === type;\n if (load) {\n await this.ciphersComponent.reload(filter);\n } else {\n await this.ciphersComponent.applyFilter(filter);\n }\n this.clearFilters();\n this.type = type;\n this.go();\n }\n\n async filterCollection(collectionId: string, load = false) {\n this.ciphersComponent.showAddNew = true;\n this.ciphersComponent.deleted = false;\n this.groupingsComponent.searchPlaceholder = this.i18nService.t('searchCollection');\n const filter = (c: CipherView) => {\n if (collectionId === 'unassigned') {\n return c.collectionIds == null || c.collectionIds.length === 0;\n } else {\n return c.collectionIds != null && c.collectionIds.indexOf(collectionId) > -1;\n }\n };\n if (load) {\n await this.ciphersComponent.reload(filter);\n } else {\n await this.ciphersComponent.applyFilter(filter);\n }\n this.clearFilters();\n this.collectionId = collectionId;\n this.go();\n }\n\n async filterDeleted(load: boolean = false) {\n this.ciphersComponent.showAddNew = false;\n this.ciphersComponent.deleted = true;\n this.groupingsComponent.searchPlaceholder = this.i18nService.t('searchTrash');\n if (load) {\n await this.ciphersComponent.reload(null, true);\n } else {\n await this.ciphersComponent.applyFilter(null);\n }\n this.clearFilters();\n this.deleted = true;\n this.go();\n }\n\n filterSearchText(searchText: string) {\n this.ciphersComponent.searchText = searchText;\n this.ciphersComponent.search(200);\n }\n\n async editCipherAttachments(cipher: CipherView) {\n if (this.organization.maxStorageGb == null || this.organization.maxStorageGb === 0) {\n this.messagingService.send('upgradeOrganization', { organizationId: cipher.organizationId });\n return;\n }\n\n let madeAttachmentChanges = false;\n\n const [modal] = await this.modalService.openViewRef(AttachmentsComponent, this.attachmentsModalRef, comp => {\n comp.organization = this.organization;\n comp.cipherId = cipher.id;\n comp.onUploadedAttachment.subscribe(() => madeAttachmentChanges = true);\n comp.onDeletedAttachment.subscribe(() => madeAttachmentChanges = true);\n });\n\n modal.onClosed.subscribe(async () => {\n if (madeAttachmentChanges) {\n await this.ciphersComponent.refresh();\n }\n madeAttachmentChanges = false;\n });\n }\n\n async editCipherCollections(cipher: CipherView) {\n const [modal] = await this.modalService.openViewRef(CollectionsComponent, this.collectionsModalRef, comp => {\n if (this.organization.canEditAnyCollection) {\n comp.collectionIds = cipher.collectionIds;\n comp.collections = this.groupingsComponent.collections.filter(c => !c.readOnly);\n }\n comp.organization = this.organization;\n comp.cipherId = cipher.id;\n comp.onSavedCollections.subscribe(async () => {\n modal.close();\n await this.ciphersComponent.refresh();\n });\n });\n }\n\n async addCipher() {\n const component = await this.editCipher(null);\n component.organizationId = this.organization.id;\n component.type = this.type;\n if (this.organization.canEditAnyCollection) {\n component.collections = this.groupingsComponent.collections.filter(c => !c.readOnly);\n }\n if (this.collectionId != null) {\n component.collectionIds = [this.collectionId];\n }\n }\n\n async editCipher(cipher: CipherView) {\n const [modal, childComponent] = await this.modalService.openViewRef(AddEditComponent, this.cipherAddEditModalRef, comp => {\n comp.organization = this.organization;\n comp.cipherId = cipher == null ? null : cipher.id;\n comp.onSavedCipher.subscribe(async (c: CipherView) => {\n modal.close();\n await this.ciphersComponent.refresh();\n });\n comp.onDeletedCipher.subscribe(async (c: CipherView) => {\n modal.close();\n await this.ciphersComponent.refresh();\n });\n comp.onRestoredCipher.subscribe(async (c: CipherView) => {\n modal.close();\n await this.ciphersComponent.refresh();\n });\n });\n\n return childComponent;\n }\n\n async cloneCipher(cipher: CipherView) {\n const component = await this.editCipher(cipher);\n component.cloneMode = true;\n component.organizationId = this.organization.id;\n if (this.organization.canEditAnyCollection) {\n component.collections = this.groupingsComponent.collections.filter(c => !c.readOnly);\n }\n // Regardless of Admin state, the collection Ids need to passed manually as they are not assigned value\n // in the add-edit componenet\n component.collectionIds = cipher.collectionIds;\n }\n\n async viewEvents(cipher: CipherView) {\n await this.modalService.openViewRef(EntityEventsComponent, this.eventsModalRef, comp => {\n comp.name = cipher.name;\n comp.organizationId = this.organization.id;\n comp.entityId = cipher.id;\n comp.showUser = true;\n comp.entity = 'cipher';\n });\n }\n\n private clearFilters() {\n this.collectionId = null;\n this.type = null;\n this.deleted = false;\n }\n\n private go(queryParams: any = null) {\n if (queryParams == null) {\n queryParams = {\n type: this.type,\n collectionId: this.collectionId,\n deleted: this.deleted ? true : null,\n };\n }\n\n this.router.navigate([], {\n relativeTo: this.route,\n queryParams: queryParams,\n replaceUrl: true,\n });\n }\n}\n","

{{'vault' | i18n}} {{'loading' | i18n}}

{{trashCleanupWarning}}
","import {\n Component,\n EventEmitter,\n Input,\n Output,\n} from '@angular/core';\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport { CipherBulkDeleteRequest } from 'jslib-common/models/request/cipherBulkDeleteRequest';\n\n@Component({\n selector: 'app-vault-bulk-delete',\n templateUrl: 'bulk-delete.component.html',\n})\nexport class BulkDeleteComponent {\n @Input() cipherIds: string[] = [];\n @Input() permanent: boolean = false;\n @Input() organization: Organization;\n @Output() onDeleted = new EventEmitter();\n\n formPromise: Promise;\n\n constructor(private cipherService: CipherService, private toasterService: ToasterService,\n private i18nService: I18nService, private apiService: ApiService) { }\n\n async submit() {\n if (!this.organization || !this.organization.canEditAnyCollection) {\n await this.deleteCiphers();\n } else {\n await this.deleteCiphersAdmin();\n }\n\n await this.formPromise;\n\n this.onDeleted.emit();\n this.toasterService.popAsync('success', null, this.i18nService.t(this.permanent ? 'permanentlyDeletedItems'\n : 'deletedItems'));\n }\n\n private async deleteCiphers() {\n if (this.permanent) {\n this.formPromise = await this.cipherService.deleteManyWithServer(this.cipherIds);\n } else {\n this.formPromise = await this.cipherService.softDeleteManyWithServer(this.cipherIds);\n }\n }\n\n private async deleteCiphersAdmin() {\n const deleteRequest = new CipherBulkDeleteRequest(this.cipherIds, this.organization.id);\n if (this.permanent) {\n this.formPromise = await this.apiService.deleteManyCiphersAdmin(deleteRequest);\n } else {\n this.formPromise = await this.apiService.putDeleteManyCiphersAdmin(deleteRequest);\n }\n }\n}\n","

{{(permanent ? 'permanentlyDeleteSelected' : 'deleteSelected') | i18n}}

{{(permanent ? 'permanentlyDeleteSelectedItemsDesc' : 'deleteSelectedItemsDesc') | i18n: cipherIds.length}}
","export class CipherBulkDeleteRequest {\n ids: string[];\n organizationId: string;\n\n constructor(ids: string[], organizationId?: string) {\n this.ids = ids == null ? [] : ids;\n this.organizationId = organizationId;\n }\n}\n","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { FolderService } from 'jslib-common/abstractions/folder.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\nimport { FolderView } from 'jslib-common/models/view/folderView';\n\n@Component({\n selector: 'app-vault-bulk-move',\n templateUrl: 'bulk-move.component.html',\n})\nexport class BulkMoveComponent implements OnInit {\n @Input() cipherIds: string[] = [];\n @Output() onMoved = new EventEmitter();\n\n folderId: string = null;\n folders: FolderView[] = [];\n formPromise: Promise;\n\n constructor(private cipherService: CipherService, private toasterService: ToasterService,\n private i18nService: I18nService, private folderService: FolderService) { }\n\n async ngOnInit() {\n this.folders = await this.folderService.getAllDecrypted();\n this.folderId = this.folders[0].id;\n }\n\n async submit() {\n this.formPromise = this.cipherService.moveManyWithServer(this.cipherIds, this.folderId);\n await this.formPromise;\n this.onMoved.emit();\n this.toasterService.popAsync('success', null, this.i18nService.t('movedItems'));\n }\n}\n","

{{'moveSelected' | i18n}}

{{'moveSelectedItemsDesc' | i18n: cipherIds.length}}

","import {\n Component,\n EventEmitter,\n Input,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\n@Component({\n selector: 'app-vault-bulk-restore',\n templateUrl: 'bulk-restore.component.html',\n})\nexport class BulkRestoreComponent {\n @Input() cipherIds: string[] = [];\n @Output() onRestored = new EventEmitter();\n\n formPromise: Promise;\n\n constructor(private cipherService: CipherService, private toasterService: ToasterService,\n private i18nService: I18nService) { }\n\n async submit() {\n this.formPromise = this.cipherService.restoreManyWithServer(this.cipherIds);\n await this.formPromise;\n this.onRestored.emit();\n this.toasterService.popAsync('success', null, this.i18nService.t('restoredItems'));\n }\n}\n","

{{'restoreSelected' | i18n}}

{{'restoreSelectedItemsDesc' | i18n: cipherIds.length}}
","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\nimport { CollectionView } from 'jslib-common/models/view/collectionView';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\n\n@Component({\n selector: 'app-vault-bulk-share',\n templateUrl: 'bulk-share.component.html',\n})\nexport class BulkShareComponent implements OnInit {\n @Input() ciphers: CipherView[] = [];\n @Input() organizationId: string;\n @Output() onShared = new EventEmitter();\n\n nonShareableCount = 0;\n collections: CollectionView[] = [];\n organizations: Organization[] = [];\n shareableCiphers: CipherView[] = [];\n formPromise: Promise;\n\n private writeableCollections: CollectionView[] = [];\n\n constructor(private cipherService: CipherService, private toasterService: ToasterService,\n private i18nService: I18nService, private collectionService: CollectionService,\n private userService: UserService, private logService: LogService) { }\n\n async ngOnInit() {\n this.shareableCiphers = this.ciphers.filter(c => !c.hasOldAttachments && c.organizationId == null);\n this.nonShareableCount = this.ciphers.length - this.shareableCiphers.length;\n const allCollections = await this.collectionService.getAllDecrypted();\n this.writeableCollections = allCollections.filter(c => !c.readOnly);\n this.organizations = await this.userService.getAllOrganizations();\n if (this.organizationId == null && this.organizations.length > 0) {\n this.organizationId = this.organizations[0].id;\n }\n this.filterCollections();\n }\n\n ngOnDestroy() {\n this.selectAll(false);\n }\n\n filterCollections() {\n this.selectAll(false);\n if (this.organizationId == null || this.writeableCollections.length === 0) {\n this.collections = [];\n } else {\n this.collections = this.writeableCollections.filter(c => c.organizationId === this.organizationId);\n }\n }\n\n async submit() {\n const checkedCollectionIds = this.collections.filter(c => (c as any).checked).map(c => c.id);\n try {\n this.formPromise = this.cipherService.shareManyWithServer(this.shareableCiphers, this.organizationId,\n checkedCollectionIds);\n await this.formPromise;\n this.onShared.emit();\n const orgName = this.organizations.find(o => o.id === this.organizationId)?.name ?? this.i18nService.t('organization');\n this.toasterService.popAsync('success', null, this.i18nService.t('movedItemsToOrg', orgName));\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n check(c: CollectionView, select?: boolean) {\n (c as any).checked = select == null ? !(c as any).checked : select;\n }\n\n selectAll(select: boolean) {\n const collections = select ? this.collections : this.writeableCollections;\n collections.forEach(c => this.check(c, select));\n }\n\n get canSave() {\n if (this.shareableCiphers != null && this.shareableCiphers.length > 0 && this.collections != null) {\n for (let i = 0; i < this.collections.length; i++) {\n if ((this.collections[i] as any).checked) {\n return true;\n }\n }\n }\n return false;\n }\n}\n","

{{'moveSelectedToOrg' | i18n}}

{{'moveManyToOrgDesc' | i18n}}

{{'moveSelectedItemsCountDesc' | i18n: this.ciphers.length : shareableCiphers.length : nonShareableCount}}

{{'collections' | i18n}}

{{'noCollectionsInList' | i18n}}
{{c.name}}
","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { ActivatedRoute } from '@angular/router';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { CryptoFunctionService } from 'jslib-common/abstractions/cryptoFunction.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\nimport { SendAccess } from 'jslib-common/models/domain/sendAccess';\nimport { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';\n\nimport { SendAccessView } from 'jslib-common/models/view/sendAccessView';\n\nimport { SendType } from 'jslib-common/enums/sendType';\nimport { SendAccessRequest } from 'jslib-common/models/request/sendAccessRequest';\nimport { ErrorResponse } from 'jslib-common/models/response/errorResponse';\n\nimport { SendAccessResponse } from 'jslib-common/models/response/sendAccessResponse';\n\n@Component({\n selector: 'app-send-access',\n templateUrl: 'access.component.html',\n})\nexport class AccessComponent implements OnInit {\n send: SendAccessView;\n sendType = SendType;\n downloading = false;\n loading = true;\n passwordRequired = false;\n formPromise: Promise;\n password: string;\n showText = false;\n unavailable = false;\n error = false;\n hideEmail = false;\n\n private id: string;\n private key: string;\n private decKey: SymmetricCryptoKey;\n private accessRequest: SendAccessRequest;\n\n constructor(private i18nService: I18nService, private cryptoFunctionService: CryptoFunctionService,\n private apiService: ApiService, private platformUtilsService: PlatformUtilsService,\n private route: ActivatedRoute, private cryptoService: CryptoService) {\n }\n\n get sendText() {\n if (this.send == null || this.send.text == null) {\n return null;\n }\n return this.showText ? this.send.text.text : this.send.text.maskedText;\n }\n\n get expirationDate() {\n if (this.send == null || this.send.expirationDate == null) {\n return null;\n }\n return this.send.expirationDate;\n }\n\n get creatorIdentifier() {\n if (this.send == null || this.send.creatorIdentifier == null) {\n return null;\n }\n return this.send.creatorIdentifier;\n }\n\n ngOnInit() {\n this.route.params.subscribe(async params => {\n this.id = params.sendId;\n this.key = params.key;\n if (this.key == null || this.id == null) {\n return;\n }\n await this.load();\n });\n }\n\n async download() {\n if (this.send == null || this.decKey == null) {\n return;\n }\n\n if (this.downloading) {\n return;\n }\n\n\n const downloadData = await this.apiService.getSendFileDownloadData(this.send, this.accessRequest);\n\n if (Utils.isNullOrWhitespace(downloadData.url)) {\n this.platformUtilsService.showToast('error', null, this.i18nService.t('missingSendFile'));\n return;\n }\n\n this.downloading = true;\n const response = await fetch(new Request(downloadData.url, { cache: 'no-store' }));\n if (response.status !== 200) {\n this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred'));\n this.downloading = false;\n return;\n }\n\n try {\n const buf = await response.arrayBuffer();\n const decBuf = await this.cryptoService.decryptFromBytes(buf, this.decKey);\n this.platformUtilsService.saveFile(window, decBuf, null, this.send.file.fileName);\n } catch (e) {\n this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred'));\n }\n\n this.downloading = false;\n }\n\n copyText() {\n this.platformUtilsService.copyToClipboard(this.send.text.text);\n this.platformUtilsService.showToast('success', null,\n this.i18nService.t('valueCopied', this.i18nService.t('sendTypeText')));\n }\n\n toggleText() {\n this.showText = !this.showText;\n }\n\n async load() {\n this.unavailable = false;\n this.error = false;\n this.hideEmail = false;\n const keyArray = Utils.fromUrlB64ToArray(this.key);\n this.accessRequest = new SendAccessRequest();\n if (this.password != null) {\n const passwordHash = await this.cryptoFunctionService.pbkdf2(this.password, keyArray, 'sha256', 100000);\n this.accessRequest.password = Utils.fromBufferToB64(passwordHash);\n }\n try {\n let sendResponse: SendAccessResponse = null;\n if (this.loading) {\n sendResponse = await this.apiService.postSendAccess(this.id, this.accessRequest);\n } else {\n this.formPromise = this.apiService.postSendAccess(this.id, this.accessRequest);\n sendResponse = await this.formPromise;\n }\n this.passwordRequired = false;\n const sendAccess = new SendAccess(sendResponse);\n this.decKey = await this.cryptoService.makeSendKey(keyArray);\n this.send = await sendAccess.decrypt(this.decKey);\n this.showText = this.send.text != null ? !this.send.text.hidden : true;\n } catch (e) {\n if (e instanceof ErrorResponse) {\n if (e.statusCode === 401) {\n this.passwordRequired = true;\n } else if (e.statusCode === 404) {\n this.unavailable = true;\n } else {\n this.error = true;\n }\n }\n }\n this.loading = false;\n this.hideEmail = this.creatorIdentifier == null && !this.passwordRequired && !this.loading && !this.unavailable;\n }\n}\n","

Bitwarden Send

{{'sendCreatorIdentifier' | i18n: creatorIdentifier }}

{{'viewSendHiddenEmailWarning' | i18n }} {{'learnMore' | i18n}}.
{{'loading' | i18n}}

{{'sendProtectedPassword' | i18n}}

{{'sendProtectedPasswordDontKnow' | i18n}}

{{'sendAccessUnavailable' | i18n}}
{{'unexpectedError' | i18n}}

{{send.name}}


{{'sendHiddenByDefault' | i18n}}

{{send.file.fileName}}

Expires: {{expirationDate | date: 'medium'}}

{{'sendAccessTaglineProductDesc' | i18n}}
{{'sendAccessTaglineLearnMore' | i18n}} Bitwarden Send {{'sendAccessTaglineOr' | i18n}} {{'sendAccessTaglineSignUp' | i18n}} {{'sendAccessTaglineTryToday' | i18n}}

","import { DatePipe } from '@angular/common';\n\nimport { Component } from '@angular/core';\n\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { SendService } from 'jslib-common/abstractions/send.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { AddEditComponent as BaseAddEditComponent } from 'jslib-angular/components/send/add-edit.component';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\n@Component({\n selector: 'app-send-add-edit',\n templateUrl: 'add-edit.component.html',\n})\nexport class AddEditComponent extends BaseAddEditComponent {\n constructor(i18nService: I18nService, platformUtilsService: PlatformUtilsService,\n environmentService: EnvironmentService, datePipe: DatePipe,\n sendService: SendService, userService: UserService,\n messagingService: MessagingService, policyService: PolicyService,\n logService: LogService) {\n super(i18nService, platformUtilsService, environmentService, datePipe, sendService, userService,\n messagingService, policyService, logService);\n }\n\n async copyLinkToClipboard(link: string): Promise {\n // Copy function on web depends on the modal being open or not. Since this event occurs during a transition\n // of the modal closing we need to add a small delay to make sure state of the DOM is consistent.\n return new Promise(resolve => {\n window.setTimeout(() => resolve(super.copyLinkToClipboard(link)), 500);\n });\n }\n}\n","

{{title}}

{{'sendDisabledWarning' | i18n}} {{'sendOptionsPolicyInEffect' | i18n}}
  • {{'sendDisableHideEmailInEffect' | i18n}}
{{'sendNameDesc' | i18n}}
{{'sendTextDesc' | i18n}}
{{'file' | i18n}} {{send.file.fileName}} ({{send.file.sizeName}})
{{'sendFileDesc' | i18n}} {{'maxFileSize' | i18n}}

{{'share' | i18n}}

{{'options' | i18n}}

{{'maxAccessCountDesc' | i18n}}
{{'sendPasswordDesc' | i18n}}
{{'sendNotesDesc' | i18n}}
","import { SendType } from '../../enums/sendType';\nimport { Utils } from '../../misc/utils';\n\nimport { Send } from '../domain/send';\nimport { SymmetricCryptoKey } from '../domain/symmetricCryptoKey';\n\nimport { SendFileView } from './sendFileView';\nimport { SendTextView } from './sendTextView';\nimport { View } from './view';\n\nexport class SendView implements View {\n id: string = null;\n accessId: string = null;\n name: string = null;\n notes: string = null;\n key: ArrayBuffer;\n cryptoKey: SymmetricCryptoKey;\n type: SendType = null;\n text = new SendTextView();\n file = new SendFileView();\n maxAccessCount?: number = null;\n accessCount: number = 0;\n revisionDate: Date = null;\n deletionDate: Date = null;\n expirationDate: Date = null;\n password: string = null;\n disabled: boolean = false;\n hideEmail: boolean = false;\n\n constructor(s?: Send) {\n if (!s) {\n return;\n }\n\n this.id = s.id;\n this.accessId = s.accessId;\n this.type = s.type;\n this.maxAccessCount = s.maxAccessCount;\n this.accessCount = s.accessCount;\n this.revisionDate = s.revisionDate;\n this.deletionDate = s.deletionDate;\n this.expirationDate = s.expirationDate;\n this.disabled = s.disabled;\n this.password = s.password;\n this.hideEmail = s.hideEmail;\n }\n\n get urlB64Key(): string {\n return Utils.fromBufferToUrlB64(this.key);\n }\n\n get maxAccessCountReached(): boolean {\n if (this.maxAccessCount == null) {\n return false;\n }\n return this.accessCount >= this.maxAccessCount;\n }\n\n get expired(): boolean {\n if (this.expirationDate == null) {\n return false;\n }\n return this.expirationDate <= new Date();\n }\n\n get pendingDelete(): boolean {\n return this.deletionDate <= new Date();\n }\n}\n","import { DatePipe } from '@angular/common';\n\nimport { Component } from '@angular/core';\n\nimport { ControlContainer, NgForm } from '@angular/forms';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { EffluxDatesComponent as BaseEffluxDatesComponent } from 'jslib-angular/components/send/efflux-dates.component';\n\n@Component({\n selector: 'app-send-efflux-dates',\n templateUrl: 'efflux-dates.component.html',\n viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],\n})\nexport class EffluxDatesComponent extends BaseEffluxDatesComponent {\n constructor(protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService,\n protected datePipe: DatePipe) {\n super(i18nService, platformUtilsService, datePipe);\n }\n}\n","
{{'deletionDateDesc' | i18n}}
{{'clear' | i18n}}
{{'expirationDateDesc' | i18n}}
","import {\n Component,\n NgZone,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\n\nimport { SendView } from 'jslib-common/models/view/sendView';\n\nimport { SendComponent as BaseSendComponent } from 'jslib-angular/components/send/send.component';\n\nimport { AddEditComponent } from './add-edit.component';\n\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { SearchService } from 'jslib-common/abstractions/search.service';\nimport { SendService } from 'jslib-common/abstractions/send.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { BroadcasterService } from 'jslib-angular/services/broadcaster.service';\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nconst BroadcasterSubscriptionId = 'SendComponent';\n\n@Component({\n selector: 'app-send',\n templateUrl: 'send.component.html',\n})\nexport class SendComponent extends BaseSendComponent {\n @ViewChild('sendAddEdit', { read: ViewContainerRef, static: true }) sendAddEditModalRef: ViewContainerRef;\n\n constructor(sendService: SendService, i18nService: I18nService,\n platformUtilsService: PlatformUtilsService, environmentService: EnvironmentService,\n ngZone: NgZone, searchService: SearchService, policyService: PolicyService, userService: UserService,\n private modalService: ModalService, private broadcasterService: BroadcasterService,\n logService: LogService) {\n super(sendService, i18nService, platformUtilsService, environmentService, ngZone, searchService,\n policyService, userService, logService);\n }\n\n async ngOnInit() {\n await super.ngOnInit();\n await this.load();\n\n // Broadcaster subscription - load if sync completes in the background\n this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {\n this.ngZone.run(async () => {\n switch (message.command) {\n case 'syncCompleted':\n if (message.successfully) {\n await this.load();\n }\n break;\n }\n });\n });\n }\n\n ngOnDestroy() {\n this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);\n }\n\n async addSend() {\n if (this.disableSend) {\n return;\n }\n\n const component = await this.editSend(null);\n component.type = this.type;\n }\n\n async editSend(send: SendView) {\n const [modal, childComponent] = await this.modalService.openViewRef(AddEditComponent, this.sendAddEditModalRef, comp => {\n comp.sendId = send == null ? null : send.id;\n comp.onSavedSend.subscribe(async (s: SendView) => {\n modal.close();\n await this.load();\n });\n comp.onDeletedSend.subscribe(async (s: SendView) => {\n modal.close();\n await this.load();\n });\n });\n\n return childComponent;\n }\n}\n","
{{'sendDisabledWarning' | i18n}}

{{'send' | i18n}} {{'loading' | i18n}}

{{s.name}} {{'disabled' | i18n}} {{'password' | i18n}} {{'maxAccessCountReached' | i18n}} {{'expired' | i18n}} {{'pendingDeletion' | i18n}}
{{s.deletionDate | date:'medium'}}
{{'loading' | i18n}}

{{'noSendsInList' | i18n}}

","import {\n Component,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\n\nimport { ApiKeyComponent } from './api-key.component';\nimport { DeauthorizeSessionsComponent } from './deauthorize-sessions.component';\nimport { DeleteAccountComponent } from './delete-account.component';\nimport { PurgeVaultComponent } from './purge-vault.component';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\n@Component({\n selector: 'app-account',\n templateUrl: 'account.component.html',\n})\nexport class AccountComponent {\n @ViewChild('deauthorizeSessionsTemplate', { read: ViewContainerRef, static: true }) deauthModalRef: ViewContainerRef;\n @ViewChild('purgeVaultTemplate', { read: ViewContainerRef, static: true }) purgeModalRef: ViewContainerRef;\n @ViewChild('deleteAccountTemplate', { read: ViewContainerRef, static: true }) deleteModalRef: ViewContainerRef;\n @ViewChild('viewUserApiKeyTemplate', { read: ViewContainerRef, static: true }) viewUserApiKeyModalRef: ViewContainerRef;\n @ViewChild('rotateUserApiKeyTemplate', { read: ViewContainerRef, static: true }) rotateUserApiKeyModalRef: ViewContainerRef;\n\n showChangePassword = true;\n showChangeKdf = true;\n showChangeEmail = true;\n\n constructor(private modalService: ModalService, private apiService: ApiService,\n private userService: UserService, private keyConnectorService: KeyConnectorService) { }\n\n async ngOnInit() {\n this.showChangeEmail = this.showChangeKdf = this.showChangePassword =\n !await this.keyConnectorService.getUsesKeyConnector();\n }\n\n async deauthorizeSessions() {\n await this.modalService.openViewRef(DeauthorizeSessionsComponent, this.deauthModalRef);\n }\n\n async purgeVault() {\n await this.modalService.openViewRef(PurgeVaultComponent, this.purgeModalRef);\n }\n\n async deleteAccount() {\n await this.modalService.openViewRef(DeleteAccountComponent, this.deleteModalRef);\n }\n\n async viewUserApiKey() {\n const entityId = await this.userService.getUserId();\n await this.modalService.openViewRef(ApiKeyComponent, this.viewUserApiKeyModalRef, comp => {\n comp.keyType = 'user';\n comp.entityId = entityId;\n comp.postKey = this.apiService.postUserApiKey.bind(this.apiService);\n comp.scope = 'api';\n comp.grantType = 'client_credentials';\n comp.apiKeyTitle = 'apiKey';\n comp.apiKeyWarning = 'userApiKeyWarning';\n comp.apiKeyDescription = 'userApiKeyDesc';\n });\n }\n\n async rotateUserApiKey() {\n const entityId = await this.userService.getUserId();\n await this.modalService.openViewRef(ApiKeyComponent, this.rotateUserApiKeyModalRef, comp => {\n comp.keyType = 'user';\n comp.isRotation = true;\n comp.entityId = entityId;\n comp.postKey = this.apiService.postUserRotateApiKey.bind(this.apiService);\n comp.scope = 'api';\n comp.grantType = 'client_credentials';\n comp.apiKeyTitle = 'apiKey';\n comp.apiKeyWarning = 'userApiKeyWarning';\n comp.apiKeyDescription = 'apiKeyRotateDesc';\n });\n }\n}\n","

{{'myAccount' | i18n}}

{{'changeEmail' | i18n}}

{{'changeMasterPassword' | i18n}}

{{'encKeySettings' | i18n}}

{{'apiKey' | i18n}}

{{'userApiKeyDesc' | i18n}}

{{'dangerZone' | i18n}}

{{'dangerZoneDesc' | i18n}}

","import { Component } from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { Verification } from 'jslib-common/types/verification';\n\n@Component({\n selector: 'app-deauthorize-sessions',\n templateUrl: 'deauthorize-sessions.component.html',\n})\nexport class DeauthorizeSessionsComponent {\n masterPassword: Verification;\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private userVerificationService: UserVerificationService,\n private messagingService: MessagingService, private logService: LogService) { }\n\n async submit() {\n try {\n this.formPromise = this.userVerificationService.buildRequest(this.masterPassword)\n .then(request => this.apiService.postSecurityStamp(request));\n await this.formPromise;\n this.toasterService.popAsync('success', this.i18nService.t('sessionsDeauthorized'),\n this.i18nService.t('logBackIn'));\n this.messagingService.send('logout');\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{'deauthorizeSessions' | i18n}}

{{'deauthorizeSessionsDesc' | i18n}}

{{'deauthorizeSessionsWarning' | i18n}}
","import { Component } from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { Verification } from 'jslib-common/types/verification';\n\n@Component({\n selector: 'app-delete-account',\n templateUrl: 'delete-account.component.html',\n})\nexport class DeleteAccountComponent {\n masterPassword: Verification;\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private userVerificationService: UserVerificationService,\n private messagingService: MessagingService, private logService: LogService) { }\n\n async submit() {\n try {\n this.formPromise = this.userVerificationService.buildRequest(this.masterPassword)\n .then(request => this.apiService.deleteAccount(request));\n await this.formPromise;\n this.toasterService.popAsync('success', this.i18nService.t('accountDeleted'),\n this.i18nService.t('accountDeletedDesc'));\n this.messagingService.send('logout');\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{'deleteAccount' | i18n}}

{{'deleteAccountDesc' | i18n}}

{{'deleteAccountWarning' | i18n}}
","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { UpdateProfileRequest } from 'jslib-common/models/request/updateProfileRequest';\n\nimport { ProfileResponse } from 'jslib-common/models/response/profileResponse';\n\n@Component({\n selector: 'app-profile',\n templateUrl: 'profile.component.html',\n})\nexport class ProfileComponent implements OnInit {\n loading = true;\n profile: ProfileResponse;\n fingerprint: string;\n hidePasswordHint = false;\n\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private userService: UserService,\n private cryptoService: CryptoService, private logService: LogService,\n private keyConnectorService: KeyConnectorService) { }\n\n async ngOnInit() {\n this.profile = await this.apiService.getProfile();\n this.loading = false;\n const fingerprint = await this.cryptoService.getFingerprint(await this.userService.getUserId());\n if (fingerprint != null) {\n this.fingerprint = fingerprint.join('-');\n }\n this.hidePasswordHint = await this.keyConnectorService.getUsesKeyConnector();\n }\n\n async submit() {\n try {\n const request = new UpdateProfileRequest(this.profile.name, this.profile.masterPasswordHint);\n this.formPromise = this.apiService.putProfile(request);\n await this.formPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('accountUpdated'));\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","
{{'loading' | i18n}}

{{'yourAccountsFingerprint' | i18n}}:
{{fingerprint}}

","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { EmailRequest } from 'jslib-common/models/request/emailRequest';\nimport { EmailTokenRequest } from 'jslib-common/models/request/emailTokenRequest';\n\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\n\n@Component({\n selector: 'app-change-email',\n templateUrl: 'change-email.component.html',\n})\nexport class ChangeEmailComponent implements OnInit {\n masterPassword: string;\n newEmail: string;\n token: string;\n tokenSent = false;\n showTwoFactorEmailWarning = false;\n\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private cryptoService: CryptoService,\n private messagingService: MessagingService, private userService: UserService,\n private logService: LogService) { }\n\n async ngOnInit() {\n const twoFactorProviders = await this.apiService.getTwoFactorProviders();\n this.showTwoFactorEmailWarning = twoFactorProviders.data.some(p => p.type === TwoFactorProviderType.Email &&\n p.enabled);\n }\n\n async submit() {\n const hasEncKey = await this.cryptoService.hasEncKey();\n if (!hasEncKey) {\n this.toasterService.popAsync('error', null, this.i18nService.t('updateKey'));\n return;\n }\n\n this.newEmail = this.newEmail.trim().toLowerCase();\n if (!this.tokenSent) {\n const request = new EmailTokenRequest();\n request.newEmail = this.newEmail;\n request.masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, null);\n try {\n this.formPromise = this.apiService.postEmailToken(request);\n await this.formPromise;\n this.tokenSent = true;\n } catch (e) {\n this.logService.error(e);\n }\n } else {\n const request = new EmailRequest();\n request.token = this.token;\n request.newEmail = this.newEmail;\n request.masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, null);\n const kdf = await this.userService.getKdf();\n const kdfIterations = await this.userService.getKdfIterations();\n const newKey = await this.cryptoService.makeKey(this.masterPassword, this.newEmail, kdf, kdfIterations);\n request.newMasterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, newKey);\n const newEncKey = await this.cryptoService.remakeEncKey(newKey);\n request.key = newEncKey[1].encryptedString;\n try {\n this.formPromise = this.apiService.postEmail(request);\n await this.formPromise;\n this.reset();\n this.toasterService.popAsync('success', this.i18nService.t('emailChanged'),\n this.i18nService.t('logBackIn'));\n this.messagingService.send('logout');\n } catch (e) {\n this.logService.error(e);\n }\n }\n }\n\n reset() {\n this.token = this.newEmail = this.masterPassword = null;\n this.tokenSent = false;\n }\n}\n","
{{'changeEmailTwoFactorWarning' | i18n}}

{{'changeEmailDesc' | i18n : newEmail}}

{{'loggedOutWarning' | i18n}}
","import { SecretVerificationRequest } from './secretVerificationRequest';\n\nexport class EmailTokenRequest extends SecretVerificationRequest {\n newEmail: string;\n masterPasswordHash: string;\n}\n","import { Component } from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { FolderService } from 'jslib-common/abstractions/folder.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { SendService } from 'jslib-common/abstractions/send.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport {\n ChangePasswordComponent as BaseChangePasswordComponent,\n} from 'jslib-angular/components/change-password.component';\n\nimport { EmergencyAccessStatusType } from 'jslib-common/enums/emergencyAccessStatusType';\nimport { Utils } from 'jslib-common/misc/utils';\n\nimport { EncString } from 'jslib-common/models/domain/encString';\nimport { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';\n\nimport { CipherWithIdRequest } from 'jslib-common/models/request/cipherWithIdRequest';\nimport { EmergencyAccessUpdateRequest } from 'jslib-common/models/request/emergencyAccessUpdateRequest';\nimport { FolderWithIdRequest } from 'jslib-common/models/request/folderWithIdRequest';\nimport { OrganizationUserResetPasswordEnrollmentRequest } from 'jslib-common/models/request/organizationUserResetPasswordEnrollmentRequest';\nimport { PasswordRequest } from 'jslib-common/models/request/passwordRequest';\nimport { SendWithIdRequest } from 'jslib-common/models/request/sendWithIdRequest';\nimport { UpdateKeyRequest } from 'jslib-common/models/request/updateKeyRequest';\n\n@Component({\n selector: 'app-change-password',\n templateUrl: 'change-password.component.html',\n})\nexport class ChangePasswordComponent extends BaseChangePasswordComponent {\n rotateEncKey = false;\n currentMasterPassword: string;\n\n constructor(i18nService: I18nService,\n cryptoService: CryptoService, messagingService: MessagingService,\n userService: UserService, passwordGenerationService: PasswordGenerationService,\n platformUtilsService: PlatformUtilsService, policyService: PolicyService,\n private folderService: FolderService, private cipherService: CipherService,\n private syncService: SyncService, private apiService: ApiService, private sendService: SendService) {\n super(i18nService, cryptoService, messagingService, userService, passwordGenerationService,\n platformUtilsService, policyService);\n }\n\n async rotateEncKeyClicked() {\n if (this.rotateEncKey) {\n const ciphers = await this.cipherService.getAllDecrypted();\n let hasOldAttachments = false;\n if (ciphers != null) {\n for (let i = 0; i < ciphers.length; i++) {\n if (ciphers[i].organizationId == null && ciphers[i].hasOldAttachments) {\n hasOldAttachments = true;\n break;\n }\n }\n }\n\n if (hasOldAttachments) {\n const learnMore = await this.platformUtilsService.showDialog(\n this.i18nService.t('oldAttachmentsNeedFixDesc'), null,\n this.i18nService.t('learnMore'), this.i18nService.t('close'), 'warning');\n if (learnMore) {\n this.platformUtilsService.launchUri(\n 'https://help.bitwarden.com/article/attachments/#fixing-old-attachments');\n }\n this.rotateEncKey = false;\n return;\n }\n\n const result = await this.platformUtilsService.showDialog(\n this.i18nService.t('updateEncryptionKeyWarning') + ' ' +\n this.i18nService.t('updateEncryptionKeyExportWarning') + ' ' +\n this.i18nService.t('rotateEncKeyConfirmation'), this.i18nService.t('rotateEncKeyTitle'),\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!result) {\n this.rotateEncKey = false;\n }\n }\n }\n\n async submit() {\n const hasEncKey = await this.cryptoService.hasEncKey();\n if (!hasEncKey) {\n this.platformUtilsService.showToast('error', null, this.i18nService.t('updateKey'));\n return;\n }\n\n await super.submit();\n }\n\n async setupSubmitActions() {\n if (this.currentMasterPassword == null || this.currentMasterPassword === '') {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPassRequired'));\n return false;\n }\n\n if (this.rotateEncKey) {\n await this.syncService.fullSync(true);\n }\n\n return super.setupSubmitActions();\n }\n\n async performSubmitActions(newMasterPasswordHash: string, newKey: SymmetricCryptoKey,\n newEncKey: [SymmetricCryptoKey, EncString]) {\n const request = new PasswordRequest();\n request.masterPasswordHash = await this.cryptoService.hashPassword(this.currentMasterPassword, null);\n request.newMasterPasswordHash = newMasterPasswordHash;\n request.key = newEncKey[1].encryptedString;\n\n try {\n if (this.rotateEncKey) {\n this.formPromise = this.apiService.postPassword(request).then(() => {\n return this.updateKey(newKey, request.newMasterPasswordHash);\n });\n } else {\n this.formPromise = this.apiService.postPassword(request);\n }\n\n await this.formPromise;\n\n this.platformUtilsService.showToast('success', this.i18nService.t('masterPasswordChanged'),\n this.i18nService.t('logBackIn'));\n this.messagingService.send('logout');\n } catch {\n this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred'));\n }\n }\n\n private async updateKey(key: SymmetricCryptoKey, masterPasswordHash: string) {\n const encKey = await this.cryptoService.makeEncKey(key);\n const privateKey = await this.cryptoService.getPrivateKey();\n let encPrivateKey: EncString = null;\n if (privateKey != null) {\n encPrivateKey = await this.cryptoService.encrypt(privateKey, encKey[0]);\n }\n const request = new UpdateKeyRequest();\n request.privateKey = encPrivateKey != null ? encPrivateKey.encryptedString : null;\n request.key = encKey[1].encryptedString;\n request.masterPasswordHash = masterPasswordHash;\n\n const folders = await this.folderService.getAllDecrypted();\n for (let i = 0; i < folders.length; i++) {\n if (folders[i].id == null) {\n continue;\n }\n const folder = await this.folderService.encrypt(folders[i], encKey[0]);\n request.folders.push(new FolderWithIdRequest(folder));\n }\n\n const ciphers = await this.cipherService.getAllDecrypted();\n for (let i = 0; i < ciphers.length; i++) {\n if (ciphers[i].organizationId != null) {\n continue;\n }\n\n const cipher = await this.cipherService.encrypt(ciphers[i], encKey[0]);\n request.ciphers.push(new CipherWithIdRequest(cipher));\n }\n\n const sends = await this.sendService.getAll();\n await Promise.all(sends.map(async send => {\n const cryptoKey = await this.cryptoService.decryptToBytes(send.key, null);\n send.key = await this.cryptoService.encrypt(cryptoKey, encKey[0]) ?? send.key;\n request.sends.push(new SendWithIdRequest(send));\n }));\n\n await this.apiService.postAccountKey(request);\n\n await this.updateEmergencyAccesses(encKey[0]);\n\n await this.updateAllResetPasswordKeys(encKey[0]);\n }\n\n private async updateEmergencyAccesses(encKey: SymmetricCryptoKey) {\n const emergencyAccess = await this.apiService.getEmergencyAccessTrusted();\n const allowedStatuses = [\n EmergencyAccessStatusType.Confirmed,\n EmergencyAccessStatusType.RecoveryInitiated,\n EmergencyAccessStatusType.RecoveryApproved,\n ];\n\n const filteredAccesses = emergencyAccess.data.filter(d => allowedStatuses.includes(d.status));\n\n for (const details of filteredAccesses) {\n const publicKeyResponse = await this.apiService.getUserPublicKey(details.granteeId);\n const publicKey = Utils.fromB64ToArray(publicKeyResponse.publicKey);\n\n const encryptedKey = await this.cryptoService.rsaEncrypt(encKey.key, publicKey.buffer);\n\n const updateRequest = new EmergencyAccessUpdateRequest();\n updateRequest.type = details.type;\n updateRequest.waitTimeDays = details.waitTimeDays;\n updateRequest.keyEncrypted = encryptedKey.encryptedString;\n\n await this.apiService.putEmergencyAccess(details.id, updateRequest);\n }\n }\n\n private async updateAllResetPasswordKeys(encKey: SymmetricCryptoKey) {\n const orgs = await this.userService.getAllOrganizations();\n\n for (const org of orgs) {\n // If not already enrolled, skip\n if (!org.resetPasswordEnrolled) {\n continue;\n }\n\n // Retrieve public key\n const response = await this.apiService.getOrganizationKeys(org.id);\n const publicKey = Utils.fromB64ToArray(response?.publicKey);\n\n // Re-enroll - encrpyt user's encKey.key with organization public key\n const encryptedKey = await this.cryptoService.rsaEncrypt(encKey.key, publicKey.buffer);\n\n // Create/Execute request\n const request = new OrganizationUserResetPasswordEnrollmentRequest();\n request.resetPasswordKey = encryptedKey.encryptedString;\n\n await this.apiService.putOrganizationUserResetPasswordEnrollment(org.id, org.userId, request);\n }\n }\n}\n","{{'loggedOutWarning' | i18n}}
","export enum EmergencyAccessStatusType {\n Invited = 0,\n Accepted = 1,\n Confirmed = 2,\n RecoveryInitiated = 3,\n RecoveryApproved = 4,\n}\n","import { EmergencyAccessType } from '../../enums/emergencyAccessType';\n\nexport class EmergencyAccessUpdateRequest {\n type: EmergencyAccessType;\n waitTimeDays: number;\n keyEncrypted?: string;\n}\n","import { FolderRequest } from './folderRequest';\n\nimport { Folder } from '../domain/folder';\n\nexport class FolderWithIdRequest extends FolderRequest {\n id: string;\n\n constructor(folder: Folder) {\n super(folder);\n this.id = folder.id;\n }\n}\n","import { SecretVerificationRequest } from './secretVerificationRequest';\n\nexport class PasswordRequest extends SecretVerificationRequest {\n newMasterPasswordHash: string;\n key: string;\n}\n","import { SendType } from '../../enums/sendType';\n\nimport { SendFileApi } from '../api/sendFileApi';\nimport { SendTextApi } from '../api/sendTextApi';\n\nimport { Send } from '../domain/send';\n\nexport class SendRequest {\n type: SendType;\n fileLength?: number;\n name: string;\n notes: string;\n key: string;\n maxAccessCount?: number;\n expirationDate: string;\n deletionDate: string;\n text: SendTextApi;\n file: SendFileApi;\n password: string;\n disabled: boolean;\n hideEmail: boolean;\n\n constructor(send: Send, fileLength?: number) {\n this.type = send.type;\n this.fileLength = fileLength;\n this.name = send.name ? send.name.encryptedString : null;\n this.notes = send.notes ? send.notes.encryptedString : null;\n this.maxAccessCount = send.maxAccessCount;\n this.expirationDate = send.expirationDate != null ? send.expirationDate.toISOString() : null;\n this.deletionDate = send.deletionDate != null ? send.deletionDate.toISOString() : null;\n this.key = send.key != null ? send.key.encryptedString : null;\n this.password = send.password;\n this.disabled = send.disabled;\n this.hideEmail = send.hideEmail;\n\n switch (this.type) {\n case SendType.Text:\n this.text = new SendTextApi();\n this.text.text = send.text.text != null ? send.text.text.encryptedString : null;\n this.text.hidden = send.text.hidden;\n break;\n case SendType.File:\n this.file = new SendFileApi();\n this.file.fileName = send.file.fileName != null ? send.file.fileName.encryptedString : null;\n break;\n default:\n break;\n }\n }\n}\n","import { CipherWithIdRequest } from './cipherWithIdRequest';\nimport { FolderWithIdRequest } from './folderWithIdRequest';\nimport { SendWithIdRequest } from './sendWithIdRequest';\n\nexport class UpdateKeyRequest {\n ciphers: CipherWithIdRequest[] = [];\n folders: FolderWithIdRequest[] = [];\n sends: SendWithIdRequest[] = [];\n masterPasswordHash: string;\n privateKey: string;\n key: string;\n}\n","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { KdfRequest } from 'jslib-common/models/request/kdfRequest';\n\nimport { KdfType } from 'jslib-common/enums/kdfType';\n\n@Component({\n selector: 'app-change-kdf',\n templateUrl: 'change-kdf.component.html',\n})\nexport class ChangeKdfComponent implements OnInit {\n masterPassword: string;\n kdfIterations: number;\n kdf = KdfType.PBKDF2_SHA256;\n kdfOptions: any[] = [];\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private cryptoService: CryptoService,\n private messagingService: MessagingService, private userService: UserService,\n private logService: LogService) {\n this.kdfOptions = [\n { name: 'PBKDF2 SHA-256', value: KdfType.PBKDF2_SHA256 },\n ];\n }\n\n async ngOnInit() {\n this.kdf = await this.userService.getKdf();\n this.kdfIterations = await this.userService.getKdfIterations();\n }\n\n async submit() {\n const hasEncKey = await this.cryptoService.hasEncKey();\n if (!hasEncKey) {\n this.toasterService.popAsync('error', null, this.i18nService.t('updateKey'));\n return;\n }\n\n const request = new KdfRequest();\n request.kdf = this.kdf;\n request.kdfIterations = this.kdfIterations;\n request.masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, null);\n const email = await this.userService.getEmail();\n const newKey = await this.cryptoService.makeKey(this.masterPassword, email, this.kdf, this.kdfIterations);\n request.newMasterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, newKey);\n const newEncKey = await this.cryptoService.remakeEncKey(newKey);\n request.key = newEncKey[1].encryptedString;\n try {\n this.formPromise = this.apiService.postAccountKdf(request);\n await this.formPromise;\n this.toasterService.popAsync('success', this.i18nService.t('encKeySettingsChanged'),\n this.i18nService.t('logBackIn'));\n this.messagingService.send('logout');\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","{{'loggedOutWarning' | i18n}}

{{'kdfIterationsDesc' | i18n : (100000 | number)}}

{{'warning' | i18n}}: {{'kdfIterationsWarning' | i18n : (50000 | number)}}
","import {\n Component,\n OnInit,\n ViewChild,\n} from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { first } from 'rxjs/operators';\n\nimport { PlanType } from 'jslib-common/enums/planType';\nimport { ProductType } from 'jslib-common/enums/productType';\n\nimport { OrganizationPlansComponent } from './organization-plans.component';\n\n@Component({\n selector: 'app-create-organization',\n templateUrl: 'create-organization.component.html',\n})\nexport class CreateOrganizationComponent implements OnInit {\n @ViewChild(OrganizationPlansComponent, { static: true }) orgPlansComponent: OrganizationPlansComponent;\n\n constructor(private route: ActivatedRoute) { }\n\n ngOnInit() {\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n if (qParams.plan === 'families') {\n this.orgPlansComponent.plan = PlanType.FamiliesAnnually;\n this.orgPlansComponent.product = ProductType.Families;\n } else if (qParams.plan === 'teams') {\n this.orgPlansComponent.plan = PlanType.TeamsAnnually;\n this.orgPlansComponent.product = ProductType.Teams;\n } else if (qParams.plan === 'enterprise') {\n this.orgPlansComponent.plan = PlanType.EnterpriseAnnually;\n this.orgPlansComponent.product = ProductType.Enterprise;\n }\n });\n }\n}\n","

{{'newOrganization' | i18n}}

{{'newOrganizationDesc' | i18n}}

","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\nimport { UpdateDomainsRequest } from 'jslib-common/models/request/updateDomainsRequest';\n\n@Component({\n selector: 'app-domain-rules',\n templateUrl: 'domain-rules.component.html',\n})\nexport class DomainRulesComponent implements OnInit {\n loading = true;\n custom: string[] = [];\n global: any[] = [];\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private logService: LogService) { }\n\n async ngOnInit() {\n const response = await this.apiService.getSettingsDomains();\n this.loading = false;\n if (response.equivalentDomains != null) {\n this.custom = response.equivalentDomains.map(d => d.join(', '));\n }\n if (response.globalEquivalentDomains != null) {\n this.global = response.globalEquivalentDomains.map(d => {\n return {\n domains: d.domains.join(', '),\n excluded: d.excluded,\n key: d.type,\n };\n });\n }\n }\n\n toggleExcluded(globalDomain: any) {\n globalDomain.excluded = !globalDomain.excluded;\n }\n\n customize(globalDomain: any) {\n globalDomain.excluded = true;\n this.custom.push(globalDomain.domains);\n }\n\n remove(index: number) {\n this.custom.splice(index, 1);\n }\n\n add() {\n this.custom.push('');\n }\n\n async submit() {\n const request = new UpdateDomainsRequest();\n request.excludedGlobalEquivalentDomains = this.global.filter(d => d.excluded)\n .map(d => d.key);\n if (request.excludedGlobalEquivalentDomains.length === 0) {\n request.excludedGlobalEquivalentDomains = null;\n }\n request.equivalentDomains = this.custom.filter(d => d != null && d.trim() !== '')\n .map(d => d.split(',').map(d2 => d2.trim()));\n if (request.equivalentDomains.length === 0) {\n request.equivalentDomains = null;\n }\n\n try {\n this.formPromise = this.apiService.putSettingsDomains(request);\n await this.formPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('domainsUpdated'));\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n indexTrackBy(index: number, obj: any): any {\n return index;\n }\n}\n","

{{'domainRules' | i18n}}

{{'domainRulesDesc' | i18n}}

{{'customEqDomains' | i18n}}

{{'loading' | i18n}}

{{'newCustomDomainDesc' | i18n}}

{{'globalEqDomains' | i18n}}

{{'loading' | i18n}}

0\">
{{d.domains}}
","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\nimport { EmergencyAccessType } from 'jslib-common/enums/emergencyAccessType';\nimport { EmergencyAccessInviteRequest } from 'jslib-common/models/request/emergencyAccessInviteRequest';\nimport { EmergencyAccessUpdateRequest } from 'jslib-common/models/request/emergencyAccessUpdateRequest';\n\n@Component({\n selector: 'emergency-access-add-edit',\n templateUrl: 'emergency-access-add-edit.component.html',\n})\nexport class EmergencyAccessAddEditComponent implements OnInit {\n @Input() name: string;\n @Input() emergencyAccessId: string;\n @Output() onSaved = new EventEmitter();\n @Output() onDeleted = new EventEmitter();\n\n loading = true;\n readOnly: boolean = false;\n editMode: boolean = false;\n title: string;\n email: string;\n type: EmergencyAccessType = EmergencyAccessType.View;\n\n formPromise: Promise;\n\n emergencyAccessType = EmergencyAccessType;\n waitTimes: { name: string; value: number; }[];\n waitTime: number;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private logService: LogService) { }\n\n async ngOnInit() {\n this.editMode = this.loading = this.emergencyAccessId != null;\n\n this.waitTimes = [\n { name: this.i18nService.t('oneDay'), value: 1 },\n { name: this.i18nService.t('days', '2'), value: 2 },\n { name: this.i18nService.t('days', '7'), value: 7 },\n { name: this.i18nService.t('days', '14'), value: 14 },\n { name: this.i18nService.t('days', '30'), value: 30 },\n { name: this.i18nService.t('days', '90'), value: 90 },\n ];\n\n if (this.editMode) {\n this.editMode = true;\n this.title = this.i18nService.t('editEmergencyContact');\n try {\n const emergencyAccess = await this.apiService.getEmergencyAccess(this.emergencyAccessId);\n this.type = emergencyAccess.type;\n this.waitTime = emergencyAccess.waitTimeDays;\n } catch (e) {\n this.logService.error(e);\n }\n } else {\n this.title = this.i18nService.t('inviteEmergencyContact');\n this.waitTime = this.waitTimes[2].value;\n }\n\n this.loading = false;\n }\n\n async submit() {\n try {\n if (this.editMode) {\n const request = new EmergencyAccessUpdateRequest();\n request.type = this.type;\n request.waitTimeDays = this.waitTime;\n\n this.formPromise = this.apiService.putEmergencyAccess(this.emergencyAccessId, request);\n } else {\n const request = new EmergencyAccessInviteRequest();\n request.email = this.email.trim();\n request.type = this.type;\n request.waitTimeDays = this.waitTime;\n\n this.formPromise = this.apiService.postEmergencyAccessInvite(request);\n }\n\n await this.formPromise;\n this.toasterService.popAsync('success', null,\n this.i18nService.t(this.editMode ? 'editedUserId' : 'invitedUsers', this.name));\n this.onSaved.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async delete() {\n this.onDeleted.emit();\n }\n}\n","

{{'premium' | i18n}} {{title}} {{name}}

{{'loading' | i18n}}

{{'inviteEmergencyContactDesc' | i18n}}

{{'userAccess' | i18n}}

{{'waitTimeDesc' | i18n}}
","export enum EmergencyAccessType\n{\n View = 0,\n Takeover = 1,\n}\n","import { Component } from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { AttachmentView } from 'jslib-common/models/view/attachmentView';\n\nimport { AttachmentsComponent as BaseAttachmentsComponent } from 'jslib-angular/components/attachments.component';\n\n@Component({\n selector: 'emergency-access-attachments',\n templateUrl: '../vault/attachments.component.html',\n})\nexport class EmergencyAccessAttachmentsComponent extends BaseAttachmentsComponent {\n viewOnly = true;\n canAccessAttachments = true;\n\n constructor(cipherService: CipherService, i18nService: I18nService,\n cryptoService: CryptoService, userService: UserService,\n platformUtilsService: PlatformUtilsService, apiService: ApiService,\n logService: LogService) {\n super(cipherService, i18nService, cryptoService, userService, platformUtilsService, apiService, window,\n logService);\n }\n\n protected async init() {\n // Do nothing since cipher is already decoded\n }\n\n protected showFixOldAttachments(attachment: AttachmentView) {\n return false;\n }\n}\n","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\n@Component({\n selector: 'emergency-access-confirm',\n templateUrl: 'emergency-access-confirm.component.html',\n})\nexport class EmergencyAccessConfirmComponent implements OnInit {\n @Input() name: string;\n @Input() userId: string;\n @Input() emergencyAccessId: string;\n @Input() formPromise: Promise;\n @Output() onConfirmed = new EventEmitter();\n\n dontAskAgain = false;\n loading = true;\n fingerprint: string;\n\n constructor(private apiService: ApiService, private cryptoService: CryptoService,\n private storageService: StorageService, private logService: LogService) { }\n\n async ngOnInit() {\n try {\n const publicKeyResponse = await this.apiService.getUserPublicKey(this.userId);\n if (publicKeyResponse != null) {\n const publicKey = Utils.fromB64ToArray(publicKeyResponse.publicKey);\n const fingerprint = await this.cryptoService.getFingerprint(this.userId, publicKey.buffer);\n if (fingerprint != null) {\n this.fingerprint = fingerprint.join('-');\n }\n }\n } catch (e) {\n this.logService.error(e);\n }\n this.loading = false;\n }\n\n async submit() {\n if (this.loading) {\n return;\n }\n\n if (this.dontAskAgain) {\n await this.storageService.save(ConstantsService.autoConfirmFingerprints, true);\n }\n\n try {\n this.onConfirmed.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{'confirmUser' | i18n}} {{name}}

{{'fingerprintEnsureIntegrityVerify' | i18n}} {{'learnMore' | i18n}}

{{fingerprint}}

","import {\n Component,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { KdfType } from 'jslib-common/enums/kdfType';\nimport { PolicyData } from 'jslib-common/models/data/policyData';\nimport { Policy } from 'jslib-common/models/domain/policy';\nimport { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';\nimport { EmergencyAccessPasswordRequest } from 'jslib-common/models/request/emergencyAccessPasswordRequest';\nimport { PolicyResponse } from 'jslib-common/models/response/policyResponse';\n\nimport { ChangePasswordComponent } from 'jslib-angular/components/change-password.component';\n\n@Component({\n selector: 'emergency-access-takeover',\n templateUrl: 'emergency-access-takeover.component.html',\n})\nexport class EmergencyAccessTakeoverComponent extends ChangePasswordComponent implements OnInit {\n @Output() onDone = new EventEmitter();\n @Input() emergencyAccessId: string;\n @Input() name: string;\n @Input() email: string;\n @Input() kdf: KdfType;\n @Input() kdfIterations: number;\n\n formPromise: Promise;\n\n constructor(i18nService: I18nService, cryptoService: CryptoService,\n messagingService: MessagingService, userService: UserService,\n passwordGenerationService: PasswordGenerationService,\n platformUtilsService: PlatformUtilsService, policyService: PolicyService,\n private apiService: ApiService, private toasterService: ToasterService, private logService: LogService) {\n super(i18nService, cryptoService, messagingService, userService, passwordGenerationService,\n platformUtilsService, policyService);\n }\n\n async ngOnInit() {\n const response = await this.apiService.getEmergencyGrantorPolicies(this.emergencyAccessId);\n if (response.data != null && response.data.length > 0) {\n const policies = response.data.map((policyResponse: PolicyResponse) => new Policy(new PolicyData(policyResponse)));\n this.enforcedPolicyOptions = await this.policyService.getMasterPasswordPolicyOptions(policies);\n }\n }\n\n async submit() {\n if (!await this.strongPassword()) {\n return;\n }\n\n const takeoverResponse = await this.apiService.postEmergencyAccessTakeover(this.emergencyAccessId);\n\n const oldKeyBuffer = await this.cryptoService.rsaDecrypt(takeoverResponse.keyEncrypted);\n const oldEncKey = new SymmetricCryptoKey(oldKeyBuffer);\n\n if (oldEncKey == null) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), this.i18nService.t('unexpectedError'));\n return;\n }\n\n const key = await this.cryptoService.makeKey(this.masterPassword, this.email, takeoverResponse.kdf, takeoverResponse.kdfIterations);\n const masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, key);\n\n const encKey = await this.cryptoService.remakeEncKey(key, oldEncKey);\n\n const request = new EmergencyAccessPasswordRequest();\n request.newMasterPasswordHash = masterPasswordHash;\n request.key = encKey[1].encryptedString;\n\n this.apiService.postEmergencyAccessPassword(this.emergencyAccessId, request);\n\n try {\n this.onDone.emit();\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","

{{'takeover' | i18n}} {{name}}

{{'loggedOutWarning' | i18n}}
","import {\n Component,\n OnInit,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { CipherData } from 'jslib-common/models/data/cipherData';\nimport { Cipher } from 'jslib-common/models/domain/cipher';\nimport { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';\nimport { EmergencyAccessViewResponse } from 'jslib-common/models/response/emergencyAccessResponse';\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\nimport { EmergencyAccessAttachmentsComponent } from './emergency-access-attachments.component';\nimport { EmergencyAddEditComponent } from './emergency-add-edit.component';\n\n@Component({\n selector: 'emergency-access-view',\n templateUrl: 'emergency-access-view.component.html',\n})\nexport class EmergencyAccessViewComponent implements OnInit {\n @ViewChild('cipherAddEdit', { read: ViewContainerRef, static: true }) cipherAddEditModalRef: ViewContainerRef;\n @ViewChild('attachments', { read: ViewContainerRef, static: true }) attachmentsModalRef: ViewContainerRef;\n\n id: string;\n ciphers: CipherView[] = [];\n loaded = false;\n\n constructor(private cipherService: CipherService, private cryptoService: CryptoService,\n private modalService: ModalService, private router: Router,\n private route: ActivatedRoute, private apiService: ApiService) { }\n\n ngOnInit() {\n this.route.params.subscribe(qParams => {\n if (qParams.id == null) {\n return this.router.navigate(['settings/emergency-access']);\n }\n\n this.id = qParams.id;\n\n this.load();\n });\n }\n\n async selectCipher(cipher: CipherView) {\n const [_, childComponent] = await this.modalService.openViewRef(EmergencyAddEditComponent, this.cipherAddEditModalRef, comp => {\n comp.cipherId = cipher == null ? null : cipher.id;\n comp.cipher = cipher;\n });\n\n return childComponent;\n }\n\n async load() {\n const response = await this.apiService.postEmergencyAccessView(this.id);\n this.ciphers = await this.getAllCiphers(response);\n this.loaded = true;\n }\n\n async viewAttachments(cipher: CipherView) {\n await this.modalService.openViewRef(EmergencyAccessAttachmentsComponent, this.attachmentsModalRef, comp => {\n comp.cipher = cipher;\n comp.emergencyAccessId = this.id;\n });\n }\n\n protected async getAllCiphers(response: EmergencyAccessViewResponse): Promise {\n const ciphers = response.ciphers;\n\n const decCiphers: CipherView[] = [];\n const oldKeyBuffer = await this.cryptoService.rsaDecrypt(response.keyEncrypted);\n const oldEncKey = new SymmetricCryptoKey(oldKeyBuffer);\n\n const promises: any[] = [];\n ciphers.forEach(cipherResponse => {\n const cipherData = new CipherData(cipherResponse);\n const cipher = new Cipher(cipherData);\n promises.push(cipher.decrypt(oldEncKey).then(c => decCiphers.push(c)));\n });\n\n await Promise.all(promises);\n decCiphers.sort(this.cipherService.getLocaleSortingFunction());\n\n return decCiphers;\n }\n}\n","

{{'vault' | i18n}}

{{c.name}} {{'shared' | i18n}} {{'attachments' | i18n}}
{{c.subTitle}}
{{'loading' | i18n}}
","import { Component } from '@angular/core';\n\nimport { AuditService } from 'jslib-common/abstractions/audit.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { EventService } from 'jslib-common/abstractions/event.service';\nimport { FolderService } from 'jslib-common/abstractions/folder.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { TotpService } from 'jslib-common/abstractions/totp.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Cipher } from 'jslib-common/models/domain/cipher';\n\nimport { AddEditComponent as BaseAddEditComponent } from '../vault/add-edit.component';\n\n@Component({\n selector: 'app-org-vault-add-edit',\n templateUrl: '../vault/add-edit.component.html',\n})\nexport class EmergencyAddEditComponent extends BaseAddEditComponent {\n originalCipher: Cipher = null;\n viewOnly = true;\n\n constructor(cipherService: CipherService, folderService: FolderService,\n i18nService: I18nService, platformUtilsService: PlatformUtilsService,\n auditService: AuditService, stateService: StateService,\n userService: UserService, collectionService: CollectionService,\n totpService: TotpService, passwordGenerationService: PasswordGenerationService,\n messagingService: MessagingService, eventService: EventService, policyService: PolicyService,\n logService: LogService, passwordRepromptService: PasswordRepromptService) {\n super(cipherService, folderService, i18nService, platformUtilsService, auditService, stateService,\n userService, collectionService, totpService, passwordGenerationService, messagingService,\n eventService, policyService, passwordRepromptService, logService);\n }\n\n async load() {\n this.title = this.i18nService.t('viewItem');\n }\n\n protected async loadCipher() {\n return Promise.resolve(this.originalCipher);\n }\n}\n","import {\n Component,\n OnInit,\n ViewChild,\n ViewContainerRef\n} from '@angular/core';\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { EmergencyAccessStatusType } from 'jslib-common/enums/emergencyAccessStatusType';\nimport { EmergencyAccessType } from 'jslib-common/enums/emergencyAccessType';\nimport { Utils } from 'jslib-common/misc/utils';\nimport { EmergencyAccessConfirmRequest } from 'jslib-common/models/request/emergencyAccessConfirmRequest';\nimport { EmergencyAccessGranteeDetailsResponse, EmergencyAccessGrantorDetailsResponse } from 'jslib-common/models/response/emergencyAccessResponse';\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\nimport { UserNamePipe } from 'jslib-angular/pipes/user-name.pipe';\n\nimport { EmergencyAccessAddEditComponent } from './emergency-access-add-edit.component';\nimport { EmergencyAccessConfirmComponent } from './emergency-access-confirm.component';\nimport { EmergencyAccessTakeoverComponent } from './emergency-access-takeover.component';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\n@Component({\n selector: 'emergency-access',\n templateUrl: 'emergency-access.component.html',\n})\nexport class EmergencyAccessComponent implements OnInit {\n @ViewChild('addEdit', { read: ViewContainerRef, static: true }) addEditModalRef: ViewContainerRef;\n @ViewChild('takeoverTemplate', { read: ViewContainerRef, static: true}) takeoverModalRef: ViewContainerRef;\n @ViewChild('confirmTemplate', { read: ViewContainerRef, static: true }) confirmModalRef: ViewContainerRef;\n\n canAccessPremium: boolean;\n trustedContacts: EmergencyAccessGranteeDetailsResponse[];\n grantedContacts: EmergencyAccessGrantorDetailsResponse[];\n emergencyAccessType = EmergencyAccessType;\n emergencyAccessStatusType = EmergencyAccessStatusType;\n actionPromise: Promise;\n isOrganizationOwner: boolean;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private modalService: ModalService, private platformUtilsService: PlatformUtilsService,\n private toasterService: ToasterService, private cryptoService: CryptoService,\n private storageService: StorageService, private userService: UserService,\n private messagingService: MessagingService, private userNamePipe: UserNamePipe,\n private logService: LogService) { }\n\n async ngOnInit() {\n this.canAccessPremium = await this.userService.canAccessPremium();\n const orgs = await this.userService.getAllOrganizations();\n this.isOrganizationOwner = orgs.some(o => o.isOwner);\n this.load();\n }\n\n async load() {\n this.trustedContacts = (await this.apiService.getEmergencyAccessTrusted()).data;\n this.grantedContacts = (await this.apiService.getEmergencyAccessGranted()).data;\n }\n\n async premiumRequired() {\n if (!this.canAccessPremium) {\n this.messagingService.send('premiumRequired');\n return;\n }\n }\n\n async edit(details: EmergencyAccessGranteeDetailsResponse) {\n const [modal] = await this.modalService.openViewRef(EmergencyAccessAddEditComponent, this.addEditModalRef, comp => {\n comp.name = this.userNamePipe.transform(details);\n comp.emergencyAccessId = details?.id;\n comp.readOnly = !this.canAccessPremium;\n comp.onSaved.subscribe(() => {\n modal.close();\n this.load();\n });\n comp.onDeleted.subscribe(() => {\n modal.close();\n this.remove(details);\n });\n });\n }\n\n invite() {\n this.edit(null);\n }\n\n async reinvite(contact: EmergencyAccessGranteeDetailsResponse) {\n if (this.actionPromise != null) {\n return;\n }\n this.actionPromise = this.apiService.postEmergencyAccessReinvite(contact.id);\n await this.actionPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('hasBeenReinvited', contact.email));\n this.actionPromise = null;\n }\n\n async confirm(contact: EmergencyAccessGranteeDetailsResponse) {\n function updateUser() {\n contact.status = EmergencyAccessStatusType.Confirmed;\n }\n\n if (this.actionPromise != null) {\n return;\n }\n\n const autoConfirm = await this.storageService.get(ConstantsService.autoConfirmFingerprints);\n if (autoConfirm == null || !autoConfirm) {\n const [modal] = await this.modalService.openViewRef(EmergencyAccessConfirmComponent, this.confirmModalRef, comp => {\n comp.name = this.userNamePipe.transform(contact);\n comp.emergencyAccessId = contact.id;\n comp.userId = contact?.granteeId;\n comp.onConfirmed.subscribe(async () => {\n modal.close();\n\n comp.formPromise = this.doConfirmation(contact);\n await comp.formPromise;\n\n updateUser();\n this.toasterService.popAsync('success', null, this.i18nService.t('hasBeenConfirmed', this.userNamePipe.transform(contact)));\n });\n });\n return;\n }\n\n this.actionPromise = this.doConfirmation(contact);\n await this.actionPromise;\n updateUser();\n\n this.toasterService.popAsync('success', null, this.i18nService.t('hasBeenConfirmed', this.userNamePipe.transform(contact)));\n this.actionPromise = null;\n }\n\n async remove(details: EmergencyAccessGranteeDetailsResponse | EmergencyAccessGrantorDetailsResponse) {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('removeUserConfirmation'), this.userNamePipe.transform(details),\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n await this.apiService.deleteEmergencyAccess(details.id);\n this.toasterService.popAsync('success', null, this.i18nService.t('removedUserId', this.userNamePipe.transform(details)));\n\n if (details instanceof EmergencyAccessGranteeDetailsResponse) {\n this.removeGrantee(details);\n } else {\n this.removeGrantor(details);\n }\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async requestAccess(details: EmergencyAccessGrantorDetailsResponse) {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('requestAccessConfirmation', details.waitTimeDays.toString()),\n this.userNamePipe.transform(details),\n this.i18nService.t('requestAccess'),\n this.i18nService.t('no'),\n 'warning',\n );\n\n if (!confirmed) {\n return false;\n }\n\n await this.apiService.postEmergencyAccessInitiate(details.id);\n\n details.status = EmergencyAccessStatusType.RecoveryInitiated;\n this.toasterService.popAsync('success', null, this.i18nService.t('requestSent', this.userNamePipe.transform(details)));\n }\n\n async approve(details: EmergencyAccessGranteeDetailsResponse) {\n const type = this.i18nService.t(details.type === EmergencyAccessType.View ? 'view' : 'takeover');\n\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('approveAccessConfirmation', this.userNamePipe.transform(details), type),\n this.userNamePipe.transform(details),\n this.i18nService.t('approve'),\n this.i18nService.t('no'),\n 'warning',\n );\n\n if (!confirmed) {\n return false;\n }\n\n await this.apiService.postEmergencyAccessApprove(details.id);\n details.status = EmergencyAccessStatusType.RecoveryApproved;\n\n this.toasterService.popAsync('success', null, this.i18nService.t('emergencyApproved', this.userNamePipe.transform(details)));\n }\n\n async reject(details: EmergencyAccessGranteeDetailsResponse) {\n await this.apiService.postEmergencyAccessReject(details.id);\n details.status = EmergencyAccessStatusType.Confirmed;\n\n this.toasterService.popAsync('success', null, this.i18nService.t('emergencyRejected', this.userNamePipe.transform(details)));\n }\n\n async takeover(details: EmergencyAccessGrantorDetailsResponse) {\n const [modal] = await this.modalService.openViewRef(EmergencyAccessTakeoverComponent, this.takeoverModalRef, comp => {\n comp.name = this.userNamePipe.transform(details);\n comp.email = details.email;\n comp.emergencyAccessId = details != null ? details.id : null;\n\n comp.onDone.subscribe(() => {\n modal.close();\n this.toasterService.popAsync('success', null, this.i18nService.t('passwordResetFor', this.userNamePipe.transform(details)));\n });\n });\n }\n\n private removeGrantee(details: EmergencyAccessGranteeDetailsResponse) {\n const index = this.trustedContacts.indexOf(details);\n if (index > -1) {\n this.trustedContacts.splice(index, 1);\n }\n }\n\n private removeGrantor(details: EmergencyAccessGrantorDetailsResponse) {\n const index = this.grantedContacts.indexOf(details);\n if (index > -1) {\n this.grantedContacts.splice(index, 1);\n }\n }\n\n // Encrypt the master password hash using the grantees public key, and send it to bitwarden for escrow.\n private async doConfirmation(details: EmergencyAccessGranteeDetailsResponse) {\n const encKey = await this.cryptoService.getEncKey();\n const publicKeyResponse = await this.apiService.getUserPublicKey(details.granteeId);\n const publicKey = Utils.fromB64ToArray(publicKeyResponse.publicKey);\n\n try {\n this.logService.debug('User\\'s fingerprint: ' +\n (await this.cryptoService.getFingerprint(details.granteeId, publicKey.buffer)).join('-'));\n } catch {\n // Ignore errors since it's just a debug message\n }\n\n const encryptedKey = await this.cryptoService.rsaEncrypt(encKey.key, publicKey.buffer);\n const request = new EmergencyAccessConfirmRequest();\n request.key = encryptedKey.encryptedString;\n await this.apiService.postEmergencyAccessConfirm(details.id, request);\n }\n}\n","

{{'emergencyAccess' | i18n}}

{{'emergencyAccessDesc' | i18n}} {{'learnMore' | i18n}}.

{{'warning' | i18n }}: {{'emergencyAccessOwnerWarning' | i18n}}

{{'trustedEmergencyContacts' | i18n}} {{'premium' | i18n}}

{{c.email}} {{'invited' | i18n}} {{'accepted' | i18n}} {{'emergencyAccessRecoveryInitiated' | i18n}} {{'emergencyAccessRecoveryApproved' | i18n}} {{'view' | i18n}} {{'takeover' | i18n}} {{c.name}}

{{'noTrustedContacts' | i18n}}

{{'designatedEmergencyContacts' | i18n}}

{{c.email}} {{'invited' | i18n}} {{'accepted' | i18n}} {{'emergencyAccessRecoveryInitiated' | i18n}} {{'emergencyAccessRecoveryApproved' | i18n}} {{'view' | i18n}} {{'takeover' | i18n}} {{c.name}}

{{'noGrantedAccess' | i18n}}

","import { EmergencyAccessStatusType } from '../../enums/emergencyAccessStatusType';\nimport { EmergencyAccessType } from '../../enums/emergencyAccessType';\nimport { KdfType } from '../../enums/kdfType';\nimport { BaseResponse } from './baseResponse';\nimport { CipherResponse } from './cipherResponse';\n\nexport class EmergencyAccessGranteeDetailsResponse extends BaseResponse {\n id: string;\n granteeId: string;\n name: string;\n email: string;\n type: EmergencyAccessType;\n status: EmergencyAccessStatusType;\n waitTimeDays: number;\n creationDate: string;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.granteeId = this.getResponseProperty('GranteeId');\n this.name = this.getResponseProperty('Name');\n this.email = this.getResponseProperty('Email');\n this.type = this.getResponseProperty('Type');\n this.status = this.getResponseProperty('Status');\n this.waitTimeDays = this.getResponseProperty('WaitTimeDays');\n this.creationDate = this.getResponseProperty('CreationDate');\n }\n}\n\nexport class EmergencyAccessGrantorDetailsResponse extends BaseResponse {\n id: string;\n grantorId: string;\n name: string;\n email: string;\n type: EmergencyAccessType;\n status: EmergencyAccessStatusType;\n waitTimeDays: number;\n creationDate: string;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.grantorId = this.getResponseProperty('GrantorId');\n this.name = this.getResponseProperty('Name');\n this.email = this.getResponseProperty('Email');\n this.type = this.getResponseProperty('Type');\n this.status = this.getResponseProperty('Status');\n this.waitTimeDays = this.getResponseProperty('WaitTimeDays');\n this.creationDate = this.getResponseProperty('CreationDate');\n }\n}\n\nexport class EmergencyAccessTakeoverResponse extends BaseResponse {\n keyEncrypted: string;\n kdf: KdfType;\n kdfIterations: number;\n\n constructor(response: any) {\n super(response);\n\n this.keyEncrypted = this.getResponseProperty('KeyEncrypted');\n this.kdf = this.getResponseProperty('Kdf');\n this.kdfIterations = this.getResponseProperty('KdfIterations');\n }\n}\n\nexport class EmergencyAccessViewResponse extends BaseResponse {\n keyEncrypted: string;\n ciphers: CipherResponse[] = [];\n\n constructor(response: any) {\n super(response);\n\n this.keyEncrypted = this.getResponseProperty('KeyEncrypted');\n\n const ciphers = this.getResponseProperty('Ciphers');\n if (ciphers != null) {\n this.ciphers = ciphers.map((c: any) => new CipherResponse(c));\n }\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class AttachmentResponse extends BaseResponse {\n id: string;\n url: string;\n fileName: string;\n key: string;\n size: string;\n sizeName: string;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.url = this.getResponseProperty('Url');\n this.fileName = this.getResponseProperty('FileName');\n this.key = this.getResponseProperty('Key');\n this.size = this.getResponseProperty('Size');\n this.sizeName = this.getResponseProperty('SizeName');\n }\n}\n","import {\n AfterContentInit,\n Component,\n Input,\n} from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { AuthService } from 'jslib-common/abstractions/auth.service';\nimport { CryptoFunctionService } from 'jslib-common/abstractions/cryptoFunction.service';\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\n\nimport { SsoComponent } from 'jslib-angular/components/sso.component';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\n\n@Component({\n selector: 'app-link-sso',\n templateUrl: 'link-sso.component.html',\n})\nexport class LinkSsoComponent extends SsoComponent implements AfterContentInit {\n @Input() organization: Organization;\n returnUri: string = '/settings/organizations';\n\n constructor(platformUtilsService: PlatformUtilsService, i18nService: I18nService,\n apiService: ApiService, authService: AuthService,\n router: Router, route: ActivatedRoute,\n cryptoFunctionService: CryptoFunctionService, passwordGenerationService: PasswordGenerationService,\n storageService: StorageService, stateService: StateService, environmentService: EnvironmentService,\n logService: LogService) {\n super(authService, router,\n i18nService, route,\n storageService, stateService,\n platformUtilsService, apiService,\n cryptoFunctionService, environmentService, passwordGenerationService, logService);\n\n this.returnUri = '/settings/organizations';\n this.redirectUri = window.location.origin + '/sso-connector.html';\n this.clientId = 'web';\n }\n\n async ngAfterContentInit() {\n this.identifier = this.organization.identifier;\n }\n}\n"," {{'linkSso' | i18n}} ","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport { FormControl } from '@angular/forms';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\nimport { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';\n\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\nimport { ThemeType } from 'jslib-common/enums/themeType';\nimport { Utils } from 'jslib-common/misc/utils';\n\n@Component({\n selector: 'app-options',\n templateUrl: 'options.component.html',\n})\nexport class OptionsComponent implements OnInit {\n vaultTimeoutAction: string = 'lock';\n disableIcons: boolean;\n enableGravatars: boolean;\n enableFullWidth: boolean;\n theme: string = null;\n locale: string;\n vaultTimeouts: { name: string; value: number; }[];\n localeOptions: any[];\n themeOptions: any[];\n\n vaultTimeout: FormControl = new FormControl(null);\n\n private startingLocale: string;\n private startingTheme: string;\n\n constructor(private storageService: StorageService, private stateService: StateService,\n private i18nService: I18nService, private toasterService: ToasterService,\n private vaultTimeoutService: VaultTimeoutService, private platformUtilsService: PlatformUtilsService,\n private messagingService: MessagingService) {\n this.vaultTimeouts = [\n { name: i18nService.t('oneMinute'), value: 1 },\n { name: i18nService.t('fiveMinutes'), value: 5 },\n { name: i18nService.t('fifteenMinutes'), value: 15 },\n { name: i18nService.t('thirtyMinutes'), value: 30 },\n { name: i18nService.t('oneHour'), value: 60 },\n { name: i18nService.t('fourHours'), value: 240 },\n { name: i18nService.t('onRefresh'), value: -1 },\n ];\n if (this.platformUtilsService.isDev()) {\n this.vaultTimeouts.push({ name: i18nService.t('never'), value: null });\n }\n\n const localeOptions: any[] = [];\n i18nService.supportedTranslationLocales.forEach(locale => {\n let name = locale;\n if (i18nService.localeNames.has(locale)) {\n name += (' - ' + i18nService.localeNames.get(locale));\n }\n localeOptions.push({ name: name, value: locale });\n });\n localeOptions.sort(Utils.getSortFunction(i18nService, 'name'));\n localeOptions.splice(0, 0, { name: i18nService.t('default'), value: null });\n this.localeOptions = localeOptions;\n this.themeOptions = [\n { name: i18nService.t('themeLight'), value: null },\n { name: i18nService.t('themeDark'), value: ThemeType.Dark },\n { name: i18nService.t('themeSystem'), value: ThemeType.System },\n ];\n }\n\n async ngOnInit() {\n this.vaultTimeout.setValue(await this.vaultTimeoutService.getVaultTimeout());\n this.vaultTimeoutAction = await this.storageService.get(ConstantsService.vaultTimeoutActionKey);\n this.disableIcons = await this.storageService.get(ConstantsService.disableFaviconKey);\n this.enableGravatars = await this.storageService.get('enableGravatars');\n this.enableFullWidth = await this.storageService.get('enableFullWidth');\n this.locale = this.startingLocale = await this.storageService.get(ConstantsService.localeKey);\n this.theme = this.startingTheme = await this.storageService.get(ConstantsService.themeKey);\n }\n\n async submit() {\n if (!this.vaultTimeout.valid) {\n this.toasterService.popAsync('error', null, this.i18nService.t('vaultTimeoutToLarge'));\n return;\n }\n\n await this.vaultTimeoutService.setVaultTimeoutOptions(this.vaultTimeout.value, this.vaultTimeoutAction);\n await this.storageService.save(ConstantsService.disableFaviconKey, this.disableIcons);\n await this.stateService.save(ConstantsService.disableFaviconKey, this.disableIcons);\n await this.storageService.save('enableGravatars', this.enableGravatars);\n await this.stateService.save('enableGravatars', this.enableGravatars);\n await this.storageService.save('enableFullWidth', this.enableFullWidth);\n this.messagingService.send('setFullWidth');\n if (this.theme !== this.startingTheme) {\n await this.storageService.save(ConstantsService.themeKey, this.theme);\n this.startingTheme = this.theme;\n const effectiveTheme = await this.platformUtilsService.getEffectiveTheme();\n const htmlEl = window.document.documentElement;\n htmlEl.classList.remove('theme_' + ThemeType.Light, 'theme_' + ThemeType.Dark);\n htmlEl.classList.add('theme_' + effectiveTheme);\n }\n await this.storageService.save(ConstantsService.localeKey, this.locale);\n if (this.locale !== this.startingLocale) {\n window.location.reload();\n } else {\n this.toasterService.popAsync('success', null, this.i18nService.t('optionsUpdated'));\n }\n }\n\n async vaultTimeoutActionChanged(newValue: string) {\n if (newValue === 'logOut') {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('vaultTimeoutLogOutConfirmation'),\n this.i18nService.t('vaultTimeoutLogOutConfirmationTitle'),\n this.i18nService.t('yes'), this.i18nService.t('cancel'), 'warning');\n if (!confirmed) {\n this.vaultTimeoutAction = 'lock';\n return;\n }\n }\n this.vaultTimeoutAction = newValue;\n }\n}\n","

{{'options' | i18n}}

{{'optionsDesc' | i18n}}

{{'languageDesc' | i18n}}
{{'disableIconsDesc' | i18n}}
{{'enableGravatarsDesc' | i18n}}
{{'enableFullWidthDesc' | i18n}}
{{'themeDesc' | i18n}}
","import { Component } from '@angular/core';\nimport {\n NG_VALIDATORS,\n NG_VALUE_ACCESSOR,\n} from '@angular/forms';\n\nimport {\n VaultTimeoutInputComponent as VaultTimeoutInputComponentBase\n} from 'jslib-angular/components/settings/vault-timeout-input.component';\n\n@Component({\n selector: 'app-vault-timeout-input',\n templateUrl: 'vault-timeout-input.component.html',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n multi: true,\n useExisting: VaultTimeoutInputComponent,\n },\n {\n provide: NG_VALIDATORS,\n multi: true,\n useExisting: VaultTimeoutInputComponent,\n },\n ],\n})\nexport class VaultTimeoutInputComponent extends VaultTimeoutInputComponentBase {\n}\n"," {{'vaultTimeoutPolicyInEffect' | i18n : vaultTimeoutPolicyHours : vaultTimeoutPolicyMinutes}}
{{'vaultTimeoutDesc' | i18n}}
{{'hours' | i18n }}
{{'minutes' | i18n }}
","import {\n Component,\n OnInit,\n ViewChild,\n} from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { TokenService } from 'jslib-common/abstractions/token.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { PaymentComponent } from './payment.component';\nimport { TaxInfoComponent } from './tax-info.component';\n\n@Component({\n selector: 'app-premium',\n templateUrl: 'premium.component.html',\n})\nexport class PremiumComponent implements OnInit {\n @ViewChild(PaymentComponent) paymentComponent: PaymentComponent;\n @ViewChild(TaxInfoComponent) taxInfoComponent: TaxInfoComponent;\n\n canAccessPremium = false;\n selfHosted = false;\n premiumPrice = 10;\n storageGbPrice = 4;\n additionalStorage = 0;\n\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, platformUtilsService: PlatformUtilsService,\n private tokenService: TokenService, private router: Router,\n private messagingService: MessagingService, private syncService: SyncService,\n private userService: UserService, private logService: LogService) {\n this.selfHosted = platformUtilsService.isSelfHost();\n }\n\n async ngOnInit() {\n this.canAccessPremium = await this.userService.canAccessPremium();\n const premium = await this.tokenService.getPremium();\n if (premium) {\n this.router.navigate(['/settings/subscription']);\n return;\n }\n }\n\n async submit() {\n let files: FileList = null;\n if (this.selfHosted) {\n const fileEl = document.getElementById('file') as HTMLInputElement;\n files = fileEl.files;\n if (files == null || files.length === 0) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('selectFile'));\n return;\n }\n }\n\n try {\n if (this.selfHosted) {\n if (!this.tokenService.getEmailVerified()) {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('verifyEmailFirst'));\n return;\n }\n\n const fd = new FormData();\n fd.append('license', files[0]);\n this.formPromise = this.apiService.postAccountLicense(fd).then(() => {\n return this.finalizePremium();\n });\n } else {\n this.formPromise = this.paymentComponent.createPaymentToken().then(result => {\n const fd = new FormData();\n fd.append('paymentMethodType', result[1].toString());\n if (result[0] != null) {\n fd.append('paymentToken', result[0]);\n }\n fd.append('additionalStorageGb', (this.additionalStorage || 0).toString());\n fd.append('country', this.taxInfoComponent.taxInfo.country);\n fd.append('postalCode', this.taxInfoComponent.taxInfo.postalCode);\n return this.apiService.postPremium(fd);\n }).then(paymentResponse => {\n if (!paymentResponse.success && paymentResponse.paymentIntentClientSecret != null) {\n return this.paymentComponent.handleStripeCardPayment(paymentResponse.paymentIntentClientSecret,\n () => this.finalizePremium());\n } else {\n return this.finalizePremium();\n }\n });\n }\n await this.formPromise;\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async finalizePremium() {\n await this.apiService.refreshIdentityToken();\n await this.syncService.fullSync(true);\n this.toasterService.popAsync('success', null, this.i18nService.t('premiumUpdated'));\n this.messagingService.send('purchasedPremium');\n this.router.navigate(['/settings/subscription']);\n }\n\n get additionalStorageTotal(): number {\n return this.storageGbPrice * Math.abs(this.additionalStorage || 0);\n }\n\n get subtotal(): number {\n return this.premiumPrice + this.additionalStorageTotal;\n }\n\n get taxCharges(): number {\n return this.taxInfoComponent != null && this.taxInfoComponent.taxRate != null ?\n (this.taxInfoComponent.taxRate / 100) * this.subtotal :\n 0;\n }\n\n get total(): number {\n return (this.subtotal + this.taxCharges) || 0;\n }\n}\n","

{{'goPremium' | i18n}}

{{'alreadyPremiumFromOrg' | i18n}}

{{'premiumUpgradeUnlockFeatures' | i18n}}

  • {{'premiumSignUpStorage' | i18n}}
  • {{'premiumSignUpTwoStep' | i18n}}
  • {{'premiumSignUpEmergency' |i18n}}
  • {{'premiumSignUpReports' | i18n}}
  • {{'premiumSignUpTotp' | i18n}}
  • {{'premiumSignUpSupport' | i18n}}
  • {{'premiumSignUpFuture' | i18n}}

{{'premiumPrice' | i18n : (premiumPrice | currency:'$')}}

{{'purchasePremium' | i18n}}

{{'uploadLicenseFilePremium' | i18n}}

{{'licenseFileDesc' | i18n : 'bitwarden_premium_license.json'}}

{{'addons' | i18n}}

{{'additionalStorageIntervalDesc' | i18n : '1 GB' : (storageGbPrice | currency:'$') : ('year' | i18n)}}

{{'summary' | i18n}}

{{'premiumMembership' | i18n}}: {{premiumPrice | currency:'$'}}
{{'additionalStorageGb' | i18n}}: {{additionalStorage || 0}} GB × {{storageGbPrice | currency:'$'}} = {{additionalStorageTotal | currency:'$'}}

{{'paymentInformation' | i18n}}

{{ 'planPrice' | i18n }}: {{ subtotal | currency: 'USD $' }}
{{ 'estimatedTax' | i18n }}: {{ taxCharges | currency: 'USD $' }}

{{'total' | i18n}}: {{total | currency:'USD $'}}/{{'year' | i18n}}

{{'paymentChargedAnnually' | i18n}}
","import {\n Component,\n NgZone,\n OnDestroy,\n OnInit,\n} from '@angular/core';\n\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { TokenService } from 'jslib-common/abstractions/token.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { BroadcasterService } from 'jslib-angular/services/broadcaster.service';\n\nconst BroadcasterSubscriptionId = 'SettingsComponent';\n\n@Component({\n selector: 'app-settings',\n templateUrl: 'settings.component.html',\n})\nexport class SettingsComponent implements OnInit, OnDestroy {\n premium: boolean;\n selfHosted: boolean;\n hasFamilySponsorshipAvailable: boolean;\n\n constructor(private tokenService: TokenService, private broadcasterService: BroadcasterService,\n private ngZone: NgZone, private platformUtilsService: PlatformUtilsService,\n private userService: UserService) { }\n\n async ngOnInit() {\n this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {\n this.ngZone.run(async () => {\n switch (message.command) {\n case 'purchasedPremium':\n await this.load();\n break;\n default:\n }\n });\n });\n\n this.selfHosted = await this.platformUtilsService.isSelfHost();\n await this.load();\n }\n\n ngOnDestroy() {\n this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);\n }\n\n async load() {\n this.premium = await this.tokenService.getPremium();\n this.hasFamilySponsorshipAvailable = await this.userService.canManageSponsorships();\n }\n}\n"," ","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport { ToasterService } from 'angular2-toaster';\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\nimport { PlanSponsorshipType } from 'jslib-common/enums/planSponsorshipType';\nimport { Organization } from 'jslib-common/models/domain/organization';\n\n@Component({\n selector: 'app-sponsored-families',\n templateUrl: 'sponsored-families.component.html',\n})\nexport class SponsoredFamiliesComponent implements OnInit {\n loading = false;\n\n availableSponsorshipOrgs: Organization[] = [];\n activeSponsorshipOrgs: Organization[] = [];\n selectedSponsorshipOrgId: string = '';\n sponsorshipEmail: string = '';\n\n // Conditional display properties\n formPromise: Promise;\n\n constructor(private userService: UserService, private apiService: ApiService,\n private i18nService: I18nService, private toasterService: ToasterService,\n private syncService: SyncService) { }\n\n async ngOnInit() {\n await this.load();\n }\n\n async submit() {\n this.formPromise = this.apiService.postCreateSponsorship(this.selectedSponsorshipOrgId, {\n sponsoredEmail: this.sponsorshipEmail,\n planSponsorshipType: PlanSponsorshipType.FamiliesForEnterprise,\n friendlyName: this.sponsorshipEmail,\n });\n\n await this.formPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('sponsorshipCreated'));\n this.formPromise = null;\n this.resetForm();\n await this.load(true);\n }\n\n async load(forceReload: boolean = false) {\n if (this.loading) {\n return;\n }\n\n this.loading = true;\n if (forceReload) {\n await this.syncService.fullSync(true);\n }\n\n const allOrgs = await this.userService.getAllOrganizations();\n this.availableSponsorshipOrgs = allOrgs.filter(org => org.familySponsorshipAvailable);\n\n this.activeSponsorshipOrgs = allOrgs.filter(org => org.familySponsorshipFriendlyName !== null);\n\n if (this.availableSponsorshipOrgs.length === 1) {\n this.selectedSponsorshipOrgId = this.availableSponsorshipOrgs[0].id;\n }\n this.loading = false;\n }\n\n\n private async resetForm() {\n this.sponsorshipEmail = '';\n this.selectedSponsorshipOrgId = '';\n }\n\n get anyActiveSponsorships(): boolean {\n return this.activeSponsorshipOrgs.length > 0;\n }\n\n get anyOrgsAvailable(): boolean {\n return this.availableSponsorshipOrgs.length > 0;\n }\n\n get moreThanOneOrgAvailable(): boolean {\n return this.availableSponsorshipOrgs.length > 1;\n }\n}\n","

{{'sponsoredFamilies' | i18n}}

{{'loading' | i18n}}

{{'sponsoredFamiliesEligible' | i18n}}

{{'sponsoredFamiliesInclude' | i18n}}:
  • {{'sponsoredFamiliesPremiumAccess' | i18n}}
  • {{'sponsoredFamiliesSharedCollections' | i18n}}
{{'recipient' | i18n}} {{'sponsoringOrg' | i18n}}
{{'sponsoredFamiliesLeaveCopy' | i18n}}
","import {\n Component,\n EventEmitter,\n Input,\n Output,\n} from '@angular/core';\nimport { ToasterService } from 'angular2-toaster';\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\n\n@Component({\n selector: '[sponsoring-org-row]',\n templateUrl: 'sponsoring-org-row.component.html',\n})\nexport class SponsoringOrgRowComponent {\n @Input() sponsoringOrg: Organization = null;\n\n @Output() sponsorshipRemoved = new EventEmitter();\n\n revokeSponsorshipPromise: Promise;\n resendEmailPromise: Promise;\n\n constructor(private toasterService: ToasterService, private apiService: ApiService,\n private i18nService: I18nService, private logService: LogService,\n private platformUtilsService: PlatformUtilsService) { }\n\n async revokeSponsorship() {\n try {\n this.revokeSponsorshipPromise = this.doRevokeSponsorship();\n await this.revokeSponsorshipPromise;\n } catch (e) {\n this.logService.error(e);\n }\n\n this.revokeSponsorshipPromise = null;\n }\n\n async resendEmail() {\n this.resendEmailPromise = this.apiService.postResendSponsorshipOffer(this.sponsoringOrg.id);\n await this.resendEmailPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('emailSent'));\n this.resendEmailPromise = null;\n }\n\n private async doRevokeSponsorship() {\n const isConfirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('revokeSponsorshipConfirmation'),\n `${this.i18nService.t('remove')} ${this.sponsoringOrg.familySponsorshipFriendlyName}?`,\n this.i18nService.t('remove'), this.i18nService.t('cancel'), 'warning');\n\n if (!isConfirmed) {\n return;\n }\n\n await this.apiService.deleteRevokeSponsorship(this.sponsoringOrg.id);\n this.toasterService.popAsync('success', null, this.i18nService.t('reclaimedFreePlan'));\n this.sponsorshipRemoved.emit();\n }\n}\n"," {{sponsoringOrg.familySponsorshipFriendlyName}} {{sponsoringOrg.name}}
","import { Component } from '@angular/core';\n\nimport {\n Toast,\n ToasterService,\n} from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { FolderService } from 'jslib-common/abstractions/folder.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\n\nimport { EncString } from 'jslib-common/models/domain/encString';\n\nimport { CipherWithIdRequest } from 'jslib-common/models/request/cipherWithIdRequest';\nimport { FolderWithIdRequest } from 'jslib-common/models/request/folderWithIdRequest';\nimport { UpdateKeyRequest } from 'jslib-common/models/request/updateKeyRequest';\n\n@Component({\n selector: 'app-update-key',\n templateUrl: 'update-key.component.html',\n})\nexport class UpdateKeyComponent {\n masterPassword: string;\n formPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private cryptoService: CryptoService,\n private messagingService: MessagingService, private syncService: SyncService,\n private folderService: FolderService, private cipherService: CipherService,\n private logService: LogService) { }\n\n async submit() {\n const hasEncKey = await this.cryptoService.hasEncKey();\n if (hasEncKey) {\n return;\n }\n\n if (this.masterPassword == null || this.masterPassword === '') {\n this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPassRequired'));\n return;\n }\n\n try {\n this.formPromise = this.makeRequest().then(request => {\n return this.apiService.postAccountKey(request);\n });\n await this.formPromise;\n const toast: Toast = {\n type: 'success',\n title: this.i18nService.t('keyUpdated'),\n body: this.i18nService.t('logBackInOthersToo'),\n timeout: 15000,\n };\n this.toasterService.popAsync(toast);\n this.messagingService.send('logout');\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n private async makeRequest(): Promise {\n const key = await this.cryptoService.getKey();\n const encKey = await this.cryptoService.makeEncKey(key);\n const privateKey = await this.cryptoService.getPrivateKey();\n let encPrivateKey: EncString = null;\n if (privateKey != null) {\n encPrivateKey = await this.cryptoService.encrypt(privateKey, encKey[0]);\n }\n const request = new UpdateKeyRequest();\n request.privateKey = encPrivateKey != null ? encPrivateKey.encryptedString : null;\n request.key = encKey[1].encryptedString;\n request.masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, null);\n\n await this.syncService.fullSync(true);\n\n const folders = await this.folderService.getAllDecrypted();\n for (let i = 0; i < folders.length; i++) {\n if (folders[i].id == null) {\n continue;\n }\n const folder = await this.folderService.encrypt(folders[i], encKey[0]);\n request.folders.push(new FolderWithIdRequest(folder));\n }\n\n const ciphers = await this.cipherService.getAllDecrypted();\n for (let i = 0; i < ciphers.length; i++) {\n if (ciphers[i].organizationId != null) {\n continue;\n }\n const cipher = await this.cipherService.encrypt(ciphers[i], encKey[0]);\n request.ciphers.push(new CipherWithIdRequest(cipher));\n }\n\n return request;\n }\n}\n","

{{'updateEncryptionKey' | i18n}}

{{'updateEncryptionKeyShortDesc' | i18n}} {{'updateEncryptionKeyDesc' | i18n}} {{'learnMore' | i18n}}

{{'updateEncryptionKeyWarning' | i18n}}
","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { SubscriptionResponse } from 'jslib-common/models/response/subscriptionResponse';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { TokenService } from 'jslib-common/abstractions/token.service';\n\n@Component({\n selector: 'app-user-subscription',\n templateUrl: 'user-subscription.component.html',\n})\nexport class UserSubscriptionComponent implements OnInit {\n loading = false;\n firstLoaded = false;\n adjustStorageAdd = true;\n showAdjustStorage = false;\n showUpdateLicense = false;\n sub: SubscriptionResponse;\n selfHosted = false;\n\n cancelPromise: Promise;\n reinstatePromise: Promise;\n\n constructor(private tokenService: TokenService, private apiService: ApiService,\n private platformUtilsService: PlatformUtilsService, private i18nService: I18nService,\n private toasterService: ToasterService, private router: Router, private logService: LogService) {\n this.selfHosted = platformUtilsService.isSelfHost();\n }\n\n async ngOnInit() {\n await this.load();\n this.firstLoaded = true;\n }\n\n async load() {\n if (this.loading) {\n return;\n }\n\n if (this.tokenService.getPremium()) {\n this.loading = true;\n this.sub = await this.apiService.getUserSubscription();\n } else {\n this.router.navigate(['/settings/premium']);\n return;\n }\n\n this.loading = false;\n }\n\n async reinstate() {\n if (this.loading) {\n return;\n }\n\n if (this.usingInAppPurchase) {\n this.platformUtilsService.showDialog(this.i18nService.t('manageSubscriptionFromStore'),\n this.i18nService.t('cancelSubscription'), null, null, 'warning');\n return;\n }\n\n const confirmed = await this.platformUtilsService.showDialog(this.i18nService.t('reinstateConfirmation'),\n this.i18nService.t('reinstateSubscription'), this.i18nService.t('yes'), this.i18nService.t('cancel'));\n if (!confirmed) {\n return;\n }\n\n try {\n this.reinstatePromise = this.apiService.postReinstatePremium();\n await this.reinstatePromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('reinstated'));\n this.load();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async cancel() {\n if (this.loading) {\n return;\n }\n\n if (this.usingInAppPurchase) {\n this.platformUtilsService.showDialog(this.i18nService.t('manageSubscriptionFromStore'),\n this.i18nService.t('cancelSubscription'), null, null, 'warning');\n return;\n }\n\n const confirmed = await this.platformUtilsService.showDialog(this.i18nService.t('cancelConfirmation'),\n this.i18nService.t('cancelSubscription'), this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return;\n }\n\n try {\n this.cancelPromise = this.apiService.postCancelPremium();\n await this.cancelPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('canceledSubscription'));\n this.load();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n downloadLicense() {\n if (this.loading) {\n return;\n }\n\n const licenseString = JSON.stringify(this.sub.license, null, 2);\n this.platformUtilsService.saveFile(window, licenseString, null, 'bitwarden_premium_license.json');\n }\n\n updateLicense() {\n if (this.loading) {\n return;\n }\n this.showUpdateLicense = true;\n }\n\n closeUpdateLicense(load: boolean) {\n this.showUpdateLicense = false;\n if (load) {\n this.load();\n }\n }\n\n adjustStorage(add: boolean) {\n if (this.usingInAppPurchase) {\n this.platformUtilsService.showDialog(this.i18nService.t('cannotPerformInAppPurchase'),\n this.i18nService.t(add ? 'addStorage' : 'removeStorage'), null, null, 'warning');\n return;\n }\n this.adjustStorageAdd = add;\n this.showAdjustStorage = true;\n }\n\n closeStorage(load: boolean) {\n this.showAdjustStorage = false;\n if (load) {\n this.load();\n }\n }\n\n get subscriptionMarkedForCancel() {\n return this.subscription != null && !this.subscription.cancelled && this.subscription.cancelAtEndDate;\n }\n\n get subscription() {\n return this.sub != null ? this.sub.subscription : null;\n }\n\n get nextInvoice() {\n return this.sub != null ? this.sub.upcomingInvoice : null;\n }\n\n get storagePercentage() {\n return this.sub != null && this.sub.maxStorageGb ?\n +(100 * (this.sub.storageGb / this.sub.maxStorageGb)).toFixed(2) : 0;\n }\n\n get storageProgressWidth() {\n return this.storagePercentage < 5 ? 5 : 0;\n }\n\n get usingInAppPurchase() {\n return this.sub != null ? this.sub.usingInAppPurchase : false;\n }\n}\n","

{{'premiumMembership' | i18n}} {{'loading' | i18n}}

{{'loading' | i18n}} {{'subscriptionCanceled' | i18n}}

{{'subscriptionPendingCanceled' | i18n}}

{{'expiration' | i18n}}
{{sub.expiration | date:'mediumDate'}}
{{'neverExpires' | i18n}}
{{'status' | i18n}}
{{(subscription && subscription.status) || '-'}} {{'pendingCancellation' | i18n}}
{{'nextCharge' | i18n}}
{{nextInvoice ? ((nextInvoice.date | date: 'mediumDate') + ', ' + (nextInvoice.amount | currency:'$')) : '-'}}
{{'details' | i18n}}
{{i.name}} {{i.quantity > 1 ? '×' + i.quantity : ''}} @ {{i.amount | currency:'$'}} {{(i.quantity * i.amount) | currency:'$'}} /{{i.interval | i18n}}
{{'manageSubscription' | i18n}}

{{'updateLicense' | i18n}}

{{'storage' | i18n}}

{{'subscriptionStorage' | i18n : sub.maxStorageGb || 0 : sub.storageName || '0 MB'}}

{{(storagePercentage / 100) | percent}}
","import { Component } from '@angular/core';\n\nimport { ToasterService } from 'angular2-toaster';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\n@Component({\n selector: 'app-verify-email',\n templateUrl: 'verify-email.component.html',\n})\nexport class VerifyEmailComponent {\n actionPromise: Promise;\n\n constructor(private apiService: ApiService, private i18nService: I18nService,\n private toasterService: ToasterService, private logService: LogService) { }\n\n async send() {\n if (this.actionPromise != null) {\n return;\n }\n try {\n this.actionPromise = this.apiService.postAccountVerifyEmail();\n await this.actionPromise;\n this.toasterService.popAsync('success', null, this.i18nService.t('checkInboxForVerification'));\n } catch (e) {\n this.logService.error(e);\n }\n this.actionPromise = null;\n }\n}\n","
{{'verifyEmail' | i18n}}

{{'verifyEmailDesc' | i18n}}

","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { AuditService } from 'jslib-common/abstractions/audit.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\nimport { BreachAccountResponse } from 'jslib-common/models/response/breachAccountResponse';\n\n@Component({\n selector: 'app-breach-report',\n templateUrl: 'breach-report.component.html',\n})\nexport class BreachReportComponent implements OnInit {\n error = false;\n username: string;\n checkedUsername: string;\n breachedAccounts: BreachAccountResponse[] = [];\n formPromise: Promise;\n\n constructor(private auditService: AuditService, private userService: UserService) { }\n\n async ngOnInit() {\n this.username = await this.userService.getEmail();\n }\n\n async submit() {\n this.error = false;\n this.username = this.username.toLowerCase();\n try {\n this.formPromise = this.auditService.breachedAccounts(this.username);\n this.breachedAccounts = await this.formPromise;\n } catch {\n this.error = true;\n }\n this.checkedUsername = this.username;\n }\n}\n","

{{'dataBreachReport' | i18n}}

{{'breachDesc' | i18n}}

{{'breachCheckUsernameEmail' | i18n}}

{{'reportError' | i18n}}...

{{'breachUsernameNotFound' | i18n : checkedUsername}} {{'breachUsernameFound' | i18n : checkedUsername : breachedAccounts.length}}
  • \"\"

    {{a.title}}

    {{'compromisedData' | i18n}}:

    • {{d}}
    {{'website' | i18n}}
    {{a.domain}}
    {{'affectedUsers' | i18n}}
    {{a.pwnCount | number}}
    {{'breachOccurred' | i18n}}
    {{a.breachDate | date: 'mediumDate'}}
    {{'breachReported' | i18n}}
    {{a.addedDate | date: 'mediumDate'}}
","import { Component } from '@angular/core';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport {\n PasswordGeneratorHistoryComponent as BasePasswordGeneratorHistoryComponent,\n} from 'jslib-angular/components/password-generator-history.component';\n\n@Component({\n selector: 'app-password-generator-history',\n templateUrl: 'password-generator-history.component.html',\n})\nexport class PasswordGeneratorHistoryComponent extends BasePasswordGeneratorHistoryComponent {\n constructor(passwordGenerationService: PasswordGenerationService, platformUtilsService: PlatformUtilsService,\n i18nService: I18nService) {\n super(passwordGenerationService, platformUtilsService, i18nService, window);\n }\n}\n","

{{'passwordHistory' | i18n}}

  • {{h.date | date:'medium'}}
{{'noPasswordsInList' | i18n}}
","import {\n Component,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport {\n PasswordGeneratorComponent as BasePasswordGeneratorComponent,\n} from 'jslib-angular/components/password-generator.component';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\nimport { PasswordGeneratorHistoryComponent } from './password-generator-history.component';\n\n@Component({\n selector: 'app-password-generator',\n templateUrl: 'password-generator.component.html',\n})\nexport class PasswordGeneratorComponent extends BasePasswordGeneratorComponent {\n @ViewChild('historyTemplate', { read: ViewContainerRef, static: true }) historyModalRef: ViewContainerRef;\n\n constructor(passwordGenerationService: PasswordGenerationService, platformUtilsService: PlatformUtilsService,\n i18nService: I18nService, private modalService: ModalService) {\n super(passwordGenerationService, platformUtilsService, i18nService, window);\n }\n\n async history() {\n await this.modalService.openViewRef(PasswordGeneratorHistoryComponent, this.historyModalRef);\n }\n\n lengthChanged() {\n document.getElementById('length').focus();\n }\n\n minNumberChanged() {\n document.getElementById('min-number').focus();\n }\n\n minSpecialChanged() {\n document.getElementById('min-special').focus();\n }\n}\n","

{{'passwordGenerator' | i18n}}

{{'passwordGeneratorPolicyInEffect' | i18n}}
","import {\n Component,\n OnInit,\n} from '@angular/core';\n\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\n@Component({\n selector: 'app-tools',\n templateUrl: 'tools.component.html',\n})\nexport class ToolsComponent implements OnInit {\n canAccessPremium = false;\n\n constructor(private userService: UserService, private messagingService: MessagingService) { }\n\n async ngOnInit() {\n this.canAccessPremium = await this.userService.canAccessPremium();\n }\n\n premiumRequired() {\n if (!this.canAccessPremium) {\n this.messagingService.send('premiumRequired');\n return;\n }\n }\n}\n"," ","import { Component } from '@angular/core';\n\nimport { FolderService } from 'jslib-common/abstractions/folder.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport {\n FolderAddEditComponent as BaseFolderAddEditComponent,\n} from 'jslib-angular/components/folder-add-edit.component';\n\n@Component({\n selector: 'app-folder-add-edit',\n templateUrl: 'folder-add-edit.component.html',\n})\nexport class FolderAddEditComponent extends BaseFolderAddEditComponent {\n constructor(folderService: FolderService, i18nService: I18nService,\n platformUtilsService: PlatformUtilsService, logService: LogService) {\n super(folderService, i18nService, platformUtilsService, logService);\n }\n}\n","

{{title}}

","import {\n Component,\n OnDestroy,\n} from '@angular/core';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { CollectionView } from 'jslib-common/models/view/collectionView';\n\nimport { ShareComponent as BaseShareComponent } from 'jslib-angular/components/share.component';\nimport { LogService } from 'jslib-common/abstractions/log.service';\n\n@Component({\n selector: 'app-vault-share',\n templateUrl: 'share.component.html',\n})\nexport class ShareComponent extends BaseShareComponent implements OnDestroy {\n constructor(collectionService: CollectionService, platformUtilsService: PlatformUtilsService,\n i18nService: I18nService, userService: UserService,\n cipherService: CipherService, logService: LogService) {\n super(collectionService, platformUtilsService, i18nService, userService, cipherService,\n logService);\n }\n\n ngOnDestroy() {\n this.selectAll(false);\n }\n\n check(c: CollectionView, select?: boolean) {\n (c as any).checked = select == null ? !(c as any).checked : select;\n }\n\n selectAll(select: boolean) {\n const collections = select ? this.collections : this.writeableCollections;\n collections.forEach(c => this.check(c, select));\n }\n}\n","

{{'moveToOrganization' | i18n}} {{cipher.name}}

{{'noOrganizationsList' | i18n}}

{{'moveToOrgDesc' | i18n}}

{{'collections' | i18n}}

{{'noCollectionsInList' | i18n}}
{{c.name}}
{{'newOrganization' | i18n}}
","import {\n ChangeDetectorRef,\n Component,\n NgZone,\n OnDestroy,\n OnInit,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { first } from 'rxjs/operators';\n\nimport { CipherType } from 'jslib-common/enums/cipherType';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\nimport { OrganizationsComponent } from '../settings/organizations.component';\nimport { UpdateKeyComponent } from '../settings/update-key.component';\nimport { AddEditComponent } from './add-edit.component';\nimport { AttachmentsComponent } from './attachments.component';\nimport { CiphersComponent } from './ciphers.component';\nimport { CollectionsComponent } from './collections.component';\nimport { FolderAddEditComponent } from './folder-add-edit.component';\nimport { GroupingsComponent } from './groupings.component';\nimport { ShareComponent } from './share.component';\n\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { TokenService } from 'jslib-common/abstractions/token.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { BroadcasterService } from 'jslib-angular/services/broadcaster.service';\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nconst BroadcasterSubscriptionId = 'VaultComponent';\n\n@Component({\n selector: 'app-vault',\n templateUrl: 'vault.component.html',\n})\nexport class VaultComponent implements OnInit, OnDestroy {\n @ViewChild(GroupingsComponent, { static: true }) groupingsComponent: GroupingsComponent;\n @ViewChild(CiphersComponent, { static: true }) ciphersComponent: CiphersComponent;\n @ViewChild(OrganizationsComponent, { static: true }) organizationsComponent: OrganizationsComponent;\n @ViewChild('attachments', { read: ViewContainerRef, static: true }) attachmentsModalRef: ViewContainerRef;\n @ViewChild('folderAddEdit', { read: ViewContainerRef, static: true }) folderAddEditModalRef: ViewContainerRef;\n @ViewChild('cipherAddEdit', { read: ViewContainerRef, static: true }) cipherAddEditModalRef: ViewContainerRef;\n @ViewChild('share', { read: ViewContainerRef, static: true }) shareModalRef: ViewContainerRef;\n @ViewChild('collections', { read: ViewContainerRef, static: true }) collectionsModalRef: ViewContainerRef;\n @ViewChild('updateKeyTemplate', { read: ViewContainerRef, static: true }) updateKeyModalRef: ViewContainerRef;\n\n favorites: boolean = false;\n type: CipherType = null;\n folderId: string = null;\n collectionId: string = null;\n showVerifyEmail = false;\n showBrowserOutdated = false;\n showUpdateKey = false;\n showPremiumCallout = false;\n showRedeemSponsorship = false;\n showProviders = false;\n deleted: boolean = false;\n trashCleanupWarning: string = null;\n\n\n constructor(private syncService: SyncService, private route: ActivatedRoute,\n private router: Router, private changeDetectorRef: ChangeDetectorRef,\n private i18nService: I18nService, private modalService: ModalService,\n private tokenService: TokenService, private cryptoService: CryptoService,\n private messagingService: MessagingService, private userService: UserService,\n private platformUtilsService: PlatformUtilsService, private broadcasterService: BroadcasterService,\n private ngZone: NgZone) { }\n\n async ngOnInit() {\n this.showVerifyEmail = !(await this.tokenService.getEmailVerified());\n this.showBrowserOutdated = window.navigator.userAgent.indexOf('MSIE') !== -1;\n this.trashCleanupWarning = this.i18nService.t(\n this.platformUtilsService.isSelfHost() ? 'trashCleanupWarningSelfHosted' : 'trashCleanupWarning'\n );\n\n this.route.queryParams.pipe(first()).subscribe(async params => {\n await this.syncService.fullSync(false);\n\n this.showUpdateKey = !(await this.cryptoService.hasEncKey());\n const canAccessPremium = await this.userService.canAccessPremium();\n this.showPremiumCallout = !this.showVerifyEmail && !canAccessPremium &&\n !this.platformUtilsService.isSelfHost();\n\n this.showProviders = (await this.userService.getAllProviders()).length > 0;\n\n const allOrgs = await this.userService.getAllOrganizations();\n this.showRedeemSponsorship = allOrgs.some(o => o.familySponsorshipAvailable) && !allOrgs.some(o => o.familySponsorshipFriendlyName != null);\n\n await Promise.all([\n this.groupingsComponent.load(),\n this.organizationsComponent.load(),\n ]);\n\n if (params == null) {\n this.groupingsComponent.selectedAll = true;\n await this.ciphersComponent.reload();\n } else {\n if (params.deleted) {\n this.groupingsComponent.selectedTrash = true;\n await this.filterDeleted();\n } else if (params.favorites) {\n this.groupingsComponent.selectedFavorites = true;\n await this.filterFavorites();\n } else if (params.type) {\n const t = parseInt(params.type, null);\n this.groupingsComponent.selectedType = t;\n await this.filterCipherType(t);\n } else if (params.folderId) {\n this.groupingsComponent.selectedFolder = true;\n this.groupingsComponent.selectedFolderId = params.folderId;\n await this.filterFolder(params.folderId);\n } else if (params.collectionId) {\n this.groupingsComponent.selectedCollectionId = params.collectionId;\n await this.filterCollection(params.collectionId);\n } else {\n this.groupingsComponent.selectedAll = true;\n await this.ciphersComponent.reload();\n }\n }\n\n this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {\n this.ngZone.run(async () => {\n switch (message.command) {\n case 'syncCompleted':\n if (message.successfully) {\n await Promise.all([\n this.groupingsComponent.load(),\n this.organizationsComponent.load(),\n this.ciphersComponent.load(this.ciphersComponent.filter),\n ]);\n this.changeDetectorRef.detectChanges();\n }\n break;\n }\n });\n });\n });\n }\n\n ngOnDestroy() {\n this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);\n }\n\n async clearGroupingFilters() {\n this.ciphersComponent.showAddNew = true;\n this.groupingsComponent.searchPlaceholder = this.i18nService.t('searchVault');\n await this.ciphersComponent.reload();\n this.clearFilters();\n this.go();\n }\n\n async filterFavorites() {\n this.ciphersComponent.showAddNew = true;\n this.groupingsComponent.searchPlaceholder = this.i18nService.t('searchFavorites');\n await this.ciphersComponent.reload(c => c.favorite);\n this.clearFilters();\n this.favorites = true;\n this.go();\n }\n\n async filterDeleted() {\n this.ciphersComponent.showAddNew = false;\n this.ciphersComponent.deleted = true;\n this.groupingsComponent.searchPlaceholder = this.i18nService.t('searchTrash');\n await this.ciphersComponent.reload(null, true);\n this.clearFilters();\n this.deleted = true;\n this.go();\n }\n\n async filterCipherType(type: CipherType) {\n this.ciphersComponent.showAddNew = true;\n this.groupingsComponent.searchPlaceholder = this.i18nService.t('searchType');\n await this.ciphersComponent.reload(c => c.type === type);\n this.clearFilters();\n this.type = type;\n this.go();\n }\n\n async filterFolder(folderId: string) {\n this.ciphersComponent.showAddNew = true;\n folderId = folderId === 'none' ? null : folderId;\n this.groupingsComponent.searchPlaceholder = this.i18nService.t('searchFolder');\n await this.ciphersComponent.reload(c => c.folderId === folderId);\n this.clearFilters();\n this.folderId = folderId == null ? 'none' : folderId;\n this.go();\n }\n\n async filterCollection(collectionId: string) {\n this.ciphersComponent.showAddNew = true;\n this.groupingsComponent.searchPlaceholder = this.i18nService.t('searchCollection');\n await this.ciphersComponent.reload(c => c.collectionIds != null &&\n c.collectionIds.indexOf(collectionId) > -1);\n this.clearFilters();\n this.collectionId = collectionId;\n this.go();\n }\n\n filterSearchText(searchText: string) {\n this.ciphersComponent.searchText = searchText;\n this.ciphersComponent.search(200);\n }\n\n async editCipherAttachments(cipher: CipherView) {\n const canAccessPremium = await this.userService.canAccessPremium();\n if (cipher.organizationId == null && !canAccessPremium) {\n this.messagingService.send('premiumRequired');\n return;\n } else if (cipher.organizationId != null) {\n const org = await this.userService.getOrganization(cipher.organizationId);\n if (org != null && (org.maxStorageGb == null || org.maxStorageGb === 0)) {\n this.messagingService.send('upgradeOrganization', { organizationId: cipher.organizationId });\n return;\n }\n }\n\n let madeAttachmentChanges = false;\n const [modal] = await this.modalService.openViewRef(AttachmentsComponent, this.attachmentsModalRef, comp => {\n comp.cipherId = cipher.id;\n comp.onUploadedAttachment.subscribe(() => madeAttachmentChanges = true);\n comp.onDeletedAttachment.subscribe(() => madeAttachmentChanges = true);\n comp.onReuploadedAttachment.subscribe(() => madeAttachmentChanges = true);\n });\n\n modal.onClosed.subscribe(async () => {\n if (madeAttachmentChanges) {\n await this.ciphersComponent.refresh();\n }\n madeAttachmentChanges = false;\n });\n }\n\n async shareCipher(cipher: CipherView) {\n const [modal] = await this.modalService.openViewRef(ShareComponent, this.shareModalRef, comp => {\n comp.cipherId = cipher.id;\n comp.onSharedCipher.subscribe(async () => {\n modal.close();\n await this.ciphersComponent.refresh();\n });\n });\n }\n\n async editCipherCollections(cipher: CipherView) {\n const [modal] = await this.modalService.openViewRef(CollectionsComponent, this.collectionsModalRef, comp => {\n comp.cipherId = cipher.id;\n comp.onSavedCollections.subscribe(async () => {\n modal.close();\n await this.ciphersComponent.refresh();\n });\n });\n }\n\n async addFolder() {\n const [modal] = await this.modalService.openViewRef(FolderAddEditComponent, this.folderAddEditModalRef, comp => {\n comp.folderId = null;\n comp.onSavedFolder.subscribe(async () => {\n modal.close();\n await this.groupingsComponent.loadFolders();\n });\n });\n }\n\n async editFolder(folderId: string) {\n const [modal] = await this.modalService.openViewRef(FolderAddEditComponent, this.folderAddEditModalRef, comp => {\n comp.folderId = folderId;\n comp.onSavedFolder.subscribe(async () => {\n modal.close();\n await this.groupingsComponent.loadFolders();\n });\n comp.onDeletedFolder.subscribe(async () => {\n modal.close();\n await this.groupingsComponent.loadFolders();\n await this.filterFolder('none');\n this.groupingsComponent.selectedFolderId = null;\n });\n });\n }\n\n async addCipher() {\n const component = await this.editCipher(null);\n component.type = this.type;\n component.folderId = this.folderId === 'none' ? null : this.folderId;\n if (this.collectionId != null) {\n const collection = this.groupingsComponent.collections.filter(c => c.id === this.collectionId);\n if (collection.length > 0) {\n component.organizationId = collection[0].organizationId;\n component.collectionIds = [this.collectionId];\n }\n }\n }\n\n async editCipher(cipher: CipherView) {\n const [modal, childComponent] = await this.modalService.openViewRef(AddEditComponent, this.cipherAddEditModalRef, comp => {\n comp.cipherId = cipher == null ? null : cipher.id;\n comp.onSavedCipher.subscribe(async (c: CipherView) => {\n modal.close();\n await this.ciphersComponent.refresh();\n });\n comp.onDeletedCipher.subscribe(async (c: CipherView) => {\n modal.close();\n await this.ciphersComponent.refresh();\n });\n comp.onRestoredCipher.subscribe(async (c: CipherView) => {\n modal.close();\n await this.ciphersComponent.refresh();\n });\n });\n\n return childComponent;\n }\n\n async cloneCipher(cipher: CipherView) {\n const component = await this.editCipher(cipher);\n component.cloneMode = true;\n }\n\n async updateKey() {\n await this.modalService.openViewRef(UpdateKeyComponent, this.updateKeyModalRef);\n }\n\n private clearFilters() {\n this.folderId = null;\n this.collectionId = null;\n this.favorites = false;\n this.type = null;\n this.deleted = false;\n }\n\n private go(queryParams: any = null) {\n if (queryParams == null) {\n queryParams = {\n favorites: this.favorites ? true : null,\n type: this.type,\n folderId: this.folderId,\n collectionId: this.collectionId,\n deleted: this.deleted ? true : null,\n };\n }\n\n this.router.navigate([], {\n relativeTo: this.route,\n queryParams: queryParams,\n replaceUrl: true,\n });\n }\n}\n","

{{'myVault' | i18n}} {{'loading' | i18n}}

{{trashCleanupWarning}}
{{'updateKeyTitle' | i18n}}

{{'updateEncryptionKeyShortDesc' | i18n}}

{{'updateBrowser' | i18n}}

{{'updateBrowserDesc' | i18n}}

{{'updateBrowser' | i18n}}
{{'goPremium' | i18n}}

{{'premiumUpgradeUnlockFeatures' | i18n}}

{{'goPremium' | i18n}}
{{'organizations' | i18n}}
{{'freeFamiliesPlan' | i18n}}

{{'sponsoredFamiliesEligible' | i18n}}

{{'redeemNow' | i18n}}
{{'providers' | i18n}}
","import { Component } from '@angular/core';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { BasePolicy, BasePolicyComponent } from './base-policy.component';\n\nexport class DisableSendPolicy extends BasePolicy {\n name = 'disableSend';\n description = 'disableSendPolicyDesc';\n type = PolicyType.DisableSend;\n component = DisableSendPolicyComponent;\n}\n\n@Component({\n selector: 'policy-disable-send',\n templateUrl: 'disable-send.component.html',\n})\nexport class DisableSendPolicyComponent extends BasePolicyComponent {\n}\n"," {{'disableSendExemption' | i18n}}
","import { Component } from '@angular/core';\nimport { FormBuilder } from '@angular/forms';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { BasePolicy, BasePolicyComponent } from './base-policy.component';\n\nexport class MasterPasswordPolicy extends BasePolicy {\n name = 'masterPass';\n description = 'masterPassPolicyDesc';\n type = PolicyType.MasterPassword;\n component = MasterPasswordPolicyComponent;\n}\n\n@Component({\n selector: 'policy-master-password',\n templateUrl: 'master-password.component.html',\n})\nexport class MasterPasswordPolicyComponent extends BasePolicyComponent {\n\n data = this.fb.group({\n minComplexity: [null],\n minLength: [null],\n requireUpper: [null],\n requireLower: [null],\n requireNumbers: [null],\n requireSpecial: [null],\n });\n\n passwordScores: { name: string; value: number; }[];\n showKeyConnectorInfo: boolean = false;\n\n constructor(private fb: FormBuilder, i18nService: I18nService, private userService: UserService) {\n super();\n\n this.passwordScores = [\n { name: '-- ' + i18nService.t('select') + ' --', value: null },\n { name: i18nService.t('weak') + ' (0)', value: 0 },\n { name: i18nService.t('weak') + ' (1)', value: 1 },\n { name: i18nService.t('weak') + ' (2)', value: 2 },\n { name: i18nService.t('good') + ' (3)', value: 3 },\n { name: i18nService.t('strong') + ' (4)', value: 4 },\n ];\n }\n\n async ngOnInit() {\n super.ngOnInit();\n const organization = await this.userService.getOrganization(this.policyResponse.organizationId);\n this.showKeyConnectorInfo = organization.keyConnectorEnabled;\n }\n}\n"," {{'keyConnectorPolicyRestriction' | i18n}}
","import { Component } from '@angular/core';\nimport { FormBuilder } from '@angular/forms';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { BasePolicy, BasePolicyComponent } from './base-policy.component';\n\nexport class PasswordGeneratorPolicy extends BasePolicy {\n name = 'passwordGenerator';\n description = 'passwordGeneratorPolicyDesc';\n type = PolicyType.PasswordGenerator;\n component = PasswordGeneratorPolicyComponent;\n}\n\n@Component({\n selector: 'policy-password-generator',\n templateUrl: 'password-generator.component.html',\n})\nexport class PasswordGeneratorPolicyComponent extends BasePolicyComponent {\n\n data = this.fb.group({\n defaultType: [null],\n minLength: [null],\n useUpper: [null],\n useLower: [null],\n useNumbers: [null],\n useSpecial: [null],\n minNumbers: [null],\n minSpecial: [null],\n minNumberWords: [null],\n capitalize: [null],\n includeNumber: [null],\n });\n\n defaultTypes: { name: string; value: string; }[];\n\n constructor(private fb: FormBuilder, i18nService: I18nService) {\n super();\n\n this.defaultTypes = [\n { name: i18nService.t('userPreference'), value: null },\n { name: i18nService.t('password'), value: 'password' },\n { name: i18nService.t('passphrase'), value: 'passphrase' },\n ];\n }\n}\n","

{{'password' | i18n}}

{{'passphrase' | i18n}}

","import { Component } from '@angular/core';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { BasePolicy, BasePolicyComponent } from './base-policy.component';\n\nexport class PersonalOwnershipPolicy extends BasePolicy {\n name = 'personalOwnership';\n description = 'personalOwnershipPolicyDesc';\n type = PolicyType.PersonalOwnership;\n component = PersonalOwnershipPolicyComponent;\n}\n\n@Component({\n selector: 'policy-personal-ownership',\n templateUrl: 'personal-ownership.component.html',\n})\nexport class PersonalOwnershipPolicyComponent extends BasePolicyComponent {\n}\n"," {{'personalOwnershipExemption' | i18n}}
","import { Component } from '@angular/core';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport { PolicyRequest } from 'jslib-common/models/request/policyRequest';\n\nimport { BasePolicy, BasePolicyComponent } from './base-policy.component';\n\nexport class RequireSsoPolicy extends BasePolicy {\n name = 'requireSso';\n description = 'requireSsoPolicyDesc';\n type = PolicyType.RequireSso;\n component = RequireSsoPolicyComponent;\n\n display(organization: Organization) {\n return organization.useSso;\n }\n}\n\n@Component({\n selector: 'policy-require-sso',\n templateUrl: 'require-sso.component.html',\n})\nexport class RequireSsoPolicyComponent extends BasePolicyComponent {\n constructor(private i18nService: I18nService) {\n super();\n }\n\n buildRequest(policiesEnabledMap: Map): Promise {\n const singleOrgEnabled = policiesEnabledMap.get(PolicyType.SingleOrg) ?? false;\n if (this.enabled.value && !singleOrgEnabled) {\n throw new Error(this.i18nService.t('requireSsoPolicyReqError'));\n }\n\n return super.buildRequest(policiesEnabledMap);\n }\n}\n"," {{'requireSsoPolicyReq' | i18n}} {{'requireSsoExemption' | i18n}}
","import { Component } from '@angular/core';\nimport { FormBuilder } from '@angular/forms';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\n\nimport { BasePolicy, BasePolicyComponent } from './base-policy.component';\n\nexport class ResetPasswordPolicy extends BasePolicy {\n name = 'resetPasswordPolicy';\n description = 'resetPasswordPolicyDescription';\n type = PolicyType.ResetPassword;\n component = ResetPasswordPolicyComponent;\n\n display(organization: Organization) {\n return organization.useResetPassword;\n }\n}\n\n@Component({\n selector: 'policy-reset-password',\n templateUrl: 'reset-password.component.html',\n})\nexport class ResetPasswordPolicyComponent extends BasePolicyComponent {\n\n data = this.fb.group({\n autoEnrollEnabled: false,\n });\n\n defaultTypes: { name: string; value: string; }[];\n showKeyConnectorInfo: boolean = false;\n\n constructor(private fb: FormBuilder, private userService: UserService) {\n super();\n }\n\n async ngOnInit() {\n super.ngOnInit();\n const organization = await this.userService.getOrganization(this.policyResponse.organizationId);\n this.showKeyConnectorInfo = organization.keyConnectorEnabled;\n }\n}\n"," {{'keyConnectorPolicyRestriction' | i18n}} {{'resetPasswordPolicyWarning' | i18n}}

{{'resetPasswordPolicyAutoEnroll' | i18n}}

{{'resetPasswordPolicyAutoEnrollDescription' | i18n}}

{{'resetPasswordPolicyAutoEnrollWarning' | i18n}}
","import { Component } from '@angular/core';\nimport { FormBuilder } from '@angular/forms';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { BasePolicy, BasePolicyComponent } from './base-policy.component';\n\nexport class SendOptionsPolicy extends BasePolicy {\n name = 'sendOptions';\n description = 'sendOptionsPolicyDesc';\n type = PolicyType.SendOptions;\n component = SendOptionsPolicyComponent;\n}\n\n@Component({\n selector: 'policy-send-options',\n templateUrl: 'send-options.component.html',\n})\nexport class SendOptionsPolicyComponent extends BasePolicyComponent {\n\n data = this.fb.group({\n disableHideEmail: false,\n });\n\n constructor(private fb: FormBuilder) {\n super();\n }\n}\n"," {{'sendOptionsExemption' | i18n}}

{{'options' | i18n}}

","import { Component } from '@angular/core';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { PolicyRequest } from 'jslib-common/models/request/policyRequest';\n\nimport { BasePolicy, BasePolicyComponent } from './base-policy.component';\n\nexport class SingleOrgPolicy extends BasePolicy {\n name = 'singleOrg';\n description = 'singleOrgDesc';\n type = PolicyType.SingleOrg;\n component = SingleOrgPolicyComponent;\n}\n\n@Component({\n selector: 'policy-single-org',\n templateUrl: 'single-org.component.html',\n})\nexport class SingleOrgPolicyComponent extends BasePolicyComponent {\n\n constructor(private i18nService: I18nService) {\n super();\n }\n\n buildRequest(policiesEnabledMap: Map): Promise {\n if (!this.enabled.value) {\n if (policiesEnabledMap.get(PolicyType.RequireSso) ?? false) {\n throw new Error(this.i18nService.t('disableRequiredError', this.i18nService.t('requireSso')));\n }\n\n if (policiesEnabledMap.get(PolicyType.MaximumVaultTimeout) ?? false) {\n throw new Error(this.i18nService.t('disableRequiredError', this.i18nService.t('maximumVaultTimeoutLabel')));\n }\n }\n\n return super.buildRequest(policiesEnabledMap);\n }\n}\n"," {{'singleOrgPolicyWarning' | i18n}}
","import { Component } from '@angular/core';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { BasePolicy, BasePolicyComponent } from './base-policy.component';\n\nexport class TwoFactorAuthenticationPolicy extends BasePolicy {\n name = 'twoStepLogin';\n description = 'twoStepLoginPolicyDesc';\n type = PolicyType.TwoFactorAuthentication;\n component = TwoFactorAuthenticationPolicyComponent;\n}\n\n@Component({\n selector: 'policy-two-factor-authentication',\n templateUrl: 'two-factor-authentication.component.html',\n})\nexport class TwoFactorAuthenticationPolicyComponent extends BasePolicyComponent {\n}\n"," {{'twoStepLoginPolicyWarning' | i18n}}
","import { Component } from '@angular/core';\nimport { FormBuilder } from '@angular/forms';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { PolicyRequest } from 'jslib-common/models/request/policyRequest';\n\nimport { BasePolicy, BasePolicyComponent } from 'src/app/organizations/policies/base-policy.component';\n\nexport class DisablePersonalVaultExportPolicy extends BasePolicy {\n name = 'disablePersonalVaultExport';\n description = 'disablePersonalVaultExportDesc';\n type = PolicyType.DisablePersonalVaultExport;\n component = DisablePersonalVaultExportPolicyComponent;\n}\n\n@Component({\n selector: 'policy-disable-personal-vault-export',\n templateUrl: 'disable-personal-vault-export.component.html',\n})\nexport class DisablePersonalVaultExportPolicyComponent extends BasePolicyComponent {\n}\n","
","import { Component } from '@angular/core';\nimport { FormBuilder } from '@angular/forms';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\nimport { PolicyRequest } from 'jslib-common/models/request/policyRequest';\n\nimport { BasePolicy, BasePolicyComponent } from 'src/app/organizations/policies/base-policy.component';\n\nexport class MaximumVaultTimeoutPolicy extends BasePolicy {\n name = 'maximumVaultTimeout';\n description = 'maximumVaultTimeoutDesc';\n type = PolicyType.MaximumVaultTimeout;\n component = MaximumVaultTimeoutPolicyComponent;\n}\n\n@Component({\n selector: 'policy-maximum-timeout',\n templateUrl: 'maximum-vault-timeout.component.html',\n})\nexport class MaximumVaultTimeoutPolicyComponent extends BasePolicyComponent {\n\n data = this.fb.group({\n hours: [null],\n minutes: [null],\n });\n\n constructor(private fb: FormBuilder, private i18nService: I18nService) {\n super();\n }\n\n loadData() {\n const minutes = this.policyResponse.data?.minutes;\n\n if (minutes == null) {\n return;\n }\n\n this.data.patchValue({\n hours: Math.floor(minutes / 60),\n minutes: minutes % 60,\n });\n }\n\n buildRequestData() {\n if (this.data.value.hours == null && this.data.value.minutes == null) {\n return null;\n }\n\n return {\n minutes: this.data.value.hours * 60 + this.data.value.minutes,\n };\n }\n\n buildRequest(policiesEnabledMap: Map): Promise {\n const singleOrgEnabled = policiesEnabledMap.get(PolicyType.SingleOrg) ?? false;\n if (this.enabled.value && !singleOrgEnabled) {\n throw new Error(this.i18nService.t('requireSsoPolicyReqError'));\n }\n\n const data = this.buildRequestData();\n if (data?.minutes == null || data?.minutes <= 0) {\n throw new Error(this.i18nService.t('invalidMaximumVaultTimeout'));\n }\n\n return super.buildRequest(policiesEnabledMap);\n }\n}\n"," {{'requireSsoPolicyReq' | i18n}}
{{'hours' | i18n }}
{{'minutes' | i18n }}
","import {\n Component,\n OnInit,\n} from '@angular/core';\nimport { FormBuilder } from '@angular/forms';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\n\nimport { OrganizationSsoRequest } from 'jslib-common/models/request/organization/organizationSsoRequest';\n\n@Component({\n selector: 'app-org-manage-sso',\n templateUrl: 'sso.component.html',\n})\nexport class SsoComponent implements OnInit {\n\n samlSigningAlgorithms = [\n 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',\n 'http://www.w3.org/2000/09/xmldsig#rsa-sha384',\n 'http://www.w3.org/2000/09/xmldsig#rsa-sha512',\n 'http://www.w3.org/2000/09/xmldsig#rsa-sha1',\n ];\n\n loading = true;\n organizationId: string;\n organization: Organization;\n formPromise: Promise;\n\n callbackPath: string;\n signedOutCallbackPath: string;\n spEntityId: string;\n spMetadataUrl: string;\n spAcsUrl: string;\n\n enabled = this.fb.control(false);\n data = this.fb.group({\n configType: [],\n\n keyConnectorEnabled: [],\n keyConnectorUrl: [],\n\n // OpenId\n authority: [],\n clientId: [],\n clientSecret: [],\n metadataAddress: [],\n redirectBehavior: [],\n getClaimsFromUserInfoEndpoint: [],\n additionalScopes: [],\n additionalUserIdClaimTypes: [],\n additionalEmailClaimTypes: [],\n additionalNameClaimTypes: [],\n acrValues: [],\n expectedReturnAcrValue: [],\n\n // SAML\n spNameIdFormat: [],\n spOutboundSigningAlgorithm: [],\n spSigningBehavior: [],\n spMinIncomingSigningAlgorithm: [],\n spWantAssertionsSigned: [],\n spValidateCertificates: [],\n\n idpEntityId: [],\n idpBindingType: [],\n idpSingleSignOnServiceUrl: [],\n idpSingleLogoutServiceUrl: [],\n idpArtifactResolutionServiceUrl: [],\n idpX509PublicCert: [],\n idpOutboundSigningAlgorithm: [],\n idpAllowUnsolicitedAuthnResponse: [],\n idpDisableOutboundLogoutRequests: [],\n idpWantAuthnRequestsSigned: [],\n });\n\n constructor(private fb: FormBuilder, private route: ActivatedRoute, private apiService: ApiService,\n private platformUtilsService: PlatformUtilsService, private i18nService: I18nService,\n private userService: UserService) { }\n\n async ngOnInit() {\n this.route.parent.parent.params.subscribe(async params => {\n this.organizationId = params.organizationId;\n await this.load();\n });\n }\n\n async load() {\n this.organization = await this.userService.getOrganization(this.organizationId);\n const ssoSettings = await this.apiService.getOrganizationSso(this.organizationId);\n\n this.data.patchValue(ssoSettings.data);\n this.enabled.setValue(ssoSettings.enabled);\n\n this.callbackPath = ssoSettings.urls.callbackPath;\n this.signedOutCallbackPath = ssoSettings.urls.signedOutCallbackPath;\n this.spEntityId = ssoSettings.urls.spEntityId;\n this.spMetadataUrl = ssoSettings.urls.spMetadataUrl;\n this.spAcsUrl = ssoSettings.urls.spAcsUrl;\n\n this.keyConnectorUrl.markAsDirty();\n\n this.loading = false;\n }\n\n copy(value: string) {\n this.platformUtilsService.copyToClipboard(value);\n }\n\n launchUri(url: string) {\n this.platformUtilsService.launchUri(url);\n }\n\n async submit() {\n this.formPromise = this.postData();\n\n try {\n const response = await this.formPromise;\n\n this.data.patchValue(response.data);\n this.enabled.setValue(response.enabled);\n\n this.platformUtilsService.showToast('success', null, this.i18nService.t('ssoSettingsSaved'));\n } catch {\n // Logged by appApiAction, do nothing\n }\n\n this.formPromise = null;\n }\n\n async postData() {\n if (this.data.get('keyConnectorEnabled').value) {\n await this.validateKeyConnectorUrl();\n\n if (this.keyConnectorUrl.hasError('invalidUrl')) {\n throw new Error(this.i18nService.t('keyConnectorTestFail'));\n }\n }\n\n const request = new OrganizationSsoRequest();\n request.enabled = this.enabled.value;\n request.data = this.data.value;\n\n return this.apiService.postOrganizationSso(this.organizationId, request);\n }\n\n async validateKeyConnectorUrl() {\n if (this.keyConnectorUrl.pristine) {\n return;\n }\n\n this.keyConnectorUrl.markAsPending();\n\n try {\n await this.apiService.getKeyConnectorAlive(this.keyConnectorUrl.value);\n this.keyConnectorUrl.updateValueAndValidity();\n } catch {\n this.keyConnectorUrl.setErrors({\n invalidUrl: true,\n });\n }\n\n this.keyConnectorUrl.markAsPristine();\n }\n\n get enableTestKeyConnector() {\n return this.data.get('keyConnectorEnabled').value &&\n this.keyConnectorUrl != null &&\n this.keyConnectorUrl.value !== '';\n }\n\n get keyConnectorUrl() {\n return this.data.get('keyConnectorUrl');\n }\n}\n","

{{'singleSignOn' | i18n}}

{{'loading' | i18n}}

{{'ssoPolicyHelpStart' | i18n}} {{'ssoPolicyHelpLink' | i18n}} {{'ssoPolicyHelpEnd' | i18n}}
{{'ssoPolicyHelpKeyConnector' | i18n}}

{{'allowSsoDesc' | i18n}}
{{'keyConnectorWarning' | i18n}}
{{'keyConnectorTestFail' | i18n}}
{{'keyConnectorTestSuccess' | i18n}}

{{'openIdConnectConfig' | i18n}}

{{'samlSpConfig' | i18n}}

{{'samlIdpConfig' | i18n}}

","import { Injectable } from '@angular/core';\nimport {\n CanActivate,\n Router,\n} from '@angular/router';\n\nimport { UserService } from 'jslib-common/abstractions/user.service';\nimport { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';\n\n@Injectable()\nexport class LockGuardService implements CanActivate {\n\n protected homepage = 'vault';\n constructor(private vaultTimeoutService: VaultTimeoutService, private userService: UserService,\n private router: Router) { }\n\n async canActivate() {\n const isAuthed = await this.userService.isAuthenticated();\n if (isAuthed) {\n const locked = await this.vaultTimeoutService.isLocked();\n if (locked) {\n return true;\n } else {\n this.router.navigate([this.homepage]);\n return false;\n }\n }\n\n this.router.navigate(['']);\n return false;\n }\n}\n","import { Injectable } from '@angular/core';\nimport {\n ActivatedRouteSnapshot,\n CanActivate,\n Router,\n} from '@angular/router';\n\nimport { UserService } from 'jslib-common/abstractions/user.service';\nimport { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';\n\n@Injectable()\nexport class UnauthGuardService implements CanActivate {\n\n protected homepage = 'vault';\n constructor(private vaultTimeoutService: VaultTimeoutService, private userService: UserService,\n private router: Router) { }\n\n async canActivate() {\n const isAuthed = await this.userService.isAuthenticated();\n if (isAuthed) {\n const locked = await this.vaultTimeoutService.isLocked();\n if (locked) {\n this.router.navigate(['lock']);\n } else {\n this.router.navigate([this.homepage]);\n }\n return false;\n }\n\n return true;\n }\n}\n","import { BaseResponse } from './baseResponse';\nimport { SelectionReadOnlyResponse } from './selectionReadOnlyResponse';\n\nexport class CollectionResponse extends BaseResponse {\n id: string;\n organizationId: string;\n name: string;\n externalId: string;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.organizationId = this.getResponseProperty('OrganizationId');\n this.name = this.getResponseProperty('Name');\n this.externalId = this.getResponseProperty('ExternalId');\n }\n}\n\nexport class CollectionDetailsResponse extends CollectionResponse {\n readOnly: boolean;\n\n constructor(response: any) {\n super(response);\n this.readOnly = this.getResponseProperty('ReadOnly') || false;\n }\n}\n\nexport class CollectionGroupDetailsResponse extends CollectionResponse {\n groups: SelectionReadOnlyResponse[] = [];\n\n constructor(response: any) {\n super(response);\n const groups = this.getResponseProperty('Groups');\n if (groups != null) {\n this.groups = groups.map((g: any) => new SelectionReadOnlyResponse(g));\n }\n }\n}\n","import { BaseResponse } from './baseResponse';\nimport { GlobalDomainResponse } from './globalDomainResponse';\n\nexport class DomainsResponse extends BaseResponse {\n equivalentDomains: string[][];\n globalEquivalentDomains: GlobalDomainResponse[] = [];\n\n constructor(response: any) {\n super(response);\n this.equivalentDomains = this.getResponseProperty('EquivalentDomains');\n const globalEquivalentDomains = this.getResponseProperty('GlobalEquivalentDomains');\n if (globalEquivalentDomains != null) {\n this.globalEquivalentDomains = globalEquivalentDomains.map((d: any) => new GlobalDomainResponse(d));\n } else {\n this.globalEquivalentDomains = [];\n }\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class FolderResponse extends BaseResponse {\n id: string;\n name: string;\n revisionDate: string;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.name = this.getResponseProperty('Name');\n this.revisionDate = this.getResponseProperty('RevisionDate');\n }\n}\n","import { BaseResponse } from './baseResponse';\nimport { PlanResponse } from './planResponse';\n\nimport { PlanType } from '../../enums/planType';\n\nexport class OrganizationResponse extends BaseResponse {\n id: string;\n identifier: string;\n name: string;\n businessName: string;\n businessAddress1: string;\n businessAddress2: string;\n businessAddress3: string;\n businessCountry: string;\n businessTaxNumber: string;\n billingEmail: string;\n plan: PlanResponse;\n planType: PlanType;\n seats: number;\n maxAutoscaleSeats: number;\n maxCollections: number;\n maxStorageGb: number;\n useGroups: boolean;\n useDirectory: boolean;\n useEvents: boolean;\n useTotp: boolean;\n use2fa: boolean;\n useApi: boolean;\n useResetPassword: boolean;\n hasPublicAndPrivateKeys: boolean;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.identifier = this.getResponseProperty('Identifier');\n this.name = this.getResponseProperty('Name');\n this.businessName = this.getResponseProperty('BusinessName');\n this.businessAddress1 = this.getResponseProperty('BusinessAddress1');\n this.businessAddress2 = this.getResponseProperty('BusinessAddress2');\n this.businessAddress3 = this.getResponseProperty('BusinessAddress3');\n this.businessCountry = this.getResponseProperty('BusinessCountry');\n this.businessTaxNumber = this.getResponseProperty('BusinessTaxNumber');\n this.billingEmail = this.getResponseProperty('BillingEmail');\n const plan = this.getResponseProperty('Plan');\n this.plan = plan == null ? null : new PlanResponse(plan);\n this.planType = this.getResponseProperty('PlanType');\n this.seats = this.getResponseProperty('Seats');\n this.maxAutoscaleSeats = this.getResponseProperty('MaxAutoscaleSeats');\n this.maxCollections = this.getResponseProperty('MaxCollections');\n this.maxStorageGb = this.getResponseProperty('MaxStorageGb');\n this.useGroups = this.getResponseProperty('UseGroups');\n this.useDirectory = this.getResponseProperty('UseDirectory');\n this.useEvents = this.getResponseProperty('UseEvents');\n this.useTotp = this.getResponseProperty('UseTotp');\n this.use2fa = this.getResponseProperty('Use2fa');\n this.useApi = this.getResponseProperty('UseApi');\n this.useResetPassword = this.getResponseProperty('UseResetPassword');\n this.hasPublicAndPrivateKeys = this.getResponseProperty('HasPublicAndPrivateKeys');\n }\n}\n","import { PlanType } from '../../enums/planType';\nimport { ProductType } from '../../enums/productType';\n\nimport { BaseResponse } from './baseResponse';\n\nexport class PlanResponse extends BaseResponse {\n type: PlanType;\n product: ProductType;\n name: string;\n isAnnual: boolean;\n nameLocalizationKey: string;\n descriptionLocalizationKey: string;\n canBeUsedByBusiness: boolean;\n baseSeats: number;\n baseStorageGb: number;\n maxCollections: number;\n maxUsers: number;\n\n hasAdditionalSeatsOption: boolean;\n maxAdditionalSeats: number;\n hasAdditionalStorageOption: boolean;\n maxAdditionalStorage: number;\n hasPremiumAccessOption: boolean;\n trialPeriodDays: number;\n\n hasSelfHost: boolean;\n hasPolicies: boolean;\n hasGroups: boolean;\n hasDirectory: boolean;\n hasEvents: boolean;\n hasTotp: boolean;\n has2fa: boolean;\n hasApi: boolean;\n hasSso: boolean;\n hasResetPassword: boolean;\n usersGetPremium: boolean;\n\n upgradeSortOrder: number;\n displaySortOrder: number;\n legacyYear: number;\n disabled: boolean;\n\n stripePlanId: string;\n stripeSeatPlanId: string;\n stripeStoragePlanId: string;\n stripePremiumAccessPlanId: string;\n basePrice: number;\n seatPrice: number;\n additionalStoragePricePerGb: number;\n premiumAccessOptionPrice: number;\n\n constructor(response: any) {\n super(response);\n this.type = this.getResponseProperty('Type');\n this.product = this.getResponseProperty('Product');\n this.name = this.getResponseProperty('Name');\n this.isAnnual = this.getResponseProperty('IsAnnual');\n this.nameLocalizationKey = this.getResponseProperty('NameLocalizationKey');\n this.descriptionLocalizationKey = this.getResponseProperty('DescriptionLocalizationKey');\n this.canBeUsedByBusiness = this.getResponseProperty('CanBeUsedByBusiness');\n this.baseSeats = this.getResponseProperty('BaseSeats');\n this.baseStorageGb = this.getResponseProperty('BaseStorageGb');\n this.maxCollections = this.getResponseProperty('MaxCollections');\n this.maxUsers = this.getResponseProperty('MaxUsers');\n this.hasAdditionalSeatsOption = this.getResponseProperty('HasAdditionalSeatsOption');\n this.maxAdditionalSeats = this.getResponseProperty('MaxAdditionalSeats');\n this.hasAdditionalStorageOption = this.getResponseProperty('HasAdditionalStorageOption');\n this.maxAdditionalStorage = this.getResponseProperty('MaxAdditionalStorage');\n this.hasPremiumAccessOption = this.getResponseProperty('HasPremiumAccessOption');\n this.trialPeriodDays = this.getResponseProperty('TrialPeriodDays');\n this.hasSelfHost = this.getResponseProperty('HasSelfHost');\n this.hasPolicies = this.getResponseProperty('HasPolicies');\n this.hasGroups = this.getResponseProperty('HasGroups');\n this.hasDirectory = this.getResponseProperty('HasDirectory');\n this.hasEvents = this.getResponseProperty('HasEvents');\n this.hasTotp = this.getResponseProperty('HasTotp');\n this.has2fa = this.getResponseProperty('Has2fa');\n this.hasApi = this.getResponseProperty('HasApi');\n this.hasSso = this.getResponseProperty('HasSso');\n this.hasResetPassword = this.getResponseProperty('HasResetPassword');\n this.usersGetPremium = this.getResponseProperty('UsersGetPremium');\n this.upgradeSortOrder = this.getResponseProperty('UpgradeSortOrder');\n this.displaySortOrder = this.getResponseProperty('SortOrder');\n this.legacyYear = this.getResponseProperty('LegacyYear');\n this.disabled = this.getResponseProperty('Disabled');\n this.stripePlanId = this.getResponseProperty('StripePlanId');\n this.stripeSeatPlanId = this.getResponseProperty('StripeSeatPlanId');\n this.stripeStoragePlanId = this.getResponseProperty('StripeStoragePlanId');\n this.stripePremiumAccessPlanId = this.getResponseProperty('StripePremiumAccessPlanId');\n this.basePrice = this.getResponseProperty('BasePrice');\n this.seatPrice = this.getResponseProperty('SeatPrice');\n this.additionalStoragePricePerGb = this.getResponseProperty('AdditionalStoragePricePerGb');\n this.premiumAccessOptionPrice = this.getResponseProperty('PremiumAccessOptionPrice');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class SubscriptionResponse extends BaseResponse {\n storageName: string;\n storageGb: number;\n maxStorageGb: number;\n subscription: BillingSubscriptionResponse;\n upcomingInvoice: BillingSubscriptionUpcomingInvoiceResponse;\n license: any;\n expiration: string;\n usingInAppPurchase: boolean;\n\n constructor(response: any) {\n super(response);\n this.storageName = this.getResponseProperty('StorageName');\n this.storageGb = this.getResponseProperty('StorageGb');\n this.maxStorageGb = this.getResponseProperty('MaxStorageGb');\n this.license = this.getResponseProperty('License');\n this.expiration = this.getResponseProperty('Expiration');\n this.usingInAppPurchase = this.getResponseProperty('UsingInAppPurchase');\n const subscription = this.getResponseProperty('Subscription');\n const upcomingInvoice = this.getResponseProperty('UpcomingInvoice');\n this.subscription = subscription == null ? null : new BillingSubscriptionResponse(subscription);\n this.upcomingInvoice = upcomingInvoice == null ? null :\n new BillingSubscriptionUpcomingInvoiceResponse(upcomingInvoice);\n }\n}\n\nexport class BillingSubscriptionResponse extends BaseResponse {\n trialStartDate: string;\n trialEndDate: string;\n periodStartDate: string;\n periodEndDate: string;\n cancelledDate: string;\n cancelAtEndDate: boolean;\n status: string;\n cancelled: boolean;\n items: BillingSubscriptionItemResponse[] = [];\n\n constructor(response: any) {\n super(response);\n this.trialEndDate = this.getResponseProperty('TrialStartDate');\n this.trialEndDate = this.getResponseProperty('TrialEndDate');\n this.periodStartDate = this.getResponseProperty('PeriodStartDate');\n this.periodEndDate = this.getResponseProperty('PeriodEndDate');\n this.cancelledDate = this.getResponseProperty('CancelledDate');\n this.cancelAtEndDate = this.getResponseProperty('CancelAtEndDate');\n this.status = this.getResponseProperty('Status');\n this.cancelled = this.getResponseProperty('Cancelled');\n const items = this.getResponseProperty('Items');\n if (items != null) {\n this.items = items.map((i: any) => new BillingSubscriptionItemResponse(i));\n }\n }\n}\n\nexport class BillingSubscriptionItemResponse extends BaseResponse {\n name: string;\n amount: number;\n quantity: number;\n interval: string;\n sponsoredSubscriptionItem: boolean;\n\n constructor(response: any) {\n super(response);\n this.name = this.getResponseProperty('Name');\n this.amount = this.getResponseProperty('Amount');\n this.quantity = this.getResponseProperty('Quantity');\n this.interval = this.getResponseProperty('Interval');\n this.sponsoredSubscriptionItem = this.getResponseProperty('SponsoredSubscriptionItem');\n }\n}\n\nexport class BillingSubscriptionUpcomingInvoiceResponse extends BaseResponse {\n date: string;\n amount: number;\n\n constructor(response: any) {\n super(response);\n this.date = this.getResponseProperty('Date');\n this.amount = this.getResponseProperty('Amount');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class OrganizationUserBulkPublicKeyResponse extends BaseResponse {\n id: string;\n userId: string;\n key: string;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.userId = this.getResponseProperty('UserId');\n this.key = this.getResponseProperty('Key');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nimport { OrganizationUserStatusType } from '../../enums/organizationUserStatusType';\nimport { OrganizationUserType } from '../../enums/organizationUserType';\nimport { ProductType } from '../../enums/productType';\nimport { PermissionsApi } from '../api/permissionsApi';\n\nexport class ProfileOrganizationResponse extends BaseResponse {\n id: string;\n name: string;\n usePolicies: boolean;\n useGroups: boolean;\n useDirectory: boolean;\n useEvents: boolean;\n useTotp: boolean;\n use2fa: boolean;\n useApi: boolean;\n useSso: boolean;\n useKeyConnector: boolean;\n useResetPassword: boolean;\n selfHost: boolean;\n usersGetPremium: boolean;\n seats: number;\n maxCollections: number;\n maxStorageGb?: number;\n key: string;\n hasPublicAndPrivateKeys: boolean;\n status: OrganizationUserStatusType;\n type: OrganizationUserType;\n enabled: boolean;\n ssoBound: boolean;\n identifier: string;\n permissions: PermissionsApi;\n resetPasswordEnrolled: boolean;\n userId: string;\n providerId: string;\n providerName: string;\n familySponsorshipFriendlyName: string;\n familySponsorshipAvailable: boolean;\n planProductType: ProductType;\n keyConnectorEnabled: boolean;\n keyConnectorUrl: string;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.name = this.getResponseProperty('Name');\n this.usePolicies = this.getResponseProperty('UsePolicies');\n this.useGroups = this.getResponseProperty('UseGroups');\n this.useDirectory = this.getResponseProperty('UseDirectory');\n this.useEvents = this.getResponseProperty('UseEvents');\n this.useTotp = this.getResponseProperty('UseTotp');\n this.use2fa = this.getResponseProperty('Use2fa');\n this.useApi = this.getResponseProperty('UseApi');\n this.useSso = this.getResponseProperty('UseSso');\n this.useKeyConnector = this.getResponseProperty('UseKeyConnector') ?? false;\n this.useResetPassword = this.getResponseProperty('UseResetPassword');\n this.selfHost = this.getResponseProperty('SelfHost');\n this.usersGetPremium = this.getResponseProperty('UsersGetPremium');\n this.seats = this.getResponseProperty('Seats');\n this.maxCollections = this.getResponseProperty('MaxCollections');\n this.maxStorageGb = this.getResponseProperty('MaxStorageGb');\n this.key = this.getResponseProperty('Key');\n this.hasPublicAndPrivateKeys = this.getResponseProperty('HasPublicAndPrivateKeys');\n this.status = this.getResponseProperty('Status');\n this.type = this.getResponseProperty('Type');\n this.enabled = this.getResponseProperty('Enabled');\n this.ssoBound = this.getResponseProperty('SsoBound');\n this.identifier = this.getResponseProperty('Identifier');\n this.permissions = new PermissionsApi(this.getResponseProperty('permissions'));\n this.resetPasswordEnrolled = this.getResponseProperty('ResetPasswordEnrolled');\n this.userId = this.getResponseProperty('UserId');\n this.providerId = this.getResponseProperty('ProviderId');\n this.providerName = this.getResponseProperty('ProviderName');\n this.familySponsorshipFriendlyName = this.getResponseProperty('FamilySponsorshipFriendlyName');\n this.familySponsorshipAvailable = this.getResponseProperty('FamilySponsorshipAvailable');\n this.planProductType = this.getResponseProperty('PlanProductType');\n this.keyConnectorEnabled = this.getResponseProperty('KeyConnectorEnabled') ?? false;\n this.keyConnectorUrl = this.getResponseProperty('KeyConnectorUrl');\n }\n}\n","import { Utils } from '../../misc/utils';\nimport { BaseResponse } from './baseResponse';\n\nexport class TwoFactorWebAuthnResponse extends BaseResponse {\n enabled: boolean;\n keys: KeyResponse[];\n\n constructor(response: any) {\n super(response);\n this.enabled = this.getResponseProperty('Enabled');\n const keys = this.getResponseProperty('Keys');\n this.keys = keys == null ? null : keys.map((k: any) => new KeyResponse(k));\n }\n}\n\nexport class KeyResponse extends BaseResponse {\n name: string;\n id: number;\n migrated: boolean;\n\n constructor(response: any) {\n super(response);\n this.name = this.getResponseProperty('Name');\n this.id = this.getResponseProperty('Id');\n this.migrated = this.getResponseProperty('Migrated');\n }\n}\n\nexport class ChallengeResponse extends BaseResponse implements PublicKeyCredentialCreationOptions {\n attestation?: AttestationConveyancePreference;\n authenticatorSelection?: AuthenticatorSelectionCriteria;\n challenge: BufferSource;\n excludeCredentials?: PublicKeyCredentialDescriptor[];\n extensions?: AuthenticationExtensionsClientInputs;\n pubKeyCredParams: PublicKeyCredentialParameters[];\n rp: PublicKeyCredentialRpEntity;\n timeout?: number;\n user: PublicKeyCredentialUserEntity;\n\n constructor(response: any) {\n super(response);\n this.attestation = this.getResponseProperty('attestation');\n this.authenticatorSelection = this.getResponseProperty('authenticatorSelection');\n this.challenge = Utils.fromUrlB64ToArray(this.getResponseProperty('challenge'));\n this.excludeCredentials = this.getResponseProperty('excludeCredentials').map((c: any) => {\n c.id = Utils.fromUrlB64ToArray(c.id).buffer;\n return c;\n });\n this.extensions = this.getResponseProperty('extensions');\n this.pubKeyCredParams = this.getResponseProperty('pubKeyCredParams');\n this.rp = this.getResponseProperty('rp');\n this.timeout = this.getResponseProperty('timeout');\n\n const user = this.getResponseProperty('user');\n user.id = Utils.fromUrlB64ToArray(user.id);\n\n this.user = user;\n }\n}\n","/**\n * Use as a Decorator on async functions, it will prevent multiple 'active' calls as the same time\n *\n * If a promise was returned from a previous call to this function, that hasn't yet resolved it will\n * be returned, instead of calling the original function again\n *\n * Results are not cached, once the promise has returned, the next call will result in a fresh call\n *\n * Read more at https://github.com/bitwarden/jslib/pull/7\n */\nexport function sequentialize(cacheKey: (args: any[]) => string) {\n return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\n const originalMethod: () => Promise = descriptor.value;\n const caches = new Map>>();\n\n const getCache = (obj: any) => {\n let cache = caches.get(obj);\n if (cache != null) {\n return cache;\n }\n cache = new Map>();\n caches.set(obj, cache);\n return cache;\n };\n\n return {\n value: function(...args: any[]) {\n const cache = getCache(this);\n const argsCacheKey = cacheKey(args);\n let response = cache.get(argsCacheKey);\n if (response != null) {\n return response;\n }\n\n const onFinally = () => {\n cache.delete(argsCacheKey);\n if (cache.size === 0) {\n caches.delete(this);\n }\n };\n response = originalMethod.apply(this, args).then((val: any) => {\n onFinally();\n return val;\n }).catch((err: any) => {\n onFinally();\n throw err;\n });\n\n cache.set(argsCacheKey, response);\n return response;\n },\n };\n };\n}\n","import {\n ITreeNodeObject,\n TreeNode,\n} from '../models/domain/treeNode';\n\nexport class ServiceUtils {\n static nestedTraverse(nodeTree: TreeNode[], partIndex: number, parts: string[],\n obj: ITreeNodeObject, parent: ITreeNodeObject, delimiter: string) {\n if (parts.length <= partIndex) {\n return;\n }\n\n const end = partIndex === parts.length - 1;\n const partName = parts[partIndex];\n\n for (let i = 0; i < nodeTree.length; i++) {\n if (nodeTree[i].node.name !== parts[partIndex]) {\n continue;\n }\n if (end && nodeTree[i].node.id !== obj.id) {\n // Another node with the same name.\n nodeTree.push(new TreeNode(obj, partName, parent));\n return;\n }\n ServiceUtils.nestedTraverse(nodeTree[i].children, partIndex + 1, parts,\n obj, nodeTree[i].node, delimiter);\n return;\n }\n\n if (nodeTree.filter(n => n.node.name === partName).length === 0) {\n if (end) {\n nodeTree.push(new TreeNode(obj, partName, parent));\n return;\n }\n const newPartName = parts[partIndex] + delimiter + parts[partIndex + 1];\n ServiceUtils.nestedTraverse(nodeTree, 0, [newPartName, ...parts.slice(partIndex + 2)],\n obj, parent, delimiter);\n }\n }\n\n static getTreeNodeObject(nodeTree: TreeNode[], id: string): TreeNode {\n for (let i = 0; i < nodeTree.length; i++) {\n if (nodeTree[i].node.id === id) {\n return nodeTree[i];\n } else if (nodeTree[i].children != null) {\n const node = ServiceUtils.getTreeNodeObject(nodeTree[i].children, id);\n if (node !== null) {\n return node;\n }\n }\n }\n return null;\n }\n}\n","import { LogLevelType } from '../enums/logLevelType';\n\nimport { LogService as LogServiceAbstraction } from '../abstractions/log.service';\n\nimport * as hrtime from 'browser-hrtime';\n\nexport class ConsoleLogService implements LogServiceAbstraction {\n protected timersMap: Map = new Map();\n\n constructor(protected isDev: boolean, protected filter: (level: LogLevelType) => boolean = null) { }\n\n debug(message: string) {\n if (!this.isDev) {\n return;\n }\n this.write(LogLevelType.Debug, message);\n }\n\n info(message: string) {\n this.write(LogLevelType.Info, message);\n }\n\n warning(message: string) {\n this.write(LogLevelType.Warning, message);\n }\n\n error(message: string) {\n this.write(LogLevelType.Error, message);\n }\n\n write(level: LogLevelType, message: string) {\n if (this.filter != null && this.filter(level)) {\n return;\n }\n\n switch (level) {\n case LogLevelType.Debug:\n // tslint:disable-next-line\n console.log(message);\n break;\n case LogLevelType.Info:\n // tslint:disable-next-line\n console.log(message);\n break;\n case LogLevelType.Warning:\n // tslint:disable-next-line\n console.warn(message);\n break;\n case LogLevelType.Error:\n // tslint:disable-next-line\n console.error(message);\n break;\n default:\n break;\n }\n }\n\n time(label: string = 'default') {\n if (!this.timersMap.has(label)) {\n this.timersMap.set(label, hrtime());\n }\n }\n\n timeEnd(label: string = 'default'): [number, number] {\n const elapsed = hrtime(this.timersMap.get(label));\n this.timersMap.delete(label);\n this.write(LogLevelType.Info, `${label}: ${elapsed[0] * 1000 + elapsed[1] / 10e6}ms`);\n return elapsed;\n }\n}\n","// EFF's Long Wordlist from https://www.eff.org/dice\nexport const EEFLongWordList = [\n 'abacus',\n 'abdomen',\n 'abdominal',\n 'abide',\n 'abiding',\n 'ability',\n 'ablaze',\n 'able',\n 'abnormal',\n 'abrasion',\n 'abrasive',\n 'abreast',\n 'abridge',\n 'abroad',\n 'abruptly',\n 'absence',\n 'absentee',\n 'absently',\n 'absinthe',\n 'absolute',\n 'absolve',\n 'abstain',\n 'abstract',\n 'absurd',\n 'accent',\n 'acclaim',\n 'acclimate',\n 'accompany',\n 'account',\n 'accuracy',\n 'accurate',\n 'accustom',\n 'acetone',\n 'achiness',\n 'aching',\n 'acid',\n 'acorn',\n 'acquaint',\n 'acquire',\n 'acre',\n 'acrobat',\n 'acronym',\n 'acting',\n 'action',\n 'activate',\n 'activator',\n 'active',\n 'activism',\n 'activist',\n 'activity',\n 'actress',\n 'acts',\n 'acutely',\n 'acuteness',\n 'aeration',\n 'aerobics',\n 'aerosol',\n 'aerospace',\n 'afar',\n 'affair',\n 'affected',\n 'affecting',\n 'affection',\n 'affidavit',\n 'affiliate',\n 'affirm',\n 'affix',\n 'afflicted',\n 'affluent',\n 'afford',\n 'affront',\n 'aflame',\n 'afloat',\n 'aflutter',\n 'afoot',\n 'afraid',\n 'afterglow',\n 'afterlife',\n 'aftermath',\n 'aftermost',\n 'afternoon',\n 'aged',\n 'ageless',\n 'agency',\n 'agenda',\n 'agent',\n 'aggregate',\n 'aghast',\n 'agile',\n 'agility',\n 'aging',\n 'agnostic',\n 'agonize',\n 'agonizing',\n 'agony',\n 'agreeable',\n 'agreeably',\n 'agreed',\n 'agreeing',\n 'agreement',\n 'aground',\n 'ahead',\n 'ahoy',\n 'aide',\n 'aids',\n 'aim',\n 'ajar',\n 'alabaster',\n 'alarm',\n 'albatross',\n 'album',\n 'alfalfa',\n 'algebra',\n 'algorithm',\n 'alias',\n 'alibi',\n 'alienable',\n 'alienate',\n 'aliens',\n 'alike',\n 'alive',\n 'alkaline',\n 'alkalize',\n 'almanac',\n 'almighty',\n 'almost',\n 'aloe',\n 'aloft',\n 'aloha',\n 'alone',\n 'alongside',\n 'aloof',\n 'alphabet',\n 'alright',\n 'although',\n 'altitude',\n 'alto',\n 'aluminum',\n 'alumni',\n 'always',\n 'amaretto',\n 'amaze',\n 'amazingly',\n 'amber',\n 'ambiance',\n 'ambiguity',\n 'ambiguous',\n 'ambition',\n 'ambitious',\n 'ambulance',\n 'ambush',\n 'amendable',\n 'amendment',\n 'amends',\n 'amenity',\n 'amiable',\n 'amicably',\n 'amid',\n 'amigo',\n 'amino',\n 'amiss',\n 'ammonia',\n 'ammonium',\n 'amnesty',\n 'amniotic',\n 'among',\n 'amount',\n 'amperage',\n 'ample',\n 'amplifier',\n 'amplify',\n 'amply',\n 'amuck',\n 'amulet',\n 'amusable',\n 'amused',\n 'amusement',\n 'amuser',\n 'amusing',\n 'anaconda',\n 'anaerobic',\n 'anagram',\n 'anatomist',\n 'anatomy',\n 'anchor',\n 'anchovy',\n 'ancient',\n 'android',\n 'anemia',\n 'anemic',\n 'aneurism',\n 'anew',\n 'angelfish',\n 'angelic',\n 'anger',\n 'angled',\n 'angler',\n 'angles',\n 'angling',\n 'angrily',\n 'angriness',\n 'anguished',\n 'angular',\n 'animal',\n 'animate',\n 'animating',\n 'animation',\n 'animator',\n 'anime',\n 'animosity',\n 'ankle',\n 'annex',\n 'annotate',\n 'announcer',\n 'annoying',\n 'annually',\n 'annuity',\n 'anointer',\n 'another',\n 'answering',\n 'antacid',\n 'antarctic',\n 'anteater',\n 'antelope',\n 'antennae',\n 'anthem',\n 'anthill',\n 'anthology',\n 'antibody',\n 'antics',\n 'antidote',\n 'antihero',\n 'antiquely',\n 'antiques',\n 'antiquity',\n 'antirust',\n 'antitoxic',\n 'antitrust',\n 'antiviral',\n 'antivirus',\n 'antler',\n 'antonym',\n 'antsy',\n 'anvil',\n 'anybody',\n 'anyhow',\n 'anymore',\n 'anyone',\n 'anyplace',\n 'anything',\n 'anytime',\n 'anyway',\n 'anywhere',\n 'aorta',\n 'apache',\n 'apostle',\n 'appealing',\n 'appear',\n 'appease',\n 'appeasing',\n 'appendage',\n 'appendix',\n 'appetite',\n 'appetizer',\n 'applaud',\n 'applause',\n 'apple',\n 'appliance',\n 'applicant',\n 'applied',\n 'apply',\n 'appointee',\n 'appraisal',\n 'appraiser',\n 'apprehend',\n 'approach',\n 'approval',\n 'approve',\n 'apricot',\n 'april',\n 'apron',\n 'aptitude',\n 'aptly',\n 'aqua',\n 'aqueduct',\n 'arbitrary',\n 'arbitrate',\n 'ardently',\n 'area',\n 'arena',\n 'arguable',\n 'arguably',\n 'argue',\n 'arise',\n 'armadillo',\n 'armband',\n 'armchair',\n 'armed',\n 'armful',\n 'armhole',\n 'arming',\n 'armless',\n 'armoire',\n 'armored',\n 'armory',\n 'armrest',\n 'army',\n 'aroma',\n 'arose',\n 'around',\n 'arousal',\n 'arrange',\n 'array',\n 'arrest',\n 'arrival',\n 'arrive',\n 'arrogance',\n 'arrogant',\n 'arson',\n 'art',\n 'ascend',\n 'ascension',\n 'ascent',\n 'ascertain',\n 'ashamed',\n 'ashen',\n 'ashes',\n 'ashy',\n 'aside',\n 'askew',\n 'asleep',\n 'asparagus',\n 'aspect',\n 'aspirate',\n 'aspire',\n 'aspirin',\n 'astonish',\n 'astound',\n 'astride',\n 'astrology',\n 'astronaut',\n 'astronomy',\n 'astute',\n 'atlantic',\n 'atlas',\n 'atom',\n 'atonable',\n 'atop',\n 'atrium',\n 'atrocious',\n 'atrophy',\n 'attach',\n 'attain',\n 'attempt',\n 'attendant',\n 'attendee',\n 'attention',\n 'attentive',\n 'attest',\n 'attic',\n 'attire',\n 'attitude',\n 'attractor',\n 'attribute',\n 'atypical',\n 'auction',\n 'audacious',\n 'audacity',\n 'audible',\n 'audibly',\n 'audience',\n 'audio',\n 'audition',\n 'augmented',\n 'august',\n 'authentic',\n 'author',\n 'autism',\n 'autistic',\n 'autograph',\n 'automaker',\n 'automated',\n 'automatic',\n 'autopilot',\n 'available',\n 'avalanche',\n 'avatar',\n 'avenge',\n 'avenging',\n 'avenue',\n 'average',\n 'aversion',\n 'avert',\n 'aviation',\n 'aviator',\n 'avid',\n 'avoid',\n 'await',\n 'awaken',\n 'award',\n 'aware',\n 'awhile',\n 'awkward',\n 'awning',\n 'awoke',\n 'awry',\n 'axis',\n 'babble',\n 'babbling',\n 'babied',\n 'baboon',\n 'backache',\n 'backboard',\n 'backboned',\n 'backdrop',\n 'backed',\n 'backer',\n 'backfield',\n 'backfire',\n 'backhand',\n 'backing',\n 'backlands',\n 'backlash',\n 'backless',\n 'backlight',\n 'backlit',\n 'backlog',\n 'backpack',\n 'backpedal',\n 'backrest',\n 'backroom',\n 'backshift',\n 'backside',\n 'backslid',\n 'backspace',\n 'backspin',\n 'backstab',\n 'backstage',\n 'backtalk',\n 'backtrack',\n 'backup',\n 'backward',\n 'backwash',\n 'backwater',\n 'backyard',\n 'bacon',\n 'bacteria',\n 'bacterium',\n 'badass',\n 'badge',\n 'badland',\n 'badly',\n 'badness',\n 'baffle',\n 'baffling',\n 'bagel',\n 'bagful',\n 'baggage',\n 'bagged',\n 'baggie',\n 'bagginess',\n 'bagging',\n 'baggy',\n 'bagpipe',\n 'baguette',\n 'baked',\n 'bakery',\n 'bakeshop',\n 'baking',\n 'balance',\n 'balancing',\n 'balcony',\n 'balmy',\n 'balsamic',\n 'bamboo',\n 'banana',\n 'banish',\n 'banister',\n 'banjo',\n 'bankable',\n 'bankbook',\n 'banked',\n 'banker',\n 'banking',\n 'banknote',\n 'bankroll',\n 'banner',\n 'bannister',\n 'banshee',\n 'banter',\n 'barbecue',\n 'barbed',\n 'barbell',\n 'barber',\n 'barcode',\n 'barge',\n 'bargraph',\n 'barista',\n 'baritone',\n 'barley',\n 'barmaid',\n 'barman',\n 'barn',\n 'barometer',\n 'barrack',\n 'barracuda',\n 'barrel',\n 'barrette',\n 'barricade',\n 'barrier',\n 'barstool',\n 'bartender',\n 'barterer',\n 'bash',\n 'basically',\n 'basics',\n 'basil',\n 'basin',\n 'basis',\n 'basket',\n 'batboy',\n 'batch',\n 'bath',\n 'baton',\n 'bats',\n 'battalion',\n 'battered',\n 'battering',\n 'battery',\n 'batting',\n 'battle',\n 'bauble',\n 'bazooka',\n 'blabber',\n 'bladder',\n 'blade',\n 'blah',\n 'blame',\n 'blaming',\n 'blanching',\n 'blandness',\n 'blank',\n 'blaspheme',\n 'blasphemy',\n 'blast',\n 'blatancy',\n 'blatantly',\n 'blazer',\n 'blazing',\n 'bleach',\n 'bleak',\n 'bleep',\n 'blemish',\n 'blend',\n 'bless',\n 'blighted',\n 'blimp',\n 'bling',\n 'blinked',\n 'blinker',\n 'blinking',\n 'blinks',\n 'blip',\n 'blissful',\n 'blitz',\n 'blizzard',\n 'bloated',\n 'bloating',\n 'blob',\n 'blog',\n 'bloomers',\n 'blooming',\n 'blooper',\n 'blot',\n 'blouse',\n 'blubber',\n 'bluff',\n 'bluish',\n 'blunderer',\n 'blunt',\n 'blurb',\n 'blurred',\n 'blurry',\n 'blurt',\n 'blush',\n 'blustery',\n 'boaster',\n 'boastful',\n 'boasting',\n 'boat',\n 'bobbed',\n 'bobbing',\n 'bobble',\n 'bobcat',\n 'bobsled',\n 'bobtail',\n 'bodacious',\n 'body',\n 'bogged',\n 'boggle',\n 'bogus',\n 'boil',\n 'bok',\n 'bolster',\n 'bolt',\n 'bonanza',\n 'bonded',\n 'bonding',\n 'bondless',\n 'boned',\n 'bonehead',\n 'boneless',\n 'bonelike',\n 'boney',\n 'bonfire',\n 'bonnet',\n 'bonsai',\n 'bonus',\n 'bony',\n 'boogeyman',\n 'boogieman',\n 'book',\n 'boondocks',\n 'booted',\n 'booth',\n 'bootie',\n 'booting',\n 'bootlace',\n 'bootleg',\n 'boots',\n 'boozy',\n 'borax',\n 'boring',\n 'borough',\n 'borrower',\n 'borrowing',\n 'boss',\n 'botanical',\n 'botanist',\n 'botany',\n 'botch',\n 'both',\n 'bottle',\n 'bottling',\n 'bottom',\n 'bounce',\n 'bouncing',\n 'bouncy',\n 'bounding',\n 'boundless',\n 'bountiful',\n 'bovine',\n 'boxcar',\n 'boxer',\n 'boxing',\n 'boxlike',\n 'boxy',\n 'breach',\n 'breath',\n 'breeches',\n 'breeching',\n 'breeder',\n 'breeding',\n 'breeze',\n 'breezy',\n 'brethren',\n 'brewery',\n 'brewing',\n 'briar',\n 'bribe',\n 'brick',\n 'bride',\n 'bridged',\n 'brigade',\n 'bright',\n 'brilliant',\n 'brim',\n 'bring',\n 'brink',\n 'brisket',\n 'briskly',\n 'briskness',\n 'bristle',\n 'brittle',\n 'broadband',\n 'broadcast',\n 'broaden',\n 'broadly',\n 'broadness',\n 'broadside',\n 'broadways',\n 'broiler',\n 'broiling',\n 'broken',\n 'broker',\n 'bronchial',\n 'bronco',\n 'bronze',\n 'bronzing',\n 'brook',\n 'broom',\n 'brought',\n 'browbeat',\n 'brownnose',\n 'browse',\n 'browsing',\n 'bruising',\n 'brunch',\n 'brunette',\n 'brunt',\n 'brush',\n 'brussels',\n 'brute',\n 'brutishly',\n 'bubble',\n 'bubbling',\n 'bubbly',\n 'buccaneer',\n 'bucked',\n 'bucket',\n 'buckle',\n 'buckshot',\n 'buckskin',\n 'bucktooth',\n 'buckwheat',\n 'buddhism',\n 'buddhist',\n 'budding',\n 'buddy',\n 'budget',\n 'buffalo',\n 'buffed',\n 'buffer',\n 'buffing',\n 'buffoon',\n 'buggy',\n 'bulb',\n 'bulge',\n 'bulginess',\n 'bulgur',\n 'bulk',\n 'bulldog',\n 'bulldozer',\n 'bullfight',\n 'bullfrog',\n 'bullhorn',\n 'bullion',\n 'bullish',\n 'bullpen',\n 'bullring',\n 'bullseye',\n 'bullwhip',\n 'bully',\n 'bunch',\n 'bundle',\n 'bungee',\n 'bunion',\n 'bunkbed',\n 'bunkhouse',\n 'bunkmate',\n 'bunny',\n 'bunt',\n 'busboy',\n 'bush',\n 'busily',\n 'busload',\n 'bust',\n 'busybody',\n 'buzz',\n 'cabana',\n 'cabbage',\n 'cabbie',\n 'cabdriver',\n 'cable',\n 'caboose',\n 'cache',\n 'cackle',\n 'cacti',\n 'cactus',\n 'caddie',\n 'caddy',\n 'cadet',\n 'cadillac',\n 'cadmium',\n 'cage',\n 'cahoots',\n 'cake',\n 'calamari',\n 'calamity',\n 'calcium',\n 'calculate',\n 'calculus',\n 'caliber',\n 'calibrate',\n 'calm',\n 'caloric',\n 'calorie',\n 'calzone',\n 'camcorder',\n 'cameo',\n 'camera',\n 'camisole',\n 'camper',\n 'campfire',\n 'camping',\n 'campsite',\n 'campus',\n 'canal',\n 'canary',\n 'cancel',\n 'candied',\n 'candle',\n 'candy',\n 'cane',\n 'canine',\n 'canister',\n 'cannabis',\n 'canned',\n 'canning',\n 'cannon',\n 'cannot',\n 'canola',\n 'canon',\n 'canopener',\n 'canopy',\n 'canteen',\n 'canyon',\n 'capable',\n 'capably',\n 'capacity',\n 'cape',\n 'capillary',\n 'capital',\n 'capitol',\n 'capped',\n 'capricorn',\n 'capsize',\n 'capsule',\n 'caption',\n 'captivate',\n 'captive',\n 'captivity',\n 'capture',\n 'caramel',\n 'carat',\n 'caravan',\n 'carbon',\n 'cardboard',\n 'carded',\n 'cardiac',\n 'cardigan',\n 'cardinal',\n 'cardstock',\n 'carefully',\n 'caregiver',\n 'careless',\n 'caress',\n 'caretaker',\n 'cargo',\n 'caring',\n 'carless',\n 'carload',\n 'carmaker',\n 'carnage',\n 'carnation',\n 'carnival',\n 'carnivore',\n 'carol',\n 'carpenter',\n 'carpentry',\n 'carpool',\n 'carport',\n 'carried',\n 'carrot',\n 'carrousel',\n 'carry',\n 'cartel',\n 'cartload',\n 'carton',\n 'cartoon',\n 'cartridge',\n 'cartwheel',\n 'carve',\n 'carving',\n 'carwash',\n 'cascade',\n 'case',\n 'cash',\n 'casing',\n 'casino',\n 'casket',\n 'cassette',\n 'casually',\n 'casualty',\n 'catacomb',\n 'catalog',\n 'catalyst',\n 'catalyze',\n 'catapult',\n 'cataract',\n 'catatonic',\n 'catcall',\n 'catchable',\n 'catcher',\n 'catching',\n 'catchy',\n 'caterer',\n 'catering',\n 'catfight',\n 'catfish',\n 'cathedral',\n 'cathouse',\n 'catlike',\n 'catnap',\n 'catnip',\n 'catsup',\n 'cattail',\n 'cattishly',\n 'cattle',\n 'catty',\n 'catwalk',\n 'caucasian',\n 'caucus',\n 'causal',\n 'causation',\n 'cause',\n 'causing',\n 'cauterize',\n 'caution',\n 'cautious',\n 'cavalier',\n 'cavalry',\n 'caviar',\n 'cavity',\n 'cedar',\n 'celery',\n 'celestial',\n 'celibacy',\n 'celibate',\n 'celtic',\n 'cement',\n 'census',\n 'ceramics',\n 'ceremony',\n 'certainly',\n 'certainty',\n 'certified',\n 'certify',\n 'cesarean',\n 'cesspool',\n 'chafe',\n 'chaffing',\n 'chain',\n 'chair',\n 'chalice',\n 'challenge',\n 'chamber',\n 'chamomile',\n 'champion',\n 'chance',\n 'change',\n 'channel',\n 'chant',\n 'chaos',\n 'chaperone',\n 'chaplain',\n 'chapped',\n 'chaps',\n 'chapter',\n 'character',\n 'charbroil',\n 'charcoal',\n 'charger',\n 'charging',\n 'chariot',\n 'charity',\n 'charm',\n 'charred',\n 'charter',\n 'charting',\n 'chase',\n 'chasing',\n 'chaste',\n 'chastise',\n 'chastity',\n 'chatroom',\n 'chatter',\n 'chatting',\n 'chatty',\n 'cheating',\n 'cheddar',\n 'cheek',\n 'cheer',\n 'cheese',\n 'cheesy',\n 'chef',\n 'chemicals',\n 'chemist',\n 'chemo',\n 'cherisher',\n 'cherub',\n 'chess',\n 'chest',\n 'chevron',\n 'chevy',\n 'chewable',\n 'chewer',\n 'chewing',\n 'chewy',\n 'chief',\n 'chihuahua',\n 'childcare',\n 'childhood',\n 'childish',\n 'childless',\n 'childlike',\n 'chili',\n 'chill',\n 'chimp',\n 'chip',\n 'chirping',\n 'chirpy',\n 'chitchat',\n 'chivalry',\n 'chive',\n 'chloride',\n 'chlorine',\n 'choice',\n 'chokehold',\n 'choking',\n 'chomp',\n 'chooser',\n 'choosing',\n 'choosy',\n 'chop',\n 'chosen',\n 'chowder',\n 'chowtime',\n 'chrome',\n 'chubby',\n 'chuck',\n 'chug',\n 'chummy',\n 'chump',\n 'chunk',\n 'churn',\n 'chute',\n 'cider',\n 'cilantro',\n 'cinch',\n 'cinema',\n 'cinnamon',\n 'circle',\n 'circling',\n 'circular',\n 'circulate',\n 'circus',\n 'citable',\n 'citadel',\n 'citation',\n 'citizen',\n 'citric',\n 'citrus',\n 'city',\n 'civic',\n 'civil',\n 'clad',\n 'claim',\n 'clambake',\n 'clammy',\n 'clamor',\n 'clamp',\n 'clamshell',\n 'clang',\n 'clanking',\n 'clapped',\n 'clapper',\n 'clapping',\n 'clarify',\n 'clarinet',\n 'clarity',\n 'clash',\n 'clasp',\n 'class',\n 'clatter',\n 'clause',\n 'clavicle',\n 'claw',\n 'clay',\n 'clean',\n 'clear',\n 'cleat',\n 'cleaver',\n 'cleft',\n 'clench',\n 'clergyman',\n 'clerical',\n 'clerk',\n 'clever',\n 'clicker',\n 'client',\n 'climate',\n 'climatic',\n 'cling',\n 'clinic',\n 'clinking',\n 'clip',\n 'clique',\n 'cloak',\n 'clobber',\n 'clock',\n 'clone',\n 'cloning',\n 'closable',\n 'closure',\n 'clothes',\n 'clothing',\n 'cloud',\n 'clover',\n 'clubbed',\n 'clubbing',\n 'clubhouse',\n 'clump',\n 'clumsily',\n 'clumsy',\n 'clunky',\n 'clustered',\n 'clutch',\n 'clutter',\n 'coach',\n 'coagulant',\n 'coastal',\n 'coaster',\n 'coasting',\n 'coastland',\n 'coastline',\n 'coat',\n 'coauthor',\n 'cobalt',\n 'cobbler',\n 'cobweb',\n 'cocoa',\n 'coconut',\n 'cod',\n 'coeditor',\n 'coerce',\n 'coexist',\n 'coffee',\n 'cofounder',\n 'cognition',\n 'cognitive',\n 'cogwheel',\n 'coherence',\n 'coherent',\n 'cohesive',\n 'coil',\n 'coke',\n 'cola',\n 'cold',\n 'coleslaw',\n 'coliseum',\n 'collage',\n 'collapse',\n 'collar',\n 'collected',\n 'collector',\n 'collide',\n 'collie',\n 'collision',\n 'colonial',\n 'colonist',\n 'colonize',\n 'colony',\n 'colossal',\n 'colt',\n 'coma',\n 'come',\n 'comfort',\n 'comfy',\n 'comic',\n 'coming',\n 'comma',\n 'commence',\n 'commend',\n 'comment',\n 'commerce',\n 'commode',\n 'commodity',\n 'commodore',\n 'common',\n 'commotion',\n 'commute',\n 'commuting',\n 'compacted',\n 'compacter',\n 'compactly',\n 'compactor',\n 'companion',\n 'company',\n 'compare',\n 'compel',\n 'compile',\n 'comply',\n 'component',\n 'composed',\n 'composer',\n 'composite',\n 'compost',\n 'composure',\n 'compound',\n 'compress',\n 'comprised',\n 'computer',\n 'computing',\n 'comrade',\n 'concave',\n 'conceal',\n 'conceded',\n 'concept',\n 'concerned',\n 'concert',\n 'conch',\n 'concierge',\n 'concise',\n 'conclude',\n 'concrete',\n 'concur',\n 'condense',\n 'condiment',\n 'condition',\n 'condone',\n 'conducive',\n 'conductor',\n 'conduit',\n 'cone',\n 'confess',\n 'confetti',\n 'confidant',\n 'confident',\n 'confider',\n 'confiding',\n 'configure',\n 'confined',\n 'confining',\n 'confirm',\n 'conflict',\n 'conform',\n 'confound',\n 'confront',\n 'confused',\n 'confusing',\n 'confusion',\n 'congenial',\n 'congested',\n 'congrats',\n 'congress',\n 'conical',\n 'conjoined',\n 'conjure',\n 'conjuror',\n 'connected',\n 'connector',\n 'consensus',\n 'consent',\n 'console',\n 'consoling',\n 'consonant',\n 'constable',\n 'constant',\n 'constrain',\n 'constrict',\n 'construct',\n 'consult',\n 'consumer',\n 'consuming',\n 'contact',\n 'container',\n 'contempt',\n 'contend',\n 'contented',\n 'contently',\n 'contents',\n 'contest',\n 'context',\n 'contort',\n 'contour',\n 'contrite',\n 'control',\n 'contusion',\n 'convene',\n 'convent',\n 'copartner',\n 'cope',\n 'copied',\n 'copier',\n 'copilot',\n 'coping',\n 'copious',\n 'copper',\n 'copy',\n 'coral',\n 'cork',\n 'cornball',\n 'cornbread',\n 'corncob',\n 'cornea',\n 'corned',\n 'corner',\n 'cornfield',\n 'cornflake',\n 'cornhusk',\n 'cornmeal',\n 'cornstalk',\n 'corny',\n 'coronary',\n 'coroner',\n 'corporal',\n 'corporate',\n 'corral',\n 'correct',\n 'corridor',\n 'corrode',\n 'corroding',\n 'corrosive',\n 'corsage',\n 'corset',\n 'cortex',\n 'cosigner',\n 'cosmetics',\n 'cosmic',\n 'cosmos',\n 'cosponsor',\n 'cost',\n 'cottage',\n 'cotton',\n 'couch',\n 'cough',\n 'could',\n 'countable',\n 'countdown',\n 'counting',\n 'countless',\n 'country',\n 'county',\n 'courier',\n 'covenant',\n 'cover',\n 'coveted',\n 'coveting',\n 'coyness',\n 'cozily',\n 'coziness',\n 'cozy',\n 'crabbing',\n 'crabgrass',\n 'crablike',\n 'crabmeat',\n 'cradle',\n 'cradling',\n 'crafter',\n 'craftily',\n 'craftsman',\n 'craftwork',\n 'crafty',\n 'cramp',\n 'cranberry',\n 'crane',\n 'cranial',\n 'cranium',\n 'crank',\n 'crate',\n 'crave',\n 'craving',\n 'crawfish',\n 'crawlers',\n 'crawling',\n 'crayfish',\n 'crayon',\n 'crazed',\n 'crazily',\n 'craziness',\n 'crazy',\n 'creamed',\n 'creamer',\n 'creamlike',\n 'crease',\n 'creasing',\n 'creatable',\n 'create',\n 'creation',\n 'creative',\n 'creature',\n 'credible',\n 'credibly',\n 'credit',\n 'creed',\n 'creme',\n 'creole',\n 'crepe',\n 'crept',\n 'crescent',\n 'crested',\n 'cresting',\n 'crestless',\n 'crevice',\n 'crewless',\n 'crewman',\n 'crewmate',\n 'crib',\n 'cricket',\n 'cried',\n 'crier',\n 'crimp',\n 'crimson',\n 'cringe',\n 'cringing',\n 'crinkle',\n 'crinkly',\n 'crisped',\n 'crisping',\n 'crisply',\n 'crispness',\n 'crispy',\n 'criteria',\n 'critter',\n 'croak',\n 'crock',\n 'crook',\n 'croon',\n 'crop',\n 'cross',\n 'crouch',\n 'crouton',\n 'crowbar',\n 'crowd',\n 'crown',\n 'crucial',\n 'crudely',\n 'crudeness',\n 'cruelly',\n 'cruelness',\n 'cruelty',\n 'crumb',\n 'crummiest',\n 'crummy',\n 'crumpet',\n 'crumpled',\n 'cruncher',\n 'crunching',\n 'crunchy',\n 'crusader',\n 'crushable',\n 'crushed',\n 'crusher',\n 'crushing',\n 'crust',\n 'crux',\n 'crying',\n 'cryptic',\n 'crystal',\n 'cubbyhole',\n 'cube',\n 'cubical',\n 'cubicle',\n 'cucumber',\n 'cuddle',\n 'cuddly',\n 'cufflink',\n 'culinary',\n 'culminate',\n 'culpable',\n 'culprit',\n 'cultivate',\n 'cultural',\n 'culture',\n 'cupbearer',\n 'cupcake',\n 'cupid',\n 'cupped',\n 'cupping',\n 'curable',\n 'curator',\n 'curdle',\n 'cure',\n 'curfew',\n 'curing',\n 'curled',\n 'curler',\n 'curliness',\n 'curling',\n 'curly',\n 'curry',\n 'curse',\n 'cursive',\n 'cursor',\n 'curtain',\n 'curtly',\n 'curtsy',\n 'curvature',\n 'curve',\n 'curvy',\n 'cushy',\n 'cusp',\n 'cussed',\n 'custard',\n 'custodian',\n 'custody',\n 'customary',\n 'customer',\n 'customize',\n 'customs',\n 'cut',\n 'cycle',\n 'cyclic',\n 'cycling',\n 'cyclist',\n 'cylinder',\n 'cymbal',\n 'cytoplasm',\n 'cytoplast',\n 'dab',\n 'dad',\n 'daffodil',\n 'dagger',\n 'daily',\n 'daintily',\n 'dainty',\n 'dairy',\n 'daisy',\n 'dallying',\n 'dance',\n 'dancing',\n 'dandelion',\n 'dander',\n 'dandruff',\n 'dandy',\n 'danger',\n 'dangle',\n 'dangling',\n 'daredevil',\n 'dares',\n 'daringly',\n 'darkened',\n 'darkening',\n 'darkish',\n 'darkness',\n 'darkroom',\n 'darling',\n 'darn',\n 'dart',\n 'darwinism',\n 'dash',\n 'dastardly',\n 'data',\n 'datebook',\n 'dating',\n 'daughter',\n 'daunting',\n 'dawdler',\n 'dawn',\n 'daybed',\n 'daybreak',\n 'daycare',\n 'daydream',\n 'daylight',\n 'daylong',\n 'dayroom',\n 'daytime',\n 'dazzler',\n 'dazzling',\n 'deacon',\n 'deafening',\n 'deafness',\n 'dealer',\n 'dealing',\n 'dealmaker',\n 'dealt',\n 'dean',\n 'debatable',\n 'debate',\n 'debating',\n 'debit',\n 'debrief',\n 'debtless',\n 'debtor',\n 'debug',\n 'debunk',\n 'decade',\n 'decaf',\n 'decal',\n 'decathlon',\n 'decay',\n 'deceased',\n 'deceit',\n 'deceiver',\n 'deceiving',\n 'december',\n 'decency',\n 'decent',\n 'deception',\n 'deceptive',\n 'decibel',\n 'decidable',\n 'decimal',\n 'decimeter',\n 'decipher',\n 'deck',\n 'declared',\n 'decline',\n 'decode',\n 'decompose',\n 'decorated',\n 'decorator',\n 'decoy',\n 'decrease',\n 'decree',\n 'dedicate',\n 'dedicator',\n 'deduce',\n 'deduct',\n 'deed',\n 'deem',\n 'deepen',\n 'deeply',\n 'deepness',\n 'deface',\n 'defacing',\n 'defame',\n 'default',\n 'defeat',\n 'defection',\n 'defective',\n 'defendant',\n 'defender',\n 'defense',\n 'defensive',\n 'deferral',\n 'deferred',\n 'defiance',\n 'defiant',\n 'defile',\n 'defiling',\n 'define',\n 'definite',\n 'deflate',\n 'deflation',\n 'deflator',\n 'deflected',\n 'deflector',\n 'defog',\n 'deforest',\n 'defraud',\n 'defrost',\n 'deftly',\n 'defuse',\n 'defy',\n 'degraded',\n 'degrading',\n 'degrease',\n 'degree',\n 'dehydrate',\n 'deity',\n 'dejected',\n 'delay',\n 'delegate',\n 'delegator',\n 'delete',\n 'deletion',\n 'delicacy',\n 'delicate',\n 'delicious',\n 'delighted',\n 'delirious',\n 'delirium',\n 'deliverer',\n 'delivery',\n 'delouse',\n 'delta',\n 'deluge',\n 'delusion',\n 'deluxe',\n 'demanding',\n 'demeaning',\n 'demeanor',\n 'demise',\n 'democracy',\n 'democrat',\n 'demote',\n 'demotion',\n 'demystify',\n 'denatured',\n 'deniable',\n 'denial',\n 'denim',\n 'denote',\n 'dense',\n 'density',\n 'dental',\n 'dentist',\n 'denture',\n 'deny',\n 'deodorant',\n 'deodorize',\n 'departed',\n 'departure',\n 'depict',\n 'deplete',\n 'depletion',\n 'deplored',\n 'deploy',\n 'deport',\n 'depose',\n 'depraved',\n 'depravity',\n 'deprecate',\n 'depress',\n 'deprive',\n 'depth',\n 'deputize',\n 'deputy',\n 'derail',\n 'deranged',\n 'derby',\n 'derived',\n 'desecrate',\n 'deserve',\n 'deserving',\n 'designate',\n 'designed',\n 'designer',\n 'designing',\n 'deskbound',\n 'desktop',\n 'deskwork',\n 'desolate',\n 'despair',\n 'despise',\n 'despite',\n 'destiny',\n 'destitute',\n 'destruct',\n 'detached',\n 'detail',\n 'detection',\n 'detective',\n 'detector',\n 'detention',\n 'detergent',\n 'detest',\n 'detonate',\n 'detonator',\n 'detoxify',\n 'detract',\n 'deuce',\n 'devalue',\n 'deviancy',\n 'deviant',\n 'deviate',\n 'deviation',\n 'deviator',\n 'device',\n 'devious',\n 'devotedly',\n 'devotee',\n 'devotion',\n 'devourer',\n 'devouring',\n 'devoutly',\n 'dexterity',\n 'dexterous',\n 'diabetes',\n 'diabetic',\n 'diabolic',\n 'diagnoses',\n 'diagnosis',\n 'diagram',\n 'dial',\n 'diameter',\n 'diaper',\n 'diaphragm',\n 'diary',\n 'dice',\n 'dicing',\n 'dictate',\n 'dictation',\n 'dictator',\n 'difficult',\n 'diffused',\n 'diffuser',\n 'diffusion',\n 'diffusive',\n 'dig',\n 'dilation',\n 'diligence',\n 'diligent',\n 'dill',\n 'dilute',\n 'dime',\n 'diminish',\n 'dimly',\n 'dimmed',\n 'dimmer',\n 'dimness',\n 'dimple',\n 'diner',\n 'dingbat',\n 'dinghy',\n 'dinginess',\n 'dingo',\n 'dingy',\n 'dining',\n 'dinner',\n 'diocese',\n 'dioxide',\n 'diploma',\n 'dipped',\n 'dipper',\n 'dipping',\n 'directed',\n 'direction',\n 'directive',\n 'directly',\n 'directory',\n 'direness',\n 'dirtiness',\n 'disabled',\n 'disagree',\n 'disallow',\n 'disarm',\n 'disarray',\n 'disaster',\n 'disband',\n 'disbelief',\n 'disburse',\n 'discard',\n 'discern',\n 'discharge',\n 'disclose',\n 'discolor',\n 'discount',\n 'discourse',\n 'discover',\n 'discuss',\n 'disdain',\n 'disengage',\n 'disfigure',\n 'disgrace',\n 'dish',\n 'disinfect',\n 'disjoin',\n 'disk',\n 'dislike',\n 'disliking',\n 'dislocate',\n 'dislodge',\n 'disloyal',\n 'dismantle',\n 'dismay',\n 'dismiss',\n 'dismount',\n 'disobey',\n 'disorder',\n 'disown',\n 'disparate',\n 'disparity',\n 'dispatch',\n 'dispense',\n 'dispersal',\n 'dispersed',\n 'disperser',\n 'displace',\n 'display',\n 'displease',\n 'disposal',\n 'dispose',\n 'disprove',\n 'dispute',\n 'disregard',\n 'disrupt',\n 'dissuade',\n 'distance',\n 'distant',\n 'distaste',\n 'distill',\n 'distinct',\n 'distort',\n 'distract',\n 'distress',\n 'district',\n 'distrust',\n 'ditch',\n 'ditto',\n 'ditzy',\n 'dividable',\n 'divided',\n 'dividend',\n 'dividers',\n 'dividing',\n 'divinely',\n 'diving',\n 'divinity',\n 'divisible',\n 'divisibly',\n 'division',\n 'divisive',\n 'divorcee',\n 'dizziness',\n 'dizzy',\n 'doable',\n 'docile',\n 'dock',\n 'doctrine',\n 'document',\n 'dodge',\n 'dodgy',\n 'doily',\n 'doing',\n 'dole',\n 'dollar',\n 'dollhouse',\n 'dollop',\n 'dolly',\n 'dolphin',\n 'domain',\n 'domelike',\n 'domestic',\n 'dominion',\n 'dominoes',\n 'donated',\n 'donation',\n 'donator',\n 'donor',\n 'donut',\n 'doodle',\n 'doorbell',\n 'doorframe',\n 'doorknob',\n 'doorman',\n 'doormat',\n 'doornail',\n 'doorpost',\n 'doorstep',\n 'doorstop',\n 'doorway',\n 'doozy',\n 'dork',\n 'dormitory',\n 'dorsal',\n 'dosage',\n 'dose',\n 'dotted',\n 'doubling',\n 'douche',\n 'dove',\n 'down',\n 'dowry',\n 'doze',\n 'drab',\n 'dragging',\n 'dragonfly',\n 'dragonish',\n 'dragster',\n 'drainable',\n 'drainage',\n 'drained',\n 'drainer',\n 'drainpipe',\n 'dramatic',\n 'dramatize',\n 'drank',\n 'drapery',\n 'drastic',\n 'draw',\n 'dreaded',\n 'dreadful',\n 'dreadlock',\n 'dreamboat',\n 'dreamily',\n 'dreamland',\n 'dreamless',\n 'dreamlike',\n 'dreamt',\n 'dreamy',\n 'drearily',\n 'dreary',\n 'drench',\n 'dress',\n 'drew',\n 'dribble',\n 'dried',\n 'drier',\n 'drift',\n 'driller',\n 'drilling',\n 'drinkable',\n 'drinking',\n 'dripping',\n 'drippy',\n 'drivable',\n 'driven',\n 'driver',\n 'driveway',\n 'driving',\n 'drizzle',\n 'drizzly',\n 'drone',\n 'drool',\n 'droop',\n 'drop-down',\n 'dropbox',\n 'dropkick',\n 'droplet',\n 'dropout',\n 'dropper',\n 'drove',\n 'drown',\n 'drowsily',\n 'drudge',\n 'drum',\n 'dry',\n 'dubbed',\n 'dubiously',\n 'duchess',\n 'duckbill',\n 'ducking',\n 'duckling',\n 'ducktail',\n 'ducky',\n 'duct',\n 'dude',\n 'duffel',\n 'dugout',\n 'duh',\n 'duke',\n 'duller',\n 'dullness',\n 'duly',\n 'dumping',\n 'dumpling',\n 'dumpster',\n 'duo',\n 'dupe',\n 'duplex',\n 'duplicate',\n 'duplicity',\n 'durable',\n 'durably',\n 'duration',\n 'duress',\n 'during',\n 'dusk',\n 'dust',\n 'dutiful',\n 'duty',\n 'duvet',\n 'dwarf',\n 'dweeb',\n 'dwelled',\n 'dweller',\n 'dwelling',\n 'dwindle',\n 'dwindling',\n 'dynamic',\n 'dynamite',\n 'dynasty',\n 'dyslexia',\n 'dyslexic',\n 'each',\n 'eagle',\n 'earache',\n 'eardrum',\n 'earflap',\n 'earful',\n 'earlobe',\n 'early',\n 'earmark',\n 'earmuff',\n 'earphone',\n 'earpiece',\n 'earplugs',\n 'earring',\n 'earshot',\n 'earthen',\n 'earthlike',\n 'earthling',\n 'earthly',\n 'earthworm',\n 'earthy',\n 'earwig',\n 'easeful',\n 'easel',\n 'easiest',\n 'easily',\n 'easiness',\n 'easing',\n 'eastbound',\n 'eastcoast',\n 'easter',\n 'eastward',\n 'eatable',\n 'eaten',\n 'eatery',\n 'eating',\n 'eats',\n 'ebay',\n 'ebony',\n 'ebook',\n 'ecard',\n 'eccentric',\n 'echo',\n 'eclair',\n 'eclipse',\n 'ecologist',\n 'ecology',\n 'economic',\n 'economist',\n 'economy',\n 'ecosphere',\n 'ecosystem',\n 'edge',\n 'edginess',\n 'edging',\n 'edgy',\n 'edition',\n 'editor',\n 'educated',\n 'education',\n 'educator',\n 'eel',\n 'effective',\n 'effects',\n 'efficient',\n 'effort',\n 'eggbeater',\n 'egging',\n 'eggnog',\n 'eggplant',\n 'eggshell',\n 'egomaniac',\n 'egotism',\n 'egotistic',\n 'either',\n 'eject',\n 'elaborate',\n 'elastic',\n 'elated',\n 'elbow',\n 'eldercare',\n 'elderly',\n 'eldest',\n 'electable',\n 'election',\n 'elective',\n 'elephant',\n 'elevate',\n 'elevating',\n 'elevation',\n 'elevator',\n 'eleven',\n 'elf',\n 'eligible',\n 'eligibly',\n 'eliminate',\n 'elite',\n 'elitism',\n 'elixir',\n 'elk',\n 'ellipse',\n 'elliptic',\n 'elm',\n 'elongated',\n 'elope',\n 'eloquence',\n 'eloquent',\n 'elsewhere',\n 'elude',\n 'elusive',\n 'elves',\n 'email',\n 'embargo',\n 'embark',\n 'embassy',\n 'embattled',\n 'embellish',\n 'ember',\n 'embezzle',\n 'emblaze',\n 'emblem',\n 'embody',\n 'embolism',\n 'emboss',\n 'embroider',\n 'emcee',\n 'emerald',\n 'emergency',\n 'emission',\n 'emit',\n 'emote',\n 'emoticon',\n 'emotion',\n 'empathic',\n 'empathy',\n 'emperor',\n 'emphases',\n 'emphasis',\n 'emphasize',\n 'emphatic',\n 'empirical',\n 'employed',\n 'employee',\n 'employer',\n 'emporium',\n 'empower',\n 'emptier',\n 'emptiness',\n 'empty',\n 'emu',\n 'enable',\n 'enactment',\n 'enamel',\n 'enchanted',\n 'enchilada',\n 'encircle',\n 'enclose',\n 'enclosure',\n 'encode',\n 'encore',\n 'encounter',\n 'encourage',\n 'encroach',\n 'encrust',\n 'encrypt',\n 'endanger',\n 'endeared',\n 'endearing',\n 'ended',\n 'ending',\n 'endless',\n 'endnote',\n 'endocrine',\n 'endorphin',\n 'endorse',\n 'endowment',\n 'endpoint',\n 'endurable',\n 'endurance',\n 'enduring',\n 'energetic',\n 'energize',\n 'energy',\n 'enforced',\n 'enforcer',\n 'engaged',\n 'engaging',\n 'engine',\n 'engorge',\n 'engraved',\n 'engraver',\n 'engraving',\n 'engross',\n 'engulf',\n 'enhance',\n 'enigmatic',\n 'enjoyable',\n 'enjoyably',\n 'enjoyer',\n 'enjoying',\n 'enjoyment',\n 'enlarged',\n 'enlarging',\n 'enlighten',\n 'enlisted',\n 'enquirer',\n 'enrage',\n 'enrich',\n 'enroll',\n 'enslave',\n 'ensnare',\n 'ensure',\n 'entail',\n 'entangled',\n 'entering',\n 'entertain',\n 'enticing',\n 'entire',\n 'entitle',\n 'entity',\n 'entomb',\n 'entourage',\n 'entrap',\n 'entree',\n 'entrench',\n 'entrust',\n 'entryway',\n 'entwine',\n 'enunciate',\n 'envelope',\n 'enviable',\n 'enviably',\n 'envious',\n 'envision',\n 'envoy',\n 'envy',\n 'enzyme',\n 'epic',\n 'epidemic',\n 'epidermal',\n 'epidermis',\n 'epidural',\n 'epilepsy',\n 'epileptic',\n 'epilogue',\n 'epiphany',\n 'episode',\n 'equal',\n 'equate',\n 'equation',\n 'equator',\n 'equinox',\n 'equipment',\n 'equity',\n 'equivocal',\n 'eradicate',\n 'erasable',\n 'erased',\n 'eraser',\n 'erasure',\n 'ergonomic',\n 'errand',\n 'errant',\n 'erratic',\n 'error',\n 'erupt',\n 'escalate',\n 'escalator',\n 'escapable',\n 'escapade',\n 'escapist',\n 'escargot',\n 'eskimo',\n 'esophagus',\n 'espionage',\n 'espresso',\n 'esquire',\n 'essay',\n 'essence',\n 'essential',\n 'establish',\n 'estate',\n 'esteemed',\n 'estimate',\n 'estimator',\n 'estranged',\n 'estrogen',\n 'etching',\n 'eternal',\n 'eternity',\n 'ethanol',\n 'ether',\n 'ethically',\n 'ethics',\n 'euphemism',\n 'evacuate',\n 'evacuee',\n 'evade',\n 'evaluate',\n 'evaluator',\n 'evaporate',\n 'evasion',\n 'evasive',\n 'even',\n 'everglade',\n 'evergreen',\n 'everybody',\n 'everyday',\n 'everyone',\n 'evict',\n 'evidence',\n 'evident',\n 'evil',\n 'evoke',\n 'evolution',\n 'evolve',\n 'exact',\n 'exalted',\n 'example',\n 'excavate',\n 'excavator',\n 'exceeding',\n 'exception',\n 'excess',\n 'exchange',\n 'excitable',\n 'exciting',\n 'exclaim',\n 'exclude',\n 'excluding',\n 'exclusion',\n 'exclusive',\n 'excretion',\n 'excretory',\n 'excursion',\n 'excusable',\n 'excusably',\n 'excuse',\n 'exemplary',\n 'exemplify',\n 'exemption',\n 'exerciser',\n 'exert',\n 'exes',\n 'exfoliate',\n 'exhale',\n 'exhaust',\n 'exhume',\n 'exile',\n 'existing',\n 'exit',\n 'exodus',\n 'exonerate',\n 'exorcism',\n 'exorcist',\n 'expand',\n 'expanse',\n 'expansion',\n 'expansive',\n 'expectant',\n 'expedited',\n 'expediter',\n 'expel',\n 'expend',\n 'expenses',\n 'expensive',\n 'expert',\n 'expire',\n 'expiring',\n 'explain',\n 'expletive',\n 'explicit',\n 'explode',\n 'exploit',\n 'explore',\n 'exploring',\n 'exponent',\n 'exporter',\n 'exposable',\n 'expose',\n 'exposure',\n 'express',\n 'expulsion',\n 'exquisite',\n 'extended',\n 'extending',\n 'extent',\n 'extenuate',\n 'exterior',\n 'external',\n 'extinct',\n 'extortion',\n 'extradite',\n 'extras',\n 'extrovert',\n 'extrude',\n 'extruding',\n 'exuberant',\n 'fable',\n 'fabric',\n 'fabulous',\n 'facebook',\n 'facecloth',\n 'facedown',\n 'faceless',\n 'facelift',\n 'faceplate',\n 'faceted',\n 'facial',\n 'facility',\n 'facing',\n 'facsimile',\n 'faction',\n 'factoid',\n 'factor',\n 'factsheet',\n 'factual',\n 'faculty',\n 'fade',\n 'fading',\n 'failing',\n 'falcon',\n 'fall',\n 'false',\n 'falsify',\n 'fame',\n 'familiar',\n 'family',\n 'famine',\n 'famished',\n 'fanatic',\n 'fancied',\n 'fanciness',\n 'fancy',\n 'fanfare',\n 'fang',\n 'fanning',\n 'fantasize',\n 'fantastic',\n 'fantasy',\n 'fascism',\n 'fastball',\n 'faster',\n 'fasting',\n 'fastness',\n 'faucet',\n 'favorable',\n 'favorably',\n 'favored',\n 'favoring',\n 'favorite',\n 'fax',\n 'feast',\n 'federal',\n 'fedora',\n 'feeble',\n 'feed',\n 'feel',\n 'feisty',\n 'feline',\n 'felt-tip',\n 'feminine',\n 'feminism',\n 'feminist',\n 'feminize',\n 'femur',\n 'fence',\n 'fencing',\n 'fender',\n 'ferment',\n 'fernlike',\n 'ferocious',\n 'ferocity',\n 'ferret',\n 'ferris',\n 'ferry',\n 'fervor',\n 'fester',\n 'festival',\n 'festive',\n 'festivity',\n 'fetal',\n 'fetch',\n 'fever',\n 'fiber',\n 'fiction',\n 'fiddle',\n 'fiddling',\n 'fidelity',\n 'fidgeting',\n 'fidgety',\n 'fifteen',\n 'fifth',\n 'fiftieth',\n 'fifty',\n 'figment',\n 'figure',\n 'figurine',\n 'filing',\n 'filled',\n 'filler',\n 'filling',\n 'film',\n 'filter',\n 'filth',\n 'filtrate',\n 'finale',\n 'finalist',\n 'finalize',\n 'finally',\n 'finance',\n 'financial',\n 'finch',\n 'fineness',\n 'finer',\n 'finicky',\n 'finished',\n 'finisher',\n 'finishing',\n 'finite',\n 'finless',\n 'finlike',\n 'fiscally',\n 'fit',\n 'five',\n 'flaccid',\n 'flagman',\n 'flagpole',\n 'flagship',\n 'flagstick',\n 'flagstone',\n 'flail',\n 'flakily',\n 'flaky',\n 'flame',\n 'flammable',\n 'flanked',\n 'flanking',\n 'flannels',\n 'flap',\n 'flaring',\n 'flashback',\n 'flashbulb',\n 'flashcard',\n 'flashily',\n 'flashing',\n 'flashy',\n 'flask',\n 'flatbed',\n 'flatfoot',\n 'flatly',\n 'flatness',\n 'flatten',\n 'flattered',\n 'flatterer',\n 'flattery',\n 'flattop',\n 'flatware',\n 'flatworm',\n 'flavored',\n 'flavorful',\n 'flavoring',\n 'flaxseed',\n 'fled',\n 'fleshed',\n 'fleshy',\n 'flick',\n 'flier',\n 'flight',\n 'flinch',\n 'fling',\n 'flint',\n 'flip',\n 'flirt',\n 'float',\n 'flock',\n 'flogging',\n 'flop',\n 'floral',\n 'florist',\n 'floss',\n 'flounder',\n 'flyable',\n 'flyaway',\n 'flyer',\n 'flying',\n 'flyover',\n 'flypaper',\n 'foam',\n 'foe',\n 'fog',\n 'foil',\n 'folic',\n 'folk',\n 'follicle',\n 'follow',\n 'fondling',\n 'fondly',\n 'fondness',\n 'fondue',\n 'font',\n 'food',\n 'fool',\n 'footage',\n 'football',\n 'footbath',\n 'footboard',\n 'footer',\n 'footgear',\n 'foothill',\n 'foothold',\n 'footing',\n 'footless',\n 'footman',\n 'footnote',\n 'footpad',\n 'footpath',\n 'footprint',\n 'footrest',\n 'footsie',\n 'footsore',\n 'footwear',\n 'footwork',\n 'fossil',\n 'foster',\n 'founder',\n 'founding',\n 'fountain',\n 'fox',\n 'foyer',\n 'fraction',\n 'fracture',\n 'fragile',\n 'fragility',\n 'fragment',\n 'fragrance',\n 'fragrant',\n 'frail',\n 'frame',\n 'framing',\n 'frantic',\n 'fraternal',\n 'frayed',\n 'fraying',\n 'frays',\n 'freckled',\n 'freckles',\n 'freebase',\n 'freebee',\n 'freebie',\n 'freedom',\n 'freefall',\n 'freehand',\n 'freeing',\n 'freeload',\n 'freely',\n 'freemason',\n 'freeness',\n 'freestyle',\n 'freeware',\n 'freeway',\n 'freewill',\n 'freezable',\n 'freezing',\n 'freight',\n 'french',\n 'frenzied',\n 'frenzy',\n 'frequency',\n 'frequent',\n 'fresh',\n 'fretful',\n 'fretted',\n 'friction',\n 'friday',\n 'fridge',\n 'fried',\n 'friend',\n 'frighten',\n 'frightful',\n 'frigidity',\n 'frigidly',\n 'frill',\n 'fringe',\n 'frisbee',\n 'frisk',\n 'fritter',\n 'frivolous',\n 'frolic',\n 'from',\n 'front',\n 'frostbite',\n 'frosted',\n 'frostily',\n 'frosting',\n 'frostlike',\n 'frosty',\n 'froth',\n 'frown',\n 'frozen',\n 'fructose',\n 'frugality',\n 'frugally',\n 'fruit',\n 'frustrate',\n 'frying',\n 'gab',\n 'gaffe',\n 'gag',\n 'gainfully',\n 'gaining',\n 'gains',\n 'gala',\n 'gallantly',\n 'galleria',\n 'gallery',\n 'galley',\n 'gallon',\n 'gallows',\n 'gallstone',\n 'galore',\n 'galvanize',\n 'gambling',\n 'game',\n 'gaming',\n 'gamma',\n 'gander',\n 'gangly',\n 'gangrene',\n 'gangway',\n 'gap',\n 'garage',\n 'garbage',\n 'garden',\n 'gargle',\n 'garland',\n 'garlic',\n 'garment',\n 'garnet',\n 'garnish',\n 'garter',\n 'gas',\n 'gatherer',\n 'gathering',\n 'gating',\n 'gauging',\n 'gauntlet',\n 'gauze',\n 'gave',\n 'gawk',\n 'gazing',\n 'gear',\n 'gecko',\n 'geek',\n 'geiger',\n 'gem',\n 'gender',\n 'generic',\n 'generous',\n 'genetics',\n 'genre',\n 'gentile',\n 'gentleman',\n 'gently',\n 'gents',\n 'geography',\n 'geologic',\n 'geologist',\n 'geology',\n 'geometric',\n 'geometry',\n 'geranium',\n 'gerbil',\n 'geriatric',\n 'germicide',\n 'germinate',\n 'germless',\n 'germproof',\n 'gestate',\n 'gestation',\n 'gesture',\n 'getaway',\n 'getting',\n 'getup',\n 'giant',\n 'gibberish',\n 'giblet',\n 'giddily',\n 'giddiness',\n 'giddy',\n 'gift',\n 'gigabyte',\n 'gigahertz',\n 'gigantic',\n 'giggle',\n 'giggling',\n 'giggly',\n 'gigolo',\n 'gilled',\n 'gills',\n 'gimmick',\n 'girdle',\n 'giveaway',\n 'given',\n 'giver',\n 'giving',\n 'gizmo',\n 'gizzard',\n 'glacial',\n 'glacier',\n 'glade',\n 'gladiator',\n 'gladly',\n 'glamorous',\n 'glamour',\n 'glance',\n 'glancing',\n 'glandular',\n 'glare',\n 'glaring',\n 'glass',\n 'glaucoma',\n 'glazing',\n 'gleaming',\n 'gleeful',\n 'glider',\n 'gliding',\n 'glimmer',\n 'glimpse',\n 'glisten',\n 'glitch',\n 'glitter',\n 'glitzy',\n 'gloater',\n 'gloating',\n 'gloomily',\n 'gloomy',\n 'glorified',\n 'glorifier',\n 'glorify',\n 'glorious',\n 'glory',\n 'gloss',\n 'glove',\n 'glowing',\n 'glowworm',\n 'glucose',\n 'glue',\n 'gluten',\n 'glutinous',\n 'glutton',\n 'gnarly',\n 'gnat',\n 'goal',\n 'goatskin',\n 'goes',\n 'goggles',\n 'going',\n 'goldfish',\n 'goldmine',\n 'goldsmith',\n 'golf',\n 'goliath',\n 'gonad',\n 'gondola',\n 'gone',\n 'gong',\n 'good',\n 'gooey',\n 'goofball',\n 'goofiness',\n 'goofy',\n 'google',\n 'goon',\n 'gopher',\n 'gore',\n 'gorged',\n 'gorgeous',\n 'gory',\n 'gosling',\n 'gossip',\n 'gothic',\n 'gotten',\n 'gout',\n 'gown',\n 'grab',\n 'graceful',\n 'graceless',\n 'gracious',\n 'gradation',\n 'graded',\n 'grader',\n 'gradient',\n 'grading',\n 'gradually',\n 'graduate',\n 'graffiti',\n 'grafted',\n 'grafting',\n 'grain',\n 'granddad',\n 'grandkid',\n 'grandly',\n 'grandma',\n 'grandpa',\n 'grandson',\n 'granite',\n 'granny',\n 'granola',\n 'grant',\n 'granular',\n 'grape',\n 'graph',\n 'grapple',\n 'grappling',\n 'grasp',\n 'grass',\n 'gratified',\n 'gratify',\n 'grating',\n 'gratitude',\n 'gratuity',\n 'gravel',\n 'graveness',\n 'graves',\n 'graveyard',\n 'gravitate',\n 'gravity',\n 'gravy',\n 'gray',\n 'grazing',\n 'greasily',\n 'greedily',\n 'greedless',\n 'greedy',\n 'green',\n 'greeter',\n 'greeting',\n 'grew',\n 'greyhound',\n 'grid',\n 'grief',\n 'grievance',\n 'grieving',\n 'grievous',\n 'grill',\n 'grimace',\n 'grimacing',\n 'grime',\n 'griminess',\n 'grimy',\n 'grinch',\n 'grinning',\n 'grip',\n 'gristle',\n 'grit',\n 'groggily',\n 'groggy',\n 'groin',\n 'groom',\n 'groove',\n 'grooving',\n 'groovy',\n 'grope',\n 'ground',\n 'grouped',\n 'grout',\n 'grove',\n 'grower',\n 'growing',\n 'growl',\n 'grub',\n 'grudge',\n 'grudging',\n 'grueling',\n 'gruffly',\n 'grumble',\n 'grumbling',\n 'grumbly',\n 'grumpily',\n 'grunge',\n 'grunt',\n 'guacamole',\n 'guidable',\n 'guidance',\n 'guide',\n 'guiding',\n 'guileless',\n 'guise',\n 'gulf',\n 'gullible',\n 'gully',\n 'gulp',\n 'gumball',\n 'gumdrop',\n 'gumminess',\n 'gumming',\n 'gummy',\n 'gurgle',\n 'gurgling',\n 'guru',\n 'gush',\n 'gusto',\n 'gusty',\n 'gutless',\n 'guts',\n 'gutter',\n 'guy',\n 'guzzler',\n 'gyration',\n 'habitable',\n 'habitant',\n 'habitat',\n 'habitual',\n 'hacked',\n 'hacker',\n 'hacking',\n 'hacksaw',\n 'had',\n 'haggler',\n 'haiku',\n 'half',\n 'halogen',\n 'halt',\n 'halved',\n 'halves',\n 'hamburger',\n 'hamlet',\n 'hammock',\n 'hamper',\n 'hamster',\n 'hamstring',\n 'handbag',\n 'handball',\n 'handbook',\n 'handbrake',\n 'handcart',\n 'handclap',\n 'handclasp',\n 'handcraft',\n 'handcuff',\n 'handed',\n 'handful',\n 'handgrip',\n 'handgun',\n 'handheld',\n 'handiness',\n 'handiwork',\n 'handlebar',\n 'handled',\n 'handler',\n 'handling',\n 'handmade',\n 'handoff',\n 'handpick',\n 'handprint',\n 'handrail',\n 'handsaw',\n 'handset',\n 'handsfree',\n 'handshake',\n 'handstand',\n 'handwash',\n 'handwork',\n 'handwoven',\n 'handwrite',\n 'handyman',\n 'hangnail',\n 'hangout',\n 'hangover',\n 'hangup',\n 'hankering',\n 'hankie',\n 'hanky',\n 'haphazard',\n 'happening',\n 'happier',\n 'happiest',\n 'happily',\n 'happiness',\n 'happy',\n 'harbor',\n 'hardcopy',\n 'hardcore',\n 'hardcover',\n 'harddisk',\n 'hardened',\n 'hardener',\n 'hardening',\n 'hardhat',\n 'hardhead',\n 'hardiness',\n 'hardly',\n 'hardness',\n 'hardship',\n 'hardware',\n 'hardwired',\n 'hardwood',\n 'hardy',\n 'harmful',\n 'harmless',\n 'harmonica',\n 'harmonics',\n 'harmonize',\n 'harmony',\n 'harness',\n 'harpist',\n 'harsh',\n 'harvest',\n 'hash',\n 'hassle',\n 'haste',\n 'hastily',\n 'hastiness',\n 'hasty',\n 'hatbox',\n 'hatchback',\n 'hatchery',\n 'hatchet',\n 'hatching',\n 'hatchling',\n 'hate',\n 'hatless',\n 'hatred',\n 'haunt',\n 'haven',\n 'hazard',\n 'hazelnut',\n 'hazily',\n 'haziness',\n 'hazing',\n 'hazy',\n 'headache',\n 'headband',\n 'headboard',\n 'headcount',\n 'headdress',\n 'headed',\n 'header',\n 'headfirst',\n 'headgear',\n 'heading',\n 'headlamp',\n 'headless',\n 'headlock',\n 'headphone',\n 'headpiece',\n 'headrest',\n 'headroom',\n 'headscarf',\n 'headset',\n 'headsman',\n 'headstand',\n 'headstone',\n 'headway',\n 'headwear',\n 'heap',\n 'heat',\n 'heave',\n 'heavily',\n 'heaviness',\n 'heaving',\n 'hedge',\n 'hedging',\n 'heftiness',\n 'hefty',\n 'helium',\n 'helmet',\n 'helper',\n 'helpful',\n 'helping',\n 'helpless',\n 'helpline',\n 'hemlock',\n 'hemstitch',\n 'hence',\n 'henchman',\n 'henna',\n 'herald',\n 'herbal',\n 'herbicide',\n 'herbs',\n 'heritage',\n 'hermit',\n 'heroics',\n 'heroism',\n 'herring',\n 'herself',\n 'hertz',\n 'hesitancy',\n 'hesitant',\n 'hesitate',\n 'hexagon',\n 'hexagram',\n 'hubcap',\n 'huddle',\n 'huddling',\n 'huff',\n 'hug',\n 'hula',\n 'hulk',\n 'hull',\n 'human',\n 'humble',\n 'humbling',\n 'humbly',\n 'humid',\n 'humiliate',\n 'humility',\n 'humming',\n 'hummus',\n 'humongous',\n 'humorist',\n 'humorless',\n 'humorous',\n 'humpback',\n 'humped',\n 'humvee',\n 'hunchback',\n 'hundredth',\n 'hunger',\n 'hungrily',\n 'hungry',\n 'hunk',\n 'hunter',\n 'hunting',\n 'huntress',\n 'huntsman',\n 'hurdle',\n 'hurled',\n 'hurler',\n 'hurling',\n 'hurray',\n 'hurricane',\n 'hurried',\n 'hurry',\n 'hurt',\n 'husband',\n 'hush',\n 'husked',\n 'huskiness',\n 'hut',\n 'hybrid',\n 'hydrant',\n 'hydrated',\n 'hydration',\n 'hydrogen',\n 'hydroxide',\n 'hyperlink',\n 'hypertext',\n 'hyphen',\n 'hypnoses',\n 'hypnosis',\n 'hypnotic',\n 'hypnotism',\n 'hypnotist',\n 'hypnotize',\n 'hypocrisy',\n 'hypocrite',\n 'ibuprofen',\n 'ice',\n 'iciness',\n 'icing',\n 'icky',\n 'icon',\n 'icy',\n 'idealism',\n 'idealist',\n 'idealize',\n 'ideally',\n 'idealness',\n 'identical',\n 'identify',\n 'identity',\n 'ideology',\n 'idiocy',\n 'idiom',\n 'idly',\n 'igloo',\n 'ignition',\n 'ignore',\n 'iguana',\n 'illicitly',\n 'illusion',\n 'illusive',\n 'image',\n 'imaginary',\n 'imagines',\n 'imaging',\n 'imbecile',\n 'imitate',\n 'imitation',\n 'immature',\n 'immerse',\n 'immersion',\n 'imminent',\n 'immobile',\n 'immodest',\n 'immorally',\n 'immortal',\n 'immovable',\n 'immovably',\n 'immunity',\n 'immunize',\n 'impaired',\n 'impale',\n 'impart',\n 'impatient',\n 'impeach',\n 'impeding',\n 'impending',\n 'imperfect',\n 'imperial',\n 'impish',\n 'implant',\n 'implement',\n 'implicate',\n 'implicit',\n 'implode',\n 'implosion',\n 'implosive',\n 'imply',\n 'impolite',\n 'important',\n 'importer',\n 'impose',\n 'imposing',\n 'impotence',\n 'impotency',\n 'impotent',\n 'impound',\n 'imprecise',\n 'imprint',\n 'imprison',\n 'impromptu',\n 'improper',\n 'improve',\n 'improving',\n 'improvise',\n 'imprudent',\n 'impulse',\n 'impulsive',\n 'impure',\n 'impurity',\n 'iodine',\n 'iodize',\n 'ion',\n 'ipad',\n 'iphone',\n 'ipod',\n 'irate',\n 'irk',\n 'iron',\n 'irregular',\n 'irrigate',\n 'irritable',\n 'irritably',\n 'irritant',\n 'irritate',\n 'islamic',\n 'islamist',\n 'isolated',\n 'isolating',\n 'isolation',\n 'isotope',\n 'issue',\n 'issuing',\n 'italicize',\n 'italics',\n 'item',\n 'itinerary',\n 'itunes',\n 'ivory',\n 'ivy',\n 'jab',\n 'jackal',\n 'jacket',\n 'jackknife',\n 'jackpot',\n 'jailbird',\n 'jailbreak',\n 'jailer',\n 'jailhouse',\n 'jalapeno',\n 'jam',\n 'janitor',\n 'january',\n 'jargon',\n 'jarring',\n 'jasmine',\n 'jaundice',\n 'jaunt',\n 'java',\n 'jawed',\n 'jawless',\n 'jawline',\n 'jaws',\n 'jaybird',\n 'jaywalker',\n 'jazz',\n 'jeep',\n 'jeeringly',\n 'jellied',\n 'jelly',\n 'jersey',\n 'jester',\n 'jet',\n 'jiffy',\n 'jigsaw',\n 'jimmy',\n 'jingle',\n 'jingling',\n 'jinx',\n 'jitters',\n 'jittery',\n 'job',\n 'jockey',\n 'jockstrap',\n 'jogger',\n 'jogging',\n 'john',\n 'joining',\n 'jokester',\n 'jokingly',\n 'jolliness',\n 'jolly',\n 'jolt',\n 'jot',\n 'jovial',\n 'joyfully',\n 'joylessly',\n 'joyous',\n 'joyride',\n 'joystick',\n 'jubilance',\n 'jubilant',\n 'judge',\n 'judgingly',\n 'judicial',\n 'judiciary',\n 'judo',\n 'juggle',\n 'juggling',\n 'jugular',\n 'juice',\n 'juiciness',\n 'juicy',\n 'jujitsu',\n 'jukebox',\n 'july',\n 'jumble',\n 'jumbo',\n 'jump',\n 'junction',\n 'juncture',\n 'june',\n 'junior',\n 'juniper',\n 'junkie',\n 'junkman',\n 'junkyard',\n 'jurist',\n 'juror',\n 'jury',\n 'justice',\n 'justifier',\n 'justify',\n 'justly',\n 'justness',\n 'juvenile',\n 'kabob',\n 'kangaroo',\n 'karaoke',\n 'karate',\n 'karma',\n 'kebab',\n 'keenly',\n 'keenness',\n 'keep',\n 'keg',\n 'kelp',\n 'kennel',\n 'kept',\n 'kerchief',\n 'kerosene',\n 'kettle',\n 'kick',\n 'kiln',\n 'kilobyte',\n 'kilogram',\n 'kilometer',\n 'kilowatt',\n 'kilt',\n 'kimono',\n 'kindle',\n 'kindling',\n 'kindly',\n 'kindness',\n 'kindred',\n 'kinetic',\n 'kinfolk',\n 'king',\n 'kinship',\n 'kinsman',\n 'kinswoman',\n 'kissable',\n 'kisser',\n 'kissing',\n 'kitchen',\n 'kite',\n 'kitten',\n 'kitty',\n 'kiwi',\n 'kleenex',\n 'knapsack',\n 'knee',\n 'knelt',\n 'knickers',\n 'knoll',\n 'koala',\n 'kooky',\n 'kosher',\n 'krypton',\n 'kudos',\n 'kung',\n 'labored',\n 'laborer',\n 'laboring',\n 'laborious',\n 'labrador',\n 'ladder',\n 'ladies',\n 'ladle',\n 'ladybug',\n 'ladylike',\n 'lagged',\n 'lagging',\n 'lagoon',\n 'lair',\n 'lake',\n 'lance',\n 'landed',\n 'landfall',\n 'landfill',\n 'landing',\n 'landlady',\n 'landless',\n 'landline',\n 'landlord',\n 'landmark',\n 'landmass',\n 'landmine',\n 'landowner',\n 'landscape',\n 'landside',\n 'landslide',\n 'language',\n 'lankiness',\n 'lanky',\n 'lantern',\n 'lapdog',\n 'lapel',\n 'lapped',\n 'lapping',\n 'laptop',\n 'lard',\n 'large',\n 'lark',\n 'lash',\n 'lasso',\n 'last',\n 'latch',\n 'late',\n 'lather',\n 'latitude',\n 'latrine',\n 'latter',\n 'latticed',\n 'launch',\n 'launder',\n 'laundry',\n 'laurel',\n 'lavender',\n 'lavish',\n 'laxative',\n 'lazily',\n 'laziness',\n 'lazy',\n 'lecturer',\n 'left',\n 'legacy',\n 'legal',\n 'legend',\n 'legged',\n 'leggings',\n 'legible',\n 'legibly',\n 'legislate',\n 'lego',\n 'legroom',\n 'legume',\n 'legwarmer',\n 'legwork',\n 'lemon',\n 'lend',\n 'length',\n 'lens',\n 'lent',\n 'leotard',\n 'lesser',\n 'letdown',\n 'lethargic',\n 'lethargy',\n 'letter',\n 'lettuce',\n 'level',\n 'leverage',\n 'levers',\n 'levitate',\n 'levitator',\n 'liability',\n 'liable',\n 'liberty',\n 'librarian',\n 'library',\n 'licking',\n 'licorice',\n 'lid',\n 'life',\n 'lifter',\n 'lifting',\n 'liftoff',\n 'ligament',\n 'likely',\n 'likeness',\n 'likewise',\n 'liking',\n 'lilac',\n 'lilly',\n 'lily',\n 'limb',\n 'limeade',\n 'limelight',\n 'limes',\n 'limit',\n 'limping',\n 'limpness',\n 'line',\n 'lingo',\n 'linguini',\n 'linguist',\n 'lining',\n 'linked',\n 'linoleum',\n 'linseed',\n 'lint',\n 'lion',\n 'lip',\n 'liquefy',\n 'liqueur',\n 'liquid',\n 'lisp',\n 'list',\n 'litigate',\n 'litigator',\n 'litmus',\n 'litter',\n 'little',\n 'livable',\n 'lived',\n 'lively',\n 'liver',\n 'livestock',\n 'lividly',\n 'living',\n 'lizard',\n 'lubricant',\n 'lubricate',\n 'lucid',\n 'luckily',\n 'luckiness',\n 'luckless',\n 'lucrative',\n 'ludicrous',\n 'lugged',\n 'lukewarm',\n 'lullaby',\n 'lumber',\n 'luminance',\n 'luminous',\n 'lumpiness',\n 'lumping',\n 'lumpish',\n 'lunacy',\n 'lunar',\n 'lunchbox',\n 'luncheon',\n 'lunchroom',\n 'lunchtime',\n 'lung',\n 'lurch',\n 'lure',\n 'luridness',\n 'lurk',\n 'lushly',\n 'lushness',\n 'luster',\n 'lustfully',\n 'lustily',\n 'lustiness',\n 'lustrous',\n 'lusty',\n 'luxurious',\n 'luxury',\n 'lying',\n 'lyrically',\n 'lyricism',\n 'lyricist',\n 'lyrics',\n 'macarena',\n 'macaroni',\n 'macaw',\n 'mace',\n 'machine',\n 'machinist',\n 'magazine',\n 'magenta',\n 'maggot',\n 'magical',\n 'magician',\n 'magma',\n 'magnesium',\n 'magnetic',\n 'magnetism',\n 'magnetize',\n 'magnifier',\n 'magnify',\n 'magnitude',\n 'magnolia',\n 'mahogany',\n 'maimed',\n 'majestic',\n 'majesty',\n 'majorette',\n 'majority',\n 'makeover',\n 'maker',\n 'makeshift',\n 'making',\n 'malformed',\n 'malt',\n 'mama',\n 'mammal',\n 'mammary',\n 'mammogram',\n 'manager',\n 'managing',\n 'manatee',\n 'mandarin',\n 'mandate',\n 'mandatory',\n 'mandolin',\n 'manger',\n 'mangle',\n 'mango',\n 'mangy',\n 'manhandle',\n 'manhole',\n 'manhood',\n 'manhunt',\n 'manicotti',\n 'manicure',\n 'manifesto',\n 'manila',\n 'mankind',\n 'manlike',\n 'manliness',\n 'manly',\n 'manmade',\n 'manned',\n 'mannish',\n 'manor',\n 'manpower',\n 'mantis',\n 'mantra',\n 'manual',\n 'many',\n 'map',\n 'marathon',\n 'marauding',\n 'marbled',\n 'marbles',\n 'marbling',\n 'march',\n 'mardi',\n 'margarine',\n 'margarita',\n 'margin',\n 'marigold',\n 'marina',\n 'marine',\n 'marital',\n 'maritime',\n 'marlin',\n 'marmalade',\n 'maroon',\n 'married',\n 'marrow',\n 'marry',\n 'marshland',\n 'marshy',\n 'marsupial',\n 'marvelous',\n 'marxism',\n 'mascot',\n 'masculine',\n 'mashed',\n 'mashing',\n 'massager',\n 'masses',\n 'massive',\n 'mastiff',\n 'matador',\n 'matchbook',\n 'matchbox',\n 'matcher',\n 'matching',\n 'matchless',\n 'material',\n 'maternal',\n 'maternity',\n 'math',\n 'mating',\n 'matriarch',\n 'matrimony',\n 'matrix',\n 'matron',\n 'matted',\n 'matter',\n 'maturely',\n 'maturing',\n 'maturity',\n 'mauve',\n 'maverick',\n 'maximize',\n 'maximum',\n 'maybe',\n 'mayday',\n 'mayflower',\n 'moaner',\n 'moaning',\n 'mobile',\n 'mobility',\n 'mobilize',\n 'mobster',\n 'mocha',\n 'mocker',\n 'mockup',\n 'modified',\n 'modify',\n 'modular',\n 'modulator',\n 'module',\n 'moisten',\n 'moistness',\n 'moisture',\n 'molar',\n 'molasses',\n 'mold',\n 'molecular',\n 'molecule',\n 'molehill',\n 'mollusk',\n 'mom',\n 'monastery',\n 'monday',\n 'monetary',\n 'monetize',\n 'moneybags',\n 'moneyless',\n 'moneywise',\n 'mongoose',\n 'mongrel',\n 'monitor',\n 'monkhood',\n 'monogamy',\n 'monogram',\n 'monologue',\n 'monopoly',\n 'monorail',\n 'monotone',\n 'monotype',\n 'monoxide',\n 'monsieur',\n 'monsoon',\n 'monstrous',\n 'monthly',\n 'monument',\n 'moocher',\n 'moodiness',\n 'moody',\n 'mooing',\n 'moonbeam',\n 'mooned',\n 'moonlight',\n 'moonlike',\n 'moonlit',\n 'moonrise',\n 'moonscape',\n 'moonshine',\n 'moonstone',\n 'moonwalk',\n 'mop',\n 'morale',\n 'morality',\n 'morally',\n 'morbidity',\n 'morbidly',\n 'morphine',\n 'morphing',\n 'morse',\n 'mortality',\n 'mortally',\n 'mortician',\n 'mortified',\n 'mortify',\n 'mortuary',\n 'mosaic',\n 'mossy',\n 'most',\n 'mothball',\n 'mothproof',\n 'motion',\n 'motivate',\n 'motivator',\n 'motive',\n 'motocross',\n 'motor',\n 'motto',\n 'mountable',\n 'mountain',\n 'mounted',\n 'mounting',\n 'mourner',\n 'mournful',\n 'mouse',\n 'mousiness',\n 'moustache',\n 'mousy',\n 'mouth',\n 'movable',\n 'move',\n 'movie',\n 'moving',\n 'mower',\n 'mowing',\n 'much',\n 'muck',\n 'mud',\n 'mug',\n 'mulberry',\n 'mulch',\n 'mule',\n 'mulled',\n 'mullets',\n 'multiple',\n 'multiply',\n 'multitask',\n 'multitude',\n 'mumble',\n 'mumbling',\n 'mumbo',\n 'mummified',\n 'mummify',\n 'mummy',\n 'mumps',\n 'munchkin',\n 'mundane',\n 'municipal',\n 'muppet',\n 'mural',\n 'murkiness',\n 'murky',\n 'murmuring',\n 'muscular',\n 'museum',\n 'mushily',\n 'mushiness',\n 'mushroom',\n 'mushy',\n 'music',\n 'musket',\n 'muskiness',\n 'musky',\n 'mustang',\n 'mustard',\n 'muster',\n 'mustiness',\n 'musty',\n 'mutable',\n 'mutate',\n 'mutation',\n 'mute',\n 'mutilated',\n 'mutilator',\n 'mutiny',\n 'mutt',\n 'mutual',\n 'muzzle',\n 'myself',\n 'myspace',\n 'mystified',\n 'mystify',\n 'myth',\n 'nacho',\n 'nag',\n 'nail',\n 'name',\n 'naming',\n 'nanny',\n 'nanometer',\n 'nape',\n 'napkin',\n 'napped',\n 'napping',\n 'nappy',\n 'narrow',\n 'nastily',\n 'nastiness',\n 'national',\n 'native',\n 'nativity',\n 'natural',\n 'nature',\n 'naturist',\n 'nautical',\n 'navigate',\n 'navigator',\n 'navy',\n 'nearby',\n 'nearest',\n 'nearly',\n 'nearness',\n 'neatly',\n 'neatness',\n 'nebula',\n 'nebulizer',\n 'nectar',\n 'negate',\n 'negation',\n 'negative',\n 'neglector',\n 'negligee',\n 'negligent',\n 'negotiate',\n 'nemeses',\n 'nemesis',\n 'neon',\n 'nephew',\n 'nerd',\n 'nervous',\n 'nervy',\n 'nest',\n 'net',\n 'neurology',\n 'neuron',\n 'neurosis',\n 'neurotic',\n 'neuter',\n 'neutron',\n 'never',\n 'next',\n 'nibble',\n 'nickname',\n 'nicotine',\n 'niece',\n 'nifty',\n 'nimble',\n 'nimbly',\n 'nineteen',\n 'ninetieth',\n 'ninja',\n 'nintendo',\n 'ninth',\n 'nuclear',\n 'nuclei',\n 'nucleus',\n 'nugget',\n 'nullify',\n 'number',\n 'numbing',\n 'numbly',\n 'numbness',\n 'numeral',\n 'numerate',\n 'numerator',\n 'numeric',\n 'numerous',\n 'nuptials',\n 'nursery',\n 'nursing',\n 'nurture',\n 'nutcase',\n 'nutlike',\n 'nutmeg',\n 'nutrient',\n 'nutshell',\n 'nuttiness',\n 'nutty',\n 'nuzzle',\n 'nylon',\n 'oaf',\n 'oak',\n 'oasis',\n 'oat',\n 'obedience',\n 'obedient',\n 'obituary',\n 'object',\n 'obligate',\n 'obliged',\n 'oblivion',\n 'oblivious',\n 'oblong',\n 'obnoxious',\n 'oboe',\n 'obscure',\n 'obscurity',\n 'observant',\n 'observer',\n 'observing',\n 'obsessed',\n 'obsession',\n 'obsessive',\n 'obsolete',\n 'obstacle',\n 'obstinate',\n 'obstruct',\n 'obtain',\n 'obtrusive',\n 'obtuse',\n 'obvious',\n 'occultist',\n 'occupancy',\n 'occupant',\n 'occupier',\n 'occupy',\n 'ocean',\n 'ocelot',\n 'octagon',\n 'octane',\n 'october',\n 'octopus',\n 'ogle',\n 'oil',\n 'oink',\n 'ointment',\n 'okay',\n 'old',\n 'olive',\n 'olympics',\n 'omega',\n 'omen',\n 'ominous',\n 'omission',\n 'omit',\n 'omnivore',\n 'onboard',\n 'oncoming',\n 'ongoing',\n 'onion',\n 'online',\n 'onlooker',\n 'only',\n 'onscreen',\n 'onset',\n 'onshore',\n 'onslaught',\n 'onstage',\n 'onto',\n 'onward',\n 'onyx',\n 'oops',\n 'ooze',\n 'oozy',\n 'opacity',\n 'opal',\n 'open',\n 'operable',\n 'operate',\n 'operating',\n 'operation',\n 'operative',\n 'operator',\n 'opium',\n 'opossum',\n 'opponent',\n 'oppose',\n 'opposing',\n 'opposite',\n 'oppressed',\n 'oppressor',\n 'opt',\n 'opulently',\n 'osmosis',\n 'other',\n 'otter',\n 'ouch',\n 'ought',\n 'ounce',\n 'outage',\n 'outback',\n 'outbid',\n 'outboard',\n 'outbound',\n 'outbreak',\n 'outburst',\n 'outcast',\n 'outclass',\n 'outcome',\n 'outdated',\n 'outdoors',\n 'outer',\n 'outfield',\n 'outfit',\n 'outflank',\n 'outgoing',\n 'outgrow',\n 'outhouse',\n 'outing',\n 'outlast',\n 'outlet',\n 'outline',\n 'outlook',\n 'outlying',\n 'outmatch',\n 'outmost',\n 'outnumber',\n 'outplayed',\n 'outpost',\n 'outpour',\n 'output',\n 'outrage',\n 'outrank',\n 'outreach',\n 'outright',\n 'outscore',\n 'outsell',\n 'outshine',\n 'outshoot',\n 'outsider',\n 'outskirts',\n 'outsmart',\n 'outsource',\n 'outspoken',\n 'outtakes',\n 'outthink',\n 'outward',\n 'outweigh',\n 'outwit',\n 'oval',\n 'ovary',\n 'oven',\n 'overact',\n 'overall',\n 'overarch',\n 'overbid',\n 'overbill',\n 'overbite',\n 'overblown',\n 'overboard',\n 'overbook',\n 'overbuilt',\n 'overcast',\n 'overcoat',\n 'overcome',\n 'overcook',\n 'overcrowd',\n 'overdraft',\n 'overdrawn',\n 'overdress',\n 'overdrive',\n 'overdue',\n 'overeager',\n 'overeater',\n 'overexert',\n 'overfed',\n 'overfeed',\n 'overfill',\n 'overflow',\n 'overfull',\n 'overgrown',\n 'overhand',\n 'overhang',\n 'overhaul',\n 'overhead',\n 'overhear',\n 'overheat',\n 'overhung',\n 'overjoyed',\n 'overkill',\n 'overlabor',\n 'overlaid',\n 'overlap',\n 'overlay',\n 'overload',\n 'overlook',\n 'overlord',\n 'overlying',\n 'overnight',\n 'overpass',\n 'overpay',\n 'overplant',\n 'overplay',\n 'overpower',\n 'overprice',\n 'overrate',\n 'overreach',\n 'overreact',\n 'override',\n 'overripe',\n 'overrule',\n 'overrun',\n 'overshoot',\n 'overshot',\n 'oversight',\n 'oversized',\n 'oversleep',\n 'oversold',\n 'overspend',\n 'overstate',\n 'overstay',\n 'overstep',\n 'overstock',\n 'overstuff',\n 'oversweet',\n 'overtake',\n 'overthrow',\n 'overtime',\n 'overtly',\n 'overtone',\n 'overture',\n 'overturn',\n 'overuse',\n 'overvalue',\n 'overview',\n 'overwrite',\n 'owl',\n 'oxford',\n 'oxidant',\n 'oxidation',\n 'oxidize',\n 'oxidizing',\n 'oxygen',\n 'oxymoron',\n 'oyster',\n 'ozone',\n 'paced',\n 'pacemaker',\n 'pacific',\n 'pacifier',\n 'pacifism',\n 'pacifist',\n 'pacify',\n 'padded',\n 'padding',\n 'paddle',\n 'paddling',\n 'padlock',\n 'pagan',\n 'pager',\n 'paging',\n 'pajamas',\n 'palace',\n 'palatable',\n 'palm',\n 'palpable',\n 'palpitate',\n 'paltry',\n 'pampered',\n 'pamperer',\n 'pampers',\n 'pamphlet',\n 'panama',\n 'pancake',\n 'pancreas',\n 'panda',\n 'pandemic',\n 'pang',\n 'panhandle',\n 'panic',\n 'panning',\n 'panorama',\n 'panoramic',\n 'panther',\n 'pantomime',\n 'pantry',\n 'pants',\n 'pantyhose',\n 'paparazzi',\n 'papaya',\n 'paper',\n 'paprika',\n 'papyrus',\n 'parabola',\n 'parachute',\n 'parade',\n 'paradox',\n 'paragraph',\n 'parakeet',\n 'paralegal',\n 'paralyses',\n 'paralysis',\n 'paralyze',\n 'paramedic',\n 'parameter',\n 'paramount',\n 'parasail',\n 'parasite',\n 'parasitic',\n 'parcel',\n 'parched',\n 'parchment',\n 'pardon',\n 'parish',\n 'parka',\n 'parking',\n 'parkway',\n 'parlor',\n 'parmesan',\n 'parole',\n 'parrot',\n 'parsley',\n 'parsnip',\n 'partake',\n 'parted',\n 'parting',\n 'partition',\n 'partly',\n 'partner',\n 'partridge',\n 'party',\n 'passable',\n 'passably',\n 'passage',\n 'passcode',\n 'passenger',\n 'passerby',\n 'passing',\n 'passion',\n 'passive',\n 'passivism',\n 'passover',\n 'passport',\n 'password',\n 'pasta',\n 'pasted',\n 'pastel',\n 'pastime',\n 'pastor',\n 'pastrami',\n 'pasture',\n 'pasty',\n 'patchwork',\n 'patchy',\n 'paternal',\n 'paternity',\n 'path',\n 'patience',\n 'patient',\n 'patio',\n 'patriarch',\n 'patriot',\n 'patrol',\n 'patronage',\n 'patronize',\n 'pauper',\n 'pavement',\n 'paver',\n 'pavestone',\n 'pavilion',\n 'paving',\n 'pawing',\n 'payable',\n 'payback',\n 'paycheck',\n 'payday',\n 'payee',\n 'payer',\n 'paying',\n 'payment',\n 'payphone',\n 'payroll',\n 'pebble',\n 'pebbly',\n 'pecan',\n 'pectin',\n 'peculiar',\n 'peddling',\n 'pediatric',\n 'pedicure',\n 'pedigree',\n 'pedometer',\n 'pegboard',\n 'pelican',\n 'pellet',\n 'pelt',\n 'pelvis',\n 'penalize',\n 'penalty',\n 'pencil',\n 'pendant',\n 'pending',\n 'penholder',\n 'penknife',\n 'pennant',\n 'penniless',\n 'penny',\n 'penpal',\n 'pension',\n 'pentagon',\n 'pentagram',\n 'pep',\n 'perceive',\n 'percent',\n 'perch',\n 'percolate',\n 'perennial',\n 'perfected',\n 'perfectly',\n 'perfume',\n 'periscope',\n 'perish',\n 'perjurer',\n 'perjury',\n 'perkiness',\n 'perky',\n 'perm',\n 'peroxide',\n 'perpetual',\n 'perplexed',\n 'persecute',\n 'persevere',\n 'persuaded',\n 'persuader',\n 'pesky',\n 'peso',\n 'pessimism',\n 'pessimist',\n 'pester',\n 'pesticide',\n 'petal',\n 'petite',\n 'petition',\n 'petri',\n 'petroleum',\n 'petted',\n 'petticoat',\n 'pettiness',\n 'petty',\n 'petunia',\n 'phantom',\n 'phobia',\n 'phoenix',\n 'phonebook',\n 'phoney',\n 'phonics',\n 'phoniness',\n 'phony',\n 'phosphate',\n 'photo',\n 'phrase',\n 'phrasing',\n 'placard',\n 'placate',\n 'placidly',\n 'plank',\n 'planner',\n 'plant',\n 'plasma',\n 'plaster',\n 'plastic',\n 'plated',\n 'platform',\n 'plating',\n 'platinum',\n 'platonic',\n 'platter',\n 'platypus',\n 'plausible',\n 'plausibly',\n 'playable',\n 'playback',\n 'player',\n 'playful',\n 'playgroup',\n 'playhouse',\n 'playing',\n 'playlist',\n 'playmaker',\n 'playmate',\n 'playoff',\n 'playpen',\n 'playroom',\n 'playset',\n 'plaything',\n 'playtime',\n 'plaza',\n 'pleading',\n 'pleat',\n 'pledge',\n 'plentiful',\n 'plenty',\n 'plethora',\n 'plexiglas',\n 'pliable',\n 'plod',\n 'plop',\n 'plot',\n 'plow',\n 'ploy',\n 'pluck',\n 'plug',\n 'plunder',\n 'plunging',\n 'plural',\n 'plus',\n 'plutonium',\n 'plywood',\n 'poach',\n 'pod',\n 'poem',\n 'poet',\n 'pogo',\n 'pointed',\n 'pointer',\n 'pointing',\n 'pointless',\n 'pointy',\n 'poise',\n 'poison',\n 'poker',\n 'poking',\n 'polar',\n 'police',\n 'policy',\n 'polio',\n 'polish',\n 'politely',\n 'polka',\n 'polo',\n 'polyester',\n 'polygon',\n 'polygraph',\n 'polymer',\n 'poncho',\n 'pond',\n 'pony',\n 'popcorn',\n 'pope',\n 'poplar',\n 'popper',\n 'poppy',\n 'popsicle',\n 'populace',\n 'popular',\n 'populate',\n 'porcupine',\n 'pork',\n 'porous',\n 'porridge',\n 'portable',\n 'portal',\n 'portfolio',\n 'porthole',\n 'portion',\n 'portly',\n 'portside',\n 'poser',\n 'posh',\n 'posing',\n 'possible',\n 'possibly',\n 'possum',\n 'postage',\n 'postal',\n 'postbox',\n 'postcard',\n 'posted',\n 'poster',\n 'posting',\n 'postnasal',\n 'posture',\n 'postwar',\n 'pouch',\n 'pounce',\n 'pouncing',\n 'pound',\n 'pouring',\n 'pout',\n 'powdered',\n 'powdering',\n 'powdery',\n 'power',\n 'powwow',\n 'pox',\n 'praising',\n 'prance',\n 'prancing',\n 'pranker',\n 'prankish',\n 'prankster',\n 'prayer',\n 'praying',\n 'preacher',\n 'preaching',\n 'preachy',\n 'preamble',\n 'precinct',\n 'precise',\n 'precision',\n 'precook',\n 'precut',\n 'predator',\n 'predefine',\n 'predict',\n 'preface',\n 'prefix',\n 'preflight',\n 'preformed',\n 'pregame',\n 'pregnancy',\n 'pregnant',\n 'preheated',\n 'prelaunch',\n 'prelaw',\n 'prelude',\n 'premiere',\n 'premises',\n 'premium',\n 'prenatal',\n 'preoccupy',\n 'preorder',\n 'prepaid',\n 'prepay',\n 'preplan',\n 'preppy',\n 'preschool',\n 'prescribe',\n 'preseason',\n 'preset',\n 'preshow',\n 'president',\n 'presoak',\n 'press',\n 'presume',\n 'presuming',\n 'preteen',\n 'pretended',\n 'pretender',\n 'pretense',\n 'pretext',\n 'pretty',\n 'pretzel',\n 'prevail',\n 'prevalent',\n 'prevent',\n 'preview',\n 'previous',\n 'prewar',\n 'prewashed',\n 'prideful',\n 'pried',\n 'primal',\n 'primarily',\n 'primary',\n 'primate',\n 'primer',\n 'primp',\n 'princess',\n 'print',\n 'prior',\n 'prism',\n 'prison',\n 'prissy',\n 'pristine',\n 'privacy',\n 'private',\n 'privatize',\n 'prize',\n 'proactive',\n 'probable',\n 'probably',\n 'probation',\n 'probe',\n 'probing',\n 'probiotic',\n 'problem',\n 'procedure',\n 'process',\n 'proclaim',\n 'procreate',\n 'procurer',\n 'prodigal',\n 'prodigy',\n 'produce',\n 'product',\n 'profane',\n 'profanity',\n 'professed',\n 'professor',\n 'profile',\n 'profound',\n 'profusely',\n 'progeny',\n 'prognosis',\n 'program',\n 'progress',\n 'projector',\n 'prologue',\n 'prolonged',\n 'promenade',\n 'prominent',\n 'promoter',\n 'promotion',\n 'prompter',\n 'promptly',\n 'prone',\n 'prong',\n 'pronounce',\n 'pronto',\n 'proofing',\n 'proofread',\n 'proofs',\n 'propeller',\n 'properly',\n 'property',\n 'proponent',\n 'proposal',\n 'propose',\n 'props',\n 'prorate',\n 'protector',\n 'protegee',\n 'proton',\n 'prototype',\n 'protozoan',\n 'protract',\n 'protrude',\n 'proud',\n 'provable',\n 'proved',\n 'proven',\n 'provided',\n 'provider',\n 'providing',\n 'province',\n 'proving',\n 'provoke',\n 'provoking',\n 'provolone',\n 'prowess',\n 'prowler',\n 'prowling',\n 'proximity',\n 'proxy',\n 'prozac',\n 'prude',\n 'prudishly',\n 'prune',\n 'pruning',\n 'pry',\n 'psychic',\n 'public',\n 'publisher',\n 'pucker',\n 'pueblo',\n 'pug',\n 'pull',\n 'pulmonary',\n 'pulp',\n 'pulsate',\n 'pulse',\n 'pulverize',\n 'puma',\n 'pumice',\n 'pummel',\n 'punch',\n 'punctual',\n 'punctuate',\n 'punctured',\n 'pungent',\n 'punisher',\n 'punk',\n 'pupil',\n 'puppet',\n 'puppy',\n 'purchase',\n 'pureblood',\n 'purebred',\n 'purely',\n 'pureness',\n 'purgatory',\n 'purge',\n 'purging',\n 'purifier',\n 'purify',\n 'purist',\n 'puritan',\n 'purity',\n 'purple',\n 'purplish',\n 'purposely',\n 'purr',\n 'purse',\n 'pursuable',\n 'pursuant',\n 'pursuit',\n 'purveyor',\n 'pushcart',\n 'pushchair',\n 'pusher',\n 'pushiness',\n 'pushing',\n 'pushover',\n 'pushpin',\n 'pushup',\n 'pushy',\n 'putdown',\n 'putt',\n 'puzzle',\n 'puzzling',\n 'pyramid',\n 'pyromania',\n 'python',\n 'quack',\n 'quadrant',\n 'quail',\n 'quaintly',\n 'quake',\n 'quaking',\n 'qualified',\n 'qualifier',\n 'qualify',\n 'quality',\n 'qualm',\n 'quantum',\n 'quarrel',\n 'quarry',\n 'quartered',\n 'quarterly',\n 'quarters',\n 'quartet',\n 'quench',\n 'query',\n 'quicken',\n 'quickly',\n 'quickness',\n 'quicksand',\n 'quickstep',\n 'quiet',\n 'quill',\n 'quilt',\n 'quintet',\n 'quintuple',\n 'quirk',\n 'quit',\n 'quiver',\n 'quizzical',\n 'quotable',\n 'quotation',\n 'quote',\n 'rabid',\n 'race',\n 'racing',\n 'racism',\n 'rack',\n 'racoon',\n 'radar',\n 'radial',\n 'radiance',\n 'radiantly',\n 'radiated',\n 'radiation',\n 'radiator',\n 'radio',\n 'radish',\n 'raffle',\n 'raft',\n 'rage',\n 'ragged',\n 'raging',\n 'ragweed',\n 'raider',\n 'railcar',\n 'railing',\n 'railroad',\n 'railway',\n 'raisin',\n 'rake',\n 'raking',\n 'rally',\n 'ramble',\n 'rambling',\n 'ramp',\n 'ramrod',\n 'ranch',\n 'rancidity',\n 'random',\n 'ranged',\n 'ranger',\n 'ranging',\n 'ranked',\n 'ranking',\n 'ransack',\n 'ranting',\n 'rants',\n 'rare',\n 'rarity',\n 'rascal',\n 'rash',\n 'rasping',\n 'ravage',\n 'raven',\n 'ravine',\n 'raving',\n 'ravioli',\n 'ravishing',\n 'reabsorb',\n 'reach',\n 'reacquire',\n 'reaction',\n 'reactive',\n 'reactor',\n 'reaffirm',\n 'ream',\n 'reanalyze',\n 'reappear',\n 'reapply',\n 'reappoint',\n 'reapprove',\n 'rearrange',\n 'rearview',\n 'reason',\n 'reassign',\n 'reassure',\n 'reattach',\n 'reawake',\n 'rebalance',\n 'rebate',\n 'rebel',\n 'rebirth',\n 'reboot',\n 'reborn',\n 'rebound',\n 'rebuff',\n 'rebuild',\n 'rebuilt',\n 'reburial',\n 'rebuttal',\n 'recall',\n 'recant',\n 'recapture',\n 'recast',\n 'recede',\n 'recent',\n 'recess',\n 'recharger',\n 'recipient',\n 'recital',\n 'recite',\n 'reckless',\n 'reclaim',\n 'recliner',\n 'reclining',\n 'recluse',\n 'reclusive',\n 'recognize',\n 'recoil',\n 'recollect',\n 'recolor',\n 'reconcile',\n 'reconfirm',\n 'reconvene',\n 'recopy',\n 'record',\n 'recount',\n 'recoup',\n 'recovery',\n 'recreate',\n 'rectal',\n 'rectangle',\n 'rectified',\n 'rectify',\n 'recycled',\n 'recycler',\n 'recycling',\n 'reemerge',\n 'reenact',\n 'reenter',\n 'reentry',\n 'reexamine',\n 'referable',\n 'referee',\n 'reference',\n 'refill',\n 'refinance',\n 'refined',\n 'refinery',\n 'refining',\n 'refinish',\n 'reflected',\n 'reflector',\n 'reflex',\n 'reflux',\n 'refocus',\n 'refold',\n 'reforest',\n 'reformat',\n 'reformed',\n 'reformer',\n 'reformist',\n 'refract',\n 'refrain',\n 'refreeze',\n 'refresh',\n 'refried',\n 'refueling',\n 'refund',\n 'refurbish',\n 'refurnish',\n 'refusal',\n 'refuse',\n 'refusing',\n 'refutable',\n 'refute',\n 'regain',\n 'regalia',\n 'regally',\n 'reggae',\n 'regime',\n 'region',\n 'register',\n 'registrar',\n 'registry',\n 'regress',\n 'regretful',\n 'regroup',\n 'regular',\n 'regulate',\n 'regulator',\n 'rehab',\n 'reheat',\n 'rehire',\n 'rehydrate',\n 'reimburse',\n 'reissue',\n 'reiterate',\n 'rejoice',\n 'rejoicing',\n 'rejoin',\n 'rekindle',\n 'relapse',\n 'relapsing',\n 'relatable',\n 'related',\n 'relation',\n 'relative',\n 'relax',\n 'relay',\n 'relearn',\n 'release',\n 'relenting',\n 'reliable',\n 'reliably',\n 'reliance',\n 'reliant',\n 'relic',\n 'relieve',\n 'relieving',\n 'relight',\n 'relish',\n 'relive',\n 'reload',\n 'relocate',\n 'relock',\n 'reluctant',\n 'rely',\n 'remake',\n 'remark',\n 'remarry',\n 'rematch',\n 'remedial',\n 'remedy',\n 'remember',\n 'reminder',\n 'remindful',\n 'remission',\n 'remix',\n 'remnant',\n 'remodeler',\n 'remold',\n 'remorse',\n 'remote',\n 'removable',\n 'removal',\n 'removed',\n 'remover',\n 'removing',\n 'rename',\n 'renderer',\n 'rendering',\n 'rendition',\n 'renegade',\n 'renewable',\n 'renewably',\n 'renewal',\n 'renewed',\n 'renounce',\n 'renovate',\n 'renovator',\n 'rentable',\n 'rental',\n 'rented',\n 'renter',\n 'reoccupy',\n 'reoccur',\n 'reopen',\n 'reorder',\n 'repackage',\n 'repacking',\n 'repaint',\n 'repair',\n 'repave',\n 'repaying',\n 'repayment',\n 'repeal',\n 'repeated',\n 'repeater',\n 'repent',\n 'rephrase',\n 'replace',\n 'replay',\n 'replica',\n 'reply',\n 'reporter',\n 'repose',\n 'repossess',\n 'repost',\n 'repressed',\n 'reprimand',\n 'reprint',\n 'reprise',\n 'reproach',\n 'reprocess',\n 'reproduce',\n 'reprogram',\n 'reps',\n 'reptile',\n 'reptilian',\n 'repugnant',\n 'repulsion',\n 'repulsive',\n 'repurpose',\n 'reputable',\n 'reputably',\n 'request',\n 'require',\n 'requisite',\n 'reroute',\n 'rerun',\n 'resale',\n 'resample',\n 'rescuer',\n 'reseal',\n 'research',\n 'reselect',\n 'reseller',\n 'resemble',\n 'resend',\n 'resent',\n 'reset',\n 'reshape',\n 'reshoot',\n 'reshuffle',\n 'residence',\n 'residency',\n 'resident',\n 'residual',\n 'residue',\n 'resigned',\n 'resilient',\n 'resistant',\n 'resisting',\n 'resize',\n 'resolute',\n 'resolved',\n 'resonant',\n 'resonate',\n 'resort',\n 'resource',\n 'respect',\n 'resubmit',\n 'result',\n 'resume',\n 'resupply',\n 'resurface',\n 'resurrect',\n 'retail',\n 'retainer',\n 'retaining',\n 'retake',\n 'retaliate',\n 'retention',\n 'rethink',\n 'retinal',\n 'retired',\n 'retiree',\n 'retiring',\n 'retold',\n 'retool',\n 'retorted',\n 'retouch',\n 'retrace',\n 'retract',\n 'retrain',\n 'retread',\n 'retreat',\n 'retrial',\n 'retrieval',\n 'retriever',\n 'retry',\n 'return',\n 'retying',\n 'retype',\n 'reunion',\n 'reunite',\n 'reusable',\n 'reuse',\n 'reveal',\n 'reveler',\n 'revenge',\n 'revenue',\n 'reverb',\n 'revered',\n 'reverence',\n 'reverend',\n 'reversal',\n 'reverse',\n 'reversing',\n 'reversion',\n 'revert',\n 'revisable',\n 'revise',\n 'revision',\n 'revisit',\n 'revivable',\n 'revival',\n 'reviver',\n 'reviving',\n 'revocable',\n 'revoke',\n 'revolt',\n 'revolver',\n 'revolving',\n 'reward',\n 'rewash',\n 'rewind',\n 'rewire',\n 'reword',\n 'rework',\n 'rewrap',\n 'rewrite',\n 'rhyme',\n 'ribbon',\n 'ribcage',\n 'rice',\n 'riches',\n 'richly',\n 'richness',\n 'rickety',\n 'ricotta',\n 'riddance',\n 'ridden',\n 'ride',\n 'riding',\n 'rifling',\n 'rift',\n 'rigging',\n 'rigid',\n 'rigor',\n 'rimless',\n 'rimmed',\n 'rind',\n 'rink',\n 'rinse',\n 'rinsing',\n 'riot',\n 'ripcord',\n 'ripeness',\n 'ripening',\n 'ripping',\n 'ripple',\n 'rippling',\n 'riptide',\n 'rise',\n 'rising',\n 'risk',\n 'risotto',\n 'ritalin',\n 'ritzy',\n 'rival',\n 'riverbank',\n 'riverbed',\n 'riverboat',\n 'riverside',\n 'riveter',\n 'riveting',\n 'roamer',\n 'roaming',\n 'roast',\n 'robbing',\n 'robe',\n 'robin',\n 'robotics',\n 'robust',\n 'rockband',\n 'rocker',\n 'rocket',\n 'rockfish',\n 'rockiness',\n 'rocking',\n 'rocklike',\n 'rockslide',\n 'rockstar',\n 'rocky',\n 'rogue',\n 'roman',\n 'romp',\n 'rope',\n 'roping',\n 'roster',\n 'rosy',\n 'rotten',\n 'rotting',\n 'rotunda',\n 'roulette',\n 'rounding',\n 'roundish',\n 'roundness',\n 'roundup',\n 'roundworm',\n 'routine',\n 'routing',\n 'rover',\n 'roving',\n 'royal',\n 'rubbed',\n 'rubber',\n 'rubbing',\n 'rubble',\n 'rubdown',\n 'ruby',\n 'ruckus',\n 'rudder',\n 'rug',\n 'ruined',\n 'rule',\n 'rumble',\n 'rumbling',\n 'rummage',\n 'rumor',\n 'runaround',\n 'rundown',\n 'runner',\n 'running',\n 'runny',\n 'runt',\n 'runway',\n 'rupture',\n 'rural',\n 'ruse',\n 'rush',\n 'rust',\n 'rut',\n 'sabbath',\n 'sabotage',\n 'sacrament',\n 'sacred',\n 'sacrifice',\n 'sadden',\n 'saddlebag',\n 'saddled',\n 'saddling',\n 'sadly',\n 'sadness',\n 'safari',\n 'safeguard',\n 'safehouse',\n 'safely',\n 'safeness',\n 'saffron',\n 'saga',\n 'sage',\n 'sagging',\n 'saggy',\n 'said',\n 'saint',\n 'sake',\n 'salad',\n 'salami',\n 'salaried',\n 'salary',\n 'saline',\n 'salon',\n 'saloon',\n 'salsa',\n 'salt',\n 'salutary',\n 'salute',\n 'salvage',\n 'salvaging',\n 'salvation',\n 'same',\n 'sample',\n 'sampling',\n 'sanction',\n 'sanctity',\n 'sanctuary',\n 'sandal',\n 'sandbag',\n 'sandbank',\n 'sandbar',\n 'sandblast',\n 'sandbox',\n 'sanded',\n 'sandfish',\n 'sanding',\n 'sandlot',\n 'sandpaper',\n 'sandpit',\n 'sandstone',\n 'sandstorm',\n 'sandworm',\n 'sandy',\n 'sanitary',\n 'sanitizer',\n 'sank',\n 'santa',\n 'sapling',\n 'sappiness',\n 'sappy',\n 'sarcasm',\n 'sarcastic',\n 'sardine',\n 'sash',\n 'sasquatch',\n 'sassy',\n 'satchel',\n 'satiable',\n 'satin',\n 'satirical',\n 'satisfied',\n 'satisfy',\n 'saturate',\n 'saturday',\n 'sauciness',\n 'saucy',\n 'sauna',\n 'savage',\n 'savanna',\n 'saved',\n 'savings',\n 'savior',\n 'savor',\n 'saxophone',\n 'say',\n 'scabbed',\n 'scabby',\n 'scalded',\n 'scalding',\n 'scale',\n 'scaling',\n 'scallion',\n 'scallop',\n 'scalping',\n 'scam',\n 'scandal',\n 'scanner',\n 'scanning',\n 'scant',\n 'scapegoat',\n 'scarce',\n 'scarcity',\n 'scarecrow',\n 'scared',\n 'scarf',\n 'scarily',\n 'scariness',\n 'scarring',\n 'scary',\n 'scavenger',\n 'scenic',\n 'schedule',\n 'schematic',\n 'scheme',\n 'scheming',\n 'schilling',\n 'schnapps',\n 'scholar',\n 'science',\n 'scientist',\n 'scion',\n 'scoff',\n 'scolding',\n 'scone',\n 'scoop',\n 'scooter',\n 'scope',\n 'scorch',\n 'scorebook',\n 'scorecard',\n 'scored',\n 'scoreless',\n 'scorer',\n 'scoring',\n 'scorn',\n 'scorpion',\n 'scotch',\n 'scoundrel',\n 'scoured',\n 'scouring',\n 'scouting',\n 'scouts',\n 'scowling',\n 'scrabble',\n 'scraggly',\n 'scrambled',\n 'scrambler',\n 'scrap',\n 'scratch',\n 'scrawny',\n 'screen',\n 'scribble',\n 'scribe',\n 'scribing',\n 'scrimmage',\n 'script',\n 'scroll',\n 'scrooge',\n 'scrounger',\n 'scrubbed',\n 'scrubber',\n 'scruffy',\n 'scrunch',\n 'scrutiny',\n 'scuba',\n 'scuff',\n 'sculptor',\n 'sculpture',\n 'scurvy',\n 'scuttle',\n 'secluded',\n 'secluding',\n 'seclusion',\n 'second',\n 'secrecy',\n 'secret',\n 'sectional',\n 'sector',\n 'secular',\n 'securely',\n 'security',\n 'sedan',\n 'sedate',\n 'sedation',\n 'sedative',\n 'sediment',\n 'seduce',\n 'seducing',\n 'segment',\n 'seismic',\n 'seizing',\n 'seldom',\n 'selected',\n 'selection',\n 'selective',\n 'selector',\n 'self',\n 'seltzer',\n 'semantic',\n 'semester',\n 'semicolon',\n 'semifinal',\n 'seminar',\n 'semisoft',\n 'semisweet',\n 'senate',\n 'senator',\n 'send',\n 'senior',\n 'senorita',\n 'sensation',\n 'sensitive',\n 'sensitize',\n 'sensually',\n 'sensuous',\n 'sepia',\n 'september',\n 'septic',\n 'septum',\n 'sequel',\n 'sequence',\n 'sequester',\n 'series',\n 'sermon',\n 'serotonin',\n 'serpent',\n 'serrated',\n 'serve',\n 'service',\n 'serving',\n 'sesame',\n 'sessions',\n 'setback',\n 'setting',\n 'settle',\n 'settling',\n 'setup',\n 'sevenfold',\n 'seventeen',\n 'seventh',\n 'seventy',\n 'severity',\n 'shabby',\n 'shack',\n 'shaded',\n 'shadily',\n 'shadiness',\n 'shading',\n 'shadow',\n 'shady',\n 'shaft',\n 'shakable',\n 'shakily',\n 'shakiness',\n 'shaking',\n 'shaky',\n 'shale',\n 'shallot',\n 'shallow',\n 'shame',\n 'shampoo',\n 'shamrock',\n 'shank',\n 'shanty',\n 'shape',\n 'shaping',\n 'share',\n 'sharpener',\n 'sharper',\n 'sharpie',\n 'sharply',\n 'sharpness',\n 'shawl',\n 'sheath',\n 'shed',\n 'sheep',\n 'sheet',\n 'shelf',\n 'shell',\n 'shelter',\n 'shelve',\n 'shelving',\n 'sherry',\n 'shield',\n 'shifter',\n 'shifting',\n 'shiftless',\n 'shifty',\n 'shimmer',\n 'shimmy',\n 'shindig',\n 'shine',\n 'shingle',\n 'shininess',\n 'shining',\n 'shiny',\n 'ship',\n 'shirt',\n 'shivering',\n 'shock',\n 'shone',\n 'shoplift',\n 'shopper',\n 'shopping',\n 'shoptalk',\n 'shore',\n 'shortage',\n 'shortcake',\n 'shortcut',\n 'shorten',\n 'shorter',\n 'shorthand',\n 'shortlist',\n 'shortly',\n 'shortness',\n 'shorts',\n 'shortwave',\n 'shorty',\n 'shout',\n 'shove',\n 'showbiz',\n 'showcase',\n 'showdown',\n 'shower',\n 'showgirl',\n 'showing',\n 'showman',\n 'shown',\n 'showoff',\n 'showpiece',\n 'showplace',\n 'showroom',\n 'showy',\n 'shrank',\n 'shrapnel',\n 'shredder',\n 'shredding',\n 'shrewdly',\n 'shriek',\n 'shrill',\n 'shrimp',\n 'shrine',\n 'shrink',\n 'shrivel',\n 'shrouded',\n 'shrubbery',\n 'shrubs',\n 'shrug',\n 'shrunk',\n 'shucking',\n 'shudder',\n 'shuffle',\n 'shuffling',\n 'shun',\n 'shush',\n 'shut',\n 'shy',\n 'siamese',\n 'siberian',\n 'sibling',\n 'siding',\n 'sierra',\n 'siesta',\n 'sift',\n 'sighing',\n 'silenced',\n 'silencer',\n 'silent',\n 'silica',\n 'silicon',\n 'silk',\n 'silliness',\n 'silly',\n 'silo',\n 'silt',\n 'silver',\n 'similarly',\n 'simile',\n 'simmering',\n 'simple',\n 'simplify',\n 'simply',\n 'sincere',\n 'sincerity',\n 'singer',\n 'singing',\n 'single',\n 'singular',\n 'sinister',\n 'sinless',\n 'sinner',\n 'sinuous',\n 'sip',\n 'siren',\n 'sister',\n 'sitcom',\n 'sitter',\n 'sitting',\n 'situated',\n 'situation',\n 'sixfold',\n 'sixteen',\n 'sixth',\n 'sixties',\n 'sixtieth',\n 'sixtyfold',\n 'sizable',\n 'sizably',\n 'size',\n 'sizing',\n 'sizzle',\n 'sizzling',\n 'skater',\n 'skating',\n 'skedaddle',\n 'skeletal',\n 'skeleton',\n 'skeptic',\n 'sketch',\n 'skewed',\n 'skewer',\n 'skid',\n 'skied',\n 'skier',\n 'skies',\n 'skiing',\n 'skilled',\n 'skillet',\n 'skillful',\n 'skimmed',\n 'skimmer',\n 'skimming',\n 'skimpily',\n 'skincare',\n 'skinhead',\n 'skinless',\n 'skinning',\n 'skinny',\n 'skintight',\n 'skipper',\n 'skipping',\n 'skirmish',\n 'skirt',\n 'skittle',\n 'skydiver',\n 'skylight',\n 'skyline',\n 'skype',\n 'skyrocket',\n 'skyward',\n 'slab',\n 'slacked',\n 'slacker',\n 'slacking',\n 'slackness',\n 'slacks',\n 'slain',\n 'slam',\n 'slander',\n 'slang',\n 'slapping',\n 'slapstick',\n 'slashed',\n 'slashing',\n 'slate',\n 'slather',\n 'slaw',\n 'sled',\n 'sleek',\n 'sleep',\n 'sleet',\n 'sleeve',\n 'slept',\n 'sliceable',\n 'sliced',\n 'slicer',\n 'slicing',\n 'slick',\n 'slider',\n 'slideshow',\n 'sliding',\n 'slighted',\n 'slighting',\n 'slightly',\n 'slimness',\n 'slimy',\n 'slinging',\n 'slingshot',\n 'slinky',\n 'slip',\n 'slit',\n 'sliver',\n 'slobbery',\n 'slogan',\n 'sloped',\n 'sloping',\n 'sloppily',\n 'sloppy',\n 'slot',\n 'slouching',\n 'slouchy',\n 'sludge',\n 'slug',\n 'slum',\n 'slurp',\n 'slush',\n 'sly',\n 'small',\n 'smartly',\n 'smartness',\n 'smasher',\n 'smashing',\n 'smashup',\n 'smell',\n 'smelting',\n 'smile',\n 'smilingly',\n 'smirk',\n 'smite',\n 'smith',\n 'smitten',\n 'smock',\n 'smog',\n 'smoked',\n 'smokeless',\n 'smokiness',\n 'smoking',\n 'smoky',\n 'smolder',\n 'smooth',\n 'smother',\n 'smudge',\n 'smudgy',\n 'smuggler',\n 'smuggling',\n 'smugly',\n 'smugness',\n 'snack',\n 'snagged',\n 'snaking',\n 'snap',\n 'snare',\n 'snarl',\n 'snazzy',\n 'sneak',\n 'sneer',\n 'sneeze',\n 'sneezing',\n 'snide',\n 'sniff',\n 'snippet',\n 'snipping',\n 'snitch',\n 'snooper',\n 'snooze',\n 'snore',\n 'snoring',\n 'snorkel',\n 'snort',\n 'snout',\n 'snowbird',\n 'snowboard',\n 'snowbound',\n 'snowcap',\n 'snowdrift',\n 'snowdrop',\n 'snowfall',\n 'snowfield',\n 'snowflake',\n 'snowiness',\n 'snowless',\n 'snowman',\n 'snowplow',\n 'snowshoe',\n 'snowstorm',\n 'snowsuit',\n 'snowy',\n 'snub',\n 'snuff',\n 'snuggle',\n 'snugly',\n 'snugness',\n 'speak',\n 'spearfish',\n 'spearhead',\n 'spearman',\n 'spearmint',\n 'species',\n 'specimen',\n 'specked',\n 'speckled',\n 'specks',\n 'spectacle',\n 'spectator',\n 'spectrum',\n 'speculate',\n 'speech',\n 'speed',\n 'spellbind',\n 'speller',\n 'spelling',\n 'spendable',\n 'spender',\n 'spending',\n 'spent',\n 'spew',\n 'sphere',\n 'spherical',\n 'sphinx',\n 'spider',\n 'spied',\n 'spiffy',\n 'spill',\n 'spilt',\n 'spinach',\n 'spinal',\n 'spindle',\n 'spinner',\n 'spinning',\n 'spinout',\n 'spinster',\n 'spiny',\n 'spiral',\n 'spirited',\n 'spiritism',\n 'spirits',\n 'spiritual',\n 'splashed',\n 'splashing',\n 'splashy',\n 'splatter',\n 'spleen',\n 'splendid',\n 'splendor',\n 'splice',\n 'splicing',\n 'splinter',\n 'splotchy',\n 'splurge',\n 'spoilage',\n 'spoiled',\n 'spoiler',\n 'spoiling',\n 'spoils',\n 'spoken',\n 'spokesman',\n 'sponge',\n 'spongy',\n 'sponsor',\n 'spoof',\n 'spookily',\n 'spooky',\n 'spool',\n 'spoon',\n 'spore',\n 'sporting',\n 'sports',\n 'sporty',\n 'spotless',\n 'spotlight',\n 'spotted',\n 'spotter',\n 'spotting',\n 'spotty',\n 'spousal',\n 'spouse',\n 'spout',\n 'sprain',\n 'sprang',\n 'sprawl',\n 'spray',\n 'spree',\n 'sprig',\n 'spring',\n 'sprinkled',\n 'sprinkler',\n 'sprint',\n 'sprite',\n 'sprout',\n 'spruce',\n 'sprung',\n 'spry',\n 'spud',\n 'spur',\n 'sputter',\n 'spyglass',\n 'squabble',\n 'squad',\n 'squall',\n 'squander',\n 'squash',\n 'squatted',\n 'squatter',\n 'squatting',\n 'squeak',\n 'squealer',\n 'squealing',\n 'squeamish',\n 'squeegee',\n 'squeeze',\n 'squeezing',\n 'squid',\n 'squiggle',\n 'squiggly',\n 'squint',\n 'squire',\n 'squirt',\n 'squishier',\n 'squishy',\n 'stability',\n 'stabilize',\n 'stable',\n 'stack',\n 'stadium',\n 'staff',\n 'stage',\n 'staging',\n 'stagnant',\n 'stagnate',\n 'stainable',\n 'stained',\n 'staining',\n 'stainless',\n 'stalemate',\n 'staleness',\n 'stalling',\n 'stallion',\n 'stamina',\n 'stammer',\n 'stamp',\n 'stand',\n 'stank',\n 'staple',\n 'stapling',\n 'starboard',\n 'starch',\n 'stardom',\n 'stardust',\n 'starfish',\n 'stargazer',\n 'staring',\n 'stark',\n 'starless',\n 'starlet',\n 'starlight',\n 'starlit',\n 'starring',\n 'starry',\n 'starship',\n 'starter',\n 'starting',\n 'startle',\n 'startling',\n 'startup',\n 'starved',\n 'starving',\n 'stash',\n 'state',\n 'static',\n 'statistic',\n 'statue',\n 'stature',\n 'status',\n 'statute',\n 'statutory',\n 'staunch',\n 'stays',\n 'steadfast',\n 'steadier',\n 'steadily',\n 'steadying',\n 'steam',\n 'steed',\n 'steep',\n 'steerable',\n 'steering',\n 'steersman',\n 'stegosaur',\n 'stellar',\n 'stem',\n 'stench',\n 'stencil',\n 'step',\n 'stereo',\n 'sterile',\n 'sterility',\n 'sterilize',\n 'sterling',\n 'sternness',\n 'sternum',\n 'stew',\n 'stick',\n 'stiffen',\n 'stiffly',\n 'stiffness',\n 'stifle',\n 'stifling',\n 'stillness',\n 'stilt',\n 'stimulant',\n 'stimulate',\n 'stimuli',\n 'stimulus',\n 'stinger',\n 'stingily',\n 'stinging',\n 'stingray',\n 'stingy',\n 'stinking',\n 'stinky',\n 'stipend',\n 'stipulate',\n 'stir',\n 'stitch',\n 'stock',\n 'stoic',\n 'stoke',\n 'stole',\n 'stomp',\n 'stonewall',\n 'stoneware',\n 'stonework',\n 'stoning',\n 'stony',\n 'stood',\n 'stooge',\n 'stool',\n 'stoop',\n 'stoplight',\n 'stoppable',\n 'stoppage',\n 'stopped',\n 'stopper',\n 'stopping',\n 'stopwatch',\n 'storable',\n 'storage',\n 'storeroom',\n 'storewide',\n 'storm',\n 'stout',\n 'stove',\n 'stowaway',\n 'stowing',\n 'straddle',\n 'straggler',\n 'strained',\n 'strainer',\n 'straining',\n 'strangely',\n 'stranger',\n 'strangle',\n 'strategic',\n 'strategy',\n 'stratus',\n 'straw',\n 'stray',\n 'streak',\n 'stream',\n 'street',\n 'strength',\n 'strenuous',\n 'strep',\n 'stress',\n 'stretch',\n 'strewn',\n 'stricken',\n 'strict',\n 'stride',\n 'strife',\n 'strike',\n 'striking',\n 'strive',\n 'striving',\n 'strobe',\n 'strode',\n 'stroller',\n 'strongbox',\n 'strongly',\n 'strongman',\n 'struck',\n 'structure',\n 'strudel',\n 'struggle',\n 'strum',\n 'strung',\n 'strut',\n 'stubbed',\n 'stubble',\n 'stubbly',\n 'stubborn',\n 'stucco',\n 'stuck',\n 'student',\n 'studied',\n 'studio',\n 'study',\n 'stuffed',\n 'stuffing',\n 'stuffy',\n 'stumble',\n 'stumbling',\n 'stump',\n 'stung',\n 'stunned',\n 'stunner',\n 'stunning',\n 'stunt',\n 'stupor',\n 'sturdily',\n 'sturdy',\n 'styling',\n 'stylishly',\n 'stylist',\n 'stylized',\n 'stylus',\n 'suave',\n 'subarctic',\n 'subatomic',\n 'subdivide',\n 'subdued',\n 'subduing',\n 'subfloor',\n 'subgroup',\n 'subheader',\n 'subject',\n 'sublease',\n 'sublet',\n 'sublevel',\n 'sublime',\n 'submarine',\n 'submerge',\n 'submersed',\n 'submitter',\n 'subpanel',\n 'subpar',\n 'subplot',\n 'subprime',\n 'subscribe',\n 'subscript',\n 'subsector',\n 'subside',\n 'subsiding',\n 'subsidize',\n 'subsidy',\n 'subsoil',\n 'subsonic',\n 'substance',\n 'subsystem',\n 'subtext',\n 'subtitle',\n 'subtly',\n 'subtotal',\n 'subtract',\n 'subtype',\n 'suburb',\n 'subway',\n 'subwoofer',\n 'subzero',\n 'succulent',\n 'such',\n 'suction',\n 'sudden',\n 'sudoku',\n 'suds',\n 'sufferer',\n 'suffering',\n 'suffice',\n 'suffix',\n 'suffocate',\n 'suffrage',\n 'sugar',\n 'suggest',\n 'suing',\n 'suitable',\n 'suitably',\n 'suitcase',\n 'suitor',\n 'sulfate',\n 'sulfide',\n 'sulfite',\n 'sulfur',\n 'sulk',\n 'sullen',\n 'sulphate',\n 'sulphuric',\n 'sultry',\n 'superbowl',\n 'superglue',\n 'superhero',\n 'superior',\n 'superjet',\n 'superman',\n 'supermom',\n 'supernova',\n 'supervise',\n 'supper',\n 'supplier',\n 'supply',\n 'support',\n 'supremacy',\n 'supreme',\n 'surcharge',\n 'surely',\n 'sureness',\n 'surface',\n 'surfacing',\n 'surfboard',\n 'surfer',\n 'surgery',\n 'surgical',\n 'surging',\n 'surname',\n 'surpass',\n 'surplus',\n 'surprise',\n 'surreal',\n 'surrender',\n 'surrogate',\n 'surround',\n 'survey',\n 'survival',\n 'survive',\n 'surviving',\n 'survivor',\n 'sushi',\n 'suspect',\n 'suspend',\n 'suspense',\n 'sustained',\n 'sustainer',\n 'swab',\n 'swaddling',\n 'swagger',\n 'swampland',\n 'swan',\n 'swapping',\n 'swarm',\n 'sway',\n 'swear',\n 'sweat',\n 'sweep',\n 'swell',\n 'swept',\n 'swerve',\n 'swifter',\n 'swiftly',\n 'swiftness',\n 'swimmable',\n 'swimmer',\n 'swimming',\n 'swimsuit',\n 'swimwear',\n 'swinger',\n 'swinging',\n 'swipe',\n 'swirl',\n 'switch',\n 'swivel',\n 'swizzle',\n 'swooned',\n 'swoop',\n 'swoosh',\n 'swore',\n 'sworn',\n 'swung',\n 'sycamore',\n 'sympathy',\n 'symphonic',\n 'symphony',\n 'symptom',\n 'synapse',\n 'syndrome',\n 'synergy',\n 'synopses',\n 'synopsis',\n 'synthesis',\n 'synthetic',\n 'syrup',\n 'system',\n 't-shirt',\n 'tabasco',\n 'tabby',\n 'tableful',\n 'tables',\n 'tablet',\n 'tableware',\n 'tabloid',\n 'tackiness',\n 'tacking',\n 'tackle',\n 'tackling',\n 'tacky',\n 'taco',\n 'tactful',\n 'tactical',\n 'tactics',\n 'tactile',\n 'tactless',\n 'tadpole',\n 'taekwondo',\n 'tag',\n 'tainted',\n 'take',\n 'taking',\n 'talcum',\n 'talisman',\n 'tall',\n 'talon',\n 'tamale',\n 'tameness',\n 'tamer',\n 'tamper',\n 'tank',\n 'tanned',\n 'tannery',\n 'tanning',\n 'tantrum',\n 'tapeless',\n 'tapered',\n 'tapering',\n 'tapestry',\n 'tapioca',\n 'tapping',\n 'taps',\n 'tarantula',\n 'target',\n 'tarmac',\n 'tarnish',\n 'tarot',\n 'tartar',\n 'tartly',\n 'tartness',\n 'task',\n 'tassel',\n 'taste',\n 'tastiness',\n 'tasting',\n 'tasty',\n 'tattered',\n 'tattle',\n 'tattling',\n 'tattoo',\n 'taunt',\n 'tavern',\n 'thank',\n 'that',\n 'thaw',\n 'theater',\n 'theatrics',\n 'thee',\n 'theft',\n 'theme',\n 'theology',\n 'theorize',\n 'thermal',\n 'thermos',\n 'thesaurus',\n 'these',\n 'thesis',\n 'thespian',\n 'thicken',\n 'thicket',\n 'thickness',\n 'thieving',\n 'thievish',\n 'thigh',\n 'thimble',\n 'thing',\n 'think',\n 'thinly',\n 'thinner',\n 'thinness',\n 'thinning',\n 'thirstily',\n 'thirsting',\n 'thirsty',\n 'thirteen',\n 'thirty',\n 'thong',\n 'thorn',\n 'those',\n 'thousand',\n 'thrash',\n 'thread',\n 'threaten',\n 'threefold',\n 'thrift',\n 'thrill',\n 'thrive',\n 'thriving',\n 'throat',\n 'throbbing',\n 'throng',\n 'throttle',\n 'throwaway',\n 'throwback',\n 'thrower',\n 'throwing',\n 'thud',\n 'thumb',\n 'thumping',\n 'thursday',\n 'thus',\n 'thwarting',\n 'thyself',\n 'tiara',\n 'tibia',\n 'tidal',\n 'tidbit',\n 'tidiness',\n 'tidings',\n 'tidy',\n 'tiger',\n 'tighten',\n 'tightly',\n 'tightness',\n 'tightrope',\n 'tightwad',\n 'tigress',\n 'tile',\n 'tiling',\n 'till',\n 'tilt',\n 'timid',\n 'timing',\n 'timothy',\n 'tinderbox',\n 'tinfoil',\n 'tingle',\n 'tingling',\n 'tingly',\n 'tinker',\n 'tinkling',\n 'tinsel',\n 'tinsmith',\n 'tint',\n 'tinwork',\n 'tiny',\n 'tipoff',\n 'tipped',\n 'tipper',\n 'tipping',\n 'tiptoeing',\n 'tiptop',\n 'tiring',\n 'tissue',\n 'trace',\n 'tracing',\n 'track',\n 'traction',\n 'tractor',\n 'trade',\n 'trading',\n 'tradition',\n 'traffic',\n 'tragedy',\n 'trailing',\n 'trailside',\n 'train',\n 'traitor',\n 'trance',\n 'tranquil',\n 'transfer',\n 'transform',\n 'translate',\n 'transpire',\n 'transport',\n 'transpose',\n 'trapdoor',\n 'trapeze',\n 'trapezoid',\n 'trapped',\n 'trapper',\n 'trapping',\n 'traps',\n 'trash',\n 'travel',\n 'traverse',\n 'travesty',\n 'tray',\n 'treachery',\n 'treading',\n 'treadmill',\n 'treason',\n 'treat',\n 'treble',\n 'tree',\n 'trekker',\n 'tremble',\n 'trembling',\n 'tremor',\n 'trench',\n 'trend',\n 'trespass',\n 'triage',\n 'trial',\n 'triangle',\n 'tribesman',\n 'tribunal',\n 'tribune',\n 'tributary',\n 'tribute',\n 'triceps',\n 'trickery',\n 'trickily',\n 'tricking',\n 'trickle',\n 'trickster',\n 'tricky',\n 'tricolor',\n 'tricycle',\n 'trident',\n 'tried',\n 'trifle',\n 'trifocals',\n 'trillion',\n 'trilogy',\n 'trimester',\n 'trimmer',\n 'trimming',\n 'trimness',\n 'trinity',\n 'trio',\n 'tripod',\n 'tripping',\n 'triumph',\n 'trivial',\n 'trodden',\n 'trolling',\n 'trombone',\n 'trophy',\n 'tropical',\n 'tropics',\n 'trouble',\n 'troubling',\n 'trough',\n 'trousers',\n 'trout',\n 'trowel',\n 'truce',\n 'truck',\n 'truffle',\n 'trump',\n 'trunks',\n 'trustable',\n 'trustee',\n 'trustful',\n 'trusting',\n 'trustless',\n 'truth',\n 'try',\n 'tubby',\n 'tubeless',\n 'tubular',\n 'tucking',\n 'tuesday',\n 'tug',\n 'tuition',\n 'tulip',\n 'tumble',\n 'tumbling',\n 'tummy',\n 'turban',\n 'turbine',\n 'turbofan',\n 'turbojet',\n 'turbulent',\n 'turf',\n 'turkey',\n 'turmoil',\n 'turret',\n 'turtle',\n 'tusk',\n 'tutor',\n 'tutu',\n 'tux',\n 'tweak',\n 'tweed',\n 'tweet',\n 'tweezers',\n 'twelve',\n 'twentieth',\n 'twenty',\n 'twerp',\n 'twice',\n 'twiddle',\n 'twiddling',\n 'twig',\n 'twilight',\n 'twine',\n 'twins',\n 'twirl',\n 'twistable',\n 'twisted',\n 'twister',\n 'twisting',\n 'twisty',\n 'twitch',\n 'twitter',\n 'tycoon',\n 'tying',\n 'tyke',\n 'udder',\n 'ultimate',\n 'ultimatum',\n 'ultra',\n 'umbilical',\n 'umbrella',\n 'umpire',\n 'unabashed',\n 'unable',\n 'unadorned',\n 'unadvised',\n 'unafraid',\n 'unaired',\n 'unaligned',\n 'unaltered',\n 'unarmored',\n 'unashamed',\n 'unaudited',\n 'unawake',\n 'unaware',\n 'unbaked',\n 'unbalance',\n 'unbeaten',\n 'unbend',\n 'unbent',\n 'unbiased',\n 'unbitten',\n 'unblended',\n 'unblessed',\n 'unblock',\n 'unbolted',\n 'unbounded',\n 'unboxed',\n 'unbraided',\n 'unbridle',\n 'unbroken',\n 'unbuckled',\n 'unbundle',\n 'unburned',\n 'unbutton',\n 'uncanny',\n 'uncapped',\n 'uncaring',\n 'uncertain',\n 'unchain',\n 'unchanged',\n 'uncharted',\n 'uncheck',\n 'uncivil',\n 'unclad',\n 'unclaimed',\n 'unclamped',\n 'unclasp',\n 'uncle',\n 'unclip',\n 'uncloak',\n 'unclog',\n 'unclothed',\n 'uncoated',\n 'uncoiled',\n 'uncolored',\n 'uncombed',\n 'uncommon',\n 'uncooked',\n 'uncork',\n 'uncorrupt',\n 'uncounted',\n 'uncouple',\n 'uncouth',\n 'uncover',\n 'uncross',\n 'uncrown',\n 'uncrushed',\n 'uncured',\n 'uncurious',\n 'uncurled',\n 'uncut',\n 'undamaged',\n 'undated',\n 'undaunted',\n 'undead',\n 'undecided',\n 'undefined',\n 'underage',\n 'underarm',\n 'undercoat',\n 'undercook',\n 'undercut',\n 'underdog',\n 'underdone',\n 'underfed',\n 'underfeed',\n 'underfoot',\n 'undergo',\n 'undergrad',\n 'underhand',\n 'underline',\n 'underling',\n 'undermine',\n 'undermost',\n 'underpaid',\n 'underpass',\n 'underpay',\n 'underrate',\n 'undertake',\n 'undertone',\n 'undertook',\n 'undertow',\n 'underuse',\n 'underwear',\n 'underwent',\n 'underwire',\n 'undesired',\n 'undiluted',\n 'undivided',\n 'undocked',\n 'undoing',\n 'undone',\n 'undrafted',\n 'undress',\n 'undrilled',\n 'undusted',\n 'undying',\n 'unearned',\n 'unearth',\n 'unease',\n 'uneasily',\n 'uneasy',\n 'uneatable',\n 'uneaten',\n 'unedited',\n 'unelected',\n 'unending',\n 'unengaged',\n 'unenvied',\n 'unequal',\n 'unethical',\n 'uneven',\n 'unexpired',\n 'unexposed',\n 'unfailing',\n 'unfair',\n 'unfasten',\n 'unfazed',\n 'unfeeling',\n 'unfiled',\n 'unfilled',\n 'unfitted',\n 'unfitting',\n 'unfixable',\n 'unfixed',\n 'unflawed',\n 'unfocused',\n 'unfold',\n 'unfounded',\n 'unframed',\n 'unfreeze',\n 'unfrosted',\n 'unfrozen',\n 'unfunded',\n 'unglazed',\n 'ungloved',\n 'unglue',\n 'ungodly',\n 'ungraded',\n 'ungreased',\n 'unguarded',\n 'unguided',\n 'unhappily',\n 'unhappy',\n 'unharmed',\n 'unhealthy',\n 'unheard',\n 'unhearing',\n 'unheated',\n 'unhelpful',\n 'unhidden',\n 'unhinge',\n 'unhitched',\n 'unholy',\n 'unhook',\n 'unicorn',\n 'unicycle',\n 'unified',\n 'unifier',\n 'uniformed',\n 'uniformly',\n 'unify',\n 'unimpeded',\n 'uninjured',\n 'uninstall',\n 'uninsured',\n 'uninvited',\n 'union',\n 'uniquely',\n 'unisexual',\n 'unison',\n 'unissued',\n 'unit',\n 'universal',\n 'universe',\n 'unjustly',\n 'unkempt',\n 'unkind',\n 'unknotted',\n 'unknowing',\n 'unknown',\n 'unlaced',\n 'unlatch',\n 'unlawful',\n 'unleaded',\n 'unlearned',\n 'unleash',\n 'unless',\n 'unleveled',\n 'unlighted',\n 'unlikable',\n 'unlimited',\n 'unlined',\n 'unlinked',\n 'unlisted',\n 'unlit',\n 'unlivable',\n 'unloaded',\n 'unloader',\n 'unlocked',\n 'unlocking',\n 'unlovable',\n 'unloved',\n 'unlovely',\n 'unloving',\n 'unluckily',\n 'unlucky',\n 'unmade',\n 'unmanaged',\n 'unmanned',\n 'unmapped',\n 'unmarked',\n 'unmasked',\n 'unmasking',\n 'unmatched',\n 'unmindful',\n 'unmixable',\n 'unmixed',\n 'unmolded',\n 'unmoral',\n 'unmovable',\n 'unmoved',\n 'unmoving',\n 'unnamable',\n 'unnamed',\n 'unnatural',\n 'unneeded',\n 'unnerve',\n 'unnerving',\n 'unnoticed',\n 'unopened',\n 'unopposed',\n 'unpack',\n 'unpadded',\n 'unpaid',\n 'unpainted',\n 'unpaired',\n 'unpaved',\n 'unpeeled',\n 'unpicked',\n 'unpiloted',\n 'unpinned',\n 'unplanned',\n 'unplanted',\n 'unpleased',\n 'unpledged',\n 'unplowed',\n 'unplug',\n 'unpopular',\n 'unproven',\n 'unquote',\n 'unranked',\n 'unrated',\n 'unraveled',\n 'unreached',\n 'unread',\n 'unreal',\n 'unreeling',\n 'unrefined',\n 'unrelated',\n 'unrented',\n 'unrest',\n 'unretired',\n 'unrevised',\n 'unrigged',\n 'unripe',\n 'unrivaled',\n 'unroasted',\n 'unrobed',\n 'unroll',\n 'unruffled',\n 'unruly',\n 'unrushed',\n 'unsaddle',\n 'unsafe',\n 'unsaid',\n 'unsalted',\n 'unsaved',\n 'unsavory',\n 'unscathed',\n 'unscented',\n 'unscrew',\n 'unsealed',\n 'unseated',\n 'unsecured',\n 'unseeing',\n 'unseemly',\n 'unseen',\n 'unselect',\n 'unselfish',\n 'unsent',\n 'unsettled',\n 'unshackle',\n 'unshaken',\n 'unshaved',\n 'unshaven',\n 'unsheathe',\n 'unshipped',\n 'unsightly',\n 'unsigned',\n 'unskilled',\n 'unsliced',\n 'unsmooth',\n 'unsnap',\n 'unsocial',\n 'unsoiled',\n 'unsold',\n 'unsolved',\n 'unsorted',\n 'unspoiled',\n 'unspoken',\n 'unstable',\n 'unstaffed',\n 'unstamped',\n 'unsteady',\n 'unsterile',\n 'unstirred',\n 'unstitch',\n 'unstopped',\n 'unstuck',\n 'unstuffed',\n 'unstylish',\n 'unsubtle',\n 'unsubtly',\n 'unsuited',\n 'unsure',\n 'unsworn',\n 'untagged',\n 'untainted',\n 'untaken',\n 'untamed',\n 'untangled',\n 'untapped',\n 'untaxed',\n 'unthawed',\n 'unthread',\n 'untidy',\n 'untie',\n 'until',\n 'untimed',\n 'untimely',\n 'untitled',\n 'untoasted',\n 'untold',\n 'untouched',\n 'untracked',\n 'untrained',\n 'untreated',\n 'untried',\n 'untrimmed',\n 'untrue',\n 'untruth',\n 'unturned',\n 'untwist',\n 'untying',\n 'unusable',\n 'unused',\n 'unusual',\n 'unvalued',\n 'unvaried',\n 'unvarying',\n 'unveiled',\n 'unveiling',\n 'unvented',\n 'unviable',\n 'unvisited',\n 'unvocal',\n 'unwanted',\n 'unwarlike',\n 'unwary',\n 'unwashed',\n 'unwatched',\n 'unweave',\n 'unwed',\n 'unwelcome',\n 'unwell',\n 'unwieldy',\n 'unwilling',\n 'unwind',\n 'unwired',\n 'unwitting',\n 'unwomanly',\n 'unworldly',\n 'unworn',\n 'unworried',\n 'unworthy',\n 'unwound',\n 'unwoven',\n 'unwrapped',\n 'unwritten',\n 'unzip',\n 'upbeat',\n 'upchuck',\n 'upcoming',\n 'upcountry',\n 'update',\n 'upfront',\n 'upgrade',\n 'upheaval',\n 'upheld',\n 'uphill',\n 'uphold',\n 'uplifted',\n 'uplifting',\n 'upload',\n 'upon',\n 'upper',\n 'upright',\n 'uprising',\n 'upriver',\n 'uproar',\n 'uproot',\n 'upscale',\n 'upside',\n 'upstage',\n 'upstairs',\n 'upstart',\n 'upstate',\n 'upstream',\n 'upstroke',\n 'upswing',\n 'uptake',\n 'uptight',\n 'uptown',\n 'upturned',\n 'upward',\n 'upwind',\n 'uranium',\n 'urban',\n 'urchin',\n 'urethane',\n 'urgency',\n 'urgent',\n 'urging',\n 'urologist',\n 'urology',\n 'usable',\n 'usage',\n 'useable',\n 'used',\n 'uselessly',\n 'user',\n 'usher',\n 'usual',\n 'utensil',\n 'utility',\n 'utilize',\n 'utmost',\n 'utopia',\n 'utter',\n 'vacancy',\n 'vacant',\n 'vacate',\n 'vacation',\n 'vagabond',\n 'vagrancy',\n 'vagrantly',\n 'vaguely',\n 'vagueness',\n 'valiant',\n 'valid',\n 'valium',\n 'valley',\n 'valuables',\n 'value',\n 'vanilla',\n 'vanish',\n 'vanity',\n 'vanquish',\n 'vantage',\n 'vaporizer',\n 'variable',\n 'variably',\n 'varied',\n 'variety',\n 'various',\n 'varmint',\n 'varnish',\n 'varsity',\n 'varying',\n 'vascular',\n 'vaseline',\n 'vastly',\n 'vastness',\n 'veal',\n 'vegan',\n 'veggie',\n 'vehicular',\n 'velcro',\n 'velocity',\n 'velvet',\n 'vendetta',\n 'vending',\n 'vendor',\n 'veneering',\n 'vengeful',\n 'venomous',\n 'ventricle',\n 'venture',\n 'venue',\n 'venus',\n 'verbalize',\n 'verbally',\n 'verbose',\n 'verdict',\n 'verify',\n 'verse',\n 'version',\n 'versus',\n 'vertebrae',\n 'vertical',\n 'vertigo',\n 'very',\n 'vessel',\n 'vest',\n 'veteran',\n 'veto',\n 'vexingly',\n 'viability',\n 'viable',\n 'vibes',\n 'vice',\n 'vicinity',\n 'victory',\n 'video',\n 'viewable',\n 'viewer',\n 'viewing',\n 'viewless',\n 'viewpoint',\n 'vigorous',\n 'village',\n 'villain',\n 'vindicate',\n 'vineyard',\n 'vintage',\n 'violate',\n 'violation',\n 'violator',\n 'violet',\n 'violin',\n 'viper',\n 'viral',\n 'virtual',\n 'virtuous',\n 'virus',\n 'visa',\n 'viscosity',\n 'viscous',\n 'viselike',\n 'visible',\n 'visibly',\n 'vision',\n 'visiting',\n 'visitor',\n 'visor',\n 'vista',\n 'vitality',\n 'vitalize',\n 'vitally',\n 'vitamins',\n 'vivacious',\n 'vividly',\n 'vividness',\n 'vixen',\n 'vocalist',\n 'vocalize',\n 'vocally',\n 'vocation',\n 'voice',\n 'voicing',\n 'void',\n 'volatile',\n 'volley',\n 'voltage',\n 'volumes',\n 'voter',\n 'voting',\n 'voucher',\n 'vowed',\n 'vowel',\n 'voyage',\n 'wackiness',\n 'wad',\n 'wafer',\n 'waffle',\n 'waged',\n 'wager',\n 'wages',\n 'waggle',\n 'wagon',\n 'wake',\n 'waking',\n 'walk',\n 'walmart',\n 'walnut',\n 'walrus',\n 'waltz',\n 'wand',\n 'wannabe',\n 'wanted',\n 'wanting',\n 'wasabi',\n 'washable',\n 'washbasin',\n 'washboard',\n 'washbowl',\n 'washcloth',\n 'washday',\n 'washed',\n 'washer',\n 'washhouse',\n 'washing',\n 'washout',\n 'washroom',\n 'washstand',\n 'washtub',\n 'wasp',\n 'wasting',\n 'watch',\n 'water',\n 'waviness',\n 'waving',\n 'wavy',\n 'whacking',\n 'whacky',\n 'wham',\n 'wharf',\n 'wheat',\n 'whenever',\n 'whiff',\n 'whimsical',\n 'whinny',\n 'whiny',\n 'whisking',\n 'whoever',\n 'whole',\n 'whomever',\n 'whoopee',\n 'whooping',\n 'whoops',\n 'why',\n 'wick',\n 'widely',\n 'widen',\n 'widget',\n 'widow',\n 'width',\n 'wieldable',\n 'wielder',\n 'wife',\n 'wifi',\n 'wikipedia',\n 'wildcard',\n 'wildcat',\n 'wilder',\n 'wildfire',\n 'wildfowl',\n 'wildland',\n 'wildlife',\n 'wildly',\n 'wildness',\n 'willed',\n 'willfully',\n 'willing',\n 'willow',\n 'willpower',\n 'wilt',\n 'wimp',\n 'wince',\n 'wincing',\n 'wind',\n 'wing',\n 'winking',\n 'winner',\n 'winnings',\n 'winter',\n 'wipe',\n 'wired',\n 'wireless',\n 'wiring',\n 'wiry',\n 'wisdom',\n 'wise',\n 'wish',\n 'wisplike',\n 'wispy',\n 'wistful',\n 'wizard',\n 'wobble',\n 'wobbling',\n 'wobbly',\n 'wok',\n 'wolf',\n 'wolverine',\n 'womanhood',\n 'womankind',\n 'womanless',\n 'womanlike',\n 'womanly',\n 'womb',\n 'woof',\n 'wooing',\n 'wool',\n 'woozy',\n 'word',\n 'work',\n 'worried',\n 'worrier',\n 'worrisome',\n 'worry',\n 'worsening',\n 'worshiper',\n 'worst',\n 'wound',\n 'woven',\n 'wow',\n 'wrangle',\n 'wrath',\n 'wreath',\n 'wreckage',\n 'wrecker',\n 'wrecking',\n 'wrench',\n 'wriggle',\n 'wriggly',\n 'wrinkle',\n 'wrinkly',\n 'wrist',\n 'writing',\n 'written',\n 'wrongdoer',\n 'wronged',\n 'wrongful',\n 'wrongly',\n 'wrongness',\n 'wrought',\n 'xbox',\n 'xerox',\n 'yahoo',\n 'yam',\n 'yanking',\n 'yapping',\n 'yard',\n 'yarn',\n 'yeah',\n 'yearbook',\n 'yearling',\n 'yearly',\n 'yearning',\n 'yeast',\n 'yelling',\n 'yelp',\n 'yen',\n 'yesterday',\n 'yiddish',\n 'yield',\n 'yin',\n 'yippee',\n 'yo-yo',\n 'yodel',\n 'yoga',\n 'yogurt',\n 'yonder',\n 'yoyo',\n 'yummy',\n 'zap',\n 'zealous',\n 'zebra',\n 'zen',\n 'zeppelin',\n 'zero',\n 'zestfully',\n 'zesty',\n 'zigzagged',\n 'zipfile',\n 'zipping',\n 'zippy',\n 'zips',\n 'zit',\n 'zodiac',\n 'zombie',\n 'zone',\n 'zoning',\n 'zookeeper',\n 'zoologist',\n 'zoology',\n 'zoom',\n];\n","import { Cipher } from './cipher';\n\nimport { CipherView } from '../view/cipherView';\n\nimport { Cipher as CipherDomain } from '../domain/cipher';\n\nexport class CipherWithIds extends Cipher {\n id: string;\n collectionIds: string[];\n\n // Use build method instead of ctor so that we can control order of JSON stringify for pretty print\n build(o: CipherView | CipherDomain) {\n this.id = o.id;\n super.build(o);\n this.collectionIds = o.collectionIds;\n }\n}\n","import { Collection } from './collection';\n\nimport { CollectionView } from '../view/collectionView';\n\nimport { Collection as CollectionDomain } from '../domain/collection';\n\nexport class CollectionWithId extends Collection {\n id: string;\n\n // Use build method instead of ctor so that we can control order of JSON stringify for pretty print\n build(o: CollectionView | CollectionDomain) {\n this.id = o.id;\n super.build(o);\n }\n}\n","import { Folder } from './folder';\n\nimport { FolderView } from '../view/folderView';\n\nimport { Folder as FolderDomain } from '../domain/folder';\n\nexport class FolderWithId extends Folder {\n id: string;\n\n // Use build method instead of ctor so that we can control order of JSON stringify for pretty print\n build(o: FolderView | FolderDomain) {\n this.id = o.id;\n super.build(o);\n }\n}\n","import { FolderData } from '../data/folderData';\n\nimport { FolderView } from '../view/folderView';\n\nimport Domain from './domainBase';\nimport { EncString } from './encString';\n\nexport class Folder extends Domain {\n id: string;\n name: EncString;\n revisionDate: Date;\n\n constructor(obj?: FolderData, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.buildDomainModel(this, obj, {\n id: null,\n name: null,\n }, alreadyEncrypted, ['id']);\n\n this.revisionDate = obj.revisionDate != null ? new Date(obj.revisionDate) : null;\n }\n\n decrypt(): Promise {\n return this.decryptObj(new FolderView(this), {\n name: null,\n }, null);\n }\n}\n","import { FolderResponse } from '../response/folderResponse';\n\nexport class FolderData {\n id: string;\n userId: string;\n name: string;\n revisionDate: string;\n\n constructor(response: FolderResponse, userId: string) {\n this.userId = userId;\n this.name = response.name;\n this.id = response.id;\n this.revisionDate = response.revisionDate;\n }\n}\n","import { ImportResult } from '../../models/domain/importResult';\nimport { BaseImporter } from '../baseImporter';\nimport { Importer } from '../importer';\n\nimport { CipherType } from '../../enums/cipherType';\nimport { FieldType } from '../../enums/fieldType';\nimport { CipherView } from '../../models/view/cipherView';\nimport { CipherImportContext } from './cipherImportContext';\n\nexport const IgnoredProperties = ['ainfo', 'autosubmit', 'notesplain', 'ps', 'scope', 'tags', 'title', 'uuid', 'notes'];\n\nexport abstract class OnePasswordCsvImporter extends BaseImporter implements Importer {\n protected loginPropertyParsers = [this.setLoginUsername, this.setLoginPassword, this.setLoginUris];\n protected creditCardPropertyParsers = [this.setCreditCardNumber, this.setCreditCardVerification, this.setCreditCardCardholderName, this.setCreditCardExpiry];\n protected identityPropertyParsers = [this.setIdentityFirstName, this.setIdentityInitial, this.setIdentityLastName, this.setIdentityUserName, this.setIdentityEmail, this.setIdentityPhone, this.setIdentityCompany];\n\n abstract setCipherType(value: any, cipher: CipherView): void;\n\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true, {\n quoteChar: '\"',\n escapeChar: '\\\\',\n });\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (this.isNullOrWhitespace(this.getProp(value, 'title'))) {\n return;\n }\n\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(this.getProp(value, 'title'), '--');\n\n this.setNotes(value, cipher);\n\n this.setCipherType(value, cipher);\n\n let altUsername: string = null;\n for (const property in value) {\n if (!value.hasOwnProperty(property) || this.isNullOrWhitespace(value[property])) {\n continue;\n }\n\n const context = new CipherImportContext(value, property, cipher);\n if (cipher.type === CipherType.Login && this.setKnownLoginValue(context)) {\n continue;\n } else if (cipher.type === CipherType.Card && this.setKnownCreditCardValue(context)) {\n continue;\n } else if (cipher.type === CipherType.Identity && this.setKnownIdentityValue(context)) {\n continue;\n }\n\n altUsername = this.setUnknownValue(context, altUsername);\n }\n\n if (cipher.type === CipherType.Login && !this.isNullOrWhitespace(altUsername) &&\n this.isNullOrWhitespace(cipher.login.username) && altUsername.indexOf('://') === -1) {\n cipher.login.username = altUsername;\n }\n\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n\n protected getProp(obj: any, name: string): any {\n const lowerObj = Object.entries(obj).reduce((agg: any, entry: [string, any]) => {\n agg[entry[0].toLowerCase()] = entry[1];\n return agg;\n }, {});\n return lowerObj[name.toLowerCase()];\n }\n\n protected getPropByRegexp(obj: any, regexp: RegExp): any {\n const matchingKeys = Object.keys(obj).reduce((agg: string[], key: string) => {\n if (key.match(regexp)) {\n agg.push(key);\n }\n return agg;\n }, []);\n if (matchingKeys.length === 0) {\n return null;\n } else {\n return obj[matchingKeys[0]];\n }\n }\n\n protected getPropIncluding(obj: any, name: string): any {\n const includesMap = Object.keys(obj).reduce((agg: string[], entry: string) => {\n if (entry.toLowerCase().includes(name.toLowerCase())) {\n agg.push(entry);\n }\n return agg;\n }, []);\n if (includesMap.length === 0) {\n return null;\n } else {\n return obj[includesMap[0]];\n }\n }\n\n protected setNotes(importRecord: any, cipher: CipherView) {\n cipher.notes = this.getValueOrDefault(this.getProp(importRecord, 'notesPlain'), '') + '\\n' +\n this.getValueOrDefault(this.getProp(importRecord, 'notes'), '') + '\\n';\n cipher.notes.trim();\n\n }\n\n protected setKnownLoginValue(context: CipherImportContext): boolean {\n return this.loginPropertyParsers.reduce((agg: boolean, func) => {\n if (!agg) {\n agg = func.bind(this)(context);\n }\n return agg;\n }, false);\n }\n\n protected setKnownCreditCardValue(context: CipherImportContext): boolean {\n return this.creditCardPropertyParsers.reduce((agg: boolean, func) => {\n if (!agg) {\n agg = func.bind(this)(context);\n }\n return agg;\n }, false);\n }\n\n protected setKnownIdentityValue(context: CipherImportContext): boolean {\n return this.identityPropertyParsers.reduce((agg: boolean, func) => {\n if (!agg) {\n agg = func.bind(this)(context);\n }\n return agg;\n }, false);\n }\n\n protected setUnknownValue(context: CipherImportContext, altUsername: string): string {\n if (IgnoredProperties.indexOf(context.lowerProperty) === -1 && !context.lowerProperty.startsWith('section:') &&\n !context.lowerProperty.startsWith('section ')) {\n if (altUsername == null && context.lowerProperty === 'email') {\n return context.importRecord[context.property];\n }\n else if (context.lowerProperty === 'created date' || context.lowerProperty === 'modified date') {\n const readableDate = new Date(parseInt(context.importRecord[context.property], 10) * 1000).toUTCString();\n this.processKvp(context.cipher, '1Password ' + context.property, readableDate);\n return null;\n }\n if (context.lowerProperty.includes('password') || context.lowerProperty.includes('key') || context.lowerProperty.includes('secret')) {\n this.processKvp(context.cipher, context.property, context.importRecord[context.property], FieldType.Hidden);\n } else {\n this.processKvp(context.cipher, context.property, context.importRecord[context.property]);\n }\n }\n return null;\n }\n\n protected setIdentityFirstName(context: CipherImportContext) {\n if (this.isNullOrWhitespace(context.cipher.identity.firstName) && context.lowerProperty.includes('first name')) {\n context.cipher.identity.firstName = context.importRecord[context.property];\n return true;\n }\n return false;\n }\n\n protected setIdentityInitial(context: CipherImportContext) {\n if (this.isNullOrWhitespace(context.cipher.identity.middleName) && context.lowerProperty.includes('initial')) {\n context.cipher.identity.middleName = context.importRecord[context.property];\n return true;\n }\n return false;\n }\n\n protected setIdentityLastName(context: CipherImportContext) {\n if (this.isNullOrWhitespace(context.cipher.identity.lastName) && context.lowerProperty.includes('last name')) {\n context.cipher.identity.lastName = context.importRecord[context.property];\n return true;\n }\n return false;\n }\n\n protected setIdentityUserName(context: CipherImportContext) {\n if (this.isNullOrWhitespace(context.cipher.identity.username) && context.lowerProperty.includes('username')) {\n context.cipher.identity.username = context.importRecord[context.property];\n return true;\n }\n return false;\n }\n\n protected setIdentityCompany(context: CipherImportContext) {\n if (this.isNullOrWhitespace(context.cipher.identity.company) && context.lowerProperty.includes('company')) {\n context.cipher.identity.company = context.importRecord[context.property];\n return true;\n }\n return false;\n }\n\n protected setIdentityPhone(context: CipherImportContext) {\n if (this.isNullOrWhitespace(context.cipher.identity.phone) && context.lowerProperty.includes('default phone')) {\n context.cipher.identity.phone = context.importRecord[context.property];\n return true;\n }\n return false;\n }\n\n protected setIdentityEmail(context: CipherImportContext) {\n if (this.isNullOrWhitespace(context.cipher.identity.email) && context.lowerProperty.includes('email')) {\n context.cipher.identity.email = context.importRecord[context.property];\n return true;\n }\n return false;\n }\n\n protected setCreditCardNumber(context: CipherImportContext): boolean {\n if (this.isNullOrWhitespace(context.cipher.card.number) && context.lowerProperty.includes('number')) {\n context.cipher.card.number = context.importRecord[context.property];\n context.cipher.card.brand = this.getCardBrand(context.cipher.card.number);\n return true;\n }\n return false;\n }\n\n protected setCreditCardVerification(context: CipherImportContext) {\n if (this.isNullOrWhitespace(context.cipher.card.code) && context.lowerProperty.includes('verification number')) {\n context.cipher.card.code = context.importRecord[context.property];\n return true;\n }\n return false;\n }\n\n protected setCreditCardCardholderName(context: CipherImportContext) {\n if (this.isNullOrWhitespace(context.cipher.card.cardholderName) && context.lowerProperty.includes('cardholder name')) {\n context.cipher.card.cardholderName = context.importRecord[context.property];\n return true;\n }\n return false;\n }\n\n protected setCreditCardExpiry(context: CipherImportContext) {\n if (this.isNullOrWhitespace(context.cipher.card.expiration) && context.lowerProperty.includes('expiry date') &&\n context.importRecord[context.property].length === 7) {\n context.cipher.card.expMonth = (context.importRecord[context.property] as string).substr(0, 2);\n if (context.cipher.card.expMonth[0] === '0') {\n context.cipher.card.expMonth = context.cipher.card.expMonth.substr(1, 1);\n }\n context.cipher.card.expYear = (context.importRecord[context.property] as string).substr(3, 4);\n return true;\n }\n return false;\n }\n\n protected setLoginPassword(context: CipherImportContext) {\n if (this.isNullOrWhitespace(context.cipher.login.password) && context.lowerProperty === 'password') {\n context.cipher.login.password = context.importRecord[context.property];\n return true;\n }\n return false;\n }\n\n protected setLoginUsername(context: CipherImportContext) {\n if (this.isNullOrWhitespace(context.cipher.login.username) && context.lowerProperty === 'username') {\n context.cipher.login.username = context.importRecord[context.property];\n return true;\n }\n return false;\n }\n\n protected setLoginUris(context: CipherImportContext) {\n if ((context.cipher.login.uris == null || context.cipher.login.uris.length === 0) && context.lowerProperty === 'urls') {\n const urls = context.importRecord[context.property].split(this.newLineRegex);\n context.cipher.login.uris = this.makeUriArray(urls);\n return true;\n } else if ((context.lowerProperty === 'url')) {\n if (context.cipher.login.uris == null) {\n context.cipher.login.uris = [];\n }\n context.cipher.login.uris.concat(this.makeUriArray(context.importRecord[context.property]));\n return true;\n }\n return false;\n }\n}\n","export enum NotificationType {\n SyncCipherUpdate = 0,\n SyncCipherCreate = 1,\n SyncLoginDelete = 2,\n SyncFolderDelete = 3,\n SyncCiphers = 4,\n\n SyncVault = 5,\n SyncOrgKeys = 6,\n SyncFolderCreate = 7,\n SyncFolderUpdate = 8,\n SyncCipherDelete = 9,\n SyncSettings = 10,\n\n LogOut = 11,\n\n SyncSendCreate = 12,\n SyncSendUpdate = 13,\n SyncSendDelete = 14,\n}\n","import { SendType } from '../../enums/sendType';\n\nimport { SendFileData } from './sendFileData';\nimport { SendTextData } from './sendTextData';\n\nimport { SendResponse } from '../response/sendResponse';\n\nexport class SendData {\n id: string;\n accessId: string;\n userId: string;\n type: SendType;\n name: string;\n notes: string;\n file: SendFileData;\n text: SendTextData;\n key: string;\n maxAccessCount?: number;\n accessCount: number;\n revisionDate: string;\n expirationDate: string;\n deletionDate: string;\n password: string;\n disabled: boolean;\n hideEmail: boolean;\n\n constructor(response?: SendResponse, userId?: string) {\n if (response == null) {\n return;\n }\n\n this.id = response.id;\n this.accessId = response.accessId;\n this.userId = userId;\n this.type = response.type;\n this.name = response.name;\n this.notes = response.notes;\n this.key = response.key;\n this.maxAccessCount = response.maxAccessCount;\n this.accessCount = response.accessCount;\n this.revisionDate = response.revisionDate;\n this.expirationDate = response.expirationDate;\n this.deletionDate = response.deletionDate;\n this.password = response.password;\n this.disabled = response.disable;\n this.hideEmail = response.hideEmail;\n\n switch (this.type) {\n case SendType.Text:\n this.text = new SendTextData(response.text);\n break;\n case SendType.File:\n this.file = new SendFileData(response.file);\n break;\n default:\n break;\n }\n }\n}\n","import { enableProdMode } from '@angular/core';\nimport { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\n\nimport 'bootstrap';\nimport 'jquery';\nimport 'popper.js';\n\n// tslint:disable-next-line\nrequire('src/scss/styles.scss');\n\nimport { AppModule } from './app.module';\n\nif (process.env.NODE_ENV === 'production') {\n enableProdMode();\n}\n\nplatformBrowserDynamic().bootstrapModule(AppModule, { preserveWhitespaces: true });\n","// extracted by mini-css-extract-plugin\nexport {};","import { ToasterModule } from 'angular2-toaster';\nimport { InfiniteScrollModule } from 'ngx-infinite-scroll';\n\nimport { DragDropModule } from '@angular/cdk/drag-drop';\nimport { NgModule } from '@angular/core';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { BrowserAnimationsModule } from '@angular/platform-browser/animations';\nimport { RouterModule } from '@angular/router';\n\nimport { AppRoutingModule } from './app-routing.module';\nimport { AppComponent } from './app.component';\nimport { OrganizationsModule } from './organizations/organizations.module';\nimport { DisablePersonalVaultExportPolicyComponent } from './policies/disable-personal-vault-export.component';\nimport { MaximumVaultTimeoutPolicyComponent } from './policies/maximum-vault-timeout.component';\n\nimport { OssRoutingModule } from 'src/app/oss-routing.module';\nimport { OssModule } from 'src/app/oss.module';\nimport { ServicesModule } from 'src/app/services/services.module';\nimport { WildcardRoutingModule } from 'src/app/wildcard-routing.module';\n\n@NgModule({\n imports: [\n OssModule,\n BrowserAnimationsModule,\n FormsModule,\n ReactiveFormsModule,\n ServicesModule,\n ToasterModule.forRoot(),\n InfiniteScrollModule,\n DragDropModule,\n AppRoutingModule,\n OssRoutingModule,\n OrganizationsModule,\n RouterModule,\n WildcardRoutingModule, // Needs to be last to catch all non-existing routes\n ],\n declarations: [\n AppComponent,\n MaximumVaultTimeoutPolicyComponent,\n DisablePersonalVaultExportPolicyComponent,\n ],\n bootstrap: [AppComponent],\n})\nexport class AppModule { }\n","import { NgModule } from '@angular/core';\nimport { RouterModule, Routes } from '@angular/router';\n\nconst routes: Routes = [\n {\n path: 'providers',\n loadChildren: async () => (await import('./providers/providers.module')).ProvidersModule,\n },\n];\n\n@NgModule({\n imports: [RouterModule.forChild(routes)],\n exports: [RouterModule],\n})\nexport class AppRoutingModule { }\n","import { CommonModule } from '@angular/common';\nimport { ComponentFactoryResolver } from '@angular/core';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { ModalService } from 'jslib-angular/services/modal.service';\n\nimport { ProviderGuardService } from './services/provider-guard.service';\nimport { ProviderTypeGuardService } from './services/provider-type-guard.service';\nimport { ProviderService } from './services/provider.service';\n\nimport { ProvidersLayoutComponent } from './providers-layout.component';\nimport { ProvidersRoutingModule } from './providers-routing.module';\n\nimport { AddOrganizationComponent } from './clients/add-organization.component';\nimport { ClientsComponent } from './clients/clients.component';\nimport { CreateOrganizationComponent } from './clients/create-organization.component';\n\nimport { AcceptProviderComponent } from './manage/accept-provider.component';\nimport { BulkConfirmComponent } from './manage/bulk/bulk-confirm.component';\nimport { BulkRemoveComponent } from './manage/bulk/bulk-remove.component';\nimport { EventsComponent } from './manage/events.component';\nimport { ManageComponent } from './manage/manage.component';\nimport { PeopleComponent } from './manage/people.component';\nimport { UserAddEditComponent } from './manage/user-add-edit.component';\n\nimport { AccountComponent } from './settings/account.component';\nimport { SettingsComponent } from './settings/settings.component';\n\nimport { SetupProviderComponent } from './setup/setup-provider.component';\nimport { SetupComponent } from './setup/setup.component';\n\nimport { OssModule } from 'src/app/oss.module';\n\n@NgModule({\n imports: [\n CommonModule,\n FormsModule,\n OssModule,\n ProvidersRoutingModule,\n ],\n declarations: [\n AcceptProviderComponent,\n AccountComponent,\n AddOrganizationComponent,\n BulkConfirmComponent,\n BulkRemoveComponent,\n ClientsComponent,\n CreateOrganizationComponent,\n EventsComponent,\n ManageComponent,\n PeopleComponent,\n ProvidersLayoutComponent,\n SettingsComponent,\n SetupComponent,\n SetupProviderComponent,\n UserAddEditComponent,\n ],\n providers: [\n ProviderService,\n ProviderGuardService,\n ProviderTypeGuardService,\n ],\n})\nexport class ProvidersModule {\n constructor(modalService: ModalService, componentFactoryResolver: ComponentFactoryResolver) {\n modalService.registerComponentFactoryResolver(AddOrganizationComponent, componentFactoryResolver);\n }\n}\n","import {\n AfterViewInit,\n ChangeDetectorRef,\n Component,\n ComponentRef,\n ElementRef,\n OnDestroy,\n Type,\n ViewChild,\n ViewContainerRef\n} from '@angular/core';\n\nimport {\n ConfigurableFocusTrap,\n ConfigurableFocusTrapFactory,\n} from '@angular/cdk/a11y';\n\nimport { ModalService } from '../../services/modal.service';\n\nimport { ModalRef } from './modal.ref';\n\n@Component({\n selector: 'app-modal',\n template: '',\n})\nexport class DynamicModalComponent implements AfterViewInit, OnDestroy {\n componentRef: ComponentRef;\n\n @ViewChild('modalContent', { read: ViewContainerRef, static: true }) modalContentRef: ViewContainerRef;\n\n childComponentType: Type;\n setComponentParameters: (component: any) => void;\n\n private focusTrap: ConfigurableFocusTrap;\n\n constructor(private modalService: ModalService, private cd: ChangeDetectorRef,\n private el: ElementRef, private focusTrapFactory: ConfigurableFocusTrapFactory,\n public modalRef: ModalRef) { }\n\n ngAfterViewInit() {\n this.loadChildComponent(this.childComponentType);\n if (this.setComponentParameters != null) {\n this.setComponentParameters(this.componentRef.instance);\n }\n this.cd.detectChanges();\n\n this.modalRef.created(this.el.nativeElement);\n this.focusTrap = this.focusTrapFactory.create(this.el.nativeElement.querySelector('.modal-dialog'));\n if (this.el.nativeElement.querySelector('[appAutoFocus]') == null) {\n this.focusTrap.focusFirstTabbableElementWhenReady();\n }\n }\n\n loadChildComponent(componentType: Type) {\n const componentFactory = this.modalService.resolveComponentFactory(componentType);\n\n this.modalContentRef.clear();\n this.componentRef = this.modalContentRef.createComponent(componentFactory);\n }\n\n ngOnDestroy() {\n if (this.componentRef) {\n this.componentRef.destroy();\n }\n this.focusTrap.destroy();\n }\n\n close() {\n this.modalRef.close();\n }\n\n getFocus() {\n const autoFocusEl = this.el.nativeElement.querySelector('[appAutoFocus]') as HTMLElement;\n autoFocusEl?.focus();\n }\n}\n","import {\n InjectFlags,\n InjectionToken,\n Injector,\n Type\n} from '@angular/core';\n\nexport class ModalInjector implements Injector {\n constructor(private _parentInjector: Injector, private _additionalTokens: WeakMap) {}\n\n get(token: Type | InjectionToken, notFoundValue?: T, flags?: InjectFlags): T;\n get(token: any, notFoundValue?: any, flags?: any) {\n return this._additionalTokens.get(token) ?? this._parentInjector.get(token, notFoundValue);\n }\n}\n","export class ProviderAddOrganizationRequest {\n organizationId: string;\n key: string;\n}\n","export function getDomain(host: string): string | null {\n return null;\n}\n\nexport function isValid(host: string): boolean {\n return true;\n}\n","import { NgModule } from '@angular/core';\nimport { RouterModule, Routes } from '@angular/router';\n\nimport { AuthGuardService } from 'jslib-angular/services/auth-guard.service';\nimport { Permissions } from 'jslib-common/enums/permissions';\n\nimport { AddOrganizationComponent } from './clients/add-organization.component';\nimport { ClientsComponent } from './clients/clients.component';\nimport { CreateOrganizationComponent } from './clients/create-organization.component';\nimport { AcceptProviderComponent } from './manage/accept-provider.component';\nimport { EventsComponent } from './manage/events.component';\nimport { ManageComponent } from './manage/manage.component';\nimport { PeopleComponent } from './manage/people.component';\nimport { ProvidersLayoutComponent } from './providers-layout.component';\nimport { SettingsComponent } from './settings/settings.component';\nimport { SetupProviderComponent } from './setup/setup-provider.component';\nimport { SetupComponent } from './setup/setup.component';\n\nimport { FrontendLayoutComponent } from 'src/app/layouts/frontend-layout.component';\n\nimport { ProvidersComponent } from 'src/app/providers/providers.component';\nimport { ProviderGuardService } from './services/provider-guard.service';\nimport { ProviderTypeGuardService } from './services/provider-type-guard.service';\nimport { AccountComponent } from './settings/account.component';\n\nconst routes: Routes = [\n {\n path: '',\n canActivate: [AuthGuardService],\n component: ProvidersComponent,\n },\n {\n path: '',\n component: FrontendLayoutComponent,\n children: [\n {\n path: 'setup-provider',\n component: SetupProviderComponent,\n data: { titleId: 'setupProvider' },\n },\n {\n path: 'accept-provider',\n component: AcceptProviderComponent,\n data: { titleId: 'acceptProvider' },\n },\n ],\n },\n {\n path: '',\n canActivate: [AuthGuardService],\n children: [\n {\n path: 'setup',\n component: SetupComponent,\n },\n {\n path: ':providerId',\n component: ProvidersLayoutComponent,\n canActivate: [ProviderGuardService],\n children: [\n { path: '', pathMatch: 'full', redirectTo: 'clients' },\n { path: 'clients/create', component: CreateOrganizationComponent },\n { path: 'clients', component: ClientsComponent, data: { titleId: 'clients' } },\n {\n path: 'manage',\n component: ManageComponent,\n children: [\n {\n path: '',\n pathMatch: 'full',\n redirectTo: 'people',\n },\n {\n path: 'people',\n component: PeopleComponent,\n canActivate: [ProviderTypeGuardService],\n data: {\n titleId: 'people',\n permissions: [Permissions.ManageUsers],\n },\n },\n {\n path: 'events',\n component: EventsComponent,\n canActivate: [ProviderTypeGuardService],\n data: {\n titleId: 'eventLogs',\n permissions: [Permissions.AccessEventLogs],\n },\n },\n ],\n },\n {\n path: 'settings',\n component: SettingsComponent,\n children: [\n {\n path: '',\n pathMatch: 'full',\n redirectTo: 'account',\n },\n {\n path: 'account',\n component: AccountComponent,\n canActivate: [ProviderTypeGuardService],\n data: {\n titleId: 'myProvider',\n permissions: [Permissions.ManageProvider],\n },\n },\n ],\n },\n ],\n },\n ],\n },\n];\n\n@NgModule({\n imports: [RouterModule.forChild(routes)],\n exports: [RouterModule],\n})\nexport class ProvidersRoutingModule { }\n","// extracted by mini-css-extract-plugin\nexport default {\"darkInputColor\":\"#fff\",\"darkInputPlaceholderColor\":\"#bac0ce\",\"lightInputColor\":\"#465057\",\"lightInputPlaceholderColor\":\"#b6b8b8\"};","import { PaymentMethodType } from '../../enums/paymentMethodType';\nimport { PlanType } from '../../enums/planType';\n\nimport { OrganizationKeysRequest } from './organizationKeysRequest';\n\nexport class OrganizationCreateRequest {\n name: string;\n businessName: string;\n billingEmail: string;\n planType: PlanType;\n key: string;\n keys: OrganizationKeysRequest;\n paymentMethodType: PaymentMethodType;\n paymentToken: string;\n additionalSeats: number;\n maxAutoscaleSeats: number;\n additionalStorageGb: number;\n premiumAccessAddon: boolean;\n collectionName: string;\n taxIdNumber: string;\n billingAddressLine1: string;\n billingAddressLine2: string;\n billingAddressCity: string;\n billingAddressState: string;\n billingAddressPostalCode: string;\n billingAddressCountry: string;\n}\n","import { PlanType } from '../../enums/planType';\n\nimport { OrganizationKeysRequest } from './organizationKeysRequest';\n\nexport class OrganizationUpgradeRequest {\n businessName: string;\n planType: PlanType;\n additionalSeats: number;\n additionalStorageGb: number;\n premiumAccessAddon: boolean;\n billingAddressCountry: string;\n billingAddressPostalCode: string;\n keys: OrganizationKeysRequest;\n}\n","import { OrganizationCreateRequest } from '../organizationCreateRequest';\n\nexport class ProviderOrganizationCreateRequest {\n constructor(public clientOwnerEmail: string, public organizationCreateRequest: OrganizationCreateRequest) { }\n}\n","export class ProviderUserAcceptRequest {\n token: string;\n}\n","import { EventType } from '../../enums/eventType';\n\nexport class EventView {\n message: string;\n humanReadableMessage: string;\n appIcon: string;\n appName: string;\n userId: string;\n userName: string;\n userEmail: string;\n date: string;\n ip: string;\n type: EventType;\n\n constructor(data: Required) {\n this.message = data.message;\n this.humanReadableMessage = data.humanReadableMessage;\n this.appIcon = data.appIcon;\n this.appName = data.appName;\n this.userId = data.userId;\n this.userName = data.userName;\n this.userEmail = data.userEmail;\n this.date = data.date;\n this.ip = data.ip;\n this.type = data.type;\n }\n}\n","export class ProviderUserConfirmRequest {\n key: string;\n}\n","type ProviderUserBulkRequestEntry = {\n id: string;\n key: string;\n};\n\nexport class ProviderUserBulkConfirmRequest {\n keys: ProviderUserBulkRequestEntry[];\n\n constructor(keys: ProviderUserBulkRequestEntry[]) {\n this.keys = keys;\n }\n}\n","type OrganizationUserBulkRequestEntry = {\n id: string;\n key: string;\n};\n\nexport class OrganizationUserBulkConfirmRequest {\n keys: OrganizationUserBulkRequestEntry[];\n\n constructor(keys: OrganizationUserBulkRequestEntry[]) {\n this.keys = keys;\n }\n}\n","import { ProviderUserType } from '../../../enums/providerUserType';\n\nexport class ProviderUserInviteRequest {\n emails: string[] = [];\n type: ProviderUserType;\n}\n","import { ProviderUserType } from '../../../enums/providerUserType';\n\nexport class ProviderUserUpdateRequest {\n type: ProviderUserType;\n}\n","export class ProviderSetupRequest {\n name: string;\n businessName: string;\n billingEmail: string;\n token: string;\n key: string;\n}\n","export class ProviderUpdateRequest {\n name: string;\n businessName: string;\n billingEmail: string;\n}\n","import { BroadcasterService as BroadcasterServiceAbstraction } from '../abstractions/broadcaster.service';\n\nexport class BroadcasterService implements BroadcasterServiceAbstraction {\n subscribers: Map any> = new Map any>();\n\n send(message: any, id?: string) {\n if (id != null) {\n if (this.subscribers.has(id)) {\n this.subscribers.get(id)(message);\n }\n return;\n }\n\n this.subscribers.forEach(value => {\n value(message);\n });\n }\n\n subscribe(id: string, messageCallback: (message: any) => any) {\n this.subscribers.set(id, messageCallback);\n }\n\n unsubscribe(id: string) {\n if (this.subscribers.has(id)) {\n this.subscribers.delete(id);\n }\n }\n}\n","export class EmergencyAccessAcceptRequest {\n token: string;\n}\n","export class OrganizationUserAcceptRequest {\n token: string;\n}\n","import { Router } from '@angular/router';\n\nimport { PasswordHintRequest } from 'jslib-common/models/request/passwordHintRequest';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nexport class HintComponent {\n email: string = '';\n formPromise: Promise;\n\n protected successRoute = 'login';\n protected onSuccessfulSubmit: () => void;\n\n constructor(protected router: Router, protected i18nService: I18nService,\n protected apiService: ApiService, protected platformUtilsService: PlatformUtilsService,\n private logService: LogService) { }\n\n async submit() {\n if (this.email == null || this.email === '') {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('emailRequired'));\n return;\n }\n if (this.email.indexOf('@') === -1) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('invalidEmail'));\n return;\n }\n\n try {\n this.formPromise = this.apiService.postPasswordHint(new PasswordHintRequest(this.email));\n await this.formPromise;\n this.platformUtilsService.showToast('success', null, this.i18nService.t('masterPassSent'));\n if (this.onSuccessfulSubmit != null) {\n this.onSuccessfulSubmit();\n } else if (this.router != null) {\n this.router.navigate([this.successRoute]);\n }\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","export class PasswordHintRequest {\n email: string;\n\n constructor(email: string) {\n this.email = email;\n }\n}\n","import { Directive, OnInit } from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\nimport { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';\n\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\nimport { EncString } from 'jslib-common/models/domain/encString';\nimport { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';\n\nimport { SecretVerificationRequest } from 'jslib-common/models/request/secretVerificationRequest';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\nimport { HashPurpose } from 'jslib-common/enums/hashPurpose';\n\n@Directive()\nexport class LockComponent implements OnInit {\n masterPassword: string = '';\n pin: string = '';\n showPassword: boolean = false;\n email: string;\n pinLock: boolean = false;\n webVaultHostname: string = '';\n formPromise: Promise;\n supportsBiometric: boolean;\n biometricLock: boolean;\n biometricText: string;\n hideInput: boolean;\n\n protected successRoute: string = 'vault';\n protected onSuccessfulSubmit: () => void;\n\n private invalidPinAttempts = 0;\n private pinSet: [boolean, boolean];\n\n constructor(protected router: Router, protected i18nService: I18nService,\n protected platformUtilsService: PlatformUtilsService, protected messagingService: MessagingService,\n protected userService: UserService, protected cryptoService: CryptoService,\n protected storageService: StorageService, protected vaultTimeoutService: VaultTimeoutService,\n protected environmentService: EnvironmentService, protected stateService: StateService,\n protected apiService: ApiService, private logService: LogService,\n private keyConnectorService: KeyConnectorService) { }\n\n async ngOnInit() {\n this.pinSet = await this.vaultTimeoutService.isPinLockSet();\n this.pinLock = (this.pinSet[0] && this.vaultTimeoutService.pinProtectedKey != null) || this.pinSet[1];\n this.supportsBiometric = await this.platformUtilsService.supportsBiometric();\n this.biometricLock = await this.vaultTimeoutService.isBiometricLockSet() &&\n (await this.cryptoService.hasKeyStored('biometric') || !this.platformUtilsService.supportsSecureStorage());\n this.biometricText = await this.storageService.get(ConstantsService.biometricText);\n this.email = await this.userService.getEmail();\n const usesKeyConnector = await this.keyConnectorService.getUsesKeyConnector();\n this.hideInput = usesKeyConnector && !this.pinLock;\n\n // Users with key connector and without biometric or pin has no MP to unlock using\n if (usesKeyConnector && !(this.biometricLock || this.pinLock)) {\n await this.vaultTimeoutService.logOut();\n }\n\n const webVaultUrl = this.environmentService.getWebVaultUrl();\n const vaultUrl = webVaultUrl === 'https://vault.bitwarden.com' ? 'https://bitwarden.com' : webVaultUrl;\n this.webVaultHostname = Utils.getHostname(vaultUrl);\n }\n\n async submit() {\n if (this.pinLock && (this.pin == null || this.pin === '')) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('pinRequired'));\n return;\n }\n if (!this.pinLock && (this.masterPassword == null || this.masterPassword === '')) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPassRequired'));\n return;\n }\n\n const kdf = await this.userService.getKdf();\n const kdfIterations = await this.userService.getKdfIterations();\n\n if (this.pinLock) {\n let failed = true;\n try {\n if (this.pinSet[0]) {\n const key = await this.cryptoService.makeKeyFromPin(this.pin, this.email, kdf, kdfIterations,\n this.vaultTimeoutService.pinProtectedKey);\n const encKey = await this.cryptoService.getEncKey(key);\n const protectedPin = await this.storageService.get(ConstantsService.protectedPin);\n const decPin = await this.cryptoService.decryptToUtf8(new EncString(protectedPin), encKey);\n failed = decPin !== this.pin;\n if (!failed) {\n await this.setKeyAndContinue(key);\n }\n } else {\n const key = await this.cryptoService.makeKeyFromPin(this.pin, this.email, kdf, kdfIterations);\n failed = false;\n await this.setKeyAndContinue(key);\n }\n } catch {\n failed = true;\n }\n\n if (failed) {\n this.invalidPinAttempts++;\n if (this.invalidPinAttempts >= 5) {\n this.messagingService.send('logout');\n return;\n }\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('invalidPin'));\n }\n } else {\n const key = await this.cryptoService.makeKey(this.masterPassword, this.email, kdf, kdfIterations);\n const storedKeyHash = await this.cryptoService.getKeyHash();\n\n let passwordValid = false;\n\n if (storedKeyHash != null) {\n passwordValid = await this.cryptoService.compareAndUpdateKeyHash(this.masterPassword, key);\n } else {\n const request = new SecretVerificationRequest();\n const serverKeyHash = await this.cryptoService.hashPassword(this.masterPassword, key,\n HashPurpose.ServerAuthorization);\n request.masterPasswordHash = serverKeyHash;\n try {\n this.formPromise = this.apiService.postAccountVerifyPassword(request);\n await this.formPromise;\n passwordValid = true;\n const localKeyHash = await this.cryptoService.hashPassword(this.masterPassword, key,\n HashPurpose.LocalAuthorization);\n await this.cryptoService.setKeyHash(localKeyHash);\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n if (passwordValid) {\n if (this.pinSet[0]) {\n const protectedPin = await this.storageService.get(ConstantsService.protectedPin);\n const encKey = await this.cryptoService.getEncKey(key);\n const decPin = await this.cryptoService.decryptToUtf8(new EncString(protectedPin), encKey);\n const pinKey = await this.cryptoService.makePinKey(decPin, this.email, kdf, kdfIterations);\n this.vaultTimeoutService.pinProtectedKey = await this.cryptoService.encrypt(key.key, pinKey);\n }\n this.setKeyAndContinue(key);\n } else {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('invalidMasterPassword'));\n }\n }\n }\n\n async logOut() {\n const confirmed = await this.platformUtilsService.showDialog(this.i18nService.t('logOutConfirmation'),\n this.i18nService.t('logOut'), this.i18nService.t('logOut'), this.i18nService.t('cancel'));\n if (confirmed) {\n this.messagingService.send('logout');\n }\n }\n\n async unlockBiometric(): Promise {\n if (!this.biometricLock) {\n return;\n }\n\n const success = (await this.cryptoService.getKey('biometric')) != null;\n\n if (success) {\n await this.doContinue();\n }\n\n return success;\n }\n\n togglePassword() {\n this.showPassword = !this.showPassword;\n document.getElementById(this.pinLock ? 'pin' : 'masterPassword').focus();\n }\n\n private async setKeyAndContinue(key: SymmetricCryptoKey) {\n await this.cryptoService.setKey(key);\n this.doContinue();\n }\n\n private async doContinue() {\n this.vaultTimeoutService.biometricLocked = false;\n this.vaultTimeoutService.everBeenUnlocked = true;\n const disableFavicon = await this.storageService.get(ConstantsService.disableFaviconKey);\n await this.stateService.save(ConstantsService.disableFaviconKey, !!disableFavicon);\n this.messagingService.send('unlocked');\n if (this.onSuccessfulSubmit != null) {\n this.onSuccessfulSubmit();\n } else if (this.router != null) {\n this.router.navigate([this.successRoute]);\n }\n }\n}\n","import {\n Directive,\n Input,\n OnInit,\n} from '@angular/core';\n\nimport { Router } from '@angular/router';\n\nimport { AuthResult } from 'jslib-common/models/domain/authResult';\n\nimport { AuthService } from 'jslib-common/abstractions/auth.service';\nimport { CryptoFunctionService } from 'jslib-common/abstractions/cryptoFunction.service';\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\n\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\nimport { CaptchaProtectedComponent } from './captchaProtected.component';\n\nconst Keys = {\n rememberedEmail: 'rememberedEmail',\n rememberEmail: 'rememberEmail',\n};\n\n@Directive()\nexport class LoginComponent extends CaptchaProtectedComponent implements OnInit {\n @Input() email: string = '';\n @Input() rememberEmail = true;\n\n masterPassword: string = '';\n showPassword: boolean = false;\n formPromise: Promise;\n onSuccessfulLogin: () => Promise;\n onSuccessfulLoginNavigate: () => Promise;\n onSuccessfulLoginTwoFactorNavigate: () => Promise;\n onSuccessfulLoginForceResetNavigate: () => Promise;\n\n protected twoFactorRoute = '2fa';\n protected successRoute = 'vault';\n protected forcePasswordResetRoute = 'update-temp-password';\n\n constructor(protected authService: AuthService, protected router: Router,\n platformUtilsService: PlatformUtilsService, i18nService: I18nService,\n protected stateService: StateService, environmentService: EnvironmentService,\n protected passwordGenerationService: PasswordGenerationService,\n protected cryptoFunctionService: CryptoFunctionService, private storageService: StorageService,\n protected logService: LogService) {\n super(environmentService, i18nService, platformUtilsService);\n }\n\n async ngOnInit() {\n if (this.email == null || this.email === '') {\n this.email = await this.storageService.get(Keys.rememberedEmail);\n if (this.email == null) {\n this.email = '';\n }\n }\n this.rememberEmail = await this.storageService.get(Keys.rememberEmail);\n if (this.rememberEmail == null) {\n this.rememberEmail = true;\n }\n if (Utils.isBrowser && !Utils.isNode) {\n this.focusInput();\n }\n }\n\n async submit() {\n await this.setupCaptcha();\n\n if (this.email == null || this.email === '') {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('emailRequired'));\n return;\n }\n if (this.email.indexOf('@') === -1) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('invalidEmail'));\n return;\n }\n if (this.masterPassword == null || this.masterPassword === '') {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPassRequired'));\n return;\n }\n\n try {\n this.formPromise = this.authService.logIn(this.email, this.masterPassword, this.captchaToken);\n const response = await this.formPromise;\n await this.storageService.save(Keys.rememberEmail, this.rememberEmail);\n if (this.rememberEmail) {\n await this.storageService.save(Keys.rememberedEmail, this.email);\n } else {\n await this.storageService.remove(Keys.rememberedEmail);\n }\n if (this.handleCaptchaRequired(response)) {\n return;\n } else if (response.twoFactor) {\n if (this.onSuccessfulLoginTwoFactorNavigate != null) {\n this.onSuccessfulLoginTwoFactorNavigate();\n } else {\n this.router.navigate([this.twoFactorRoute]);\n }\n } else if (response.forcePasswordReset) {\n if (this.onSuccessfulLoginForceResetNavigate != null) {\n this.onSuccessfulLoginForceResetNavigate();\n } else {\n this.router.navigate([this.forcePasswordResetRoute]);\n }\n } else {\n const disableFavicon = await this.storageService.get(ConstantsService.disableFaviconKey);\n await this.stateService.save(ConstantsService.disableFaviconKey, !!disableFavicon);\n if (this.onSuccessfulLogin != null) {\n this.onSuccessfulLogin();\n }\n if (this.onSuccessfulLoginNavigate != null) {\n this.onSuccessfulLoginNavigate();\n } else {\n this.router.navigate([this.successRoute]);\n }\n }\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n togglePassword() {\n this.showPassword = !this.showPassword;\n document.getElementById('masterPassword').focus();\n }\n\n async launchSsoBrowser(clientId: string, ssoRedirectUri: string) {\n // Generate necessary sso params\n const passwordOptions: any = {\n type: 'password',\n length: 64,\n uppercase: true,\n lowercase: true,\n numbers: true,\n special: false,\n };\n const state = await this.passwordGenerationService.generatePassword(passwordOptions);\n const ssoCodeVerifier = await this.passwordGenerationService.generatePassword(passwordOptions);\n const codeVerifierHash = await this.cryptoFunctionService.hash(ssoCodeVerifier, 'sha256');\n const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);\n\n // Save sso params\n await this.storageService.save(ConstantsService.ssoStateKey, state);\n await this.storageService.save(ConstantsService.ssoCodeVerifierKey, ssoCodeVerifier);\n\n // Build URI\n const webUrl = this.environmentService.getWebVaultUrl();\n\n // Launch browser\n this.platformUtilsService.launchUri(webUrl + '/#/sso?clientId=' + clientId +\n '&redirectUri=' + encodeURIComponent(ssoRedirectUri) +\n '&state=' + state + '&codeChallenge=' + codeChallenge);\n }\n\n protected focusInput() {\n document.getElementById(this.email == null || this.email === '' ? 'email' : 'masterPassword').focus();\n }\n}\n","import { I18nService } from '../abstractions/i18n.service';\nimport { IFrameComponent } from './iframe_component';\n\nexport class CaptchaIFrame extends IFrameComponent {\n constructor(win: Window, webVaultUrl: string,\n private i18nService: I18nService, successCallback: (message: string) => any, errorCallback: (message: string) => any,\n infoCallback: (message: string) => any) {\n super(win, webVaultUrl, 'captcha-connector.html', 'hcaptcha_iframe', successCallback, errorCallback, (message: string) => {\n const parsedMessage = JSON.parse(message);\n if (typeof (parsedMessage) !== 'string') {\n this.iframe.height = (parsedMessage.height).toString();\n this.iframe.width = (parsedMessage.width).toString();\n } else {\n infoCallback(parsedMessage);\n }\n });\n }\n\n init(siteKey: string): void {\n super.initComponent(this.createParams({ siteKey: siteKey, locale: this.i18nService.translationLocale }, 1));\n }\n}\n","import { I18nService } from '../abstractions/i18n.service';\n\nexport abstract class IFrameComponent {\n iframe: HTMLIFrameElement;\n private connectorLink: HTMLAnchorElement;\n private parseFunction = this.parseMessage.bind(this);\n\n constructor(private win: Window, protected webVaultUrl: string, private path: string, private iframeId: string,\n public successCallback?: (message: string) => any,\n public errorCallback?: (message: string) => any, public infoCallback?: (message: string) => any) {\n this.connectorLink = win.document.createElement('a');\n }\n\n stop() {\n this.sendMessage('stop');\n }\n\n start() {\n this.sendMessage('start');\n }\n\n sendMessage(message: any) {\n if (!this.iframe || !this.iframe.src || !this.iframe.contentWindow) {\n return;\n }\n\n this.iframe.contentWindow.postMessage(message, this.iframe.src);\n }\n\n base64Encode(str: string): string {\n return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (match, p1) => {\n return String.fromCharCode(('0x' + p1) as any);\n }));\n }\n\n cleanup() {\n this.win.removeEventListener('message', this.parseFunction, false);\n }\n\n protected createParams(data: any, version: number) {\n return new URLSearchParams({\n data: this.base64Encode(JSON.stringify(data)),\n parent: encodeURIComponent(this.win.document.location.href),\n v: version.toString(),\n });\n }\n\n protected initComponent(params: URLSearchParams): void {\n this.connectorLink.href = `${this.webVaultUrl}/${this.path}?${params}`;\n this.iframe = this.win.document.getElementById(this.iframeId) as HTMLIFrameElement;\n this.iframe.src = this.connectorLink.href;\n\n this.win.addEventListener('message', this.parseFunction, false);\n }\n\n private parseMessage(event: MessageEvent) {\n if (!this.validMessage(event)) {\n return;\n }\n\n const parts: string[] = event.data.split('|');\n if (parts[0] === 'success' && this.successCallback) {\n this.successCallback(parts[1]);\n } else if (parts[0] === 'error' && this.errorCallback) {\n this.errorCallback(parts[1]);\n } else if (parts[0] === 'info' && this.infoCallback) {\n this.infoCallback(parts[1]);\n }\n }\n\n private validMessage(event: MessageEvent) {\n if (event.origin == null || event.origin === '' || event.origin !== (this.connectorLink as any).origin ||\n event.data == null || typeof (event.data) !== 'string') {\n return false;\n }\n\n return event.data.indexOf('success|') === 0 || event.data.indexOf('error|') === 0 ||\n event.data.indexOf('info|') === 0;\n }\n}\n","export class DeleteRecoverRequest {\n email: string;\n}\n","import { SecretVerificationRequest } from './secretVerificationRequest';\n\nexport class TwoFactorRecoveryRequest extends SecretVerificationRequest {\n recoveryCode: string;\n email: string;\n}\n","import { Directive, OnInit } from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { KeysRequest } from 'jslib-common/models/request/keysRequest';\nimport { ReferenceEventRequest } from 'jslib-common/models/request/referenceEventRequest';\nimport { RegisterRequest } from 'jslib-common/models/request/registerRequest';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { AuthService } from 'jslib-common/abstractions/auth.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\n\nimport { KdfType } from 'jslib-common/enums/kdfType';\n\nimport { CaptchaProtectedComponent } from './captchaProtected.component';\n\n@Directive()\nexport class RegisterComponent extends CaptchaProtectedComponent implements OnInit {\n name: string = '';\n email: string = '';\n masterPassword: string = '';\n confirmMasterPassword: string = '';\n hint: string = '';\n showPassword: boolean = false;\n formPromise: Promise;\n masterPasswordScore: number;\n referenceData: ReferenceEventRequest;\n showTerms = true;\n acceptPolicies: boolean = false;\n\n protected successRoute = 'login';\n private masterPasswordStrengthTimeout: any;\n\n constructor(protected authService: AuthService, protected router: Router,\n i18nService: I18nService, protected cryptoService: CryptoService,\n protected apiService: ApiService, protected stateService: StateService,\n platformUtilsService: PlatformUtilsService,\n protected passwordGenerationService: PasswordGenerationService, environmentService: EnvironmentService,\n protected logService: LogService) {\n super(environmentService, i18nService, platformUtilsService);\n this.showTerms = !platformUtilsService.isSelfHost();\n }\n\n async ngOnInit() {\n this.setupCaptcha();\n }\n\n get masterPasswordScoreWidth() {\n return this.masterPasswordScore == null ? 0 : (this.masterPasswordScore + 1) * 20;\n }\n\n get masterPasswordScoreColor() {\n switch (this.masterPasswordScore) {\n case 4:\n return 'success';\n case 3:\n return 'primary';\n case 2:\n return 'warning';\n default:\n return 'danger';\n }\n }\n\n get masterPasswordScoreText() {\n switch (this.masterPasswordScore) {\n case 4:\n return this.i18nService.t('strong');\n case 3:\n return this.i18nService.t('good');\n case 2:\n return this.i18nService.t('weak');\n default:\n return this.masterPasswordScore != null ? this.i18nService.t('weak') : null;\n }\n }\n\n async submit() {\n if (!this.acceptPolicies && this.showTerms) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('acceptPoliciesError'));\n return;\n }\n\n if (this.email == null || this.email === '') {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('emailRequired'));\n return;\n }\n if (this.email.indexOf('@') === -1) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('invalidEmail'));\n return;\n }\n if (this.masterPassword == null || this.masterPassword === '') {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPassRequired'));\n return;\n }\n if (this.masterPassword.length < 8) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPassLength'));\n return;\n }\n if (this.masterPassword !== this.confirmMasterPassword) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('masterPassDoesntMatch'));\n return;\n }\n\n const strengthResult = this.passwordGenerationService.passwordStrength(this.masterPassword,\n this.getPasswordStrengthUserInput());\n if (strengthResult != null && strengthResult.score < 3) {\n const result = await this.platformUtilsService.showDialog(this.i18nService.t('weakMasterPasswordDesc'),\n this.i18nService.t('weakMasterPassword'), this.i18nService.t('yes'), this.i18nService.t('no'),\n 'warning');\n if (!result) {\n return;\n }\n }\n\n if (this.hint === this.masterPassword) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('hintEqualsPassword'));\n return;\n }\n\n this.name = this.name === '' ? null : this.name;\n this.email = this.email.trim().toLowerCase();\n const kdf = KdfType.PBKDF2_SHA256;\n const useLowerKdf = this.platformUtilsService.isIE();\n const kdfIterations = useLowerKdf ? 10000 : 100000;\n const key = await this.cryptoService.makeKey(this.masterPassword, this.email, kdf, kdfIterations);\n const encKey = await this.cryptoService.makeEncKey(key);\n const hashedPassword = await this.cryptoService.hashPassword(this.masterPassword, key);\n const keys = await this.cryptoService.makeKeyPair(encKey[0]);\n const request = new RegisterRequest(this.email, this.name, hashedPassword,\n this.hint, encKey[1].encryptedString, kdf, kdfIterations, this.referenceData, this.captchaToken);\n request.keys = new KeysRequest(keys[0], keys[1].encryptedString);\n const orgInvite = await this.stateService.get('orgInvitation');\n if (orgInvite != null && orgInvite.token != null && orgInvite.organizationUserId != null) {\n request.token = orgInvite.token;\n request.organizationUserId = orgInvite.organizationUserId;\n }\n\n try {\n this.formPromise = this.apiService.postRegister(request);\n try {\n await this.formPromise;\n } catch (e) {\n if (this.handleCaptchaRequired(e)) {\n return;\n } else {\n throw e;\n }\n }\n this.platformUtilsService.showToast('success', null, this.i18nService.t('newAccountCreated'));\n this.router.navigate([this.successRoute], { queryParams: { email: this.email } });\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n togglePassword(confirmField: boolean) {\n this.showPassword = !this.showPassword;\n document.getElementById(confirmField ? 'masterPasswordRetype' : 'masterPassword').focus();\n }\n\n updatePasswordStrength() {\n if (this.masterPasswordStrengthTimeout != null) {\n clearTimeout(this.masterPasswordStrengthTimeout);\n }\n this.masterPasswordStrengthTimeout = setTimeout(() => {\n const strengthResult = this.passwordGenerationService.passwordStrength(this.masterPassword,\n this.getPasswordStrengthUserInput());\n this.masterPasswordScore = strengthResult == null ? null : strengthResult.score;\n }, 300);\n }\n\n private getPasswordStrengthUserInput() {\n let userInput: string[] = [];\n const atPosition = this.email.indexOf('@');\n if (atPosition > -1) {\n userInput = userInput.concat(this.email.substr(0, atPosition).trim().toLowerCase().split(/[^A-Za-z0-9]/));\n }\n if (this.name != null && this.name !== '') {\n userInput = userInput.concat(this.name.trim().toLowerCase().split(' '));\n }\n return userInput;\n }\n}\n","import { KeysRequest } from './keysRequest';\nimport { ReferenceEventRequest } from './referenceEventRequest';\n\nimport { KdfType } from '../../enums/kdfType';\n\nimport { CaptchaProtectedRequest } from './captchaProtectedRequest';\n\nexport class RegisterRequest implements CaptchaProtectedRequest {\n masterPasswordHint: string;\n keys: KeysRequest;\n token: string;\n organizationUserId: string;\n\n\n constructor(public email: string, public name: string, public masterPasswordHash: string,\n masterPasswordHint: string, public key: string, public kdf: KdfType, public kdfIterations: number,\n public referenceData: ReferenceEventRequest, public captchaResponse: string) {\n this.masterPasswordHint = masterPasswordHint ? masterPasswordHint : null;\n }\n}\n","export class ReferenceEventRequest {\n id: string;\n layout: string;\n flow: string;\n}\n","import {\n Directive,\n OnInit,\n} from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\n\n@Directive()\nexport class RemovePasswordComponent implements OnInit {\n\n actionPromise: Promise;\n continuing: boolean = false;\n leaving: boolean = false;\n\n loading: boolean = true;\n organization: Organization;\n email: string;\n\n constructor(private router: Router, private userService: UserService,\n private apiService: ApiService, private syncService: SyncService,\n private platformUtilsService: PlatformUtilsService, private i18nService: I18nService,\n private keyConnectorService: KeyConnectorService, private storageService: StorageService) { }\n\n async ngOnInit() {\n this.organization = await this.keyConnectorService.getManagingOrganization();\n this.email = await this.userService.getEmail();\n await this.syncService.fullSync(false);\n this.loading = false;\n }\n\n async convert() {\n this.continuing = true;\n this.actionPromise = this.keyConnectorService.migrateUser();\n\n try {\n await this.actionPromise;\n this.platformUtilsService.showToast('success', null, this.i18nService.t('removedMasterPassword'));\n await this.keyConnectorService.removeConvertAccountRequired();\n this.router.navigate(['']);\n } catch (e) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), e.message);\n }\n }\n\n async leave() {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('leaveOrganizationConfirmation'), this.organization.name,\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.leaving = true;\n this.actionPromise = this.apiService.postLeaveOrganization(this.organization.id).then(() => {\n return this.syncService.fullSync(true);\n });\n await this.actionPromise;\n this.platformUtilsService.showToast('success', null, this.i18nService.t('leftOrganization'));\n await this.keyConnectorService.removeConvertAccountRequired();\n this.router.navigate(['']);\n } catch (e) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), e);\n }\n }\n}\n","import { Directive } from '@angular/core';\nimport {\n ActivatedRoute,\n Router\n} from '@angular/router';\n\nimport { first } from 'rxjs/operators';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { EncString } from 'jslib-common/models/domain/encString';\nimport { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';\n\nimport { KeysRequest } from 'jslib-common/models/request/keysRequest';\nimport { OrganizationUserResetPasswordEnrollmentRequest } from 'jslib-common/models/request/organizationUserResetPasswordEnrollmentRequest';\nimport { SetPasswordRequest } from 'jslib-common/models/request/setPasswordRequest';\n\nimport { ChangePasswordComponent as BaseChangePasswordComponent } from './change-password.component';\n\nimport { HashPurpose } from 'jslib-common/enums/hashPurpose';\nimport { KdfType } from 'jslib-common/enums/kdfType';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\n@Directive()\nexport class SetPasswordComponent extends BaseChangePasswordComponent {\n syncLoading: boolean = true;\n showPassword: boolean = false;\n hint: string = '';\n identifier: string = null;\n orgId: string;\n resetPasswordAutoEnroll = false;\n\n onSuccessfulChangePassword: () => Promise;\n successRoute = 'vault';\n\n constructor(i18nService: I18nService, cryptoService: CryptoService, messagingService: MessagingService,\n userService: UserService, passwordGenerationService: PasswordGenerationService,\n platformUtilsService: PlatformUtilsService, policyService: PolicyService, protected router: Router,\n private apiService: ApiService, private syncService: SyncService, private route: ActivatedRoute) {\n super(i18nService, cryptoService, messagingService, userService, passwordGenerationService,\n platformUtilsService, policyService);\n }\n\n async ngOnInit() {\n await this.syncService.fullSync(true);\n this.syncLoading = false;\n\n this.route.queryParams.pipe(first()).subscribe(async qParams => {\n if (qParams.identifier != null) {\n this.identifier = qParams.identifier;\n }\n });\n\n // Automatic Enrollment Detection\n if (this.identifier != null) {\n try {\n const response = await this.apiService.getOrganizationAutoEnrollStatus(this.identifier);\n this.orgId = response.id;\n this.resetPasswordAutoEnroll = response.resetPasswordEnabled;\n this.enforcedPolicyOptions =\n await this.policyService.getMasterPasswordPoliciesForInvitedUsers(this.orgId);\n } catch {\n this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred'));\n }\n }\n\n super.ngOnInit();\n }\n\n async setupSubmitActions() {\n this.kdf = KdfType.PBKDF2_SHA256;\n const useLowerKdf = this.platformUtilsService.isIE();\n this.kdfIterations = useLowerKdf ? 10000 : 100000;\n return true;\n }\n\n async performSubmitActions(masterPasswordHash: string, key: SymmetricCryptoKey,\n encKey: [SymmetricCryptoKey, EncString]) {\n const keys = await this.cryptoService.makeKeyPair(encKey[0]);\n const request = new SetPasswordRequest(\n masterPasswordHash,\n encKey[1].encryptedString,\n this.hint,\n this.kdf,\n this.kdfIterations,\n this.identifier,\n new KeysRequest(keys[0], keys[1].encryptedString)\n );\n try {\n if (this.resetPasswordAutoEnroll) {\n this.formPromise = this.apiService.setPassword(request).then(async () => {\n await this.onSetPasswordSuccess(key, encKey, keys);\n return this.apiService.getOrganizationKeys(this.orgId);\n }).then(async response => {\n if (response == null) {\n throw new Error(this.i18nService.t('resetPasswordOrgKeysError'));\n }\n const userId = await this.userService.getUserId();\n const publicKey = Utils.fromB64ToArray(response.publicKey);\n\n // RSA Encrypt user's encKey.key with organization public key\n const userEncKey = await this.cryptoService.getEncKey();\n const encryptedKey = await this.cryptoService.rsaEncrypt(userEncKey.key, publicKey.buffer);\n\n const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest();\n resetRequest.resetPasswordKey = encryptedKey.encryptedString;\n\n return this.apiService.putOrganizationUserResetPasswordEnrollment(this.orgId, userId, resetRequest);\n });\n } else {\n this.formPromise = this.apiService.setPassword(request).then(async () => {\n await this.onSetPasswordSuccess(key, encKey, keys);\n });\n }\n\n await this.formPromise;\n\n if (this.onSuccessfulChangePassword != null) {\n this.onSuccessfulChangePassword();\n } else {\n this.router.navigate([this.successRoute]);\n }\n } catch {\n this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred'));\n }\n }\n\n togglePassword(confirmField: boolean) {\n this.showPassword = !this.showPassword;\n document.getElementById(confirmField ? 'masterPasswordRetype' : 'masterPassword').focus();\n }\n\n private async onSetPasswordSuccess(key: SymmetricCryptoKey, encKey: [SymmetricCryptoKey, EncString], keys: [string, EncString]) {\n await this.userService.setInformation(await this.userService.getUserId(), await this.userService.getEmail(),\n this.kdf, this.kdfIterations);\n await this.cryptoService.setKey(key);\n await this.cryptoService.setEncKey(encKey[1].encryptedString);\n await this.cryptoService.setEncPrivateKey(keys[1].encryptedString);\n\n const localKeyHash = await this.cryptoService.hashPassword(this.masterPassword, key,\n HashPurpose.LocalAuthorization);\n await this.cryptoService.setKeyHash(localKeyHash);\n }\n}\n","import { KeysRequest } from './keysRequest';\n\nimport { KdfType } from '../../enums/kdfType';\n\nexport class SetPasswordRequest {\n masterPasswordHash: string;\n key: string;\n masterPasswordHint: string;\n keys: KeysRequest;\n kdf: KdfType;\n kdfIterations: number;\n orgIdentifier: string;\n\n constructor(masterPasswordHash: string, key: string, masterPasswordHint: string, kdf: KdfType,\n kdfIterations: number, orgIdentifier: string, keys: KeysRequest) {\n this.masterPasswordHash = masterPasswordHash;\n this.key = key;\n this.masterPasswordHint = masterPasswordHint;\n this.kdf = kdf;\n this.kdfIterations = kdfIterations;\n this.orgIdentifier = orgIdentifier;\n this.keys = keys;\n }\n}\n","import {\n Directive,\n EventEmitter,\n OnInit,\n Output,\n} from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\n\nimport { AuthService } from 'jslib-common/abstractions/auth.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\n@Directive()\nexport class TwoFactorOptionsComponent implements OnInit {\n @Output() onProviderSelected = new EventEmitter();\n @Output() onRecoverSelected = new EventEmitter();\n\n providers: any[] = [];\n\n constructor(protected authService: AuthService, protected router: Router,\n protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService,\n protected win: Window) { }\n\n ngOnInit() {\n this.providers = this.authService.getSupportedTwoFactorProviders(this.win);\n }\n\n choose(p: any) {\n this.onProviderSelected.emit(p.type);\n }\n\n recover() {\n this.platformUtilsService.launchUri('https://help.bitwarden.com/article/lost-two-step-device/');\n this.onRecoverSelected.emit();\n }\n}\n","import { Directive, OnDestroy, OnInit } from '@angular/core';\n\nimport {\n ActivatedRoute,\n Router,\n} from '@angular/router';\n\nimport { first } from 'rxjs/operators';\n\nimport { TwoFactorProviderType } from 'jslib-common/enums/twoFactorProviderType';\n\nimport { TwoFactorEmailRequest } from 'jslib-common/models/request/twoFactorEmailRequest';\n\nimport { AuthResult } from 'jslib-common/models/domain/authResult';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { AuthService } from 'jslib-common/abstractions/auth.service';\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\n\nimport { TwoFactorProviders } from 'jslib-common/services/auth.service';\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\nimport * as DuoWebSDK from 'duo_web_sdk';\nimport { WebAuthnIFrame } from 'jslib-common/misc/webauthn_iframe';\n\n@Directive()\nexport class TwoFactorComponent implements OnInit, OnDestroy {\n token: string = '';\n remember: boolean = false;\n webAuthnReady: boolean = false;\n webAuthnNewTab: boolean = false;\n providers = TwoFactorProviders;\n providerType = TwoFactorProviderType;\n selectedProviderType: TwoFactorProviderType = TwoFactorProviderType.Authenticator;\n webAuthnSupported: boolean = false;\n webAuthn: WebAuthnIFrame = null;\n title: string = '';\n twoFactorEmail: string = null;\n formPromise: Promise;\n emailPromise: Promise;\n identifier: string = null;\n onSuccessfulLogin: () => Promise;\n onSuccessfulLoginNavigate: () => Promise;\n\n get webAuthnAllow(): string {\n return `publickey-credentials-get ${this.environmentService.getWebVaultUrl()}`;\n }\n\n protected loginRoute = 'login';\n protected successRoute = 'vault';\n\n constructor(protected authService: AuthService, protected router: Router,\n protected i18nService: I18nService, protected apiService: ApiService,\n protected platformUtilsService: PlatformUtilsService, protected win: Window,\n protected environmentService: EnvironmentService, protected stateService: StateService,\n protected storageService: StorageService, protected route: ActivatedRoute,\n protected logService: LogService) {\n this.webAuthnSupported = this.platformUtilsService.supportsWebAuthn(win);\n }\n\n async ngOnInit() {\n if (!this.authing || this.authService.twoFactorProvidersData == null) {\n this.router.navigate([this.loginRoute]);\n return;\n }\n\n this.route.queryParams.pipe(first()).subscribe(qParams => {\n if (qParams.identifier != null) {\n this.identifier = qParams.identifier;\n }\n });\n\n if (this.needsLock) {\n this.successRoute = 'lock';\n }\n\n if (this.win != null && this.webAuthnSupported) {\n const webVaultUrl = this.environmentService.getWebVaultUrl();\n this.webAuthn = new WebAuthnIFrame(this.win, webVaultUrl, this.webAuthnNewTab, this.platformUtilsService,\n this.i18nService, (token: string) => {\n this.token = token;\n this.submit();\n }, (error: string) => {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), error);\n }, (info: string) => {\n if (info === 'ready') {\n this.webAuthnReady = true;\n }\n }\n );\n }\n\n this.selectedProviderType = this.authService.getDefaultTwoFactorProvider(this.webAuthnSupported);\n await this.init();\n }\n\n ngOnDestroy(): void {\n this.cleanupWebAuthn();\n this.webAuthn = null;\n }\n\n async init() {\n if (this.selectedProviderType == null) {\n this.title = this.i18nService.t('loginUnavailable');\n return;\n }\n\n this.cleanupWebAuthn();\n this.title = (TwoFactorProviders as any)[this.selectedProviderType].name;\n const providerData = this.authService.twoFactorProvidersData.get(this.selectedProviderType);\n switch (this.selectedProviderType) {\n case TwoFactorProviderType.WebAuthn:\n if (!this.webAuthnNewTab) {\n setTimeout(() => {\n this.authWebAuthn();\n }, 500);\n }\n break;\n case TwoFactorProviderType.Duo:\n case TwoFactorProviderType.OrganizationDuo:\n setTimeout(() => {\n DuoWebSDK.init({\n iframe: undefined,\n host: providerData.Host,\n sig_request: providerData.Signature,\n submit_callback: async (f: HTMLFormElement) => {\n const sig = f.querySelector('input[name=\"sig_response\"]') as HTMLInputElement;\n if (sig != null) {\n this.token = sig.value;\n await this.submit();\n }\n },\n });\n }, 0);\n break;\n case TwoFactorProviderType.Email:\n this.twoFactorEmail = providerData.Email;\n if (this.authService.twoFactorProvidersData.size > 1) {\n await this.sendEmail(false);\n }\n break;\n default:\n break;\n }\n }\n\n async submit() {\n if (this.token == null || this.token === '') {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('verificationCodeRequired'));\n return;\n }\n\n if (this.selectedProviderType === TwoFactorProviderType.WebAuthn) {\n if (this.webAuthn != null) {\n this.webAuthn.stop();\n } else {\n return;\n }\n } else if (this.selectedProviderType === TwoFactorProviderType.Email ||\n this.selectedProviderType === TwoFactorProviderType.Authenticator) {\n this.token = this.token.replace(' ', '').trim();\n }\n\n try {\n await this.doSubmit();\n } catch {\n if (this.selectedProviderType === TwoFactorProviderType.WebAuthn && this.webAuthn != null) {\n this.webAuthn.start();\n }\n }\n }\n\n async doSubmit() {\n this.formPromise = this.authService.logInTwoFactor(this.selectedProviderType, this.token, this.remember);\n const response: AuthResult = await this.formPromise;\n const disableFavicon = await this.storageService.get(ConstantsService.disableFaviconKey);\n await this.stateService.save(ConstantsService.disableFaviconKey, !!disableFavicon);\n if (this.onSuccessfulLogin != null) {\n this.onSuccessfulLogin();\n }\n if (response.resetMasterPassword) {\n this.successRoute = 'set-password';\n }\n if (response.forcePasswordReset) {\n this.successRoute = 'update-temp-password';\n }\n if (this.onSuccessfulLoginNavigate != null) {\n this.onSuccessfulLoginNavigate();\n } else {\n this.router.navigate([this.successRoute], {\n queryParams: {\n identifier: this.identifier,\n },\n });\n }\n }\n\n async sendEmail(doToast: boolean) {\n if (this.selectedProviderType !== TwoFactorProviderType.Email) {\n return;\n }\n\n if (this.emailPromise != null) {\n return;\n }\n\n try {\n const request = new TwoFactorEmailRequest();\n request.email = this.authService.email;\n request.masterPasswordHash = this.authService.masterPasswordHash;\n this.emailPromise = this.apiService.postTwoFactorEmail(request);\n await this.emailPromise;\n if (doToast) {\n this.platformUtilsService.showToast('success', null,\n this.i18nService.t('verificationCodeEmailSent', this.twoFactorEmail));\n }\n } catch (e) {\n this.logService.error(e);\n }\n\n this.emailPromise = null;\n }\n\n authWebAuthn() {\n const providerData = this.authService.twoFactorProvidersData.get(this.selectedProviderType);\n\n if (!this.webAuthnSupported || this.webAuthn == null) {\n return;\n }\n\n this.webAuthn.init(providerData);\n }\n\n private cleanupWebAuthn() {\n if (this.webAuthn != null) {\n this.webAuthn.stop();\n this.webAuthn.cleanup();\n }\n }\n\n get authing(): boolean {\n return this.authService.authingWithPassword() || this.authService.authingWithSso() || this.authService.authingWithApiKey();\n }\n\n get needsLock(): boolean {\n return this.authService.authingWithSso() || this.authService.authingWithApiKey();\n }\n}\n","import { TwoFactorProviderType } from '../../enums/twoFactorProviderType';\n\nexport class AuthResult {\n twoFactor: boolean = false;\n captchaSiteKey: string = '';\n resetMasterPassword: boolean = false;\n forcePasswordReset: boolean = false;\n twoFactorProviders: Map = null;\n}\n","import { KeysRequest } from '../keysRequest';\n\nimport { KdfType } from '../../../enums/kdfType';\n\nexport class SetKeyConnectorKeyRequest {\n key: string;\n keys: KeysRequest;\n kdf: KdfType;\n kdfIterations: number;\n orgIdentifier: string;\n\n constructor(key: string, kdf: KdfType, kdfIterations: number, orgIdentifier: string, keys: KeysRequest) {\n this.key = key;\n this.kdf = kdf;\n this.kdfIterations = kdfIterations;\n this.orgIdentifier = orgIdentifier;\n this.keys = keys;\n }\n}\n","import { DeviceType } from '../../enums/deviceType';\n\nimport { PlatformUtilsService } from '../../abstractions/platformUtils.service';\n\nexport class DeviceRequest {\n type: DeviceType;\n name: string;\n identifier: string;\n pushToken?: string;\n\n constructor(appId: string, platformUtilsService: PlatformUtilsService) {\n this.type = platformUtilsService.getDevice();\n this.name = platformUtilsService.getDeviceString();\n this.identifier = appId;\n this.pushToken = null;\n }\n}\n","export class PreloginRequest {\n email: string;\n\n constructor(email: string) {\n this.email = email;\n }\n}\n","import { TwoFactorProviderType } from '../../enums/twoFactorProviderType';\n\nimport { CaptchaProtectedRequest } from './captchaProtectedRequest';\nimport { DeviceRequest } from './deviceRequest';\n\nimport { Utils } from '../../misc/utils';\n\nexport class TokenRequest implements CaptchaProtectedRequest {\n email: string;\n masterPasswordHash: string;\n code: string;\n codeVerifier: string;\n redirectUri: string;\n clientId: string;\n clientSecret: string;\n device?: DeviceRequest;\n\n constructor(credentials: string[], codes: string[], clientIdClientSecret: string[], public provider: TwoFactorProviderType,\n public token: string, public remember: boolean, public captchaResponse: string, device?: DeviceRequest) {\n if (credentials != null && credentials.length > 1) {\n this.email = credentials[0];\n this.masterPasswordHash = credentials[1];\n } else if (codes != null && codes.length > 2) {\n this.code = codes[0];\n this.codeVerifier = codes[1];\n this.redirectUri = codes[2];\n } else if (clientIdClientSecret != null && clientIdClientSecret.length > 1) {\n this.clientId = clientIdClientSecret[0];\n this.clientSecret = clientIdClientSecret[1];\n }\n this.device = device != null ? device : null;\n }\n\n toIdentityToken(clientId: string) {\n const obj: any = {\n scope: 'api offline_access',\n client_id: clientId,\n };\n\n if (this.clientSecret != null) {\n obj.scope = clientId.startsWith('organization') ? 'api.organization' : 'api';\n obj.grant_type = 'client_credentials';\n obj.client_secret = this.clientSecret;\n } else if (this.masterPasswordHash != null && this.email != null) {\n obj.grant_type = 'password';\n obj.username = this.email;\n obj.password = this.masterPasswordHash;\n } else if (this.code != null && this.codeVerifier != null && this.redirectUri != null) {\n obj.grant_type = 'authorization_code';\n obj.code = this.code;\n obj.code_verifier = this.codeVerifier;\n obj.redirect_uri = this.redirectUri;\n } else {\n throw new Error('must provide credentials or codes');\n }\n\n if (this.device) {\n obj.deviceType = this.device.type;\n obj.deviceIdentifier = this.device.identifier;\n obj.deviceName = this.device.name;\n // no push tokens for browser apps yet\n // obj.devicePushToken = this.device.pushToken;\n }\n\n if (this.token && this.provider != null) {\n obj.twoFactorToken = this.token;\n obj.twoFactorProvider = this.provider;\n obj.twoFactorRemember = this.remember ? '1' : '0';\n }\n\n if (this.captchaResponse != null) {\n obj.captchaResponse = this.captchaResponse;\n }\n\n\n return obj;\n }\n\n alterIdentityTokenHeaders(headers: Headers) {\n if (this.clientSecret == null && this.masterPasswordHash != null && this.email != null) {\n headers.set('Auth-Email', Utils.fromUtf8ToUrlB64(this.email));\n }\n }\n}\n","import { I18nService } from '../abstractions/i18n.service';\nimport { PlatformUtilsService } from '../abstractions/platformUtils.service';\n\nexport class WebAuthnIFrame {\n private iframe: HTMLIFrameElement = null;\n private connectorLink: HTMLAnchorElement;\n private parseFunction = this.parseMessage.bind(this);\n\n constructor(private win: Window, private webVaultUrl: string, private webAuthnNewTab: boolean,\n private platformUtilsService: PlatformUtilsService, private i18nService: I18nService,\n private successCallback: Function, private errorCallback: Function, private infoCallback: Function) {\n this.connectorLink = win.document.createElement('a');\n }\n\n init(data: any): void {\n const params = new URLSearchParams({\n data: this.base64Encode(JSON.stringify(data)),\n parent: encodeURIComponent(this.win.document.location.href),\n btnText: encodeURIComponent(this.i18nService.t('webAuthnAuthenticate')),\n v: '1',\n });\n\n if (this.webAuthnNewTab) {\n // Firefox fallback which opens the webauthn page in a new tab\n params.append('locale', this.i18nService.translationLocale);\n this.platformUtilsService.launchUri(`${this.webVaultUrl}/webauthn-fallback-connector.html?${params}`);\n } else {\n this.connectorLink.href = `${this.webVaultUrl}/webauthn-connector.html?${params}`;\n this.iframe = this.win.document.getElementById('webauthn_iframe') as HTMLIFrameElement;\n this.iframe.allow = 'publickey-credentials-get ' + new URL(this.webVaultUrl).origin;\n this.iframe.src = this.connectorLink.href;\n\n this.win.addEventListener('message', this.parseFunction, false);\n }\n }\n\n stop() {\n this.sendMessage('stop');\n }\n\n start() {\n this.sendMessage('start');\n }\n\n sendMessage(message: any) {\n if (!this.iframe || !this.iframe.src || !this.iframe.contentWindow) {\n return;\n }\n\n this.iframe.contentWindow.postMessage(message, this.iframe.src);\n }\n\n base64Encode(str: string): string {\n return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (match, p1) => {\n return String.fromCharCode(('0x' + p1) as any);\n }));\n }\n\n cleanup() {\n this.win.removeEventListener('message', this.parseFunction, false);\n }\n\n private parseMessage(event: MessageEvent) {\n if (!this.validMessage(event)) {\n return;\n }\n\n const parts: string[] = event.data.split('|');\n if (parts[0] === 'success' && this.successCallback) {\n this.successCallback(parts[1]);\n } else if (parts[0] === 'error' && this.errorCallback) {\n this.errorCallback(parts[1]);\n } else if (parts[0] === 'info' && this.infoCallback) {\n this.infoCallback(parts[1]);\n }\n }\n\n private validMessage(event: MessageEvent) {\n if (event.origin == null || event.origin === '' || event.origin !== (this.connectorLink as any).origin ||\n event.data == null || typeof (event.data) !== 'string') {\n return false;\n }\n\n return event.data.indexOf('success|') === 0 || event.data.indexOf('error|') === 0 ||\n event.data.indexOf('info|') === 0;\n }\n}\n","import { Directive } from '@angular/core';\n\nimport { ApiService } from 'jslib-common/abstractions/api.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ChangePasswordComponent as BaseChangePasswordComponent } from './change-password.component';\n\nimport { EncString } from 'jslib-common/models/domain/encString';\nimport { MasterPasswordPolicyOptions } from 'jslib-common/models/domain/masterPasswordPolicyOptions';\nimport { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';\n\nimport { UpdateTempPasswordRequest } from 'jslib-common/models/request/updateTempPasswordRequest';\n\n@Directive()\nexport class UpdateTempPasswordComponent extends BaseChangePasswordComponent {\n hint: string;\n key: string;\n enforcedPolicyOptions: MasterPasswordPolicyOptions;\n showPassword: boolean = false;\n\n onSuccessfulChangePassword: () => Promise;\n\n constructor(i18nService: I18nService, platformUtilsService: PlatformUtilsService,\n passwordGenerationService: PasswordGenerationService, policyService: PolicyService,\n cryptoService: CryptoService, userService: UserService,\n messagingService: MessagingService, private apiService: ApiService,\n private syncService: SyncService, private logService: LogService) {\n super(i18nService, cryptoService, messagingService, userService, passwordGenerationService,\n platformUtilsService, policyService);\n }\n\n async ngOnInit() {\n await this.syncService.fullSync(true);\n super.ngOnInit();\n }\n\n togglePassword(confirmField: boolean) {\n this.showPassword = !this.showPassword;\n document.getElementById(confirmField ? 'masterPasswordRetype' : 'masterPassword').focus();\n }\n\n async setupSubmitActions(): Promise {\n this.enforcedPolicyOptions = await this.policyService.getMasterPasswordPolicyOptions();\n this.email = await this.userService.getEmail();\n this.kdf = await this.userService.getKdf();\n this.kdfIterations = await this.userService.getKdfIterations();\n return true;\n }\n\n async submit() {\n // Validation\n if (!await this.strongPassword()) {\n return;\n }\n\n if (!await this.setupSubmitActions()) {\n return;\n }\n\n try {\n // Create new key and hash new password\n const newKey = await this.cryptoService.makeKey(this.masterPassword, this.email.trim().toLowerCase(),\n this.kdf, this.kdfIterations);\n const newPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, newKey);\n\n // Grab user's current enc key\n const userEncKey = await this.cryptoService.getEncKey();\n\n // Create new encKey for the User\n const newEncKey = await this.cryptoService.remakeEncKey(newKey, userEncKey);\n\n await this.performSubmitActions(newPasswordHash, newKey, newEncKey);\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async performSubmitActions(masterPasswordHash: string, key: SymmetricCryptoKey,\n encKey: [SymmetricCryptoKey, EncString]) {\n try {\n // Create request\n const request = new UpdateTempPasswordRequest();\n request.key = encKey[1].encryptedString;\n request.newMasterPasswordHash = masterPasswordHash;\n request.masterPasswordHint = this.hint;\n\n // Update user's password\n this.formPromise = this.apiService.putUpdateTempPassword(request);\n await this.formPromise;\n this.platformUtilsService.showToast('success', null, this.i18nService.t('updatedMasterPassword'));\n\n if (this.onSuccessfulChangePassword != null) {\n this.onSuccessfulChangePassword();\n } else {\n this.messagingService.send('logout');\n }\n } catch (e) {\n this.logService.error(e);\n }\n }\n}\n","import { OrganizationUserResetPasswordRequest } from './organizationUserResetPasswordRequest';\n\nexport class UpdateTempPasswordRequest extends OrganizationUserResetPasswordRequest {\n masterPasswordHint: string;\n}\n","export class VerifyEmailRequest {\n userId: string;\n token: string;\n\n constructor(userId: string, token: string) {\n this.userId = userId;\n this.token = token;\n }\n}\n","export class VerifyDeleteRecoverRequest {\n userId: string;\n token: string;\n\n constructor(userId: string, token: string) {\n this.userId = userId;\n this.token = token;\n }\n}\n","import { SelectionReadOnlyRequest } from './selectionReadOnlyRequest';\n\nexport class GroupRequest {\n name: string;\n accessAll: boolean;\n externalId: string;\n collections: SelectionReadOnlyRequest[] = [];\n}\n","export class OrganizationUserConfirmRequest {\n key: string;\n}\n","import { SelectionReadOnlyRequest } from './selectionReadOnlyRequest';\n\nimport { OrganizationUserType } from '../../enums/organizationUserType';\nimport { PermissionsApi } from '../api/permissionsApi';\n\nexport class OrganizationUserInviteRequest {\n emails: string[] = [];\n type: OrganizationUserType;\n accessAll: boolean;\n collections: SelectionReadOnlyRequest[] = [];\n permissions: PermissionsApi;\n}\n","import { SelectionReadOnlyRequest } from './selectionReadOnlyRequest';\n\nimport { OrganizationUserType } from '../../enums/organizationUserType';\nimport { PermissionsApi } from '../api/permissionsApi';\n\nexport class OrganizationUserUpdateRequest {\n type: OrganizationUserType;\n accessAll: boolean;\n collections: SelectionReadOnlyRequest[] = [];\n permissions: PermissionsApi;\n}\n","export class OrganizationUserUpdateGroupsRequest {\n groupIds: string[] = [];\n}\n","import { PolicyType } from '../../enums/policyType';\n\nexport class PolicyRequest {\n type: PolicyType;\n enabled: boolean;\n data: any;\n}\n","import { OrganizationKeysRequest } from './organizationKeysRequest';\n\nexport class OrganizationUpdateRequest {\n name: string;\n identifier: string;\n businessName: string;\n billingEmail: string;\n keys: OrganizationKeysRequest;\n}\n","export class OrganizationSubscriptionUpdateRequest {\n constructor(public seatAdjustment: number, public maxAutoscaleSeats?: number) { }\n}\n","export enum TransactionType {\n Charge = 0,\n Credit = 1,\n PromotionalCredit = 2,\n ReferralCredit = 3,\n Refund = 4,\n}\n","export class VerifyBankRequest {\n amount1: number;\n amount2: number;\n}\n","export class BitPayInvoiceRequest {\n userId: string;\n organizationId: string;\n credit: boolean;\n amount: number;\n returnUrl: string;\n name: string;\n email: string;\n}\n","import { PaymentMethodType } from '../../enums/paymentMethodType';\nimport { OrganizationTaxInfoUpdateRequest } from '../request/organizationTaxInfoUpdateRequest';\n\nexport class PaymentRequest extends OrganizationTaxInfoUpdateRequest {\n paymentMethodType: PaymentMethodType;\n paymentToken: string;\n}\n","export class StorageRequest {\n storageGbAdjustment: number;\n}\n","import { SecretVerificationRequest } from './secretVerificationRequest';\n\nexport class UpdateTwoFactorDuoRequest extends SecretVerificationRequest {\n integrationKey: string;\n secretKey: string;\n host: string;\n}\n","import { SecretVerificationRequest } from './secretVerificationRequest';\n\nimport { TwoFactorProviderType } from '../../enums/twoFactorProviderType';\n\nexport class TwoFactorProviderRequest extends SecretVerificationRequest {\n type: TwoFactorProviderType;\n}\n","import { SecretVerificationRequest } from './secretVerificationRequest';\n\nexport class UpdateTwoFactorAuthenticatorRequest extends SecretVerificationRequest {\n token: string;\n key: string;\n}\n","import { SecretVerificationRequest } from './secretVerificationRequest';\n\nexport class UpdateTwoFactorEmailRequest extends SecretVerificationRequest {\n token: string;\n email: string;\n}\n","import { SecretVerificationRequest } from './secretVerificationRequest';\n\nexport class UpdateTwoFactorWebAuthnDeleteRequest extends SecretVerificationRequest {\n id: number;\n}\n","import { SecretVerificationRequest } from './secretVerificationRequest';\n\nexport class UpdateTwoFactorWebAuthnRequest extends SecretVerificationRequest {\n deviceResponse: PublicKeyCredential;\n name: string;\n id: number;\n}\n","import { SecretVerificationRequest } from './secretVerificationRequest';\n\nexport class UpdateTwoFactorYubioOtpRequest extends SecretVerificationRequest {\n key1: string;\n key2: string;\n key3: string;\n key4: string;\n key5: string;\n nfc: boolean;\n}\n","import {\n Directive,\n EventEmitter,\n OnInit,\n Output,\n} from '@angular/core';\nimport { FormBuilder } from '@angular/forms';\n\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { EventService } from 'jslib-common/abstractions/event.service';\nimport { ExportService } from 'jslib-common/abstractions/export.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';\n\nimport { EventType } from 'jslib-common/enums/eventType';\nimport { PolicyType } from 'jslib-common/enums/policyType';\n\n@Directive()\nexport class ExportComponent implements OnInit {\n @Output() onSaved = new EventEmitter();\n\n formPromise: Promise;\n disabledByPolicy: boolean = false;\n\n exportForm = this.fb.group({\n format: ['json'],\n secret: [''],\n });\n\n formatOptions = [\n { name: '.json', value: 'json' },\n { name: '.csv', value: 'csv' },\n { name: '.json (Encrypted)', value: 'encrypted_json' },\n ];\n\n constructor(protected cryptoService: CryptoService, protected i18nService: I18nService,\n protected platformUtilsService: PlatformUtilsService, protected exportService: ExportService,\n protected eventService: EventService, private policyService: PolicyService, protected win: Window,\n private logService: LogService, private userVerificationService: UserVerificationService,\n private fb: FormBuilder) { }\n\n async ngOnInit() {\n await this.checkExportDisabled();\n }\n\n async checkExportDisabled() {\n this.disabledByPolicy = await this.policyService.policyAppliesToUser(PolicyType.DisablePersonalVaultExport);\n if (this.disabledByPolicy) {\n this.exportForm.disable();\n }\n }\n\n get encryptedFormat() {\n return this.format === 'encrypted_json';\n }\n\n async submit() {\n if (this.disabledByPolicy) {\n this.platformUtilsService.showToast('error', null, this.i18nService.t('personalVaultExportPolicyInEffect'));\n return;\n }\n\n const acceptedWarning = await this.warningDialog();\n if (!acceptedWarning) {\n return;\n }\n\n const secret = this.exportForm.get('secret').value;\n try {\n await this.userVerificationService.verifyUser(secret);\n } catch (e) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), e.message);\n return;\n }\n\n try {\n this.formPromise = this.getExportData();\n const data = await this.formPromise;\n this.downloadFile(data);\n this.saved();\n await this.collectEvent();\n this.exportForm.get('secret').setValue('');\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async warningDialog() {\n if (this.encryptedFormat) {\n return await this.platformUtilsService.showDialog(\n '

' + this.i18nService.t('encExportKeyWarningDesc') +\n '

' + this.i18nService.t('encExportAccountWarningDesc'),\n this.i18nService.t('confirmVaultExport'), this.i18nService.t('exportVault'),\n this.i18nService.t('cancel'), 'warning',\n true);\n } else {\n return await this.platformUtilsService.showDialog(\n this.i18nService.t('exportWarningDesc'),\n this.i18nService.t('confirmVaultExport'), this.i18nService.t('exportVault'),\n this.i18nService.t('cancel'), 'warning');\n }\n }\n\n protected saved() {\n this.onSaved.emit();\n }\n\n protected getExportData() {\n return this.exportService.getExport(this.format);\n }\n\n protected getFileName(prefix?: string) {\n let extension = this.format;\n if (this.format === 'encrypted_json') {\n if (prefix == null) {\n prefix = 'encrypted';\n } else {\n prefix = 'encrypted_' + prefix;\n }\n extension = 'json';\n }\n return this.exportService.getFileName(prefix, extension);\n }\n\n protected async collectEvent(): Promise {\n await this.eventService.collect(EventType.User_ClientExportedVault);\n }\n\n get format() {\n return this.exportForm.get('format').value;\n }\n\n private downloadFile(csv: string): void {\n const fileName = this.getFileName();\n this.platformUtilsService.saveFile(this.win, csv, { type: 'text/plain' }, fileName);\n }\n}\n","import { View } from './view';\n\nimport { Attachment } from '../domain/attachment';\nimport { SymmetricCryptoKey } from '../domain/symmetricCryptoKey';\n\nexport class AttachmentView implements View {\n id: string = null;\n url: string = null;\n size: string = null;\n sizeName: string = null;\n fileName: string = null;\n key: SymmetricCryptoKey = null;\n\n constructor(a?: Attachment) {\n if (!a) {\n return;\n }\n\n this.id = a.id;\n this.url = a.url;\n this.size = a.size;\n this.sizeName = a.sizeName;\n }\n\n get fileSize(): number {\n try {\n if (this.size != null) {\n return parseInt(this.size, null);\n }\n } catch {\n // Invalid file size.\n }\n return 0;\n }\n}\n","export class AttachmentRequest {\n fileName: string;\n key: string;\n fileSize: number;\n adminRequest: boolean;\n}\n","import {\n Directive,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { CipherRepromptType } from 'jslib-common/enums/cipherRepromptType';\nimport { CipherType } from 'jslib-common/enums/cipherType';\nimport { EventType } from 'jslib-common/enums/eventType';\nimport { OrganizationUserStatusType } from 'jslib-common/enums/organizationUserStatusType';\nimport { PolicyType } from 'jslib-common/enums/policyType';\nimport { SecureNoteType } from 'jslib-common/enums/secureNoteType';\nimport { UriMatchType } from 'jslib-common/enums/uriMatchType';\n\nimport { AuditService } from 'jslib-common/abstractions/audit.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { EventService } from 'jslib-common/abstractions/event.service';\nimport { FolderService } from 'jslib-common/abstractions/folder.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Cipher } from 'jslib-common/models/domain/cipher';\n\nimport { CardView } from 'jslib-common/models/view/cardView';\nimport { CipherView } from 'jslib-common/models/view/cipherView';\nimport { CollectionView } from 'jslib-common/models/view/collectionView';\nimport { FolderView } from 'jslib-common/models/view/folderView';\nimport { IdentityView } from 'jslib-common/models/view/identityView';\nimport { LoginUriView } from 'jslib-common/models/view/loginUriView';\nimport { LoginView } from 'jslib-common/models/view/loginView';\nimport { SecureNoteView } from 'jslib-common/models/view/secureNoteView';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\n@Directive()\nexport class AddEditComponent implements OnInit {\n @Input() cloneMode: boolean = false;\n @Input() folderId: string = null;\n @Input() cipherId: string;\n @Input() type: CipherType;\n @Input() collectionIds: string[];\n @Input() organizationId: string = null;\n @Output() onSavedCipher = new EventEmitter();\n @Output() onDeletedCipher = new EventEmitter();\n @Output() onRestoredCipher = new EventEmitter();\n @Output() onCancelled = new EventEmitter();\n @Output() onEditAttachments = new EventEmitter();\n @Output() onShareCipher = new EventEmitter();\n @Output() onEditCollections = new EventEmitter();\n @Output() onGeneratePassword = new EventEmitter();\n\n editMode: boolean = false;\n cipher: CipherView;\n folders: FolderView[];\n collections: CollectionView[] = [];\n title: string;\n formPromise: Promise;\n deletePromise: Promise;\n restorePromise: Promise;\n checkPasswordPromise: Promise;\n showPassword: boolean = false;\n showCardNumber: boolean = false;\n showCardCode: boolean = false;\n cipherType = CipherType;\n typeOptions: any[];\n cardBrandOptions: any[];\n cardExpMonthOptions: any[];\n identityTitleOptions: any[];\n uriMatchOptions: any[];\n ownershipOptions: any[] = [];\n autofillOnPageLoadOptions: any[];\n currentDate = new Date();\n allowPersonal = true;\n reprompt: boolean = false;\n canUseReprompt: boolean = true;\n\n protected writeableCollections: CollectionView[];\n private previousCipherId: string;\n\n constructor(protected cipherService: CipherService, protected folderService: FolderService,\n protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService,\n protected auditService: AuditService, protected stateService: StateService,\n protected userService: UserService, protected collectionService: CollectionService,\n protected messagingService: MessagingService, protected eventService: EventService,\n protected policyService: PolicyService, protected passwordRepromptService: PasswordRepromptService,\n private logService: LogService) {\n this.typeOptions = [\n { name: i18nService.t('typeLogin'), value: CipherType.Login },\n { name: i18nService.t('typeCard'), value: CipherType.Card },\n { name: i18nService.t('typeIdentity'), value: CipherType.Identity },\n { name: i18nService.t('typeSecureNote'), value: CipherType.SecureNote },\n ];\n this.cardBrandOptions = [\n { name: '-- ' + i18nService.t('select') + ' --', value: null },\n { name: 'Visa', value: 'Visa' },\n { name: 'Mastercard', value: 'Mastercard' },\n { name: 'American Express', value: 'Amex' },\n { name: 'Discover', value: 'Discover' },\n { name: 'Diners Club', value: 'Diners Club' },\n { name: 'JCB', value: 'JCB' },\n { name: 'Maestro', value: 'Maestro' },\n { name: 'UnionPay', value: 'UnionPay' },\n { name: i18nService.t('other'), value: 'Other' },\n ];\n this.cardExpMonthOptions = [\n { name: '-- ' + i18nService.t('select') + ' --', value: null },\n { name: '01 - ' + i18nService.t('january'), value: '1' },\n { name: '02 - ' + i18nService.t('february'), value: '2' },\n { name: '03 - ' + i18nService.t('march'), value: '3' },\n { name: '04 - ' + i18nService.t('april'), value: '4' },\n { name: '05 - ' + i18nService.t('may'), value: '5' },\n { name: '06 - ' + i18nService.t('june'), value: '6' },\n { name: '07 - ' + i18nService.t('july'), value: '7' },\n { name: '08 - ' + i18nService.t('august'), value: '8' },\n { name: '09 - ' + i18nService.t('september'), value: '9' },\n { name: '10 - ' + i18nService.t('october'), value: '10' },\n { name: '11 - ' + i18nService.t('november'), value: '11' },\n { name: '12 - ' + i18nService.t('december'), value: '12' },\n ];\n this.identityTitleOptions = [\n { name: '-- ' + i18nService.t('select') + ' --', value: null },\n { name: i18nService.t('mr'), value: i18nService.t('mr') },\n { name: i18nService.t('mrs'), value: i18nService.t('mrs') },\n { name: i18nService.t('ms'), value: i18nService.t('ms') },\n { name: i18nService.t('dr'), value: i18nService.t('dr') },\n ];\n this.uriMatchOptions = [\n { name: i18nService.t('defaultMatchDetection'), value: null },\n { name: i18nService.t('baseDomain'), value: UriMatchType.Domain },\n { name: i18nService.t('host'), value: UriMatchType.Host },\n { name: i18nService.t('startsWith'), value: UriMatchType.StartsWith },\n { name: i18nService.t('regEx'), value: UriMatchType.RegularExpression },\n { name: i18nService.t('exact'), value: UriMatchType.Exact },\n { name: i18nService.t('never'), value: UriMatchType.Never },\n ];\n this.autofillOnPageLoadOptions = [\n { name: i18nService.t('autoFillOnPageLoadUseDefault'), value: null },\n { name: i18nService.t('autoFillOnPageLoadYes'), value: true },\n { name: i18nService.t('autoFillOnPageLoadNo'), value: false },\n ];\n }\n\n async ngOnInit() {\n await this.init();\n }\n\n async init() {\n if (await this.policyService.policyAppliesToUser(PolicyType.PersonalOwnership)) {\n this.allowPersonal = false;\n } else {\n const myEmail = await this.userService.getEmail();\n this.ownershipOptions.push({ name: myEmail, value: null });\n }\n\n const orgs = await this.userService.getAllOrganizations();\n orgs.sort(Utils.getSortFunction(this.i18nService, 'name')).forEach(o => {\n if (o.enabled && o.status === OrganizationUserStatusType.Confirmed) {\n this.ownershipOptions.push({ name: o.name, value: o.id });\n }\n });\n if (!this.allowPersonal) {\n this.organizationId = this.ownershipOptions[0].value;\n }\n\n this.writeableCollections = await this.loadCollections();\n\n this.canUseReprompt = await this.passwordRepromptService.enabled();\n }\n\n async load() {\n this.editMode = this.cipherId != null;\n if (this.editMode) {\n this.editMode = true;\n if (this.cloneMode) {\n this.cloneMode = true;\n this.title = this.i18nService.t('addItem');\n } else {\n this.title = this.i18nService.t('editItem');\n }\n } else {\n this.title = this.i18nService.t('addItem');\n }\n\n const addEditCipherInfo: any = await this.stateService.get('addEditCipherInfo');\n if (addEditCipherInfo != null) {\n this.cipher = addEditCipherInfo.cipher;\n this.collectionIds = addEditCipherInfo.collectionIds;\n }\n await this.stateService.remove('addEditCipherInfo');\n\n if (this.cipher == null) {\n if (this.editMode) {\n const cipher = await this.loadCipher();\n this.cipher = await cipher.decrypt();\n\n // Adjust Cipher Name if Cloning\n if (this.cloneMode) {\n this.cipher.name += ' - ' + this.i18nService.t('clone');\n // If not allowing personal ownership, update cipher's org Id to prompt downstream changes\n if (this.cipher.organizationId == null && !this.allowPersonal) {\n this.cipher.organizationId = this.organizationId;\n }\n }\n } else {\n this.cipher = new CipherView();\n this.cipher.organizationId = this.organizationId == null ? null : this.organizationId;\n this.cipher.folderId = this.folderId;\n this.cipher.type = this.type == null ? CipherType.Login : this.type;\n this.cipher.login = new LoginView();\n this.cipher.login.uris = [new LoginUriView()];\n this.cipher.card = new CardView();\n this.cipher.identity = new IdentityView();\n this.cipher.secureNote = new SecureNoteView();\n this.cipher.secureNote.type = SecureNoteType.Generic;\n this.cipher.reprompt = CipherRepromptType.None;\n }\n }\n\n if (this.cipher != null && (!this.editMode || addEditCipherInfo != null || this.cloneMode)) {\n await this.organizationChanged();\n if (this.collectionIds != null && this.collectionIds.length > 0 && this.collections.length > 0) {\n this.collections.forEach(c => {\n if (this.collectionIds.indexOf(c.id) > -1) {\n (c as any).checked = true;\n }\n });\n }\n }\n\n this.folders = await this.folderService.getAllDecrypted();\n\n if (this.editMode && this.previousCipherId !== this.cipherId) {\n this.eventService.collect(EventType.Cipher_ClientViewed, this.cipherId);\n }\n this.previousCipherId = this.cipherId;\n this.reprompt = this.cipher.reprompt !== CipherRepromptType.None;\n }\n\n async submit(): Promise {\n if (this.cipher.isDeleted) {\n return this.restore();\n }\n\n if (this.cipher.name == null || this.cipher.name === '') {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('nameRequired'));\n return false;\n }\n\n if ((!this.editMode || this.cloneMode) && !this.allowPersonal && this.cipher.organizationId == null) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('personalOwnershipSubmitError'));\n return false;\n }\n\n if ((!this.editMode || this.cloneMode) && this.cipher.type === CipherType.Login &&\n this.cipher.login.uris != null && this.cipher.login.uris.length === 1 &&\n (this.cipher.login.uris[0].uri == null || this.cipher.login.uris[0].uri === '')) {\n this.cipher.login.uris = null;\n }\n\n // Allows saving of selected collections during \"Add\" and \"Clone\" flows\n if ((!this.editMode || this.cloneMode) && this.cipher.organizationId != null) {\n this.cipher.collectionIds = this.collections == null ? [] :\n this.collections.filter(c => (c as any).checked).map(c => c.id);\n }\n\n // Clear current Cipher Id to trigger \"Add\" cipher flow\n if (this.cloneMode) {\n this.cipher.id = null;\n }\n\n const cipher = await this.encryptCipher();\n try {\n this.formPromise = this.saveCipher(cipher);\n await this.formPromise;\n this.cipher.id = cipher.id;\n this.platformUtilsService.showToast('success', null,\n this.i18nService.t(this.editMode && !this.cloneMode ? 'editedItem' : 'addedItem'));\n this.onSavedCipher.emit(this.cipher);\n this.messagingService.send(this.editMode && !this.cloneMode ? 'editedCipher' : 'addedCipher');\n return true;\n } catch (e) {\n this.logService.error(e);\n }\n\n return false;\n }\n\n addUri() {\n if (this.cipher.type !== CipherType.Login) {\n return;\n }\n\n if (this.cipher.login.uris == null) {\n this.cipher.login.uris = [];\n }\n\n this.cipher.login.uris.push(new LoginUriView());\n }\n\n removeUri(uri: LoginUriView) {\n if (this.cipher.type !== CipherType.Login || this.cipher.login.uris == null) {\n return;\n }\n\n const i = this.cipher.login.uris.indexOf(uri);\n if (i > -1) {\n this.cipher.login.uris.splice(i, 1);\n }\n }\n\n trackByFunction(index: number, item: any) {\n return index;\n }\n\n cancel() {\n this.onCancelled.emit(this.cipher);\n }\n\n attachments() {\n this.onEditAttachments.emit(this.cipher);\n }\n\n share() {\n this.onShareCipher.emit(this.cipher);\n }\n\n editCollections() {\n this.onEditCollections.emit(this.cipher);\n }\n\n async delete(): Promise {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t(this.cipher.isDeleted ? 'permanentlyDeleteItemConfirmation' : 'deleteItemConfirmation'),\n this.i18nService.t('deleteItem'), this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.deletePromise = this.deleteCipher();\n await this.deletePromise;\n this.platformUtilsService.showToast('success', null,\n this.i18nService.t(this.cipher.isDeleted ? 'permanentlyDeletedItem' : 'deletedItem'));\n this.onDeletedCipher.emit(this.cipher);\n this.messagingService.send(this.cipher.isDeleted ? 'permanentlyDeletedCipher' : 'deletedCipher');\n } catch (e) {\n this.logService.error(e);\n }\n\n return true;\n }\n\n async restore(): Promise {\n if (!this.cipher.isDeleted) {\n return false;\n }\n\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('restoreItemConfirmation'), this.i18nService.t('restoreItem'),\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.restorePromise = this.restoreCipher();\n await this.restorePromise;\n this.platformUtilsService.showToast('success', null, this.i18nService.t('restoredItem'));\n this.onRestoredCipher.emit(this.cipher);\n this.messagingService.send('restoredCipher');\n } catch (e) {\n this.logService.error(e);\n }\n\n return true;\n }\n\n async generatePassword(): Promise {\n if (this.cipher.login != null && this.cipher.login.password != null && this.cipher.login.password.length) {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('overwritePasswordConfirmation'), this.i18nService.t('overwritePassword'),\n this.i18nService.t('yes'), this.i18nService.t('no'));\n if (!confirmed) {\n return false;\n }\n }\n\n this.onGeneratePassword.emit();\n return true;\n }\n\n togglePassword() {\n this.showPassword = !this.showPassword;\n document.getElementById('loginPassword').focus();\n if (this.editMode && this.showPassword) {\n this.eventService.collect(EventType.Cipher_ClientToggledPasswordVisible, this.cipherId);\n }\n }\n\n async toggleCardNumber() {\n this.showCardNumber = !this.showCardNumber;\n if (this.showCardNumber) {\n this.eventService.collect(EventType.Cipher_ClientToggledCardNumberVisible, this.cipherId);\n }\n }\n\n toggleCardCode() {\n this.showCardCode = !this.showCardCode;\n document.getElementById('cardCode').focus();\n if (this.editMode && this.showCardCode) {\n this.eventService.collect(EventType.Cipher_ClientToggledCardCodeVisible, this.cipherId);\n }\n }\n\n toggleUriOptions(uri: LoginUriView) {\n const u = (uri as any);\n u.showOptions = u.showOptions == null && uri.match != null ? false : !u.showOptions;\n }\n\n loginUriMatchChanged(uri: LoginUriView) {\n const u = (uri as any);\n u.showOptions = u.showOptions == null ? true : u.showOptions;\n }\n\n async organizationChanged() {\n if (this.writeableCollections != null) {\n this.writeableCollections.forEach(c => (c as any).checked = false);\n }\n if (this.cipher.organizationId != null) {\n this.collections = this.writeableCollections.filter(c => c.organizationId === this.cipher.organizationId);\n const org = await this.userService.getOrganization(this.cipher.organizationId);\n if (org != null) {\n this.cipher.organizationUseTotp = org.useTotp;\n }\n } else {\n this.collections = [];\n }\n }\n\n async checkPassword() {\n if (this.checkPasswordPromise != null) {\n return;\n }\n\n if (this.cipher.login == null || this.cipher.login.password == null || this.cipher.login.password === '') {\n return;\n }\n\n this.checkPasswordPromise = this.auditService.passwordLeaked(this.cipher.login.password);\n const matches = await this.checkPasswordPromise;\n this.checkPasswordPromise = null;\n\n if (matches > 0) {\n this.platformUtilsService.showToast('warning', null,\n this.i18nService.t('passwordExposed', matches.toString()));\n } else {\n this.platformUtilsService.showToast('success', null, this.i18nService.t('passwordSafe'));\n }\n }\n\n repromptChanged() {\n this.reprompt = !this.reprompt;\n if (this.reprompt) {\n this.cipher.reprompt = CipherRepromptType.Password;\n } else {\n this.cipher.reprompt = CipherRepromptType.None;\n }\n }\n\n protected async loadCollections() {\n const allCollections = await this.collectionService.getAllDecrypted();\n return allCollections.filter(c => !c.readOnly);\n }\n\n protected loadCipher() {\n return this.cipherService.get(this.cipherId);\n }\n\n protected encryptCipher() {\n return this.cipherService.encrypt(this.cipher);\n }\n\n protected saveCipher(cipher: Cipher) {\n return this.cipherService.saveWithServer(cipher);\n }\n\n protected deleteCipher() {\n return this.cipher.isDeleted ? this.cipherService.deleteWithServer(this.cipher.id)\n : this.cipherService.softDeleteWithServer(this.cipher.id);\n }\n\n protected restoreCipher() {\n return this.cipherService.restoreWithServer(this.cipher.id);\n }\n}\n","import {\n Directive,\n Input,\n OnChanges,\n SimpleChanges,\n} from '@angular/core';\n\nimport {\n CdkDragDrop,\n moveItemInArray,\n} from '@angular/cdk/drag-drop';\n\nimport { EventService } from 'jslib-common/abstractions/event.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\nimport { FieldView } from 'jslib-common/models/view/fieldView';\n\nimport { CipherType } from 'jslib-common/enums/cipherType';\nimport { EventType } from 'jslib-common/enums/eventType';\nimport { FieldType } from 'jslib-common/enums/fieldType';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\n@Directive()\nexport class AddEditCustomFieldsComponent implements OnChanges {\n @Input() cipher: CipherView;\n @Input() thisCipherType: CipherType;\n @Input() editMode: boolean;\n\n addFieldType: FieldType = FieldType.Text;\n addFieldTypeOptions: any[];\n addFieldLinkedTypeOption: any;\n linkedFieldOptions: any[] = [];\n\n cipherType = CipherType;\n fieldType = FieldType;\n eventType = EventType;\n\n constructor(private i18nService: I18nService, private eventService: EventService) {\n this.addFieldTypeOptions = [\n { name: i18nService.t('cfTypeText'), value: FieldType.Text },\n { name: i18nService.t('cfTypeHidden'), value: FieldType.Hidden },\n { name: i18nService.t('cfTypeBoolean'), value: FieldType.Boolean },\n ];\n this.addFieldLinkedTypeOption = { name: this.i18nService.t('cfTypeLinked'), value: FieldType.Linked };\n }\n\n ngOnChanges(changes: SimpleChanges) {\n if (changes.thisCipherType != null) {\n this.setLinkedFieldOptions();\n\n if (!changes.thisCipherType.firstChange) {\n this.resetCipherLinkedFields();\n }\n }\n }\n\n addField() {\n if (this.cipher.fields == null) {\n this.cipher.fields = [];\n }\n\n const f = new FieldView();\n f.type = this.addFieldType;\n f.newField = true;\n\n if (f.type === FieldType.Linked) {\n f.linkedId = this.linkedFieldOptions[0].value;\n }\n\n this.cipher.fields.push(f);\n }\n\n removeField(field: FieldView) {\n const i = this.cipher.fields.indexOf(field);\n if (i > -1) {\n this.cipher.fields.splice(i, 1);\n }\n }\n\n toggleFieldValue(field: FieldView) {\n const f = (field as any);\n f.showValue = !f.showValue;\n if (this.editMode && f.showValue) {\n this.eventService.collect(EventType.Cipher_ClientToggledHiddenFieldVisible, this.cipher.id);\n }\n }\n\n trackByFunction(index: number, item: any) {\n return index;\n }\n\n drop(event: CdkDragDrop) {\n moveItemInArray(this.cipher.fields, event.previousIndex, event.currentIndex);\n }\n\n private setLinkedFieldOptions() {\n if (this.cipher.linkedFieldOptions == null) {\n return;\n }\n\n const options: any = [];\n this.cipher.linkedFieldOptions.forEach((linkedFieldOption, id) =>\n options.push({ name: this.i18nService.t(linkedFieldOption.i18nKey), value: id }));\n this.linkedFieldOptions = options.sort(Utils.getSortFunction(this.i18nService, 'name'));\n }\n\n private resetCipherLinkedFields() {\n if (this.cipher.fields == null || this.cipher.fields.length === 0) {\n return;\n }\n\n // Delete any Linked custom fields if the item type does not support them\n if (this.cipher.linkedFieldOptions == null) {\n this.cipher.fields = this.cipher.fields.filter(f => f.type !== FieldType.Linked);\n return;\n }\n\n this.cipher.fields\n .filter(f => f.type === FieldType.Linked)\n .forEach(f => f.linkedId = this.linkedFieldOptions[0].value);\n }\n}\n","import { PlanSponsorshipType } from '../../../enums/planSponsorshipType';\n\nexport class OrganizationSponsorshipRedeemRequest {\n planSponsorshipType: PlanSponsorshipType;\n sponsoredOrganizationId: string;\n}\n","import {\n Directive,\n EventEmitter,\n Input,\n Output,\n} from '@angular/core';\n\nimport { SearchService } from 'jslib-common/abstractions/search.service';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\n@Directive()\nexport class CiphersComponent {\n @Input() activeCipherId: string = null;\n @Output() onCipherClicked = new EventEmitter();\n @Output() onCipherRightClicked = new EventEmitter();\n @Output() onAddCipher = new EventEmitter();\n @Output() onAddCipherOptions = new EventEmitter();\n\n loaded: boolean = false;\n ciphers: CipherView[] = [];\n searchText: string;\n searchPlaceholder: string = null;\n filter: (cipher: CipherView) => boolean = null;\n deleted: boolean = false;\n\n protected searchPending = false;\n\n private searchTimeout: any = null;\n\n constructor(protected searchService: SearchService) { }\n\n async load(filter: (cipher: CipherView) => boolean = null, deleted: boolean = false) {\n this.deleted = deleted || false;\n await this.applyFilter(filter);\n this.loaded = true;\n }\n\n async reload(filter: (cipher: CipherView) => boolean = null, deleted: boolean = false) {\n this.loaded = false;\n this.ciphers = [];\n await this.load(filter, deleted);\n }\n\n async refresh() {\n await this.reload(this.filter, this.deleted);\n }\n\n async applyFilter(filter: (cipher: CipherView) => boolean = null) {\n this.filter = filter;\n await this.search(null);\n }\n\n async search(timeout: number = null, indexedCiphers?: CipherView[]) {\n this.searchPending = false;\n if (this.searchTimeout != null) {\n clearTimeout(this.searchTimeout);\n }\n if (timeout == null) {\n await this.doSearch(indexedCiphers);\n return;\n }\n this.searchPending = true;\n this.searchTimeout = setTimeout(async () => {\n await this.doSearch(indexedCiphers);\n this.searchPending = false;\n }, timeout);\n }\n\n selectCipher(cipher: CipherView) {\n this.onCipherClicked.emit(cipher);\n }\n\n rightClickCipher(cipher: CipherView) {\n this.onCipherRightClicked.emit(cipher);\n }\n\n addCipher() {\n this.onAddCipher.emit();\n }\n\n addCipherOptions() {\n this.onAddCipherOptions.emit();\n }\n\n isSearching() {\n return !this.searchPending && this.searchService.isSearchable(this.searchText);\n }\n\n protected deletedFilter: (cipher: CipherView) => boolean = c => c.isDeleted === this.deleted;\n\n protected async doSearch(indexedCiphers?: CipherView[]) {\n this.ciphers = await this.searchService.searchCiphers(this.searchText, [this.filter, this.deletedFilter], indexedCiphers);\n }\n}\n","import {\n Directive,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\nimport { CollectionView } from 'jslib-common/models/view/collectionView';\n\nimport { Cipher } from 'jslib-common/models/domain/cipher';\n\n@Directive()\nexport class CollectionsComponent implements OnInit {\n @Input() cipherId: string;\n @Input() allowSelectNone = false;\n @Output() onSavedCollections = new EventEmitter();\n\n formPromise: Promise;\n cipher: CipherView;\n collectionIds: string[];\n collections: CollectionView[] = [];\n\n protected cipherDomain: Cipher;\n\n constructor(protected collectionService: CollectionService, protected platformUtilsService: PlatformUtilsService,\n protected i18nService: I18nService, protected cipherService: CipherService, private logService: LogService) { }\n\n async ngOnInit() {\n await this.load();\n }\n\n async load() {\n this.cipherDomain = await this.loadCipher();\n this.collectionIds = this.loadCipherCollections();\n this.cipher = await this.cipherDomain.decrypt();\n this.collections = await this.loadCollections();\n\n this.collections.forEach(c => (c as any).checked = false);\n if (this.collectionIds != null) {\n this.collections.forEach(c => {\n (c as any).checked = this.collectionIds != null && this.collectionIds.indexOf(c.id) > -1;\n });\n }\n }\n\n async submit() {\n const selectedCollectionIds = this.collections\n .filter(c => !!(c as any).checked)\n .map(c => c.id);\n if (!this.allowSelectNone && selectedCollectionIds.length === 0) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('selectOneCollection'));\n return;\n }\n this.cipherDomain.collectionIds = selectedCollectionIds;\n try {\n this.formPromise = this.saveCollections();\n await this.formPromise;\n this.onSavedCollections.emit();\n this.platformUtilsService.showToast('success', null, this.i18nService.t('editedItem'));\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n protected loadCipher() {\n return this.cipherService.get(this.cipherId);\n }\n\n protected loadCipherCollections() {\n return this.cipherDomain.collectionIds;\n }\n\n protected async loadCollections() {\n const allCollections = await this.collectionService.getAllDecrypted();\n return allCollections.filter(c => !c.readOnly && c.organizationId === this.cipher.organizationId);\n }\n\n protected saveCollections() {\n return this.cipherService.saveCollectionsWithServer(this.cipherDomain);\n }\n}\n","import {\n Directive,\n EventEmitter,\n Input,\n Output,\n} from '@angular/core';\n\nimport { CipherType } from 'jslib-common/enums/cipherType';\n\nimport { CollectionView } from 'jslib-common/models/view/collectionView';\nimport { FolderView } from 'jslib-common/models/view/folderView';\n\nimport { TreeNode } from 'jslib-common/models/domain/treeNode';\n\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { FolderService } from 'jslib-common/abstractions/folder.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\n@Directive()\nexport class GroupingsComponent {\n @Input() showFolders = true;\n @Input() showCollections = true;\n @Input() showFavorites = true;\n @Input() showTrash = true;\n\n @Output() onAllClicked = new EventEmitter();\n @Output() onFavoritesClicked = new EventEmitter();\n @Output() onTrashClicked = new EventEmitter();\n @Output() onCipherTypeClicked = new EventEmitter();\n @Output() onFolderClicked = new EventEmitter();\n @Output() onAddFolder = new EventEmitter();\n @Output() onEditFolder = new EventEmitter();\n @Output() onCollectionClicked = new EventEmitter();\n\n folders: FolderView[];\n nestedFolders: TreeNode[];\n collections: CollectionView[];\n nestedCollections: TreeNode[];\n loaded: boolean = false;\n cipherType = CipherType;\n selectedAll: boolean = false;\n selectedFavorites: boolean = false;\n selectedTrash: boolean = false;\n selectedType: CipherType = null;\n selectedFolder: boolean = false;\n selectedFolderId: string = null;\n selectedCollectionId: string = null;\n\n private collapsedGroupings: Set;\n private collapsedGroupingsKey: string;\n\n constructor(protected collectionService: CollectionService, protected folderService: FolderService,\n protected storageService: StorageService, protected userService: UserService) { }\n\n async load(setLoaded = true) {\n const userId = await this.userService.getUserId();\n this.collapsedGroupingsKey = ConstantsService.collapsedGroupingsKey + '_' + userId;\n const collapsedGroupings = await this.storageService.get(this.collapsedGroupingsKey);\n if (collapsedGroupings == null) {\n this.collapsedGroupings = new Set();\n } else {\n this.collapsedGroupings = new Set(collapsedGroupings);\n }\n\n await this.loadFolders();\n await this.loadCollections();\n\n if (setLoaded) {\n this.loaded = true;\n }\n }\n\n async loadCollections(organizationId?: string) {\n if (!this.showCollections) {\n return;\n }\n const collections = await this.collectionService.getAllDecrypted();\n if (organizationId != null) {\n this.collections = collections.filter(c => c.organizationId === organizationId);\n } else {\n this.collections = collections;\n }\n this.nestedCollections = await this.collectionService.getAllNested(this.collections);\n }\n\n async loadFolders() {\n if (!this.showFolders) {\n return;\n }\n this.folders = await this.folderService.getAllDecrypted();\n this.nestedFolders = await this.folderService.getAllNested();\n }\n\n selectAll() {\n this.clearSelections();\n this.selectedAll = true;\n this.onAllClicked.emit();\n }\n\n selectFavorites() {\n this.clearSelections();\n this.selectedFavorites = true;\n this.onFavoritesClicked.emit();\n }\n\n selectTrash() {\n this.clearSelections();\n this.selectedTrash = true;\n this.onTrashClicked.emit();\n }\n\n selectType(type: CipherType) {\n this.clearSelections();\n this.selectedType = type;\n this.onCipherTypeClicked.emit(type);\n }\n\n selectFolder(folder: FolderView) {\n this.clearSelections();\n this.selectedFolder = true;\n this.selectedFolderId = folder.id;\n this.onFolderClicked.emit(folder);\n }\n\n addFolder() {\n this.onAddFolder.emit();\n }\n\n editFolder(folder: FolderView) {\n this.onEditFolder.emit(folder);\n }\n\n selectCollection(collection: CollectionView) {\n this.clearSelections();\n this.selectedCollectionId = collection.id;\n this.onCollectionClicked.emit(collection);\n }\n\n clearSelections() {\n this.selectedAll = false;\n this.selectedFavorites = false;\n this.selectedTrash = false;\n this.selectedType = null;\n this.selectedFolder = false;\n this.selectedFolderId = null;\n this.selectedCollectionId = null;\n }\n\n collapse(grouping: FolderView | CollectionView, idPrefix = '') {\n if (grouping.id == null) {\n return;\n }\n const id = idPrefix + grouping.id;\n if (this.isCollapsed(grouping, idPrefix)) {\n this.collapsedGroupings.delete(id);\n } else {\n this.collapsedGroupings.add(id);\n }\n this.storageService.save(this.collapsedGroupingsKey, this.collapsedGroupings);\n }\n\n isCollapsed(grouping: FolderView | CollectionView, idPrefix = '') {\n return this.collapsedGroupings.has(idPrefix + grouping.id);\n }\n}\n","import { SendType } from '../../enums/sendType';\n\nimport { SendAccessResponse } from '../response/sendAccessResponse';\n\nimport { SendAccessView } from '../view/sendAccessView';\n\nimport Domain from './domainBase';\nimport { EncString } from './encString';\nimport { SendFile } from './sendFile';\nimport { SendText } from './sendText';\nimport { SymmetricCryptoKey } from './symmetricCryptoKey';\n\nexport class SendAccess extends Domain {\n id: string;\n type: SendType;\n name: EncString;\n file: SendFile;\n text: SendText;\n expirationDate: Date;\n creatorIdentifier: string;\n\n constructor(obj?: SendAccessResponse, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.buildDomainModel(this, obj, {\n id: null,\n name: null,\n expirationDate: null,\n creatorIdentifier: null,\n }, alreadyEncrypted, ['id', 'expirationDate', 'creatorIdentifier']);\n\n this.type = obj.type;\n\n switch (this.type) {\n case SendType.Text:\n this.text = new SendText(obj.text, alreadyEncrypted);\n break;\n case SendType.File:\n this.file = new SendFile(obj.file, alreadyEncrypted);\n break;\n default:\n break;\n }\n }\n\n async decrypt(key: SymmetricCryptoKey): Promise {\n const model = new SendAccessView(this);\n\n await this.decryptObj(model, {\n name: null,\n }, null, key);\n\n switch (this.type) {\n case SendType.File:\n model.file = await this.file.decrypt(key);\n break;\n case SendType.Text:\n model.text = await this.text.decrypt(key);\n break;\n default:\n break;\n }\n\n return model;\n }\n}\n","import { SendType } from '../../enums/sendType';\n\nimport { SendAccess } from '../domain/sendAccess';\n\nimport { SendFileView } from './sendFileView';\nimport { SendTextView } from './sendTextView';\nimport { View } from './view';\n\nexport class SendAccessView implements View {\n id: string = null;\n name: string = null;\n type: SendType = null;\n text = new SendTextView();\n file = new SendFileView();\n expirationDate: Date = null;\n creatorIdentifier: string = null;\n\n constructor(s?: SendAccess) {\n if (!s) {\n return;\n }\n\n this.id = s.id;\n this.type = s.type;\n this.expirationDate = s.expirationDate;\n this.creatorIdentifier = s.creatorIdentifier;\n }\n}\n","export class SendAccessRequest {\n password: string;\n}\n","import { DatePipe } from '@angular/common';\nimport {\n Directive,\n EventEmitter,\n Input,\n OnInit,\n Output\n} from '@angular/core';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\nimport { SendType } from 'jslib-common/enums/sendType';\n\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { SendService } from 'jslib-common/abstractions/send.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { SendFileView } from 'jslib-common/models/view/sendFileView';\nimport { SendTextView } from 'jslib-common/models/view/sendTextView';\nimport { SendView } from 'jslib-common/models/view/sendView';\n\nimport { EncArrayBuffer } from 'jslib-common/models/domain/encArrayBuffer';\nimport { Send } from 'jslib-common/models/domain/send';\n\n@Directive()\nexport class AddEditComponent implements OnInit {\n @Input() sendId: string;\n @Input() type: SendType;\n\n @Output() onSavedSend = new EventEmitter();\n @Output() onDeletedSend = new EventEmitter();\n @Output() onCancelled = new EventEmitter();\n\n copyLink = false;\n disableSend = false;\n disableHideEmail = false;\n send: SendView;\n deletionDate: string;\n expirationDate: string;\n hasPassword: boolean;\n password: string;\n showPassword = false;\n formPromise: Promise;\n deletePromise: Promise;\n sendType = SendType;\n typeOptions: any[];\n canAccessPremium = true;\n emailVerified = true;\n alertShown = false;\n showOptions = false;\n\n private sendLinkBaseUrl: string;\n\n constructor(protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService,\n protected environmentService: EnvironmentService, protected datePipe: DatePipe,\n protected sendService: SendService, protected userService: UserService,\n protected messagingService: MessagingService, protected policyService: PolicyService,\n private logService: LogService) {\n this.typeOptions = [\n { name: i18nService.t('sendTypeFile'), value: SendType.File },\n { name: i18nService.t('sendTypeText'), value: SendType.Text },\n ];\n this.sendLinkBaseUrl = this.environmentService.getSendUrl();\n }\n\n get link(): string {\n if (this.send.id != null && this.send.accessId != null) {\n return this.sendLinkBaseUrl + this.send.accessId + '/' + this.send.urlB64Key;\n }\n return null;\n }\n\n get isSafari() {\n return this.platformUtilsService.isSafari();\n }\n\n get isDateTimeLocalSupported(): boolean {\n return !(this.platformUtilsService.isFirefox() || this.platformUtilsService.isSafari());\n }\n\n async ngOnInit() {\n await this.load();\n }\n\n get editMode(): boolean {\n return this.sendId != null;\n }\n\n get title(): string {\n return this.i18nService.t(\n this.editMode ?\n 'editSend' :\n 'createSend'\n );\n }\n\n setDates(event: {deletionDate: string, expirationDate: string}) {\n this.deletionDate = event.deletionDate;\n this.expirationDate = event.expirationDate;\n }\n\n async load() {\n this.disableSend = await this.policyService.policyAppliesToUser(PolicyType.DisableSend);\n this.disableHideEmail = await this.policyService.policyAppliesToUser(PolicyType.SendOptions,\n p => p.data.disableHideEmail);\n\n this.canAccessPremium = await this.userService.canAccessPremium();\n this.emailVerified = await this.userService.getEmailVerified();\n if (!this.canAccessPremium || !this.emailVerified) {\n this.type = SendType.Text;\n }\n\n if (this.send == null) {\n if (this.editMode) {\n const send = await this.loadSend();\n this.send = await send.decrypt();\n } else {\n this.send = new SendView();\n this.send.type = this.type == null ? SendType.File : this.type;\n this.send.file = new SendFileView();\n this.send.text = new SendTextView();\n this.send.deletionDate = new Date();\n this.send.deletionDate.setDate(this.send.deletionDate.getDate() + 7);\n }\n }\n\n this.hasPassword = this.send.password != null && this.send.password.trim() !== '';\n }\n\n async submit(): Promise {\n if (this.disableSend) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('sendDisabledWarning'));\n return false;\n }\n\n if (this.send.name == null || this.send.name === '') {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('nameRequired'));\n return false;\n }\n\n let file: File = null;\n if (this.send.type === SendType.File && !this.editMode) {\n const fileEl = document.getElementById('file') as HTMLInputElement;\n const files = fileEl.files;\n if (files == null || files.length === 0) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('selectFile'));\n return;\n }\n\n file = files[0];\n if (files[0].size > 524288000) { // 500 MB\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('maxFileSize'));\n return;\n }\n }\n\n if (this.password != null && this.password.trim() === '') {\n this.password = null;\n }\n\n this.formPromise = this.encryptSend(file)\n .then(async encSend => {\n const uploadPromise = this.sendService.saveWithServer(encSend);\n await uploadPromise;\n if (this.send.id == null) {\n this.send.id = encSend[0].id;\n }\n if (this.send.accessId == null) {\n this.send.accessId = encSend[0].accessId;\n }\n this.onSavedSend.emit(this.send);\n if (this.copyLink && this.link != null) {\n const copySuccess = await this.copyLinkToClipboard(this.link);\n if (copySuccess ?? true) {\n this.platformUtilsService.showToast('success', null,\n this.i18nService.t(this.editMode ? 'editedSend' : 'createdSend'));\n } else {\n await this.platformUtilsService.showDialog(\n this.i18nService.t(this.editMode ? 'editedSend' : 'createdSend'), null,\n this.i18nService.t('ok'), null, 'success', null);\n await this.copyLinkToClipboard(this.link);\n }\n }\n });\n try {\n await this.formPromise;\n return true;\n } catch (e) {\n this.logService.error(e);\n }\n return false;\n }\n\n async copyLinkToClipboard(link: string): Promise {\n return Promise.resolve(this.platformUtilsService.copyToClipboard(link));\n }\n\n async delete(): Promise {\n if (this.deletePromise != null) {\n return false;\n }\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('deleteSendConfirmation'),\n this.i18nService.t('deleteSend'),\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.deletePromise = this.sendService.deleteWithServer(this.send.id);\n await this.deletePromise;\n this.platformUtilsService.showToast('success', null, this.i18nService.t('deletedSend'));\n await this.load();\n this.onDeletedSend.emit(this.send);\n return true;\n } catch (e) {\n this.logService.error(e);\n }\n\n return false;\n }\n\n typeChanged() {\n if (this.send.type === SendType.File && !this.alertShown) {\n if (!this.canAccessPremium) {\n this.alertShown = true;\n this.messagingService.send('premiumRequired');\n } else if (!this.emailVerified) {\n this.alertShown = true;\n this.messagingService.send('emailVerificationRequired');\n }\n }\n }\n\n toggleOptions() {\n this.showOptions = !this.showOptions;\n }\n\n protected async loadSend(): Promise {\n return this.sendService.get(this.sendId);\n }\n\n protected async encryptSend(file: File): Promise<[Send, EncArrayBuffer]> {\n const sendData = await this.sendService.encrypt(this.send, file, this.password, null);\n\n // Parse dates\n try {\n sendData[0].deletionDate = this.deletionDate == null ? null : new Date(this.deletionDate);\n } catch {\n sendData[0].deletionDate = null;\n }\n try {\n sendData[0].expirationDate = this.expirationDate == null ? null : new Date(this.expirationDate);\n } catch {\n sendData[0].expirationDate = null;\n }\n\n return sendData;\n }\n\n protected togglePasswordVisible() {\n this.showPassword = !this.showPassword;\n document.getElementById('password').focus();\n }\n}\n","import { DatePipe } from '@angular/common';\nimport {\n Directive,\n EventEmitter,\n Input,\n OnInit,\n Output\n} from '@angular/core';\nimport { FormControl, FormGroup } from '@angular/forms';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\n// Different BrowserPath = different controls.\nenum BrowserPath {\n // Native datetime-locale.\n // We are happy.\n Default = 'default',\n\n // Native date and time inputs, but no datetime-locale.\n // We use individual date and time inputs and create a datetime programatically on submit.\n Firefox = 'firefox',\n\n // No native date, time, or datetime-locale inputs.\n // We use a polyfill for dates and a dropdown for times.\n Safari = 'safari',\n}\n\nenum DateField {\n DeletionDate = 'deletion',\n ExpriationDate = 'expiration',\n}\n\n// Value = hours\nenum DatePreset {\n OneHour = 1,\n OneDay = 24,\n TwoDays = 48,\n ThreeDays = 72,\n SevenDays = 168,\n ThirtyDays = 720,\n Custom = 0,\n Never = null,\n}\n\n// TimeOption is used for the dropdown implementation of custom times\n// twelveHour = displayed time; twentyFourHour = time used in logic\ninterface TimeOption {\n twelveHour: string;\n twentyFourHour: string;\n}\n\n@Directive()\nexport class EffluxDatesComponent implements OnInit {\n @Input() readonly initialDeletionDate: Date;\n @Input() readonly initialExpirationDate: Date;\n @Input() readonly editMode: boolean;\n @Input() readonly disabled: boolean;\n\n @Output() datesChanged = new EventEmitter<{deletionDate: string, expirationDate: string}>();\n\n get browserPath(): BrowserPath {\n if (this.platformUtilsService.isFirefox()) {\n return BrowserPath.Firefox;\n } else if (this.platformUtilsService.isSafari()) {\n return BrowserPath.Safari;\n }\n return BrowserPath.Default;\n }\n\n datesForm = new FormGroup({\n selectedDeletionDatePreset: new FormControl(),\n selectedExpirationDatePreset: new FormControl(),\n defaultDeletionDateTime: new FormControl(),\n defaultExpirationDateTime: new FormControl(),\n fallbackDeletionDate: new FormControl(),\n fallbackDeletionTime: new FormControl(),\n fallbackExpirationDate: new FormControl(),\n fallbackExpirationTime: new FormControl(),\n });\n\n deletionDatePresets: any[] = [\n { name: this.i18nService.t('oneHour'), value: DatePreset.OneHour },\n { name: this.i18nService.t('oneDay'), value: DatePreset.OneDay },\n { name: this.i18nService.t('days', '2'), value: DatePreset.TwoDays },\n { name: this.i18nService.t('days', '3'), value: DatePreset.ThreeDays },\n { name: this.i18nService.t('days', '7'), value: DatePreset.SevenDays },\n { name: this.i18nService.t('days', '30'), value: DatePreset.ThirtyDays },\n { name: this.i18nService.t('custom'), value: DatePreset.Custom },\n ];\n\n expirationDatePresets: any[] = [\n { name: this.i18nService.t('never'), value: DatePreset.Never },\n ].concat([...this.deletionDatePresets]);\n\n get selectedDeletionDatePreset(): FormControl {\n return this.datesForm.get('selectedDeletionDatePreset') as FormControl;\n }\n\n get selectedExpirationDatePreset(): FormControl {\n return this.datesForm.get('selectedExpirationDatePreset') as FormControl;\n }\n\n get defaultDeletionDateTime(): FormControl {\n return this.datesForm.get('defaultDeletionDateTime') as FormControl;\n }\n\n get defaultExpirationDateTime(): FormControl {\n return this.datesForm.get('defaultExpirationDateTime') as FormControl;\n }\n\n get fallbackDeletionDate(): FormControl {\n return this.datesForm.get('fallbackDeletionDate') as FormControl;\n }\n\n get fallbackDeletionTime(): FormControl {\n return this.datesForm.get('fallbackDeletionTime') as FormControl;\n }\n\n get fallbackExpirationDate(): FormControl {\n return this.datesForm.get('fallbackExpirationDate') as FormControl;\n }\n\n get fallbackExpirationTime(): FormControl {\n return this.datesForm.get('fallbackExpirationTime') as FormControl;\n }\n\n // Should be able to call these at any time and compute a submitable value\n get formattedDeletionDate(): string {\n switch (this.selectedDeletionDatePreset.value as DatePreset) {\n case DatePreset.Never:\n this.selectedDeletionDatePreset.setValue(DatePreset.SevenDays);\n return this.formattedDeletionDate;\n case DatePreset.Custom:\n switch (this.browserPath) {\n case BrowserPath.Safari:\n case BrowserPath.Firefox:\n return this.fallbackDeletionDate.value + 'T' + this.fallbackDeletionTime.value;\n default:\n return this.defaultDeletionDateTime.value;\n }\n default:\n const now = new Date();\n const miliseconds = now.setTime(now.getTime() +\n (this.selectedDeletionDatePreset.value as number * 60 * 60 * 1000)) ;\n return new Date(miliseconds).toString();\n }\n }\n\n get formattedExpirationDate(): string {\n switch (this.selectedExpirationDatePreset.value as DatePreset) {\n case DatePreset.Never:\n return null;\n case DatePreset.Custom:\n switch (this.browserPath) {\n case BrowserPath.Safari:\n case BrowserPath.Firefox:\n if ((!this.fallbackExpirationDate.value || !this.fallbackExpirationTime.value) &&\n this.editMode) {\n return null;\n }\n return this.fallbackExpirationDate.value + 'T' + this.fallbackExpirationTime.value;\n default:\n if (!this.defaultExpirationDateTime.value) {\n return null;\n }\n return this.defaultExpirationDateTime.value;\n }\n default:\n const now = new Date();\n const miliseconds = now.setTime(now.getTime() +\n (this.selectedExpirationDatePreset.value as number * 60 * 60 * 1000));\n return new Date(miliseconds).toString();\n }\n }\n //\n\n get safariDeletionTimePresetOptions() {\n return this.safariTimePresetOptions(DateField.DeletionDate);\n }\n\n get safariExpirationTimePresetOptions() {\n return this.safariTimePresetOptions(DateField.ExpriationDate);\n }\n\n private get nextWeek(): Date {\n const nextWeek = new Date();\n nextWeek.setDate(nextWeek.getDate() + 7);\n return nextWeek;\n }\n\n constructor(protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService,\n protected datePipe: DatePipe) {\n }\n\n ngOnInit(): void {\n this.setInitialFormValues();\n this.emitDates();\n this.datesForm.valueChanges.subscribe(() => {\n this.emitDates();\n });\n }\n\n onDeletionDatePresetSelect(value: DatePreset) {\n this.selectedDeletionDatePreset.setValue(value);\n }\n\n clearExpiration() {\n switch (this.browserPath) {\n case BrowserPath.Safari:\n case BrowserPath.Firefox:\n this.fallbackExpirationDate.setValue(null);\n this.fallbackExpirationTime.setValue(null);\n break;\n case BrowserPath.Default:\n this.defaultExpirationDateTime.setValue(null);\n break;\n }\n }\n\n protected emitDates() {\n this.datesChanged.emit({\n deletionDate: this.formattedDeletionDate,\n expirationDate: this.formattedExpirationDate,\n });\n }\n\n protected setInitialFormValues() {\n if (this.editMode) {\n this.selectedDeletionDatePreset.setValue(DatePreset.Custom);\n this.selectedExpirationDatePreset.setValue(DatePreset.Custom);\n switch (this.browserPath) {\n case BrowserPath.Safari:\n case BrowserPath.Firefox:\n this.fallbackDeletionDate.setValue(this.initialDeletionDate.toISOString().slice(0, 10));\n this.fallbackDeletionTime.setValue(this.initialDeletionDate.toTimeString().slice(0, 5));\n if (this.initialExpirationDate != null) {\n this.fallbackExpirationDate.setValue(this.initialExpirationDate.toISOString().slice(0, 10));\n this.fallbackExpirationTime.setValue(this.initialExpirationDate.toTimeString().slice(0, 5));\n }\n break;\n case BrowserPath.Default:\n if (this.initialExpirationDate) {\n this.defaultExpirationDateTime.setValue(\n this.datePipe.transform(new Date(this.initialExpirationDate), 'yyyy-MM-ddTHH:mm'));\n }\n this.defaultDeletionDateTime.setValue(this.datePipe.transform(new Date(this.initialDeletionDate), 'yyyy-MM-ddTHH:mm'));\n break;\n }\n } else {\n this.selectedDeletionDatePreset.setValue(DatePreset.SevenDays);\n this.selectedExpirationDatePreset.setValue(DatePreset.Never);\n\n switch (this.browserPath) {\n case BrowserPath.Safari:\n this.fallbackDeletionDate.setValue(this.nextWeek.toISOString().slice(0, 10));\n this.fallbackDeletionTime.setValue(this.safariTimePresetOptions(DateField.DeletionDate)[1].twentyFourHour);\n break;\n default:\n break;\n }\n }\n }\n\n protected safariTimePresetOptions(field: DateField): TimeOption[] {\n // init individual arrays for major sort groups\n const noon: TimeOption[] = [];\n const midnight: TimeOption[] = [];\n const ams: TimeOption[] = [];\n const pms: TimeOption[] = [];\n\n // determine minute skip (5 min, 10 min, 15 min, etc.)\n const minuteIncrementer = 15;\n\n // loop through each hour on a 12 hour system\n for (let h = 1; h <= 12; h++) {\n // loop through each minute in the hour using the skip to incriment\n for (let m = 0; m < 60; m += minuteIncrementer) {\n // init the final strings that will be added to the lists\n let hour = h.toString();\n let minutes = m.toString();\n\n // add prepending 0s to single digit hours/minutes\n if (h < 10) {\n hour = '0' + hour;\n }\n if (m < 10) {\n minutes = '0' + minutes;\n }\n\n // build time strings and push to relevant sort groups\n if (h === 12) {\n const midnightOption: TimeOption = {\n twelveHour: `${hour}:${minutes} AM`,\n twentyFourHour: `00:${minutes}`,\n };\n midnight.push(midnightOption);\n\n const noonOption: TimeOption = {\n twelveHour: `${hour}:${minutes} PM`,\n twentyFourHour: `${hour}:${minutes}`,\n };\n noon.push(noonOption);\n } else {\n const amOption: TimeOption = {\n twelveHour: `${hour}:${minutes} AM`,\n twentyFourHour: `${hour}:${minutes}`,\n };\n ams.push(amOption);\n\n const pmOption: TimeOption = {\n twelveHour: `${hour}:${minutes} PM`,\n twentyFourHour: `${h + 12}:${minutes}`,\n };\n pms.push(pmOption);\n }\n }\n }\n\n // bring all the arrays together in the right order\n const validTimes = [...midnight, ...ams, ...noon, ...pms];\n\n // determine if an unsupported value already exists on the send & add that to the top of the option list\n // example: if the Send was created with a different client\n if (field === DateField.ExpriationDate && this.initialExpirationDate != null && this.editMode) {\n const previousValue: TimeOption = {\n twelveHour: this.datePipe.transform(this.initialExpirationDate, 'hh:mm a'),\n twentyFourHour: this.datePipe.transform(this.initialExpirationDate, 'HH:mm'),\n };\n return [previousValue, { twelveHour: null, twentyFourHour: null }, ...validTimes];\n } else if (field === DateField.DeletionDate && this.initialDeletionDate != null && this.editMode) {\n const previousValue: TimeOption = {\n twelveHour: this.datePipe.transform(this.initialDeletionDate, 'hh:mm a'),\n twentyFourHour: this.datePipe.transform(this.initialDeletionDate, 'HH:mm'),\n };\n return [previousValue, ...validTimes];\n } else {\n return [{ twelveHour: null, twentyFourHour: null }, ...validTimes];\n }\n }\n}\n","import {\n Directive,\n NgZone,\n OnInit,\n} from '@angular/core';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\nimport { SendType } from 'jslib-common/enums/sendType';\n\nimport { SendView } from 'jslib-common/models/view/sendView';\n\nimport { EnvironmentService } from 'jslib-common/abstractions/environment.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { SearchService } from 'jslib-common/abstractions/search.service';\nimport { SendService } from 'jslib-common/abstractions/send.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\n@Directive()\nexport class SendComponent implements OnInit {\n\n disableSend = false;\n sendType = SendType;\n loaded = false;\n loading = true;\n refreshing = false;\n expired: boolean = false;\n type: SendType = null;\n sends: SendView[] = [];\n filteredSends: SendView[] = [];\n searchText: string;\n selectedType: SendType;\n selectedAll: boolean;\n searchPlaceholder: string;\n filter: (cipher: SendView) => boolean;\n searchPending = false;\n hasSearched = false; // search() function called - returns true if text qualifies for search\n\n actionPromise: any;\n onSuccessfulRemovePassword: () => Promise;\n onSuccessfulDelete: () => Promise;\n onSuccessfulLoad: () => Promise;\n\n private searchTimeout: any;\n\n constructor(protected sendService: SendService, protected i18nService: I18nService,\n protected platformUtilsService: PlatformUtilsService, protected environmentService: EnvironmentService,\n protected ngZone: NgZone, protected searchService: SearchService,\n protected policyService: PolicyService, protected userService: UserService,\n private logService: LogService) { }\n\n async ngOnInit() {\n this.disableSend = await this.policyService.policyAppliesToUser(PolicyType.DisableSend);\n }\n\n async load(filter: (send: SendView) => boolean = null) {\n this.loading = true;\n const sends = await this.sendService.getAllDecrypted();\n this.sends = sends;\n if (this.onSuccessfulLoad != null) {\n await this.onSuccessfulLoad();\n } else {\n // Default action\n this.selectAll();\n }\n this.loading = false;\n this.loaded = true;\n }\n\n async reload(filter: (send: SendView) => boolean = null) {\n this.loaded = false;\n this.sends = [];\n await this.load(filter);\n }\n\n async refresh() {\n try {\n this.refreshing = true;\n await this.reload(this.filter);\n } finally {\n this.refreshing = false;\n }\n }\n\n async applyFilter(filter: (send: SendView) => boolean = null) {\n this.filter = filter;\n await this.search(null);\n }\n\n async search(timeout: number = null) {\n this.searchPending = false;\n if (this.searchTimeout != null) {\n clearTimeout(this.searchTimeout);\n }\n if (timeout == null) {\n this.hasSearched = this.searchService.isSearchable(this.searchText);\n this.filteredSends = this.sends.filter(s => this.filter == null || this.filter(s));\n this.applyTextSearch();\n return;\n }\n this.searchPending = true;\n this.searchTimeout = setTimeout(async () => {\n this.hasSearched = this.searchService.isSearchable(this.searchText);\n this.filteredSends = this.sends.filter(s => this.filter == null || this.filter(s));\n this.applyTextSearch();\n this.searchPending = false;\n }, timeout);\n }\n\n async removePassword(s: SendView): Promise {\n if (this.actionPromise != null || s.password == null) {\n return;\n }\n const confirmed = await this.platformUtilsService.showDialog(this.i18nService.t('removePasswordConfirmation'),\n this.i18nService.t('removePassword'),\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.actionPromise = this.sendService.removePasswordWithServer(s.id);\n await this.actionPromise;\n if (this.onSuccessfulRemovePassword != null) {\n this.onSuccessfulRemovePassword();\n } else {\n // Default actions\n this.platformUtilsService.showToast('success', null, this.i18nService.t('removedPassword'));\n await this.load();\n }\n } catch (e) {\n this.logService.error(e);\n }\n this.actionPromise = null;\n }\n\n async delete(s: SendView): Promise {\n if (this.actionPromise != null) {\n return false;\n }\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('deleteSendConfirmation'),\n this.i18nService.t('deleteSend'),\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.actionPromise = this.sendService.deleteWithServer(s.id);\n await this.actionPromise;\n\n if (this.onSuccessfulDelete != null) {\n this.onSuccessfulDelete();\n } else {\n // Default actions\n this.platformUtilsService.showToast('success', null, this.i18nService.t('deletedSend'));\n await this.refresh();\n }\n } catch (e) {\n this.logService.error(e);\n }\n this.actionPromise = null;\n return true;\n }\n\n copy(s: SendView) {\n const sendLinkBaseUrl = this.environmentService.getSendUrl();\n const link = sendLinkBaseUrl + s.accessId + '/' + s.urlB64Key;\n this.platformUtilsService.copyToClipboard(link);\n this.platformUtilsService.showToast('success', null,\n this.i18nService.t('valueCopied', this.i18nService.t('sendLink')));\n }\n\n searchTextChanged() {\n this.search(200);\n }\n\n selectAll() {\n this.clearSelections();\n this.selectedAll = true;\n this.applyFilter(null);\n }\n\n selectType(type: SendType) {\n this.clearSelections();\n this.selectedType = type;\n this.applyFilter(s => s.type === type);\n }\n\n clearSelections() {\n this.selectedAll = false;\n this.selectedType = null;\n }\n\n private applyTextSearch() {\n if (this.searchText != null) {\n this.filteredSends = this.searchService.searchSends(this.filteredSends, this.searchText);\n }\n }\n}\n","export class UpdateProfileRequest {\n name: string;\n masterPasswordHint: string;\n culture = 'en-US'; // deprecated\n\n constructor(name: string, masterPasswordHint: string) {\n this.name = name;\n this.masterPasswordHint = masterPasswordHint ? masterPasswordHint : null;\n }\n}\n","import { EmailTokenRequest } from './emailTokenRequest';\n\nexport class EmailRequest extends EmailTokenRequest {\n newMasterPasswordHash: string;\n token: string;\n key: string;\n}\n","import { SendRequest } from './sendRequest';\n\nimport { Send } from '../domain/send';\n\nexport class SendWithIdRequest extends SendRequest {\n id: string;\n\n constructor(send: Send) {\n super(send);\n this.id = send.id;\n }\n}\n","import { PasswordRequest } from './passwordRequest';\n\nimport { KdfType } from '../../enums/kdfType';\n\nexport class KdfRequest extends PasswordRequest {\n kdf: KdfType;\n kdfIterations: number;\n}\n","export class UpdateDomainsRequest {\n equivalentDomains: string[][];\n excludedGlobalEquivalentDomains: number[];\n}\n","import { EmergencyAccessType } from '../../enums/emergencyAccessType';\n\nexport class EmergencyAccessInviteRequest {\n email: string;\n type: EmergencyAccessType;\n waitTimeDays: number;\n}\n","export class EmergencyAccessPasswordRequest {\n newMasterPasswordHash: string;\n key: string;\n}\n","export class EmergencyAccessConfirmRequest {\n key: string;\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class PasswordHistoryResponse extends BaseResponse {\n password: string;\n lastUsedDate: string;\n\n constructor(response: any) {\n super(response);\n this.password = this.getResponseProperty('Password');\n this.lastUsedDate = this.getResponseProperty('LastUsedDate');\n }\n}\n","import {\n Directive,\n Input,\n OnInit,\n} from '@angular/core';\nimport {\n AbstractControl,\n ControlValueAccessor,\n FormBuilder,\n ValidationErrors,\n Validator\n} from '@angular/forms';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\n\nimport { PolicyType } from 'jslib-common/enums/policyType';\nimport { Policy } from 'jslib-common/models/domain/policy';\n\n@Directive()\nexport class VaultTimeoutInputComponent implements ControlValueAccessor, Validator, OnInit {\n\n get showCustom() {\n return this.form.get('vaultTimeout').value === VaultTimeoutInputComponent.CUSTOM_VALUE;\n }\n\n static CUSTOM_VALUE = -100;\n\n form = this.fb.group({\n vaultTimeout: [null],\n custom: this.fb.group({\n hours: [null],\n minutes: [null],\n }),\n });\n\n @Input() vaultTimeouts: { name: string; value: number; }[];\n vaultTimeoutPolicy: Policy;\n vaultTimeoutPolicyHours: number;\n vaultTimeoutPolicyMinutes: number;\n\n private onChange: (vaultTimeout: number) => void;\n private validatorChange: () => void;\n\n constructor(private fb: FormBuilder, private policyService: PolicyService, private i18nService: I18nService) {\n }\n\n async ngOnInit() {\n if (await this.policyService.policyAppliesToUser(PolicyType.MaximumVaultTimeout)) {\n const vaultTimeoutPolicy = await this.policyService.getAll(PolicyType.MaximumVaultTimeout);\n\n this.vaultTimeoutPolicy = vaultTimeoutPolicy[0];\n this.vaultTimeoutPolicyHours = Math.floor(this.vaultTimeoutPolicy.data.minutes / 60);\n this.vaultTimeoutPolicyMinutes = this.vaultTimeoutPolicy.data.minutes % 60;\n\n this.vaultTimeouts = this.vaultTimeouts.filter(t =>\n t.value <= this.vaultTimeoutPolicy.data.minutes &&\n (t.value > 0 || t.value === VaultTimeoutInputComponent.CUSTOM_VALUE) &&\n t.value != null\n );\n this.validatorChange();\n }\n\n this.form.valueChanges.subscribe(async value => {\n this.onChange(this.getVaultTimeout(value));\n });\n\n // Assign the previous value to the custom fields\n this.form.get('vaultTimeout').valueChanges.subscribe(value => {\n if (value !== VaultTimeoutInputComponent.CUSTOM_VALUE) {\n return;\n }\n\n const current = Math.max(this.form.value.vaultTimeout, 0);\n this.form.patchValue({\n custom: {\n hours: Math.floor(current / 60),\n minutes: current % 60,\n },\n });\n });\n }\n\n ngOnChanges() {\n this.vaultTimeouts.push({ name: this.i18nService.t('custom'), value: VaultTimeoutInputComponent.CUSTOM_VALUE });\n }\n\n getVaultTimeout(value: any) {\n if (value.vaultTimeout !== VaultTimeoutInputComponent.CUSTOM_VALUE) {\n return value.vaultTimeout;\n }\n\n return value.custom.hours * 60 + value.custom.minutes;\n }\n\n writeValue(value: number): void {\n if (value == null) {\n return;\n }\n\n if (this.vaultTimeouts.every(p => p.value !== value)) {\n this.form.setValue({\n vaultTimeout: VaultTimeoutInputComponent.CUSTOM_VALUE,\n custom: {\n hours: Math.floor(value / 60),\n minutes: value % 60,\n },\n });\n return;\n }\n\n this.form.patchValue({\n vaultTimeout: value,\n });\n }\n\n registerOnChange(onChange: any): void {\n this.onChange = onChange;\n }\n\n // tslint:disable-next-line\n registerOnTouched(onTouched: any): void {}\n\n // tslint:disable-next-line\n setDisabledState?(isDisabled: boolean): void { }\n\n validate(control: AbstractControl): ValidationErrors {\n if (this.vaultTimeoutPolicy && this.vaultTimeoutPolicy?.data?.minutes < control.value) {\n return { policyError: true };\n }\n\n return null;\n }\n\n registerOnValidatorChange(fn: () => void): void {\n this.validatorChange = fn;\n }\n}\n","import { Directive, OnInit } from '@angular/core';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { GeneratedPasswordHistory } from 'jslib-common/models/domain/generatedPasswordHistory';\n\n@Directive()\nexport class PasswordGeneratorHistoryComponent implements OnInit {\n history: GeneratedPasswordHistory[] = [];\n\n constructor(protected passwordGenerationService: PasswordGenerationService,\n protected platformUtilsService: PlatformUtilsService, protected i18nService: I18nService,\n private win: Window) { }\n\n async ngOnInit() {\n this.history = await this.passwordGenerationService.getHistory();\n }\n\n clear() {\n this.history = [];\n this.passwordGenerationService.clear();\n }\n\n copy(password: string) {\n const copyOptions = this.win != null ? { window: this.win } : null;\n this.platformUtilsService.copyToClipboard(password, copyOptions);\n this.platformUtilsService.showToast('info', null,\n this.i18nService.t('valueCopied', this.i18nService.t('password')));\n }\n}\n","import {\n Directive,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { PasswordGeneratorPolicyOptions } from 'jslib-common/models/domain/passwordGeneratorPolicyOptions';\n\n@Directive()\nexport class PasswordGeneratorComponent implements OnInit {\n @Input() showSelect: boolean = false;\n @Output() onSelected = new EventEmitter();\n\n passTypeOptions: any[];\n options: any = {};\n password: string = '-';\n showOptions = false;\n avoidAmbiguous = false;\n enforcedPolicyOptions: PasswordGeneratorPolicyOptions;\n\n constructor(protected passwordGenerationService: PasswordGenerationService,\n protected platformUtilsService: PlatformUtilsService, protected i18nService: I18nService,\n private win: Window) {\n this.passTypeOptions = [\n { name: i18nService.t('password'), value: 'password' },\n { name: i18nService.t('passphrase'), value: 'passphrase' },\n ];\n }\n\n async ngOnInit() {\n const optionsResponse = await this.passwordGenerationService.getOptions();\n this.options = optionsResponse[0];\n this.enforcedPolicyOptions = optionsResponse[1];\n this.avoidAmbiguous = !this.options.ambiguous;\n this.options.type = this.options.type === 'passphrase' ? 'passphrase' : 'password';\n this.password = await this.passwordGenerationService.generatePassword(this.options);\n await this.passwordGenerationService.addHistory(this.password);\n }\n\n async sliderChanged() {\n this.saveOptions(false);\n await this.passwordGenerationService.addHistory(this.password);\n }\n\n async sliderInput() {\n this.normalizeOptions();\n this.password = await this.passwordGenerationService.generatePassword(this.options);\n }\n\n async saveOptions(regenerate: boolean = true) {\n this.normalizeOptions();\n await this.passwordGenerationService.saveOptions(this.options);\n\n if (regenerate) {\n await this.regenerate();\n }\n }\n\n async regenerate() {\n this.password = await this.passwordGenerationService.generatePassword(this.options);\n await this.passwordGenerationService.addHistory(this.password);\n }\n\n copy() {\n const copyOptions = this.win != null ? { window: this.win } : null;\n this.platformUtilsService.copyToClipboard(this.password, copyOptions);\n this.platformUtilsService.showToast('info', null,\n this.i18nService.t('valueCopied', this.i18nService.t('password')));\n }\n\n select() {\n this.onSelected.emit(this.password);\n }\n\n toggleOptions() {\n this.showOptions = !this.showOptions;\n }\n\n private normalizeOptions() {\n // Application level normalize options depedent on class variables\n this.options.ambiguous = !this.avoidAmbiguous;\n\n if (!this.options.uppercase && !this.options.lowercase && !this.options.number && !this.options.special) {\n this.options.lowercase = true;\n if (this.win != null) {\n const lowercase = this.win.document.querySelector('#lowercase') as HTMLInputElement;\n if (lowercase) {\n lowercase.checked = true;\n }\n }\n }\n\n this.passwordGenerationService.normalizeOptions(this.options, this.enforcedPolicyOptions);\n }\n}\n","import {\n Directive,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { FolderService } from 'jslib-common/abstractions/folder.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\n\nimport { FolderView } from 'jslib-common/models/view/folderView';\n\n@Directive()\nexport class FolderAddEditComponent implements OnInit {\n @Input() folderId: string;\n @Output() onSavedFolder = new EventEmitter();\n @Output() onDeletedFolder = new EventEmitter();\n\n editMode: boolean = false;\n folder: FolderView = new FolderView();\n title: string;\n formPromise: Promise;\n deletePromise: Promise;\n\n constructor(protected folderService: FolderService, protected i18nService: I18nService,\n protected platformUtilsService: PlatformUtilsService, private logService: LogService) { }\n\n async ngOnInit() {\n await this.init();\n }\n\n async submit(): Promise {\n if (this.folder.name == null || this.folder.name === '') {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('nameRequired'));\n return false;\n }\n\n try {\n const folder = await this.folderService.encrypt(this.folder);\n this.formPromise = this.folderService.saveWithServer(folder);\n await this.formPromise;\n this.platformUtilsService.showToast('success', null,\n this.i18nService.t(this.editMode ? 'editedFolder' : 'addedFolder'));\n this.onSavedFolder.emit(this.folder);\n return true;\n } catch (e) {\n this.logService.error(e);\n }\n\n return false;\n }\n\n async delete(): Promise {\n const confirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('deleteFolderConfirmation'), this.i18nService.t('deleteFolder'),\n this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');\n if (!confirmed) {\n return false;\n }\n\n try {\n this.deletePromise = this.folderService.deleteWithServer(this.folder.id);\n await this.deletePromise;\n this.platformUtilsService.showToast('success', null, this.i18nService.t('deletedFolder'));\n this.onDeletedFolder.emit(this.folder);\n } catch (e) {\n this.logService.error(e);\n }\n\n return true;\n }\n\n protected async init() {\n this.editMode = this.folderId != null;\n\n if (this.editMode) {\n this.editMode = true;\n this.title = this.i18nService.t('editFolder');\n const folder = await this.folderService.get(this.folderId);\n this.folder = await folder.decrypt();\n } else {\n this.title = this.i18nService.t('addFolder');\n }\n }\n}\n","import {\n Directive,\n EventEmitter,\n Input,\n OnInit,\n Output,\n} from '@angular/core';\n\nimport { OrganizationUserStatusType } from 'jslib-common/enums/organizationUserStatusType';\n\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\n\nimport { Organization } from 'jslib-common/models/domain/organization';\nimport { CipherView } from 'jslib-common/models/view/cipherView';\nimport { CollectionView } from 'jslib-common/models/view/collectionView';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\n@Directive()\nexport class ShareComponent implements OnInit {\n @Input() cipherId: string;\n @Input() organizationId: string;\n @Output() onSharedCipher = new EventEmitter();\n\n formPromise: Promise;\n cipher: CipherView;\n collections: CollectionView[] = [];\n organizations: Organization[] = [];\n\n protected writeableCollections: CollectionView[] = [];\n\n constructor(protected collectionService: CollectionService, protected platformUtilsService: PlatformUtilsService,\n protected i18nService: I18nService, protected userService: UserService,\n protected cipherService: CipherService, private logService: LogService) { }\n\n async ngOnInit() {\n await this.load();\n }\n\n async load() {\n const allCollections = await this.collectionService.getAllDecrypted();\n this.writeableCollections = allCollections.map(c => c).filter(c => !c.readOnly);\n const orgs = await this.userService.getAllOrganizations();\n this.organizations = orgs.sort(Utils.getSortFunction(this.i18nService, 'name'))\n .filter(o => o.enabled && o.status === OrganizationUserStatusType.Confirmed);\n\n const cipherDomain = await this.cipherService.get(this.cipherId);\n this.cipher = await cipherDomain.decrypt();\n if (this.organizationId == null && this.organizations.length > 0) {\n this.organizationId = this.organizations[0].id;\n }\n this.filterCollections();\n }\n\n filterCollections() {\n this.writeableCollections.forEach(c => (c as any).checked = false);\n if (this.organizationId == null || this.writeableCollections.length === 0) {\n this.collections = [];\n } else {\n this.collections = this.writeableCollections.filter(c => c.organizationId === this.organizationId);\n }\n }\n\n async submit(): Promise {\n const selectedCollectionIds = this.collections\n .filter(c => !!(c as any).checked)\n .map(c => c.id);\n if (selectedCollectionIds.length === 0) {\n this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),\n this.i18nService.t('selectOneCollection'));\n return;\n }\n\n const cipherDomain = await this.cipherService.get(this.cipherId);\n const cipherView = await cipherDomain.decrypt();\n const orgName = this.organizations.find(o => o.id === this.organizationId)?.name ?? this.i18nService.t('organization');\n\n try {\n this.formPromise = this.cipherService.shareWithServer(cipherView, this.organizationId,\n selectedCollectionIds).then(async () => {\n this.onSharedCipher.emit();\n this.platformUtilsService.showToast('success', null,\n this.i18nService.t('movedItemToOrg', cipherView.name, orgName));\n });\n await this.formPromise;\n return true;\n } catch (e) {\n this.logService.error(e);\n }\n return false;\n }\n\n get canSave() {\n if (this.collections != null) {\n for (let i = 0; i < this.collections.length; i++) {\n if ((this.collections[i] as any).checked) {\n return true;\n }\n }\n }\n return false;\n }\n}\n","import {\n Directive,\n ElementRef,\n HostListener,\n OnInit,\n} from '@angular/core';\n\n@Directive({\n selector: '[appBoxRow]',\n})\nexport class BoxRowDirective implements OnInit {\n el: HTMLElement = null;\n formEls: Element[];\n\n constructor(private elRef: ElementRef) {\n this.el = elRef.nativeElement;\n }\n\n ngOnInit(): void {\n this.formEls = Array.from(this.el.querySelectorAll('input:not([type=\"hidden\"]), select, textarea'));\n this.formEls.forEach(formEl => {\n formEl.addEventListener('focus', (event: Event) => {\n this.el.classList.add('active');\n }, false);\n\n formEl.addEventListener('blur', (event: Event) => {\n this.el.classList.remove('active');\n }, false);\n });\n }\n\n @HostListener('click', ['$event']) onClick(event: Event) {\n const target = event.target as HTMLElement;\n if (target !== this.el && !target.classList.contains('progress') &&\n !target.classList.contains('progress-bar')) {\n return;\n }\n\n if (this.formEls.length > 0) {\n const formEl = (this.formEls[0] as HTMLElement);\n if (formEl.tagName.toLowerCase() === 'input') {\n const inputEl = (formEl as HTMLInputElement);\n if (inputEl.type != null && inputEl.type.toLowerCase() === 'checkbox') {\n inputEl.click();\n return;\n }\n }\n formEl.focus();\n }\n }\n}\n","import {\n Pipe,\n PipeTransform,\n} from '@angular/core';\n\nimport { CipherView } from 'jslib-common/models/view/cipherView';\n\n@Pipe({\n name: 'searchCiphers',\n})\nexport class SearchCiphersPipe implements PipeTransform {\n transform(ciphers: CipherView[], searchText: string, deleted: boolean = false): CipherView[] {\n if (ciphers == null || ciphers.length === 0) {\n return [];\n }\n\n if (searchText == null || searchText.length < 2) {\n return ciphers.filter(c => {\n return deleted !== c.isDeleted;\n });\n }\n\n searchText = searchText.trim().toLowerCase();\n return ciphers.filter(c => {\n if (deleted !== c.isDeleted) {\n return false;\n }\n if (c.name != null && c.name.toLowerCase().indexOf(searchText) > -1) {\n return true;\n }\n if (searchText.length >= 8 && c.id.startsWith(searchText)) {\n return true;\n }\n if (c.subTitle != null && c.subTitle.toLowerCase().indexOf(searchText) > -1) {\n return true;\n }\n if (c.login && c.login.uri != null && c.login.uri.toLowerCase().indexOf(searchText) > -1) {\n return true;\n }\n\n return false;\n });\n }\n}\n","import { Component } from '@angular/core';\n\nimport { AppComponent as BaseAppComponent } from 'src/app/app.component';\nimport { DisablePersonalVaultExportPolicy } from './policies/disable-personal-vault-export.component';\nimport { MaximumVaultTimeoutPolicy } from './policies/maximum-vault-timeout.component';\n\n@Component({\n selector: 'app-root',\n templateUrl: '../../../src/app/app.component.html',\n})\nexport class AppComponent extends BaseAppComponent {\n\n ngOnInit() {\n super.ngOnInit();\n\n this.policyListService.addPolicies([\n new MaximumVaultTimeoutPolicy(),\n new DisablePersonalVaultExportPolicy(),\n ]);\n }\n\n}\n"," ","import * as jq from 'jquery';\nimport Swal from 'sweetalert2';\n\nimport {\n BodyOutputType,\n Toast,\n ToasterConfig,\n ToasterService,\n} from 'angular2-toaster';\n\nimport {\n Component,\n NgZone,\n OnDestroy,\n OnInit,\n SecurityContext,\n} from '@angular/core';\nimport { DomSanitizer } from '@angular/platform-browser';\nimport {\n NavigationEnd,\n Router,\n} from '@angular/router';\n\nimport { BroadcasterService } from 'jslib-angular/services/broadcaster.service';\n\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\n\nimport { AuthService } from 'jslib-common/abstractions/auth.service';\nimport { CipherService } from 'jslib-common/abstractions/cipher.service';\nimport { CollectionService } from 'jslib-common/abstractions/collection.service';\nimport { CryptoService } from 'jslib-common/abstractions/crypto.service';\nimport { EventService } from 'jslib-common/abstractions/event.service';\nimport { FolderService } from 'jslib-common/abstractions/folder.service';\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';\nimport { NotificationsService } from 'jslib-common/abstractions/notifications.service';\nimport { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService } from 'jslib-common/abstractions/policy.service';\nimport { SearchService } from 'jslib-common/abstractions/search.service';\nimport { SettingsService } from 'jslib-common/abstractions/settings.service';\nimport { StateService } from 'jslib-common/abstractions/state.service';\nimport { SyncService } from 'jslib-common/abstractions/sync.service';\nimport { TokenService } from 'jslib-common/abstractions/token.service';\nimport { UserService } from 'jslib-common/abstractions/user.service';\nimport { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';\n\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\nimport { PolicyListService } from './services/policy-list.service';\nimport { RouterService } from './services/router.service';\n\nimport { DisableSendPolicy } from './organizations/policies/disable-send.component';\nimport { MasterPasswordPolicy } from './organizations/policies/master-password.component';\nimport { PasswordGeneratorPolicy } from './organizations/policies/password-generator.component';\nimport { PersonalOwnershipPolicy } from './organizations/policies/personal-ownership.component';\nimport { RequireSsoPolicy } from './organizations/policies/require-sso.component';\nimport { ResetPasswordPolicy } from './organizations/policies/reset-password.component';\nimport { SendOptionsPolicy } from './organizations/policies/send-options.component';\nimport { SingleOrgPolicy } from './organizations/policies/single-org.component';\nimport { TwoFactorAuthenticationPolicy } from './organizations/policies/two-factor-authentication.component';\n\nconst BroadcasterSubscriptionId = 'AppComponent';\nconst IdleTimeout = 60000 * 10; // 10 minutes\n\n@Component({\n selector: 'app-root',\n templateUrl: 'app.component.html',\n})\nexport class AppComponent implements OnDestroy, OnInit {\n\n toasterConfig: ToasterConfig = new ToasterConfig({\n showCloseButton: true,\n mouseoverTimerStop: true,\n animation: 'flyRight',\n limit: 5,\n });\n\n private lastActivity: number = null;\n private idleTimer: number = null;\n private isIdle = false;\n\n constructor(\n private broadcasterService: BroadcasterService, private userService: UserService,\n private tokenService: TokenService, private folderService: FolderService,\n private settingsService: SettingsService, private syncService: SyncService,\n private passwordGenerationService: PasswordGenerationService, private cipherService: CipherService,\n private authService: AuthService, private router: Router,\n private toasterService: ToasterService, private i18nService: I18nService,\n private platformUtilsService: PlatformUtilsService, private ngZone: NgZone,\n private vaultTimeoutService: VaultTimeoutService, private storageService: StorageService,\n private cryptoService: CryptoService, private collectionService: CollectionService,\n private sanitizer: DomSanitizer, private searchService: SearchService,\n private notificationsService: NotificationsService, private routerService: RouterService,\n private stateService: StateService, private eventService: EventService,\n private policyService: PolicyService, protected policyListService: PolicyListService,\n private keyConnectorService: KeyConnectorService) { }\n\n ngOnInit() {\n this.ngZone.runOutsideAngular(() => {\n window.onmousemove = () => this.recordActivity();\n window.onmousedown = () => this.recordActivity();\n window.ontouchstart = () => this.recordActivity();\n window.onclick = () => this.recordActivity();\n window.onscroll = () => this.recordActivity();\n window.onkeypress = () => this.recordActivity();\n });\n\n this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {\n this.ngZone.run(async () => {\n switch (message.command) {\n case 'loggedIn':\n case 'loggedOut':\n case 'unlocked':\n this.notificationsService.updateConnection(false);\n break;\n case 'authBlocked':\n this.router.navigate(['/']);\n break;\n case 'logout':\n this.logOut(!!message.expired);\n break;\n case 'lockVault':\n await this.vaultTimeoutService.lock();\n break;\n case 'locked':\n this.notificationsService.updateConnection(false);\n this.router.navigate(['lock']);\n break;\n case 'lockedUrl':\n window.setTimeout(() => this.routerService.setPreviousUrl(message.url), 500);\n break;\n case 'syncStarted':\n break;\n case 'syncCompleted':\n break;\n case 'upgradeOrganization':\n const upgradeConfirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('upgradeOrganizationDesc'), this.i18nService.t('upgradeOrganization'),\n this.i18nService.t('upgradeOrganization'), this.i18nService.t('cancel'));\n if (upgradeConfirmed) {\n this.router.navigate(['organizations', message.organizationId, 'settings', 'billing']);\n }\n break;\n case 'premiumRequired':\n const premiumConfirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('premiumRequiredDesc'), this.i18nService.t('premiumRequired'),\n this.i18nService.t('learnMore'), this.i18nService.t('cancel'));\n if (premiumConfirmed) {\n this.router.navigate(['settings/premium']);\n }\n break;\n case 'emailVerificationRequired':\n const emailVerificationConfirmed = await this.platformUtilsService.showDialog(\n this.i18nService.t('emailVerificationRequiredDesc'),\n this.i18nService.t('emailVerificationRequired'),\n this.i18nService.t('learnMore'), this.i18nService.t('cancel'));\n if (emailVerificationConfirmed) {\n this.platformUtilsService.launchUri('https://bitwarden.com/help/article/create-bitwarden-account/');\n }\n break;\n case 'showToast':\n this.showToast(message);\n break;\n case 'setFullWidth':\n this.setFullWidth();\n break;\n case 'convertAccountToKeyConnector':\n this.keyConnectorService.setConvertAccountRequired(true);\n this.router.navigate(['/remove-password']);\n break;\n default:\n break;\n }\n });\n });\n\n this.router.events.subscribe(event => {\n if (event instanceof NavigationEnd) {\n const modals = Array.from(document.querySelectorAll('.modal'));\n for (const modal of modals) {\n (jq(modal) as any).modal('hide');\n }\n\n if (document.querySelector('.swal-modal') != null) {\n Swal.close(undefined);\n }\n }\n });\n\n this.policyListService.addPolicies([\n new TwoFactorAuthenticationPolicy(),\n new MasterPasswordPolicy(),\n new PasswordGeneratorPolicy(),\n new SingleOrgPolicy(),\n new RequireSsoPolicy(),\n new PersonalOwnershipPolicy(),\n new DisableSendPolicy(),\n new SendOptionsPolicy(),\n new ResetPasswordPolicy(),\n ]);\n\n this.setFullWidth();\n }\n\n ngOnDestroy() {\n this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);\n }\n\n private async logOut(expired: boolean) {\n await this.eventService.uploadEvents();\n const userId = await this.userService.getUserId();\n\n await Promise.all([\n this.eventService.clearEvents(),\n this.syncService.setLastSync(new Date(0)),\n this.tokenService.clearToken(),\n this.cryptoService.clearKeys(),\n this.userService.clear(),\n this.settingsService.clear(userId),\n this.cipherService.clear(userId),\n this.folderService.clear(userId),\n this.collectionService.clear(userId),\n this.policyService.clear(userId),\n this.passwordGenerationService.clear(),\n this.stateService.purge(),\n this.keyConnectorService.clear(),\n ]);\n\n this.searchService.clearIndex();\n this.authService.logOut(async () => {\n if (expired) {\n this.toasterService.popAsync('warning', this.i18nService.t('loggedOut'),\n this.i18nService.t('loginExpired'));\n }\n\n Swal.close();\n this.router.navigate(['/']);\n });\n }\n\n private async recordActivity() {\n const now = (new Date()).getTime();\n if (this.lastActivity != null && now - this.lastActivity < 250) {\n return;\n }\n\n this.lastActivity = now;\n this.storageService.save(ConstantsService.lastActiveKey, now);\n\n // Idle states\n if (this.isIdle) {\n this.isIdle = false;\n this.idleStateChanged();\n }\n if (this.idleTimer != null) {\n window.clearTimeout(this.idleTimer);\n this.idleTimer = null;\n }\n this.idleTimer = window.setTimeout(() => {\n if (!this.isIdle) {\n this.isIdle = true;\n this.idleStateChanged();\n }\n }, IdleTimeout);\n }\n\n private showToast(msg: any) {\n const toast: Toast = {\n type: msg.type,\n title: msg.title,\n };\n if (typeof (msg.text) === 'string') {\n toast.body = msg.text;\n } else if (msg.text.length === 1) {\n toast.body = msg.text[0];\n } else {\n let message = '';\n msg.text.forEach((t: string) =>\n message += ('

' + this.sanitizer.sanitize(SecurityContext.HTML, t) + '

'));\n toast.body = message;\n toast.bodyOutputType = BodyOutputType.TrustedHtml;\n }\n if (msg.options != null) {\n if (msg.options.trustedHtml === true) {\n toast.bodyOutputType = BodyOutputType.TrustedHtml;\n }\n if (msg.options.timeout != null && msg.options.timeout > 0) {\n toast.timeout = msg.options.timeout;\n }\n }\n this.toasterService.popAsync(toast);\n }\n\n private idleStateChanged() {\n if (this.isIdle) {\n this.notificationsService.disconnectFromInactivity();\n } else {\n this.notificationsService.reconnectFromActivity();\n }\n }\n\n private async setFullWidth() {\n const enableFullWidth = await this.storageService.get('enableFullWidth');\n if (enableFullWidth) {\n document.body.classList.add('full-width');\n } else {\n document.body.classList.remove('full-width');\n }\n }\n}\n","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\n\nimport { OssModule } from 'src/app/oss.module';\n\nimport { SsoComponent } from './manage/sso.component';\nimport { OrganizationsRoutingModule } from './organizations-routing.module';\n\n@NgModule({\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n OssModule,\n OrganizationsRoutingModule,\n ],\n declarations: [\n SsoComponent,\n ],\n})\nexport class OrganizationsModule {}\n","import { SsoConfigApi } from '../../api/ssoConfigApi';\n\nexport class OrganizationSsoRequest {\n enabled: boolean = false;\n data: SsoConfigApi;\n}\n","import { NgModule } from '@angular/core';\nimport { RouterModule, Routes } from '@angular/router';\n\nimport { AuthGuardService } from 'jslib-angular/services/auth-guard.service';\n\nimport { Permissions } from 'jslib-common/enums/permissions';\n\nimport { OrganizationLayoutComponent } from 'src/app/layouts/organization-layout.component';\nimport { ManageComponent } from 'src/app/organizations/manage/manage.component';\nimport { OrganizationGuardService } from 'src/app/services/organization-guard.service';\nimport { OrganizationTypeGuardService } from 'src/app/services/organization-type-guard.service';\n\nimport { SsoComponent } from './manage/sso.component';\n\nconst routes: Routes = [\n {\n path: 'organizations/:organizationId',\n component: OrganizationLayoutComponent,\n canActivate: [AuthGuardService, OrganizationGuardService],\n children: [\n {\n path: 'manage',\n component: ManageComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n permissions: [\n Permissions.CreateNewCollections,\n Permissions.EditAnyCollection,\n Permissions.DeleteAnyCollection,\n Permissions.EditAssignedCollections,\n Permissions.DeleteAssignedCollections,\n Permissions.AccessEventLogs,\n Permissions.ManageGroups,\n Permissions.ManageUsers,\n Permissions.ManagePolicies,\n Permissions.ManageSso,\n ],\n },\n children: [\n {\n path: 'sso',\n component: SsoComponent,\n },\n ],\n },\n ],\n },\n];\n\n@NgModule({\n imports: [RouterModule.forChild(routes)],\n exports: [RouterModule],\n})\nexport class OrganizationsRoutingModule { }\n","import { NgModule } from '@angular/core';\nimport {\n RouterModule,\n Routes,\n} from '@angular/router';\n\nimport { FrontendLayoutComponent } from './layouts/frontend-layout.component';\nimport { OrganizationLayoutComponent } from './layouts/organization-layout.component';\nimport { UserLayoutComponent } from './layouts/user-layout.component';\n\nimport { AcceptEmergencyComponent } from './accounts/accept-emergency.component';\nimport { AcceptOrganizationComponent } from './accounts/accept-organization.component';\nimport { HintComponent } from './accounts/hint.component';\nimport { LockComponent } from './accounts/lock.component';\nimport { LoginComponent } from './accounts/login.component';\nimport { RecoverDeleteComponent } from './accounts/recover-delete.component';\nimport { RecoverTwoFactorComponent } from './accounts/recover-two-factor.component';\nimport { RegisterComponent } from './accounts/register.component';\nimport { RemovePasswordComponent } from './accounts/remove-password.component';\nimport { SetPasswordComponent } from './accounts/set-password.component';\nimport { SsoComponent } from './accounts/sso.component';\nimport { TwoFactorComponent } from './accounts/two-factor.component';\nimport { UpdateTempPasswordComponent } from './accounts/update-temp-password.component';\nimport { VerifyEmailTokenComponent } from './accounts/verify-email-token.component';\nimport { VerifyRecoverDeleteComponent } from './accounts/verify-recover-delete.component';\n\nimport { CollectionsComponent as OrgManageCollectionsComponent } from './organizations/manage/collections.component';\nimport { EventsComponent as OrgEventsComponent } from './organizations/manage/events.component';\nimport { GroupsComponent as OrgGroupsComponent } from './organizations/manage/groups.component';\nimport { ManageComponent as OrgManageComponent } from './organizations/manage/manage.component';\nimport { PeopleComponent as OrgPeopleComponent } from './organizations/manage/people.component';\nimport { PoliciesComponent as OrgPoliciesComponent } from './organizations/manage/policies.component';\n\nimport { AccountComponent as OrgAccountComponent } from './organizations/settings/account.component';\nimport { OrganizationBillingComponent } from './organizations/settings/organization-billing.component';\nimport { OrganizationSubscriptionComponent } from './organizations/settings/organization-subscription.component';\nimport { SettingsComponent as OrgSettingsComponent } from './organizations/settings/settings.component';\nimport {\n TwoFactorSetupComponent as OrgTwoFactorSetupComponent,\n} from './organizations/settings/two-factor-setup.component';\n\nimport { FamiliesForEnterpriseSetupComponent } from './organizations/sponsorships/families-for-enterprise-setup.component';\nimport { ExportComponent as OrgExportComponent } from './organizations/tools/export.component';\nimport {\n ExposedPasswordsReportComponent as OrgExposedPasswordsReportComponent,\n} from './organizations/tools/exposed-passwords-report.component';\nimport { ImportComponent as OrgImportComponent } from './organizations/tools/import.component';\nimport {\n InactiveTwoFactorReportComponent as OrgInactiveTwoFactorReportComponent,\n} from './organizations/tools/inactive-two-factor-report.component';\nimport {\n ReusedPasswordsReportComponent as OrgReusedPasswordsReportComponent,\n} from './organizations/tools/reused-passwords-report.component';\nimport { ToolsComponent as OrgToolsComponent } from './organizations/tools/tools.component';\nimport {\n UnsecuredWebsitesReportComponent as OrgUnsecuredWebsitesReportComponent,\n} from './organizations/tools/unsecured-websites-report.component';\nimport {\n WeakPasswordsReportComponent as OrgWeakPasswordsReportComponent,\n} from './organizations/tools/weak-passwords-report.component';\n\nimport { VaultComponent as OrgVaultComponent } from './organizations/vault/vault.component';\n\nimport { AccessComponent } from './send/access.component';\nimport { SendComponent } from './send/send.component';\n\nimport { AccountComponent } from './settings/account.component';\nimport { CreateOrganizationComponent } from './settings/create-organization.component';\nimport { DomainRulesComponent } from './settings/domain-rules.component';\nimport { OptionsComponent } from './settings/options.component';\nimport { OrganizationsComponent } from './settings/organizations.component';\nimport { PremiumComponent } from './settings/premium.component';\nimport { SettingsComponent } from './settings/settings.component';\nimport { TwoFactorSetupComponent } from './settings/two-factor-setup.component';\nimport { UserBillingComponent } from './settings/user-billing.component';\nimport { UserSubscriptionComponent } from './settings/user-subscription.component';\n\nimport { BreachReportComponent } from './tools/breach-report.component';\nimport { ExportComponent } from './tools/export.component';\nimport { ExposedPasswordsReportComponent } from './tools/exposed-passwords-report.component';\nimport { ImportComponent } from './tools/import.component';\nimport { InactiveTwoFactorReportComponent } from './tools/inactive-two-factor-report.component';\nimport { PasswordGeneratorComponent } from './tools/password-generator.component';\nimport { ReusedPasswordsReportComponent } from './tools/reused-passwords-report.component';\nimport { ToolsComponent } from './tools/tools.component';\nimport { UnsecuredWebsitesReportComponent } from './tools/unsecured-websites-report.component';\nimport { WeakPasswordsReportComponent } from './tools/weak-passwords-report.component';\n\nimport { VaultComponent } from './vault/vault.component';\n\nimport { OrganizationGuardService } from './services/organization-guard.service';\nimport { OrganizationTypeGuardService } from './services/organization-type-guard.service';\n\nimport { AuthGuardService } from 'jslib-angular/services/auth-guard.service';\nimport { LockGuardService } from 'jslib-angular/services/lock-guard.service';\nimport { UnauthGuardService } from 'jslib-angular/services/unauth-guard.service';\n\nimport { Permissions } from 'jslib-common/enums/permissions';\n\nimport { EmergencyAccessViewComponent } from './settings/emergency-access-view.component';\nimport { EmergencyAccessComponent } from './settings/emergency-access.component';\nimport { SponsoredFamiliesComponent } from './settings/sponsored-families.component';\n\nconst routes: Routes = [\n {\n path: '',\n component: FrontendLayoutComponent,\n children: [\n { path: '', pathMatch: 'full', component: LoginComponent, canActivate: [UnauthGuardService] },\n { path: '2fa', component: TwoFactorComponent, canActivate: [UnauthGuardService] },\n {\n path: 'register', component: RegisterComponent,\n canActivate: [UnauthGuardService],\n data: { titleId: 'createAccount' },\n },\n {\n path: 'sso', component: SsoComponent,\n canActivate: [UnauthGuardService],\n data: { titleId: 'enterpriseSingleSignOn' },\n },\n {\n path: 'set-password', component: SetPasswordComponent,\n data: { titleId: 'setMasterPassword' },\n },\n {\n path: 'hint', component: HintComponent,\n canActivate: [UnauthGuardService],\n data: { titleId: 'passwordHint' },\n },\n {\n path: 'lock',\n component: LockComponent,\n canActivate: [LockGuardService],\n },\n { path: 'verify-email', component: VerifyEmailTokenComponent },\n {\n path: 'accept-organization',\n component: AcceptOrganizationComponent,\n data: { titleId: 'joinOrganization' },\n },\n {\n path: 'accept-emergency',\n component: AcceptEmergencyComponent,\n data: { titleId: 'acceptEmergency' },\n },\n { path: 'recover', pathMatch: 'full', redirectTo: 'recover-2fa' },\n {\n path: 'recover-2fa',\n component: RecoverTwoFactorComponent,\n canActivate: [UnauthGuardService],\n data: { titleId: 'recoverAccountTwoStep' },\n },\n {\n path: 'recover-delete',\n component: RecoverDeleteComponent,\n canActivate: [UnauthGuardService],\n data: { titleId: 'deleteAccount' },\n },\n {\n path: 'verify-recover-delete',\n component: VerifyRecoverDeleteComponent,\n canActivate: [UnauthGuardService],\n data: { titleId: 'deleteAccount' },\n },\n {\n path: 'send/:sendId/:key',\n component: AccessComponent,\n data: { title: 'Bitwarden Send' },\n },\n {\n path: 'update-temp-password',\n component: UpdateTempPasswordComponent,\n canActivate: [AuthGuardService],\n data: { titleId: 'updateTempPassword' },\n },\n {\n path: 'remove-password',\n component: RemovePasswordComponent,\n canActivate: [AuthGuardService],\n data: { titleId: 'removeMasterPassword' },\n },\n ],\n },\n {\n path: '',\n component: UserLayoutComponent,\n canActivate: [AuthGuardService],\n children: [\n { path: 'vault', component: VaultComponent, data: { titleId: 'myVault' } },\n { path: 'sends', component: SendComponent, data: { title: 'Send' } },\n {\n path: 'settings',\n component: SettingsComponent,\n children: [\n { path: '', pathMatch: 'full', redirectTo: 'account' },\n { path: 'account', component: AccountComponent, data: { titleId: 'myAccount' } },\n { path: 'options', component: OptionsComponent, data: { titleId: 'options' } },\n { path: 'domain-rules', component: DomainRulesComponent, data: { titleId: 'domainRules' } },\n { path: 'two-factor', component: TwoFactorSetupComponent, data: { titleId: 'twoStepLogin' } },\n { path: 'premium', component: PremiumComponent, data: { titleId: 'goPremium' } },\n { path: 'billing', component: UserBillingComponent, data: { titleId: 'billing' } },\n {\n path: 'subscription',\n component: UserSubscriptionComponent,\n data: { titleId: 'premiumMembership' },\n },\n { path: 'organizations', component: OrganizationsComponent, data: { titleId: 'organizations' } },\n {\n path: 'create-organization',\n component: CreateOrganizationComponent,\n data: { titleId: 'newOrganization' },\n },\n {\n path: 'emergency-access',\n children: [\n {\n path: '',\n component: EmergencyAccessComponent,\n data: { titleId: 'emergencyAccess' },\n },\n {\n path: ':id',\n component: EmergencyAccessViewComponent,\n data: { titleId: 'emergencyAccess' },\n },\n ],\n },\n {\n path: 'sponsored-families',\n component: SponsoredFamiliesComponent,\n data: { titleId: 'sponsoredFamilies' },\n },\n ],\n },\n {\n path: 'tools',\n component: ToolsComponent,\n canActivate: [AuthGuardService],\n children: [\n { path: '', pathMatch: 'full', redirectTo: 'generator' },\n { path: 'import', component: ImportComponent, data: { titleId: 'importData' } },\n { path: 'export', component: ExportComponent, data: { titleId: 'exportVault' } },\n {\n path: 'generator',\n component: PasswordGeneratorComponent,\n data: { titleId: 'passwordGenerator' },\n },\n { path: 'breach-report', component: BreachReportComponent, data: { titleId: 'dataBreachReport' } },\n {\n path: 'reused-passwords-report',\n component: ReusedPasswordsReportComponent,\n data: { titleId: 'reusedPasswordsReport' },\n },\n {\n path: 'unsecured-websites-report',\n component: UnsecuredWebsitesReportComponent,\n data: { titleId: 'unsecuredWebsitesReport' },\n },\n {\n path: 'weak-passwords-report',\n component: WeakPasswordsReportComponent,\n data: { titleId: 'weakPasswordsReport' },\n },\n {\n path: 'exposed-passwords-report',\n component: ExposedPasswordsReportComponent,\n data: { titleId: 'exposedPasswordsReport' },\n },\n {\n path: 'inactive-two-factor-report',\n component: InactiveTwoFactorReportComponent,\n data: { titleId: 'inactive2faReport' },\n },\n ],\n },\n { path: 'setup/families-for-enterprise', component: FamiliesForEnterpriseSetupComponent },\n ],\n },\n {\n path: 'organizations/:organizationId',\n component: OrganizationLayoutComponent,\n canActivate: [AuthGuardService, OrganizationGuardService],\n children: [\n { path: '', pathMatch: 'full', redirectTo: 'vault' },\n { path: 'vault', component: OrgVaultComponent, data: { titleId: 'vault' } },\n {\n path: 'tools',\n component: OrgToolsComponent,\n canActivate: [OrganizationTypeGuardService],\n data: { permissions: [Permissions.AccessImportExport, Permissions.AccessReports] },\n children: [\n {\n path: '',\n pathMatch: 'full',\n redirectTo: 'import',\n },\n {\n path: 'import',\n component: OrgImportComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n titleId: 'importData',\n permissions: [Permissions.AccessImportExport],\n },\n },\n {\n path: 'export',\n component: OrgExportComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n titleId: 'exportVault',\n permissions: [Permissions.AccessImportExport],\n },\n },\n {\n path: 'exposed-passwords-report',\n component: OrgExposedPasswordsReportComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n titleId: 'exposedPasswordsReport',\n permissions: [Permissions.AccessReports],\n },\n },\n {\n path: 'inactive-two-factor-report',\n component: OrgInactiveTwoFactorReportComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n titleId: 'inactive2faReport',\n permissions: [Permissions.AccessReports],\n },\n },\n {\n path: 'reused-passwords-report',\n component: OrgReusedPasswordsReportComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n titleId: 'reusedPasswordsReport',\n permissions: [Permissions.AccessReports],\n },\n },\n {\n path: 'unsecured-websites-report',\n component: OrgUnsecuredWebsitesReportComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n titleId: 'unsecuredWebsitesReport',\n permissions: [Permissions.AccessReports],\n },\n },\n {\n path: 'weak-passwords-report',\n component: OrgWeakPasswordsReportComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n titleId: 'weakPasswordsReport',\n permissions: [Permissions.AccessReports],\n },\n },\n ],\n },\n {\n path: 'manage',\n component: OrgManageComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n permissions: [\n Permissions.CreateNewCollections,\n Permissions.EditAnyCollection,\n Permissions.DeleteAnyCollection,\n Permissions.EditAssignedCollections,\n Permissions.DeleteAssignedCollections,\n Permissions.AccessEventLogs,\n Permissions.ManageGroups,\n Permissions.ManageUsers,\n Permissions.ManagePolicies,\n ],\n },\n children: [\n {\n path: '',\n pathMatch: 'full',\n redirectTo: 'people',\n },\n {\n path: 'collections',\n component: OrgManageCollectionsComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n titleId: 'collections',\n permissions: [\n Permissions.CreateNewCollections,\n Permissions.EditAnyCollection,\n Permissions.DeleteAnyCollection,\n Permissions.EditAssignedCollections,\n Permissions.DeleteAssignedCollections,\n ],\n },\n },\n {\n path: 'events',\n component: OrgEventsComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n titleId: 'eventLogs',\n permissions: [Permissions.AccessEventLogs],\n },\n },\n {\n path: 'groups',\n component: OrgGroupsComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n titleId: 'groups',\n permissions: [Permissions.ManageGroups],\n },\n },\n {\n path: 'people',\n component: OrgPeopleComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n titleId: 'people',\n permissions: [Permissions.ManageUsers, Permissions.ManageUsersPassword],\n },\n },\n {\n path: 'policies',\n component: OrgPoliciesComponent,\n canActivate: [OrganizationTypeGuardService],\n data: {\n titleId: 'policies',\n permissions: [Permissions.ManagePolicies],\n },\n },\n ],\n },\n {\n path: 'settings',\n component: OrgSettingsComponent,\n canActivate: [OrganizationTypeGuardService],\n data: { permissions: [Permissions.ManageOrganization] },\n children: [\n { path: '', pathMatch: 'full', redirectTo: 'account' },\n { path: 'account', component: OrgAccountComponent, data: { titleId: 'myOrganization' } },\n { path: 'two-factor', component: OrgTwoFactorSetupComponent, data: { titleId: 'twoStepLogin' } },\n {\n path: 'billing',\n component: OrganizationBillingComponent,\n data: { titleId: 'billing' },\n },\n {\n path: 'subscription',\n component: OrganizationSubscriptionComponent,\n data: { titleId: 'subscription' },\n },\n ],\n },\n ],\n },\n];\n\n@NgModule({\n imports: [RouterModule.forRoot(routes, {\n useHash: true,\n paramsInheritanceStrategy: 'always',\n /*enableTracing: true,*/\n })],\n exports: [RouterModule],\n})\nexport class OssRoutingModule { }\n","import {\n APP_INITIALIZER,\n LOCALE_ID,\n NgModule,\n} from '@angular/core';\n\nimport { ToasterModule } from 'angular2-toaster';\n\nimport { BroadcasterMessagingService } from '../../services/broadcasterMessaging.service';\nimport { HtmlStorageService } from '../../services/htmlStorage.service';\nimport { I18nService } from '../../services/i18n.service';\nimport { MemoryStorageService } from '../../services/memoryStorage.service';\nimport { PasswordRepromptService } from '../../services/passwordReprompt.service';\nimport { WebPlatformUtilsService } from '../../services/webPlatformUtils.service';\n\nimport { EventService } from './event.service';\nimport { OrganizationGuardService } from './organization-guard.service';\nimport { OrganizationTypeGuardService } from './organization-type-guard.service';\nimport { PolicyListService } from './policy-list.service';\nimport { RouterService } from './router.service';\n\nimport { AuthGuardService } from 'jslib-angular/services/auth-guard.service';\nimport { BroadcasterService } from 'jslib-angular/services/broadcaster.service';\nimport { LockGuardService } from 'jslib-angular/services/lock-guard.service';\nimport { ModalService as ModalServiceAbstraction } from 'jslib-angular/services/modal.service';\nimport { UnauthGuardService } from 'jslib-angular/services/unauth-guard.service';\nimport { ValidationService } from 'jslib-angular/services/validation.service';\n\nimport { ApiService } from 'jslib-common/services/api.service';\nimport { AppIdService } from 'jslib-common/services/appId.service';\nimport { AuditService } from 'jslib-common/services/audit.service';\nimport { AuthService } from 'jslib-common/services/auth.service';\nimport { CipherService } from 'jslib-common/services/cipher.service';\nimport { CollectionService } from 'jslib-common/services/collection.service';\nimport { ConsoleLogService } from 'jslib-common/services/consoleLog.service';\nimport { ConstantsService } from 'jslib-common/services/constants.service';\nimport { ContainerService } from 'jslib-common/services/container.service';\nimport { CryptoService } from 'jslib-common/services/crypto.service';\nimport { EnvironmentService } from 'jslib-common/services/environment.service';\nimport { EventService as EventLoggingService } from 'jslib-common/services/event.service';\nimport { ExportService } from 'jslib-common/services/export.service';\nimport { FileUploadService } from 'jslib-common/services/fileUpload.service';\nimport { FolderService } from 'jslib-common/services/folder.service';\nimport { ImportService } from 'jslib-common/services/import.service';\nimport { KeyConnectorService } from 'jslib-common/services/keyConnector.service';\nimport { NotificationsService } from 'jslib-common/services/notifications.service';\nimport { PasswordGenerationService } from 'jslib-common/services/passwordGeneration.service';\nimport { PolicyService } from 'jslib-common/services/policy.service';\nimport { SearchService } from 'jslib-common/services/search.service';\nimport { SendService } from 'jslib-common/services/send.service';\nimport { SettingsService } from 'jslib-common/services/settings.service';\nimport { StateService } from 'jslib-common/services/state.service';\nimport { SyncService } from 'jslib-common/services/sync.service';\nimport { TokenService } from 'jslib-common/services/token.service';\nimport { TotpService } from 'jslib-common/services/totp.service';\nimport { UserService } from 'jslib-common/services/user.service';\nimport { UserVerificationService } from 'jslib-common/services/userVerification.service';\nimport { VaultTimeoutService } from 'jslib-common/services/vaultTimeout.service';\nimport { WebCryptoFunctionService } from 'jslib-common/services/webCryptoFunction.service';\n\nimport { ApiService as ApiServiceAbstraction } from 'jslib-common/abstractions/api.service';\nimport { AuditService as AuditServiceAbstraction } from 'jslib-common/abstractions/audit.service';\nimport { AuthService as AuthServiceAbstraction } from 'jslib-common/abstractions/auth.service';\nimport { CipherService as CipherServiceAbstraction } from 'jslib-common/abstractions/cipher.service';\nimport { CollectionService as CollectionServiceAbstraction } from 'jslib-common/abstractions/collection.service';\nimport { CryptoService as CryptoServiceAbstraction } from 'jslib-common/abstractions/crypto.service';\nimport { CryptoFunctionService as CryptoFunctionServiceAbstraction } from 'jslib-common/abstractions/cryptoFunction.service';\nimport { EnvironmentService as EnvironmentServiceAbstraction, Urls } from 'jslib-common/abstractions/environment.service';\nimport { EventService as EventLoggingServiceAbstraction } from 'jslib-common/abstractions/event.service';\nimport { ExportService as ExportServiceAbstraction } from 'jslib-common/abstractions/export.service';\nimport { FileUploadService as FileUploadServiceAbstraction } from 'jslib-common/abstractions/fileUpload.service';\nimport { FolderService as FolderServiceAbstraction } from 'jslib-common/abstractions/folder.service';\nimport { I18nService as I18nServiceAbstraction } from 'jslib-common/abstractions/i18n.service';\nimport { ImportService as ImportServiceAbstraction } from 'jslib-common/abstractions/import.service';\nimport { KeyConnectorService as KeyConnectorServiceAbstraction } from 'jslib-common/abstractions/keyConnector.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService as MessagingServiceAbstraction } from 'jslib-common/abstractions/messaging.service';\nimport { NotificationsService as NotificationsServiceAbstraction } from 'jslib-common/abstractions/notifications.service';\nimport {\n PasswordGenerationService as PasswordGenerationServiceAbstraction,\n} from 'jslib-common/abstractions/passwordGeneration.service';\nimport { PasswordRepromptService as PasswordRepromptServiceAbstraction } from 'jslib-common/abstractions/passwordReprompt.service';\nimport { PlatformUtilsService as PlatformUtilsServiceAbstraction } from 'jslib-common/abstractions/platformUtils.service';\nimport { PolicyService as PolicyServiceAbstraction } from 'jslib-common/abstractions/policy.service';\nimport { SearchService as SearchServiceAbstraction } from 'jslib-common/abstractions/search.service';\nimport { SendService as SendServiceAbstraction } from 'jslib-common/abstractions/send.service';\nimport { SettingsService as SettingsServiceAbstraction } from 'jslib-common/abstractions/settings.service';\nimport { StateService as StateServiceAbstraction } from 'jslib-common/abstractions/state.service';\nimport { StorageService as StorageServiceAbstraction } from 'jslib-common/abstractions/storage.service';\nimport { SyncService as SyncServiceAbstraction } from 'jslib-common/abstractions/sync.service';\nimport { TokenService as TokenServiceAbstraction } from 'jslib-common/abstractions/token.service';\nimport { TotpService as TotpServiceAbstraction } from 'jslib-common/abstractions/totp.service';\nimport { UserService as UserServiceAbstraction } from 'jslib-common/abstractions/user.service';\nimport { UserVerificationService as UserVerificationServiceAbstraction } from 'jslib-common/abstractions/userVerification.service';\nimport { VaultTimeoutService as VaultTimeoutServiceAbstraction } from 'jslib-common/abstractions/vaultTimeout.service';\nimport { ModalService } from './modal.service';\n\nimport { ThemeType } from 'jslib-common/enums/themeType';\n\nconst i18nService = new I18nService(window.navigator.language, 'locales');\nconst stateService = new StateService();\nconst broadcasterService = new BroadcasterService();\nconst messagingService = new BroadcasterMessagingService(broadcasterService);\nconst consoleLogService = new ConsoleLogService(false);\nconst platformUtilsService = new WebPlatformUtilsService(i18nService, messagingService, consoleLogService, () => storageService);\nconst storageService: StorageServiceAbstraction = new HtmlStorageService(platformUtilsService);\nconst secureStorageService: StorageServiceAbstraction = new MemoryStorageService();\nconst cryptoFunctionService: CryptoFunctionServiceAbstraction = new WebCryptoFunctionService(window,\n platformUtilsService);\nconst cryptoService = new CryptoService(storageService,\n platformUtilsService.isDev() ? storageService : secureStorageService, cryptoFunctionService, platformUtilsService,\n consoleLogService);\nconst tokenService = new TokenService(storageService);\nconst appIdService = new AppIdService(storageService);\nconst environmentService = new EnvironmentService(storageService);\nconst apiService = new ApiService(tokenService, platformUtilsService, environmentService,\n async (expired: boolean) => messagingService.send('logout', { expired: expired }));\nconst userService = new UserService(tokenService, storageService);\nconst settingsService = new SettingsService(userService, storageService);\nexport let searchService: SearchService = null;\nconst fileUploadService = new FileUploadService(consoleLogService, apiService);\nconst cipherService = new CipherService(cryptoService, userService, settingsService,\n apiService, fileUploadService, storageService, i18nService, () => searchService, consoleLogService);\nconst folderService = new FolderService(cryptoService, userService, apiService, storageService,\n i18nService, cipherService);\nconst collectionService = new CollectionService(cryptoService, userService, storageService, i18nService);\nsearchService = new SearchService(cipherService, consoleLogService, i18nService);\nconst policyService = new PolicyService(userService, storageService, apiService);\nconst sendService = new SendService(cryptoService, userService, apiService, fileUploadService, storageService,\n i18nService, cryptoFunctionService);\nconst keyConnectorService = new KeyConnectorService(storageService, userService, cryptoService, apiService,\n tokenService, consoleLogService);\nconst vaultTimeoutService = new VaultTimeoutService(cipherService, folderService, collectionService,\n cryptoService, platformUtilsService, storageService, messagingService, searchService, userService, tokenService,\n policyService, keyConnectorService, null, async () => messagingService.send('logout', { expired: false }));\nconst syncService = new SyncService(userService, apiService, settingsService,\n folderService, cipherService, cryptoService, collectionService, storageService, messagingService, policyService,\n sendService, consoleLogService, tokenService, keyConnectorService,\n async (expired: boolean) => messagingService.send('logout', { expired: expired }));\nconst passwordGenerationService = new PasswordGenerationService(cryptoService, storageService, policyService);\nconst totpService = new TotpService(storageService, cryptoFunctionService, consoleLogService);\nconst containerService = new ContainerService(cryptoService);\nconst authService = new AuthService(cryptoService, apiService,\n userService, tokenService, appIdService, i18nService, platformUtilsService, messagingService, vaultTimeoutService,\n consoleLogService, cryptoFunctionService, environmentService, keyConnectorService);\nconst exportService = new ExportService(folderService, cipherService, apiService, cryptoService);\nconst importService = new ImportService(cipherService, folderService, apiService, i18nService, collectionService,\n platformUtilsService, cryptoService);\nconst notificationsService = new NotificationsService(userService, syncService, appIdService, apiService, vaultTimeoutService,\n environmentService, async () => messagingService.send('logout', { expired: true }), consoleLogService);\nconst auditService = new AuditService(cryptoFunctionService, apiService);\nconst eventLoggingService = new EventLoggingService(storageService, apiService, userService, cipherService, consoleLogService);\nconst userVerificationService = new UserVerificationService(cryptoService, i18nService, apiService);\n\ncontainerService.attachToWindow(window);\n\nexport function initFactory(): Function {\n return async () => {\n await (storageService as HtmlStorageService).init();\n\n const urls = process.env.URLS as Urls;\n urls.base ??= window.location.origin;\n environmentService.setUrls(urls, false);\n\n setTimeout(() => notificationsService.init(), 3000);\n\n vaultTimeoutService.init(true);\n const locale = await storageService.get(ConstantsService.localeKey);\n await i18nService.init(locale);\n eventLoggingService.init(true);\n authService.init();\n const htmlEl = window.document.documentElement;\n htmlEl.classList.add('locale_' + i18nService.translationLocale);\n\n // Initial theme is set in index.html which must be updated if there are any changes to theming logic\n platformUtilsService.onDefaultSystemThemeChange(async sysTheme => {\n const bwTheme = await storageService.get(ConstantsService.themeKey);\n if (bwTheme === ThemeType.System) {\n htmlEl.classList.remove('theme_' + ThemeType.Light, 'theme_' + ThemeType.Dark);\n htmlEl.classList.add('theme_' + sysTheme);\n }\n });\n\n stateService.save(ConstantsService.disableFaviconKey,\n await storageService.get(ConstantsService.disableFaviconKey));\n stateService.save('enableGravatars', await storageService.get('enableGravatars'));\n };\n}\n\n@NgModule({\n imports: [\n ToasterModule,\n ],\n declarations: [],\n providers: [\n ValidationService,\n AuthGuardService,\n OrganizationGuardService,\n OrganizationTypeGuardService,\n UnauthGuardService,\n RouterService,\n EventService,\n LockGuardService,\n PolicyListService,\n { provide: ModalServiceAbstraction, useClass: ModalService },\n { provide: AuditServiceAbstraction, useValue: auditService },\n { provide: AuthServiceAbstraction, useValue: authService },\n { provide: CipherServiceAbstraction, useValue: cipherService },\n { provide: FolderServiceAbstraction, useValue: folderService },\n { provide: LogService, useValue: consoleLogService },\n { provide: CollectionServiceAbstraction, useValue: collectionService },\n { provide: EnvironmentServiceAbstraction, useValue: environmentService },\n { provide: TotpServiceAbstraction, useValue: totpService },\n { provide: TokenServiceAbstraction, useValue: tokenService },\n { provide: I18nServiceAbstraction, useValue: i18nService },\n { provide: CryptoServiceAbstraction, useValue: cryptoService },\n { provide: PlatformUtilsServiceAbstraction, useValue: platformUtilsService },\n { provide: PasswordGenerationServiceAbstraction, useValue: passwordGenerationService },\n { provide: ApiServiceAbstraction, useValue: apiService },\n { provide: FileUploadServiceAbstraction, useValue: fileUploadService },\n { provide: SyncServiceAbstraction, useValue: syncService },\n { provide: UserServiceAbstraction, useValue: userService },\n { provide: MessagingServiceAbstraction, useValue: messagingService },\n { provide: BroadcasterService, useValue: broadcasterService },\n { provide: SettingsServiceAbstraction, useValue: settingsService },\n { provide: VaultTimeoutServiceAbstraction, useValue: vaultTimeoutService },\n { provide: StorageServiceAbstraction, useValue: storageService },\n { provide: StateServiceAbstraction, useValue: stateService },\n { provide: ExportServiceAbstraction, useValue: exportService },\n { provide: SearchServiceAbstraction, useValue: searchService },\n { provide: ImportServiceAbstraction, useValue: importService },\n { provide: NotificationsServiceAbstraction, useValue: notificationsService },\n { provide: CryptoFunctionServiceAbstraction, useValue: cryptoFunctionService },\n { provide: EventLoggingServiceAbstraction, useValue: eventLoggingService },\n { provide: PolicyServiceAbstraction, useValue: policyService },\n { provide: SendServiceAbstraction, useValue: sendService },\n { provide: KeyConnectorServiceAbstraction, useValue: keyConnectorService },\n { provide: UserVerificationServiceAbstraction, useValue: userVerificationService },\n { provide: PasswordRepromptServiceAbstraction, useClass: PasswordRepromptService },\n { provide: LogService, useValue: consoleLogService },\n {\n provide: APP_INITIALIZER,\n useFactory: initFactory,\n deps: [],\n multi: true,\n },\n {\n provide: LOCALE_ID,\n useFactory: () => i18nService.translationLocale,\n deps: [],\n },\n ],\n})\nexport class ServicesModule {\n}\n","import { MessagingService } from 'jslib-common/abstractions/messaging.service';\n\nimport { BroadcasterService } from 'jslib-angular/services/broadcaster.service';\n\nexport class BroadcasterMessagingService implements MessagingService {\n constructor(private broadcasterService: BroadcasterService) { }\n\n send(subscriber: string, arg: any = {}) {\n const message = Object.assign({}, { command: subscriber }, arg);\n this.broadcasterService.send(message);\n }\n}\n","import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\nexport class HtmlStorageService implements StorageService {\n private localStorageKeys = new Set(['appId', 'anonymousAppId', 'rememberedEmail', 'passwordGenerationOptions',\n ConstantsService.disableFaviconKey, 'rememberEmail', 'enableGravatars', 'enableFullWidth',\n ConstantsService.localeKey, ConstantsService.autoConfirmFingerprints,\n ConstantsService.vaultTimeoutKey, ConstantsService.vaultTimeoutActionKey, ConstantsService.ssoCodeVerifierKey,\n ConstantsService.ssoStateKey, 'ssoOrgIdentifier', ConstantsService.themeKey]);\n private localStorageStartsWithKeys = ['twoFactorToken_', ConstantsService.collapsedGroupingsKey + '_'];\n private memoryStorageStartsWithKeys = ['ciphers_', 'folders_', 'collections_', 'settings_', 'lastSync_'];\n private memoryStorage = new Map();\n\n constructor(private platformUtilsService: PlatformUtilsService) { }\n\n async init() {\n // LockOption -> VaultTimeout (uses the same legacy string value for backwards compat)\n const vaultTimeout = await this.get(ConstantsService.vaultTimeoutKey);\n if (vaultTimeout == null && !this.platformUtilsService.isDev()) {\n await this.save(ConstantsService.vaultTimeoutKey, 15);\n }\n\n // Default Action to lock\n const vaultTimeoutAction = await this.get(ConstantsService.vaultTimeoutActionKey);\n if (vaultTimeoutAction == null) {\n await this.save(ConstantsService.vaultTimeoutActionKey, 'lock');\n }\n }\n\n get(key: string): Promise {\n let json: string = null;\n if (this.isLocalStorage(key)) {\n json = window.localStorage.getItem(key);\n } else if (this.isMemoryStorage(key)) {\n json = this.memoryStorage.get(key);\n } else {\n json = window.sessionStorage.getItem(key);\n }\n if (json != null) {\n const obj = JSON.parse(json);\n return Promise.resolve(obj as T);\n }\n return Promise.resolve(null);\n }\n\n async has(key: string): Promise {\n return await this.get(key) != null;\n }\n\n save(key: string, obj: any): Promise {\n if (obj == null) {\n return this.remove(key);\n }\n\n if (obj instanceof Set) {\n obj = Array.from(obj);\n }\n\n const json = JSON.stringify(obj);\n if (this.isLocalStorage(key)) {\n window.localStorage.setItem(key, json);\n } else if (this.isMemoryStorage(key)) {\n this.memoryStorage.set(key, json);\n } else {\n window.sessionStorage.setItem(key, json);\n }\n return Promise.resolve();\n }\n\n remove(key: string): Promise {\n if (this.isLocalStorage(key)) {\n window.localStorage.removeItem(key);\n } else if (this.isMemoryStorage(key)) {\n this.memoryStorage.delete(key);\n } else {\n window.sessionStorage.removeItem(key);\n }\n return Promise.resolve();\n }\n\n private isLocalStorage(key: string): boolean {\n if (this.localStorageKeys.has(key)) {\n return true;\n }\n for (const swKey of this.localStorageStartsWithKeys) {\n if (key.startsWith(swKey)) {\n return true;\n }\n }\n return false;\n }\n\n private isMemoryStorage(key: string): boolean {\n for (const swKey of this.memoryStorageStartsWithKeys) {\n if (key.startsWith(swKey)) {\n return true;\n }\n }\n return false;\n }\n}\n","import { I18nService as BaseI18nService } from 'jslib-common/services/i18n.service';\n\nexport class I18nService extends BaseI18nService {\n constructor(systemLanguage: string, localesDirectory: string) {\n super(systemLanguage || 'en-US', localesDirectory, async (formattedLocale: string) => {\n const filePath = this.localesDirectory + '/' + formattedLocale + '/messages.json?cache=' +\n process.env.CACHE_TAG;\n const localesResult = await fetch(filePath);\n const locales = await localesResult.json();\n return locales;\n });\n\n // Please leave 'en' where it is, as it's our fallback language in case no translation can be found\n this.supportedTranslationLocales = [\n 'en', 'az', 'bg', 'ca', 'cs', 'da', 'de', 'el', 'eo', 'en-GB', 'en-IN', 'es', 'et', 'fi', 'fr', 'he', 'hr', 'hu', 'id', 'it', 'ja', 'kn', 'ko', 'lv', 'ml', 'nb',\n 'nl', 'pl', 'pt-PT', 'pt-BR', 'ro', 'ru', 'sk', 'sr', 'sv', 'tr', 'uk', 'zh-CN', 'zh-TW',\n ];\n }\n}\n","import { I18nService as I18nServiceAbstraction } from '../abstractions/i18n.service';\n\nexport class I18nService implements I18nServiceAbstraction {\n locale: string;\n // First locale is the default (English)\n supportedTranslationLocales: string[] = ['en'];\n translationLocale: string;\n collator: Intl.Collator;\n localeNames = new Map([\n ['af', 'Afrikaans'],\n ['az', 'Azərbaycanca'],\n ['be', 'Беларуская'],\n ['bg', 'български'],\n ['ca', 'català'],\n ['cs', 'čeština'],\n ['da', 'dansk'],\n ['de', 'Deutsch'],\n ['el', 'Ελληνικά'],\n ['en', 'English'],\n ['en-GB', 'English (British)'],\n ['eo', 'Esperanto'],\n ['es', 'español'],\n ['et', 'eesti'],\n ['fa', 'فارسی'],\n ['fi', 'suomi'],\n ['fr', 'français'],\n ['he', 'עברית'],\n ['hi', 'हिन्दी'],\n ['hr', 'hrvatski'],\n ['hu', 'magyar'],\n ['id', 'Bahasa Indonesia'],\n ['it', 'italiano'],\n ['ja', '日本語'],\n ['ko', '한국어'],\n ['lv', 'Latvietis'],\n ['ml', 'മലയാളം'],\n ['nb', 'norsk (bokmål)'],\n ['nl', 'Nederlands'],\n ['pl', 'polski'],\n ['pt-BR', 'português do Brasil'],\n ['pt-PT', 'português'],\n ['ro', 'română'],\n ['ru', 'русский'],\n ['sk', 'slovenčina'],\n ['sr', 'Српски'],\n ['sv', 'svenska'],\n ['th', 'ไทย'],\n ['tr', 'Türkçe'],\n ['uk', 'українська'],\n ['vi', 'Tiếng Việt'],\n ['zh-CN', '中文(中国大陆)'],\n ['zh-TW', '中文(台灣)'],\n ]);\n\n protected inited: boolean;\n protected defaultMessages: any = {};\n protected localeMessages: any = {};\n\n constructor(protected systemLanguage: string, protected localesDirectory: string,\n protected getLocalesJson: (formattedLocale: string) => Promise) {\n this.systemLanguage = systemLanguage.replace('_', '-');\n }\n\n async init(locale?: string) {\n if (this.inited) {\n throw new Error('i18n already initialized.');\n }\n if (this.supportedTranslationLocales == null || this.supportedTranslationLocales.length === 0) {\n throw new Error('supportedTranslationLocales not set.');\n }\n\n this.inited = true;\n this.locale = this.translationLocale = locale != null ? locale : this.systemLanguage;\n\n try {\n this.collator = new Intl.Collator(this.locale, { numeric: true, sensitivity: 'base' });\n } catch {\n this.collator = null;\n }\n\n if (this.supportedTranslationLocales.indexOf(this.translationLocale) === -1) {\n this.translationLocale = this.translationLocale.slice(0, 2);\n\n if (this.supportedTranslationLocales.indexOf(this.translationLocale) === -1) {\n this.translationLocale = this.supportedTranslationLocales[0];\n }\n }\n\n if (this.localesDirectory != null) {\n await this.loadMessages(this.translationLocale, this.localeMessages);\n if (this.translationLocale !== this.supportedTranslationLocales[0]) {\n await this.loadMessages(this.supportedTranslationLocales[0], this.defaultMessages);\n }\n }\n }\n\n t(id: string, p1?: string, p2?: string, p3?: string): string {\n return this.translate(id, p1, p2, p3);\n }\n\n translate(id: string, p1?: string, p2?: string, p3?: string): string {\n let result: string;\n if (this.localeMessages.hasOwnProperty(id) && this.localeMessages[id]) {\n result = this.localeMessages[id];\n } else if (this.defaultMessages.hasOwnProperty(id) && this.defaultMessages[id]) {\n result = this.defaultMessages[id];\n } else {\n result = '';\n }\n\n if (result !== '') {\n if (p1 != null) {\n result = result.split('__$1__').join(p1);\n }\n if (p2 != null) {\n result = result.split('__$2__').join(p2);\n }\n if (p3 != null) {\n result = result.split('__$3__').join(p3);\n }\n }\n\n return result;\n }\n\n private async loadMessages(locale: string, messagesObj: any): Promise {\n const formattedLocale = locale.replace('-', '_');\n const locales = await this.getLocalesJson(formattedLocale);\n for (const prop in locales) {\n if (!locales.hasOwnProperty(prop)) {\n continue;\n }\n messagesObj[prop] = locales[prop].message;\n\n if (locales[prop].placeholders) {\n for (const placeProp in locales[prop].placeholders) {\n if (!locales[prop].placeholders.hasOwnProperty(placeProp) ||\n !locales[prop].placeholders[placeProp].content) {\n continue;\n }\n\n const replaceToken = '\\\\$' + placeProp.toUpperCase() + '\\\\$';\n let replaceContent = locales[prop].placeholders[placeProp].content;\n if (replaceContent === '$1' || replaceContent === '$2' || replaceContent === '$3') {\n replaceContent = '__$' + replaceContent + '__';\n }\n messagesObj[prop] = messagesObj[prop].replace(new RegExp(replaceToken, 'g'), replaceContent);\n }\n }\n }\n }\n\n}\n","import { StorageService } from 'jslib-common/abstractions/storage.service';\n\nexport class MemoryStorageService implements StorageService {\n private store = new Map();\n\n get(key: string): Promise {\n if (this.store.has(key)) {\n const obj = this.store.get(key);\n return Promise.resolve(obj as T);\n }\n return Promise.resolve(null);\n }\n\n async has(key: string): Promise {\n return this.get(key) != null;\n }\n\n save(key: string, obj: any): Promise {\n if (obj == null) {\n return this.remove(key);\n }\n this.store.set(key, obj);\n return Promise.resolve();\n }\n\n remove(key: string): Promise {\n this.store.delete(key);\n return Promise.resolve();\n }\n}\n","import { Injectable } from '@angular/core';\n\nimport { PasswordRepromptService as BasePasswordRepromptService } from 'jslib-angular/services/passwordReprompt.service';\nimport { PasswordRepromptComponent } from '../app/components/password-reprompt.component';\n\n@Injectable()\nexport class PasswordRepromptService extends BasePasswordRepromptService {\n component = PasswordRepromptComponent;\n}\n","import { Injectable } from '@angular/core';\n\nimport { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';\nimport { PasswordRepromptService as PasswordRepromptServiceAbstraction } from 'jslib-common/abstractions/passwordReprompt.service';\n\nimport { PasswordRepromptComponent } from '../components/password-reprompt.component';\nimport { ModalService } from './modal.service';\n\n@Injectable()\nexport class PasswordRepromptService implements PasswordRepromptServiceAbstraction {\n protected component = PasswordRepromptComponent;\n\n constructor(private modalService: ModalService, private keyConnectorService: KeyConnectorService) { }\n\n protectedFields() {\n return ['TOTP', 'Password', 'H_Field', 'Card Number', 'Security Code'];\n }\n\n async showPasswordPrompt() {\n if (!await this.enabled()) {\n return true;\n }\n\n const ref = this.modalService.open(this.component, {allowMultipleModals: true});\n\n if (ref == null) {\n return false;\n }\n\n const result = await ref.onClosedPromise();\n return result === true;\n }\n\n async enabled() {\n return !await this.keyConnectorService.getUsesKeyConnector();\n }\n}\n","import Swal, { SweetAlertIcon } from 'sweetalert2';\n\nimport { DeviceType } from 'jslib-common/enums/deviceType';\nimport { ThemeType } from 'jslib-common/enums/themeType';\n\nimport { I18nService } from 'jslib-common/abstractions/i18n.service';\nimport { LogService } from 'jslib-common/abstractions/log.service';\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\nimport { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';\nimport { StorageService } from 'jslib-common/abstractions/storage.service';\n\nimport { ConstantsService } from 'jslib-common/services/constants.service';\n\nexport class WebPlatformUtilsService implements PlatformUtilsService {\n identityClientId: string = 'web';\n\n private browserCache: DeviceType = null;\n private prefersColorSchemeDark = window.matchMedia('(prefers-color-scheme: dark)');\n\n constructor(private i18nService: I18nService, private messagingService: MessagingService,\n private logService: LogService, private storageService: () => StorageService) { }\n\n getDevice(): DeviceType {\n if (this.browserCache != null) {\n return this.browserCache;\n }\n\n if (navigator.userAgent.indexOf(' Firefox/') !== -1 || navigator.userAgent.indexOf(' Gecko/') !== -1) {\n this.browserCache = DeviceType.FirefoxBrowser;\n } else if (navigator.userAgent.indexOf(' OPR/') >= 0) {\n this.browserCache = DeviceType.OperaBrowser;\n } else if (navigator.userAgent.indexOf(' Edg/') !== -1) {\n this.browserCache = DeviceType.EdgeBrowser;\n } else if (navigator.userAgent.indexOf(' Vivaldi/') !== -1) {\n this.browserCache = DeviceType.VivaldiBrowser;\n } else if (navigator.userAgent.indexOf(' Safari/') !== -1 && navigator.userAgent.indexOf('Chrome') === -1) {\n this.browserCache = DeviceType.SafariBrowser;\n } else if ((window as any).chrome && navigator.userAgent.indexOf(' Chrome/') !== -1) {\n this.browserCache = DeviceType.ChromeBrowser;\n } else if (navigator.userAgent.indexOf(' Trident/') !== -1) {\n this.browserCache = DeviceType.IEBrowser;\n } else {\n this.browserCache = DeviceType.UnknownBrowser;\n }\n\n return this.browserCache;\n }\n\n getDeviceString(): string {\n const device = DeviceType[this.getDevice()].toLowerCase();\n return device.replace('browser', '');\n }\n\n isFirefox(): boolean {\n return this.getDevice() === DeviceType.FirefoxBrowser;\n }\n\n isChrome(): boolean {\n return this.getDevice() === DeviceType.ChromeBrowser;\n }\n\n isEdge(): boolean {\n return this.getDevice() === DeviceType.EdgeBrowser;\n }\n\n isOpera(): boolean {\n return this.getDevice() === DeviceType.OperaBrowser;\n }\n\n isVivaldi(): boolean {\n return this.getDevice() === DeviceType.VivaldiBrowser;\n }\n\n isSafari(): boolean {\n return this.getDevice() === DeviceType.SafariBrowser;\n }\n\n isIE(): boolean {\n return this.getDevice() === DeviceType.IEBrowser;\n }\n\n isMacAppStore(): boolean {\n return false;\n }\n\n isViewOpen(): Promise {\n return Promise.resolve(false);\n }\n\n launchUri(uri: string, options?: any): void {\n const a = document.createElement('a');\n a.href = uri;\n if (options == null || !options.sameWindow) {\n a.target = '_blank';\n a.rel = 'noreferrer noopener';\n }\n a.classList.add('d-none');\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n }\n\n saveFile(win: Window, blobData: any, blobOptions: any, fileName: string): void {\n let blob: Blob = null;\n let type: string = null;\n const fileNameLower = fileName.toLowerCase();\n let doDownload = true;\n if (fileNameLower.endsWith('.pdf')) {\n type = 'application/pdf';\n doDownload = false;\n } else if (fileNameLower.endsWith('.xlsx')) {\n type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';\n } else if (fileNameLower.endsWith('.docx')) {\n type = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';\n } else if (fileNameLower.endsWith('.pptx')) {\n type = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';\n } else if (fileNameLower.endsWith('.csv')) {\n type = 'text/csv';\n } else if (fileNameLower.endsWith('.png')) {\n type = 'image/png';\n } else if (fileNameLower.endsWith('.jpg') || fileNameLower.endsWith('.jpeg')) {\n type = 'image/jpeg';\n } else if (fileNameLower.endsWith('.gif')) {\n type = 'image/gif';\n }\n if (type != null) {\n blobOptions = blobOptions || {};\n if (blobOptions.type == null) {\n blobOptions.type = type;\n }\n }\n if (blobOptions != null && !this.isIE()) {\n blob = new Blob([blobData], blobOptions);\n } else {\n blob = new Blob([blobData]);\n }\n if (navigator.msSaveOrOpenBlob) {\n navigator.msSaveBlob(blob, fileName);\n } else {\n const a = win.document.createElement('a');\n if (doDownload) {\n a.download = fileName;\n } else if (!this.isSafari()) {\n a.target = '_blank';\n }\n a.href = URL.createObjectURL(blob);\n a.style.position = 'fixed';\n win.document.body.appendChild(a);\n a.click();\n win.document.body.removeChild(a);\n }\n }\n\n getApplicationVersion(): Promise {\n return Promise.resolve(process.env.APPLICATION_VERSION || '-');\n }\n\n supportsWebAuthn(win: Window): boolean {\n return (typeof (PublicKeyCredential) !== 'undefined');\n }\n\n supportsDuo(): boolean {\n return true;\n }\n\n showToast(type: 'error' | 'success' | 'warning' | 'info', title: string, text: string | string[],\n options?: any): void {\n this.messagingService.send('showToast', {\n text: text,\n title: title,\n type: type,\n options: options,\n });\n }\n\n async showDialog(body: string, title?: string, confirmText?: string, cancelText?: string, type?: string,\n bodyIsHtml: boolean = false) {\n let iconClasses: string = null;\n if (type != null) {\n // If you add custom types to this part, the type to SweetAlertIcon cast below needs to be changed.\n switch (type) {\n case 'success':\n iconClasses = 'fa-check text-success';\n break;\n case 'warning':\n iconClasses = 'fa-warning text-warning';\n break;\n case 'error':\n iconClasses = 'fa-bolt text-danger';\n break;\n case 'info':\n iconClasses = 'fa-info-circle text-info';\n break;\n default:\n break;\n }\n }\n\n const bootstrapModal = document.querySelector('div.modal');\n if (bootstrapModal != null) {\n bootstrapModal.removeAttribute('tabindex');\n }\n\n const iconHtmlStr = iconClasses != null ? `` : undefined;\n const confirmed = await Swal.fire({\n heightAuto: false,\n buttonsStyling: false,\n icon: type as SweetAlertIcon, // required to be any of the SweetAlertIcons to output the iconHtml.\n iconHtml: iconHtmlStr,\n text: bodyIsHtml ? null : body,\n html: bodyIsHtml ? body : null,\n titleText: title,\n showCancelButton: (cancelText != null),\n cancelButtonText: cancelText,\n showConfirmButton: true,\n confirmButtonText: confirmText == null ? this.i18nService.t('ok') : confirmText,\n });\n\n if (bootstrapModal != null) {\n bootstrapModal.setAttribute('tabindex', '-1');\n }\n\n return confirmed.value;\n }\n\n isDev(): boolean {\n return process.env.NODE_ENV === 'development';\n }\n\n isSelfHost(): boolean {\n return process.env.ENV.toString() === 'selfhosted';\n }\n\n copyToClipboard(text: string, options?: any): void | boolean {\n let win = window;\n let doc = window.document;\n if (options && (options.window || options.win)) {\n win = options.window || options.win;\n doc = win.document;\n } else if (options && options.doc) {\n doc = options.doc;\n }\n if ((win as any).clipboardData && (win as any).clipboardData.setData) {\n // IE specific code path to prevent textarea being shown while dialog is visible.\n (win as any).clipboardData.setData('Text', text);\n } else if (doc.queryCommandSupported && doc.queryCommandSupported('copy')) {\n const textarea = doc.createElement('textarea');\n textarea.textContent = text;\n // Prevent scrolling to bottom of page in MS Edge.\n textarea.style.position = 'fixed';\n let copyEl = doc.body;\n // For some reason copy command won't work when modal is open if appending to body\n if (doc.body.classList.contains('modal-open')) {\n copyEl = doc.body.querySelector('.modal');\n }\n copyEl.appendChild(textarea);\n textarea.select();\n let success = false;\n try {\n // Security exception may be thrown by some browsers.\n success = doc.execCommand('copy');\n if (!success) {\n this.logService.debug('Copy command unsupported or disabled.');\n }\n } catch (e) {\n // tslint:disable-next-line\n console.warn('Copy to clipboard failed.', e);\n } finally {\n copyEl.removeChild(textarea);\n }\n return success;\n }\n }\n\n readFromClipboard(options?: any): Promise {\n throw new Error('Cannot read from clipboard on web.');\n }\n\n supportsBiometric() {\n return Promise.resolve(false);\n }\n\n authenticateBiometric() {\n return Promise.resolve(false);\n }\n\n supportsSecureStorage() {\n return false;\n }\n\n getDefaultSystemTheme(): Promise {\n return Promise.resolve(this.prefersColorSchemeDark.matches ? ThemeType.Dark : ThemeType.Light);\n }\n\n async getEffectiveTheme(): Promise {\n const theme = await this.storageService().get(ConstantsService.themeKey);\n if (theme === ThemeType.Dark) {\n return ThemeType.Dark;\n } else if (theme === ThemeType.System) {\n return this.getDefaultSystemTheme();\n } else {\n return ThemeType.Light;\n }\n }\n\n onDefaultSystemThemeChange(callback: ((theme: ThemeType.Light | ThemeType.Dark) => unknown)) {\n try {\n this.prefersColorSchemeDark.addEventListener('change', ({ matches }) => {\n callback(matches ? ThemeType.Dark : ThemeType.Light);\n });\n } catch (e) {\n // Safari older than v14\n this.prefersColorSchemeDark.addListener(ev => {\n callback(ev.matches ? ThemeType.Dark : ThemeType.Light);\n });\n }\n }\n}\n","import { DeviceType } from '../enums/deviceType';\nimport { PolicyType } from '../enums/policyType';\n\nimport { ApiService as ApiServiceAbstraction } from '../abstractions/api.service';\nimport { EnvironmentService } from '../abstractions/environment.service';\nimport { PlatformUtilsService } from '../abstractions/platformUtils.service';\nimport { TokenService } from '../abstractions/token.service';\n\nimport { AttachmentRequest } from '../models/request/attachmentRequest';\nimport { BitPayInvoiceRequest } from '../models/request/bitPayInvoiceRequest';\nimport { CipherBulkDeleteRequest } from '../models/request/cipherBulkDeleteRequest';\nimport { CipherBulkMoveRequest } from '../models/request/cipherBulkMoveRequest';\nimport { CipherBulkShareRequest } from '../models/request/cipherBulkShareRequest';\nimport { CipherCollectionsRequest } from '../models/request/cipherCollectionsRequest';\nimport { CipherCreateRequest } from '../models/request/cipherCreateRequest';\nimport { CipherRequest } from '../models/request/cipherRequest';\nimport { CipherShareRequest } from '../models/request/cipherShareRequest';\nimport { CollectionRequest } from '../models/request/collectionRequest';\nimport { DeleteRecoverRequest } from '../models/request/deleteRecoverRequest';\nimport { EmailRequest } from '../models/request/emailRequest';\nimport { EmailTokenRequest } from '../models/request/emailTokenRequest';\nimport { EmergencyAccessAcceptRequest } from '../models/request/emergencyAccessAcceptRequest';\nimport { EmergencyAccessConfirmRequest } from '../models/request/emergencyAccessConfirmRequest';\nimport { EmergencyAccessInviteRequest } from '../models/request/emergencyAccessInviteRequest';\nimport { EmergencyAccessPasswordRequest } from '../models/request/emergencyAccessPasswordRequest';\nimport { EmergencyAccessUpdateRequest } from '../models/request/emergencyAccessUpdateRequest';\nimport { EventRequest } from '../models/request/eventRequest';\nimport { FolderRequest } from '../models/request/folderRequest';\nimport { GroupRequest } from '../models/request/groupRequest';\nimport { IapCheckRequest } from '../models/request/iapCheckRequest';\nimport { ImportCiphersRequest } from '../models/request/importCiphersRequest';\nimport { ImportDirectoryRequest } from '../models/request/importDirectoryRequest';\nimport { ImportOrganizationCiphersRequest } from '../models/request/importOrganizationCiphersRequest';\nimport { KdfRequest } from '../models/request/kdfRequest';\nimport { KeysRequest } from '../models/request/keysRequest';\nimport { OrganizationSponsorshipCreateRequest } from '../models/request/organization/organizationSponsorshipCreateRequest';\nimport { OrganizationSponsorshipRedeemRequest } from '../models/request/organization/organizationSponsorshipRedeemRequest';\nimport { OrganizationSsoRequest } from '../models/request/organization/organizationSsoRequest';\nimport { OrganizationCreateRequest } from '../models/request/organizationCreateRequest';\nimport { OrganizationImportRequest } from '../models/request/organizationImportRequest';\nimport { OrganizationKeysRequest } from '../models/request/organizationKeysRequest';\nimport { OrganizationSubscriptionUpdateRequest } from '../models/request/organizationSubscriptionUpdateRequest';\nimport { OrganizationTaxInfoUpdateRequest } from '../models/request/organizationTaxInfoUpdateRequest';\nimport { OrganizationUpdateRequest } from '../models/request/organizationUpdateRequest';\nimport { OrganizationUpgradeRequest } from '../models/request/organizationUpgradeRequest';\nimport { OrganizationUserAcceptRequest } from '../models/request/organizationUserAcceptRequest';\nimport { OrganizationUserBulkConfirmRequest } from '../models/request/organizationUserBulkConfirmRequest';\nimport { OrganizationUserBulkRequest } from '../models/request/organizationUserBulkRequest';\nimport { OrganizationUserConfirmRequest } from '../models/request/organizationUserConfirmRequest';\nimport { OrganizationUserInviteRequest } from '../models/request/organizationUserInviteRequest';\nimport { OrganizationUserResetPasswordEnrollmentRequest } from '../models/request/organizationUserResetPasswordEnrollmentRequest';\nimport { OrganizationUserResetPasswordRequest } from '../models/request/organizationUserResetPasswordRequest';\nimport { OrganizationUserUpdateGroupsRequest } from '../models/request/organizationUserUpdateGroupsRequest';\nimport { OrganizationUserUpdateRequest } from '../models/request/organizationUserUpdateRequest';\nimport { PasswordHintRequest } from '../models/request/passwordHintRequest';\nimport { PasswordRequest } from '../models/request/passwordRequest';\nimport { PaymentRequest } from '../models/request/paymentRequest';\nimport { PolicyRequest } from '../models/request/policyRequest';\nimport { PreloginRequest } from '../models/request/preloginRequest';\nimport { ProviderAddOrganizationRequest } from '../models/request/provider/providerAddOrganizationRequest';\nimport { ProviderOrganizationCreateRequest } from '../models/request/provider/providerOrganizationCreateRequest';\nimport { ProviderSetupRequest } from '../models/request/provider/providerSetupRequest';\nimport { ProviderUpdateRequest } from '../models/request/provider/providerUpdateRequest';\nimport { ProviderUserAcceptRequest } from '../models/request/provider/providerUserAcceptRequest';\nimport { ProviderUserBulkConfirmRequest } from '../models/request/provider/providerUserBulkConfirmRequest';\nimport { ProviderUserBulkRequest } from '../models/request/provider/providerUserBulkRequest';\nimport { ProviderUserConfirmRequest } from '../models/request/provider/providerUserConfirmRequest';\nimport { ProviderUserInviteRequest } from '../models/request/provider/providerUserInviteRequest';\nimport { ProviderUserUpdateRequest } from '../models/request/provider/providerUserUpdateRequest';\nimport { RegisterRequest } from '../models/request/registerRequest';\nimport { SeatRequest } from '../models/request/seatRequest';\nimport { SecretVerificationRequest } from '../models/request/secretVerificationRequest';\nimport { SelectionReadOnlyRequest } from '../models/request/selectionReadOnlyRequest';\nimport { SendAccessRequest } from '../models/request/sendAccessRequest';\nimport { SendRequest } from '../models/request/sendRequest';\nimport { SetPasswordRequest } from '../models/request/setPasswordRequest';\nimport { StorageRequest } from '../models/request/storageRequest';\nimport { TaxInfoUpdateRequest } from '../models/request/taxInfoUpdateRequest';\nimport { TokenRequest } from '../models/request/tokenRequest';\nimport { TwoFactorEmailRequest } from '../models/request/twoFactorEmailRequest';\nimport { TwoFactorProviderRequest } from '../models/request/twoFactorProviderRequest';\nimport { TwoFactorRecoveryRequest } from '../models/request/twoFactorRecoveryRequest';\nimport { UpdateDomainsRequest } from '../models/request/updateDomainsRequest';\nimport { UpdateKeyRequest } from '../models/request/updateKeyRequest';\nimport { UpdateProfileRequest } from '../models/request/updateProfileRequest';\nimport { UpdateTempPasswordRequest } from '../models/request/updateTempPasswordRequest';\nimport { UpdateTwoFactorAuthenticatorRequest } from '../models/request/updateTwoFactorAuthenticatorRequest';\nimport { UpdateTwoFactorDuoRequest } from '../models/request/updateTwoFactorDuoRequest';\nimport { UpdateTwoFactorEmailRequest } from '../models/request/updateTwoFactorEmailRequest';\nimport { UpdateTwoFactorWebAuthnDeleteRequest } from '../models/request/updateTwoFactorWebAuthnDeleteRequest';\nimport { UpdateTwoFactorWebAuthnRequest } from '../models/request/updateTwoFactorWebAuthnRequest';\nimport { UpdateTwoFactorYubioOtpRequest } from '../models/request/updateTwoFactorYubioOtpRequest';\nimport { VerifyBankRequest } from '../models/request/verifyBankRequest';\nimport { VerifyDeleteRecoverRequest } from '../models/request/verifyDeleteRecoverRequest';\nimport { VerifyEmailRequest } from '../models/request/verifyEmailRequest';\n\nimport { Utils } from '../misc/utils';\n\nimport { ApiKeyResponse } from '../models/response/apiKeyResponse';\nimport { AttachmentResponse } from '../models/response/attachmentResponse';\nimport { AttachmentUploadDataResponse } from '../models/response/attachmentUploadDataResponse';\nimport { BillingResponse } from '../models/response/billingResponse';\nimport { BreachAccountResponse } from '../models/response/breachAccountResponse';\nimport { CipherResponse } from '../models/response/cipherResponse';\nimport {\n CollectionGroupDetailsResponse,\n CollectionResponse,\n} from '../models/response/collectionResponse';\nimport { DomainsResponse } from '../models/response/domainsResponse';\nimport {\n EmergencyAccessGranteeDetailsResponse,\n EmergencyAccessGrantorDetailsResponse,\n EmergencyAccessTakeoverResponse,\n EmergencyAccessViewResponse\n} from '../models/response/emergencyAccessResponse';\nimport { ErrorResponse } from '../models/response/errorResponse';\nimport { EventResponse } from '../models/response/eventResponse';\nimport { FolderResponse } from '../models/response/folderResponse';\nimport {\n GroupDetailsResponse,\n GroupResponse,\n} from '../models/response/groupResponse';\nimport { IdentityCaptchaResponse } from '../models/response/identityCaptchaResponse';\nimport { IdentityTokenResponse } from '../models/response/identityTokenResponse';\nimport { IdentityTwoFactorResponse } from '../models/response/identityTwoFactorResponse';\nimport { ListResponse } from '../models/response/listResponse';\nimport { OrganizationSsoResponse } from '../models/response/organization/organizationSsoResponse';\nimport { OrganizationAutoEnrollStatusResponse } from '../models/response/organizationAutoEnrollStatusResponse';\nimport { OrganizationKeysResponse } from '../models/response/organizationKeysResponse';\nimport { OrganizationResponse } from '../models/response/organizationResponse';\nimport { OrganizationSubscriptionResponse } from '../models/response/organizationSubscriptionResponse';\nimport { OrganizationUserBulkPublicKeyResponse } from '../models/response/organizationUserBulkPublicKeyResponse';\nimport { OrganizationUserBulkResponse } from '../models/response/organizationUserBulkResponse';\nimport {\n OrganizationUserDetailsResponse,\n OrganizationUserResetPasswordDetailsReponse,\n OrganizationUserUserDetailsResponse,\n} from '../models/response/organizationUserResponse';\nimport { PaymentResponse } from '../models/response/paymentResponse';\nimport { PlanResponse } from '../models/response/planResponse';\nimport { PolicyResponse } from '../models/response/policyResponse';\nimport { PreloginResponse } from '../models/response/preloginResponse';\nimport { ProfileResponse } from '../models/response/profileResponse';\nimport { ProviderOrganizationOrganizationDetailsResponse, ProviderOrganizationResponse } from '../models/response/provider/providerOrganizationResponse';\nimport { ProviderResponse } from '../models/response/provider/providerResponse';\nimport { ProviderUserBulkPublicKeyResponse } from '../models/response/provider/providerUserBulkPublicKeyResponse';\nimport { ProviderUserBulkResponse } from '../models/response/provider/providerUserBulkResponse';\nimport {\n ProviderUserResponse,\n ProviderUserUserDetailsResponse\n} from '../models/response/provider/providerUserResponse';\nimport { SelectionReadOnlyResponse } from '../models/response/selectionReadOnlyResponse';\nimport { SendAccessResponse } from '../models/response/sendAccessResponse';\nimport { SendFileDownloadDataResponse } from '../models/response/sendFileDownloadDataResponse';\nimport { SendFileUploadDataResponse } from '../models/response/sendFileUploadDataResponse';\nimport { SendResponse } from '../models/response/sendResponse';\nimport { SubscriptionResponse } from '../models/response/subscriptionResponse';\nimport { SyncResponse } from '../models/response/syncResponse';\nimport { TaxInfoResponse } from '../models/response/taxInfoResponse';\nimport { TaxRateResponse } from '../models/response/taxRateResponse';\nimport { TwoFactorAuthenticatorResponse } from '../models/response/twoFactorAuthenticatorResponse';\nimport { TwoFactorDuoResponse } from '../models/response/twoFactorDuoResponse';\nimport { TwoFactorEmailResponse } from '../models/response/twoFactorEmailResponse';\nimport { TwoFactorProviderResponse } from '../models/response/twoFactorProviderResponse';\nimport { TwoFactorRecoverResponse } from '../models/response/twoFactorRescoverResponse';\nimport { TwoFactorWebAuthnResponse } from '../models/response/twoFactorWebAuthnResponse';\nimport { ChallengeResponse } from '../models/response/twoFactorWebAuthnResponse';\nimport { TwoFactorYubiKeyResponse } from '../models/response/twoFactorYubiKeyResponse';\nimport { UserKeyResponse } from '../models/response/userKeyResponse';\n\nimport { SetKeyConnectorKeyRequest } from '../models/request/account/setKeyConnectorKeyRequest';\nimport { VerifyOTPRequest } from '../models/request/account/verifyOTPRequest';\nimport { KeyConnectorUserKeyRequest } from '../models/request/keyConnectorUserKeyRequest';\nimport { KeyConnectorUserKeyResponse } from '../models/response/keyConnectorUserKeyResponse';\nimport { SendAccessView } from '../models/view/sendAccessView';\n\n\n\nexport class ApiService implements ApiServiceAbstraction {\n protected apiKeyRefresh: (clientId: string, clientSecret: string) => Promise;\n private device: DeviceType;\n private deviceType: string;\n private isWebClient = false;\n private isDesktopClient = false;\n\n constructor(private tokenService: TokenService, private platformUtilsService: PlatformUtilsService,\n private environmentService: EnvironmentService, private logoutCallback: (expired: boolean) => Promise,\n private customUserAgent: string = null) {\n this.device = platformUtilsService.getDevice();\n this.deviceType = this.device.toString();\n this.isWebClient = this.device === DeviceType.IEBrowser || this.device === DeviceType.ChromeBrowser ||\n this.device === DeviceType.EdgeBrowser || this.device === DeviceType.FirefoxBrowser ||\n this.device === DeviceType.OperaBrowser || this.device === DeviceType.SafariBrowser ||\n this.device === DeviceType.UnknownBrowser || this.device === DeviceType.VivaldiBrowser;\n this.isDesktopClient = this.device === DeviceType.WindowsDesktop || this.device === DeviceType.MacOsDesktop ||\n this.device === DeviceType.LinuxDesktop;\n }\n\n // Auth APIs\n\n async postIdentityToken(request: TokenRequest): Promise {\n const headers = new Headers({\n 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',\n 'Accept': 'application/json',\n 'Device-Type': this.deviceType,\n });\n if (this.customUserAgent != null) {\n headers.set('User-Agent', this.customUserAgent);\n }\n request.alterIdentityTokenHeaders(headers);\n const response = await this.fetch(new Request(this.environmentService.getIdentityUrl() + '/connect/token', {\n body: this.qsStringify(request.toIdentityToken(request.clientId ?? this.platformUtilsService.identityClientId)),\n credentials: this.getCredentials(),\n cache: 'no-store',\n headers: headers,\n method: 'POST',\n }));\n\n let responseJson: any = null;\n if (this.isJsonResponse(response)) {\n responseJson = await response.json();\n }\n\n if (responseJson != null) {\n if (response.status === 200) {\n return new IdentityTokenResponse(responseJson);\n } else if (response.status === 400 && responseJson.TwoFactorProviders2 &&\n Object.keys(responseJson.TwoFactorProviders2).length) {\n await this.tokenService.clearTwoFactorToken(request.email);\n return new IdentityTwoFactorResponse(responseJson);\n } else if (response.status === 400 && responseJson.HCaptcha_SiteKey &&\n Object.keys(responseJson.HCaptcha_SiteKey).length) {\n return new IdentityCaptchaResponse(responseJson);\n }\n }\n\n return Promise.reject(new ErrorResponse(responseJson, response.status, true));\n }\n\n async refreshIdentityToken(): Promise {\n try {\n await this.doAuthRefresh();\n } catch (e) {\n return Promise.reject(null);\n }\n }\n\n // Account APIs\n\n async getProfile(): Promise {\n const r = await this.send('GET', '/accounts/profile', null, true, true);\n return new ProfileResponse(r);\n }\n\n async getUserBilling(): Promise {\n const r = await this.send('GET', '/accounts/billing', null, true, true);\n return new BillingResponse(r);\n }\n\n async getUserSubscription(): Promise {\n const r = await this.send('GET', '/accounts/subscription', null, true, true);\n return new SubscriptionResponse(r);\n }\n\n async getTaxInfo(): Promise {\n const r = await this.send('GET', '/accounts/tax', null, true, true);\n return new TaxInfoResponse(r);\n }\n\n async putProfile(request: UpdateProfileRequest): Promise {\n const r = await this.send('PUT', '/accounts/profile', request, true, true);\n return new ProfileResponse(r);\n }\n\n putTaxInfo(request: TaxInfoUpdateRequest): Promise {\n return this.send('PUT', '/accounts/tax', request, true, false);\n }\n\n async postPrelogin(request: PreloginRequest): Promise {\n const r = await this.send('POST', '/accounts/prelogin', request, false, true);\n return new PreloginResponse(r);\n }\n\n postEmailToken(request: EmailTokenRequest): Promise {\n return this.send('POST', '/accounts/email-token', request, true, false);\n }\n\n postEmail(request: EmailRequest): Promise {\n return this.send('POST', '/accounts/email', request, true, false);\n }\n\n postPassword(request: PasswordRequest): Promise {\n return this.send('POST', '/accounts/password', request, true, false);\n }\n\n setPassword(request: SetPasswordRequest): Promise {\n return this.send('POST', '/accounts/set-password', request, true, false);\n }\n\n postSetKeyConnectorKey(request: SetKeyConnectorKeyRequest): Promise {\n return this.send('POST', '/accounts/set-key-connector-key', request, true, false);\n }\n\n postSecurityStamp(request: SecretVerificationRequest): Promise {\n return this.send('POST', '/accounts/security-stamp', request, true, false);\n }\n\n deleteAccount(request: SecretVerificationRequest): Promise {\n return this.send('DELETE', '/accounts', request, true, false);\n }\n\n async getAccountRevisionDate(): Promise {\n const r = await this.send('GET', '/accounts/revision-date', null, true, true);\n return r as number;\n }\n\n postPasswordHint(request: PasswordHintRequest): Promise {\n return this.send('POST', '/accounts/password-hint', request, false, false);\n }\n\n postRegister(request: RegisterRequest): Promise {\n return this.send('POST', '/accounts/register', request, false, false);\n }\n\n async postPremium(data: FormData): Promise {\n const r = await this.send('POST', '/accounts/premium', data, true, true);\n return new PaymentResponse(r);\n }\n\n async postIapCheck(request: IapCheckRequest): Promise {\n return this.send('POST', '/accounts/iap-check', request, true, false);\n }\n\n postReinstatePremium(): Promise {\n return this.send('POST', '/accounts/reinstate-premium', null, true, false);\n }\n\n postCancelPremium(): Promise {\n return this.send('POST', '/accounts/cancel-premium', null, true, false);\n }\n\n async postAccountStorage(request: StorageRequest): Promise {\n const r = await this.send('POST', '/accounts/storage', request, true, true);\n return new PaymentResponse(r);\n }\n\n postAccountPayment(request: PaymentRequest): Promise {\n return this.send('POST', '/accounts/payment', request, true, false);\n }\n\n postAccountLicense(data: FormData): Promise {\n return this.send('POST', '/accounts/license', data, true, false);\n }\n\n postAccountKeys(request: KeysRequest): Promise {\n return this.send('POST', '/accounts/keys', request, true, false);\n }\n\n postAccountKey(request: UpdateKeyRequest): Promise {\n return this.send('POST', '/accounts/key', request, true, false);\n }\n\n postAccountVerifyEmail(): Promise {\n return this.send('POST', '/accounts/verify-email', null, true, false);\n }\n\n postAccountVerifyEmailToken(request: VerifyEmailRequest): Promise {\n return this.send('POST', '/accounts/verify-email-token', request, false, false);\n }\n\n postAccountVerifyPassword(request: SecretVerificationRequest): Promise {\n return this.send('POST', '/accounts/verify-password', request, true, false);\n }\n\n postAccountRecoverDelete(request: DeleteRecoverRequest): Promise {\n return this.send('POST', '/accounts/delete-recover', request, false, false);\n }\n\n postAccountRecoverDeleteToken(request: VerifyDeleteRecoverRequest): Promise {\n return this.send('POST', '/accounts/delete-recover-token', request, false, false);\n }\n\n postAccountKdf(request: KdfRequest): Promise {\n return this.send('POST', '/accounts/kdf', request, true, false);\n }\n\n async deleteSsoUser(organizationId: string): Promise {\n return this.send('DELETE', '/accounts/sso/' + organizationId, null, true, false);\n }\n\n async getSsoUserIdentifier(): Promise {\n return this.send('GET', '/accounts/sso/user-identifier', null, true, true);\n }\n\n async postUserApiKey(id: string, request: SecretVerificationRequest): Promise {\n const r = await this.send('POST', '/accounts/api-key', request, true, true);\n return new ApiKeyResponse(r);\n }\n\n async postUserRotateApiKey(id: string, request: SecretVerificationRequest): Promise {\n const r = await this.send('POST', '/accounts/rotate-api-key', request, true, true);\n return new ApiKeyResponse(r);\n }\n\n putUpdateTempPassword(request: UpdateTempPasswordRequest): Promise {\n return this.send('PUT', '/accounts/update-temp-password', request, true, false);\n }\n\n postAccountRequestOTP(): Promise {\n return this.send('POST', '/accounts/request-otp', null, true, false);\n }\n\n postAccountVerifyOTP(request: VerifyOTPRequest): Promise {\n return this.send('POST', '/accounts/verify-otp', request, true, false);\n }\n\n postConvertToKeyConnector(): Promise {\n return this.send('POST', '/accounts/convert-to-key-connector', null, true, false);\n }\n\n // Folder APIs\n\n async getFolder(id: string): Promise {\n const r = await this.send('GET', '/folders/' + id, null, true, true);\n return new FolderResponse(r);\n }\n\n async postFolder(request: FolderRequest): Promise {\n const r = await this.send('POST', '/folders', request, true, true);\n return new FolderResponse(r);\n }\n\n async putFolder(id: string, request: FolderRequest): Promise {\n const r = await this.send('PUT', '/folders/' + id, request, true, true);\n return new FolderResponse(r);\n }\n\n deleteFolder(id: string): Promise {\n return this.send('DELETE', '/folders/' + id, null, true, false);\n }\n\n // Send APIs\n\n async getSend(id: string): Promise {\n const r = await this.send('GET', '/sends/' + id, null, true, true);\n return new SendResponse(r);\n }\n\n async postSendAccess(id: string, request: SendAccessRequest, apiUrl?: string): Promise {\n const addSendIdHeader = (headers: Headers) => {\n headers.set('Send-Id', id);\n };\n const r = await this.send('POST', '/sends/access/' + id, request, false, true, apiUrl, addSendIdHeader);\n return new SendAccessResponse(r);\n }\n\n async getSendFileDownloadData(send: SendAccessView, request: SendAccessRequest, apiUrl?: string): Promise {\n const addSendIdHeader = (headers: Headers) => {\n headers.set('Send-Id', send.id);\n };\n const r = await this.send('POST', '/sends/' + send.id + '/access/file/' + send.file.id, request, false, true,\n apiUrl, addSendIdHeader);\n return new SendFileDownloadDataResponse(r);\n }\n\n async getSends(): Promise> {\n const r = await this.send('GET', '/sends', null, true, true);\n return new ListResponse(r, SendResponse);\n }\n\n async postSend(request: SendRequest): Promise {\n const r = await this.send('POST', '/sends', request, true, true);\n return new SendResponse(r);\n }\n\n async postFileTypeSend(request: SendRequest): Promise {\n const r = await this.send('POST', '/sends/file/v2', request, true, true);\n return new SendFileUploadDataResponse(r);\n }\n\n async renewSendFileUploadUrl(sendId: string, fileId: string): Promise {\n const r = await this.send('GET', '/sends/' + sendId + '/file/' + fileId, null, true, true);\n return new SendFileUploadDataResponse(r);\n }\n\n postSendFile(sendId: string, fileId: string, data: FormData): Promise {\n return this.send('POST', '/sends/' + sendId + '/file/' + fileId, data, true, false);\n }\n\n /**\n * @deprecated Mar 25 2021: This method has been deprecated in favor of direct uploads.\n * This method still exists for backward compatibility with old server versions.\n */\n async postSendFileLegacy(data: FormData): Promise {\n const r = await this.send('POST', '/sends/file', data, true, true);\n return new SendResponse(r);\n }\n\n async putSend(id: string, request: SendRequest): Promise {\n const r = await this.send('PUT', '/sends/' + id, request, true, true);\n return new SendResponse(r);\n }\n\n async putSendRemovePassword(id: string): Promise {\n const r = await this.send('PUT', '/sends/' + id + '/remove-password', null, true, true);\n return new SendResponse(r);\n }\n\n deleteSend(id: string): Promise {\n return this.send('DELETE', '/sends/' + id, null, true, false);\n }\n\n // Cipher APIs\n\n async getCipher(id: string): Promise {\n const r = await this.send('GET', '/ciphers/' + id, null, true, true);\n return new CipherResponse(r);\n }\n\n async getCipherAdmin(id: string): Promise {\n const r = await this.send('GET', '/ciphers/' + id + '/admin', null, true, true);\n return new CipherResponse(r);\n }\n\n async getCiphersOrganization(organizationId: string): Promise> {\n const r = await this.send('GET', '/ciphers/organization-details?organizationId=' + organizationId,\n null, true, true);\n return new ListResponse(r, CipherResponse);\n }\n\n async postCipher(request: CipherRequest): Promise {\n const r = await this.send('POST', '/ciphers', request, true, true);\n return new CipherResponse(r);\n }\n\n async postCipherCreate(request: CipherCreateRequest): Promise {\n const r = await this.send('POST', '/ciphers/create', request, true, true);\n return new CipherResponse(r);\n }\n\n async postCipherAdmin(request: CipherCreateRequest): Promise {\n const r = await this.send('POST', '/ciphers/admin', request, true, true);\n return new CipherResponse(r);\n }\n\n async putCipher(id: string, request: CipherRequest): Promise {\n const r = await this.send('PUT', '/ciphers/' + id, request, true, true);\n return new CipherResponse(r);\n }\n\n async putCipherAdmin(id: string, request: CipherRequest): Promise {\n const r = await this.send('PUT', '/ciphers/' + id + '/admin', request, true, true);\n return new CipherResponse(r);\n }\n\n deleteCipher(id: string): Promise {\n return this.send('DELETE', '/ciphers/' + id, null, true, false);\n }\n\n deleteCipherAdmin(id: string): Promise {\n return this.send('DELETE', '/ciphers/' + id + '/admin', null, true, false);\n }\n\n deleteManyCiphers(request: CipherBulkDeleteRequest): Promise {\n return this.send('DELETE', '/ciphers', request, true, false);\n }\n\n deleteManyCiphersAdmin(request: CipherBulkDeleteRequest): Promise {\n return this.send('DELETE', '/ciphers/admin', request, true, false);\n }\n\n putMoveCiphers(request: CipherBulkMoveRequest): Promise {\n return this.send('PUT', '/ciphers/move', request, true, false);\n }\n\n async putShareCipher(id: string, request: CipherShareRequest): Promise {\n const r = await this.send('PUT', '/ciphers/' + id + '/share', request, true, true);\n return new CipherResponse(r);\n }\n\n putShareCiphers(request: CipherBulkShareRequest): Promise {\n return this.send('PUT', '/ciphers/share', request, true, false);\n }\n\n putCipherCollections(id: string, request: CipherCollectionsRequest): Promise {\n return this.send('PUT', '/ciphers/' + id + '/collections', request, true, false);\n }\n\n putCipherCollectionsAdmin(id: string, request: CipherCollectionsRequest): Promise {\n return this.send('PUT', '/ciphers/' + id + '/collections-admin', request, true, false);\n }\n\n postPurgeCiphers(request: SecretVerificationRequest, organizationId: string = null): Promise {\n let path = '/ciphers/purge';\n if (organizationId != null) {\n path += '?organizationId=' + organizationId;\n }\n return this.send('POST', path, request, true, false);\n }\n\n postImportCiphers(request: ImportCiphersRequest): Promise {\n return this.send('POST', '/ciphers/import', request, true, false);\n }\n\n postImportOrganizationCiphers(organizationId: string, request: ImportOrganizationCiphersRequest): Promise {\n return this.send('POST', '/ciphers/import-organization?organizationId=' + organizationId, request, true, false);\n }\n\n putDeleteCipher(id: string): Promise {\n return this.send('PUT', '/ciphers/' + id + '/delete', null, true, false);\n }\n\n putDeleteCipherAdmin(id: string): Promise {\n return this.send('PUT', '/ciphers/' + id + '/delete-admin', null, true, false);\n }\n\n putDeleteManyCiphers(request: CipherBulkDeleteRequest): Promise {\n return this.send('PUT', '/ciphers/delete', request, true, false);\n }\n\n putDeleteManyCiphersAdmin(request: CipherBulkDeleteRequest): Promise {\n return this.send('PUT', '/ciphers/delete-admin', request, true, false);\n }\n\n async putRestoreCipher(id: string): Promise {\n const r = await this.send('PUT', '/ciphers/' + id + '/restore', null, true, true);\n return new CipherResponse(r);\n }\n\n async putRestoreCipherAdmin(id: string): Promise {\n const r = await this.send('PUT', '/ciphers/' + id + '/restore-admin', null, true, true);\n return new CipherResponse(r);\n }\n\n async putRestoreManyCiphers(request: CipherBulkDeleteRequest): Promise> {\n const r = await this.send('PUT', '/ciphers/restore', request, true, true);\n return new ListResponse(r, CipherResponse);\n }\n\n // Attachments APIs\n\n async getAttachmentData(cipherId: string, attachmentId: string, emergencyAccessId?: string): Promise {\n const path = (emergencyAccessId != null ?\n '/emergency-access/' + emergencyAccessId + '/' :\n '/ciphers/') + cipherId + '/attachment/' + attachmentId;\n const r = await this.send('GET', path, null, true, true);\n return new AttachmentResponse(r);\n }\n\n async postCipherAttachment(id: string, request: AttachmentRequest): Promise {\n const r = await this.send('POST', '/ciphers/' + id + '/attachment/v2', request, true, true);\n return new AttachmentUploadDataResponse(r);\n }\n\n /**\n * @deprecated Mar 25 2021: This method has been deprecated in favor of direct uploads.\n * This method still exists for backward compatibility with old server versions.\n */\n async postCipherAttachmentLegacy(id: string, data: FormData): Promise {\n const r = await this.send('POST', '/ciphers/' + id + '/attachment', data, true, true);\n return new CipherResponse(r);\n }\n\n /**\n * @deprecated Mar 25 2021: This method has been deprecated in favor of direct uploads.\n * This method still exists for backward compatibility with old server versions.\n */\n async postCipherAttachmentAdminLegacy(id: string, data: FormData): Promise {\n const r = await this.send('POST', '/ciphers/' + id + '/attachment-admin', data, true, true);\n return new CipherResponse(r);\n }\n\n deleteCipherAttachment(id: string, attachmentId: string): Promise {\n return this.send('DELETE', '/ciphers/' + id + '/attachment/' + attachmentId, null, true, false);\n }\n\n deleteCipherAttachmentAdmin(id: string, attachmentId: string): Promise {\n return this.send('DELETE', '/ciphers/' + id + '/attachment/' + attachmentId + '/admin', null, true, false);\n }\n\n postShareCipherAttachment(id: string, attachmentId: string, data: FormData,\n organizationId: string): Promise {\n return this.send('POST', '/ciphers/' + id + '/attachment/' +\n attachmentId + '/share?organizationId=' + organizationId, data, true, false);\n }\n\n async renewAttachmentUploadUrl(id: string, attachmentId: string): Promise {\n const r = await this.send('GET', '/ciphers/' + id + '/attachment/' + attachmentId + '/renew', null, true, true);\n return new AttachmentUploadDataResponse(r);\n }\n\n postAttachmentFile(id: string, attachmentId: string, data: FormData): Promise {\n return this.send('POST', '/ciphers/' + id + '/attachment/' + attachmentId, data, true, false);\n }\n\n // Collections APIs\n\n async getCollectionDetails(organizationId: string, id: string): Promise {\n const r = await this.send('GET', '/organizations/' + organizationId + '/collections/' + id + '/details',\n null, true, true);\n return new CollectionGroupDetailsResponse(r);\n }\n\n async getUserCollections(): Promise> {\n const r = await this.send('GET', '/collections', null, true, true);\n return new ListResponse(r, CollectionResponse);\n }\n\n async getCollections(organizationId: string): Promise> {\n const r = await this.send('GET', '/organizations/' + organizationId + '/collections', null, true, true);\n return new ListResponse(r, CollectionResponse);\n }\n\n async getCollectionUsers(organizationId: string, id: string): Promise {\n const r = await this.send('GET', '/organizations/' + organizationId + '/collections/' + id + '/users',\n null, true, true);\n return r.map((dr: any) => new SelectionReadOnlyResponse(dr));\n }\n\n async postCollection(organizationId: string, request: CollectionRequest): Promise {\n const r = await this.send('POST', '/organizations/' + organizationId + '/collections', request, true, true);\n return new CollectionResponse(r);\n }\n\n async putCollection(organizationId: string, id: string, request: CollectionRequest): Promise {\n const r = await this.send('PUT', '/organizations/' + organizationId + '/collections/' + id,\n request, true, true);\n return new CollectionResponse(r);\n }\n\n async putCollectionUsers(organizationId: string, id: string, request: SelectionReadOnlyRequest[]): Promise {\n await this.send('PUT', '/organizations/' + organizationId + '/collections/' + id + '/users',\n request, true, false);\n }\n\n deleteCollection(organizationId: string, id: string): Promise {\n return this.send('DELETE', '/organizations/' + organizationId + '/collections/' + id, null, true, false);\n }\n\n deleteCollectionUser(organizationId: string, id: string, organizationUserId: string): Promise {\n return this.send('DELETE',\n '/organizations/' + organizationId + '/collections/' + id + '/user/' + organizationUserId,\n null, true, false);\n }\n\n // Groups APIs\n\n async getGroupDetails(organizationId: string, id: string): Promise {\n const r = await this.send('GET', '/organizations/' + organizationId + '/groups/' + id + '/details',\n null, true, true);\n return new GroupDetailsResponse(r);\n }\n\n async getGroups(organizationId: string): Promise> {\n const r = await this.send('GET', '/organizations/' + organizationId + '/groups', null, true, true);\n return new ListResponse(r, GroupResponse);\n }\n\n async getGroupUsers(organizationId: string, id: string): Promise {\n const r = await this.send('GET', '/organizations/' + organizationId + '/groups/' + id + '/users',\n null, true, true);\n return r;\n }\n\n async postGroup(organizationId: string, request: GroupRequest): Promise {\n const r = await this.send('POST', '/organizations/' + organizationId + '/groups', request, true, true);\n return new GroupResponse(r);\n }\n\n async putGroup(organizationId: string, id: string, request: GroupRequest): Promise {\n const r = await this.send('PUT', '/organizations/' + organizationId + '/groups/' + id, request, true, true);\n return new GroupResponse(r);\n }\n\n async putGroupUsers(organizationId: string, id: string, request: string[]): Promise {\n await this.send('PUT', '/organizations/' + organizationId + '/groups/' + id + '/users', request, true, false);\n }\n\n deleteGroup(organizationId: string, id: string): Promise {\n return this.send('DELETE', '/organizations/' + organizationId + '/groups/' + id, null, true, false);\n }\n\n deleteGroupUser(organizationId: string, id: string, organizationUserId: string): Promise {\n return this.send('DELETE',\n '/organizations/' + organizationId + '/groups/' + id + '/user/' + organizationUserId, null, true, false);\n }\n\n // Policy APIs\n\n async getPolicy(organizationId: string, type: PolicyType): Promise {\n const r = await this.send('GET', '/organizations/' + organizationId + '/policies/' + type, null, true, true);\n return new PolicyResponse(r);\n }\n\n async getPolicies(organizationId: string): Promise> {\n const r = await this.send('GET', '/organizations/' + organizationId + '/policies', null, true, true);\n return new ListResponse(r, PolicyResponse);\n }\n\n async getPoliciesByToken(organizationId: string, token: string, email: string, organizationUserId: string):\n Promise> {\n const r = await this.send('GET', '/organizations/' + organizationId + '/policies/token?' +\n 'token=' + encodeURIComponent(token) + '&email=' + encodeURIComponent(email) +\n '&organizationUserId=' + organizationUserId, null, false, true);\n return new ListResponse(r, PolicyResponse);\n }\n\n async getPoliciesByInvitedUser(\n organizationId: string,\n userId: string\n ): Promise> {\n const r = await this.send(\n \"GET\",\n \"/organizations/\" + organizationId + \"/policies/invited-user?\" + \"userId=\" + userId,\n null,\n false,\n true\n );\n return new ListResponse(r, PolicyResponse);\n }\n\n async putPolicy(organizationId: string, type: PolicyType, request: PolicyRequest): Promise {\n const r = await this.send('PUT', '/organizations/' + organizationId + '/policies/' + type, request, true, true);\n return new PolicyResponse(r);\n }\n\n // Organization User APIs\n\n async getOrganizationUser(organizationId: string, id: string): Promise {\n const r = await this.send('GET', '/organizations/' + organizationId + '/users/' + id, null, true, true);\n return new OrganizationUserDetailsResponse(r);\n }\n\n async getOrganizationUserGroups(organizationId: string, id: string): Promise {\n const r = await this.send('GET', '/organizations/' + organizationId + '/users/' + id + '/groups',\n null, true, true);\n return r;\n }\n\n async getOrganizationUsers(organizationId: string): Promise> {\n const r = await this.send('GET', '/organizations/' + organizationId + '/users', null, true, true);\n return new ListResponse(r, OrganizationUserUserDetailsResponse);\n }\n\n async getOrganizationUserResetPasswordDetails(organizationId: string, id: string):\n Promise {\n const r = await this.send('GET', '/organizations/' + organizationId + '/users/' + id +\n '/reset-password-details', null, true, true);\n return new OrganizationUserResetPasswordDetailsReponse(r);\n }\n\n async getOrganizationAutoEnrollStatus(identifier: string): Promise {\n const r = await this.send('GET', '/organizations/' + identifier + '/auto-enroll-status', null, true, true);\n return new OrganizationAutoEnrollStatusResponse(r);\n }\n\n postOrganizationUserInvite(organizationId: string, request: OrganizationUserInviteRequest): Promise {\n return this.send('POST', '/organizations/' + organizationId + '/users/invite', request, true, false);\n }\n\n postOrganizationUserReinvite(organizationId: string, id: string): Promise {\n return this.send('POST', '/organizations/' + organizationId + '/users/' + id + '/reinvite', null, true, false);\n }\n\n async postManyOrganizationUserReinvite(organizationId: string, request: OrganizationUserBulkRequest): Promise> {\n const r = await this.send('POST', '/organizations/' + organizationId + '/users/reinvite', request, true, true);\n return new ListResponse(r, OrganizationUserBulkResponse);\n }\n\n postOrganizationUserAccept(organizationId: string, id: string,\n request: OrganizationUserAcceptRequest): Promise {\n return this.send('POST', '/organizations/' + organizationId + '/users/' + id + '/accept', request, true, false);\n }\n\n postOrganizationUserConfirm(organizationId: string, id: string,\n request: OrganizationUserConfirmRequest): Promise {\n return this.send('POST', '/organizations/' + organizationId + '/users/' + id + '/confirm',\n request, true, false);\n }\n\n async postOrganizationUsersPublicKey(organizationId: string, request: OrganizationUserBulkRequest): Promise> {\n const r = await this.send('POST', '/organizations/' + organizationId + '/users/public-keys', request, true, true);\n return new ListResponse(r, OrganizationUserBulkPublicKeyResponse);\n }\n\n async postOrganizationUserBulkConfirm(organizationId: string, request: OrganizationUserBulkConfirmRequest): Promise> {\n const r = await this.send('POST', '/organizations/' + organizationId + '/users/confirm', request, true, true);\n return new ListResponse(r, OrganizationUserBulkResponse);\n }\n\n putOrganizationUser(organizationId: string, id: string, request: OrganizationUserUpdateRequest): Promise {\n return this.send('PUT', '/organizations/' + organizationId + '/users/' + id, request, true, false);\n }\n\n putOrganizationUserGroups(organizationId: string, id: string,\n request: OrganizationUserUpdateGroupsRequest): Promise {\n return this.send('PUT', '/organizations/' + organizationId + '/users/' + id + '/groups', request, true, false);\n }\n\n putOrganizationUserResetPasswordEnrollment(organizationId: string, userId: string,\n request: OrganizationUserResetPasswordEnrollmentRequest): Promise {\n return this.send('PUT', '/organizations/' + organizationId + '/users/' + userId + '/reset-password-enrollment',\n request, true, false);\n }\n\n putOrganizationUserResetPassword(organizationId: string, id: string,\n request: OrganizationUserResetPasswordRequest): Promise {\n return this.send('PUT', '/organizations/' + organizationId + '/users/' + id + '/reset-password',\n request, true, false);\n }\n\n deleteOrganizationUser(organizationId: string, id: string): Promise {\n return this.send('DELETE', '/organizations/' + organizationId + '/users/' + id, null, true, false);\n }\n\n async deleteManyOrganizationUsers(organizationId: string, request: OrganizationUserBulkRequest): Promise> {\n const r = await this.send('DELETE', '/organizations/' + organizationId + '/users', request, true, true);\n return new ListResponse(r, OrganizationUserBulkResponse);\n }\n\n // Plan APIs\n\n async getPlans(): Promise> {\n const r = await this.send('GET', '/plans/', null, true, true);\n return new ListResponse(r, PlanResponse);\n }\n\n async postImportDirectory(organizationId: string, request: ImportDirectoryRequest): Promise {\n return this.send('POST', '/organizations/' + organizationId + '/import', request, true, false);\n }\n\n async postPublicImportDirectory(request: OrganizationImportRequest): Promise {\n return this.send('POST', '/public/organization/import', request, true, false);\n }\n\n async getTaxRates(): Promise> {\n const r = await this.send('GET', '/plans/sales-tax-rates/', null, true, true);\n return new ListResponse(r, TaxRateResponse);\n }\n\n // Settings APIs\n\n async getSettingsDomains(): Promise {\n const r = await this.send('GET', '/settings/domains', null, true, true);\n return new DomainsResponse(r);\n }\n\n async putSettingsDomains(request: UpdateDomainsRequest): Promise {\n const r = await this.send('PUT', '/settings/domains', request, true, true);\n return new DomainsResponse(r);\n }\n\n // Sync APIs\n\n async getSync(): Promise {\n const path = this.isDesktopClient || this.isWebClient ? '/sync?excludeDomains=true' : '/sync';\n const r = await this.send('GET', path, null, true, true);\n return new SyncResponse(r);\n }\n\n // Two-factor APIs\n\n async getTwoFactorProviders(): Promise> {\n const r = await this.send('GET', '/two-factor', null, true, true);\n return new ListResponse(r, TwoFactorProviderResponse);\n }\n\n async getTwoFactorOrganizationProviders(organizationId: string): Promise> {\n const r = await this.send('GET', '/organizations/' + organizationId + '/two-factor', null, true, true);\n return new ListResponse(r, TwoFactorProviderResponse);\n }\n\n async getTwoFactorAuthenticator(request: SecretVerificationRequest): Promise {\n const r = await this.send('POST', '/two-factor/get-authenticator', request, true, true);\n return new TwoFactorAuthenticatorResponse(r);\n }\n\n async getTwoFactorEmail(request: SecretVerificationRequest): Promise {\n const r = await this.send('POST', '/two-factor/get-email', request, true, true);\n return new TwoFactorEmailResponse(r);\n }\n\n async getTwoFactorDuo(request: SecretVerificationRequest): Promise {\n const r = await this.send('POST', '/two-factor/get-duo', request, true, true);\n return new TwoFactorDuoResponse(r);\n }\n\n async getTwoFactorOrganizationDuo(organizationId: string,\n request: SecretVerificationRequest): Promise {\n const r = await this.send('POST', '/organizations/' + organizationId + '/two-factor/get-duo',\n request, true, true);\n return new TwoFactorDuoResponse(r);\n }\n\n async getTwoFactorYubiKey(request: SecretVerificationRequest): Promise {\n const r = await this.send('POST', '/two-factor/get-yubikey', request, true, true);\n return new TwoFactorYubiKeyResponse(r);\n }\n\n async getTwoFactorWebAuthn(request: SecretVerificationRequest): Promise {\n const r = await this.send('POST', '/two-factor/get-webauthn', request, true, true);\n return new TwoFactorWebAuthnResponse(r);\n }\n\n async getTwoFactorWebAuthnChallenge(request: SecretVerificationRequest): Promise {\n const r = await this.send('POST', '/two-factor/get-webauthn-challenge', request, true, true);\n return new ChallengeResponse(r);\n }\n\n async getTwoFactorRecover(request: SecretVerificationRequest): Promise {\n const r = await this.send('POST', '/two-factor/get-recover', request, true, true);\n return new TwoFactorRecoverResponse(r);\n }\n\n async putTwoFactorAuthenticator(\n request: UpdateTwoFactorAuthenticatorRequest): Promise {\n const r = await this.send('PUT', '/two-factor/authenticator', request, true, true);\n return new TwoFactorAuthenticatorResponse(r);\n }\n\n async putTwoFactorEmail(request: UpdateTwoFactorEmailRequest): Promise {\n const r = await this.send('PUT', '/two-factor/email', request, true, true);\n return new TwoFactorEmailResponse(r);\n }\n\n async putTwoFactorDuo(request: UpdateTwoFactorDuoRequest): Promise {\n const r = await this.send('PUT', '/two-factor/duo', request, true, true);\n return new TwoFactorDuoResponse(r);\n }\n\n async putTwoFactorOrganizationDuo(organizationId: string,\n request: UpdateTwoFactorDuoRequest): Promise {\n const r = await this.send('PUT', '/organizations/' + organizationId + '/two-factor/duo', request, true, true);\n return new TwoFactorDuoResponse(r);\n }\n\n async putTwoFactorYubiKey(request: UpdateTwoFactorYubioOtpRequest): Promise {\n const r = await this.send('PUT', '/two-factor/yubikey', request, true, true);\n return new TwoFactorYubiKeyResponse(r);\n }\n\n async putTwoFactorWebAuthn(request: UpdateTwoFactorWebAuthnRequest): Promise {\n const response = request.deviceResponse.response as AuthenticatorAttestationResponse;\n const data: any = Object.assign({}, request);\n\n data.deviceResponse = {\n id: request.deviceResponse.id,\n rawId: btoa(request.deviceResponse.id),\n type: request.deviceResponse.type,\n extensions: request.deviceResponse.getClientExtensionResults(),\n response: {\n AttestationObject: Utils.fromBufferToB64(response.attestationObject),\n clientDataJson: Utils.fromBufferToB64(response.clientDataJSON),\n },\n };\n\n const r = await this.send('PUT', '/two-factor/webauthn', data, true, true);\n return new TwoFactorWebAuthnResponse(r);\n }\n\n async deleteTwoFactorWebAuthn(request: UpdateTwoFactorWebAuthnDeleteRequest): Promise {\n const r = await this.send('DELETE', '/two-factor/webauthn', request, true, true);\n return new TwoFactorWebAuthnResponse(r);\n }\n\n async putTwoFactorDisable(request: TwoFactorProviderRequest): Promise {\n const r = await this.send('PUT', '/two-factor/disable', request, true, true);\n return new TwoFactorProviderResponse(r);\n }\n\n async putTwoFactorOrganizationDisable(organizationId: string,\n request: TwoFactorProviderRequest): Promise {\n const r = await this.send('PUT', '/organizations/' + organizationId + '/two-factor/disable',\n request, true, true);\n return new TwoFactorProviderResponse(r);\n }\n\n postTwoFactorRecover(request: TwoFactorRecoveryRequest): Promise {\n return this.send('POST', '/two-factor/recover', request, false, false);\n }\n\n postTwoFactorEmailSetup(request: TwoFactorEmailRequest): Promise {\n return this.send('POST', '/two-factor/send-email', request, true, false);\n }\n\n postTwoFactorEmail(request: TwoFactorEmailRequest): Promise {\n return this.send('POST', '/two-factor/send-email-login', request, false, false);\n }\n\n // Emergency Access APIs\n\n async getEmergencyAccessTrusted(): Promise> {\n const r = await this.send('GET', '/emergency-access/trusted', null, true, true);\n return new ListResponse(r, EmergencyAccessGranteeDetailsResponse);\n }\n\n async getEmergencyAccessGranted(): Promise> {\n const r = await this.send('GET', '/emergency-access/granted', null, true, true);\n return new ListResponse(r, EmergencyAccessGrantorDetailsResponse);\n }\n\n async getEmergencyAccess(id: string): Promise {\n const r = await this.send('GET', '/emergency-access/' + id, null, true, true);\n return new EmergencyAccessGranteeDetailsResponse(r);\n }\n\n async getEmergencyGrantorPolicies(id: string): Promise> {\n const r = await this.send('GET', '/emergency-access/' + id + '/policies', null, true, true);\n return new ListResponse(r, PolicyResponse);\n }\n\n putEmergencyAccess(id: string, request: EmergencyAccessUpdateRequest): Promise {\n return this.send('PUT', '/emergency-access/' + id, request, true, false);\n }\n\n deleteEmergencyAccess(id: string): Promise {\n return this.send('DELETE', '/emergency-access/' + id, null, true, false);\n }\n\n postEmergencyAccessInvite(request: EmergencyAccessInviteRequest): Promise {\n return this.send('POST', '/emergency-access/invite', request, true, false);\n }\n\n postEmergencyAccessReinvite(id: string): Promise {\n return this.send('POST', '/emergency-access/' + id + '/reinvite', null, true, false);\n }\n\n postEmergencyAccessAccept(id: string, request: EmergencyAccessAcceptRequest): Promise {\n return this.send('POST', '/emergency-access/' + id + '/accept', request, true, false);\n }\n\n postEmergencyAccessConfirm(id: string, request: EmergencyAccessConfirmRequest): Promise {\n return this.send('POST', '/emergency-access/' + id + '/confirm', request, true, false);\n }\n\n postEmergencyAccessInitiate(id: string): Promise {\n return this.send('POST', '/emergency-access/' + id + '/initiate', null, true, false);\n }\n\n postEmergencyAccessApprove(id: string): Promise {\n return this.send('POST', '/emergency-access/' + id + '/approve', null, true, false);\n }\n\n postEmergencyAccessReject(id: string): Promise {\n return this.send('POST', '/emergency-access/' + id + '/reject', null, true, false);\n }\n\n async postEmergencyAccessTakeover(id: string): Promise {\n const r = await this.send('POST', '/emergency-access/' + id + '/takeover', null, true, true);\n return new EmergencyAccessTakeoverResponse(r);\n }\n\n async postEmergencyAccessPassword(id: string, request: EmergencyAccessPasswordRequest): Promise {\n const r = await this.send('POST', '/emergency-access/' + id + '/password', request, true, true);\n }\n\n async postEmergencyAccessView(id: string): Promise {\n const r = await this.send('POST', '/emergency-access/' + id + '/view', null, true, true);\n return new EmergencyAccessViewResponse(r);\n }\n\n // Organization APIs\n\n async getOrganization(id: string): Promise {\n const r = await this.send('GET', '/organizations/' + id, null, true, true);\n return new OrganizationResponse(r);\n }\n\n async getOrganizationBilling(id: string): Promise {\n const r = await this.send('GET', '/organizations/' + id + '/billing', null, true, true);\n return new BillingResponse(r);\n }\n\n async getOrganizationSubscription(id: string): Promise {\n const r = await this.send('GET', '/organizations/' + id + '/subscription', null, true, true);\n return new OrganizationSubscriptionResponse(r);\n }\n\n async getOrganizationLicense(id: string, installationId: string): Promise {\n return this.send('GET', '/organizations/' + id + '/license?installationId=' + installationId,\n null, true, true);\n }\n\n async getOrganizationTaxInfo(id: string): Promise {\n const r = await this.send('GET', '/organizations/' + id + '/tax', null, true, true);\n return new TaxInfoResponse(r);\n }\n\n async getOrganizationSso(id: string): Promise {\n const r = await this.send('GET', '/organizations/' + id + '/sso', null, true, true);\n return new OrganizationSsoResponse(r);\n }\n\n async postOrganization(request: OrganizationCreateRequest): Promise {\n const r = await this.send('POST', '/organizations', request, true, true);\n return new OrganizationResponse(r);\n }\n\n async putOrganization(id: string, request: OrganizationUpdateRequest): Promise {\n const r = await this.send('PUT', '/organizations/' + id, request, true, true);\n return new OrganizationResponse(r);\n }\n\n async putOrganizationTaxInfo(id: string, request: OrganizationTaxInfoUpdateRequest): Promise {\n return this.send('PUT', '/organizations/' + id + '/tax', request, true, false);\n }\n\n postLeaveOrganization(id: string): Promise {\n return this.send('POST', '/organizations/' + id + '/leave', null, true, false);\n }\n\n async postOrganizationLicense(data: FormData): Promise {\n const r = await this.send('POST', '/organizations/license', data, true, true);\n return new OrganizationResponse(r);\n }\n\n async postOrganizationLicenseUpdate(id: string, data: FormData): Promise {\n return this.send('POST', '/organizations/' + id + '/license', data, true, false);\n }\n\n async postOrganizationApiKey(id: string, request: SecretVerificationRequest): Promise {\n const r = await this.send('POST', '/organizations/' + id + '/api-key', request, true, true);\n return new ApiKeyResponse(r);\n }\n\n async postOrganizationRotateApiKey(id: string, request: SecretVerificationRequest): Promise {\n const r = await this.send('POST', '/organizations/' + id + '/rotate-api-key', request, true, true);\n return new ApiKeyResponse(r);\n }\n\n async postOrganizationSso(id: string, request: OrganizationSsoRequest): Promise {\n const r = await this.send('POST', '/organizations/' + id + '/sso', request, true, true);\n return new OrganizationSsoResponse(r);\n }\n\n async postOrganizationUpgrade(id: string, request: OrganizationUpgradeRequest): Promise {\n const r = await this.send('POST', '/organizations/' + id + '/upgrade', request, true, true);\n return new PaymentResponse(r);\n }\n\n async postOrganizationUpdateSubscription(id: string, request: OrganizationSubscriptionUpdateRequest): Promise {\n return this.send('POST', '/organizations/' + id + '/subscription', request, true, false);\n }\n\n async postOrganizationSeat(id: string, request: SeatRequest): Promise {\n const r = await this.send('POST', '/organizations/' + id + '/seat', request, true, true);\n return new PaymentResponse(r);\n }\n\n async postOrganizationStorage(id: string, request: StorageRequest): Promise {\n const r = await this.send('POST', '/organizations/' + id + '/storage', request, true, true);\n return new PaymentResponse(r);\n }\n\n postOrganizationPayment(id: string, request: PaymentRequest): Promise {\n return this.send('POST', '/organizations/' + id + '/payment', request, true, false);\n }\n\n postOrganizationVerifyBank(id: string, request: VerifyBankRequest): Promise {\n return this.send('POST', '/organizations/' + id + '/verify-bank', request, true, false);\n }\n\n postOrganizationCancel(id: string): Promise {\n return this.send('POST', '/organizations/' + id + '/cancel', null, true, false);\n }\n\n postOrganizationReinstate(id: string): Promise {\n return this.send('POST', '/organizations/' + id + '/reinstate', null, true, false);\n }\n\n deleteOrganization(id: string, request: SecretVerificationRequest): Promise {\n return this.send('DELETE', '/organizations/' + id, request, true, false);\n }\n\n async getOrganizationKeys(id: string): Promise {\n const r = await this.send('GET', '/organizations/' + id + '/keys', null, true, true);\n return new OrganizationKeysResponse(r);\n }\n\n async postOrganizationKeys(id: string, request: OrganizationKeysRequest): Promise {\n const r = await this.send('POST', '/organizations/' + id + '/keys', request, true, true);\n return new OrganizationKeysResponse(r);\n }\n\n // Provider APIs\n\n async postProviderSetup(id: string, request: ProviderSetupRequest) {\n const r = await this.send('POST', '/providers/' + id + '/setup', request, true, true);\n return new ProviderResponse(r);\n }\n\n async getProvider(id: string) {\n const r = await this.send('GET', '/providers/' + id, null, true, true);\n return new ProviderResponse(r);\n }\n\n async putProvider(id: string, request: ProviderUpdateRequest) {\n const r = await this.send('PUT', '/providers/' + id, request, true, true);\n return new ProviderResponse(r);\n }\n\n // Provider User APIs\n\n async getProviderUsers(providerId: string): Promise> {\n const r = await this.send('GET', '/providers/' + providerId + '/users', null, true, true);\n return new ListResponse(r, ProviderUserUserDetailsResponse);\n }\n\n async getProviderUser(providerId: string, id: string): Promise {\n const r = await this.send('GET', '/providers/' + providerId + '/users/' + id, null, true, true);\n return new ProviderUserResponse(r);\n }\n\n postProviderUserInvite(providerId: string, request: ProviderUserInviteRequest): Promise {\n return this.send('POST', '/providers/' + providerId + '/users/invite', request, true, false);\n }\n\n postProviderUserReinvite(providerId: string, id: string): Promise {\n return this.send('POST', '/providers/' + providerId + '/users/' + id + '/reinvite', null, true, false);\n }\n\n async postManyProviderUserReinvite(providerId: string, request: ProviderUserBulkRequest): Promise> {\n const r = await this.send('POST', '/providers/' + providerId + '/users/reinvite', request, true, true);\n return new ListResponse(r, ProviderUserBulkResponse);\n }\n\n async postProviderUserBulkConfirm(providerId: string, request: ProviderUserBulkConfirmRequest): Promise> {\n const r = await this.send('POST', '/providers/' + providerId + '/users/confirm', request, true, true);\n return new ListResponse(r, ProviderUserBulkResponse);\n }\n\n async deleteManyProviderUsers(providerId: string, request: ProviderUserBulkRequest): Promise> {\n const r = await this.send('DELETE', '/providers/' + providerId + '/users', request, true, true);\n return new ListResponse(r, ProviderUserBulkResponse);\n }\n\n postProviderUserAccept(providerId: string, id: string, request: ProviderUserAcceptRequest): Promise {\n return this.send('POST', '/providers/' + providerId + '/users/' + id + '/accept', request, true, false);\n }\n\n postProviderUserConfirm(providerId: string, id: string, request: ProviderUserConfirmRequest): Promise {\n return this.send('POST', '/providers/' + providerId + '/users/' + id + '/confirm',\n request, true, false);\n }\n\n async postProviderUsersPublicKey(providerId: string, request: ProviderUserBulkRequest): Promise> {\n const r = await this.send('POST', '/providers/' + providerId + '/users/public-keys', request, true, true);\n return new ListResponse(r, ProviderUserBulkPublicKeyResponse);\n }\n\n\n putProviderUser(providerId: string, id: string, request: ProviderUserUpdateRequest): Promise {\n return this.send('PUT', '/providers/' + providerId + '/users/' + id, request, true, false);\n }\n\n deleteProviderUser(providerId: string, id: string): Promise {\n return this.send('DELETE', '/providers/' + providerId + '/users/' + id, null, true, false);\n }\n\n // Provider Organization APIs\n\n async getProviderClients(providerId: string): Promise> {\n const r = await this.send('GET', '/providers/' + providerId + '/organizations', null, true, true);\n return new ListResponse(r, ProviderOrganizationOrganizationDetailsResponse);\n }\n\n postProviderAddOrganization(providerId: string, request: ProviderAddOrganizationRequest): Promise {\n return this.send('POST', '/providers/' + providerId + '/organizations/add', request, true, false);\n }\n\n async postProviderCreateOrganization(providerId: string, request: ProviderOrganizationCreateRequest): Promise {\n const r = await this.send('POST', '/providers/' + providerId + '/organizations', request, true, true);\n return new ProviderOrganizationResponse(r);\n }\n\n deleteProviderOrganization(providerId: string, id: string): Promise {\n return this.send('DELETE', '/providers/' + providerId + '/organizations/' + id, null, true, false);\n }\n\n // Event APIs\n\n async getEvents(start: string, end: string, token: string): Promise> {\n const r = await this.send('GET', this.addEventParameters('/events', start, end, token), null, true, true);\n return new ListResponse(r, EventResponse);\n }\n\n async getEventsCipher(id: string, start: string, end: string,\n token: string): Promise> {\n const r = await this.send('GET', this.addEventParameters('/ciphers/' + id + '/events', start, end, token),\n null, true, true);\n return new ListResponse(r, EventResponse);\n }\n\n async getEventsOrganization(id: string, start: string, end: string,\n token: string): Promise> {\n const r = await this.send('GET', this.addEventParameters('/organizations/' + id + '/events', start, end, token),\n null, true, true);\n return new ListResponse(r, EventResponse);\n }\n\n async getEventsOrganizationUser(organizationId: string, id: string,\n start: string, end: string, token: string): Promise> {\n const r = await this.send('GET',\n this.addEventParameters('/organizations/' + organizationId + '/users/' + id + '/events', start, end, token),\n null, true, true);\n return new ListResponse(r, EventResponse);\n }\n\n async getEventsProvider(id: string, start: string, end: string, token: string): Promise> {\n const r = await this.send('GET', this.addEventParameters('/providers/' + id + '/events', start, end, token), null, true, true);\n return new ListResponse(r, EventResponse);\n }\n\n async getEventsProviderUser(providerId: string, id: string,\n start: string, end: string, token: string): Promise> {\n const r = await this.send('GET',\n this.addEventParameters('/providers/' + providerId + '/users/' + id + '/events', start, end, token),\n null, true, true);\n return new ListResponse(r, EventResponse);\n }\n\n async postEventsCollect(request: EventRequest[]): Promise {\n const authHeader = await this.getActiveBearerToken();\n const headers = new Headers({\n 'Device-Type': this.deviceType,\n 'Authorization': 'Bearer ' + authHeader,\n 'Content-Type': 'application/json; charset=utf-8',\n });\n if (this.customUserAgent != null) {\n headers.set('User-Agent', this.customUserAgent);\n }\n const response = await this.fetch(new Request(this.environmentService.getEventsUrl() + '/collect', {\n cache: 'no-store',\n credentials: this.getCredentials(),\n method: 'POST',\n body: JSON.stringify(request),\n headers: headers,\n }));\n if (response.status !== 200) {\n return Promise.reject('Event post failed.');\n }\n }\n\n // User APIs\n\n async getUserPublicKey(id: string): Promise {\n const r = await this.send('GET', '/users/' + id + '/public-key', null, true, true);\n return new UserKeyResponse(r);\n }\n\n // HIBP APIs\n\n async getHibpBreach(username: string): Promise {\n const r = await this.send('GET', '/hibp/breach?username=' + username, null, true, true);\n return r.map((a: any) => new BreachAccountResponse(a));\n }\n\n // Misc\n\n async postBitPayInvoice(request: BitPayInvoiceRequest): Promise {\n const r = await this.send('POST', '/bitpay-invoice', request, true, true);\n return r as string;\n }\n\n async postSetupPayment(): Promise {\n const r = await this.send('POST', '/setup-payment', null, true, true);\n return r as string;\n }\n\n // Key Connector\n\n async getUserKeyFromKeyConnector(keyConnectorUrl: string): Promise {\n const authHeader = await this.getActiveBearerToken();\n\n const response = await this.fetch(new Request(keyConnectorUrl + '/user-keys', {\n cache: 'no-store',\n method: 'GET',\n headers: new Headers({\n 'Accept': 'application/json',\n 'Authorization': 'Bearer ' + authHeader,\n }),\n }));\n\n if (response.status !== 200) {\n const error = await this.handleError(response, false, true);\n return Promise.reject(error);\n }\n\n return new KeyConnectorUserKeyResponse(await response.json());\n }\n\n async postUserKeyToKeyConnector(keyConnectorUrl: string, request: KeyConnectorUserKeyRequest): Promise {\n const authHeader = await this.getActiveBearerToken();\n\n const response = await this.fetch(new Request(keyConnectorUrl + '/user-keys', {\n cache: 'no-store',\n method: 'POST',\n headers: new Headers({\n 'Accept': 'application/json',\n 'Authorization': 'Bearer ' + authHeader,\n 'Content-Type': 'application/json; charset=utf-8',\n }),\n body: JSON.stringify(request),\n }));\n\n if (response.status !== 200) {\n const error = await this.handleError(response, false, true);\n return Promise.reject(error);\n }\n }\n\n async getKeyConnectorAlive(keyConnectorUrl: string) {\n const response = await this.fetch(new Request(keyConnectorUrl + '/alive', {\n cache: 'no-store',\n method: 'GET',\n headers: new Headers({\n 'Accept': 'application/json',\n 'Content-Type': 'application/json; charset=utf-8',\n }),\n }));\n\n if (response.status !== 200) {\n const error = await this.handleError(response, false, true);\n return Promise.reject(error);\n }\n }\n\n // Helpers\n\n async getActiveBearerToken(): Promise {\n let accessToken = await this.tokenService.getToken();\n if (this.tokenService.tokenNeedsRefresh()) {\n await this.doAuthRefresh();\n accessToken = await this.tokenService.getToken();\n }\n return accessToken;\n }\n\n fetch(request: Request): Promise {\n if (request.method === 'GET') {\n request.headers.set('Cache-Control', 'no-store');\n request.headers.set('Pragma', 'no-cache');\n }\n return this.nativeFetch(request);\n }\n\n nativeFetch(request: Request): Promise {\n return fetch(request);\n }\n\n async preValidateSso(identifier: string): Promise {\n if (identifier == null || identifier === '') {\n throw new Error('Organization Identifier was not provided.');\n }\n const headers = new Headers({\n 'Accept': 'application/json',\n 'Device-Type': this.deviceType,\n });\n if (this.customUserAgent != null) {\n headers.set('User-Agent', this.customUserAgent);\n }\n\n const path = `/account/prevalidate?domainHint=${encodeURIComponent(identifier)}`;\n const response = await this.fetch(new Request(this.environmentService.getIdentityUrl() + path, {\n cache: 'no-store',\n credentials: this.getCredentials(),\n headers: headers,\n method: 'GET',\n }));\n\n if (response.status === 200) {\n return true;\n } else {\n const error = await this.handleError(response, false, true);\n return Promise.reject(error);\n }\n }\n\n async postCreateSponsorship(sponsoredOrgId: string, request: OrganizationSponsorshipCreateRequest): Promise {\n return await this.send('POST',\n '/organization/sponsorship/' + sponsoredOrgId + '/families-for-enterprise',\n request, true, false);\n }\n\n async deleteRevokeSponsorship(sponsoringOrganizationId: string): Promise {\n return await this.send('DELETE',\n '/organization/sponsorship/' + sponsoringOrganizationId,\n null, true, false);\n }\n\n async deleteRemoveSponsorship(sponsoringOrgId: string): Promise {\n return await this.send('DELETE',\n '/organization/sponsorship/sponsored/' + sponsoringOrgId,\n null, true, false);\n }\n\n async postPreValidateSponsorshipToken(sponsorshipToken: string): Promise {\n const r = await this.send('POST', '/organization/sponsorship/validate-token?sponsorshipToken=' + encodeURIComponent(sponsorshipToken),\n null, true, true);\n return r as boolean;\n }\n\n async postRedeemSponsorship(sponsorshipToken: string, request: OrganizationSponsorshipRedeemRequest): Promise {\n return await this.send('POST', '/organization/sponsorship/redeem?sponsorshipToken=' + encodeURIComponent(sponsorshipToken),\n request, true, false);\n }\n\n async postResendSponsorshipOffer(sponsoringOrgId: string): Promise {\n return await this.send('POST',\n '/organization/sponsorship/' + sponsoringOrgId + '/families-for-enterprise/resend',\n null, true, false);\n }\n\n\n protected async doAuthRefresh(): Promise {\n const refreshToken = await this.tokenService.getRefreshToken();\n if (refreshToken != null && refreshToken !== '') {\n return this.doRefreshToken();\n }\n\n const clientId = await this.tokenService.getClientId();\n const clientSecret = await this.tokenService.getClientSecret();\n if (!Utils.isNullOrWhitespace(clientId) && !Utils.isNullOrWhitespace(clientSecret)) {\n return this.doApiTokenRefresh();\n }\n\n throw new Error('Cannot refresh token, no refresh token or api keys are stored');\n }\n\n protected async doApiTokenRefresh(): Promise {\n const clientId = await this.tokenService.getClientId();\n const clientSecret = await this.tokenService.getClientSecret();\n if (Utils.isNullOrWhitespace(clientId) || Utils.isNullOrWhitespace(clientSecret) || this.apiKeyRefresh == null) {\n throw new Error();\n }\n\n await this.apiKeyRefresh(clientId, clientSecret);\n }\n\n protected async doRefreshToken(): Promise {\n const refreshToken = await this.tokenService.getRefreshToken();\n if (refreshToken == null || refreshToken === '') {\n throw new Error();\n }\n const headers = new Headers({\n 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',\n 'Accept': 'application/json',\n 'Device-Type': this.deviceType,\n });\n if (this.customUserAgent != null) {\n headers.set('User-Agent', this.customUserAgent);\n }\n\n const decodedToken = this.tokenService.decodeToken();\n const response = await this.fetch(new Request(this.environmentService.getIdentityUrl() + '/connect/token', {\n body: this.qsStringify({\n grant_type: 'refresh_token',\n client_id: decodedToken.client_id,\n refresh_token: refreshToken,\n }),\n cache: 'no-store',\n credentials: this.getCredentials(),\n headers: headers,\n method: 'POST',\n }));\n\n if (response.status === 200) {\n const responseJson = await response.json();\n const tokenResponse = new IdentityTokenResponse(responseJson);\n await this.tokenService.setTokens(tokenResponse.accessToken, tokenResponse.refreshToken, null);\n } else {\n const error = await this.handleError(response, true, true);\n return Promise.reject(error);\n }\n }\n\n private async send(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, body: any,\n authed: boolean, hasResponse: boolean, apiUrl?: string,\n alterHeaders?: (headers: Headers) => void): Promise {\n apiUrl = Utils.isNullOrWhitespace(apiUrl) ? this.environmentService.getApiUrl() : apiUrl;\n\n const requestUrl = apiUrl + path;\n // Prevent directory traversal from malicious paths\n if (new URL(requestUrl).href !== requestUrl) {\n return Promise.reject('Invalid request url path.');\n }\n\n const headers = new Headers({\n 'Device-Type': this.deviceType,\n });\n if (this.customUserAgent != null) {\n headers.set('User-Agent', this.customUserAgent);\n }\n\n const requestInit: RequestInit = {\n cache: 'no-store',\n credentials: this.getCredentials(),\n method: method,\n };\n\n if (authed) {\n const authHeader = await this.getActiveBearerToken();\n headers.set('Authorization', 'Bearer ' + authHeader);\n }\n if (body != null) {\n if (typeof body === 'string') {\n requestInit.body = body;\n headers.set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');\n } else if (typeof body === 'object') {\n if (body instanceof FormData) {\n requestInit.body = body;\n } else {\n headers.set('Content-Type', 'application/json; charset=utf-8');\n requestInit.body = JSON.stringify(body);\n }\n }\n }\n if (hasResponse) {\n headers.set('Accept', 'application/json');\n }\n if (alterHeaders != null) {\n alterHeaders(headers);\n }\n\n requestInit.headers = headers;\n const response = await this.fetch(new Request(requestUrl, requestInit));\n\n if (hasResponse && response.status === 200) {\n const responseJson = await response.json();\n return responseJson;\n } else if (response.status !== 200) {\n const error = await this.handleError(response, false, authed);\n return Promise.reject(error);\n }\n }\n\n private async handleError(response: Response, tokenError: boolean, authed: boolean): Promise {\n if (authed && ((tokenError && response.status === 400) || response.status === 401 || response.status === 403)) {\n await this.logoutCallback(true);\n return null;\n }\n\n let responseJson: any = null;\n if (this.isJsonResponse(response)) {\n responseJson = await response.json();\n } else if (this.isTextResponse(response)) {\n responseJson = { Message: await response.text() };\n }\n\n return new ErrorResponse(responseJson, response.status, tokenError);\n }\n\n private qsStringify(params: any): string {\n return Object.keys(params).map(key => {\n return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);\n }).join('&');\n }\n\n private getCredentials(): RequestCredentials {\n if (!this.isWebClient || this.environmentService.hasBaseUrl()) {\n return 'include';\n }\n return undefined;\n }\n\n private addEventParameters(base: string, start: string, end: string, token: string) {\n if (start != null) {\n base += ('?start=' + start);\n }\n if (end != null) {\n base += (base.indexOf('?') > -1 ? '&' : '?');\n base += ('end=' + end);\n }\n if (token != null) {\n base += (base.indexOf('?') > -1 ? '&' : '?');\n base += ('continuationToken=' + token);\n }\n return base;\n }\n\n private isJsonResponse(response: Response): boolean {\n const typeHeader = response.headers.get('content-type');\n return typeHeader != null && typeHeader.indexOf('application/json') > -1;\n }\n\n private isTextResponse(response: Response): boolean {\n const typeHeader = response.headers.get('content-type');\n return typeHeader != null && typeHeader.indexOf('text') > -1;\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class ApiKeyResponse extends BaseResponse {\n apiKey: string;\n\n constructor(response: any) {\n super(response);\n this.apiKey = this.getResponseProperty('ApiKey');\n }\n}\n","import { FileUploadType } from '../../enums/fileUploadType';\nimport { BaseResponse } from './baseResponse';\nimport { CipherResponse } from './cipherResponse';\n\nexport class AttachmentUploadDataResponse extends BaseResponse {\n attachmentId: string;\n fileUploadType: FileUploadType;\n cipherResponse: CipherResponse;\n cipherMiniResponse: CipherResponse;\n url: string = null;\n constructor(response: any) {\n super(response);\n this.attachmentId = this.getResponseProperty('AttachmentId');\n this.fileUploadType = this.getResponseProperty('FileUploadType');\n const cipherResponse = this.getResponseProperty('CipherResponse');\n const cipherMiniResponse = this.getResponseProperty('CipherMiniResponse');\n this.cipherResponse = cipherResponse == null ? null : new CipherResponse(cipherResponse);\n this.cipherMiniResponse = cipherMiniResponse == null ? null : new CipherResponse(cipherMiniResponse);\n this.url = this.getResponseProperty('Url');\n }\n\n}\n","import { BaseResponse } from './baseResponse';\n\nimport { PaymentMethodType } from '../../enums/paymentMethodType';\nimport { TransactionType } from '../../enums/transactionType';\n\nexport class BillingResponse extends BaseResponse {\n balance: number;\n paymentSource: BillingSourceResponse;\n invoices: BillingInvoiceResponse[] = [];\n transactions: BillingTransactionResponse[] = [];\n\n constructor(response: any) {\n super(response);\n this.balance = this.getResponseProperty('Balance');\n const paymentSource = this.getResponseProperty('PaymentSource');\n const transactions = this.getResponseProperty('Transactions');\n const invoices = this.getResponseProperty('Invoices');\n this.paymentSource = paymentSource == null ? null : new BillingSourceResponse(paymentSource);\n if (transactions != null) {\n this.transactions = transactions.map((t: any) => new BillingTransactionResponse(t));\n }\n if (invoices != null) {\n this.invoices = invoices.map((i: any) => new BillingInvoiceResponse(i));\n }\n }\n}\n\nexport class BillingSourceResponse extends BaseResponse {\n type: PaymentMethodType;\n cardBrand: string;\n description: string;\n needsVerification: boolean;\n\n constructor(response: any) {\n super(response);\n this.type = this.getResponseProperty('Type');\n this.cardBrand = this.getResponseProperty('CardBrand');\n this.description = this.getResponseProperty('Description');\n this.needsVerification = this.getResponseProperty('NeedsVerification');\n }\n}\n\nexport class BillingInvoiceResponse extends BaseResponse {\n url: string;\n pdfUrl: string;\n number: string;\n paid: boolean;\n date: string;\n amount: number;\n\n constructor(response: any) {\n super(response);\n this.url = this.getResponseProperty('Url');\n this.pdfUrl = this.getResponseProperty('PdfUrl');\n this.number = this.getResponseProperty('Number');\n this.paid = this.getResponseProperty('Paid');\n this.date = this.getResponseProperty('Date');\n this.amount = this.getResponseProperty('Amount');\n }\n}\n\nexport class BillingTransactionResponse extends BaseResponse {\n createdDate: string;\n amount: number;\n refunded: boolean;\n partiallyRefunded: boolean;\n refundedAmount: number;\n type: TransactionType;\n paymentMethodType: PaymentMethodType;\n details: string;\n\n constructor(response: any) {\n super(response);\n this.createdDate = this.getResponseProperty('CreatedDate');\n this.amount = this.getResponseProperty('Amount');\n this.refunded = this.getResponseProperty('Refunded');\n this.partiallyRefunded = this.getResponseProperty('PartiallyRefunded');\n this.refundedAmount = this.getResponseProperty('RefundedAmount');\n this.type = this.getResponseProperty('Type');\n this.paymentMethodType = this.getResponseProperty('PaymentMethodType');\n this.details = this.getResponseProperty('Details');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class BreachAccountResponse extends BaseResponse {\n addedDate: string;\n breachDate: string;\n dataClasses: string[];\n description: string;\n domain: string;\n isActive: boolean;\n isVerified: boolean;\n logoPath: string;\n modifiedDate: string;\n name: string;\n pwnCount: number;\n title: string;\n\n constructor(response: any) {\n super(response);\n this.addedDate = this.getResponseProperty('AddedDate');\n this.breachDate = this.getResponseProperty('BreachDate');\n this.dataClasses = this.getResponseProperty('DataClasses');\n this.description = this.getResponseProperty('Description');\n this.domain = this.getResponseProperty('Domain');\n this.isActive = this.getResponseProperty('IsActive');\n this.isVerified = this.getResponseProperty('IsVerified');\n this.logoPath = this.getResponseProperty('LogoPath');\n this.modifiedDate = this.getResponseProperty('ModifiedDate');\n this.name = this.getResponseProperty('Name');\n this.pwnCount = this.getResponseProperty('PwnCount');\n this.title = this.getResponseProperty('Title');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class GlobalDomainResponse extends BaseResponse {\n type: number;\n domains: string[];\n excluded: boolean;\n\n constructor(response: any) {\n super(response);\n this.type = this.getResponseProperty('Type');\n this.domains = this.getResponseProperty('Domains');\n this.excluded = this.getResponseProperty('Excluded');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nimport { DeviceType } from '../../enums/deviceType';\nimport { EventType } from '../../enums/eventType';\n\nexport class EventResponse extends BaseResponse {\n type: EventType;\n userId: string;\n organizationId: string;\n providerId: string;\n cipherId: string;\n collectionId: string;\n groupId: string;\n policyId: string;\n organizationUserId: string;\n providerUserId: string;\n providerOrganizationId: string;\n actingUserId: string;\n date: string;\n deviceType: DeviceType;\n ipAddress: string;\n\n constructor(response: any) {\n super(response);\n this.type = this.getResponseProperty('Type');\n this.userId = this.getResponseProperty('UserId');\n this.organizationId = this.getResponseProperty('OrganizationId');\n this.providerId = this.getResponseProperty('ProviderId');\n this.cipherId = this.getResponseProperty('CipherId');\n this.collectionId = this.getResponseProperty('CollectionId');\n this.groupId = this.getResponseProperty('GroupId');\n this.policyId = this.getResponseProperty('PolicyId');\n this.organizationUserId = this.getResponseProperty('OrganizationUserId');\n this.providerUserId = this.getResponseProperty('ProviderUserId');\n this.providerOrganizationId = this.getResponseProperty('ProviderOrganizationId');\n this.actingUserId = this.getResponseProperty('ActingUserId');\n this.date = this.getResponseProperty('Date');\n this.deviceType = this.getResponseProperty('DeviceType');\n this.ipAddress = this.getResponseProperty('IpAddress');\n }\n}\n","import { BaseResponse } from './baseResponse';\nimport { SelectionReadOnlyResponse } from './selectionReadOnlyResponse';\n\nexport class GroupResponse extends BaseResponse {\n id: string;\n organizationId: string;\n name: string;\n accessAll: boolean;\n externalId: string;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.organizationId = this.getResponseProperty('OrganizationId');\n this.name = this.getResponseProperty('Name');\n this.accessAll = this.getResponseProperty('AccessAll');\n this.externalId = this.getResponseProperty('ExternalId');\n }\n}\n\nexport class GroupDetailsResponse extends GroupResponse {\n collections: SelectionReadOnlyResponse[] = [];\n\n constructor(response: any) {\n super(response);\n const collections = this.getResponseProperty('Collections');\n if (collections != null) {\n this.collections = collections.map((c: any) => new SelectionReadOnlyResponse(c));\n }\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class IdentityCaptchaResponse extends BaseResponse {\n siteKey: string;\n\n constructor(response: any) {\n super(response);\n this.siteKey = this.getResponseProperty('HCaptcha_SiteKey');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nimport { KdfType } from '../../enums/kdfType';\n\nexport class IdentityTokenResponse extends BaseResponse {\n accessToken: string;\n expiresIn: number;\n refreshToken: string;\n tokenType: string;\n\n resetMasterPassword: boolean;\n privateKey: string;\n key: string;\n twoFactorToken: string;\n kdf: KdfType;\n kdfIterations: number;\n forcePasswordReset: boolean;\n apiUseKeyConnector: boolean;\n keyConnectorUrl: string;\n\n constructor(response: any) {\n super(response);\n this.accessToken = response.access_token;\n this.expiresIn = response.expires_in;\n this.refreshToken = response.refresh_token;\n this.tokenType = response.token_type;\n\n this.resetMasterPassword = this.getResponseProperty('ResetMasterPassword');\n this.privateKey = this.getResponseProperty('PrivateKey');\n this.key = this.getResponseProperty('Key');\n this.twoFactorToken = this.getResponseProperty('TwoFactorToken');\n this.kdf = this.getResponseProperty('Kdf');\n this.kdfIterations = this.getResponseProperty('KdfIterations');\n this.forcePasswordReset = this.getResponseProperty('ForcePasswordReset');\n this.apiUseKeyConnector = this.getResponseProperty('ApiUseKeyConnector');\n this.keyConnectorUrl = this.getResponseProperty('KeyConnectorUrl');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nimport { TwoFactorProviderType } from '../../enums/twoFactorProviderType';\n\nexport class IdentityTwoFactorResponse extends BaseResponse {\n twoFactorProviders: TwoFactorProviderType[];\n twoFactorProviders2 = new Map();\n captchaToken: string;\n\n constructor(response: any) {\n super(response);\n this.captchaToken = this.getResponseProperty('CaptchaBypassToken');\n this.twoFactorProviders = this.getResponseProperty('TwoFactorProviders');\n const twoFactorProviders2 = this.getResponseProperty('TwoFactorProviders2');\n if (twoFactorProviders2 != null) {\n for (const prop in twoFactorProviders2) {\n if (twoFactorProviders2.hasOwnProperty(prop)) {\n this.twoFactorProviders2.set(parseInt(prop, null), twoFactorProviders2[prop]);\n }\n }\n }\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class ListResponse extends BaseResponse {\n data: T[];\n continuationToken: string;\n\n constructor(response: any, t: new (dataResponse: any) => T) {\n super(response);\n const data = this.getResponseProperty('Data');\n this.data = data == null ? [] : data.map((dr: any) => new t(dr));\n this.continuationToken = this.getResponseProperty('ContinuationToken');\n }\n}\n","import { SsoConfigApi } from '../../api/ssoConfigApi';\nimport { BaseResponse } from '../baseResponse';\n\nexport class OrganizationSsoResponse extends BaseResponse {\n enabled: boolean;\n data: SsoConfigApi;\n urls: SsoUrls;\n\n constructor(response: any) {\n super(response);\n this.enabled = this.getResponseProperty('Enabled');\n this.data = new SsoConfigApi(this.getResponseProperty('Data'));\n this.urls = new SsoUrls(this.getResponseProperty('Urls'));\n }\n}\n\nclass SsoUrls extends BaseResponse {\n callbackPath: string;\n signedOutCallbackPath: string;\n spEntityId: string;\n spMetadataUrl: string;\n spAcsUrl: string;\n\n constructor(response: any) {\n super(response);\n this.callbackPath = this.getResponseProperty('CallbackPath');\n this.signedOutCallbackPath = this.getResponseProperty('SignedOutCallbackPath');\n this.spEntityId = this.getResponseProperty('SpEntityId');\n this.spMetadataUrl = this.getResponseProperty('SpMetadataUrl');\n this.spAcsUrl = this.getResponseProperty('SpAcsUrl');\n }\n}\n","import { BaseResponse } from '../response/baseResponse';\n\nenum SsoType {\n OpenIdConnect = 1,\n Saml2 = 2,\n}\n\nenum OpenIdConnectRedirectBehavior {\n RedirectGet = 0,\n FormPost = 1,\n}\n\nenum Saml2BindingType {\n HttpRedirect = 1,\n HttpPost = 2,\n Artifact = 4,\n}\n\nenum Saml2NameIdFormat {\n NotConfigured = 0,\n Unspecified = 1,\n EmailAddress = 2,\n X509SubjectName = 3,\n WindowsDomainQualifiedName = 4,\n KerberosPrincipalName = 5,\n EntityIdentifier = 6,\n Persistent = 7,\n Transient = 8,\n}\n\nenum Saml2SigningBehavior {\n IfIdpWantAuthnRequestsSigned = 0,\n Always = 1,\n Never = 3,\n}\n\nexport class SsoConfigApi extends BaseResponse {\n configType: SsoType;\n\n keyConnectorEnabled: boolean;\n keyConnectorUrl: string;\n\n // OpenId\n authority: string;\n clientId: string;\n clientSecret: string;\n metadataAddress: string;\n redirectBehavior: OpenIdConnectRedirectBehavior;\n getClaimsFromUserInfoEndpoint: boolean;\n additionalScopes: string;\n additionalUserIdClaimTypes: string;\n additionalEmailClaimTypes: string;\n additionalNameClaimTypes: string;\n acrValues: string;\n expectedReturnAcrValue: string;\n\n // SAML\n spNameIdFormat: Saml2NameIdFormat;\n spOutboundSigningAlgorithm: string;\n spSigningBehavior: Saml2SigningBehavior;\n spMinIncomingSigningAlgorithm: boolean;\n spWantAssertionsSigned: boolean;\n spValidateCertificates: boolean;\n\n idpEntityId: string;\n idpBindingType: Saml2BindingType;\n idpSingleSignOnServiceUrl: string;\n idpSingleLogoutServiceUrl: string;\n idpArtifactResolutionServiceUrl: string;\n idpX509PublicCert: string;\n idpOutboundSigningAlgorithm: string;\n idpAllowUnsolicitedAuthnResponse: boolean;\n idpDisableOutboundLogoutRequests: boolean;\n idpWantAuthnRequestsSigned: boolean;\n\n constructor(data: any = null) {\n super(data);\n if (data == null) {\n return;\n }\n\n this.configType = this.getResponseProperty('ConfigType');\n\n this.keyConnectorEnabled = this.getResponseProperty('KeyConnectorEnabled');\n this.keyConnectorUrl = this.getResponseProperty('KeyConnectorUrl');\n\n this.authority = this.getResponseProperty('Authority');\n this.clientId = this.getResponseProperty('ClientId');\n this.clientSecret = this.getResponseProperty('ClientSecret');\n this.metadataAddress = this.getResponseProperty('MetadataAddress');\n this.redirectBehavior = this.getResponseProperty('RedirectBehavior');\n this.getClaimsFromUserInfoEndpoint = this.getResponseProperty('GetClaimsFromUserInfoEndpoint');\n this.additionalScopes = this.getResponseProperty('AdditionalScopes');\n this.additionalUserIdClaimTypes = this.getResponseProperty('AdditionalUserIdClaimTypes');\n this.additionalEmailClaimTypes = this.getResponseProperty('AdditionalEmailClaimTypes');\n this.additionalNameClaimTypes = this.getResponseProperty('AdditionalNameClaimTypes');\n this.acrValues = this.getResponseProperty('AcrValues');\n this.expectedReturnAcrValue = this.getResponseProperty('ExpectedReturnAcrValue');\n\n this.spNameIdFormat = this.getResponseProperty('SpNameIdFormat');\n this.spOutboundSigningAlgorithm = this.getResponseProperty('SpOutboundSigningAlgorithm');\n this.spSigningBehavior = this.getResponseProperty('SpSigningBehavior');\n this.spMinIncomingSigningAlgorithm = this.getResponseProperty('SpMinIncomingSigningAlgorithm');\n this.spWantAssertionsSigned = this.getResponseProperty('SpWantAssertionsSigned');\n this.spValidateCertificates = this.getResponseProperty('SpValidateCertificates');\n\n this.idpEntityId = this.getResponseProperty('IdpEntityId');\n this.idpBindingType = this.getResponseProperty('IdpBindingType');\n this.idpSingleSignOnServiceUrl = this.getResponseProperty('IdpSingleSignOnServiceUrl');\n this.idpSingleLogoutServiceUrl = this.getResponseProperty('IdpSingleLogoutServiceUrl');\n this.idpArtifactResolutionServiceUrl = this.getResponseProperty('IdpArtifactResolutionServiceUrl');\n this.idpX509PublicCert = this.getResponseProperty('IdpX509PublicCert');\n this.idpOutboundSigningAlgorithm = this.getResponseProperty('IdpOutboundSigningAlgorithm');\n this.idpAllowUnsolicitedAuthnResponse = this.getResponseProperty('IdpAllowUnsolicitedAuthnResponse');\n this.idpDisableOutboundLogoutRequests = this.getResponseProperty('IdpDisableOutboundLogoutRequests');\n this.idpWantAuthnRequestsSigned = this.getResponseProperty('IdpWantAuthnRequestsSigned');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class OrganizationAutoEnrollStatusResponse extends BaseResponse {\n id: string;\n resetPasswordEnabled: boolean;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.resetPasswordEnabled = this.getResponseProperty('ResetPasswordEnabled');\n }\n}\n","import { KeysResponse } from './keysResponse';\n\nexport class OrganizationKeysResponse extends KeysResponse {\n constructor(response: any) {\n super(response);\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class KeysResponse extends BaseResponse {\n privateKey: string;\n publicKey: string;\n\n constructor(response: any) {\n super(response);\n this.privateKey = this.getResponseProperty('PrivateKey');\n this.publicKey = this.getResponseProperty('PublicKey');\n }\n}\n","import { OrganizationResponse } from './organizationResponse';\nimport {\n BillingSubscriptionResponse,\n BillingSubscriptionUpcomingInvoiceResponse,\n} from './subscriptionResponse';\n\nexport class OrganizationSubscriptionResponse extends OrganizationResponse {\n storageName: string;\n storageGb: number;\n subscription: BillingSubscriptionResponse;\n upcomingInvoice: BillingSubscriptionUpcomingInvoiceResponse;\n expiration: string;\n\n constructor(response: any) {\n super(response);\n this.storageName = this.getResponseProperty('StorageName');\n this.storageGb = this.getResponseProperty('StorageGb');\n const subscription = this.getResponseProperty('Subscription');\n this.subscription = subscription == null ? null : new BillingSubscriptionResponse(subscription);\n const upcomingInvoice = this.getResponseProperty('UpcomingInvoice');\n this.upcomingInvoice = upcomingInvoice == null ? null :\n new BillingSubscriptionUpcomingInvoiceResponse(upcomingInvoice);\n this.expiration = this.getResponseProperty('Expiration');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class OrganizationUserBulkResponse extends BaseResponse {\n id: string;\n error: string;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.error = this.getResponseProperty('Error');\n }\n}\n","import { BaseResponse } from './baseResponse';\nimport { SelectionReadOnlyResponse } from './selectionReadOnlyResponse';\n\nimport { PermissionsApi } from '../api/permissionsApi';\n\nimport { KdfType } from '../../enums/kdfType';\nimport { OrganizationUserStatusType } from '../../enums/organizationUserStatusType';\nimport { OrganizationUserType } from '../../enums/organizationUserType';\n\nexport class OrganizationUserResponse extends BaseResponse {\n id: string;\n userId: string;\n type: OrganizationUserType;\n status: OrganizationUserStatusType;\n accessAll: boolean;\n permissions: PermissionsApi;\n resetPasswordEnrolled: boolean;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.userId = this.getResponseProperty('UserId');\n this.type = this.getResponseProperty('Type');\n this.status = this.getResponseProperty('Status');\n this.permissions = new PermissionsApi(this.getResponseProperty('Permissions'));\n this.accessAll = this.getResponseProperty('AccessAll');\n this.resetPasswordEnrolled = this.getResponseProperty('ResetPasswordEnrolled');\n }\n}\n\nexport class OrganizationUserUserDetailsResponse extends OrganizationUserResponse {\n name: string;\n email: string;\n twoFactorEnabled: boolean;\n usesKeyConnector: boolean;\n\n constructor(response: any) {\n super(response);\n this.name = this.getResponseProperty('Name');\n this.email = this.getResponseProperty('Email');\n this.twoFactorEnabled = this.getResponseProperty('TwoFactorEnabled');\n this.usesKeyConnector = this.getResponseProperty('UsesKeyConnector') ?? false;\n }\n}\n\nexport class OrganizationUserDetailsResponse extends OrganizationUserResponse {\n collections: SelectionReadOnlyResponse[] = [];\n\n constructor(response: any) {\n super(response);\n const collections = this.getResponseProperty('Collections');\n if (collections != null) {\n this.collections = collections.map((c: any) => new SelectionReadOnlyResponse(c));\n }\n }\n}\n\nexport class OrganizationUserResetPasswordDetailsReponse extends BaseResponse {\n kdf: KdfType;\n kdfIterations: number;\n resetPasswordKey: string;\n encryptedPrivateKey: string;\n\n constructor(response: any) {\n super(response);\n this.kdf = this.getResponseProperty('Kdf');\n this.kdfIterations = this.getResponseProperty('KdfIterations');\n this.resetPasswordKey = this.getResponseProperty('ResetPasswordKey');\n this.encryptedPrivateKey = this.getResponseProperty('EncryptedPrivateKey');\n }\n}\n","import { BaseResponse } from './baseResponse';\nimport { ProfileResponse } from './profileResponse';\n\nexport class PaymentResponse extends BaseResponse {\n userProfile: ProfileResponse;\n paymentIntentClientSecret: string;\n success: boolean;\n\n constructor(response: any) {\n super(response);\n const userProfile = this.getResponseProperty('UserProfile');\n if (userProfile != null) {\n this.userProfile = new ProfileResponse(userProfile);\n }\n this.paymentIntentClientSecret = this.getResponseProperty('PaymentIntentClientSecret');\n this.success = this.getResponseProperty('Success');\n }\n}\n","import { ProfileOrganizationResponse } from './profileOrganizationResponse';\n\nexport class ProfileProviderOrganizationResponse extends ProfileOrganizationResponse {\n constructor(response: any) {\n super(response);\n this.keyConnectorEnabled = false;\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nimport { ProviderUserStatusType } from '../../enums/providerUserStatusType';\nimport { ProviderUserType } from '../../enums/providerUserType';\n\nimport { PermissionsApi } from '../api/permissionsApi';\n\nexport class ProfileProviderResponse extends BaseResponse {\n id: string;\n name: string;\n key: string;\n status: ProviderUserStatusType;\n type: ProviderUserType;\n enabled: boolean;\n permissions: PermissionsApi;\n userId: string;\n useEvents: boolean;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.name = this.getResponseProperty('Name');\n this.key = this.getResponseProperty('Key');\n this.status = this.getResponseProperty('Status');\n this.type = this.getResponseProperty('Type');\n this.enabled = this.getResponseProperty('Enabled');\n this.permissions = new PermissionsApi(this.getResponseProperty('permissions'));\n this.userId = this.getResponseProperty('UserId');\n this.useEvents = this.getResponseProperty('UseEvents');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nimport { KdfType } from '../../enums/kdfType';\n\nexport class PreloginResponse extends BaseResponse {\n kdf: KdfType;\n kdfIterations: number;\n\n constructor(response: any) {\n super(response);\n this.kdf = this.getResponseProperty('Kdf');\n this.kdfIterations = this.getResponseProperty('KdfIterations');\n }\n}\n","import { BaseResponse } from '../baseResponse';\n\nexport class ProviderOrganizationResponse extends BaseResponse {\n id: string;\n providerId: string;\n organizationId: string;\n key: string;\n settings: string;\n creationDate: string;\n revisionDate: string;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.providerId = this.getResponseProperty('ProviderId');\n this.organizationId = this.getResponseProperty('OrganizationId');\n this.key = this.getResponseProperty('Key');\n this.settings = this.getResponseProperty('Settings');\n this.creationDate = this.getResponseProperty('CreationDate');\n this.revisionDate = this.getResponseProperty('RevisionDate');\n }\n}\n\nexport class ProviderOrganizationOrganizationDetailsResponse extends ProviderOrganizationResponse {\n organizationName: string;\n\n constructor(response: any) {\n super(response);\n this.organizationName = this.getResponseProperty('OrganizationName');\n }\n}\n","import { BaseResponse } from '../baseResponse';\n\nexport class ProviderResponse extends BaseResponse {\n id: string;\n name: string;\n businessName: string;\n billingEmail: string;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.name = this.getResponseProperty('Name');\n this.businessName = this.getResponseProperty('BusinessName');\n this.billingEmail = this.getResponseProperty('BillingEmail');\n }\n}\n","import { OrganizationUserBulkPublicKeyResponse } from '../organizationUserBulkPublicKeyResponse';\n\nexport class ProviderUserBulkPublicKeyResponse extends OrganizationUserBulkPublicKeyResponse {\n\n}\n","import { BaseResponse } from '../baseResponse';\n\nexport class ProviderUserBulkResponse extends BaseResponse {\n id: string;\n error: string;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.error = this.getResponseProperty('Error');\n }\n}\n","import { BaseResponse } from '../baseResponse';\n\nimport { PermissionsApi } from '../../api/permissionsApi';\n\nimport { ProviderUserStatusType } from '../../../enums/providerUserStatusType';\nimport { ProviderUserType } from '../../../enums/providerUserType';\n\nexport class ProviderUserResponse extends BaseResponse {\n id: string;\n userId: string;\n type: ProviderUserType;\n status: ProviderUserStatusType;\n permissions: PermissionsApi;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.userId = this.getResponseProperty('UserId');\n this.type = this.getResponseProperty('Type');\n this.status = this.getResponseProperty('Status');\n this.permissions = new PermissionsApi(this.getResponseProperty('Permissions'));\n }\n}\n\nexport class ProviderUserUserDetailsResponse extends ProviderUserResponse {\n name: string;\n email: string;\n\n constructor(response: any) {\n super(response);\n this.name = this.getResponseProperty('Name');\n this.email = this.getResponseProperty('Email');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nimport { SendType } from '../../enums/sendType';\n\nimport { SendFileApi } from '../api/sendFileApi';\nimport { SendTextApi } from '../api/sendTextApi';\n\nexport class SendAccessResponse extends BaseResponse {\n id: string;\n type: SendType;\n name: string;\n file: SendFileApi;\n text: SendTextApi;\n expirationDate: Date;\n creatorIdentifier: string;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.type = this.getResponseProperty('Type');\n this.name = this.getResponseProperty('Name');\n\n const text = this.getResponseProperty('Text');\n if (text != null) {\n this.text = new SendTextApi(text);\n }\n\n const file = this.getResponseProperty('File');\n if (file != null) {\n this.file = new SendFileApi(file);\n }\n\n this.expirationDate = this.getResponseProperty('ExpirationDate');\n this.creatorIdentifier = this.getResponseProperty('CreatorIdentifier');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class SendFileDownloadDataResponse extends BaseResponse {\n\n id: string = null;\n url: string = null;\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.url = this.getResponseProperty('Url');\n }\n}\n","import { FileUploadType } from '../../enums/fileUploadType';\n\nimport { BaseResponse } from './baseResponse';\nimport { SendResponse } from './sendResponse';\n\nexport class SendFileUploadDataResponse extends BaseResponse {\n\n fileUploadType: FileUploadType;\n sendResponse: SendResponse;\n url: string = null;\n constructor(response: any) {\n super(response);\n this.fileUploadType = this.getResponseProperty('FileUploadType');\n const sendResponse = this.getResponseProperty('SendResponse');\n this.sendResponse = sendResponse == null ? null : new SendResponse(sendResponse);\n this.url = this.getResponseProperty('Url');\n }\n}\n","import { BaseResponse } from './baseResponse';\nimport { CipherResponse } from './cipherResponse';\nimport { CollectionDetailsResponse } from './collectionResponse';\nimport { DomainsResponse } from './domainsResponse';\nimport { FolderResponse } from './folderResponse';\nimport { PolicyResponse } from './policyResponse';\nimport { ProfileResponse } from './profileResponse';\nimport { SendResponse } from './sendResponse';\n\nexport class SyncResponse extends BaseResponse {\n profile?: ProfileResponse;\n folders: FolderResponse[] = [];\n collections: CollectionDetailsResponse[] = [];\n ciphers: CipherResponse[] = [];\n domains?: DomainsResponse;\n policies?: PolicyResponse[] = [];\n sends: SendResponse[] = [];\n\n constructor(response: any) {\n super(response);\n\n const profile = this.getResponseProperty('Profile');\n if (profile != null) {\n this.profile = new ProfileResponse(profile);\n }\n\n const folders = this.getResponseProperty('Folders');\n if (folders != null) {\n this.folders = folders.map((f: any) => new FolderResponse(f));\n }\n\n const collections = this.getResponseProperty('Collections');\n if (collections != null) {\n this.collections = collections.map((c: any) => new CollectionDetailsResponse(c));\n }\n\n const ciphers = this.getResponseProperty('Ciphers');\n if (ciphers != null) {\n this.ciphers = ciphers.map((c: any) => new CipherResponse(c));\n }\n\n const domains = this.getResponseProperty('Domains');\n if (domains != null) {\n this.domains = new DomainsResponse(domains);\n }\n\n const policies = this.getResponseProperty('Policies');\n if (policies != null) {\n this.policies = policies.map((p: any) => new PolicyResponse(p));\n }\n\n const sends = this.getResponseProperty('Sends');\n if (sends != null) {\n this.sends = sends.map((s: any) => new SendResponse(s));\n }\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class TaxInfoResponse extends BaseResponse {\n taxId: string;\n taxIdType: string;\n line1: string;\n line2: string;\n city: string;\n state: string;\n country: string;\n postalCode: string;\n\n constructor(response: any) {\n super(response);\n this.taxId = this.getResponseProperty('TaxIdNumber');\n this.taxIdType = this.getResponseProperty('TaxIdType');\n this.line1 = this.getResponseProperty('Line1');\n this.line2 = this.getResponseProperty('Line2');\n this.city = this.getResponseProperty('City');\n this.state = this.getResponseProperty('State');\n this.postalCode = this.getResponseProperty('PostalCode');\n this.country = this.getResponseProperty('Country');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class TaxRateResponse extends BaseResponse {\n id: string;\n country: string;\n state: string;\n postalCode: string;\n rate: number;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.country = this.getResponseProperty('Country');\n this.state = this.getResponseProperty('State');\n this.postalCode = this.getResponseProperty('PostalCode');\n this.rate = this.getResponseProperty('Rate');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class TwoFactorAuthenticatorResponse extends BaseResponse {\n enabled: boolean;\n key: string;\n\n constructor(response: any) {\n super(response);\n this.enabled = this.getResponseProperty('Enabled');\n this.key = this.getResponseProperty('Key');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class TwoFactorDuoResponse extends BaseResponse {\n enabled: boolean;\n host: string;\n secretKey: string;\n integrationKey: string;\n\n constructor(response: any) {\n super(response);\n this.enabled = this.getResponseProperty('Enabled');\n this.host = this.getResponseProperty('Host');\n this.secretKey = this.getResponseProperty('SecretKey');\n this.integrationKey = this.getResponseProperty('IntegrationKey');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class TwoFactorEmailResponse extends BaseResponse {\n enabled: boolean;\n email: string;\n\n constructor(response: any) {\n super(response);\n this.enabled = this.getResponseProperty('Enabled');\n this.email = this.getResponseProperty('Email');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nimport { TwoFactorProviderType } from '../../enums/twoFactorProviderType';\n\nexport class TwoFactorProviderResponse extends BaseResponse {\n enabled: boolean;\n type: TwoFactorProviderType;\n\n constructor(response: any) {\n super(response);\n this.enabled = this.getResponseProperty('Enabled');\n this.type = this.getResponseProperty('Type');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class TwoFactorRecoverResponse extends BaseResponse {\n code: string;\n\n constructor(response: any) {\n super(response);\n this.code = this.getResponseProperty('Code');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class TwoFactorYubiKeyResponse extends BaseResponse {\n enabled: boolean;\n key1: string;\n key2: string;\n key3: string;\n key4: string;\n key5: string;\n nfc: boolean;\n\n constructor(response: any) {\n super(response);\n this.enabled = this.getResponseProperty('Enabled');\n this.key1 = this.getResponseProperty('Key1');\n this.key2 = this.getResponseProperty('Key2');\n this.key3 = this.getResponseProperty('Key3');\n this.key4 = this.getResponseProperty('Key4');\n this.key5 = this.getResponseProperty('Key5');\n this.nfc = this.getResponseProperty('Nfc');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class UserKeyResponse extends BaseResponse {\n userId: string;\n publicKey: string;\n\n constructor(response: any) {\n super(response);\n this.userId = this.getResponseProperty('UserId');\n this.publicKey = this.getResponseProperty('PublicKey');\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nexport class KeyConnectorUserKeyResponse extends BaseResponse {\n key: string;\n\n constructor(response: any) {\n super(response);\n this.key = this.getResponseProperty('Key');\n }\n}\n","import { Utils } from '../misc/utils';\n\nimport { AppIdService as AppIdServiceAbstraction } from '../abstractions/appId.service';\nimport { StorageService } from '../abstractions/storage.service';\n\nexport class AppIdService implements AppIdServiceAbstraction {\n constructor(private storageService: StorageService) {\n }\n\n getAppId(): Promise {\n return this.makeAndGetAppId('appId');\n }\n\n getAnonymousAppId(): Promise {\n return this.makeAndGetAppId('anonymousAppId');\n }\n\n private async makeAndGetAppId(key: string) {\n const existingId = await this.storageService.get(key);\n if (existingId != null) {\n return existingId;\n }\n\n const guid = Utils.newGuid();\n await this.storageService.save(key, guid);\n return guid;\n }\n}\n","import { ApiService } from '../abstractions/api.service';\nimport { AuditService as AuditServiceAbstraction } from '../abstractions/audit.service';\nimport { CryptoFunctionService } from '../abstractions/cryptoFunction.service';\n\nimport { throttle } from '../misc/throttle';\nimport { Utils } from '../misc/utils';\n\nimport { BreachAccountResponse } from '../models/response/breachAccountResponse';\nimport { ErrorResponse } from '../models/response/errorResponse';\n\nconst PwnedPasswordsApi = 'https://api.pwnedpasswords.com/range/';\n\nexport class AuditService implements AuditServiceAbstraction {\n constructor(private cryptoFunctionService: CryptoFunctionService, private apiService: ApiService) { }\n\n @throttle(100, () => 'passwordLeaked')\n async passwordLeaked(password: string): Promise {\n const hashBytes = await this.cryptoFunctionService.hash(password, 'sha1');\n const hash = Utils.fromBufferToHex(hashBytes).toUpperCase();\n const hashStart = hash.substr(0, 5);\n const hashEnding = hash.substr(5);\n\n const response = await this.apiService.nativeFetch(new Request(PwnedPasswordsApi + hashStart));\n const leakedHashes = await response.text();\n const match = leakedHashes.split(/\\r?\\n/).find(v => {\n return v.split(':')[0] === hashEnding;\n });\n\n return match != null ? parseInt(match.split(':')[1], 10) : 0;\n }\n\n async breachedAccounts(username: string): Promise {\n try {\n return await this.apiService.getHibpBreach(username);\n } catch (e) {\n const error = e as ErrorResponse;\n if (error.statusCode === 404) {\n return [];\n }\n throw new Error();\n }\n }\n}\n","/**\n * Use as a Decorator on async functions, it will limit how many times the function can be\n * in-flight at a time.\n *\n * Calls beyond the limit will be queued, and run when one of the active calls finishes\n */\nexport function throttle(limit: number, throttleKey: (args: any[]) => string) {\n return (target: any, propertyKey: string | symbol,\n descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise>) => {\n const originalMethod: () => Promise = descriptor.value;\n const allThrottles = new Map void)[]>>();\n\n const getThrottles = (obj: any) => {\n let throttles = allThrottles.get(obj);\n if (throttles != null) {\n return throttles;\n }\n throttles = new Map void)[]>();\n allThrottles.set(obj, throttles);\n return throttles;\n };\n\n return {\n value: function(...args: any[]) {\n const throttles = getThrottles(this);\n const argsThrottleKey = throttleKey(args);\n let queue = throttles.get(argsThrottleKey);\n if (queue == null) {\n queue = [];\n throttles.set(argsThrottleKey, queue);\n }\n\n return new Promise((resolve, reject) => {\n const exec = () => {\n const onFinally = () => {\n queue.splice(queue.indexOf(exec), 1);\n if (queue.length >= limit) {\n queue[limit - 1]();\n } else if (queue.length === 0) {\n throttles.delete(argsThrottleKey);\n if (throttles.size === 0) {\n allThrottles.delete(this);\n }\n }\n };\n originalMethod.apply(this, args).then((val: any) => {\n onFinally();\n return val;\n }).catch((err: any) => {\n onFinally();\n throw err;\n }).then(resolve, reject);\n };\n queue.push(exec);\n if (queue.length <= limit) {\n exec();\n }\n });\n },\n };\n };\n}\n","import { CipherType } from '../enums/cipherType';\nimport { FieldType } from '../enums/fieldType';\nimport { UriMatchType } from '../enums/uriMatchType';\n\nimport { CipherData } from '../models/data/cipherData';\n\nimport { Attachment } from '../models/domain/attachment';\nimport { Card } from '../models/domain/card';\nimport { Cipher } from '../models/domain/cipher';\nimport Domain from '../models/domain/domainBase';\nimport { EncArrayBuffer } from '../models/domain/encArrayBuffer';\nimport { EncString } from '../models/domain/encString';\nimport { Field } from '../models/domain/field';\nimport { Identity } from '../models/domain/identity';\nimport { Login } from '../models/domain/login';\nimport { LoginUri } from '../models/domain/loginUri';\nimport { Password } from '../models/domain/password';\nimport { SecureNote } from '../models/domain/secureNote';\nimport { SymmetricCryptoKey } from '../models/domain/symmetricCryptoKey';\n\nimport { AttachmentRequest } from '../models/request/attachmentRequest';\nimport { CipherBulkDeleteRequest } from '../models/request/cipherBulkDeleteRequest';\nimport { CipherBulkMoveRequest } from '../models/request/cipherBulkMoveRequest';\nimport { CipherBulkRestoreRequest } from '../models/request/cipherBulkRestoreRequest';\nimport { CipherBulkShareRequest } from '../models/request/cipherBulkShareRequest';\nimport { CipherCollectionsRequest } from '../models/request/cipherCollectionsRequest';\nimport { CipherCreateRequest } from '../models/request/cipherCreateRequest';\nimport { CipherRequest } from '../models/request/cipherRequest';\nimport { CipherShareRequest } from '../models/request/cipherShareRequest';\n\nimport { CipherResponse } from '../models/response/cipherResponse';\nimport { ErrorResponse } from '../models/response/errorResponse';\n\nimport { AttachmentView } from '../models/view/attachmentView';\nimport { CipherView } from '../models/view/cipherView';\nimport { FieldView } from '../models/view/fieldView';\nimport { PasswordHistoryView } from '../models/view/passwordHistoryView';\nimport { View } from '../models/view/view';\n\nimport { SortedCiphersCache } from '../models/domain/sortedCiphersCache';\n\nimport { ApiService } from '../abstractions/api.service';\nimport { CipherService as CipherServiceAbstraction } from '../abstractions/cipher.service';\nimport { CryptoService } from '../abstractions/crypto.service';\nimport { FileUploadService } from '../abstractions/fileUpload.service';\nimport { I18nService } from '../abstractions/i18n.service';\nimport { SearchService } from '../abstractions/search.service';\nimport { SettingsService } from '../abstractions/settings.service';\nimport { StorageService } from '../abstractions/storage.service';\nimport { UserService } from '../abstractions/user.service';\n\nimport { ConstantsService } from './constants.service';\n\nimport { LogService } from '../abstractions/log.service';\nimport { sequentialize } from '../misc/sequentialize';\nimport { Utils } from '../misc/utils';\n\nconst Keys = {\n ciphersPrefix: 'ciphers_',\n localData: 'sitesLocalData',\n neverDomains: 'neverDomains',\n};\n\nconst DomainMatchBlacklist = new Map>([\n ['google.com', new Set(['script.google.com'])],\n]);\n\nexport class CipherService implements CipherServiceAbstraction {\n // tslint:disable-next-line\n _decryptedCipherCache: CipherView[];\n\n private sortedCiphersCache: SortedCiphersCache = new SortedCiphersCache(this.sortCiphersByLastUsed);\n\n constructor(private cryptoService: CryptoService, private userService: UserService,\n private settingsService: SettingsService, private apiService: ApiService,\n private fileUploadService: FileUploadService, private storageService: StorageService,\n private i18nService: I18nService, private searchService: () => SearchService,\n private logService: LogService) {\n }\n\n get decryptedCipherCache() {\n return this._decryptedCipherCache;\n }\n set decryptedCipherCache(value: CipherView[]) {\n this._decryptedCipherCache = value;\n if (this.searchService != null) {\n if (value == null) {\n this.searchService().clearIndex();\n } else {\n this.searchService().indexCiphers();\n }\n }\n }\n\n clearCache(): void {\n this.decryptedCipherCache = null;\n this.sortedCiphersCache.clear();\n }\n\n async encrypt(model: CipherView, key?: SymmetricCryptoKey, originalCipher: Cipher = null): Promise {\n // Adjust password history\n if (model.id != null) {\n if (originalCipher == null) {\n originalCipher = await this.get(model.id);\n }\n if (originalCipher != null) {\n const existingCipher = await originalCipher.decrypt();\n model.passwordHistory = existingCipher.passwordHistory || [];\n if (model.type === CipherType.Login && existingCipher.type === CipherType.Login) {\n if (existingCipher.login.password != null && existingCipher.login.password !== '' &&\n existingCipher.login.password !== model.login.password) {\n const ph = new PasswordHistoryView();\n ph.password = existingCipher.login.password;\n ph.lastUsedDate = model.login.passwordRevisionDate = new Date();\n model.passwordHistory.splice(0, 0, ph);\n } else {\n model.login.passwordRevisionDate = existingCipher.login.passwordRevisionDate;\n }\n }\n if (existingCipher.hasFields) {\n const existingHiddenFields = existingCipher.fields.filter(f => f.type === FieldType.Hidden &&\n f.name != null && f.name !== '' && f.value != null && f.value !== '');\n const hiddenFields = model.fields == null ? [] :\n model.fields.filter(f => f.type === FieldType.Hidden && f.name != null && f.name !== '');\n existingHiddenFields.forEach(ef => {\n const matchedField = hiddenFields.find(f => f.name === ef.name);\n if (matchedField == null || matchedField.value !== ef.value) {\n const ph = new PasswordHistoryView();\n ph.password = ef.name + ': ' + ef.value;\n ph.lastUsedDate = new Date();\n model.passwordHistory.splice(0, 0, ph);\n }\n });\n }\n }\n if (model.passwordHistory != null && model.passwordHistory.length === 0) {\n model.passwordHistory = null;\n } else if (model.passwordHistory != null && model.passwordHistory.length > 5) {\n // only save last 5 history\n model.passwordHistory = model.passwordHistory.slice(0, 5);\n }\n }\n\n const cipher = new Cipher();\n cipher.id = model.id;\n cipher.folderId = model.folderId;\n cipher.favorite = model.favorite;\n cipher.organizationId = model.organizationId;\n cipher.type = model.type;\n cipher.collectionIds = model.collectionIds;\n cipher.revisionDate = model.revisionDate;\n cipher.reprompt = model.reprompt;\n\n if (key == null && cipher.organizationId != null) {\n key = await this.cryptoService.getOrgKey(cipher.organizationId);\n if (key == null) {\n throw new Error('Cannot encrypt cipher for organization. No key.');\n }\n }\n await Promise.all([\n this.encryptObjProperty(model, cipher, {\n name: null,\n notes: null,\n }, key),\n this.encryptCipherData(cipher, model, key),\n this.encryptFields(model.fields, key).then(fields => {\n cipher.fields = fields;\n }),\n this.encryptPasswordHistories(model.passwordHistory, key).then(ph => {\n cipher.passwordHistory = ph;\n }),\n this.encryptAttachments(model.attachments, key).then(attachments => {\n cipher.attachments = attachments;\n }),\n ]);\n\n return cipher;\n }\n\n async encryptAttachments(attachmentsModel: AttachmentView[], key: SymmetricCryptoKey): Promise {\n if (attachmentsModel == null || attachmentsModel.length === 0) {\n return null;\n }\n\n const promises: Promise[] = [];\n const encAttachments: Attachment[] = [];\n attachmentsModel.forEach(async model => {\n const attachment = new Attachment();\n attachment.id = model.id;\n attachment.size = model.size;\n attachment.sizeName = model.sizeName;\n attachment.url = model.url;\n const promise = this.encryptObjProperty(model, attachment, {\n fileName: null,\n }, key).then(async () => {\n if (model.key != null) {\n attachment.key = await this.cryptoService.encrypt(model.key.key, key);\n }\n encAttachments.push(attachment);\n });\n promises.push(promise);\n });\n\n await Promise.all(promises);\n return encAttachments;\n }\n\n async encryptFields(fieldsModel: FieldView[], key: SymmetricCryptoKey): Promise {\n if (!fieldsModel || !fieldsModel.length) {\n return null;\n }\n\n const self = this;\n const encFields: Field[] = [];\n await fieldsModel.reduce((promise, field) => {\n return promise.then(() => {\n return self.encryptField(field, key);\n }).then((encField: Field) => {\n encFields.push(encField);\n });\n }, Promise.resolve());\n\n return encFields;\n }\n\n async encryptField(fieldModel: FieldView, key: SymmetricCryptoKey): Promise {\n const field = new Field();\n field.type = fieldModel.type;\n field.linkedId = fieldModel.linkedId;\n // normalize boolean type field values\n if (fieldModel.type === FieldType.Boolean && fieldModel.value !== 'true') {\n fieldModel.value = 'false';\n }\n\n await this.encryptObjProperty(fieldModel, field, {\n name: null,\n value: null,\n }, key);\n\n return field;\n }\n\n async encryptPasswordHistories(phModels: PasswordHistoryView[], key: SymmetricCryptoKey): Promise {\n if (!phModels || !phModels.length) {\n return null;\n }\n\n const self = this;\n const encPhs: Password[] = [];\n await phModels.reduce((promise, ph) => {\n return promise.then(() => {\n return self.encryptPasswordHistory(ph, key);\n }).then((encPh: Password) => {\n encPhs.push(encPh);\n });\n }, Promise.resolve());\n\n return encPhs;\n }\n\n async encryptPasswordHistory(phModel: PasswordHistoryView, key: SymmetricCryptoKey): Promise {\n const ph = new Password();\n ph.lastUsedDate = phModel.lastUsedDate;\n\n await this.encryptObjProperty(phModel, ph, {\n password: null,\n }, key);\n\n return ph;\n }\n\n async get(id: string): Promise {\n const userId = await this.userService.getUserId();\n const localData = await this.storageService.get(Keys.localData);\n const ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(\n Keys.ciphersPrefix + userId);\n if (ciphers == null || !ciphers.hasOwnProperty(id)) {\n return null;\n }\n\n return new Cipher(ciphers[id], false, localData ? localData[id] : null);\n }\n\n async getAll(): Promise {\n const userId = await this.userService.getUserId();\n const localData = await this.storageService.get(Keys.localData);\n const ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(\n Keys.ciphersPrefix + userId);\n const response: Cipher[] = [];\n for (const id in ciphers) {\n if (ciphers.hasOwnProperty(id)) {\n response.push(new Cipher(ciphers[id], false, localData ? localData[id] : null));\n }\n }\n return response;\n }\n\n @sequentialize(() => 'getAllDecrypted')\n async getAllDecrypted(): Promise {\n if (this.decryptedCipherCache != null) {\n const userId = await this.userService.getUserId();\n if (this.searchService != null && (this.searchService().indexedEntityId ?? userId) !== userId)\n {\n await this.searchService().indexCiphers(userId, this.decryptedCipherCache);\n }\n return this.decryptedCipherCache;\n }\n\n const decCiphers: CipherView[] = [];\n const hasKey = await this.cryptoService.hasKey();\n if (!hasKey) {\n throw new Error('No key.');\n }\n\n const promises: any[] = [];\n const ciphers = await this.getAll();\n ciphers.forEach(cipher => {\n promises.push(cipher.decrypt().then(c => decCiphers.push(c)));\n });\n\n await Promise.all(promises);\n decCiphers.sort(this.getLocaleSortingFunction());\n this.decryptedCipherCache = decCiphers;\n return this.decryptedCipherCache;\n }\n\n async getAllDecryptedForGrouping(groupingId: string, folder: boolean = true): Promise {\n const ciphers = await this.getAllDecrypted();\n\n return ciphers.filter(cipher => {\n if (cipher.isDeleted) {\n return false;\n }\n if (folder && cipher.folderId === groupingId) {\n return true;\n } else if (!folder && cipher.collectionIds != null && cipher.collectionIds.indexOf(groupingId) > -1) {\n return true;\n }\n\n return false;\n });\n }\n\n async getAllDecryptedForUrl(url: string, includeOtherTypes?: CipherType[],\n defaultMatch: UriMatchType = null): Promise {\n if (url == null && includeOtherTypes == null) {\n return Promise.resolve([]);\n }\n\n const domain = Utils.getDomain(url);\n const eqDomainsPromise = domain == null ? Promise.resolve([]) :\n this.settingsService.getEquivalentDomains().then((eqDomains: any[][]) => {\n let matches: any[] = [];\n eqDomains.forEach(eqDomain => {\n if (eqDomain.length && eqDomain.indexOf(domain) >= 0) {\n matches = matches.concat(eqDomain);\n }\n });\n\n if (!matches.length) {\n matches.push(domain);\n }\n\n return matches;\n });\n\n const result = await Promise.all([eqDomainsPromise, this.getAllDecrypted()]);\n const matchingDomains = result[0];\n const ciphers = result[1];\n\n if (defaultMatch == null) {\n defaultMatch = await this.storageService.get(ConstantsService.defaultUriMatch);\n if (defaultMatch == null) {\n defaultMatch = UriMatchType.Domain;\n }\n }\n\n return ciphers.filter(cipher => {\n if (cipher.deletedDate != null) {\n return false;\n }\n if (includeOtherTypes != null && includeOtherTypes.indexOf(cipher.type) > -1) {\n return true;\n }\n\n if (url != null && cipher.type === CipherType.Login && cipher.login.uris != null) {\n for (let i = 0; i < cipher.login.uris.length; i++) {\n const u = cipher.login.uris[i];\n if (u.uri == null) {\n continue;\n }\n\n const match = u.match == null ? defaultMatch : u.match;\n switch (match) {\n case UriMatchType.Domain:\n if (domain != null && u.domain != null && matchingDomains.indexOf(u.domain) > -1) {\n if (DomainMatchBlacklist.has(u.domain)) {\n const domainUrlHost = Utils.getHost(url);\n if (!DomainMatchBlacklist.get(u.domain).has(domainUrlHost)) {\n return true;\n }\n } else {\n return true;\n }\n }\n break;\n case UriMatchType.Host:\n const urlHost = Utils.getHost(url);\n if (urlHost != null && urlHost === Utils.getHost(u.uri)) {\n return true;\n }\n break;\n case UriMatchType.Exact:\n if (url === u.uri) {\n return true;\n }\n break;\n case UriMatchType.StartsWith:\n if (url.startsWith(u.uri)) {\n return true;\n }\n break;\n case UriMatchType.RegularExpression:\n try {\n const regex = new RegExp(u.uri, 'i');\n if (regex.test(url)) {\n return true;\n }\n } catch (e) {\n this.logService.error(e);\n }\n break;\n case UriMatchType.Never:\n default:\n break;\n }\n }\n }\n\n return false;\n });\n }\n\n async getAllFromApiForOrganization(organizationId: string): Promise {\n const ciphers = await this.apiService.getCiphersOrganization(organizationId);\n if (ciphers != null && ciphers.data != null && ciphers.data.length) {\n const decCiphers: CipherView[] = [];\n const promises: any[] = [];\n ciphers.data.forEach(r => {\n const data = new CipherData(r);\n const cipher = new Cipher(data);\n promises.push(cipher.decrypt().then(c => decCiphers.push(c)));\n });\n await Promise.all(promises);\n decCiphers.sort(this.getLocaleSortingFunction());\n return decCiphers;\n } else {\n return [];\n }\n }\n\n async getLastUsedForUrl(url: string, autofillOnPageLoad: boolean = false): Promise {\n return this.getCipherForUrl(url, true, false, autofillOnPageLoad);\n }\n\n async getLastLaunchedForUrl(url: string, autofillOnPageLoad: boolean = false): Promise {\n return this.getCipherForUrl(url, false, true, autofillOnPageLoad);\n }\n\n async getNextCipherForUrl(url: string): Promise {\n return this.getCipherForUrl(url, false, false, false);\n }\n\n updateLastUsedIndexForUrl(url: string) {\n this.sortedCiphersCache.updateLastUsedIndex(url);\n }\n\n async updateLastUsedDate(id: string): Promise {\n let ciphersLocalData = await this.storageService.get(Keys.localData);\n if (!ciphersLocalData) {\n ciphersLocalData = {};\n }\n\n if (ciphersLocalData[id]) {\n ciphersLocalData[id].lastUsedDate = new Date().getTime();\n } else {\n ciphersLocalData[id] = {\n lastUsedDate: new Date().getTime(),\n };\n }\n\n await this.storageService.save(Keys.localData, ciphersLocalData);\n\n if (this.decryptedCipherCache == null) {\n return;\n }\n\n for (let i = 0; i < this.decryptedCipherCache.length; i++) {\n const cached = this.decryptedCipherCache[i];\n if (cached.id === id) {\n cached.localData = ciphersLocalData[id];\n break;\n }\n }\n }\n\n async updateLastLaunchedDate(id: string): Promise {\n let ciphersLocalData = await this.storageService.get(Keys.localData);\n if (!ciphersLocalData) {\n ciphersLocalData = {};\n }\n\n if (ciphersLocalData[id]) {\n ciphersLocalData[id].lastLaunched = new Date().getTime();\n } else {\n ciphersLocalData[id] = {\n lastUsedDate: new Date().getTime(),\n };\n }\n\n await this.storageService.save(Keys.localData, ciphersLocalData);\n\n if (this.decryptedCipherCache == null) {\n return;\n }\n\n for (let i = 0; i < this.decryptedCipherCache.length; i++) {\n const cached = this.decryptedCipherCache[i];\n if (cached.id === id) {\n cached.localData = ciphersLocalData[id];\n break;\n }\n }\n }\n\n async saveNeverDomain(domain: string): Promise {\n if (domain == null) {\n return;\n }\n\n let domains = await this.storageService.get<{ [id: string]: any; }>(Keys.neverDomains);\n if (!domains) {\n domains = {};\n }\n domains[domain] = null;\n await this.storageService.save(Keys.neverDomains, domains);\n }\n\n async saveWithServer(cipher: Cipher): Promise {\n let response: CipherResponse;\n if (cipher.id == null) {\n if (cipher.collectionIds != null) {\n const request = new CipherCreateRequest(cipher);\n response = await this.apiService.postCipherCreate(request);\n } else {\n const request = new CipherRequest(cipher);\n response = await this.apiService.postCipher(request);\n }\n cipher.id = response.id;\n } else {\n const request = new CipherRequest(cipher);\n response = await this.apiService.putCipher(cipher.id, request);\n }\n\n const userId = await this.userService.getUserId();\n const data = new CipherData(response, userId, cipher.collectionIds);\n await this.upsert(data);\n }\n\n async shareWithServer(cipher: CipherView, organizationId: string, collectionIds: string[]): Promise {\n const attachmentPromises: Promise[] = [];\n if (cipher.attachments != null) {\n cipher.attachments.forEach(attachment => {\n if (attachment.key == null) {\n attachmentPromises.push(this.shareAttachmentWithServer(attachment, cipher.id, organizationId));\n }\n });\n }\n await Promise.all(attachmentPromises);\n\n cipher.organizationId = organizationId;\n cipher.collectionIds = collectionIds;\n const encCipher = await this.encrypt(cipher);\n const request = new CipherShareRequest(encCipher);\n const response = await this.apiService.putShareCipher(cipher.id, request);\n const userId = await this.userService.getUserId();\n const data = new CipherData(response, userId, collectionIds);\n await this.upsert(data);\n }\n\n async shareManyWithServer(ciphers: CipherView[], organizationId: string, collectionIds: string[]): Promise {\n const promises: Promise[] = [];\n const encCiphers: Cipher[] = [];\n for (const cipher of ciphers) {\n cipher.organizationId = organizationId;\n cipher.collectionIds = collectionIds;\n promises.push(this.encrypt(cipher).then(c => {\n encCiphers.push(c);\n }));\n }\n await Promise.all(promises);\n const request = new CipherBulkShareRequest(encCiphers, collectionIds);\n await this.apiService.putShareCiphers(request);\n const userId = await this.userService.getUserId();\n await this.upsert(encCiphers.map(c => c.toCipherData(userId)));\n }\n\n saveAttachmentWithServer(cipher: Cipher, unencryptedFile: any, admin = false): Promise {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.readAsArrayBuffer(unencryptedFile);\n reader.onload = async (evt: any) => {\n try {\n const cData = await this.saveAttachmentRawWithServer(cipher,\n unencryptedFile.name, evt.target.result, admin);\n resolve(cData);\n } catch (e) {\n reject(e);\n }\n };\n reader.onerror = evt => {\n reject('Error reading file.');\n };\n });\n }\n\n async saveAttachmentRawWithServer(cipher: Cipher, filename: string,\n data: ArrayBuffer, admin = false): Promise {\n const key = await this.cryptoService.getOrgKey(cipher.organizationId);\n const encFileName = await this.cryptoService.encrypt(filename, key);\n\n const dataEncKey = await this.cryptoService.makeEncKey(key);\n const encData = await this.cryptoService.encryptToBytes(data, dataEncKey[0]);\n\n const request: AttachmentRequest = {\n key: dataEncKey[1].encryptedString,\n fileName: encFileName.encryptedString,\n fileSize: encData.buffer.byteLength,\n adminRequest: admin,\n };\n\n let response: CipherResponse;\n try {\n const uploadDataResponse = await this.apiService.postCipherAttachment(cipher.id, request);\n response = admin ? uploadDataResponse.cipherMiniResponse : uploadDataResponse.cipherResponse;\n await this.fileUploadService.uploadCipherAttachment(admin, uploadDataResponse, encFileName, encData);\n } catch (e) {\n if (e instanceof ErrorResponse && (e as ErrorResponse).statusCode === 404 || (e as ErrorResponse).statusCode === 405) {\n response = await this.legacyServerAttachmentFileUpload(admin, cipher.id, encFileName, encData, dataEncKey[1]);\n } else if (e instanceof ErrorResponse) {\n throw new Error((e as ErrorResponse).getSingleMessage());\n } else {\n throw e;\n }\n }\n\n const userId = await this.userService.getUserId();\n const cData = new CipherData(response, userId, cipher.collectionIds);\n if (!admin) {\n await this.upsert(cData);\n }\n return new Cipher(cData);\n }\n\n /**\n * @deprecated Mar 25 2021: This method has been deprecated in favor of direct uploads.\n * This method still exists for backward compatibility with old server versions.\n */\n async legacyServerAttachmentFileUpload(admin: boolean, cipherId: string, encFileName: EncString,\n encData: EncArrayBuffer, key: EncString) {\n const fd = new FormData();\n try {\n const blob = new Blob([encData.buffer], { type: 'application/octet-stream' });\n fd.append('key', key.encryptedString);\n fd.append('data', blob, encFileName.encryptedString);\n } catch (e) {\n if (Utils.isNode && !Utils.isBrowser) {\n fd.append('key', key.encryptedString);\n fd.append('data', Buffer.from(encData.buffer) as any, {\n filepath: encFileName.encryptedString,\n contentType: 'application/octet-stream',\n } as any);\n } else {\n throw e;\n }\n }\n\n let response: CipherResponse;\n try {\n if (admin) {\n response = await this.apiService.postCipherAttachmentAdminLegacy(cipherId, fd);\n } else {\n response = await this.apiService.postCipherAttachmentLegacy(cipherId, fd);\n }\n } catch (e) {\n throw new Error((e as ErrorResponse).getSingleMessage());\n }\n\n return response;\n }\n\n async saveCollectionsWithServer(cipher: Cipher): Promise {\n const request = new CipherCollectionsRequest(cipher.collectionIds);\n await this.apiService.putCipherCollections(cipher.id, request);\n const userId = await this.userService.getUserId();\n const data = cipher.toCipherData(userId);\n await this.upsert(data);\n }\n\n async upsert(cipher: CipherData | CipherData[]): Promise {\n const userId = await this.userService.getUserId();\n let ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(\n Keys.ciphersPrefix + userId);\n if (ciphers == null) {\n ciphers = {};\n }\n\n if (cipher instanceof CipherData) {\n const c = cipher as CipherData;\n ciphers[c.id] = c;\n } else {\n (cipher as CipherData[]).forEach(c => {\n ciphers[c.id] = c;\n });\n }\n\n await this.storageService.save(Keys.ciphersPrefix + userId, ciphers);\n this.decryptedCipherCache = null;\n }\n\n async replace(ciphers: { [id: string]: CipherData; }): Promise {\n const userId = await this.userService.getUserId();\n await this.storageService.save(Keys.ciphersPrefix + userId, ciphers);\n this.decryptedCipherCache = null;\n }\n\n async clear(userId: string): Promise {\n await this.storageService.remove(Keys.ciphersPrefix + userId);\n this.clearCache();\n }\n\n async moveManyWithServer(ids: string[], folderId: string): Promise {\n await this.apiService.putMoveCiphers(new CipherBulkMoveRequest(ids, folderId));\n\n const userId = await this.userService.getUserId();\n let ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(\n Keys.ciphersPrefix + userId);\n if (ciphers == null) {\n ciphers = {};\n }\n\n ids.forEach(id => {\n if (ciphers.hasOwnProperty(id)) {\n ciphers[id].folderId = folderId;\n }\n });\n\n await this.storageService.save(Keys.ciphersPrefix + userId, ciphers);\n this.decryptedCipherCache = null;\n }\n\n async delete(id: string | string[]): Promise {\n const userId = await this.userService.getUserId();\n const ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(\n Keys.ciphersPrefix + userId);\n if (ciphers == null) {\n return;\n }\n\n if (typeof id === 'string') {\n if (ciphers[id] == null) {\n return;\n }\n delete ciphers[id];\n } else {\n (id as string[]).forEach(i => {\n delete ciphers[i];\n });\n }\n\n await this.storageService.save(Keys.ciphersPrefix + userId, ciphers);\n this.decryptedCipherCache = null;\n }\n\n async deleteWithServer(id: string): Promise {\n await this.apiService.deleteCipher(id);\n await this.delete(id);\n }\n\n async deleteManyWithServer(ids: string[]): Promise {\n await this.apiService.deleteManyCiphers(new CipherBulkDeleteRequest(ids));\n await this.delete(ids);\n }\n\n async deleteAttachment(id: string, attachmentId: string): Promise {\n const userId = await this.userService.getUserId();\n const ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(\n Keys.ciphersPrefix + userId);\n\n if (ciphers == null || !ciphers.hasOwnProperty(id) || ciphers[id].attachments == null) {\n return;\n }\n\n for (let i = 0; i < ciphers[id].attachments.length; i++) {\n if (ciphers[id].attachments[i].id === attachmentId) {\n ciphers[id].attachments.splice(i, 1);\n }\n }\n\n await this.storageService.save(Keys.ciphersPrefix + userId, ciphers);\n this.decryptedCipherCache = null;\n }\n\n async deleteAttachmentWithServer(id: string, attachmentId: string): Promise {\n try {\n await this.apiService.deleteCipherAttachment(id, attachmentId);\n } catch (e) {\n return Promise.reject((e as ErrorResponse).getSingleMessage());\n }\n await this.deleteAttachment(id, attachmentId);\n }\n\n sortCiphersByLastUsed(a: CipherView, b: CipherView): number {\n const aLastUsed = a.localData && a.localData.lastUsedDate ? a.localData.lastUsedDate as number : null;\n const bLastUsed = b.localData && b.localData.lastUsedDate ? b.localData.lastUsedDate as number : null;\n\n const bothNotNull = aLastUsed != null && bLastUsed != null;\n if (bothNotNull && aLastUsed < bLastUsed) {\n return 1;\n }\n if (aLastUsed != null && bLastUsed == null) {\n return -1;\n }\n\n if (bothNotNull && aLastUsed > bLastUsed) {\n return -1;\n }\n if (bLastUsed != null && aLastUsed == null) {\n return 1;\n }\n\n return 0;\n }\n\n sortCiphersByLastUsedThenName(a: CipherView, b: CipherView): number {\n const result = this.sortCiphersByLastUsed(a, b);\n if (result !== 0) {\n return result;\n }\n\n return this.getLocaleSortingFunction()(a, b);\n }\n\n getLocaleSortingFunction(): (a: CipherView, b: CipherView) => number {\n return (a, b) => {\n let aName = a.name;\n let bName = b.name;\n\n if (aName == null && bName != null) {\n return -1;\n }\n if (aName != null && bName == null) {\n return 1;\n }\n if (aName == null && bName == null) {\n return 0;\n }\n\n const result = this.i18nService.collator ? this.i18nService.collator.compare(aName, bName) :\n aName.localeCompare(bName);\n\n if (result !== 0 || a.type !== CipherType.Login || b.type !== CipherType.Login) {\n return result;\n }\n\n if (a.login.username != null) {\n aName += a.login.username;\n }\n\n if (b.login.username != null) {\n bName += b.login.username;\n }\n\n return this.i18nService.collator ? this.i18nService.collator.compare(aName, bName) :\n aName.localeCompare(bName);\n };\n }\n\n async softDelete(id: string | string[]): Promise {\n const userId = await this.userService.getUserId();\n const ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(\n Keys.ciphersPrefix + userId);\n if (ciphers == null) {\n return;\n }\n\n const setDeletedDate = (cipherId: string) => {\n if (ciphers[cipherId] == null) {\n return;\n }\n ciphers[cipherId].deletedDate = new Date().toISOString();\n };\n\n if (typeof id === 'string') {\n setDeletedDate(id);\n } else {\n (id as string[]).forEach(setDeletedDate);\n }\n\n await this.storageService.save(Keys.ciphersPrefix + userId, ciphers);\n this.decryptedCipherCache = null;\n }\n\n async softDeleteWithServer(id: string): Promise {\n await this.apiService.putDeleteCipher(id);\n await this.softDelete(id);\n }\n\n async softDeleteManyWithServer(ids: string[]): Promise {\n await this.apiService.putDeleteManyCiphers(new CipherBulkDeleteRequest(ids));\n await this.softDelete(ids);\n }\n\n async restore(cipher: { id: string, revisionDate: string; } | { id: string, revisionDate: string; }[]) {\n const userId = await this.userService.getUserId();\n const ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(\n Keys.ciphersPrefix + userId);\n if (ciphers == null) {\n return;\n }\n\n const clearDeletedDate = (c: { id: string, revisionDate: string; }) => {\n if (ciphers[c.id] == null) {\n return;\n }\n ciphers[c.id].deletedDate = null;\n ciphers[c.id].revisionDate = c.revisionDate;\n };\n\n\n if (cipher.constructor.name === 'Array') {\n (cipher as { id: string, revisionDate: string; }[]).forEach(clearDeletedDate);\n } else {\n clearDeletedDate(cipher as { id: string, revisionDate: string; });\n }\n\n await this.storageService.save(Keys.ciphersPrefix + userId, ciphers);\n this.decryptedCipherCache = null;\n }\n\n async restoreWithServer(id: string): Promise {\n const response = await this.apiService.putRestoreCipher(id);\n await this.restore({ id: id, revisionDate: response.revisionDate });\n }\n\n async restoreManyWithServer(ids: string[]): Promise {\n const response = await this.apiService.putRestoreManyCiphers(new CipherBulkRestoreRequest(ids));\n const restores: { id: string, revisionDate: string; }[] = [];\n for (const cipher of response.data) {\n restores.push({ id: cipher.id, revisionDate: cipher.revisionDate });\n }\n await this.restore(restores);\n }\n\n // Helpers\n\n private async shareAttachmentWithServer(attachmentView: AttachmentView, cipherId: string,\n organizationId: string): Promise {\n const attachmentResponse = await this.apiService.nativeFetch(\n new Request(attachmentView.url, { cache: 'no-store' }));\n if (attachmentResponse.status !== 200) {\n throw Error('Failed to download attachment: ' + attachmentResponse.status.toString());\n }\n\n const buf = await attachmentResponse.arrayBuffer();\n const decBuf = await this.cryptoService.decryptFromBytes(buf, null);\n const key = await this.cryptoService.getOrgKey(organizationId);\n const encFileName = await this.cryptoService.encrypt(attachmentView.fileName, key);\n\n const dataEncKey = await this.cryptoService.makeEncKey(key);\n const encData = await this.cryptoService.encryptToBytes(decBuf, dataEncKey[0]);\n\n const fd = new FormData();\n try {\n const blob = new Blob([encData.buffer], { type: 'application/octet-stream' });\n fd.append('key', dataEncKey[1].encryptedString);\n fd.append('data', blob, encFileName.encryptedString);\n } catch (e) {\n if (Utils.isNode && !Utils.isBrowser) {\n fd.append('key', dataEncKey[1].encryptedString);\n fd.append('data', Buffer.from(encData.buffer) as any, {\n filepath: encFileName.encryptedString,\n contentType: 'application/octet-stream',\n } as any);\n } else {\n throw e;\n }\n }\n\n try {\n await this.apiService.postShareCipherAttachment(cipherId, attachmentView.id, fd, organizationId);\n } catch (e) {\n throw new Error((e as ErrorResponse).getSingleMessage());\n }\n }\n\n private async encryptObjProperty(model: V, obj: D,\n map: any, key: SymmetricCryptoKey): Promise {\n const promises = [];\n const self = this;\n\n for (const prop in map) {\n if (!map.hasOwnProperty(prop)) {\n continue;\n }\n\n // tslint:disable-next-line\n (function (theProp, theObj) {\n const p = Promise.resolve().then(() => {\n const modelProp = (model as any)[(map[theProp] || theProp)];\n if (modelProp && modelProp !== '') {\n return self.cryptoService.encrypt(modelProp, key);\n }\n return null;\n }).then((val: EncString) => {\n (theObj as any)[theProp] = val;\n });\n promises.push(p);\n })(prop, obj);\n }\n\n await Promise.all(promises);\n }\n\n private async encryptCipherData(cipher: Cipher, model: CipherView, key: SymmetricCryptoKey) {\n switch (cipher.type) {\n case CipherType.Login:\n cipher.login = new Login();\n cipher.login.passwordRevisionDate = model.login.passwordRevisionDate;\n cipher.login.autofillOnPageLoad = model.login.autofillOnPageLoad;\n await this.encryptObjProperty(model.login, cipher.login, {\n username: null,\n password: null,\n totp: null,\n }, key);\n\n if (model.login.uris != null) {\n cipher.login.uris = [];\n for (let i = 0; i < model.login.uris.length; i++) {\n const loginUri = new LoginUri();\n loginUri.match = model.login.uris[i].match;\n await this.encryptObjProperty(model.login.uris[i], loginUri, {\n uri: null,\n }, key);\n cipher.login.uris.push(loginUri);\n }\n }\n return;\n case CipherType.SecureNote:\n cipher.secureNote = new SecureNote();\n cipher.secureNote.type = model.secureNote.type;\n return;\n case CipherType.Card:\n cipher.card = new Card();\n await this.encryptObjProperty(model.card, cipher.card, {\n cardholderName: null,\n brand: null,\n number: null,\n expMonth: null,\n expYear: null,\n code: null,\n }, key);\n return;\n case CipherType.Identity:\n cipher.identity = new Identity();\n await this.encryptObjProperty(model.identity, cipher.identity, {\n title: null,\n firstName: null,\n middleName: null,\n lastName: null,\n address1: null,\n address2: null,\n address3: null,\n city: null,\n state: null,\n postalCode: null,\n country: null,\n company: null,\n email: null,\n phone: null,\n ssn: null,\n username: null,\n passportNumber: null,\n licenseNumber: null,\n }, key);\n return;\n default:\n throw new Error('Unknown cipher type.');\n }\n }\n\n private async getCipherForUrl(url: string, lastUsed: boolean, lastLaunched: boolean, autofillOnPageLoad: boolean): Promise {\n const cacheKey = autofillOnPageLoad ? 'autofillOnPageLoad-' + url : url;\n\n if (!this.sortedCiphersCache.isCached(cacheKey)) {\n let ciphers = await this.getAllDecryptedForUrl(url);\n if (!ciphers) {\n return null;\n }\n\n if (autofillOnPageLoad) {\n const autofillOnPageLoadDefault = await this.storageService.get(ConstantsService.autoFillOnPageLoadDefaultKey);\n ciphers = ciphers.filter(cipher => cipher.login.autofillOnPageLoad ||\n (cipher.login.autofillOnPageLoad == null && autofillOnPageLoadDefault !== false));\n if (ciphers.length === 0) {\n return null;\n }\n }\n\n this.sortedCiphersCache.addCiphers(cacheKey, ciphers);\n }\n\n if (lastLaunched) {\n return this.sortedCiphersCache.getLastLaunched(cacheKey);\n } else if (lastUsed) {\n return this.sortedCiphersCache.getLastUsed(cacheKey);\n } else {\n return this.sortedCiphersCache.getNext(cacheKey);\n }\n }\n}\n","export class CipherBulkMoveRequest {\n ids: string[];\n folderId: string;\n\n constructor(ids: string[], folderId: string) {\n this.ids = ids == null ? [] : ids;\n this.folderId = folderId;\n }\n}\n","export class CipherBulkRestoreRequest {\n ids: string[];\n\n constructor(ids: string[]) {\n this.ids = ids == null ? [] : ids;\n }\n}\n","import { CipherWithIdRequest } from './cipherWithIdRequest';\n\nimport { Cipher } from '../domain/cipher';\n\nexport class CipherBulkShareRequest {\n ciphers: CipherWithIdRequest[];\n collectionIds: string[];\n\n constructor(ciphers: Cipher[], collectionIds: string[]) {\n if (ciphers != null) {\n this.ciphers = [];\n ciphers.forEach(c => {\n this.ciphers.push(new CipherWithIdRequest(c));\n });\n }\n this.collectionIds = collectionIds;\n }\n}\n","import { CipherRequest } from './cipherRequest';\n\nimport { Cipher } from '../domain/cipher';\n\nexport class CipherShareRequest {\n cipher: CipherRequest;\n collectionIds: string[];\n\n constructor(cipher: Cipher) {\n this.cipher = new CipherRequest(cipher);\n this.collectionIds = cipher.collectionIds;\n }\n}\n","import { CipherView } from '../view/cipherView';\n\nconst CacheTTL = 3000;\n\nexport class SortedCiphersCache {\n private readonly sortedCiphersByUrl: Map = new Map();\n private readonly timeouts: Map = new Map();\n\n constructor(private readonly comparator: (a: CipherView, b: CipherView) => number) { }\n\n isCached(url: string) {\n return this.sortedCiphersByUrl.has(url);\n }\n\n addCiphers(url: string, ciphers: CipherView[]) {\n ciphers.sort(this.comparator);\n this.sortedCiphersByUrl.set(url, new Ciphers(ciphers));\n this.resetTimer(url);\n }\n\n getLastUsed(url: string) {\n this.resetTimer(url);\n return this.isCached(url) ? this.sortedCiphersByUrl.get(url).getLastUsed() : null;\n }\n\n getLastLaunched(url: string) {\n return this.isCached(url) ? this.sortedCiphersByUrl.get(url).getLastLaunched() : null;\n }\n\n getNext(url: string) {\n this.resetTimer(url);\n return this.isCached(url) ? this.sortedCiphersByUrl.get(url).getNext() : null;\n }\n\n updateLastUsedIndex(url: string) {\n if (this.isCached(url)) {\n this.sortedCiphersByUrl.get(url).updateLastUsedIndex();\n }\n }\n\n clear() {\n this.sortedCiphersByUrl.clear();\n this.timeouts.clear();\n }\n\n private resetTimer(url: string) {\n clearTimeout(this.timeouts.get(url));\n this.timeouts.set(url, setTimeout(() => {\n this.sortedCiphersByUrl.delete(url);\n this.timeouts.delete(url);\n }, CacheTTL));\n }\n}\n\nclass Ciphers {\n lastUsedIndex = -1;\n\n constructor(private readonly ciphers: CipherView[]) { }\n\n getLastUsed() {\n this.lastUsedIndex = Math.max(this.lastUsedIndex, 0);\n return this.ciphers[this.lastUsedIndex];\n }\n\n getLastLaunched() {\n const usedCiphers = this.ciphers.filter(cipher => cipher.localData?.lastLaunched);\n const sortedCiphers = usedCiphers.sort((x, y) => y.localData.lastLaunched.valueOf() - x.localData.lastLaunched.valueOf());\n return sortedCiphers[0];\n }\n\n getNextIndex() {\n return (this.lastUsedIndex + 1) % this.ciphers.length;\n }\n\n getNext() {\n return this.ciphers[this.getNextIndex()];\n }\n\n updateLastUsedIndex() {\n this.lastUsedIndex = this.getNextIndex();\n }\n}\n","import { CollectionData } from '../models/data/collectionData';\n\nimport { Collection } from '../models/domain/collection';\nimport { TreeNode } from '../models/domain/treeNode';\n\nimport { CollectionView } from '../models/view/collectionView';\n\nimport { CollectionService as CollectionServiceAbstraction } from '../abstractions/collection.service';\nimport { CryptoService } from '../abstractions/crypto.service';\nimport { I18nService } from '../abstractions/i18n.service';\nimport { StorageService } from '../abstractions/storage.service';\nimport { UserService } from '../abstractions/user.service';\n\nimport { ServiceUtils } from '../misc/serviceUtils';\nimport { Utils } from '../misc/utils';\n\nconst Keys = {\n collectionsPrefix: 'collections_',\n};\nconst NestingDelimiter = '/';\n\nexport class CollectionService implements CollectionServiceAbstraction {\n decryptedCollectionCache: CollectionView[];\n\n constructor(private cryptoService: CryptoService, private userService: UserService,\n private storageService: StorageService, private i18nService: I18nService) {\n }\n\n clearCache(): void {\n this.decryptedCollectionCache = null;\n }\n\n async encrypt(model: CollectionView): Promise {\n if (model.organizationId == null) {\n throw new Error('Collection has no organization id.');\n }\n const key = await this.cryptoService.getOrgKey(model.organizationId);\n if (key == null) {\n throw new Error('No key for this collection\\'s organization.');\n }\n const collection = new Collection();\n collection.id = model.id;\n collection.organizationId = model.organizationId;\n collection.readOnly = model.readOnly;\n collection.name = await this.cryptoService.encrypt(model.name, key);\n return collection;\n }\n\n async decryptMany(collections: Collection[]): Promise {\n if (collections == null) {\n return [];\n }\n const decCollections: CollectionView[] = [];\n const promises: Promise[] = [];\n collections.forEach(collection => {\n promises.push(collection.decrypt().then(c => decCollections.push(c)));\n });\n await Promise.all(promises);\n return decCollections.sort(Utils.getSortFunction(this.i18nService, 'name'));\n }\n\n async get(id: string): Promise {\n const userId = await this.userService.getUserId();\n const collections = await this.storageService.get<{ [id: string]: CollectionData; }>(\n Keys.collectionsPrefix + userId);\n if (collections == null || !collections.hasOwnProperty(id)) {\n return null;\n }\n\n return new Collection(collections[id]);\n }\n\n async getAll(): Promise {\n const userId = await this.userService.getUserId();\n const collections = await this.storageService.get<{ [id: string]: CollectionData; }>(\n Keys.collectionsPrefix + userId);\n const response: Collection[] = [];\n for (const id in collections) {\n if (collections.hasOwnProperty(id)) {\n response.push(new Collection(collections[id]));\n }\n }\n return response;\n }\n\n async getAllDecrypted(): Promise {\n if (this.decryptedCollectionCache != null) {\n return this.decryptedCollectionCache;\n }\n\n const hasKey = await this.cryptoService.hasKey();\n if (!hasKey) {\n throw new Error('No key.');\n }\n\n const collections = await this.getAll();\n this.decryptedCollectionCache = await this.decryptMany(collections);\n return this.decryptedCollectionCache;\n }\n\n async getAllNested(collections: CollectionView[] = null): Promise[]> {\n if (collections == null) {\n collections = await this.getAllDecrypted();\n }\n const nodes: TreeNode[] = [];\n collections.forEach(c => {\n const collectionCopy = new CollectionView();\n collectionCopy.id = c.id;\n collectionCopy.organizationId = c.organizationId;\n const parts = c.name != null ? c.name.replace(/^\\/+|\\/+$/g, '').split(NestingDelimiter) : [];\n ServiceUtils.nestedTraverse(nodes, 0, parts, collectionCopy, null, NestingDelimiter);\n });\n return nodes;\n }\n\n async getNested(id: string): Promise> {\n const collections = await this.getAllNested();\n return ServiceUtils.getTreeNodeObject(collections, id) as TreeNode;\n }\n\n async upsert(collection: CollectionData | CollectionData[]): Promise {\n const userId = await this.userService.getUserId();\n let collections = await this.storageService.get<{ [id: string]: CollectionData; }>(\n Keys.collectionsPrefix + userId);\n if (collections == null) {\n collections = {};\n }\n\n if (collection instanceof CollectionData) {\n const c = collection as CollectionData;\n collections[c.id] = c;\n } else {\n (collection as CollectionData[]).forEach(c => {\n collections[c.id] = c;\n });\n }\n\n await this.storageService.save(Keys.collectionsPrefix + userId, collections);\n this.decryptedCollectionCache = null;\n }\n\n async replace(collections: { [id: string]: CollectionData; }): Promise {\n const userId = await this.userService.getUserId();\n await this.storageService.save(Keys.collectionsPrefix + userId, collections);\n this.decryptedCollectionCache = null;\n }\n\n async clear(userId: string): Promise {\n await this.storageService.remove(Keys.collectionsPrefix + userId);\n this.decryptedCollectionCache = null;\n }\n\n async delete(id: string | string[]): Promise {\n const userId = await this.userService.getUserId();\n const collections = await this.storageService.get<{ [id: string]: CollectionData; }>(\n Keys.collectionsPrefix + userId);\n if (collections == null) {\n return;\n }\n\n if (typeof id === 'string') {\n const i = id as string;\n delete collections[id];\n } else {\n (id as string[]).forEach(i => {\n delete collections[i];\n });\n }\n\n await this.storageService.save(Keys.collectionsPrefix + userId, collections);\n this.decryptedCollectionCache = null;\n }\n}\n","export class TreeNode {\n parent: T;\n node: T;\n children: TreeNode[] = [];\n\n constructor(node: T, name: string, parent: T) {\n this.parent = parent;\n this.node = node;\n this.node.name = name;\n }\n}\n\nexport interface ITreeNodeObject {\n id: string;\n name: string;\n}\n","export enum LogLevelType {\n Debug,\n Info,\n Warning,\n Error,\n}\n","import { CryptoService } from '../abstractions/crypto.service';\n\nexport class ContainerService {\n constructor(private cryptoService: CryptoService) {\n }\n\n // deprecated, use attachToGlobal instead\n attachToWindow(win: any) {\n this.attachToGlobal(win);\n }\n\n attachToGlobal(global: any) {\n if (!global.bitwardenContainerService) {\n global.bitwardenContainerService = this;\n }\n }\n\n getCryptoService(): CryptoService {\n return this.cryptoService;\n }\n}\n","import * as bigInt from 'big-integer';\n\nimport { EncryptionType } from '../enums/encryptionType';\nimport { HashPurpose } from '../enums/hashPurpose';\nimport { KdfType } from '../enums/kdfType';\n\nimport { EncArrayBuffer } from '../models/domain/encArrayBuffer';\nimport { EncryptedObject } from '../models/domain/encryptedObject';\nimport { EncString } from '../models/domain/encString';\nimport { SymmetricCryptoKey } from '../models/domain/symmetricCryptoKey';\nimport { ProfileOrganizationResponse } from '../models/response/profileOrganizationResponse';\n\nimport { CryptoService as CryptoServiceAbstraction } from '../abstractions/crypto.service';\nimport { CryptoFunctionService } from '../abstractions/cryptoFunction.service';\nimport { LogService } from '../abstractions/log.service';\nimport { PlatformUtilsService } from '../abstractions/platformUtils.service';\nimport {\n KeySuffixOptions,\n StorageService,\n} from '../abstractions/storage.service';\n\nimport { ConstantsService } from './constants.service';\n\nimport { sequentialize } from '../misc/sequentialize';\nimport { Utils } from '../misc/utils';\nimport { EEFLongWordList } from '../misc/wordlist';\nimport { ProfileProviderOrganizationResponse } from '../models/response/profileProviderOrganizationResponse';\nimport { ProfileProviderResponse } from '../models/response/profileProviderResponse';\n\nexport const Keys = {\n key: 'key', // Master Key\n encOrgKeys: 'encOrgKeys',\n encProviderKeys: 'encProviderKeys',\n encPrivateKey: 'encPrivateKey',\n encKey: 'encKey', // Generated Symmetric Key\n keyHash: 'keyHash',\n};\n\nexport class CryptoService implements CryptoServiceAbstraction {\n private key: SymmetricCryptoKey;\n private encKey: SymmetricCryptoKey;\n private legacyEtmKey: SymmetricCryptoKey;\n private keyHash: string;\n private publicKey: ArrayBuffer;\n private privateKey: ArrayBuffer;\n private orgKeys: Map;\n private providerKeys: Map;\n\n constructor(private storageService: StorageService, protected secureStorageService: StorageService,\n private cryptoFunctionService: CryptoFunctionService, protected platformUtilService: PlatformUtilsService,\n protected logService: LogService) {\n }\n\n async setKey(key: SymmetricCryptoKey): Promise {\n this.key = key;\n\n await this.storeKey(key);\n }\n\n setKeyHash(keyHash: string): Promise<{}> {\n this.keyHash = keyHash;\n return this.storageService.save(Keys.keyHash, keyHash);\n }\n\n async setEncKey(encKey: string): Promise<{}> {\n if (encKey == null) {\n return;\n }\n\n await this.storageService.save(Keys.encKey, encKey);\n this.encKey = null;\n }\n\n async setEncPrivateKey(encPrivateKey: string): Promise<{}> {\n if (encPrivateKey == null) {\n return;\n }\n\n await this.storageService.save(Keys.encPrivateKey, encPrivateKey);\n this.privateKey = null;\n }\n\n async setOrgKeys(orgs: ProfileOrganizationResponse[], providerOrgs: ProfileProviderOrganizationResponse[]): Promise<{}> {\n const orgKeys: any = {};\n orgs.forEach(org => {\n orgKeys[org.id] = org.key;\n });\n\n for (const providerOrg of providerOrgs) {\n // Convert provider encrypted keys to user encrypted.\n const providerKey = await this.getProviderKey(providerOrg.providerId);\n const decValue = await this.decryptToBytes(new EncString(providerOrg.key), providerKey);\n orgKeys[providerOrg.id] = await (await this.rsaEncrypt(decValue)).encryptedString;\n }\n\n this.orgKeys = null;\n return this.storageService.save(Keys.encOrgKeys, orgKeys);\n }\n\n setProviderKeys(providers: ProfileProviderResponse[]): Promise<{}> {\n const providerKeys: any = {};\n providers.forEach(provider => {\n providerKeys[provider.id] = provider.key;\n });\n\n this.providerKeys = null;\n return this.storageService.save(Keys.encProviderKeys, providerKeys);\n }\n\n async getKey(keySuffix?: KeySuffixOptions): Promise {\n if (this.key != null) {\n return this.key;\n }\n\n keySuffix ||= 'auto';\n const symmetricKey = await this.getKeyFromStorage(keySuffix);\n\n if (symmetricKey != null) {\n this.setKey(symmetricKey);\n }\n\n return symmetricKey;\n }\n\n async getKeyFromStorage(keySuffix: KeySuffixOptions): Promise {\n const key = await this.retrieveKeyFromStorage(keySuffix);\n if (key != null) {\n\n const symmetricKey = new SymmetricCryptoKey(Utils.fromB64ToArray(key).buffer);\n\n if (!await this.validateKey(symmetricKey)) {\n this.logService.warning('Wrong key, throwing away stored key');\n this.secureStorageService.remove(Keys.key, { keySuffix: keySuffix });\n return null;\n }\n\n return symmetricKey;\n }\n return null;\n }\n\n async getKeyHash(): Promise {\n if (this.keyHash != null) {\n return this.keyHash;\n }\n\n const keyHash = await this.storageService.get(Keys.keyHash);\n if (keyHash != null) {\n this.keyHash = keyHash;\n }\n\n return keyHash == null ? null : this.keyHash;\n }\n\n async compareAndUpdateKeyHash(masterPassword: string, key: SymmetricCryptoKey): Promise {\n const storedKeyHash = await this.getKeyHash();\n if (masterPassword != null && storedKeyHash != null) {\n const localKeyHash = await this.hashPassword(masterPassword, key, HashPurpose.LocalAuthorization);\n if (localKeyHash != null && storedKeyHash === localKeyHash) {\n return true;\n }\n\n // TODO: remove serverKeyHash check in 1-2 releases after everyone's keyHash has been updated\n const serverKeyHash = await this.hashPassword(masterPassword, key, HashPurpose.ServerAuthorization);\n if (serverKeyHash != null && storedKeyHash === serverKeyHash) {\n await this.setKeyHash(localKeyHash);\n return true;\n }\n }\n\n return false;\n }\n\n @sequentialize(() => 'getEncKey')\n async getEncKey(key: SymmetricCryptoKey = null): Promise {\n if (this.encKey != null) {\n return this.encKey;\n }\n\n const encKey = await this.storageService.get(Keys.encKey);\n if (encKey == null) {\n return null;\n }\n\n if (key == null) {\n key = await this.getKey();\n }\n if (key == null) {\n return null;\n }\n\n let decEncKey: ArrayBuffer;\n const encKeyCipher = new EncString(encKey);\n if (encKeyCipher.encryptionType === EncryptionType.AesCbc256_B64) {\n decEncKey = await this.decryptToBytes(encKeyCipher, key);\n } else if (encKeyCipher.encryptionType === EncryptionType.AesCbc256_HmacSha256_B64) {\n const newKey = await this.stretchKey(key);\n decEncKey = await this.decryptToBytes(encKeyCipher, newKey);\n } else {\n throw new Error('Unsupported encKey type.');\n }\n\n if (decEncKey == null) {\n return null;\n }\n this.encKey = new SymmetricCryptoKey(decEncKey);\n return this.encKey;\n }\n\n async getPublicKey(): Promise {\n if (this.publicKey != null) {\n return this.publicKey;\n }\n\n const privateKey = await this.getPrivateKey();\n if (privateKey == null) {\n return null;\n }\n\n this.publicKey = await this.cryptoFunctionService.rsaExtractPublicKey(privateKey);\n return this.publicKey;\n }\n\n async getPrivateKey(): Promise {\n if (this.privateKey != null) {\n return this.privateKey;\n }\n\n const encPrivateKey = await this.storageService.get(Keys.encPrivateKey);\n if (encPrivateKey == null) {\n return null;\n }\n\n this.privateKey = await this.decryptToBytes(new EncString(encPrivateKey), null);\n return this.privateKey;\n }\n\n async getFingerprint(userId: string, publicKey?: ArrayBuffer): Promise {\n if (publicKey == null) {\n publicKey = await this.getPublicKey();\n }\n if (publicKey === null) {\n throw new Error('No public key available.');\n }\n const keyFingerprint = await this.cryptoFunctionService.hash(publicKey, 'sha256');\n const userFingerprint = await this.cryptoFunctionService.hkdfExpand(keyFingerprint, userId, 32, 'sha256');\n return this.hashPhrase(userFingerprint);\n }\n\n @sequentialize(() => 'getOrgKeys')\n async getOrgKeys(): Promise> {\n if (this.orgKeys != null && this.orgKeys.size > 0) {\n return this.orgKeys;\n }\n\n const encOrgKeys = await this.storageService.get(Keys.encOrgKeys);\n if (encOrgKeys == null) {\n return null;\n }\n\n const orgKeys: Map = new Map();\n let setKey = false;\n\n for (const orgId in encOrgKeys) {\n if (!encOrgKeys.hasOwnProperty(orgId)) {\n continue;\n }\n\n const decValue = await this.rsaDecrypt(encOrgKeys[orgId]);\n orgKeys.set(orgId, new SymmetricCryptoKey(decValue));\n setKey = true;\n }\n\n if (setKey) {\n this.orgKeys = orgKeys;\n }\n\n return this.orgKeys;\n }\n\n async getOrgKey(orgId: string): Promise {\n if (orgId == null) {\n return null;\n }\n\n const orgKeys = await this.getOrgKeys();\n if (orgKeys == null || !orgKeys.has(orgId)) {\n return null;\n }\n\n return orgKeys.get(orgId);\n }\n\n @sequentialize(() => 'getProviderKeys')\n async getProviderKeys(): Promise> {\n if (this.providerKeys != null && this.providerKeys.size > 0) {\n return this.providerKeys;\n }\n\n const encProviderKeys = await this.storageService.get(Keys.encProviderKeys);\n if (encProviderKeys == null) {\n return null;\n }\n\n const providerKeys: Map = new Map();\n let setKey = false;\n\n for (const orgId in encProviderKeys) {\n if (!encProviderKeys.hasOwnProperty(orgId)) {\n continue;\n }\n\n const decValue = await this.rsaDecrypt(encProviderKeys[orgId]);\n providerKeys.set(orgId, new SymmetricCryptoKey(decValue));\n setKey = true;\n }\n\n if (setKey) {\n this.providerKeys = providerKeys;\n }\n\n return this.providerKeys;\n }\n\n async getProviderKey(providerId: string): Promise {\n if (providerId == null) {\n return null;\n }\n\n const providerKeys = await this.getProviderKeys();\n if (providerKeys == null || !providerKeys.has(providerId)) {\n return null;\n }\n\n return providerKeys.get(providerId);\n }\n\n async hasKey(): Promise {\n return this.hasKeyInMemory() || await this.hasKeyStored('auto') || await this.hasKeyStored('biometric');\n }\n\n hasKeyInMemory(): boolean {\n return this.key != null;\n }\n\n hasKeyStored(keySuffix: KeySuffixOptions): Promise {\n return this.secureStorageService.has(Keys.key, { keySuffix: keySuffix });\n }\n\n async hasEncKey(): Promise {\n const encKey = await this.storageService.get(Keys.encKey);\n return encKey != null;\n }\n\n async clearKey(clearSecretStorage: boolean = true): Promise {\n this.key = this.legacyEtmKey = null;\n if (clearSecretStorage) {\n this.clearStoredKey('auto');\n this.clearStoredKey('biometric');\n }\n }\n\n async clearStoredKey(keySuffix: KeySuffixOptions) {\n await this.secureStorageService.remove(Keys.key, { keySuffix: keySuffix });\n }\n\n clearKeyHash(): Promise {\n this.keyHash = null;\n return this.storageService.remove(Keys.keyHash);\n }\n\n clearEncKey(memoryOnly?: boolean): Promise {\n this.encKey = null;\n if (memoryOnly) {\n return Promise.resolve();\n }\n return this.storageService.remove(Keys.encKey);\n }\n\n clearKeyPair(memoryOnly?: boolean): Promise {\n this.privateKey = null;\n this.publicKey = null;\n if (memoryOnly) {\n return Promise.resolve();\n }\n return this.storageService.remove(Keys.encPrivateKey);\n }\n\n clearOrgKeys(memoryOnly?: boolean): Promise {\n this.orgKeys = null;\n if (memoryOnly) {\n return Promise.resolve();\n }\n return this.storageService.remove(Keys.encOrgKeys);\n }\n\n clearProviderKeys(memoryOnly?: boolean): Promise {\n this.providerKeys = null;\n if (memoryOnly) {\n return Promise.resolve();\n }\n return this.storageService.remove(Keys.encOrgKeys);\n }\n\n clearPinProtectedKey(): Promise {\n return this.storageService.remove(ConstantsService.pinProtectedKey);\n }\n\n async clearKeys(): Promise {\n await this.clearKey();\n await this.clearKeyHash();\n await this.clearOrgKeys();\n await this.clearProviderKeys();\n await this.clearEncKey();\n await this.clearKeyPair();\n await this.clearPinProtectedKey();\n }\n\n async toggleKey(): Promise {\n const key = await this.getKey();\n\n await this.setKey(key);\n }\n\n async makeKey(password: string, salt: string, kdf: KdfType, kdfIterations: number):\n Promise {\n let key: ArrayBuffer = null;\n if (kdf == null || kdf === KdfType.PBKDF2_SHA256) {\n if (kdfIterations == null) {\n kdfIterations = 5000;\n } else if (kdfIterations < 5000) {\n throw new Error('PBKDF2 iteration minimum is 5000.');\n }\n key = await this.cryptoFunctionService.pbkdf2(password, salt, 'sha256', kdfIterations);\n } else {\n throw new Error('Unknown Kdf.');\n }\n return new SymmetricCryptoKey(key);\n }\n\n async makeKeyFromPin(pin: string, salt: string, kdf: KdfType, kdfIterations: number,\n protectedKeyCs: EncString = null):\n Promise {\n if (protectedKeyCs == null) {\n const pinProtectedKey = await this.storageService.get(ConstantsService.pinProtectedKey);\n if (pinProtectedKey == null) {\n throw new Error('No PIN protected key found.');\n }\n protectedKeyCs = new EncString(pinProtectedKey);\n }\n const pinKey = await this.makePinKey(pin, salt, kdf, kdfIterations);\n const decKey = await this.decryptToBytes(protectedKeyCs, pinKey);\n return new SymmetricCryptoKey(decKey);\n }\n\n async makeShareKey(): Promise<[EncString, SymmetricCryptoKey]> {\n const shareKey = await this.cryptoFunctionService.randomBytes(64);\n const publicKey = await this.getPublicKey();\n const encShareKey = await this.rsaEncrypt(shareKey, publicKey);\n return [encShareKey, new SymmetricCryptoKey(shareKey)];\n }\n\n async makeKeyPair(key?: SymmetricCryptoKey): Promise<[string, EncString]> {\n const keyPair = await this.cryptoFunctionService.rsaGenerateKeyPair(2048);\n const publicB64 = Utils.fromBufferToB64(keyPair[0]);\n const privateEnc = await this.encrypt(keyPair[1], key);\n return [publicB64, privateEnc];\n }\n\n async makePinKey(pin: string, salt: string, kdf: KdfType, kdfIterations: number): Promise {\n const pinKey = await this.makeKey(pin, salt, kdf, kdfIterations);\n return await this.stretchKey(pinKey);\n }\n\n async makeSendKey(keyMaterial: ArrayBuffer): Promise {\n const sendKey = await this.cryptoFunctionService.hkdf(keyMaterial, 'bitwarden-send', 'send', 64, 'sha256');\n return new SymmetricCryptoKey(sendKey);\n }\n\n async hashPassword(password: string, key: SymmetricCryptoKey, hashPurpose?: HashPurpose): Promise {\n if (key == null) {\n key = await this.getKey();\n }\n if (password == null || key == null) {\n throw new Error('Invalid parameters.');\n }\n\n const iterations = hashPurpose === HashPurpose.LocalAuthorization ? 2 : 1;\n const hash = await this.cryptoFunctionService.pbkdf2(key.key, password, 'sha256', iterations);\n return Utils.fromBufferToB64(hash);\n }\n\n async makeEncKey(key: SymmetricCryptoKey): Promise<[SymmetricCryptoKey, EncString]> {\n const theKey = await this.getKeyForEncryption(key);\n const encKey = await this.cryptoFunctionService.randomBytes(64);\n return this.buildEncKey(theKey, encKey);\n }\n\n async remakeEncKey(key: SymmetricCryptoKey, encKey?: SymmetricCryptoKey): Promise<[SymmetricCryptoKey, EncString]> {\n if (encKey == null) {\n encKey = await this.getEncKey();\n }\n return this.buildEncKey(key, encKey.key);\n }\n\n async encrypt(plainValue: string | ArrayBuffer, key?: SymmetricCryptoKey): Promise {\n if (plainValue == null) {\n return Promise.resolve(null);\n }\n\n let plainBuf: ArrayBuffer;\n if (typeof (plainValue) === 'string') {\n plainBuf = Utils.fromUtf8ToArray(plainValue).buffer;\n } else {\n plainBuf = plainValue;\n }\n\n const encObj = await this.aesEncrypt(plainBuf, key);\n const iv = Utils.fromBufferToB64(encObj.iv);\n const data = Utils.fromBufferToB64(encObj.data);\n const mac = encObj.mac != null ? Utils.fromBufferToB64(encObj.mac) : null;\n return new EncString(encObj.key.encType, data, iv, mac);\n }\n\n async encryptToBytes(plainValue: ArrayBuffer, key?: SymmetricCryptoKey): Promise {\n const encValue = await this.aesEncrypt(plainValue, key);\n let macLen = 0;\n if (encValue.mac != null) {\n macLen = encValue.mac.byteLength;\n }\n\n const encBytes = new Uint8Array(1 + encValue.iv.byteLength + macLen + encValue.data.byteLength);\n encBytes.set([encValue.key.encType]);\n encBytes.set(new Uint8Array(encValue.iv), 1);\n if (encValue.mac != null) {\n encBytes.set(new Uint8Array(encValue.mac), 1 + encValue.iv.byteLength);\n }\n\n encBytes.set(new Uint8Array(encValue.data), 1 + encValue.iv.byteLength + macLen);\n return new EncArrayBuffer(encBytes.buffer);\n }\n\n async rsaEncrypt(data: ArrayBuffer, publicKey?: ArrayBuffer): Promise {\n if (publicKey == null) {\n publicKey = await this.getPublicKey();\n }\n if (publicKey == null) {\n throw new Error('Public key unavailable.');\n }\n\n const encBytes = await this.cryptoFunctionService.rsaEncrypt(data, publicKey, 'sha1');\n return new EncString(EncryptionType.Rsa2048_OaepSha1_B64, Utils.fromBufferToB64(encBytes));\n }\n\n async rsaDecrypt(encValue: string, privateKeyValue?: ArrayBuffer): Promise {\n const headerPieces = encValue.split('.');\n let encType: EncryptionType = null;\n let encPieces: string[];\n\n if (headerPieces.length === 1) {\n encType = EncryptionType.Rsa2048_OaepSha256_B64;\n encPieces = [headerPieces[0]];\n } else if (headerPieces.length === 2) {\n try {\n encType = parseInt(headerPieces[0], null);\n encPieces = headerPieces[1].split('|');\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n switch (encType) {\n case EncryptionType.Rsa2048_OaepSha256_B64:\n case EncryptionType.Rsa2048_OaepSha1_B64:\n // HmacSha256 types are deprecated\n case EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64:\n case EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64:\n break;\n default:\n throw new Error('encType unavailable.');\n }\n\n if (encPieces == null || encPieces.length <= 0) {\n throw new Error('encPieces unavailable.');\n }\n\n const data = Utils.fromB64ToArray(encPieces[0]).buffer;\n const privateKey = privateKeyValue ?? await this.getPrivateKey();\n if (privateKey == null) {\n throw new Error('No private key.');\n }\n\n let alg: 'sha1' | 'sha256' = 'sha1';\n switch (encType) {\n case EncryptionType.Rsa2048_OaepSha256_B64:\n case EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64:\n alg = 'sha256';\n break;\n case EncryptionType.Rsa2048_OaepSha1_B64:\n case EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64:\n break;\n default:\n throw new Error('encType unavailable.');\n }\n\n return this.cryptoFunctionService.rsaDecrypt(data, privateKey, alg);\n }\n\n async decryptToBytes(encString: EncString, key?: SymmetricCryptoKey): Promise {\n const iv = Utils.fromB64ToArray(encString.iv).buffer;\n const data = Utils.fromB64ToArray(encString.data).buffer;\n const mac = encString.mac ? Utils.fromB64ToArray(encString.mac).buffer : null;\n const decipher = await this.aesDecryptToBytes(encString.encryptionType, data, iv, mac, key);\n if (decipher == null) {\n return null;\n }\n\n return decipher;\n }\n\n async decryptToUtf8(encString: EncString, key?: SymmetricCryptoKey): Promise {\n return await this.aesDecryptToUtf8(encString.encryptionType, encString.data,\n encString.iv, encString.mac, key);\n }\n\n async decryptFromBytes(encBuf: ArrayBuffer, key: SymmetricCryptoKey): Promise {\n if (encBuf == null) {\n throw new Error('no encBuf.');\n }\n\n const encBytes = new Uint8Array(encBuf);\n const encType = encBytes[0];\n let ctBytes: Uint8Array = null;\n let ivBytes: Uint8Array = null;\n let macBytes: Uint8Array = null;\n\n switch (encType) {\n case EncryptionType.AesCbc128_HmacSha256_B64:\n case EncryptionType.AesCbc256_HmacSha256_B64:\n if (encBytes.length <= 49) { // 1 + 16 + 32 + ctLength\n return null;\n }\n\n ivBytes = encBytes.slice(1, 17);\n macBytes = encBytes.slice(17, 49);\n ctBytes = encBytes.slice(49);\n break;\n case EncryptionType.AesCbc256_B64:\n if (encBytes.length <= 17) { // 1 + 16 + ctLength\n return null;\n }\n\n ivBytes = encBytes.slice(1, 17);\n ctBytes = encBytes.slice(17);\n break;\n default:\n return null;\n }\n\n return await this.aesDecryptToBytes(encType, ctBytes.buffer, ivBytes.buffer,\n macBytes != null ? macBytes.buffer : null, key);\n }\n\n // EFForg/OpenWireless\n // ref https://github.com/EFForg/OpenWireless/blob/master/app/js/diceware.js\n async randomNumber(min: number, max: number): Promise {\n let rval = 0;\n const range = max - min + 1;\n const bitsNeeded = Math.ceil(Math.log2(range));\n if (bitsNeeded > 53) {\n throw new Error('We cannot generate numbers larger than 53 bits.');\n }\n\n const bytesNeeded = Math.ceil(bitsNeeded / 8);\n const mask = Math.pow(2, bitsNeeded) - 1;\n // 7776 -> (2^13 = 8192) -1 == 8191 or 0x00001111 11111111\n\n // Fill a byte array with N random numbers\n const byteArray = new Uint8Array(await this.cryptoFunctionService.randomBytes(bytesNeeded));\n\n let p = (bytesNeeded - 1) * 8;\n for (let i = 0; i < bytesNeeded; i++) {\n rval += byteArray[i] * Math.pow(2, p);\n p -= 8;\n }\n\n // Use & to apply the mask and reduce the number of recursive lookups\n // tslint:disable-next-line\n rval = rval & mask;\n\n if (rval >= range) {\n // Integer out of acceptable range\n return this.randomNumber(min, max);\n }\n\n // Return an integer that falls within the range\n return min + rval;\n }\n\n async validateKey(key: SymmetricCryptoKey) {\n try {\n const encPrivateKey = await this.storageService.get(Keys.encPrivateKey);\n const encKey = await this.getEncKey(key);\n if (encPrivateKey == null || encKey == null) {\n return false;\n }\n\n const privateKey = await this.decryptToBytes(new EncString(encPrivateKey), encKey);\n await this.cryptoFunctionService.rsaExtractPublicKey(privateKey);\n } catch (e) {\n return false;\n }\n\n return true;\n }\n\n // Helpers\n\n protected async storeKey(key: SymmetricCryptoKey) {\n if (await this.shouldStoreKey('auto') || await this.shouldStoreKey('biometric')) {\n this.secureStorageService.save(Keys.key, key.keyB64);\n } else {\n this.secureStorageService.remove(Keys.key);\n }\n }\n\n protected async shouldStoreKey(keySuffix: KeySuffixOptions) {\n let shouldStoreKey = false;\n if (keySuffix === 'auto') {\n const vaultTimeout = await this.storageService.get(ConstantsService.vaultTimeoutKey);\n shouldStoreKey = vaultTimeout == null;\n } else if (keySuffix === 'biometric') {\n const biometricUnlock = await this.storageService.get(ConstantsService.biometricUnlockKey);\n shouldStoreKey = biometricUnlock && this.platformUtilService.supportsSecureStorage();\n }\n return shouldStoreKey;\n }\n\n protected retrieveKeyFromStorage(keySuffix: KeySuffixOptions) {\n return this.secureStorageService.get(Keys.key, { keySuffix: keySuffix });\n }\n\n private async aesEncrypt(data: ArrayBuffer, key: SymmetricCryptoKey): Promise {\n const obj = new EncryptedObject();\n obj.key = await this.getKeyForEncryption(key);\n obj.iv = await this.cryptoFunctionService.randomBytes(16);\n obj.data = await this.cryptoFunctionService.aesEncrypt(data, obj.iv, obj.key.encKey);\n\n if (obj.key.macKey != null) {\n const macData = new Uint8Array(obj.iv.byteLength + obj.data.byteLength);\n macData.set(new Uint8Array(obj.iv), 0);\n macData.set(new Uint8Array(obj.data), obj.iv.byteLength);\n obj.mac = await this.cryptoFunctionService.hmac(macData.buffer, obj.key.macKey, 'sha256');\n }\n\n return obj;\n }\n\n private async aesDecryptToUtf8(encType: EncryptionType, data: string, iv: string, mac: string,\n key: SymmetricCryptoKey): Promise {\n const keyForEnc = await this.getKeyForEncryption(key);\n const theKey = this.resolveLegacyKey(encType, keyForEnc);\n\n if (theKey.macKey != null && mac == null) {\n this.logService.error('mac required.');\n return null;\n }\n\n if (theKey.encType !== encType) {\n this.logService.error('encType unavailable.');\n return null;\n }\n\n const fastParams = this.cryptoFunctionService.aesDecryptFastParameters(data, iv, mac, theKey);\n if (fastParams.macKey != null && fastParams.mac != null) {\n const computedMac = await this.cryptoFunctionService.hmacFast(fastParams.macData,\n fastParams.macKey, 'sha256');\n const macsEqual = await this.cryptoFunctionService.compareFast(fastParams.mac, computedMac);\n if (!macsEqual) {\n this.logService.error('mac failed.');\n return null;\n }\n }\n\n return this.cryptoFunctionService.aesDecryptFast(fastParams);\n }\n\n private async aesDecryptToBytes(encType: EncryptionType, data: ArrayBuffer, iv: ArrayBuffer,\n mac: ArrayBuffer, key: SymmetricCryptoKey): Promise {\n const keyForEnc = await this.getKeyForEncryption(key);\n const theKey = this.resolveLegacyKey(encType, keyForEnc);\n\n if (theKey.macKey != null && mac == null) {\n return null;\n }\n\n if (theKey.encType !== encType) {\n return null;\n }\n\n if (theKey.macKey != null && mac != null) {\n const macData = new Uint8Array(iv.byteLength + data.byteLength);\n macData.set(new Uint8Array(iv), 0);\n macData.set(new Uint8Array(data), iv.byteLength);\n const computedMac = await this.cryptoFunctionService.hmac(macData.buffer, theKey.macKey, 'sha256');\n if (computedMac === null) {\n return null;\n }\n\n const macsMatch = await this.cryptoFunctionService.compare(mac, computedMac);\n if (!macsMatch) {\n this.logService.error('mac failed.');\n return null;\n }\n }\n\n return await this.cryptoFunctionService.aesDecrypt(data, iv, theKey.encKey);\n }\n\n private async getKeyForEncryption(key?: SymmetricCryptoKey): Promise {\n if (key != null) {\n return key;\n }\n\n const encKey = await this.getEncKey();\n if (encKey != null) {\n return encKey;\n }\n\n return await this.getKey();\n }\n\n private resolveLegacyKey(encType: EncryptionType, key: SymmetricCryptoKey): SymmetricCryptoKey {\n if (encType === EncryptionType.AesCbc128_HmacSha256_B64 &&\n key.encType === EncryptionType.AesCbc256_B64) {\n // Old encrypt-then-mac scheme, make a new key\n if (this.legacyEtmKey == null) {\n this.legacyEtmKey = new SymmetricCryptoKey(key.key, EncryptionType.AesCbc128_HmacSha256_B64);\n }\n return this.legacyEtmKey;\n }\n\n return key;\n }\n\n private async stretchKey(key: SymmetricCryptoKey): Promise {\n const newKey = new Uint8Array(64);\n const encKey = await this.cryptoFunctionService.hkdfExpand(key.key, 'enc', 32, 'sha256');\n const macKey = await this.cryptoFunctionService.hkdfExpand(key.key, 'mac', 32, 'sha256');\n newKey.set(new Uint8Array(encKey));\n newKey.set(new Uint8Array(macKey), 32);\n return new SymmetricCryptoKey(newKey.buffer);\n }\n\n private async hashPhrase(hash: ArrayBuffer, minimumEntropy: number = 64) {\n const entropyPerWord = Math.log(EEFLongWordList.length) / Math.log(2);\n let numWords = Math.ceil(minimumEntropy / entropyPerWord);\n\n const hashArr = Array.from(new Uint8Array(hash));\n const entropyAvailable = hashArr.length * 4;\n if (numWords * entropyPerWord > entropyAvailable) {\n throw new Error('Output entropy of hash function is too small');\n }\n\n const phrase: string[] = [];\n let hashNumber = bigInt.fromArray(hashArr, 256);\n while (numWords--) {\n const remainder = hashNumber.mod(EEFLongWordList.length);\n hashNumber = hashNumber.divide(EEFLongWordList.length);\n phrase.push(EEFLongWordList[remainder as any]);\n }\n return phrase;\n }\n\n private async buildEncKey(key: SymmetricCryptoKey, encKey: ArrayBuffer)\n : Promise<[SymmetricCryptoKey, EncString]> {\n let encKeyEnc: EncString = null;\n if (key.key.byteLength === 32) {\n const newKey = await this.stretchKey(key);\n encKeyEnc = await this.encrypt(encKey, newKey);\n } else if (key.key.byteLength === 64) {\n encKeyEnc = await this.encrypt(encKey, key);\n } else {\n throw new Error('Invalid key size.');\n }\n return [new SymmetricCryptoKey(encKey), encKeyEnc];\n }\n}\n","export class EncArrayBuffer {\n constructor(public buffer: ArrayBuffer) { }\n}\n","import { SymmetricCryptoKey } from './symmetricCryptoKey';\n\nexport class EncryptedObject {\n iv: ArrayBuffer;\n data: ArrayBuffer;\n mac: ArrayBuffer;\n key: SymmetricCryptoKey;\n}\n","import { Observable, Subject } from 'rxjs';\n\nimport { EnvironmentUrls } from '../models/domain/environmentUrls';\n\nimport { ConstantsService } from './constants.service';\n\nimport { EnvironmentService as EnvironmentServiceAbstraction, Urls } from '../abstractions/environment.service';\nimport { StorageService } from '../abstractions/storage.service';\n\nexport class EnvironmentService implements EnvironmentServiceAbstraction {\n\n private readonly urlsSubject = new Subject();\n urls: Observable = this.urlsSubject; // tslint:disable-line\n\n private baseUrl: string;\n private webVaultUrl: string;\n private apiUrl: string;\n private identityUrl: string;\n private iconsUrl: string;\n private notificationsUrl: string;\n private eventsUrl: string;\n private keyConnectorUrl: string;\n\n constructor(private storageService: StorageService) {}\n\n hasBaseUrl() {\n return this.baseUrl != null;\n }\n\n getNotificationsUrl() {\n if (this.notificationsUrl != null) {\n return this.notificationsUrl;\n }\n\n if (this.baseUrl != null) {\n return this.baseUrl + '/notifications';\n }\n\n return 'https://notifications.bitwarden.com';\n }\n\n getWebVaultUrl() {\n if (this.webVaultUrl != null) {\n return this.webVaultUrl;\n }\n\n if (this.baseUrl) {\n return this.baseUrl;\n }\n return 'https://vault.bitwarden.com';\n }\n\n getSendUrl() {\n return this.getWebVaultUrl() === 'https://vault.bitwarden.com'\n ? 'https://send.bitwarden.com/#'\n : this.getWebVaultUrl() + '/#/send/';\n }\n\n getIconsUrl() {\n if (this.iconsUrl != null) {\n return this.iconsUrl;\n }\n\n if (this.baseUrl) {\n return this.baseUrl + '/icons';\n }\n\n return 'https://icons.bitwarden.net';\n }\n\n getApiUrl() {\n if (this.apiUrl != null) {\n return this.apiUrl;\n }\n\n if (this.baseUrl) {\n return this.baseUrl + '/api';\n }\n\n return 'https://api.bitwarden.com';\n }\n\n getIdentityUrl() {\n if (this.identityUrl != null) {\n return this.identityUrl;\n }\n\n if (this.baseUrl) {\n return this.baseUrl + '/identity';\n }\n\n return 'https://identity.bitwarden.com';\n }\n\n getEventsUrl() {\n if (this.eventsUrl != null) {\n return this.eventsUrl;\n }\n\n if (this.baseUrl) {\n return this.baseUrl + '/events';\n }\n\n return 'https://events.bitwarden.com';\n }\n\n getKeyConnectorUrl() {\n return this.keyConnectorUrl;\n }\n\n async setUrlsFromStorage(): Promise {\n const urlsObj: any = await this.storageService.get(ConstantsService.environmentUrlsKey);\n const urls = urlsObj || {\n base: null,\n api: null,\n identity: null,\n icons: null,\n notifications: null,\n events: null,\n webVault: null,\n keyConnector: null,\n };\n\n const envUrls = new EnvironmentUrls();\n\n if (urls.base) {\n this.baseUrl = envUrls.base = urls.base;\n return;\n }\n\n this.webVaultUrl = urls.webVault;\n this.apiUrl = envUrls.api = urls.api;\n this.identityUrl = envUrls.identity = urls.identity;\n this.iconsUrl = urls.icons;\n this.notificationsUrl = urls.notifications;\n this.eventsUrl = envUrls.events = urls.events;\n this.keyConnectorUrl = urls.keyConnector;\n }\n\n async setUrls(urls: Urls, saveSettings: boolean = true): Promise {\n urls.base = this.formatUrl(urls.base);\n urls.webVault = this.formatUrl(urls.webVault);\n urls.api = this.formatUrl(urls.api);\n urls.identity = this.formatUrl(urls.identity);\n urls.icons = this.formatUrl(urls.icons);\n urls.notifications = this.formatUrl(urls.notifications);\n urls.events = this.formatUrl(urls.events);\n urls.keyConnector = this.formatUrl(urls.keyConnector);\n\n if (saveSettings) {\n await this.storageService.save(ConstantsService.environmentUrlsKey, {\n base: urls.base,\n api: urls.api,\n identity: urls.identity,\n webVault: urls.webVault,\n icons: urls.icons,\n notifications: urls.notifications,\n events: urls.events,\n keyConnector: urls.keyConnector,\n });\n }\n\n this.baseUrl = urls.base;\n this.webVaultUrl = urls.webVault;\n this.apiUrl = urls.api;\n this.identityUrl = urls.identity;\n this.iconsUrl = urls.icons;\n this.notificationsUrl = urls.notifications;\n this.eventsUrl = urls.events;\n this.keyConnectorUrl = urls.keyConnector;\n\n this.urlsSubject.next(urls);\n\n return urls;\n }\n\n getUrls() {\n return {\n base: this.baseUrl,\n webVault: this.webVaultUrl,\n api: this.apiUrl,\n identity: this.identityUrl,\n icons: this.iconsUrl,\n notifications: this.notificationsUrl,\n events: this.eventsUrl,\n keyConnector: this.keyConnectorUrl,\n };\n }\n\n private formatUrl(url: string): string {\n if (url == null || url === '') {\n return null;\n }\n\n url = url.replace(/\\/+$/g, '');\n if (!url.startsWith('http://') && !url.startsWith('https://')) {\n url = 'https://' + url;\n }\n\n return url.trim();\n }\n}\n","export class EnvironmentUrls {\n base: string;\n api: string;\n identity: string;\n events: string;\n}\n","import { EventType } from '../enums/eventType';\n\nimport { EventData } from '../models/data/eventData';\n\nimport { EventRequest } from '../models/request/eventRequest';\n\nimport { ApiService } from '../abstractions/api.service';\nimport { CipherService } from '../abstractions/cipher.service';\nimport { EventService as EventServiceAbstraction } from '../abstractions/event.service';\nimport { StorageService } from '../abstractions/storage.service';\nimport { UserService } from '../abstractions/user.service';\n\nimport { LogService } from '../abstractions/log.service';\nimport { ConstantsService } from './constants.service';\n\nexport class EventService implements EventServiceAbstraction {\n private inited = false;\n\n constructor(private storageService: StorageService, private apiService: ApiService,\n private userService: UserService, private cipherService: CipherService,\n private logService: LogService) { }\n\n init(checkOnInterval: boolean) {\n if (this.inited) {\n return;\n }\n\n this.inited = true;\n if (checkOnInterval) {\n this.uploadEvents();\n setInterval(() => this.uploadEvents(), 60 * 1000); // check every 60 seconds\n }\n }\n\n async collect(eventType: EventType, cipherId: string = null, uploadImmediately = false): Promise {\n const authed = await this.userService.isAuthenticated();\n if (!authed) {\n return;\n }\n const organizations = await this.userService.getAllOrganizations();\n if (organizations == null) {\n return;\n }\n const orgIds = new Set(organizations.filter(o => o.useEvents).map(o => o.id));\n if (orgIds.size === 0) {\n return;\n }\n if (cipherId != null) {\n const cipher = await this.cipherService.get(cipherId);\n if (cipher == null || cipher.organizationId == null || !orgIds.has(cipher.organizationId)) {\n return;\n }\n }\n let eventCollection = await this.storageService.get(ConstantsService.eventCollectionKey);\n if (eventCollection == null) {\n eventCollection = [];\n }\n const event = new EventData();\n event.type = eventType;\n event.cipherId = cipherId;\n event.date = new Date().toISOString();\n eventCollection.push(event);\n await this.storageService.save(ConstantsService.eventCollectionKey, eventCollection);\n if (uploadImmediately) {\n await this.uploadEvents();\n }\n }\n\n async uploadEvents(): Promise {\n const authed = await this.userService.isAuthenticated();\n if (!authed) {\n return;\n }\n const eventCollection = await this.storageService.get(ConstantsService.eventCollectionKey);\n if (eventCollection == null || eventCollection.length === 0) {\n return;\n }\n const request = eventCollection.map(e => {\n const req = new EventRequest();\n req.type = e.type;\n req.cipherId = e.cipherId;\n req.date = e.date;\n return req;\n });\n try {\n await this.apiService.postEventsCollect(request);\n this.clearEvents();\n } catch (e) {\n this.logService.error(e);\n }\n }\n\n async clearEvents(): Promise {\n await this.storageService.remove(ConstantsService.eventCollectionKey);\n }\n}\n","import { EventType } from '../../enums/eventType';\n\nexport class EventData {\n type: EventType;\n cipherId: string;\n date: string;\n}\n","import { EventType } from '../../enums/eventType';\n\nexport class EventRequest {\n type: EventType;\n cipherId: string;\n date: string;\n}\n","import * as papa from 'papaparse';\n\nimport { CipherType } from '../enums/cipherType';\n\nimport { ApiService } from '../abstractions/api.service';\nimport { CipherService } from '../abstractions/cipher.service';\nimport { CryptoService } from '../abstractions/crypto.service';\nimport { ExportService as ExportServiceAbstraction } from '../abstractions/export.service';\nimport { FolderService } from '../abstractions/folder.service';\n\nimport { CipherView } from '../models/view/cipherView';\nimport { CollectionView } from '../models/view/collectionView';\nimport { FolderView } from '../models/view/folderView';\n\nimport { Cipher } from '../models/domain/cipher';\nimport { Collection } from '../models/domain/collection';\nimport { Folder } from '../models/domain/folder';\n\nimport { CipherData } from '../models/data/cipherData';\nimport { CollectionData } from '../models/data/collectionData';\nimport { CollectionDetailsResponse } from '../models/response/collectionResponse';\n\nimport { CipherWithIds as CipherExport } from '../models/export/cipherWithIds';\nimport { CollectionWithId as CollectionExport } from '../models/export/collectionWithId';\nimport { Event } from '../models/export/event';\nimport { FolderWithId as FolderExport } from '../models/export/folderWithId';\nimport { EventView } from '../models/view/eventView';\n\nimport { Utils } from '../misc/utils';\n\nexport class ExportService implements ExportServiceAbstraction {\n constructor(private folderService: FolderService, private cipherService: CipherService,\n private apiService: ApiService, private cryptoService: CryptoService) { }\n\n async getExport(format: 'csv' | 'json' | 'encrypted_json' = 'csv'): Promise {\n if (format === 'encrypted_json') {\n return this.getEncryptedExport();\n } else {\n return this.getDecryptedExport(format);\n }\n }\n\n async getOrganizationExport(organizationId: string,\n format: 'csv' | 'json' | 'encrypted_json' = 'csv'): Promise {\n if (format === 'encrypted_json') {\n return this.getOrganizationEncryptedExport(organizationId);\n } else {\n return this.getOrganizationDecryptedExport(organizationId, format);\n }\n }\n\n async getEventExport(events: EventView[]): Promise {\n return papa.unparse(events.map(e => new Event(e)));\n }\n\n getFileName(prefix: string = null, extension: string = 'csv'): string {\n const now = new Date();\n const dateString =\n now.getFullYear() + '' + this.padNumber(now.getMonth() + 1, 2) + '' + this.padNumber(now.getDate(), 2) +\n this.padNumber(now.getHours(), 2) + '' + this.padNumber(now.getMinutes(), 2) +\n this.padNumber(now.getSeconds(), 2);\n\n return 'bitwarden' + (prefix ? ('_' + prefix) : '') + '_export_' + dateString + '.' + extension;\n }\n\n private async getDecryptedExport(format: 'json' | 'csv'): Promise {\n let decFolders: FolderView[] = [];\n let decCiphers: CipherView[] = [];\n const promises = [];\n\n promises.push(this.folderService.getAllDecrypted().then(folders => {\n decFolders = folders;\n }));\n\n promises.push(this.cipherService.getAllDecrypted().then(ciphers => {\n decCiphers = ciphers.filter(f => f.deletedDate == null);\n }));\n\n await Promise.all(promises);\n\n if (format === 'csv') {\n const foldersMap = new Map();\n decFolders.forEach(f => {\n if (f.id != null) {\n foldersMap.set(f.id, f);\n }\n });\n\n const exportCiphers: any[] = [];\n decCiphers.forEach(c => {\n // only export logins and secure notes\n if (c.type !== CipherType.Login && c.type !== CipherType.SecureNote) {\n return;\n }\n if (c.organizationId != null) {\n return;\n }\n\n const cipher: any = {};\n cipher.folder = c.folderId != null && foldersMap.has(c.folderId) ?\n foldersMap.get(c.folderId).name : null;\n cipher.favorite = c.favorite ? 1 : null;\n this.buildCommonCipher(cipher, c);\n exportCiphers.push(cipher);\n });\n\n return papa.unparse(exportCiphers);\n } else {\n const jsonDoc: any = {\n encrypted: false,\n folders: [],\n items: [],\n };\n\n decFolders.forEach(f => {\n if (f.id == null) {\n return;\n }\n const folder = new FolderExport();\n folder.build(f);\n jsonDoc.folders.push(folder);\n });\n\n decCiphers.forEach(c => {\n if (c.organizationId != null) {\n return;\n }\n const cipher = new CipherExport();\n cipher.build(c);\n cipher.collectionIds = null;\n jsonDoc.items.push(cipher);\n });\n\n return JSON.stringify(jsonDoc, null, ' ');\n }\n }\n\n private async getEncryptedExport(): Promise {\n let folders: Folder[] = [];\n let ciphers: Cipher[] = [];\n const promises = [];\n\n promises.push(this.folderService.getAll().then(f => {\n folders = f;\n }));\n\n promises.push(this.cipherService.getAll().then(c => {\n ciphers = c.filter(f => f.deletedDate == null);\n }));\n\n await Promise.all(promises);\n\n const encKeyValidation = await this.cryptoService.encrypt(Utils.newGuid());\n\n const jsonDoc: any = {\n encrypted: true,\n encKeyValidation_DO_NOT_EDIT: encKeyValidation.encryptedString,\n folders: [],\n items: [],\n };\n\n folders.forEach(f => {\n if (f.id == null) {\n return;\n }\n const folder = new FolderExport();\n folder.build(f);\n jsonDoc.folders.push(folder);\n });\n\n ciphers.forEach(c => {\n if (c.organizationId != null) {\n return;\n }\n const cipher = new CipherExport();\n cipher.build(c);\n cipher.collectionIds = null;\n jsonDoc.items.push(cipher);\n });\n\n return JSON.stringify(jsonDoc, null, ' ');\n }\n\n private async getOrganizationDecryptedExport(organizationId: string, format: 'json' | 'csv'): Promise {\n const decCollections: CollectionView[] = [];\n const decCiphers: CipherView[] = [];\n const promises = [];\n\n promises.push(this.apiService.getCollections(organizationId).then(collections => {\n const collectionPromises: any = [];\n if (collections != null && collections.data != null && collections.data.length > 0) {\n collections.data.forEach(c => {\n const collection = new Collection(new CollectionData(c as CollectionDetailsResponse));\n collectionPromises.push(collection.decrypt().then(decCol => {\n decCollections.push(decCol);\n }));\n });\n }\n return Promise.all(collectionPromises);\n }));\n\n promises.push(this.apiService.getCiphersOrganization(organizationId).then(ciphers => {\n const cipherPromises: any = [];\n if (ciphers != null && ciphers.data != null && ciphers.data.length > 0) {\n ciphers.data.filter(c => c.deletedDate === null).forEach(c => {\n const cipher = new Cipher(new CipherData(c));\n cipherPromises.push(cipher.decrypt().then(decCipher => {\n decCiphers.push(decCipher);\n }));\n });\n }\n return Promise.all(cipherPromises);\n }));\n\n await Promise.all(promises);\n\n if (format === 'csv') {\n const collectionsMap = new Map();\n decCollections.forEach(c => {\n collectionsMap.set(c.id, c);\n });\n\n const exportCiphers: any[] = [];\n decCiphers.forEach(c => {\n // only export logins and secure notes\n if (c.type !== CipherType.Login && c.type !== CipherType.SecureNote) {\n return;\n }\n\n const cipher: any = {};\n cipher.collections = [];\n if (c.collectionIds != null) {\n cipher.collections = c.collectionIds.filter(id => collectionsMap.has(id))\n .map(id => collectionsMap.get(id).name);\n }\n this.buildCommonCipher(cipher, c);\n exportCiphers.push(cipher);\n });\n\n return papa.unparse(exportCiphers);\n } else {\n const jsonDoc: any = {\n encrypted: false,\n collections: [],\n items: [],\n };\n\n decCollections.forEach(c => {\n const collection = new CollectionExport();\n collection.build(c);\n jsonDoc.collections.push(collection);\n });\n\n decCiphers.forEach(c => {\n const cipher = new CipherExport();\n cipher.build(c);\n jsonDoc.items.push(cipher);\n });\n return JSON.stringify(jsonDoc, null, ' ');\n }\n }\n\n private async getOrganizationEncryptedExport(organizationId: string): Promise {\n const collections: Collection[] = [];\n const ciphers: Cipher[] = [];\n const promises = [];\n\n promises.push(this.apiService.getCollections(organizationId).then(c => {\n const collectionPromises: any = [];\n if (c != null && c.data != null && c.data.length > 0) {\n c.data.forEach(r => {\n const collection = new Collection(new CollectionData(r as CollectionDetailsResponse));\n collections.push(collection);\n });\n }\n return Promise.all(collectionPromises);\n }));\n\n promises.push(this.apiService.getCiphersOrganization(organizationId).then(c => {\n const cipherPromises: any = [];\n if (c != null && c.data != null && c.data.length > 0) {\n c.data.filter(item => item.deletedDate === null).forEach(item => {\n const cipher = new Cipher(new CipherData(item));\n ciphers.push(cipher);\n });\n }\n return Promise.all(cipherPromises);\n }));\n\n await Promise.all(promises);\n\n const orgKey = await this.cryptoService.getOrgKey(organizationId);\n const encKeyValidation = await this.cryptoService.encrypt(Utils.newGuid(), orgKey);\n\n const jsonDoc: any = {\n encrypted: true,\n encKeyValidation_DO_NOT_EDIT: encKeyValidation.encryptedString,\n collections: [],\n items: [],\n };\n\n collections.forEach(c => {\n const collection = new CollectionExport();\n collection.build(c);\n jsonDoc.collections.push(collection);\n });\n\n ciphers.forEach(c => {\n const cipher = new CipherExport();\n cipher.build(c);\n jsonDoc.items.push(cipher);\n });\n return JSON.stringify(jsonDoc, null, ' ');\n }\n\n private padNumber(num: number, width: number, padCharacter: string = '0'): string {\n const numString = num.toString();\n return numString.length >= width ? numString :\n new Array(width - numString.length + 1).join(padCharacter) + numString;\n }\n\n private buildCommonCipher(cipher: any, c: CipherView) {\n cipher.type = null;\n cipher.name = c.name;\n cipher.notes = c.notes;\n cipher.fields = null;\n cipher.reprompt = c.reprompt;\n // Login props\n cipher.login_uri = null;\n cipher.login_username = null;\n cipher.login_password = null;\n cipher.login_totp = null;\n\n if (c.fields) {\n c.fields.forEach((f: any) => {\n if (!cipher.fields) {\n cipher.fields = '';\n } else {\n cipher.fields += '\\n';\n }\n\n cipher.fields += ((f.name || '') + ': ' + f.value);\n });\n }\n\n switch (c.type) {\n case CipherType.Login:\n cipher.type = 'login';\n cipher.login_username = c.login.username;\n cipher.login_password = c.login.password;\n cipher.login_totp = c.login.totp;\n\n if (c.login.uris) {\n cipher.login_uri = [];\n c.login.uris.forEach(u => {\n cipher.login_uri.push(u.uri);\n });\n }\n break;\n case CipherType.SecureNote:\n cipher.type = 'note';\n break;\n default:\n return;\n }\n\n return cipher;\n }\n}\n","import { CipherRepromptType } from '../../enums/cipherRepromptType';\nimport { CipherType } from '../../enums/cipherType';\n\nimport { CipherView } from '../view/cipherView';\n\nimport { Cipher as CipherDomain } from '../domain/cipher';\nimport { EncString } from '../domain/encString';\n\nimport { Card } from './card';\nimport { Field } from './field';\nimport { Identity } from './identity';\nimport { Login } from './login';\nimport { SecureNote } from './secureNote';\n\nexport class Cipher {\n static template(): Cipher {\n const req = new Cipher();\n req.organizationId = null;\n req.collectionIds = null;\n req.folderId = null;\n req.type = CipherType.Login;\n req.name = 'Item name';\n req.notes = 'Some notes about this item.';\n req.favorite = false;\n req.fields = [];\n req.login = null;\n req.secureNote = null;\n req.card = null;\n req.identity = null;\n req.reprompt = CipherRepromptType.None;\n return req;\n }\n\n static toView(req: Cipher, view = new CipherView()) {\n view.type = req.type;\n view.folderId = req.folderId;\n if (view.organizationId == null) {\n view.organizationId = req.organizationId;\n }\n if (view.collectionIds || req.collectionIds) {\n const set = new Set((view.collectionIds ?? []).concat(req.collectionIds ?? []));\n view.collectionIds = Array.from(set.values());\n }\n view.name = req.name;\n view.notes = req.notes;\n view.favorite = req.favorite;\n view.reprompt = req.reprompt ?? CipherRepromptType.None;\n\n if (req.fields != null) {\n view.fields = req.fields.map(f => Field.toView(f));\n }\n\n switch (req.type) {\n case CipherType.Login:\n view.login = Login.toView(req.login);\n break;\n case CipherType.SecureNote:\n view.secureNote = SecureNote.toView(req.secureNote);\n break;\n case CipherType.Card:\n view.card = Card.toView(req.card);\n break;\n case CipherType.Identity:\n view.identity = Identity.toView(req.identity);\n break;\n }\n\n return view;\n }\n\n static toDomain(req: Cipher, domain = new CipherDomain()) {\n domain.type = req.type;\n domain.folderId = req.folderId;\n if (domain.organizationId == null) {\n domain.organizationId = req.organizationId;\n }\n domain.name = req.name != null ? new EncString(req.name) : null;\n domain.notes = req.notes != null ? new EncString(req.notes) : null;\n domain.favorite = req.favorite;\n domain.reprompt = req.reprompt ?? CipherRepromptType.None;\n\n if (req.fields != null) {\n domain.fields = req.fields.map(f => Field.toDomain(f));\n }\n\n switch (req.type) {\n case CipherType.Login:\n domain.login = Login.toDomain(req.login);\n break;\n case CipherType.SecureNote:\n domain.secureNote = SecureNote.toDomain(req.secureNote);\n break;\n case CipherType.Card:\n domain.card = Card.toDomain(req.card);\n break;\n case CipherType.Identity:\n domain.identity = Identity.toDomain(req.identity);\n break;\n }\n\n return domain;\n }\n\n type: CipherType;\n folderId: string;\n organizationId: string;\n collectionIds: string[];\n name: string;\n notes: string;\n favorite: boolean;\n fields: Field[];\n login: Login;\n secureNote: SecureNote;\n card: Card;\n identity: Identity;\n reprompt: CipherRepromptType;\n\n // Use build method instead of ctor so that we can control order of JSON stringify for pretty print\n build(o: CipherView | CipherDomain) {\n this.organizationId = o.organizationId;\n this.folderId = o.folderId;\n this.type = o.type;\n this.reprompt = o.reprompt;\n\n if (o instanceof CipherView) {\n this.name = o.name;\n this.notes = o.notes;\n } else {\n this.name = o.name?.encryptedString;\n this.notes = o.notes?.encryptedString;\n }\n\n this.favorite = o.favorite;\n\n if (o.fields != null) {\n if (o instanceof CipherView) {\n this.fields = o.fields.map(f => new Field(f));\n } else {\n this.fields = o.fields.map(f => new Field(f));\n }\n }\n\n switch (o.type) {\n case CipherType.Login:\n this.login = new Login(o.login);\n break;\n case CipherType.SecureNote:\n this.secureNote = new SecureNote(o.secureNote);\n break;\n case CipherType.Card:\n this.card = new Card(o.card);\n break;\n case CipherType.Identity:\n this.identity = new Identity(o.identity);\n break;\n }\n }\n}\n","import { CardView } from '../view/cardView';\n\nimport { Card as CardDomain } from '../domain/card';\nimport { EncString } from '../domain/encString';\n\nexport class Card {\n static template(): Card {\n const req = new Card();\n req.cardholderName = 'John Doe';\n req.brand = 'visa';\n req.number = '4242424242424242';\n req.expMonth = '04';\n req.expYear = '2023';\n req.code = '123';\n return req;\n }\n\n static toView(req: Card, view = new CardView()) {\n view.cardholderName = req.cardholderName;\n view.brand = req.brand;\n view.number = req.number;\n view.expMonth = req.expMonth;\n view.expYear = req.expYear;\n view.code = req.code;\n return view;\n }\n\n static toDomain(req: Card, domain = new CardDomain()) {\n domain.cardholderName = req.cardholderName != null ? new EncString(req.cardholderName) : null;\n domain.brand = req.brand != null ? new EncString(req.brand) : null;\n domain.number = req.number != null ? new EncString(req.number) : null;\n domain.expMonth = req.expMonth != null ? new EncString(req.expMonth) : null;\n domain.expYear = req.expYear != null ? new EncString(req.expYear) : null;\n domain.code = req.code != null ? new EncString(req.code) : null;\n return domain;\n }\n\n cardholderName: string;\n brand: string;\n number: string;\n expMonth: string;\n expYear: string;\n code: string;\n\n constructor(o?: CardView | CardDomain) {\n if (o == null) {\n return;\n }\n\n if (o instanceof CardView) {\n this.cardholderName = o.cardholderName;\n this.brand = o.brand;\n this.number = o.number;\n this.expMonth = o.expMonth;\n this.expYear = o.expYear;\n this.code = o.code;\n } else {\n this.cardholderName = o.cardholderName?.encryptedString;\n this.brand = o.brand?.encryptedString;\n this.number = o.number?.encryptedString;\n this.expMonth = o.expMonth?.encryptedString;\n this.expYear = o.expYear?.encryptedString;\n this.code = o.code?.encryptedString;\n }\n }\n}\n","import { FieldType } from '../../enums/fieldType';\nimport { LinkedIdType } from '../../enums/linkedIdType';\n\nimport { FieldView } from '../view/fieldView';\n\nimport { EncString } from '../domain/encString';\nimport { Field as FieldDomain } from '../domain/field';\n\nexport class Field {\n static template(): Field {\n const req = new Field();\n req.name = 'Field name';\n req.value = 'Some value';\n req.type = FieldType.Text;\n return req;\n }\n\n static toView(req: Field, view = new FieldView()) {\n view.type = req.type;\n view.value = req.value;\n view.name = req.name;\n view.linkedId = req.linkedId;\n return view;\n }\n\n static toDomain(req: Field, domain = new FieldDomain()) {\n domain.type = req.type;\n domain.value = req.value != null ? new EncString(req.value) : null;\n domain.name = req.name != null ? new EncString(req.name) : null;\n domain.linkedId = req.linkedId;\n return domain;\n }\n\n name: string;\n value: string;\n type: FieldType;\n linkedId: LinkedIdType;\n\n constructor(o?: FieldView | FieldDomain) {\n if (o == null) {\n return;\n }\n\n if (o instanceof FieldView) {\n this.name = o.name;\n this.value = o.value;\n } else {\n this.name = o.name?.encryptedString;\n this.value = o.value?.encryptedString;\n }\n this.type = o.type;\n this.linkedId = o.linkedId;\n }\n}\n","import { IdentityView } from '../view/identityView';\n\nimport { EncString } from '../domain/encString';\nimport { Identity as IdentityDomain } from '../domain/identity';\n\nexport class Identity {\n static template(): Identity {\n const req = new Identity();\n req.title = 'Mr';\n req.firstName = 'John';\n req.middleName = 'William';\n req.lastName = 'Doe';\n req.address1 = '123 Any St';\n req.address2 = 'Apt #123';\n req.address3 = null;\n req.city = 'New York';\n req.state = 'NY';\n req.postalCode = '10001';\n req.country = 'US';\n req.company = 'Acme Inc.';\n req.email = 'john@company.com';\n req.phone = '5555551234';\n req.ssn = '000-123-4567';\n req.username = 'jdoe';\n req.passportNumber = 'US-123456789';\n req.licenseNumber = 'D123-12-123-12333';\n return req;\n }\n\n static toView(req: Identity, view = new IdentityView()) {\n view.title = req.title;\n view.firstName = req.firstName;\n view.middleName = req.middleName;\n view.lastName = req.lastName;\n view.address1 = req.address1;\n view.address2 = req.address2;\n view.address3 = req.address3;\n view.city = req.city;\n view.state = req.state;\n view.postalCode = req.postalCode;\n view.country = req.country;\n view.company = req.company;\n view.email = req.email;\n view.phone = req.phone;\n view.ssn = req.ssn;\n view.username = req.username;\n view.passportNumber = req.passportNumber;\n view.licenseNumber = req.licenseNumber;\n return view;\n }\n\n static toDomain(req: Identity, domain = new IdentityDomain()) {\n domain.title = req.title != null ? new EncString(req.title) : null;\n domain.firstName = req.firstName != null ? new EncString(req.firstName) : null;\n domain.middleName = req.middleName != null ? new EncString(req.middleName) : null;\n domain.lastName = req.lastName != null ? new EncString(req.lastName) : null;\n domain.address1 = req.address1 != null ? new EncString(req.address1) : null;\n domain.address2 = req.address2 != null ? new EncString(req.address2) : null;\n domain.address3 = req.address3 != null ? new EncString(req.address3) : null;\n domain.city = req.city != null ? new EncString(req.city) : null;\n domain.state = req.state != null ? new EncString(req.state) : null;\n domain.postalCode = req.postalCode != null ? new EncString(req.postalCode) : null;\n domain.country = req.country != null ? new EncString(req.country) : null;\n domain.company = req.company != null ? new EncString(req.company) : null;\n domain.email = req.email != null ? new EncString(req.email) : null;\n domain.phone = req.phone != null ? new EncString(req.phone) : null;\n domain.ssn = req.ssn != null ? new EncString(req.ssn) : null;\n domain.username = req.username != null ? new EncString(req.username) : null;\n domain.passportNumber = req.passportNumber != null ? new EncString(req.passportNumber) : null;\n domain.licenseNumber = req.licenseNumber != null ? new EncString(req.licenseNumber) : null;\n return domain;\n }\n\n title: string;\n firstName: string;\n middleName: string;\n lastName: string;\n address1: string;\n address2: string;\n address3: string;\n city: string;\n state: string;\n postalCode: string;\n country: string;\n company: string;\n email: string;\n phone: string;\n ssn: string;\n username: string;\n passportNumber: string;\n licenseNumber: string;\n\n constructor(o?: IdentityView | IdentityDomain) {\n if (o == null) {\n return;\n }\n\n if (o instanceof IdentityView) {\n this.title = o.title;\n this.firstName = o.firstName;\n this.middleName = o.middleName;\n this.lastName = o.lastName;\n this.address1 = o.address1;\n this.address2 = o.address2;\n this.address3 = o.address3;\n this.city = o.city;\n this.state = o.state;\n this.postalCode = o.postalCode;\n this.country = o.country;\n this.company = o.company;\n this.email = o.email;\n this.phone = o.phone;\n this.ssn = o.ssn;\n this.username = o.username;\n this.passportNumber = o.passportNumber;\n this.licenseNumber = o.licenseNumber;\n } else {\n this.title = o.title?.encryptedString;\n this.firstName = o.firstName?.encryptedString;\n this.middleName = o.middleName?.encryptedString;\n this.lastName = o.lastName?.encryptedString;\n this.address1 = o.address1?.encryptedString;\n this.address2 = o.address2?.encryptedString;\n this.address3 = o.address3?.encryptedString;\n this.city = o.city?.encryptedString;\n this.state = o.state?.encryptedString;\n this.postalCode = o.postalCode?.encryptedString;\n this.country = o.country?.encryptedString;\n this.company = o.company?.encryptedString;\n this.email = o.email?.encryptedString;\n this.phone = o.phone?.encryptedString;\n this.ssn = o.ssn?.encryptedString;\n this.username = o.username?.encryptedString;\n this.passportNumber = o.passportNumber?.encryptedString;\n this.licenseNumber = o.licenseNumber?.encryptedString;\n }\n }\n}\n","import { LoginUri } from './loginUri';\n\nimport { LoginView } from '../view/loginView';\n\nimport { EncString } from '../domain/encString';\nimport { Login as LoginDomain } from '../domain/login';\n\nexport class Login {\n static template(): Login {\n const req = new Login();\n req.uris = [];\n req.username = 'jdoe';\n req.password = 'myp@ssword123';\n req.totp = 'JBSWY3DPEHPK3PXP';\n return req;\n }\n\n static toView(req: Login, view = new LoginView()) {\n if (req.uris != null) {\n view.uris = req.uris.map(u => LoginUri.toView(u));\n }\n view.username = req.username;\n view.password = req.password;\n view.totp = req.totp;\n return view;\n }\n\n static toDomain(req: Login, domain = new LoginDomain()) {\n if (req.uris != null) {\n domain.uris = req.uris.map(u => LoginUri.toDomain(u));\n }\n domain.username = req.username != null ? new EncString(req.username) : null;\n domain.password = req.password != null ? new EncString(req.password) : null;\n domain.totp = req.totp != null ? new EncString(req.totp) : null;\n return domain;\n }\n\n uris: LoginUri[];\n username: string;\n password: string;\n totp: string;\n\n constructor(o?: LoginView | LoginDomain) {\n if (o == null) {\n return;\n }\n\n if (o.uris != null) {\n if (o instanceof LoginView) {\n this.uris = o.uris.map(u => new LoginUri(u));\n } else {\n this.uris = o.uris.map(u => new LoginUri(u));\n }\n }\n\n if (o instanceof LoginView) {\n this.username = o.username;\n this.password = o.password;\n this.totp = o.totp;\n } else {\n this.username = o.username?.encryptedString;\n this.password = o.password?.encryptedString;\n this.totp = o.totp?.encryptedString;\n }\n }\n}\n","import { UriMatchType } from '../../enums/uriMatchType';\n\nimport { LoginUriView } from '../view/loginUriView';\n\nimport { EncString } from '../domain/encString';\nimport { LoginUri as LoginUriDomain } from '../domain/loginUri';\n\nexport class LoginUri {\n static template(): LoginUri {\n const req = new LoginUri();\n req.uri = 'https://google.com';\n req.match = null;\n return req;\n }\n\n static toView(req: LoginUri, view = new LoginUriView()) {\n view.uri = req.uri;\n view.match = req.match;\n return view;\n }\n\n static toDomain(req: LoginUri, domain = new LoginUriDomain()) {\n domain.uri = req.uri != null ? new EncString(req.uri) : null;\n domain.match = req.match;\n return domain;\n }\n\n uri: string;\n match: UriMatchType = null;\n\n constructor(o?: LoginUriView | LoginUriDomain) {\n if (o == null) {\n return;\n }\n\n if (o instanceof LoginUriView) {\n this.uri = o.uri;\n } else {\n this.uri = o.uri?.encryptedString;\n }\n this.match = o.match;\n }\n}\n","import { SecureNoteType } from '../../enums/secureNoteType';\n\nimport { SecureNoteView } from '../view/secureNoteView';\n\nimport { SecureNote as SecureNoteDomain } from '../domain/secureNote';\n\nexport class SecureNote {\n static template(): SecureNote {\n const req = new SecureNote();\n req.type = SecureNoteType.Generic;\n return req;\n }\n\n static toView(req: SecureNote, view = new SecureNoteView()) {\n view.type = req.type;\n return view;\n }\n\n static toDomain(req: SecureNote, view = new SecureNoteDomain()) {\n view.type = req.type;\n return view;\n }\n\n type: SecureNoteType;\n\n constructor(o?: SecureNoteView | SecureNoteDomain) {\n if (o == null) {\n return;\n }\n\n this.type = o.type;\n }\n}\n","import { CollectionView } from '../view/collectionView';\n\nimport { Collection as CollectionDomain } from '../domain/collection';\nimport { EncString } from '../domain/encString';\n\nexport class Collection {\n static template(): Collection {\n const req = new Collection();\n req.organizationId = '00000000-0000-0000-0000-000000000000';\n req.name = 'Collection name';\n req.externalId = null;\n return req;\n }\n\n static toView(req: Collection, view = new CollectionView()) {\n view.name = req.name;\n view.externalId = req.externalId;\n if (view.organizationId == null) {\n view.organizationId = req.organizationId;\n }\n return view;\n }\n\n static toDomain(req: Collection, domain = new CollectionDomain()) {\n domain.name = req.name != null ? new EncString(req.name) : null;\n domain.externalId = req.externalId;\n if (domain.organizationId == null) {\n domain.organizationId = req.organizationId;\n }\n return domain;\n }\n\n organizationId: string;\n name: string;\n externalId: string;\n\n // Use build method instead of ctor so that we can control order of JSON stringify for pretty print\n build(o: CollectionView | CollectionDomain) {\n this.organizationId = o.organizationId;\n if (o instanceof CollectionView) {\n this.name = o.name;\n } else {\n this.name = o.name?.encryptedString;\n }\n this.externalId = o.externalId;\n }\n}\n","import { EventType } from '../../enums/eventType';\nimport { EventView } from '../view/eventView';\n\nexport class Event {\n message: string;\n appIcon: string;\n appName: string;\n userId: string;\n userName: string;\n userEmail: string;\n date: string;\n ip: string;\n type: string;\n\n constructor(event: EventView) {\n this.message = event.humanReadableMessage;\n this.appIcon = event.appIcon;\n this.appName = event.appName;\n this.userId = event.userId;\n this.userName = event.userName;\n this.userEmail = event.userEmail;\n this.date = event.date;\n this.ip = event.ip;\n this.type = EventType[event.type];\n }\n}\n","import { FolderView } from '../view/folderView';\n\nimport { EncString } from '../domain/encString';\nimport { Folder as FolderDomain } from '../domain/folder';\n\nexport class Folder {\n static template(): Folder {\n const req = new Folder();\n req.name = 'Folder name';\n return req;\n }\n\n static toView(req: Folder, view = new FolderView()) {\n view.name = req.name;\n return view;\n }\n\n static toDomain(req: Folder, domain = new FolderDomain()) {\n domain.name = req.name != null ? new EncString(req.name) : null;\n return domain;\n }\n\n name: string;\n\n // Use build method instead of ctor so that we can control order of JSON stringify for pretty print\n build(o: FolderView | FolderDomain) {\n if (o instanceof FolderView) {\n this.name = o.name;\n } else {\n this.name = o.name?.encryptedString;\n }\n }\n}\n","import { ApiService } from '../abstractions/api.service';\nimport { FileUploadService as FileUploadServiceAbstraction } from '../abstractions/fileUpload.service';\nimport { LogService } from '../abstractions/log.service';\n\nimport { FileUploadType } from '../enums/fileUploadType';\n\nimport { EncArrayBuffer } from '../models/domain/encArrayBuffer';\nimport { EncString } from '../models/domain/encString';\n\nimport { AttachmentUploadDataResponse } from '../models/response/attachmentUploadDataResponse';\nimport { SendFileUploadDataResponse } from '../models/response/sendFileUploadDataResponse';\n\nimport { AzureFileUploadService } from './azureFileUpload.service';\nimport { BitwardenFileUploadService } from './bitwardenFileUpload.service';\n\nexport class FileUploadService implements FileUploadServiceAbstraction {\n private azureFileUploadService: AzureFileUploadService;\n private bitwardenFileUploadService: BitwardenFileUploadService;\n\n constructor(private logService: LogService, private apiService: ApiService) {\n this.azureFileUploadService = new AzureFileUploadService(logService);\n this.bitwardenFileUploadService = new BitwardenFileUploadService(apiService);\n }\n\n async uploadSendFile(uploadData: SendFileUploadDataResponse, fileName: EncString, encryptedFileData: EncArrayBuffer) {\n try {\n switch (uploadData.fileUploadType) {\n case FileUploadType.Direct:\n await this.bitwardenFileUploadService.upload(fileName.encryptedString, encryptedFileData,\n fd => this.apiService.postSendFile(uploadData.sendResponse.id, uploadData.sendResponse.file.id, fd));\n break;\n case FileUploadType.Azure:\n const renewalCallback = async () => {\n const renewalResponse = await this.apiService.renewSendFileUploadUrl(uploadData.sendResponse.id,\n uploadData.sendResponse.file.id);\n return renewalResponse.url;\n };\n await this.azureFileUploadService.upload(uploadData.url, encryptedFileData,\n renewalCallback);\n break;\n default:\n throw new Error('Unknown file upload type');\n }\n } catch (e) {\n await this.apiService.deleteSend(uploadData.sendResponse.id);\n throw e;\n }\n }\n\n async uploadCipherAttachment(admin: boolean, uploadData: AttachmentUploadDataResponse, encryptedFileName: EncString,\n encryptedFileData: EncArrayBuffer) {\n const response = admin ? uploadData.cipherMiniResponse : uploadData.cipherResponse;\n try {\n switch (uploadData.fileUploadType) {\n case FileUploadType.Direct:\n await this.bitwardenFileUploadService.upload(encryptedFileName.encryptedString, encryptedFileData,\n fd => this.apiService.postAttachmentFile(response.id, uploadData.attachmentId, fd));\n break;\n case FileUploadType.Azure:\n const renewalCallback = async () => {\n const renewalResponse = await this.apiService.renewAttachmentUploadUrl(response.id,\n uploadData.attachmentId);\n return renewalResponse.url;\n };\n await this.azureFileUploadService.upload(uploadData.url, encryptedFileData, renewalCallback);\n break;\n default:\n throw new Error('Unknown file upload type.');\n }\n } catch (e) {\n if (admin) {\n await this.apiService.deleteCipherAttachmentAdmin(response.id, uploadData.attachmentId);\n } else {\n await this.apiService.deleteCipherAttachment(response.id, uploadData.attachmentId);\n }\n throw e;\n }\n }\n}\n","export enum FileUploadType {\n Direct = 0,\n Azure = 1,\n}\n","import { LogService } from '../abstractions/log.service';\n\nimport { Utils } from '../misc/utils';\n\nimport { EncArrayBuffer } from '../models/domain/encArrayBuffer';\n\nconst MAX_SINGLE_BLOB_UPLOAD_SIZE = 256 * 1024 * 1024; // 256 MiB\nconst MAX_BLOCKS_PER_BLOB = 50000;\n\nexport class AzureFileUploadService {\n constructor(private logService: LogService) { }\n\n async upload(url: string, data: EncArrayBuffer, renewalCallback: () => Promise) {\n if (data.buffer.byteLength <= MAX_SINGLE_BLOB_UPLOAD_SIZE) {\n return await this.azureUploadBlob(url, data);\n } else {\n return await this.azureUploadBlocks(url, data, renewalCallback);\n }\n }\n private async azureUploadBlob(url: string, data: EncArrayBuffer) {\n const urlObject = Utils.getUrl(url);\n const headers = new Headers({\n 'x-ms-date': new Date().toUTCString(),\n 'x-ms-version': urlObject.searchParams.get('sv'),\n 'Content-Length': data.buffer.byteLength.toString(),\n 'x-ms-blob-type': 'BlockBlob',\n });\n\n const request = new Request(url, {\n body: data.buffer,\n cache: 'no-store',\n method: 'PUT',\n headers: headers,\n });\n\n const blobResponse = await fetch(request);\n\n if (blobResponse.status !== 201) {\n throw new Error(`Failed to create Azure blob: ${blobResponse.status}`);\n }\n }\n private async azureUploadBlocks(url: string, data: EncArrayBuffer, renewalCallback: () => Promise) {\n const baseUrl = Utils.getUrl(url);\n const blockSize = this.getMaxBlockSize(baseUrl.searchParams.get('sv'));\n let blockIndex = 0;\n const numBlocks = Math.ceil(data.buffer.byteLength / blockSize);\n const blocksStaged: string[] = [];\n\n if (numBlocks > MAX_BLOCKS_PER_BLOB) {\n throw new Error(`Cannot upload file, exceeds maximum size of ${blockSize * MAX_BLOCKS_PER_BLOB}`);\n }\n\n try {\n while (blockIndex < numBlocks) {\n url = await this.renewUrlIfNecessary(url, renewalCallback);\n const blockUrl = Utils.getUrl(url);\n const blockId = this.encodedBlockId(blockIndex);\n blockUrl.searchParams.append('comp', 'block');\n blockUrl.searchParams.append('blockid', blockId);\n const start = blockIndex * blockSize;\n const blockData = data.buffer.slice(start, start + blockSize);\n const blockHeaders = new Headers({\n 'x-ms-date': new Date().toUTCString(),\n 'x-ms-version': blockUrl.searchParams.get('sv'),\n 'Content-Length': blockData.byteLength.toString(),\n });\n\n const blockRequest = new Request(blockUrl.toString(), {\n body: blockData,\n cache: 'no-store',\n method: 'PUT',\n headers: blockHeaders,\n });\n\n const blockResponse = await fetch(blockRequest);\n\n if (blockResponse.status !== 201) {\n const message = `Unsuccessful block PUT. Received status ${blockResponse.status}`;\n this.logService.error(message + '\\n' + await blockResponse.json());\n throw new Error(message);\n }\n\n blocksStaged.push(blockId);\n blockIndex++;\n }\n\n url = await this.renewUrlIfNecessary(url, renewalCallback);\n const blockListUrl = Utils.getUrl(url);\n const blockListXml = this.blockListXml(blocksStaged);\n blockListUrl.searchParams.append('comp', 'blocklist');\n const headers = new Headers({\n 'x-ms-date': new Date().toUTCString(),\n 'x-ms-version': blockListUrl.searchParams.get('sv'),\n 'Content-Length': blockListXml.length.toString(),\n });\n\n const request = new Request(blockListUrl.toString(), {\n body: blockListXml,\n cache: 'no-store',\n method: 'PUT',\n headers: headers,\n });\n\n const response = await fetch(request);\n\n if (response.status !== 201) {\n const message = `Unsuccessful block list PUT. Received status ${response.status}`;\n this.logService.error(message + '\\n' + await response.json());\n throw new Error(message);\n }\n } catch (e) {\n throw e;\n }\n }\n\n private async renewUrlIfNecessary(url: string, renewalCallback: () => Promise): Promise {\n const urlObject = Utils.getUrl(url);\n const expiry = new Date(urlObject.searchParams.get('se') ?? '');\n\n if (isNaN(expiry.getTime())) {\n expiry.setTime(Date.now() + 3600000);\n }\n\n if (expiry.getTime() < Date.now() + 1000) {\n return await renewalCallback();\n }\n return url;\n }\n\n private encodedBlockId(blockIndex: number) {\n // Encoded blockId max size is 64, so pre-encoding max size is 48\n const utfBlockId = ('000000000000000000000000000000000000000000000000' + blockIndex.toString()).slice(-48);\n return Utils.fromUtf8ToB64(utfBlockId);\n }\n\n private blockListXml(blockIdList: string[]) {\n let xml = '';\n blockIdList.forEach(blockId => {\n xml += `${blockId}`;\n });\n xml += '';\n return xml;\n }\n\n private getMaxBlockSize(version: string) {\n if (Version.compare(version, '2019-12-12') >= 0) {\n return 4000 * 1024 * 1024; // 4000 MiB\n } else if (Version.compare(version, '2016-05-31') >= 0) {\n return 100 * 1024 * 1024; // 100 MiB\n } else {\n return 4 * 1024 * 1024; // 4 MiB\n }\n }\n}\n\nclass Version {\n /**\n * Compares two Azure Versions against each other\n * @param a Version to compare\n * @param b Version to compare\n * @returns a number less than zero if b is newer than a, 0 if equal,\n * and greater than zero if a is newer than b\n */\n static compare(a: Required | string, b: Required | string) {\n if (typeof (a) === 'string') {\n a = new Version(a);\n }\n\n if (typeof (b) === 'string') {\n b = new Version(b);\n }\n\n return a.year !== b.year ? a.year - b.year :\n a.month !== b.month ? a.month - b.month :\n a.day !== b.day ? a.day - b.day :\n 0;\n }\n year = 0;\n month = 0;\n day = 0;\n\n constructor(version: string) {\n try {\n const parts = version.split('-').map(v => Number.parseInt(v, 10));\n this.year = parts[0];\n this.month = parts[1];\n this.day = parts[2];\n } catch {\n // Ignore error\n }\n }\n /**\n * Compares two Azure Versions against each other\n * @param compareTo Version to compare against\n * @returns a number less than zero if compareTo is newer, 0 if equal,\n * and greater than zero if this is greater than compareTo\n */\n compare(compareTo: Required | string) {\n return Version.compare(this, compareTo);\n }\n}\n","import { ApiService } from '../abstractions/api.service';\n\nimport { EncArrayBuffer } from '../models/domain/encArrayBuffer';\n\nimport { Utils } from '../misc/utils';\n\nexport class BitwardenFileUploadService\n{\n constructor(private apiService: ApiService) { }\n\n async upload(encryptedFileName: string, encryptedFileData: EncArrayBuffer, apiCall: (fd: FormData) => Promise) {\n const fd = new FormData();\n try {\n const blob = new Blob([encryptedFileData.buffer], { type: 'application/octet-stream' });\n fd.append('data', blob, encryptedFileName);\n } catch (e) {\n if (Utils.isNode && !Utils.isBrowser) {\n fd.append('data', Buffer.from(encryptedFileData.buffer) as any, {\n filepath: encryptedFileName,\n contentType: 'application/octet-stream',\n } as any);\n } else {\n throw e;\n }\n }\n\n await apiCall(fd);\n }\n}\n","import { FolderData } from '../models/data/folderData';\n\nimport { Folder } from '../models/domain/folder';\nimport { SymmetricCryptoKey } from '../models/domain/symmetricCryptoKey';\nimport { TreeNode } from '../models/domain/treeNode';\n\nimport { FolderRequest } from '../models/request/folderRequest';\n\nimport { FolderResponse } from '../models/response/folderResponse';\n\nimport { FolderView } from '../models/view/folderView';\n\nimport { ApiService } from '../abstractions/api.service';\nimport { CipherService } from '../abstractions/cipher.service';\nimport { CryptoService } from '../abstractions/crypto.service';\nimport { FolderService as FolderServiceAbstraction } from '../abstractions/folder.service';\nimport { I18nService } from '../abstractions/i18n.service';\nimport { StorageService } from '../abstractions/storage.service';\nimport { UserService } from '../abstractions/user.service';\nimport { CipherData } from '../models/data/cipherData';\n\nimport { ServiceUtils } from '../misc/serviceUtils';\nimport { Utils } from '../misc/utils';\n\nconst Keys = {\n foldersPrefix: 'folders_',\n ciphersPrefix: 'ciphers_',\n};\nconst NestingDelimiter = '/';\n\nexport class FolderService implements FolderServiceAbstraction {\n decryptedFolderCache: FolderView[];\n\n constructor(private cryptoService: CryptoService, private userService: UserService,\n private apiService: ApiService, private storageService: StorageService,\n private i18nService: I18nService, private cipherService: CipherService) { }\n\n clearCache(): void {\n this.decryptedFolderCache = null;\n }\n\n async encrypt(model: FolderView, key?: SymmetricCryptoKey): Promise {\n const folder = new Folder();\n folder.id = model.id;\n folder.name = await this.cryptoService.encrypt(model.name, key);\n return folder;\n }\n\n async get(id: string): Promise {\n const userId = await this.userService.getUserId();\n const folders = await this.storageService.get<{ [id: string]: FolderData; }>(\n Keys.foldersPrefix + userId);\n if (folders == null || !folders.hasOwnProperty(id)) {\n return null;\n }\n\n return new Folder(folders[id]);\n }\n\n async getAll(): Promise {\n const userId = await this.userService.getUserId();\n const folders = await this.storageService.get<{ [id: string]: FolderData; }>(\n Keys.foldersPrefix + userId);\n const response: Folder[] = [];\n for (const id in folders) {\n if (folders.hasOwnProperty(id)) {\n response.push(new Folder(folders[id]));\n }\n }\n return response;\n }\n\n async getAllDecrypted(): Promise {\n if (this.decryptedFolderCache != null) {\n return this.decryptedFolderCache;\n }\n\n const hasKey = await this.cryptoService.hasKey();\n if (!hasKey) {\n throw new Error('No key.');\n }\n\n const decFolders: FolderView[] = [];\n const promises: Promise[] = [];\n const folders = await this.getAll();\n folders.forEach(folder => {\n promises.push(folder.decrypt().then(f => decFolders.push(f)));\n });\n\n await Promise.all(promises);\n decFolders.sort(Utils.getSortFunction(this.i18nService, 'name'));\n\n const noneFolder = new FolderView();\n noneFolder.name = this.i18nService.t('noneFolder');\n decFolders.push(noneFolder);\n\n this.decryptedFolderCache = decFolders;\n return this.decryptedFolderCache;\n }\n\n async getAllNested(): Promise[]> {\n const folders = await this.getAllDecrypted();\n const nodes: TreeNode[] = [];\n folders.forEach(f => {\n const folderCopy = new FolderView();\n folderCopy.id = f.id;\n folderCopy.revisionDate = f.revisionDate;\n const parts = f.name != null ? f.name.replace(/^\\/+|\\/+$/g, '').split(NestingDelimiter) : [];\n ServiceUtils.nestedTraverse(nodes, 0, parts, folderCopy, null, NestingDelimiter);\n });\n return nodes;\n }\n\n async getNested(id: string): Promise> {\n const folders = await this.getAllNested();\n return ServiceUtils.getTreeNodeObject(folders, id) as TreeNode;\n }\n\n async saveWithServer(folder: Folder): Promise {\n const request = new FolderRequest(folder);\n\n let response: FolderResponse;\n if (folder.id == null) {\n response = await this.apiService.postFolder(request);\n folder.id = response.id;\n } else {\n response = await this.apiService.putFolder(folder.id, request);\n }\n\n const userId = await this.userService.getUserId();\n const data = new FolderData(response, userId);\n await this.upsert(data);\n }\n\n async upsert(folder: FolderData | FolderData[]): Promise {\n const userId = await this.userService.getUserId();\n let folders = await this.storageService.get<{ [id: string]: FolderData; }>(\n Keys.foldersPrefix + userId);\n if (folders == null) {\n folders = {};\n }\n\n if (folder instanceof FolderData) {\n const f = folder as FolderData;\n folders[f.id] = f;\n } else {\n (folder as FolderData[]).forEach(f => {\n folders[f.id] = f;\n });\n }\n\n await this.storageService.save(Keys.foldersPrefix + userId, folders);\n this.decryptedFolderCache = null;\n }\n\n async replace(folders: { [id: string]: FolderData; }): Promise {\n const userId = await this.userService.getUserId();\n await this.storageService.save(Keys.foldersPrefix + userId, folders);\n this.decryptedFolderCache = null;\n }\n\n async clear(userId: string): Promise {\n await this.storageService.remove(Keys.foldersPrefix + userId);\n this.decryptedFolderCache = null;\n }\n\n async delete(id: string | string[]): Promise {\n const userId = await this.userService.getUserId();\n const folders = await this.storageService.get<{ [id: string]: FolderData; }>(\n Keys.foldersPrefix + userId);\n if (folders == null) {\n return;\n }\n\n if (typeof id === 'string') {\n if (folders[id] == null) {\n return;\n }\n delete folders[id];\n } else {\n (id as string[]).forEach(i => {\n delete folders[i];\n });\n }\n\n await this.storageService.save(Keys.foldersPrefix + userId, folders);\n this.decryptedFolderCache = null;\n\n // Items in a deleted folder are re-assigned to \"No Folder\"\n const ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(Keys.ciphersPrefix + userId);\n if (ciphers != null) {\n const updates: CipherData[] = [];\n for (const cId in ciphers) {\n if (ciphers[cId].folderId === id) {\n ciphers[cId].folderId = null;\n updates.push(ciphers[cId]);\n }\n }\n if (updates.length > 0) {\n this.cipherService.upsert(updates);\n }\n }\n }\n\n async deleteWithServer(id: string): Promise {\n await this.apiService.deleteFolder(id);\n await this.delete(id);\n }\n}\n","import { ApiService } from '../abstractions/api.service';\nimport { CipherService } from '../abstractions/cipher.service';\nimport { CollectionService } from '../abstractions/collection.service';\nimport { CryptoService } from '../abstractions/crypto.service';\nimport { FolderService } from '../abstractions/folder.service';\nimport { I18nService } from '../abstractions/i18n.service';\nimport {\n ImportOption,\n ImportService as ImportServiceAbstraction,\n} from '../abstractions/import.service';\nimport { PlatformUtilsService } from '../abstractions/platformUtils.service';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CipherType } from '../enums/cipherType';\n\nimport { Utils } from '../misc/utils';\n\nimport { CipherRequest } from '../models/request/cipherRequest';\nimport { CollectionRequest } from '../models/request/collectionRequest';\nimport { FolderRequest } from '../models/request/folderRequest';\nimport { ImportCiphersRequest } from '../models/request/importCiphersRequest';\nimport { ImportOrganizationCiphersRequest } from '../models/request/importOrganizationCiphersRequest';\nimport { KvpRequest } from '../models/request/kvpRequest';\n\nimport { ErrorResponse } from '../models/response/errorResponse';\nimport { CipherView } from '../models/view/cipherView';\n\nimport { AscendoCsvImporter } from '../importers/ascendoCsvImporter';\nimport { AvastCsvImporter } from '../importers/avastCsvImporter';\nimport { AvastJsonImporter } from '../importers/avastJsonImporter';\nimport { AviraCsvImporter } from '../importers/aviraCsvImporter';\nimport { BitwardenCsvImporter } from '../importers/bitwardenCsvImporter';\nimport { BitwardenJsonImporter } from '../importers/bitwardenJsonImporter';\nimport { BlackBerryCsvImporter } from '../importers/blackBerryCsvImporter';\nimport { BlurCsvImporter } from '../importers/blurCsvImporter';\nimport { ButtercupCsvImporter } from '../importers/buttercupCsvImporter';\nimport { ChromeCsvImporter } from '../importers/chromeCsvImporter';\nimport { ClipperzHtmlImporter } from '../importers/clipperzHtmlImporter';\nimport { CodebookCsvImporter } from '../importers/codebookCsvImporter';\nimport { DashlaneJsonImporter } from '../importers/dashlaneJsonImporter';\nimport { EncryptrCsvImporter } from '../importers/encryptrCsvImporter';\nimport { EnpassCsvImporter } from '../importers/enpassCsvImporter';\nimport { EnpassJsonImporter } from '../importers/enpassJsonImporter';\nimport { FirefoxCsvImporter } from '../importers/firefoxCsvImporter';\nimport { FSecureFskImporter } from '../importers/fsecureFskImporter';\nimport { GnomeJsonImporter } from '../importers/gnomeJsonImporter';\nimport { Importer } from '../importers/importer';\nimport { KasperskyTxtImporter } from '../importers/kasperskyTxtImporter';\nimport { KeePass2XmlImporter } from '../importers/keepass2XmlImporter';\nimport { KeePassXCsvImporter } from '../importers/keepassxCsvImporter';\nimport { KeeperCsvImporter } from '../importers/keeperCsvImporter';\nimport { LastPassCsvImporter } from '../importers/lastpassCsvImporter';\nimport { LogMeOnceCsvImporter } from '../importers/logMeOnceCsvImporter';\nimport { MeldiumCsvImporter } from '../importers/meldiumCsvImporter';\nimport { MSecureCsvImporter } from '../importers/msecureCsvImporter';\nimport { MykiCsvImporter } from '../importers/mykiCsvImporter';\nimport { NordPassCsvImporter } from '../importers/nordpassCsvImporter';\nimport { OnePassword1PifImporter } from '../importers/onepasswordImporters/onepassword1PifImporter';\nimport { OnePasswordMacCsvImporter } from '../importers/onepasswordImporters/onepasswordMacCsvImporter';\nimport { OnePasswordWinCsvImporter } from '../importers/onepasswordImporters/onepasswordWinCsvImporter';\nimport { PadlockCsvImporter } from '../importers/padlockCsvImporter';\nimport { PassKeepCsvImporter } from '../importers/passkeepCsvImporter';\nimport { PassmanJsonImporter } from '../importers/passmanJsonImporter';\nimport { PasspackCsvImporter } from '../importers/passpackCsvImporter';\nimport { PasswordAgentCsvImporter } from '../importers/passwordAgentCsvImporter';\nimport { PasswordBossJsonImporter } from '../importers/passwordBossJsonImporter';\nimport { PasswordDragonXmlImporter } from '../importers/passwordDragonXmlImporter';\nimport { PasswordSafeXmlImporter } from '../importers/passwordSafeXmlImporter';\nimport { PasswordWalletTxtImporter } from '../importers/passwordWalletTxtImporter';\nimport { RememBearCsvImporter } from '../importers/rememBearCsvImporter';\nimport { RoboFormCsvImporter } from '../importers/roboformCsvImporter';\nimport { SafariCsvImporter } from '../importers/safariCsvImporter';\nimport { SafeInCloudXmlImporter } from '../importers/safeInCloudXmlImporter';\nimport { SaferPassCsvImporter } from '../importers/saferpassCsvImport';\nimport { SecureSafeCsvImporter } from '../importers/secureSafeCsvImporter';\nimport { SplashIdCsvImporter } from '../importers/splashIdCsvImporter';\nimport { StickyPasswordXmlImporter } from '../importers/stickyPasswordXmlImporter';\nimport { TrueKeyCsvImporter } from '../importers/truekeyCsvImporter';\nimport { UpmCsvImporter } from '../importers/upmCsvImporter';\nimport { YotiCsvImporter } from '../importers/yotiCsvImporter';\nimport { ZohoVaultCsvImporter } from '../importers/zohoVaultCsvImporter';\n\nexport class ImportService implements ImportServiceAbstraction {\n featuredImportOptions = [\n { id: 'bitwardenjson', name: 'Bitwarden (json)' },\n { id: 'bitwardencsv', name: 'Bitwarden (csv)' },\n { id: 'chromecsv', name: 'Chrome (csv)' },\n { id: 'dashlanejson', name: 'Dashlane (json)' },\n { id: 'firefoxcsv', name: 'Firefox (csv)' },\n { id: 'keepass2xml', name: 'KeePass 2 (xml)' },\n { id: 'lastpasscsv', name: 'LastPass (csv)' },\n { id: 'safaricsv', name: 'Safari and macOS (csv)' },\n { id: '1password1pif', name: '1Password (1pif)' },\n ];\n\n regularImportOptions: ImportOption[] = [\n { id: 'keepassxcsv', name: 'KeePassX (csv)' },\n { id: '1passwordwincsv', name: '1Password 6 and 7 Windows (csv)' },\n { id: '1passwordmaccsv', name: '1Password 6 and 7 Mac (csv)' },\n { id: 'roboformcsv', name: 'RoboForm (csv)' },\n { id: 'keepercsv', name: 'Keeper (csv)' },\n { id: 'enpasscsv', name: 'Enpass (csv)' },\n { id: 'enpassjson', name: 'Enpass (json)' },\n { id: 'safeincloudxml', name: 'SafeInCloud (xml)' },\n { id: 'pwsafexml', name: 'Password Safe (xml)' },\n { id: 'stickypasswordxml', name: 'Sticky Password (xml)' },\n { id: 'msecurecsv', name: 'mSecure (csv)' },\n { id: 'truekeycsv', name: 'True Key (csv)' },\n { id: 'passwordbossjson', name: 'Password Boss (json)' },\n { id: 'zohovaultcsv', name: 'Zoho Vault (csv)' },\n { id: 'splashidcsv', name: 'SplashID (csv)' },\n { id: 'passworddragonxml', name: 'Password Dragon (xml)' },\n { id: 'padlockcsv', name: 'Padlock (csv)' },\n { id: 'passboltcsv', name: 'Passbolt (csv)' },\n { id: 'clipperzhtml', name: 'Clipperz (html)' },\n { id: 'aviracsv', name: 'Avira (csv)' },\n { id: 'saferpasscsv', name: 'SaferPass (csv)' },\n { id: 'upmcsv', name: 'Universal Password Manager (csv)' },\n { id: 'ascendocsv', name: 'Ascendo DataVault (csv)' },\n { id: 'meldiumcsv', name: 'Meldium (csv)' },\n { id: 'passkeepcsv', name: 'PassKeep (csv)' },\n { id: 'operacsv', name: 'Opera (csv)' },\n { id: 'vivaldicsv', name: 'Vivaldi (csv)' },\n { id: 'gnomejson', name: 'GNOME Passwords and Keys/Seahorse (json)' },\n { id: 'blurcsv', name: 'Blur (csv)' },\n { id: 'passwordagentcsv', name: 'Password Agent (csv)' },\n { id: 'passpackcsv', name: 'Passpack (csv)' },\n { id: 'passmanjson', name: 'Passman (json)' },\n { id: 'avastcsv', name: 'Avast Passwords (csv)' },\n { id: 'avastjson', name: 'Avast Passwords (json)' },\n { id: 'fsecurefsk', name: 'F-Secure KEY (fsk)' },\n { id: 'kasperskytxt', name: 'Kaspersky Password Manager (txt)' },\n { id: 'remembearcsv', name: 'RememBear (csv)' },\n { id: 'passwordwallettxt', name: 'PasswordWallet (txt)' },\n { id: 'mykicsv', name: 'Myki (csv)' },\n { id: 'securesafecsv', name: 'SecureSafe (csv)' },\n { id: 'logmeoncecsv', name: 'LogMeOnce (csv)' },\n { id: 'blackberrycsv', name: 'BlackBerry Password Keeper (csv)' },\n { id: 'buttercupcsv', name: 'Buttercup (csv)' },\n { id: 'codebookcsv', name: 'Codebook (csv)' },\n { id: 'encryptrcsv', name: 'Encryptr (csv)' },\n { id: 'yoticsv', name: 'Yoti (csv)' },\n { id: 'nordpasscsv', name: 'Nordpass (csv)' },\n ];\n\n constructor(private cipherService: CipherService, private folderService: FolderService,\n private apiService: ApiService, private i18nService: I18nService,\n private collectionService: CollectionService, private platformUtilsService: PlatformUtilsService,\n private cryptoService: CryptoService) { }\n\n getImportOptions(): ImportOption[] {\n return this.featuredImportOptions.concat(this.regularImportOptions);\n }\n\n async import(importer: Importer, fileContents: string, organizationId: string = null): Promise {\n const importResult = await importer.parse(fileContents);\n if (importResult.success) {\n if (importResult.folders.length === 0 && importResult.ciphers.length === 0) {\n return new Error(this.i18nService.t('importNothingError'));\n } else if (importResult.ciphers.length > 0) {\n const halfway = Math.floor(importResult.ciphers.length / 2);\n const last = importResult.ciphers.length - 1;\n\n if (this.badData(importResult.ciphers[0]) &&\n this.badData(importResult.ciphers[halfway]) &&\n this.badData(importResult.ciphers[last])) {\n return new Error(this.i18nService.t('importFormatError'));\n }\n }\n try {\n await this.postImport(importResult, organizationId);\n } catch (error) {\n const errorResponse = new ErrorResponse(error, 400);\n return this.handleServerError(errorResponse, importResult);\n }\n return null;\n } else {\n if (!Utils.isNullOrWhitespace(importResult.errorMessage)) {\n return new Error(importResult.errorMessage);\n } else {\n return new Error(this.i18nService.t('importFormatError'));\n }\n }\n }\n\n getImporter(format: string, organizationId: string = null): Importer {\n const importer = this.getImporterInstance(format);\n if (importer == null) {\n return null;\n }\n importer.organizationId = organizationId;\n return importer;\n }\n\n private getImporterInstance(format: string) {\n if (format == null || format === '') {\n return null;\n }\n\n switch (format) {\n case 'bitwardencsv':\n return new BitwardenCsvImporter();\n case 'bitwardenjson':\n return new BitwardenJsonImporter(this.cryptoService, this.i18nService);\n case 'lastpasscsv':\n case 'passboltcsv':\n return new LastPassCsvImporter();\n case 'keepassxcsv':\n return new KeePassXCsvImporter();\n case 'aviracsv':\n return new AviraCsvImporter();\n case 'blurcsv':\n return new BlurCsvImporter();\n case 'safeincloudxml':\n return new SafeInCloudXmlImporter();\n case 'padlockcsv':\n return new PadlockCsvImporter();\n case 'keepass2xml':\n return new KeePass2XmlImporter();\n case 'chromecsv':\n case 'operacsv':\n case 'vivaldicsv':\n return new ChromeCsvImporter();\n case 'firefoxcsv':\n return new FirefoxCsvImporter();\n case 'upmcsv':\n return new UpmCsvImporter();\n case 'saferpasscsv':\n return new SaferPassCsvImporter();\n case 'safaricsv':\n return new SafariCsvImporter();\n case 'meldiumcsv':\n return new MeldiumCsvImporter();\n case '1password1pif':\n return new OnePassword1PifImporter();\n case '1passwordwincsv':\n return new OnePasswordWinCsvImporter();\n case '1passwordmaccsv':\n return new OnePasswordMacCsvImporter();\n case 'keepercsv':\n return new KeeperCsvImporter();\n case 'passworddragonxml':\n return new PasswordDragonXmlImporter();\n case 'enpasscsv':\n return new EnpassCsvImporter();\n case 'enpassjson':\n return new EnpassJsonImporter();\n case 'pwsafexml':\n return new PasswordSafeXmlImporter();\n case 'dashlanejson':\n return new DashlaneJsonImporter();\n case 'msecurecsv':\n return new MSecureCsvImporter();\n case 'stickypasswordxml':\n return new StickyPasswordXmlImporter();\n case 'truekeycsv':\n return new TrueKeyCsvImporter();\n case 'clipperzhtml':\n return new ClipperzHtmlImporter();\n case 'roboformcsv':\n return new RoboFormCsvImporter();\n case 'ascendocsv':\n return new AscendoCsvImporter();\n case 'passwordbossjson':\n return new PasswordBossJsonImporter();\n case 'zohovaultcsv':\n return new ZohoVaultCsvImporter();\n case 'splashidcsv':\n return new SplashIdCsvImporter();\n case 'passkeepcsv':\n return new PassKeepCsvImporter();\n case 'gnomejson':\n return new GnomeJsonImporter();\n case 'passwordagentcsv':\n return new PasswordAgentCsvImporter();\n case 'passpackcsv':\n return new PasspackCsvImporter();\n case 'passmanjson':\n return new PassmanJsonImporter();\n case 'avastcsv':\n return new AvastCsvImporter();\n case 'avastjson':\n return new AvastJsonImporter();\n case 'fsecurefsk':\n return new FSecureFskImporter();\n case 'kasperskytxt':\n return new KasperskyTxtImporter();\n case 'remembearcsv':\n return new RememBearCsvImporter();\n case 'passwordwallettxt':\n return new PasswordWalletTxtImporter();\n case 'mykicsv':\n return new MykiCsvImporter();\n case 'securesafecsv':\n return new SecureSafeCsvImporter();\n case 'logmeoncecsv':\n return new LogMeOnceCsvImporter();\n case 'blackberrycsv':\n return new BlackBerryCsvImporter();\n case 'buttercupcsv':\n return new ButtercupCsvImporter();\n case 'codebookcsv':\n return new CodebookCsvImporter();\n case 'encryptrcsv':\n return new EncryptrCsvImporter();\n case 'yoticsv':\n return new YotiCsvImporter();\n case 'nordpasscsv':\n return new NordPassCsvImporter();\n default:\n return null;\n }\n }\n\n private async postImport(importResult: ImportResult, organizationId: string = null) {\n if (organizationId == null) {\n const request = new ImportCiphersRequest();\n for (let i = 0; i < importResult.ciphers.length; i++) {\n const c = await this.cipherService.encrypt(importResult.ciphers[i]);\n request.ciphers.push(new CipherRequest(c));\n }\n if (importResult.folders != null) {\n for (let i = 0; i < importResult.folders.length; i++) {\n const f = await this.folderService.encrypt(importResult.folders[i]);\n request.folders.push(new FolderRequest(f));\n }\n }\n if (importResult.folderRelationships != null) {\n importResult.folderRelationships.forEach(r =>\n request.folderRelationships.push(new KvpRequest(r[0], r[1])));\n }\n return await this.apiService.postImportCiphers(request);\n } else {\n const request = new ImportOrganizationCiphersRequest();\n for (let i = 0; i < importResult.ciphers.length; i++) {\n importResult.ciphers[i].organizationId = organizationId;\n const c = await this.cipherService.encrypt(importResult.ciphers[i]);\n request.ciphers.push(new CipherRequest(c));\n }\n if (importResult.collections != null) {\n for (let i = 0; i < importResult.collections.length; i++) {\n importResult.collections[i].organizationId = organizationId;\n const c = await this.collectionService.encrypt(importResult.collections[i]);\n request.collections.push(new CollectionRequest(c));\n }\n }\n if (importResult.collectionRelationships != null) {\n importResult.collectionRelationships.forEach(r =>\n request.collectionRelationships.push(new KvpRequest(r[0], r[1])));\n }\n return await this.apiService.postImportOrganizationCiphers(organizationId, request);\n }\n }\n\n private badData(c: CipherView) {\n return (c.name == null || c.name === '--') &&\n (c.type === CipherType.Login && c.login != null && Utils.isNullOrWhitespace(c.login.password));\n }\n\n private handleServerError(errorResponse: ErrorResponse, importResult: ImportResult): Error {\n if (errorResponse.validationErrors == null) {\n return new Error(errorResponse.message);\n }\n\n let errorMessage = '';\n\n Object.entries(errorResponse.validationErrors).forEach(([key, value], index) => {\n let item;\n let itemType;\n const i = Number(key.match(/[0-9]+/)[0]);\n\n switch (key.match(/^\\w+/)[0]) {\n case 'Ciphers':\n item = importResult.ciphers[i];\n itemType = CipherType[item.type];\n break;\n case 'Folders':\n item = importResult.folders[i];\n itemType = 'Folder';\n break;\n case 'Collections':\n item = importResult.collections[i];\n itemType = 'Collection';\n break;\n default:\n return;\n }\n\n if (index > 0) {\n errorMessage += '\\n\\n';\n }\n\n if (itemType !== 'Folder' && itemType !== 'Collection') {\n errorMessage += '[' + (i + 1) + '] ';\n }\n\n errorMessage += '[' + itemType + '] \"' + item.name + '\": ' + value;\n });\n\n return new Error(errorMessage);\n }\n}\n","import { CipherRequest } from './cipherRequest';\nimport { FolderRequest } from './folderRequest';\nimport { KvpRequest } from './kvpRequest';\n\nexport class ImportCiphersRequest {\n ciphers: CipherRequest[] = [];\n folders: FolderRequest[] = [];\n folderRelationships: KvpRequest[] = [];\n}\n","import { CipherRequest } from './cipherRequest';\nimport { CollectionRequest } from './collectionRequest';\nimport { KvpRequest } from './kvpRequest';\n\nexport class ImportOrganizationCiphersRequest {\n ciphers: CipherRequest[] = [];\n collections: CollectionRequest[] = [];\n collectionRelationships: KvpRequest[] = [];\n}\n","export class KvpRequest {\n key: TK;\n value: TV;\n\n constructor(key: TK, value: TV) {\n this.key = key;\n this.value = value;\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class AscendoCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, false);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (value.length < 2) {\n return;\n }\n\n const cipher = this.initLoginCipher();\n cipher.notes = this.getValueOrDefault(value[value.length - 1]);\n cipher.name = this.getValueOrDefault(value[0], '--');\n\n if (value.length > 2 && (value.length % 2) === 0) {\n for (let i = 0; i < value.length - 2; i += 2) {\n const val: string = value[i + 2];\n const field: string = value[i + 1];\n if (this.isNullOrWhitespace(val) || this.isNullOrWhitespace(field)) {\n continue;\n }\n\n const fieldLower = field.toLowerCase();\n if (cipher.login.password == null && this.passwordFieldNames.indexOf(fieldLower) > -1) {\n cipher.login.password = this.getValueOrDefault(val);\n } else if (cipher.login.username == null &&\n this.usernameFieldNames.indexOf(fieldLower) > -1) {\n cipher.login.username = this.getValueOrDefault(val);\n } else if ((cipher.login.uris == null || cipher.login.uris.length === 0) &&\n this.uriFieldNames.indexOf(fieldLower) > -1) {\n cipher.login.uris = this.makeUriArray(val);\n } else {\n this.processKvp(cipher, field, val);\n }\n }\n }\n\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class AvastCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.name);\n cipher.login.uris = this.makeUriArray(value.web);\n cipher.login.password = this.getValueOrDefault(value.password);\n cipher.login.username = this.getValueOrDefault(value.login);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CipherType } from '../enums/cipherType';\nimport { SecureNoteType } from '../enums/secureNoteType';\n\nexport class AvastJsonImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = JSON.parse(data);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n if (results.logins != null) {\n results.logins.forEach((value: any) => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.custName);\n cipher.notes = this.getValueOrDefault(value.note);\n cipher.login.uris = this.makeUriArray(value.url);\n cipher.login.password = this.getValueOrDefault(value.pwd);\n cipher.login.username = this.getValueOrDefault(value.loginName);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n }\n\n if (results.notes != null) {\n results.notes.forEach((value: any) => {\n const cipher = this.initLoginCipher();\n cipher.type = CipherType.SecureNote;\n cipher.secureNote.type = SecureNoteType.Generic;\n cipher.name = this.getValueOrDefault(value.label);\n cipher.notes = this.getValueOrDefault(value.text);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n }\n\n if (results.cards != null) {\n results.cards.forEach((value: any) => {\n const cipher = this.initLoginCipher();\n cipher.type = CipherType.Card;\n cipher.name = this.getValueOrDefault(value.custName);\n cipher.notes = this.getValueOrDefault(value.note);\n cipher.card.cardholderName = this.getValueOrDefault(value.holderName);\n cipher.card.number = this.getValueOrDefault(value.cardNumber);\n cipher.card.code = this.getValueOrDefault(value.cvv);\n cipher.card.brand = this.getCardBrand(cipher.card.number);\n if (value.expirationDate != null) {\n if (value.expirationDate.month != null) {\n cipher.card.expMonth = value.expirationDate.month + '';\n }\n if (value.expirationDate.year != null) {\n cipher.card.expYear = value.expirationDate.year + '';\n }\n }\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class AviraCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.name,\n this.getValueOrDefault(this.nameFromUrl(value.website), '--'));\n cipher.login.uris = this.makeUriArray(value.website);\n cipher.login.password = this.getValueOrDefault(value.password);\n\n if (this.isNullOrWhitespace(value.username) && !this.isNullOrWhitespace(value.secondary_username)) {\n cipher.login.username = value.secondary_username;\n } else {\n cipher.login.username = this.getValueOrDefault(value.username);\n cipher.notes = this.getValueOrDefault(value.secondary_username);\n }\n\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CipherView } from '../models/view/cipherView';\nimport { CollectionView } from '../models/view/collectionView';\nimport { FieldView } from '../models/view/fieldView';\nimport { FolderView } from '../models/view/folderView';\nimport { LoginView } from '../models/view/loginView';\nimport { SecureNoteView } from '../models/view/secureNoteView';\n\nimport { CipherRepromptType } from '../enums/cipherRepromptType';\nimport { CipherType } from '../enums/cipherType';\nimport { FieldType } from '../enums/fieldType';\nimport { SecureNoteType } from '../enums/secureNoteType';\n\nexport class BitwardenCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (this.organization && !this.isNullOrWhitespace(value.collections)) {\n const collections = (value.collections as string).split(',');\n collections.forEach(col => {\n let addCollection = true;\n let collectionIndex = result.collections.length;\n\n for (let i = 0; i < result.collections.length; i++) {\n if (result.collections[i].name === col) {\n addCollection = false;\n collectionIndex = i;\n break;\n }\n }\n\n if (addCollection) {\n const collection = new CollectionView();\n collection.name = col;\n result.collections.push(collection);\n }\n\n result.collectionRelationships.push([result.ciphers.length, collectionIndex]);\n });\n } else if (!this.organization) {\n this.processFolder(result, value.folder);\n }\n\n const cipher = new CipherView();\n cipher.favorite = !this.organization && this.getValueOrDefault(value.favorite, '0') !== '0' ? true : false;\n cipher.type = CipherType.Login;\n cipher.notes = this.getValueOrDefault(value.notes);\n cipher.name = this.getValueOrDefault(value.name, '--');\n try {\n cipher.reprompt = parseInt(this.getValueOrDefault(value.reprompt, CipherRepromptType.None.toString()), 10);\n } catch (e) {\n // tslint:disable-next-line\n console.error('Unable to parse reprompt value', e);\n cipher.reprompt = CipherRepromptType.None;\n }\n\n if (!this.isNullOrWhitespace(value.fields)) {\n const fields = this.splitNewLine(value.fields);\n for (let i = 0; i < fields.length; i++) {\n if (this.isNullOrWhitespace(fields[i])) {\n continue;\n }\n\n const delimPosition = fields[i].lastIndexOf(': ');\n if (delimPosition === -1) {\n continue;\n }\n\n if (cipher.fields == null) {\n cipher.fields = [];\n }\n\n const field = new FieldView();\n field.name = fields[i].substr(0, delimPosition);\n field.value = null;\n field.type = FieldType.Text;\n if (fields[i].length > (delimPosition + 2)) {\n field.value = fields[i].substr(delimPosition + 2);\n }\n cipher.fields.push(field);\n }\n }\n\n const valueType = value.type != null ? value.type.toLowerCase() : null;\n switch (valueType) {\n case 'note':\n cipher.type = CipherType.SecureNote;\n cipher.secureNote = new SecureNoteView();\n cipher.secureNote.type = SecureNoteType.Generic;\n break;\n default:\n cipher.type = CipherType.Login;\n cipher.login = new LoginView();\n cipher.login.totp = this.getValueOrDefault(value.login_totp || value.totp);\n cipher.login.username = this.getValueOrDefault(value.login_username || value.username);\n cipher.login.password = this.getValueOrDefault(value.login_password || value.password);\n const uris = this.parseSingleRowCsv(value.login_uri || value.uri);\n cipher.login.uris = this.makeUriArray(uris);\n break;\n }\n\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { EncString } from '../models/domain/encString';\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CipherWithIds } from '../models/export/cipherWithIds';\nimport { CollectionWithId } from '../models/export/collectionWithId';\nimport { FolderWithId } from '../models/export/folderWithId';\n\nimport { CryptoService } from '../abstractions/crypto.service';\nimport { I18nService } from '../abstractions/i18n.service';\n\nexport class BitwardenJsonImporter extends BaseImporter implements Importer {\n private results: any;\n private result: ImportResult;\n\n constructor(private cryptoService: CryptoService, private i18nService: I18nService) {\n super();\n }\n\n async parse(data: string): Promise {\n this.result = new ImportResult();\n this.results = JSON.parse(data);\n if (this.results == null || this.results.items == null || this.results.items.length === 0) {\n this.result.success = false;\n return this.result;\n }\n\n if (this.results.encrypted) {\n await this.parseEncrypted();\n } else {\n this.parseDecrypted();\n }\n\n return this.result;\n }\n\n private async parseEncrypted() {\n if (this.results.encKeyValidation_DO_NOT_EDIT != null) {\n const orgKey = await this.cryptoService.getOrgKey(this.organizationId);\n const encKeyValidation = new EncString(this.results.encKeyValidation_DO_NOT_EDIT);\n const encKeyValidationDecrypt = await this.cryptoService.decryptToUtf8(encKeyValidation, orgKey);\n if (encKeyValidationDecrypt === null) {\n this.result.success = false;\n this.result.errorMessage = this.i18nService.t('importEncKeyError');\n return;\n }\n }\n\n const groupingsMap = new Map();\n\n if (this.organization && this.results.collections != null) {\n for (const c of this.results.collections as CollectionWithId[]) {\n const collection = CollectionWithId.toDomain(c);\n if (collection != null) {\n collection.id = null;\n collection.organizationId = this.organizationId;\n const view = await collection.decrypt();\n groupingsMap.set(c.id, this.result.collections.length);\n this.result.collections.push(view);\n }\n }\n } else if (!this.organization && this.results.folders != null) {\n for (const f of this.results.folders as FolderWithId[]) {\n const folder = FolderWithId.toDomain(f);\n if (folder != null) {\n folder.id = null;\n const view = await folder.decrypt();\n groupingsMap.set(f.id, this.result.folders.length);\n this.result.folders.push(view);\n }\n }\n }\n\n for (const c of this.results.items as CipherWithIds[]) {\n const cipher = CipherWithIds.toDomain(c);\n // reset ids incase they were set for some reason\n cipher.id = null;\n cipher.folderId = null;\n cipher.organizationId = this.organizationId;\n cipher.collectionIds = null;\n\n // make sure password history is limited\n if (cipher.passwordHistory != null && cipher.passwordHistory.length > 5) {\n cipher.passwordHistory = cipher.passwordHistory.slice(0, 5);\n }\n\n if (!this.organization && c.folderId != null && groupingsMap.has(c.folderId)) {\n this.result.folderRelationships.push([this.result.ciphers.length, groupingsMap.get(c.folderId)]);\n } else if (this.organization && c.collectionIds != null) {\n c.collectionIds.forEach(cId => {\n if (groupingsMap.has(cId)) {\n this.result.collectionRelationships.push([this.result.ciphers.length, groupingsMap.get(cId)]);\n }\n });\n }\n\n const view = await cipher.decrypt();\n this.cleanupCipher(view);\n this.result.ciphers.push(view);\n }\n\n this.result.success = true;\n }\n\n private parseDecrypted() {\n const groupingsMap = new Map();\n if (this.organization && this.results.collections != null) {\n this.results.collections.forEach((c: CollectionWithId) => {\n const collection = CollectionWithId.toView(c);\n if (collection != null) {\n collection.id = null;\n collection.organizationId = null;\n groupingsMap.set(c.id, this.result.collections.length);\n this.result.collections.push(collection);\n }\n });\n } else if (!this.organization && this.results.folders != null) {\n this.results.folders.forEach((f: FolderWithId) => {\n const folder = FolderWithId.toView(f);\n if (folder != null) {\n folder.id = null;\n groupingsMap.set(f.id, this.result.folders.length);\n this.result.folders.push(folder);\n }\n });\n }\n\n this.results.items.forEach((c: CipherWithIds) => {\n const cipher = CipherWithIds.toView(c);\n // reset ids incase they were set for some reason\n cipher.id = null;\n cipher.folderId = null;\n cipher.organizationId = null;\n cipher.collectionIds = null;\n\n // make sure password history is limited\n if (cipher.passwordHistory != null && cipher.passwordHistory.length > 5) {\n cipher.passwordHistory = cipher.passwordHistory.slice(0, 5);\n }\n\n if (!this.organization && c.folderId != null && groupingsMap.has(c.folderId)) {\n this.result.folderRelationships.push([this.result.ciphers.length, groupingsMap.get(c.folderId)]);\n } else if (this.organization && c.collectionIds != null) {\n c.collectionIds.forEach(cId => {\n if (groupingsMap.has(cId)) {\n this.result.collectionRelationships.push([this.result.ciphers.length, groupingsMap.get(cId)]);\n }\n });\n }\n\n this.cleanupCipher(cipher);\n this.result.ciphers.push(cipher);\n });\n\n this.result.success = true;\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class BlackBerryCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (value.grouping === 'list') {\n return;\n }\n const cipher = this.initLoginCipher();\n cipher.favorite = value.fav === '1';\n cipher.name = this.getValueOrDefault(value.name);\n cipher.notes = this.getValueOrDefault(value.extra);\n if (value.grouping !== 'note') {\n cipher.login.uris = this.makeUriArray(value.url);\n cipher.login.password = this.getValueOrDefault(value.password);\n cipher.login.username = this.getValueOrDefault(value.username);\n }\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class BlurCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (value.label === 'null') {\n value.label = null;\n }\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.label,\n this.getValueOrDefault(this.nameFromUrl(value.domain), '--'));\n cipher.login.uris = this.makeUriArray(value.domain);\n cipher.login.password = this.getValueOrDefault(value.password);\n\n if (this.isNullOrWhitespace(value.email) && !this.isNullOrWhitespace(value.username)) {\n cipher.login.username = value.username;\n } else {\n cipher.login.username = this.getValueOrDefault(value.email);\n cipher.notes = this.getValueOrDefault(value.username);\n }\n\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nconst OfficialProps = [\n '!group_id', '!group_name', 'title', 'username', 'password', 'URL', 'id',\n];\n\nexport class ButtercupCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n this.processFolder(result, this.getValueOrDefault(value['!group_name']));\n\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.title, '--');\n cipher.login.username = this.getValueOrDefault(value.username);\n cipher.login.password = this.getValueOrDefault(value.password);\n cipher.login.uris = this.makeUriArray(value.URL);\n\n let processingCustomFields = false;\n for (const prop in value) {\n if (value.hasOwnProperty(prop)) {\n if (!processingCustomFields && OfficialProps.indexOf(prop) === -1) {\n processingCustomFields = true;\n }\n if (processingCustomFields) {\n this.processKvp(cipher, prop, value[prop]);\n }\n }\n }\n\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class ChromeCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.name, '--');\n cipher.login.username = this.getValueOrDefault(value.username);\n cipher.login.password = this.getValueOrDefault(value.password);\n cipher.login.uris = this.makeUriArray(value.url);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class ClipperzHtmlImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const doc = this.parseXml(data);\n if (doc == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n const textarea = doc.querySelector('textarea');\n if (textarea == null || this.isNullOrWhitespace(textarea.textContent)) {\n result.errorMessage = 'Missing textarea.';\n result.success = false;\n return Promise.resolve(result);\n }\n\n const entries = JSON.parse(textarea.textContent);\n entries.forEach((entry: any) => {\n const cipher = this.initLoginCipher();\n if (!this.isNullOrWhitespace(entry.label)) {\n cipher.name = entry.label.split(' ')[0];\n }\n if (entry.data != null && !this.isNullOrWhitespace(entry.data.notes)) {\n cipher.notes = entry.data.notes.split('\\\\n').join('\\n');\n }\n\n if (entry.currentVersion != null && entry.currentVersion.fields != null) {\n for (const property in entry.currentVersion.fields) {\n if (!entry.currentVersion.fields.hasOwnProperty(property)) {\n continue;\n }\n\n const field = entry.currentVersion.fields[property];\n const actionType = field.actionType != null ? field.actionType.toLowerCase() : null;\n switch (actionType) {\n case 'password':\n cipher.login.password = this.getValueOrDefault(field.value);\n break;\n case 'email':\n case 'username':\n case 'user':\n case 'name':\n cipher.login.username = this.getValueOrDefault(field.value);\n break;\n case 'url':\n cipher.login.uris = this.makeUriArray(field.value);\n break;\n default:\n const labelLower = field.label != null ? field.label.toLowerCase() : null;\n if (cipher.login.password == null && this.passwordFieldNames.indexOf(labelLower) > -1) {\n cipher.login.password = this.getValueOrDefault(field.value);\n } else if (cipher.login.username == null &&\n this.usernameFieldNames.indexOf(labelLower) > -1) {\n cipher.login.username = this.getValueOrDefault(field.value);\n } else if ((cipher.login.uris == null || cipher.login.uris.length === 0) &&\n this.uriFieldNames.indexOf(labelLower) > -1) {\n cipher.login.uris = this.makeUriArray(field.value);\n } else {\n this.processKvp(cipher, field.label, field.value);\n }\n break;\n }\n }\n }\n\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class CodebookCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n this.processFolder(result, this.getValueOrDefault(value.Category));\n\n const cipher = this.initLoginCipher();\n cipher.favorite = this.getValueOrDefault(value.Favorite) === 'True';\n cipher.name = this.getValueOrDefault(value.Entry, '--');\n cipher.notes = this.getValueOrDefault(value.Note);\n cipher.login.username = this.getValueOrDefault(value.Username, value.Email);\n cipher.login.password = this.getValueOrDefault(value.Password);\n cipher.login.totp = this.getValueOrDefault(value.TOTP);\n cipher.login.uris = this.makeUriArray(value.Website);\n\n if (!this.isNullOrWhitespace(value.Username)) {\n this.processKvp(cipher, 'Email', value.Email);\n }\n this.processKvp(cipher, 'Phone', value.Phone);\n this.processKvp(cipher, 'PIN', value.PIN);\n this.processKvp(cipher, 'Account', value.Account);\n this.processKvp(cipher, 'Date', value.Date);\n\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CardView } from '../models/view/cardView';\nimport { CipherView } from '../models/view/cipherView';\nimport { IdentityView } from '../models/view/identityView';\nimport { SecureNoteView } from '../models/view/secureNoteView';\n\nimport { CipherType } from '../enums/cipherType';\nimport { SecureNoteType } from '../enums/secureNoteType';\n\nconst HandledResults = new Set(['ADDRESS', 'AUTHENTIFIANT', 'BANKSTATEMENT', 'IDCARD', 'IDENTITY',\n 'PAYMENTMEANS_CREDITCARD', 'PAYMENTMEAN_PAYPAL', 'EMAIL']);\n\nexport class DashlaneJsonImporter extends BaseImporter implements Importer {\n private result: ImportResult;\n\n parse(data: string): Promise {\n this.result = new ImportResult();\n const results = JSON.parse(data);\n if (results == null || results.length === 0) {\n this.result.success = false;\n return Promise.resolve(this.result);\n }\n\n if (results.ADDRESS != null) {\n this.processAddress(results.ADDRESS);\n }\n if (results.AUTHENTIFIANT != null) {\n this.processAuth(results.AUTHENTIFIANT);\n }\n if (results.BANKSTATEMENT != null) {\n this.processNote(results.BANKSTATEMENT, 'BankAccountName');\n }\n if (results.IDCARD != null) {\n this.processNote(results.IDCARD, 'Fullname');\n }\n if (results.PAYMENTMEANS_CREDITCARD != null) {\n this.processCard(results.PAYMENTMEANS_CREDITCARD);\n }\n if (results.IDENTITY != null) {\n this.processIdentity(results.IDENTITY);\n }\n\n for (const key in results) {\n if (results.hasOwnProperty(key) && !HandledResults.has(key)) {\n this.processNote(results[key], null, 'Generic Note');\n }\n }\n\n this.result.success = true;\n return Promise.resolve(this.result);\n }\n\n private processAuth(results: any[]) {\n results.forEach((credential: any) => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(credential.title);\n\n cipher.login.username = this.getValueOrDefault(credential.login,\n this.getValueOrDefault(credential.secondaryLogin));\n if (this.isNullOrWhitespace(cipher.login.username)) {\n cipher.login.username = this.getValueOrDefault(credential.email);\n } else if (!this.isNullOrWhitespace(credential.email)) {\n cipher.notes = ('Email: ' + credential.email + '\\n');\n }\n\n cipher.login.password = this.getValueOrDefault(credential.password);\n cipher.login.uris = this.makeUriArray(credential.domain);\n cipher.notes += this.getValueOrDefault(credential.note, '');\n\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n this.result.ciphers.push(cipher);\n });\n }\n\n private processIdentity(results: any[]) {\n results.forEach((obj: any) => {\n const cipher = new CipherView();\n cipher.identity = new IdentityView();\n cipher.type = CipherType.Identity;\n cipher.name = this.getValueOrDefault(obj.fullName, '');\n const nameParts = cipher.name.split(' ');\n if (nameParts.length > 0) {\n cipher.identity.firstName = this.getValueOrDefault(nameParts[0]);\n }\n if (nameParts.length === 2) {\n cipher.identity.lastName = this.getValueOrDefault(nameParts[1]);\n } else if (nameParts.length === 3) {\n cipher.identity.middleName = this.getValueOrDefault(nameParts[1]);\n cipher.identity.lastName = this.getValueOrDefault(nameParts[2]);\n }\n cipher.identity.username = this.getValueOrDefault(obj.pseudo);\n this.cleanupCipher(cipher);\n this.result.ciphers.push(cipher);\n });\n }\n\n private processAddress(results: any[]) {\n results.forEach((obj: any) => {\n const cipher = new CipherView();\n cipher.identity = new IdentityView();\n cipher.type = CipherType.Identity;\n cipher.name = this.getValueOrDefault(obj.addressName);\n cipher.identity.address1 = this.getValueOrDefault(obj.addressFull);\n cipher.identity.city = this.getValueOrDefault(obj.city);\n cipher.identity.state = this.getValueOrDefault(obj.state);\n cipher.identity.postalCode = this.getValueOrDefault(obj.zipcode);\n cipher.identity.country = this.getValueOrDefault(obj.country);\n if (cipher.identity.country != null) {\n cipher.identity.country = cipher.identity.country.toUpperCase();\n }\n this.cleanupCipher(cipher);\n this.result.ciphers.push(cipher);\n });\n }\n\n private processCard(results: any[]) {\n results.forEach((obj: any) => {\n const cipher = new CipherView();\n cipher.card = new CardView();\n cipher.type = CipherType.Card;\n cipher.name = this.getValueOrDefault(obj.bank);\n cipher.card.number = this.getValueOrDefault(obj.cardNumber);\n cipher.card.brand = this.getCardBrand(cipher.card.number);\n cipher.card.cardholderName = this.getValueOrDefault(obj.owner);\n if (!this.isNullOrWhitespace(cipher.card.brand)) {\n if (this.isNullOrWhitespace(cipher.name)) {\n cipher.name = cipher.card.brand;\n } else {\n cipher.name += (' - ' + cipher.card.brand);\n }\n }\n this.cleanupCipher(cipher);\n this.result.ciphers.push(cipher);\n });\n }\n\n private processNote(results: any[], nameProperty: string, name: string = null) {\n results.forEach((obj: any) => {\n const cipher = new CipherView();\n cipher.secureNote = new SecureNoteView();\n cipher.type = CipherType.SecureNote;\n cipher.secureNote.type = SecureNoteType.Generic;\n if (name != null) {\n cipher.name = name;\n } else {\n cipher.name = this.getValueOrDefault(obj[nameProperty]);\n }\n for (const key in obj) {\n if (obj.hasOwnProperty(key) && key !== nameProperty) {\n this.processKvp(cipher, key, obj[key].toString());\n }\n }\n this.cleanupCipher(cipher);\n this.result.ciphers.push(cipher);\n });\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CardView } from '../models/view/cardView';\n\nimport { CipherType } from '../enums/cipherType';\n\nexport class EncryptrCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.Label, '--');\n cipher.notes = this.getValueOrDefault(value.Notes);\n const text = this.getValueOrDefault(value.Text);\n if (!this.isNullOrWhitespace(text)) {\n if (this.isNullOrWhitespace(cipher.notes)) {\n cipher.notes = text;\n } else {\n cipher.notes += ('\\n\\n' + text);\n }\n }\n\n const type = value['Entry Type'];\n if (type === 'Password') {\n cipher.login.username = this.getValueOrDefault(value.Username);\n cipher.login.password = this.getValueOrDefault(value.Password);\n cipher.login.uris = this.makeUriArray(value['Site URL']);\n } else if (type === 'Credit Card') {\n cipher.type = CipherType.Card;\n cipher.card = new CardView();\n cipher.card.cardholderName = this.getValueOrDefault(value['Name on card']);\n cipher.card.number = this.getValueOrDefault(value['Card Number']);\n cipher.card.brand = this.getCardBrand(cipher.card.number);\n cipher.card.code = this.getValueOrDefault(value.CVV);\n const expiry = this.getValueOrDefault(value.Expiry);\n if (!this.isNullOrWhitespace(expiry)) {\n const expParts = expiry.split('/');\n if (expParts.length > 1) {\n cipher.card.expMonth = parseInt(expParts[0], null).toString();\n cipher.card.expYear = (2000 + parseInt(expParts[1], null)).toString();\n }\n }\n }\n\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CipherType } from '../enums/cipherType';\nimport { SecureNoteType } from '../enums/secureNoteType';\n\nimport { CardView } from '../models/view/cardView';\nimport { SecureNoteView } from '../models/view/secureNoteView';\n\nexport class EnpassCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, false);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n let firstRow = true;\n results.forEach(value => {\n if (value.length < 2 || (firstRow && (value[0] === 'Title' || value[0] === 'title'))) {\n firstRow = false;\n return;\n }\n\n const cipher = this.initLoginCipher();\n cipher.notes = this.getValueOrDefault(value[value.length - 1]);\n cipher.name = this.getValueOrDefault(value[0], '--');\n\n if (value.length === 2 || (!this.containsField(value, 'username') &&\n !this.containsField(value, 'password') && !this.containsField(value, 'email') &&\n !this.containsField(value, 'url'))) {\n cipher.type = CipherType.SecureNote;\n cipher.secureNote = new SecureNoteView();\n cipher.secureNote.type = SecureNoteType.Generic;\n }\n\n if (this.containsField(value, 'cardholder') && this.containsField(value, 'number') &&\n this.containsField(value, 'expiry date')) {\n cipher.type = CipherType.Card;\n cipher.card = new CardView();\n }\n\n if (value.length > 2 && (value.length % 2) === 0) {\n for (let i = 0; i < value.length - 2; i += 2) {\n const fieldValue: string = value[i + 2];\n if (this.isNullOrWhitespace(fieldValue)) {\n continue;\n }\n\n const fieldName: string = value[i + 1];\n const fieldNameLower = fieldName.toLowerCase();\n\n if (cipher.type === CipherType.Login) {\n if (fieldNameLower === 'url' && (cipher.login.uris == null || cipher.login.uris.length === 0)) {\n cipher.login.uris = this.makeUriArray(fieldValue);\n continue;\n } else if ((fieldNameLower === 'username' || fieldNameLower === 'email') &&\n this.isNullOrWhitespace(cipher.login.username)) {\n cipher.login.username = fieldValue;\n continue;\n } else if (fieldNameLower === 'password' && this.isNullOrWhitespace(cipher.login.password)) {\n cipher.login.password = fieldValue;\n continue;\n } else if (fieldNameLower === 'totp' && this.isNullOrWhitespace(cipher.login.totp)) {\n cipher.login.totp = fieldValue;\n continue;\n }\n } else if (cipher.type === CipherType.Card) {\n if (fieldNameLower === 'cardholder' && this.isNullOrWhitespace(cipher.card.cardholderName)) {\n cipher.card.cardholderName = fieldValue;\n continue;\n } else if (fieldNameLower === 'number' && this.isNullOrWhitespace(cipher.card.number)) {\n cipher.card.number = fieldValue;\n cipher.card.brand = this.getCardBrand(fieldValue);\n continue;\n } else if (fieldNameLower === 'cvc' && this.isNullOrWhitespace(cipher.card.code)) {\n cipher.card.code = fieldValue;\n continue;\n } else if (fieldNameLower === 'expiry date' && this.isNullOrWhitespace(cipher.card.expMonth) &&\n this.isNullOrWhitespace(cipher.card.expYear)) {\n if (this.setCardExpiration(cipher, fieldValue)) {\n continue;\n }\n } else if (fieldNameLower === 'type') {\n // Skip since brand was determined from number above\n continue;\n }\n }\n\n this.processKvp(cipher, fieldName, fieldValue);\n }\n }\n\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n\n private containsField(fields: any[], name: string) {\n if (fields == null || name == null) {\n return false;\n }\n return fields.filter(f => !this.isNullOrWhitespace(f) &&\n f.toLowerCase() === name.toLowerCase()).length > 0;\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CardView } from '../models/view/cardView';\nimport { CipherView } from '../models/view/cipherView';\nimport { FolderView } from '../models/view/folderView';\n\nimport { CipherType } from '../enums/cipherType';\nimport { FieldType } from '../enums/fieldType';\n\nexport class EnpassJsonImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = JSON.parse(data);\n if (results == null || results.items == null || results.items.length === 0) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n const foldersMap = new Map();\n const foldersIndexMap = new Map();\n const folderTree = this.buildFolderTree(results.folders);\n this.flattenFolderTree(null, folderTree, foldersMap);\n foldersMap.forEach((val, key) => {\n foldersIndexMap.set(key, result.folders.length);\n const f = new FolderView();\n f.name = val;\n result.folders.push(f);\n });\n\n results.items.forEach((item: any) => {\n if (item.folders != null && item.folders.length > 0 && foldersIndexMap.has(item.folders[0])) {\n result.folderRelationships.push([result.ciphers.length, foldersIndexMap.get(item.folders[0])]);\n }\n\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(item.title);\n cipher.favorite = item.favorite > 0;\n\n if (item.template_type != null && item.fields != null && item.fields.length > 0) {\n if (item.template_type.indexOf('login.') === 0 || item.template_type.indexOf('password.') === 0) {\n this.processLogin(cipher, item.fields);\n } else if (item.template_type.indexOf('creditcard.') === 0) {\n this.processCard(cipher, item.fields);\n } else if (item.template_type.indexOf('identity.') < 0 &&\n item.fields.some((f: any) => f.type === 'password' && !this.isNullOrWhitespace(f.value))) {\n this.processLogin(cipher, item.fields);\n } else {\n this.processNote(cipher, item.fields);\n }\n }\n\n cipher.notes += ('\\n' + this.getValueOrDefault(item.note, ''));\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n\n private processLogin(cipher: CipherView, fields: any[]) {\n const urls: string[] = [];\n fields.forEach((field: any) => {\n if (this.isNullOrWhitespace(field.value) || field.type === 'section') {\n return;\n }\n\n if ((field.type === 'username' || field.type === 'email') &&\n this.isNullOrWhitespace(cipher.login.username)) {\n cipher.login.username = field.value;\n } else if (field.type === 'password' && this.isNullOrWhitespace(cipher.login.password)) {\n cipher.login.password = field.value;\n } else if (field.type === 'totp' && this.isNullOrWhitespace(cipher.login.totp)) {\n cipher.login.totp = field.value;\n } else if (field.type === 'url') {\n urls.push(field.value);\n } else {\n this.processKvp(cipher, field.label, field.value,\n field.sensitive === 1 ? FieldType.Hidden : FieldType.Text);\n }\n });\n cipher.login.uris = this.makeUriArray(urls);\n }\n\n private processCard(cipher: CipherView, fields: any[]) {\n cipher.card = new CardView();\n cipher.type = CipherType.Card;\n fields.forEach((field: any) => {\n if (this.isNullOrWhitespace(field.value) || field.type === 'section' || field.type === 'ccType') {\n return;\n }\n\n if (field.type === 'ccName' && this.isNullOrWhitespace(cipher.card.cardholderName)) {\n cipher.card.cardholderName = field.value;\n } else if (field.type === 'ccNumber' && this.isNullOrWhitespace(cipher.card.number)) {\n cipher.card.number = field.value;\n cipher.card.brand = this.getCardBrand(cipher.card.number);\n } else if (field.type === 'ccCvc' && this.isNullOrWhitespace(cipher.card.code)) {\n cipher.card.code = field.value;\n } else if (field.type === 'ccExpiry' && this.isNullOrWhitespace(cipher.card.expYear)) {\n if (!this.setCardExpiration(cipher, field.value)) {\n this.processKvp(cipher, field.label, field.value,\n field.sensitive === 1 ? FieldType.Hidden : FieldType.Text);\n }\n } else {\n this.processKvp(cipher, field.label, field.value,\n field.sensitive === 1 ? FieldType.Hidden : FieldType.Text);\n }\n });\n }\n\n private processNote(cipher: CipherView, fields: any[]) {\n fields.forEach((field: any) => {\n if (this.isNullOrWhitespace(field.value) || field.type === 'section') {\n return;\n }\n this.processKvp(cipher, field.label, field.value,\n field.sensitive === 1 ? FieldType.Hidden : FieldType.Text);\n });\n }\n\n private buildFolderTree(folders: any[]): any[] {\n if (folders == null) {\n return [];\n }\n const folderTree: any[] = [];\n const map = new Map([]);\n folders.forEach((obj: any) => {\n map.set(obj.uuid, obj);\n obj.children = [];\n });\n folders.forEach((obj: any) => {\n if (obj.parent_uuid != null && obj.parent_uuid !== '' && map.has(obj.parent_uuid)) {\n map.get(obj.parent_uuid).children.push(obj);\n } else {\n folderTree.push(obj);\n }\n });\n return folderTree;\n }\n\n private flattenFolderTree(titlePrefix: string, tree: any[], map: Map) {\n if (tree == null) {\n return;\n }\n tree.forEach((f: any) => {\n if (f.title != null && f.title.trim() !== '') {\n let title = f.title.trim();\n if (titlePrefix != null && titlePrefix.trim() !== '') {\n title = titlePrefix + '/' + title;\n }\n map.set(f.uuid, title);\n if (f.children != null && f.children.length !== 0) {\n this.flattenFolderTree(title, f.children, map);\n }\n }\n });\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class FirefoxCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.filter(value => {\n return value.url !== 'chrome://FirefoxAccounts';\n }).forEach(value => {\n const cipher = this.initLoginCipher();\n const url = this.getValueOrDefault(value.url, this.getValueOrDefault(value.hostname));\n cipher.name = this.getValueOrDefault(this.nameFromUrl(url), '--');\n cipher.login.username = this.getValueOrDefault(value.username);\n cipher.login.password = this.getValueOrDefault(value.password);\n cipher.login.uris = this.makeUriArray(url);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CardView } from '../models/view/cardView';\n\nimport { CipherType } from '../enums/cipherType';\n\nexport class FSecureFskImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = JSON.parse(data);\n if (results == null || results.data == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n for (const key in results.data) {\n if (!results.data.hasOwnProperty(key)) {\n continue;\n }\n\n const value = results.data[key];\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.service);\n cipher.notes = this.getValueOrDefault(value.notes);\n\n if (value.style === 'website') {\n cipher.login.username = this.getValueOrDefault(value.username);\n cipher.login.password = this.getValueOrDefault(value.password);\n cipher.login.uris = this.makeUriArray(value.url);\n } else if (value.style === 'creditcard') {\n cipher.type = CipherType.Card;\n cipher.card = new CardView();\n cipher.card.cardholderName = this.getValueOrDefault(value.username);\n cipher.card.number = this.getValueOrDefault(value.creditNumber);\n cipher.card.brand = this.getCardBrand(cipher.card.number);\n cipher.card.code = this.getValueOrDefault(value.creditCvv);\n if (!this.isNullOrWhitespace(value.creditExpiry)) {\n if (!this.setCardExpiration(cipher, value.creditExpiry)) {\n this.processKvp(cipher, 'Expiration', value.creditExpiry);\n }\n }\n if (!this.isNullOrWhitespace(value.password)) {\n this.processKvp(cipher, 'PIN', value.password);\n }\n } else {\n continue;\n }\n\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class GnomeJsonImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = JSON.parse(data);\n if (results == null || Object.keys(results).length === 0) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n for (const keyRing in results) {\n if (!results.hasOwnProperty(keyRing) || this.isNullOrWhitespace(keyRing) ||\n results[keyRing].length === 0) {\n continue;\n }\n\n results[keyRing].forEach((value: any) => {\n if (this.isNullOrWhitespace(value.display_name) || value.display_name.indexOf('http') !== 0) {\n return;\n }\n\n this.processFolder(result, keyRing);\n const cipher = this.initLoginCipher();\n cipher.name = value.display_name.replace('http://', '').replace('https://', '');\n if (cipher.name.length > 30) {\n cipher.name = cipher.name.substring(0, 30);\n }\n cipher.login.password = this.getValueOrDefault(value.secret);\n cipher.login.uris = this.makeUriArray(value.display_name);\n\n if (value.attributes != null) {\n cipher.login.username = value.attributes != null ?\n this.getValueOrDefault(value.attributes.username_value) : null;\n for (const attr in value.attributes) {\n if (!value.attributes.hasOwnProperty(attr) || attr === 'username_value' ||\n attr === 'xdg:schema') {\n continue;\n }\n this.processKvp(cipher, attr, value.attributes[attr]);\n }\n }\n\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n }\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nconst NotesHeader = 'Notes\\n\\n';\nconst ApplicationsHeader = 'Applications\\n\\n';\nconst WebsitesHeader = 'Websites\\n\\n';\nconst Delimiter = '\\n---\\n';\n\nexport class KasperskyTxtImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n\n let notesData: string;\n let applicationsData: string;\n let websitesData: string;\n let workingData = this.splitNewLine(data).join('\\n');\n\n if (workingData.indexOf(NotesHeader) !== -1) {\n const parts = workingData.split(NotesHeader);\n if (parts.length > 1) {\n workingData = parts[0];\n notesData = parts[1];\n }\n }\n if (workingData.indexOf(ApplicationsHeader) !== -1) {\n const parts = workingData.split(ApplicationsHeader);\n if (parts.length > 1) {\n workingData = parts[0];\n applicationsData = parts[1];\n }\n }\n if (workingData.indexOf(WebsitesHeader) === 0) {\n const parts = workingData.split(WebsitesHeader);\n if (parts.length > 1) {\n workingData = parts[0];\n websitesData = parts[1];\n }\n }\n\n const notes = this.parseDataCategory(notesData);\n const applications = this.parseDataCategory(applicationsData);\n const websites = this.parseDataCategory(websitesData);\n\n notes.forEach(n => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(n.get('Name'));\n cipher.notes = this.getValueOrDefault(n.get('Text'));\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n websites.concat(applications).forEach(w => {\n const cipher = this.initLoginCipher();\n const nameKey = w.has('Website name') ? 'Website name' : 'Application';\n cipher.name = this.getValueOrDefault(w.get(nameKey), '');\n if (!this.isNullOrWhitespace(w.get('Login name'))) {\n if (!this.isNullOrWhitespace(cipher.name)) {\n cipher.name += ': ';\n }\n cipher.name += w.get('Login name');\n }\n cipher.notes = this.getValueOrDefault(w.get('Comment'));\n if (w.has('Website URL')) {\n cipher.login.uris = this.makeUriArray(w.get('Website URL'));\n }\n cipher.login.username = this.getValueOrDefault(w.get('Login'));\n cipher.login.password = this.getValueOrDefault(w.get('Password'));\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n\n private parseDataCategory(data: string): Map[] {\n if (this.isNullOrWhitespace(data) || data.indexOf(Delimiter) === -1) {\n return [];\n }\n const items: Map[] = [];\n data.split(Delimiter).forEach(p => {\n if (p.indexOf('\\n') === -1) {\n return;\n }\n const item = new Map();\n let itemComment: string;\n let itemCommentKey: string;\n p.split('\\n').forEach(l => {\n if (itemComment != null) {\n itemComment += ('\\n' + l);\n return;\n }\n const colonIndex = l.indexOf(':');\n let key: string;\n let val: string;\n if (colonIndex === -1) {\n return;\n } else {\n key = l.substring(0, colonIndex);\n if (l.length > colonIndex + 1) {\n val = l.substring(colonIndex + 2);\n }\n }\n if (key != null) {\n item.set(key, val);\n }\n if (key === 'Comment' || key === 'Text') {\n itemComment = val;\n itemCommentKey = key;\n }\n });\n if (itemComment != null && itemCommentKey != null) {\n item.set(itemCommentKey, itemComment);\n }\n if (item.size === 0) {\n return;\n }\n items.push(item);\n });\n return items;\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { FieldType } from '../enums/fieldType';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { FolderView } from '../models/view/folderView';\n\nexport class KeePass2XmlImporter extends BaseImporter implements Importer {\n result = new ImportResult();\n\n parse(data: string): Promise {\n const doc = this.parseXml(data);\n if (doc == null) {\n this.result.success = false;\n return Promise.resolve(this.result);\n }\n\n const rootGroup = doc.querySelector('KeePassFile > Root > Group');\n if (rootGroup == null) {\n this.result.errorMessage = 'Missing `KeePassFile > Root > Group` node.';\n this.result.success = false;\n return Promise.resolve(this.result);\n }\n\n this.traverse(rootGroup, true, '');\n\n if (this.organization) {\n this.moveFoldersToCollections(this.result);\n }\n\n this.result.success = true;\n return Promise.resolve(this.result);\n }\n\n traverse(node: Element, isRootNode: boolean, groupPrefixName: string) {\n const folderIndex = this.result.folders.length;\n let groupName = groupPrefixName;\n\n if (!isRootNode) {\n if (groupName !== '') {\n groupName += '/';\n }\n const nameEl = this.querySelectorDirectChild(node, 'Name');\n groupName += nameEl == null ? '-' : nameEl.textContent;\n const folder = new FolderView();\n folder.name = groupName;\n this.result.folders.push(folder);\n }\n\n this.querySelectorAllDirectChild(node, 'Entry').forEach(entry => {\n const cipherIndex = this.result.ciphers.length;\n\n const cipher = this.initLoginCipher();\n this.querySelectorAllDirectChild(entry, 'String').forEach(entryString => {\n const valueEl = this.querySelectorDirectChild(entryString, 'Value');\n const value = valueEl != null ? valueEl.textContent : null;\n if (this.isNullOrWhitespace(value)) {\n return;\n }\n const keyEl = this.querySelectorDirectChild(entryString, 'Key');\n const key = keyEl != null ? keyEl.textContent : null;\n\n if (key === 'URL') {\n cipher.login.uris = this.makeUriArray(value);\n } else if (key === 'UserName') {\n cipher.login.username = value;\n } else if (key === 'Password') {\n cipher.login.password = value;\n } else if (key === 'otp') {\n cipher.login.totp = value.replace('key=', '');\n } else if (key === 'Title') {\n cipher.name = value;\n } else if (key === 'Notes') {\n cipher.notes += (value + '\\n');\n } else {\n let type = FieldType.Text;\n const attrs = (valueEl.attributes as any);\n if (attrs.length > 0 && attrs.ProtectInMemory != null &&\n attrs.ProtectInMemory.value === 'True') {\n type = FieldType.Hidden;\n }\n this.processKvp(cipher, key, value, type);\n }\n });\n\n this.cleanupCipher(cipher);\n this.result.ciphers.push(cipher);\n\n if (!isRootNode) {\n this.result.folderRelationships.push([cipherIndex, folderIndex]);\n }\n });\n\n this.querySelectorAllDirectChild(node, 'Group').forEach(group => {\n this.traverse(group, false, groupName);\n });\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class KeePassXCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (this.isNullOrWhitespace(value.Title)) {\n return;\n }\n\n value.Group = !this.isNullOrWhitespace(value.Group) && value.Group.startsWith('Root/') ?\n value.Group.replace('Root/', '') : value.Group;\n const groupName = !this.isNullOrWhitespace(value.Group) ? value.Group : null;\n this.processFolder(result, groupName);\n\n const cipher = this.initLoginCipher();\n cipher.notes = this.getValueOrDefault(value.Notes);\n cipher.name = this.getValueOrDefault(value.Title, '--');\n cipher.login.username = this.getValueOrDefault(value.Username);\n cipher.login.password = this.getValueOrDefault(value.Password);\n cipher.login.uris = this.makeUriArray(value.URL);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { FolderView } from '../models/view/folderView';\n\nexport class KeeperCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, false);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (value.length < 6) {\n return;\n }\n\n this.processFolder(result, value[0]);\n const cipher = this.initLoginCipher();\n cipher.notes = this.getValueOrDefault(value[5]) + '\\n';\n cipher.name = this.getValueOrDefault(value[1], '--');\n cipher.login.username = this.getValueOrDefault(value[2]);\n cipher.login.password = this.getValueOrDefault(value[3]);\n cipher.login.uris = this.makeUriArray(value[4]);\n\n if (value.length > 7) {\n // we have some custom fields.\n for (let i = 7; i < value.length; i = i + 2) {\n this.processKvp(cipher, value[i], value[i + 1]);\n }\n }\n\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CardView } from '../models/view/cardView';\nimport { CipherView } from '../models/view/cipherView';\nimport { FolderView } from '../models/view/folderView';\nimport { IdentityView } from '../models/view/identityView';\nimport { LoginView } from '../models/view/loginView';\nimport { SecureNoteView } from '../models/view/secureNoteView';\n\nimport { CipherType } from '../enums/cipherType';\nimport { SecureNoteType } from '../enums/secureNoteType';\n\nexport class LastPassCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach((value, index) => {\n const cipherIndex = result.ciphers.length;\n let folderIndex = result.folders.length;\n let grouping = value.grouping;\n if (grouping != null) {\n grouping = grouping.replace(/\\\\/g, '/').replace(/[\\x00-\\x1F\\x7F-\\x9F]/g, '');\n }\n const hasFolder = this.getValueOrDefault(grouping, '(none)') !== '(none)';\n let addFolder = hasFolder;\n\n if (hasFolder) {\n for (let i = 0; i < result.folders.length; i++) {\n if (result.folders[i].name === grouping) {\n addFolder = false;\n folderIndex = i;\n break;\n }\n }\n }\n\n const cipher = this.buildBaseCipher(value);\n if (cipher.type === CipherType.Login) {\n cipher.notes = this.getValueOrDefault(value.extra);\n cipher.login = new LoginView();\n cipher.login.uris = this.makeUriArray(value.url);\n cipher.login.username = this.getValueOrDefault(value.username);\n cipher.login.password = this.getValueOrDefault(value.password);\n cipher.login.totp = this.getValueOrDefault(value.totp);\n } else if (cipher.type === CipherType.SecureNote) {\n this.parseSecureNote(value, cipher);\n } else if (cipher.type === CipherType.Card) {\n cipher.card = this.parseCard(value);\n cipher.notes = this.getValueOrDefault(value.notes);\n } else if (cipher.type === CipherType.Identity) {\n cipher.identity = this.parseIdentity(value);\n cipher.notes = this.getValueOrDefault(value.notes);\n if (!this.isNullOrWhitespace(value.ccnum)) {\n // there is a card on this identity too\n const cardCipher = this.buildBaseCipher(value);\n cardCipher.identity = null;\n cardCipher.type = CipherType.Card;\n cardCipher.card = this.parseCard(value);\n result.ciphers.push(cardCipher);\n }\n }\n\n result.ciphers.push(cipher);\n\n if (addFolder) {\n const f = new FolderView();\n f.name = grouping;\n result.folders.push(f);\n }\n if (hasFolder) {\n result.folderRelationships.push([cipherIndex, folderIndex]);\n }\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n\n private buildBaseCipher(value: any) {\n const cipher = new CipherView();\n if (value.hasOwnProperty('profilename') && value.hasOwnProperty('profilelanguage')) {\n // form fill\n cipher.favorite = false;\n cipher.name = this.getValueOrDefault(value.profilename, '--');\n cipher.type = CipherType.Card;\n\n if (!this.isNullOrWhitespace(value.title) || !this.isNullOrWhitespace(value.firstname) ||\n !this.isNullOrWhitespace(value.lastname) || !this.isNullOrWhitespace(value.address1) ||\n !this.isNullOrWhitespace(value.phone) || !this.isNullOrWhitespace(value.username) ||\n !this.isNullOrWhitespace(value.email)) {\n cipher.type = CipherType.Identity;\n }\n } else {\n // site or secure note\n cipher.favorite = !this.organization && this.getValueOrDefault(value.fav, '0') === '1';\n cipher.name = this.getValueOrDefault(value.name, '--');\n cipher.type = value.url === 'http://sn' ? CipherType.SecureNote : CipherType.Login;\n }\n return cipher;\n }\n\n private parseCard(value: any): CardView {\n const card = new CardView();\n card.cardholderName = this.getValueOrDefault(value.ccname);\n card.number = this.getValueOrDefault(value.ccnum);\n card.code = this.getValueOrDefault(value.cccsc);\n card.brand = this.getCardBrand(value.ccnum);\n\n if (!this.isNullOrWhitespace(value.ccexp) && value.ccexp.indexOf('-') > -1) {\n const ccexpParts = (value.ccexp as string).split('-');\n if (ccexpParts.length > 1) {\n card.expYear = ccexpParts[0];\n card.expMonth = ccexpParts[1];\n if (card.expMonth.length === 2 && card.expMonth[0] === '0') {\n card.expMonth = card.expMonth[1];\n }\n }\n }\n\n return card;\n }\n\n private parseIdentity(value: any): IdentityView {\n const identity = new IdentityView();\n identity.title = this.getValueOrDefault(value.title);\n identity.firstName = this.getValueOrDefault(value.firstname);\n identity.middleName = this.getValueOrDefault(value.middlename);\n identity.lastName = this.getValueOrDefault(value.lastname);\n identity.username = this.getValueOrDefault(value.username);\n identity.company = this.getValueOrDefault(value.company);\n identity.ssn = this.getValueOrDefault(value.ssn);\n identity.address1 = this.getValueOrDefault(value.address1);\n identity.address2 = this.getValueOrDefault(value.address2);\n identity.address3 = this.getValueOrDefault(value.address3);\n identity.city = this.getValueOrDefault(value.city);\n identity.state = this.getValueOrDefault(value.state);\n identity.postalCode = this.getValueOrDefault(value.zip);\n identity.country = this.getValueOrDefault(value.country);\n identity.email = this.getValueOrDefault(value.email);\n identity.phone = this.getValueOrDefault(value.phone);\n\n if (!this.isNullOrWhitespace(identity.title)) {\n identity.title = identity.title.charAt(0).toUpperCase() + identity.title.slice(1);\n }\n\n return identity;\n }\n\n private parseSecureNote(value: any, cipher: CipherView) {\n const extraParts = this.splitNewLine(value.extra);\n let processedNote = false;\n\n if (extraParts.length) {\n const typeParts = extraParts[0].split(':');\n if (typeParts.length > 1 && typeParts[0] === 'NoteType' &&\n (typeParts[1] === 'Credit Card' || typeParts[1] === 'Address')) {\n if (typeParts[1] === 'Credit Card') {\n const mappedData = this.parseSecureNoteMapping(cipher, extraParts, {\n 'Number': 'number',\n 'Name on Card': 'cardholderName',\n 'Security Code': 'code',\n // LP provides date in a format like 'June,2020'\n // Store in expMonth, then parse and modify\n 'Expiration Date': 'expMonth',\n });\n\n if (this.isNullOrWhitespace(mappedData.expMonth) || mappedData.expMonth === ',') {\n // No expiration data\n mappedData.expMonth = undefined;\n } else {\n const [monthString, year] = mappedData.expMonth.split(',');\n // Parse month name into number\n if (!this.isNullOrWhitespace(monthString)) {\n const month = new Date(Date.parse(monthString.trim() + ' 1, 2012')).getMonth() + 1;\n if (isNaN(month)) {\n mappedData.expMonth = undefined;\n } else {\n mappedData.expMonth = month.toString();\n }\n } else {\n mappedData.expMonth = undefined;\n }\n if (!this.isNullOrWhitespace(year)) {\n mappedData.expYear = year;\n }\n }\n\n cipher.type = CipherType.Card;\n cipher.card = mappedData;\n } else if (typeParts[1] === 'Address') {\n const mappedData = this.parseSecureNoteMapping(cipher, extraParts, {\n 'Title': 'title',\n 'First Name': 'firstName',\n 'Last Name': 'lastName',\n 'Middle Name': 'middleName',\n 'Company': 'company',\n 'Address 1': 'address1',\n 'Address 2': 'address2',\n 'Address 3': 'address3',\n 'City / Town': 'city',\n 'State': 'state',\n 'Zip / Postal Code': 'postalCode',\n 'Country': 'country',\n 'Email Address': 'email',\n 'Username': 'username',\n });\n cipher.type = CipherType.Identity;\n cipher.identity = mappedData;\n }\n processedNote = true;\n }\n }\n\n if (!processedNote) {\n cipher.secureNote = new SecureNoteView();\n cipher.secureNote.type = SecureNoteType.Generic;\n cipher.notes = this.getValueOrDefault(value.extra);\n }\n }\n\n private parseSecureNoteMapping(cipher: CipherView, extraParts: string[], map: any): T {\n const dataObj: any = {};\n\n let processingNotes = false;\n extraParts.forEach(extraPart => {\n let key: string = null;\n let val: string = null;\n if (!processingNotes) {\n if (this.isNullOrWhitespace(extraPart)) {\n return;\n }\n const colonIndex = extraPart.indexOf(':');\n if (colonIndex === -1) {\n key = extraPart;\n } else {\n key = extraPart.substring(0, colonIndex);\n if (extraPart.length > colonIndex) {\n val = extraPart.substring(colonIndex + 1);\n }\n }\n if (this.isNullOrWhitespace(key) || this.isNullOrWhitespace(val) || key === 'NoteType') {\n return;\n }\n }\n\n if (processingNotes) {\n cipher.notes += ('\\n' + extraPart);\n } else if (key === 'Notes') {\n if (!this.isNullOrWhitespace(cipher.notes)) {\n cipher.notes += ('\\n' + val);\n } else {\n cipher.notes = val;\n }\n processingNotes = true;\n } else if (map.hasOwnProperty(key)) {\n dataObj[map[key]] = val;\n } else {\n this.processKvp(cipher, key, val);\n }\n });\n\n return dataObj;\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class LogMeOnceCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, false);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (value.length < 4) {\n return;\n }\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value[0], '--');\n cipher.login.username = this.getValueOrDefault(value[2]);\n cipher.login.password = this.getValueOrDefault(value[3]);\n cipher.login.uris = this.makeUriArray(value[1]);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class MeldiumCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.DisplayName, '--');\n cipher.notes = this.getValueOrDefault(value.Notes);\n cipher.login.username = this.getValueOrDefault(value.UserName);\n cipher.login.password = this.getValueOrDefault(value.Password);\n cipher.login.uris = this.makeUriArray(value.Url);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CipherType } from '../enums/cipherType';\nimport { SecureNoteType } from '../enums/secureNoteType';\n\nimport { SecureNoteView } from '../models/view/secureNoteView';\n\nexport class MSecureCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, false);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (value.length < 3) {\n return;\n }\n\n const folderName = this.getValueOrDefault(value[0], 'Unassigned') !== 'Unassigned' ? value[0] : null;\n this.processFolder(result, folderName);\n\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value[2], '--');\n\n if (value[1] === 'Web Logins' || value[1] === 'Login') {\n cipher.login.uris = this.makeUriArray(value[4]);\n cipher.login.username = this.getValueOrDefault(value[5]);\n cipher.login.password = this.getValueOrDefault(value[6]);\n cipher.notes = !this.isNullOrWhitespace(value[3]) ? value[3].split('\\\\n').join('\\n') : null;\n } else if (value.length > 3) {\n cipher.type = CipherType.SecureNote;\n cipher.secureNote = new SecureNoteView();\n cipher.secureNote.type = SecureNoteType.Generic;\n for (let i = 3; i < value.length; i++) {\n if (!this.isNullOrWhitespace(value[i])) {\n cipher.notes += (value[i] + '\\n');\n }\n }\n }\n\n if (!this.isNullOrWhitespace(value[1]) && cipher.type !== CipherType.Login) {\n cipher.name = value[1] + ': ' + cipher.name;\n }\n\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { CipherType } from '../enums/cipherType';\nimport { SecureNoteType } from '../enums/secureNoteType';\n\nimport { CardView } from '../models/view/cardView';\nimport { IdentityView } from '../models/view/identityView';\nimport { SecureNoteView } from '../models/view/secureNoteView';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class MykiCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.nickname, '--');\n cipher.notes = this.getValueOrDefault(value.additionalInfo);\n\n if (value.url !== undefined) {\n // Accounts\n cipher.login.uris = this.makeUriArray(value.url);\n cipher.login.username = this.getValueOrDefault(value.username);\n cipher.login.password = this.getValueOrDefault(value.password);\n cipher.login.totp = this.getValueOrDefault(value.twoFactAuthToken);\n } else if (value.cardNumber !== undefined) {\n // Cards\n cipher.card = new CardView();\n cipher.type = CipherType.Card;\n cipher.card.cardholderName = this.getValueOrDefault(value.cardName);\n cipher.card.number = this.getValueOrDefault(value.cardNumber);\n cipher.card.brand = this.getCardBrand(cipher.card.number);\n cipher.card.expMonth = this.getValueOrDefault(value.exp_month);\n cipher.card.expYear = this.getValueOrDefault(value.exp_year);\n cipher.card.code = this.getValueOrDefault(value.cvv);\n } else if (value.firstName !== undefined) {\n // Identities\n cipher.identity = new IdentityView();\n cipher.type = CipherType.Identity;\n cipher.identity.title = this.getValueOrDefault(value.title);\n cipher.identity.firstName = this.getValueOrDefault(value.firstName);\n cipher.identity.middleName = this.getValueOrDefault(value.middleName);\n cipher.identity.lastName = this.getValueOrDefault(value.lastName);\n cipher.identity.phone = this.getValueOrDefault(value.number);\n cipher.identity.email = this.getValueOrDefault(value.email);\n cipher.identity.address1 = this.getValueOrDefault(value.firstAddressLine);\n cipher.identity.address2 = this.getValueOrDefault(value.secondAddressLine);\n cipher.identity.city = this.getValueOrDefault(value.city);\n cipher.identity.country = this.getValueOrDefault(value.country);\n cipher.identity.postalCode = this.getValueOrDefault(value.zipCode);\n } else if (value.content !== undefined) {\n // Notes\n cipher.secureNote = new SecureNoteView();\n cipher.type = CipherType.SecureNote;\n cipher.secureNote.type = SecureNoteType.Generic;\n cipher.name = this.getValueOrDefault(value.title, '--');\n cipher.notes = this.getValueOrDefault(value.content);\n } else {\n return;\n }\n\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CipherView } from '../models/view/cipherView';\nimport { LoginView } from '../models/view/loginView';\n\nimport { CipherType } from '../enums/cipherType';\nimport { SecureNoteType } from '../enums/secureNoteType';\n\ntype nodePassCsvParsed = {\n name: string;\n url: string;\n username: string;\n password: string;\n note: string;\n cardholdername: string;\n cardnumber: string;\n cvc: string;\n expirydate: string;\n zipcode: string;\n folder: string;\n full_name: string;\n phone_number: string;\n email: string;\n address1: string;\n address2: string;\n city: string;\n country: string;\n state: string;\n};\n\nexport class NordPassCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results: nodePassCsvParsed[] = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(record => {\n\n const recordType = this.evaluateType(record);\n if (recordType === undefined) {\n return;\n }\n\n if (!this.organization) {\n this.processFolder(result, record.folder);\n }\n\n const cipher = new CipherView();\n cipher.name = this.getValueOrDefault(record.name, '--');\n cipher.notes = this.getValueOrDefault(record.note);\n\n switch (recordType) {\n case CipherType.Login:\n cipher.type = CipherType.Login;\n cipher.login = new LoginView();\n cipher.login.username = this.getValueOrDefault(record.username);\n cipher.login.password = this.getValueOrDefault(record.password);\n cipher.login.uris = this.makeUriArray(record.url);\n break;\n case CipherType.Card:\n cipher.type = CipherType.Card;\n cipher.card.cardholderName = this.getValueOrDefault(record.cardholdername);\n cipher.card.number = this.getValueOrDefault(record.cardnumber);\n cipher.card.code = this.getValueOrDefault(record.cvc);\n cipher.card.brand = this.getCardBrand(cipher.card.number);\n this.setCardExpiration(cipher, record.expirydate);\n break;\n\n case CipherType.Identity:\n cipher.type = CipherType.Identity;\n\n this.processName(cipher, this.getValueOrDefault(record.full_name));\n cipher.identity.address1 = this.getValueOrDefault(record.address1);\n cipher.identity.address2 = this.getValueOrDefault(record.address2);\n cipher.identity.city = this.getValueOrDefault(record.city);\n cipher.identity.state = this.getValueOrDefault(record.state);\n cipher.identity.postalCode = this.getValueOrDefault(record.zipcode);\n cipher.identity.country = this.getValueOrDefault(record.country);\n if (cipher.identity.country != null) {\n cipher.identity.country = cipher.identity.country.toUpperCase();\n }\n cipher.identity.email = this.getValueOrDefault(record.email);\n cipher.identity.phone = this.getValueOrDefault(record.phone_number);\n break;\n case CipherType.SecureNote:\n cipher.type = CipherType.SecureNote;\n cipher.secureNote.type = SecureNoteType.Generic;\n break;\n default:\n break;\n }\n\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n\n private evaluateType(record: nodePassCsvParsed): CipherType {\n\n if (!this.isNullOrWhitespace(record.username)) {\n return CipherType.Login;\n }\n\n if (!this.isNullOrWhitespace(record.cardnumber)) {\n return CipherType.Card;\n }\n\n if (!this.isNullOrWhitespace(record.full_name)) {\n return CipherType.Identity;\n }\n\n if (!this.isNullOrWhitespace(record.note)) {\n return CipherType.SecureNote;\n }\n\n return undefined;\n }\n\n private processName(cipher: CipherView, fullName: string) {\n\n if (this.isNullOrWhitespace(fullName)) {\n return;\n }\n\n const nameParts = fullName.split(' ');\n if (nameParts.length > 0) {\n cipher.identity.firstName = this.getValueOrDefault(nameParts[0]);\n }\n if (nameParts.length === 2) {\n cipher.identity.lastName = this.getValueOrDefault(nameParts[1]);\n } else if (nameParts.length >= 3) {\n cipher.identity.middleName = this.getValueOrDefault(nameParts[1]);\n cipher.identity.lastName = nameParts.slice(2, nameParts.length).join(' ');\n }\n }\n}\n","import { BaseImporter } from '../baseImporter';\nimport { Importer } from '../importer';\n\nimport { ImportResult } from '../../models/domain/importResult';\n\nimport { CardView } from '../../models/view/cardView';\nimport { CipherView } from '../../models/view/cipherView';\nimport { IdentityView } from '../../models/view/identityView';\nimport { PasswordHistoryView } from '../../models/view/passwordHistoryView';\nimport { SecureNoteView } from '../../models/view/secureNoteView';\n\nimport { CipherType } from '../../enums/cipherType';\nimport { FieldType } from '../../enums/fieldType';\nimport { SecureNoteType } from '../../enums/secureNoteType';\n\nexport class OnePassword1PifImporter extends BaseImporter implements Importer {\n result = new ImportResult();\n\n parse(data: string): Promise {\n data.split(this.newLineRegex).forEach(line => {\n if (this.isNullOrWhitespace(line) || line[0] !== '{') {\n return;\n }\n const item = JSON.parse(line);\n if (item.trashed === true) {\n return;\n }\n const cipher = this.initLoginCipher();\n\n if (this.isNullOrWhitespace(item.hmac)) {\n this.processStandardItem(item, cipher);\n } else {\n this.processWinOpVaultItem(item, cipher);\n }\n\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n this.result.ciphers.push(cipher);\n });\n\n this.result.success = true;\n return Promise.resolve(this.result);\n }\n\n private processWinOpVaultItem(item: any, cipher: CipherView) {\n if (item.overview != null) {\n cipher.name = this.getValueOrDefault(item.overview.title);\n if (item.overview.URLs != null) {\n const urls: string[] = [];\n item.overview.URLs.forEach((url: any) => {\n if (!this.isNullOrWhitespace(url.u)) {\n urls.push(url.u);\n }\n });\n cipher.login.uris = this.makeUriArray(urls);\n }\n }\n\n if (item.details != null) {\n if (item.details.passwordHistory != null) {\n this.parsePasswordHistory(item.details.passwordHistory, cipher);\n }\n if (!this.isNullOrWhitespace(item.details.ccnum) || !this.isNullOrWhitespace(item.details.cvv)) {\n cipher.type = CipherType.Card;\n cipher.card = new CardView();\n } else if (!this.isNullOrWhitespace(item.details.firstname) ||\n !this.isNullOrWhitespace(item.details.address1)) {\n cipher.type = CipherType.Identity;\n cipher.identity = new IdentityView();\n }\n if (cipher.type === CipherType.Login && !this.isNullOrWhitespace(item.details.password)) {\n cipher.login.password = item.details.password;\n }\n if (!this.isNullOrWhitespace(item.details.notesPlain)) {\n cipher.notes = item.details.notesPlain.split(this.newLineRegex).join('\\n') + '\\n';\n }\n if (item.details.fields != null) {\n this.parseFields(item.details.fields, cipher, 'designation', 'value', 'name');\n }\n if (item.details.sections != null) {\n item.details.sections.forEach((section: any) => {\n if (section.fields != null) {\n this.parseFields(section.fields, cipher, 'n', 'v', 't');\n }\n });\n }\n }\n }\n\n private processStandardItem(item: any, cipher: CipherView) {\n cipher.favorite = item.openContents && item.openContents.faveIndex ? true : false;\n cipher.name = this.getValueOrDefault(item.title);\n\n if (item.typeName === 'securenotes.SecureNote') {\n cipher.type = CipherType.SecureNote;\n cipher.secureNote = new SecureNoteView();\n cipher.secureNote.type = SecureNoteType.Generic;\n } else if (item.typeName === 'wallet.financial.CreditCard') {\n cipher.type = CipherType.Card;\n cipher.card = new CardView();\n } else if (item.typeName === 'identities.Identity') {\n cipher.type = CipherType.Identity;\n cipher.identity = new IdentityView();\n } else {\n cipher.login.uris = this.makeUriArray(item.location);\n }\n\n if (item.secureContents != null) {\n if (item.secureContents.passwordHistory != null) {\n this.parsePasswordHistory(item.secureContents.passwordHistory, cipher);\n }\n if (!this.isNullOrWhitespace(item.secureContents.notesPlain)) {\n cipher.notes = item.secureContents.notesPlain.split(this.newLineRegex).join('\\n') + '\\n';\n }\n if (cipher.type === CipherType.Login) {\n if (!this.isNullOrWhitespace(item.secureContents.password)) {\n cipher.login.password = item.secureContents.password;\n }\n if (item.secureContents.URLs != null) {\n const urls: string[] = [];\n item.secureContents.URLs.forEach((u: any) => {\n if (!this.isNullOrWhitespace(u.url)) {\n urls.push(u.url);\n }\n });\n if (urls.length > 0) {\n cipher.login.uris = this.makeUriArray(urls);\n }\n }\n }\n if (item.secureContents.fields != null) {\n this.parseFields(item.secureContents.fields, cipher, 'designation', 'value', 'name');\n }\n if (item.secureContents.sections != null) {\n item.secureContents.sections.forEach((section: any) => {\n if (section.fields != null) {\n this.parseFields(section.fields, cipher, 'n', 'v', 't');\n }\n });\n }\n }\n }\n\n private parsePasswordHistory(items: any[], cipher: CipherView) {\n const maxSize = items.length > 5 ? 5 : items.length;\n cipher.passwordHistory = items\n .filter((h: any) => !this.isNullOrWhitespace(h.value) && h.time != null)\n .sort((a, b) => b.time - a.time)\n .slice(0, maxSize)\n .map((h: any) => {\n const ph = new PasswordHistoryView();\n ph.password = h.value;\n ph.lastUsedDate = new Date(('' + h.time).length >= 13 ? h.time : h.time * 1000);\n return ph;\n });\n }\n\n private parseFields(fields: any[], cipher: CipherView, designationKey: string, valueKey: string, nameKey: string) {\n fields.forEach((field: any) => {\n if (field[valueKey] == null || field[valueKey].toString().trim() === '') {\n return;\n }\n\n const fieldValue = field[valueKey].toString();\n const fieldDesignation = field[designationKey] != null ? field[designationKey].toString() : null;\n\n if (cipher.type === CipherType.Login) {\n if (this.isNullOrWhitespace(cipher.login.username) && fieldDesignation === 'username') {\n cipher.login.username = fieldValue;\n return;\n } else if (this.isNullOrWhitespace(cipher.login.password) && fieldDesignation === 'password') {\n cipher.login.password = fieldValue;\n return;\n } else if (this.isNullOrWhitespace(cipher.login.totp) && fieldDesignation != null &&\n fieldDesignation.startsWith('TOTP_')) {\n cipher.login.totp = fieldValue;\n return;\n }\n } else if (cipher.type === CipherType.Card) {\n if (this.isNullOrWhitespace(cipher.card.number) && fieldDesignation === 'ccnum') {\n cipher.card.number = fieldValue;\n cipher.card.brand = this.getCardBrand(fieldValue);\n return;\n } else if (this.isNullOrWhitespace(cipher.card.code) && fieldDesignation === 'cvv') {\n cipher.card.code = fieldValue;\n return;\n } else if (this.isNullOrWhitespace(cipher.card.cardholderName) && fieldDesignation === 'cardholder') {\n cipher.card.cardholderName = fieldValue;\n return;\n } else if (this.isNullOrWhitespace(cipher.card.expiration) && fieldDesignation === 'expiry' &&\n fieldValue.length === 6) {\n cipher.card.expMonth = (fieldValue as string).substr(4, 2);\n if (cipher.card.expMonth[0] === '0') {\n cipher.card.expMonth = cipher.card.expMonth.substr(1, 1);\n }\n cipher.card.expYear = (fieldValue as string).substr(0, 4);\n return;\n } else if (fieldDesignation === 'type') {\n // Skip since brand was determined from number above\n return;\n }\n } else if (cipher.type === CipherType.Identity) {\n const identity = cipher.identity;\n if (this.isNullOrWhitespace(identity.firstName) && fieldDesignation === 'firstname') {\n identity.firstName = fieldValue;\n return;\n } else if (this.isNullOrWhitespace(identity.lastName) && fieldDesignation === 'lastname') {\n identity.lastName = fieldValue;\n return;\n } else if (this.isNullOrWhitespace(identity.middleName) && fieldDesignation === 'initial') {\n identity.middleName = fieldValue;\n return;\n } else if (this.isNullOrWhitespace(identity.phone) && fieldDesignation === 'defphone') {\n identity.phone = fieldValue;\n return;\n } else if (this.isNullOrWhitespace(identity.company) && fieldDesignation === 'company') {\n identity.company = fieldValue;\n return;\n } else if (this.isNullOrWhitespace(identity.email) && fieldDesignation === 'email') {\n identity.email = fieldValue;\n return;\n } else if (this.isNullOrWhitespace(identity.username) && fieldDesignation === 'username') {\n identity.username = fieldValue;\n return;\n } else if (fieldDesignation === 'address') {\n // fieldValue is an object casted into a string, so access the plain value instead\n const { street, city, country, zip } = field[valueKey];\n identity.address1 = this.getValueOrDefault(street);\n identity.city = this.getValueOrDefault(city);\n if (!this.isNullOrWhitespace(country)) {\n identity.country = country.toUpperCase();\n }\n identity.postalCode = this.getValueOrDefault(zip);\n return;\n }\n }\n\n const fieldName = this.isNullOrWhitespace(field[nameKey]) ? 'no_name' : field[nameKey];\n if (fieldName === 'password' && cipher.passwordHistory != null &&\n cipher.passwordHistory.some(h => h.password === fieldValue)) {\n return;\n }\n\n const fieldType = field.k === 'concealed' ? FieldType.Hidden : FieldType.Text;\n this.processKvp(cipher, fieldName, fieldValue, fieldType);\n });\n }\n}\n","import { Importer } from '../importer';\nimport { IgnoredProperties, OnePasswordCsvImporter } from './onepasswordCsvImporter';\n\nimport { CipherType } from '../../enums/cipherType';\nimport { CardView } from '../../models/view/cardView';\nimport { CipherView } from '../../models/view/cipherView';\nimport { IdentityView } from '../../models/view/identityView';\n\nexport class OnePasswordMacCsvImporter extends OnePasswordCsvImporter implements Importer {\n setCipherType(value: any, cipher: CipherView) {\n const onePassType = this.getValueOrDefault(this.getProp(value, 'type'), 'Login');\n switch (onePassType) {\n case 'Credit Card':\n cipher.type = CipherType.Card;\n cipher.card = new CardView();\n IgnoredProperties.push('type');\n break;\n case 'Identity':\n cipher.type = CipherType.Identity;\n cipher.identity = new IdentityView();\n IgnoredProperties.push('type');\n break;\n case 'Login':\n case 'Secure Note':\n IgnoredProperties.push('type');\n default:\n break;\n }\n }\n}\n","import { CipherView } from '../../models/view/cipherView';\n\nexport class CipherImportContext {\n lowerProperty: string;\n constructor(public importRecord: any, public property: string, public cipher: CipherView) {\n this.lowerProperty = property.toLowerCase();\n }\n}\n","import { Importer } from '../importer';\nimport { CipherImportContext } from './cipherImportContext';\nimport { OnePasswordCsvImporter } from './onepasswordCsvImporter';\n\nimport { CipherType } from '../../enums/cipherType';\nimport { CardView } from '../../models/view/cardView';\nimport { CipherView } from '../../models/view/cipherView';\nimport { IdentityView } from '../../models/view/identityView';\nimport { LoginView } from '../../models/view/loginView';\n\nexport class OnePasswordWinCsvImporter extends OnePasswordCsvImporter implements Importer {\n constructor() {\n super();\n this.identityPropertyParsers.push(this.setIdentityAddress);\n }\n\n setCipherType(value: any, cipher: CipherView) {\n cipher.type = CipherType.Login;\n cipher.login = new LoginView();\n\n if (!this.isNullOrWhitespace(this.getPropByRegexp(value, /\\d+: number/i)) &&\n !this.isNullOrWhitespace(this.getPropByRegexp(value, /\\d+: expiry date/i))) {\n cipher.type = CipherType.Card;\n cipher.card = new CardView();\n }\n\n if (!this.isNullOrWhitespace(this.getPropByRegexp(value, /name \\d+: first name/i)) ||\n !this.isNullOrWhitespace(this.getPropByRegexp(value, /name \\d+: initial/i)) ||\n !this.isNullOrWhitespace(this.getPropByRegexp(value, /name \\d+: last name/i)) ||\n !this.isNullOrWhitespace(this.getPropByRegexp(value, /internet \\d+: email/i))) {\n cipher.type = CipherType.Identity;\n cipher.identity = new IdentityView();\n }\n }\n\n setIdentityAddress(context: CipherImportContext) {\n if (context.lowerProperty.match(/address \\d+: address/i)) {\n this.processKvp(context.cipher, 'address', context.importRecord[context.property]);\n return true;\n }\n return false;\n }\n\n setCreditCardExpiry(context: CipherImportContext) {\n if (this.isNullOrWhitespace(context.cipher.card.expiration) && context.lowerProperty.includes('expiry date')) {\n const expSplit = (context.importRecord[context.property] as string).split('/');\n context.cipher.card.expMonth = expSplit[0];\n if (context.cipher.card.expMonth[0] === '0' && context.cipher.card.expMonth.length === 2) {\n context.cipher.card.expMonth = context.cipher.card.expMonth.substr(1, 1);\n }\n context.cipher.card.expYear = expSplit[2].length > 4 ? expSplit[2].substr(0, 4) : expSplit[2];\n return true;\n }\n return false;\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CollectionView } from '../models/view/collectionView';\nimport { FolderView } from '../models/view/folderView';\n\nexport class PadlockCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, false);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n let headers: string[] = null;\n results.forEach(value => {\n if (headers == null) {\n headers = value.map((v: string) => v);\n return;\n }\n\n if (value.length < 2 || value.length !== headers.length) {\n return;\n }\n\n if (!this.isNullOrWhitespace(value[1])) {\n if (this.organization) {\n const tags = (value[1] as string).split(',');\n tags.forEach(tag => {\n tag = tag.trim();\n let addCollection = true;\n let collectionIndex = result.collections.length;\n\n for (let i = 0; i < result.collections.length; i++) {\n if (result.collections[i].name === tag) {\n addCollection = false;\n collectionIndex = i;\n break;\n }\n }\n\n if (addCollection) {\n const collection = new CollectionView();\n collection.name = tag;\n result.collections.push(collection);\n }\n\n result.collectionRelationships.push([result.ciphers.length, collectionIndex]);\n });\n } else {\n const tags = (value[1] as string).split(',');\n const tag = tags.length > 0 ? tags[0].trim() : null;\n this.processFolder(result, tag);\n }\n }\n\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value[0], '--');\n\n for (let i = 2; i < value.length; i++) {\n const header = headers[i].trim().toLowerCase();\n if (this.isNullOrWhitespace(value[i]) || this.isNullOrWhitespace(header)) {\n continue;\n }\n\n if (this.usernameFieldNames.indexOf(header) > -1) {\n cipher.login.username = value[i];\n } else if (this.passwordFieldNames.indexOf(header) > -1) {\n cipher.login.password = value[i];\n } else if (this.uriFieldNames.indexOf(header) > -1) {\n cipher.login.uris = this.makeUriArray(value[i]);\n } else {\n this.processKvp(cipher, headers[i], value[i]);\n }\n }\n\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class PassKeepCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n this.processFolder(result, this.getValue('category', value));\n const cipher = this.initLoginCipher();\n cipher.notes = this.getValue('description', value);\n cipher.name = this.getValueOrDefault(this.getValue('title', value), '--');\n cipher.login.username = this.getValue('username', value);\n cipher.login.password = this.getValue('password', value);\n cipher.login.uris = this.makeUriArray(this.getValue('site', value));\n this.processKvp(cipher, 'Password 2', this.getValue('password2', value));\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n\n private getValue(key: string, value: any) {\n return this.getValueOrDefault(value[key], this.getValueOrDefault(value[(' ' + key)]));\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class PassmanJsonImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = JSON.parse(data);\n if (results == null || results.length === 0) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach((credential: any) => {\n if (credential.tags != null && credential.tags.length > 0) {\n const folderName = credential.tags[0].text;\n this.processFolder(result, folderName);\n }\n\n const cipher = this.initLoginCipher();\n cipher.name = credential.label;\n\n cipher.login.username = this.getValueOrDefault(credential.username);\n if (this.isNullOrWhitespace(cipher.login.username)) {\n cipher.login.username = this.getValueOrDefault(credential.email);\n } else if (!this.isNullOrWhitespace(credential.email)) {\n cipher.notes = ('Email: ' + credential.email + '\\n');\n }\n\n cipher.login.password = this.getValueOrDefault(credential.password);\n cipher.login.uris = this.makeUriArray(credential.url);\n cipher.notes += this.getValueOrDefault(credential.description, '');\n if (credential.otp != null) {\n cipher.login.totp = this.getValueOrDefault(credential.otp.secret);\n }\n\n if (credential.custom_fields != null) {\n credential.custom_fields.forEach((customField: any) => {\n switch (customField.field_type) {\n case 'text':\n case 'password':\n this.processKvp(cipher, customField.label, customField.value);\n break;\n }\n });\n }\n\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CollectionView } from '../models/view/collectionView';\n\nexport class PasspackCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n const tagsJson = !this.isNullOrWhitespace(value.Tags) ? JSON.parse(value.Tags) : null;\n const tags: string[] = tagsJson != null && tagsJson.tags != null && tagsJson.tags.length > 0 ?\n tagsJson.tags.map((tagJson: string) => {\n try {\n const t = JSON.parse(tagJson);\n return this.getValueOrDefault(t.tag);\n } catch {\n // Ignore error\n }\n return null;\n }).filter((t: string) => !this.isNullOrWhitespace(t)) : null;\n\n if (this.organization && tags != null && tags.length > 0) {\n tags.forEach(tag => {\n let addCollection = true;\n let collectionIndex = result.collections.length;\n\n for (let i = 0; i < result.collections.length; i++) {\n if (result.collections[i].name === tag) {\n addCollection = false;\n collectionIndex = i;\n break;\n }\n }\n\n if (addCollection) {\n const collection = new CollectionView();\n collection.name = tag;\n result.collections.push(collection);\n }\n\n result.collectionRelationships.push([result.ciphers.length, collectionIndex]);\n });\n } else if (!this.organization && tags != null && tags.length > 0) {\n this.processFolder(result, tags[0]);\n }\n\n const cipher = this.initLoginCipher();\n cipher.notes = this.getValueOrDefault(value.Notes, '');\n cipher.notes += ('\\n\\n' + this.getValueOrDefault(value['Shared Notes'], '') + '\\n');\n cipher.name = this.getValueOrDefault(value['Entry Name'], '--');\n cipher.login.username = this.getValueOrDefault(value['User ID']);\n cipher.login.password = this.getValueOrDefault(value.Password);\n cipher.login.uris = this.makeUriArray(value.URL);\n\n if (value.__parsed_extra != null && value.__parsed_extra.length > 0) {\n value.__parsed_extra.forEach((extra: string) => {\n if (!this.isNullOrWhitespace(extra)) {\n cipher.notes += ('\\n' + extra);\n }\n });\n }\n\n const fieldsJson = !this.isNullOrWhitespace(value['Extra Fields']) ?\n JSON.parse(value['Extra Fields']) : null;\n const fields = fieldsJson != null && fieldsJson.extraFields != null &&\n fieldsJson.extraFields.length > 0 ? fieldsJson.extraFields.map((fieldJson: string) => {\n try {\n return JSON.parse(fieldJson);\n } catch {\n // Ignore error\n }\n return null;\n }) : null;\n if (fields != null) {\n fields.forEach((f: any) => {\n if (f != null) {\n this.processKvp(cipher, f.name, f.data);\n }\n });\n }\n\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class PasswordAgentCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, false);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n let newVersion = true;\n results.forEach(value => {\n if (value.length !== 5 && value.length < 9) {\n return;\n }\n const altFormat = value.length === 10 && value[0] === '0';\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value[altFormat ? 1 : 0], '--');\n cipher.login.username = this.getValueOrDefault(value[altFormat ? 2 : 1]);\n cipher.login.password = this.getValueOrDefault(value[altFormat ? 3 : 2]);\n if (value.length === 5) {\n newVersion = false;\n cipher.notes = this.getValueOrDefault(value[4]);\n cipher.login.uris = this.makeUriArray(value[3]);\n } else {\n const folder = this.getValueOrDefault(value[altFormat ? 9 : 8], '(None)');\n let folderName = folder !== '(None)' ? folder.split('\\\\').join('/') : null;\n if (folderName != null) {\n folderName = folder.split(' > ').join('/');\n folderName = folder.split('>').join('/');\n }\n this.processFolder(result, folderName);\n cipher.notes = this.getValueOrDefault(value[altFormat ? 5 : 3]);\n cipher.login.uris = this.makeUriArray(value[4]);\n }\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (newVersion && this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CardView } from '../models/view/cardView';\nimport { FolderView } from '../models/view/folderView';\n\nimport { CipherType } from '../enums/cipherType';\n\nexport class PasswordBossJsonImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = JSON.parse(data);\n if (results == null || results.items == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n const foldersMap = new Map();\n results.folders.forEach((value: any) => {\n foldersMap.set(value.id, value.name);\n });\n const foldersIndexMap = new Map();\n foldersMap.forEach((val, key) => {\n foldersIndexMap.set(key, result.folders.length);\n const f = new FolderView();\n f.name = val;\n result.folders.push(f);\n });\n\n results.items.forEach((value: any) => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.name, '--');\n cipher.login.uris = this.makeUriArray(value.login_url);\n\n if (value.folder != null && foldersIndexMap.has(value.folder)) {\n result.folderRelationships.push([result.ciphers.length, foldersIndexMap.get(value.folder)]);\n }\n\n if (value.identifiers == null) {\n return;\n }\n\n if (!this.isNullOrWhitespace(value.identifiers.notes)) {\n cipher.notes = value.identifiers.notes.split('\\\\r\\\\n').join('\\n').split('\\\\n').join('\\n');\n }\n\n if (value.type === 'CreditCard') {\n cipher.card = new CardView();\n cipher.type = CipherType.Card;\n }\n\n for (const property in value.identifiers) {\n if (!value.identifiers.hasOwnProperty(property)) {\n continue;\n }\n const valObj = value.identifiers[property];\n const val = valObj != null ? valObj.toString() : null;\n if (this.isNullOrWhitespace(val) || property === 'notes' || property === 'ignoreItemInSecurityScore') {\n continue;\n }\n\n if (property === 'custom_fields') {\n valObj.forEach((cf: any) => {\n this.processKvp(cipher, cf.name, cf.value);\n });\n continue;\n }\n\n if (cipher.type === CipherType.Card) {\n if (property === 'cardNumber') {\n cipher.card.number = val;\n cipher.card.brand = this.getCardBrand(val);\n continue;\n } else if (property === 'nameOnCard') {\n cipher.card.cardholderName = val;\n continue;\n } else if (property === 'security_code') {\n cipher.card.code = val;\n continue;\n } else if (property === 'expires') {\n try {\n const expDate = new Date(val);\n cipher.card.expYear = expDate.getFullYear().toString();\n cipher.card.expMonth = (expDate.getMonth() + 1).toString();\n } catch {\n // Ignore error\n }\n continue;\n } else if (property === 'cardType') {\n continue;\n }\n } else {\n if ((property === 'username' || property === 'email') &&\n this.isNullOrWhitespace(cipher.login.username)) {\n cipher.login.username = val;\n continue;\n } else if (property === 'password') {\n cipher.login.password = val;\n continue;\n } else if (property === 'totp') {\n cipher.login.totp = val;\n continue;\n } else if ((cipher.login.uris == null || cipher.login.uris.length === 0) &&\n this.uriFieldNames.indexOf(property) > -1) {\n cipher.login.uris = this.makeUriArray(val);\n continue;\n }\n }\n\n this.processKvp(cipher, property, val);\n }\n\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class PasswordDragonXmlImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const doc = this.parseXml(data);\n if (doc == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n const records = doc.querySelectorAll('PasswordManager > record');\n Array.from(records).forEach(record => {\n const category = this.querySelectorDirectChild(record, 'Category');\n const categoryText = category != null && !this.isNullOrWhitespace(category.textContent) &&\n category.textContent !== 'Unfiled' ? category.textContent : null;\n this.processFolder(result, categoryText);\n\n const accountName = this.querySelectorDirectChild(record, 'Account-Name');\n const userId = this.querySelectorDirectChild(record, 'User-Id');\n const password = this.querySelectorDirectChild(record, 'Password');\n const url = this.querySelectorDirectChild(record, 'URL');\n const notes = this.querySelectorDirectChild(record, 'Notes');\n const cipher = this.initLoginCipher();\n cipher.name = accountName != null ? this.getValueOrDefault(accountName.textContent, '--') : '--';\n cipher.notes = notes != null ? this.getValueOrDefault(notes.textContent) : '';\n cipher.login.username = userId != null ? this.getValueOrDefault(userId.textContent) : null;\n cipher.login.password = password != null ? this.getValueOrDefault(password.textContent) : null;\n cipher.login.uris = url != null ? this.makeUriArray(url.textContent) : null;\n\n const attributes: string[] = [];\n for (let i = 1; i <= 10; i++) {\n attributes.push('Attribute-' + i);\n }\n\n this.querySelectorAllDirectChild(record, attributes.join(',')).forEach(attr => {\n if (this.isNullOrWhitespace(attr.textContent) || attr.textContent === 'null') {\n return;\n }\n this.processKvp(cipher, attr.tagName, attr.textContent);\n });\n\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class PasswordSafeXmlImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const doc = this.parseXml(data);\n if (doc == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n const passwordSafe = doc.querySelector('passwordsafe');\n if (passwordSafe == null) {\n result.errorMessage = 'Missing `passwordsafe` node.';\n result.success = false;\n return Promise.resolve(result);\n }\n\n const notesDelimiter = passwordSafe.getAttribute('delimiter');\n const entries = doc.querySelectorAll('passwordsafe > entry');\n Array.from(entries).forEach(entry => {\n const group = this.querySelectorDirectChild(entry, 'group');\n const groupText = group != null && !this.isNullOrWhitespace(group.textContent) ?\n group.textContent.split('.').join('/') : null;\n this.processFolder(result, groupText);\n\n const title = this.querySelectorDirectChild(entry, 'title');\n const username = this.querySelectorDirectChild(entry, 'username');\n const email = this.querySelectorDirectChild(entry, 'email');\n const password = this.querySelectorDirectChild(entry, 'password');\n const url = this.querySelectorDirectChild(entry, 'url');\n const notes = this.querySelectorDirectChild(entry, 'notes');\n const cipher = this.initLoginCipher();\n cipher.name = title != null ? this.getValueOrDefault(title.textContent, '--') : '--';\n cipher.notes = notes != null ?\n this.getValueOrDefault(notes.textContent, '').split(notesDelimiter).join('\\n') : null;\n cipher.login.username = username != null ? this.getValueOrDefault(username.textContent) : null;\n cipher.login.password = password != null ? this.getValueOrDefault(password.textContent) : null;\n cipher.login.uris = url != null ? this.makeUriArray(url.textContent) : null;\n\n if (this.isNullOrWhitespace(cipher.login.username) && email != null) {\n cipher.login.username = this.getValueOrDefault(email.textContent);\n } else if (email != null && !this.isNullOrWhitespace(email.textContent)) {\n cipher.notes = this.isNullOrWhitespace(cipher.notes) ? 'Email: ' + email.textContent\n : (cipher.notes + '\\n' + 'Email: ' + email.textContent);\n }\n\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class PasswordWalletTxtImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, false);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (value.length < 1) {\n return;\n }\n if (value.length > 5) {\n this.processFolder(result, value[5]);\n }\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value[0], '--');\n if (value.length > 4) {\n cipher.notes = this.getValueOrDefault(value[4], '').split('¬').join('\\n');\n }\n if (value.length > 2) {\n cipher.login.username = this.getValueOrDefault(value[2]);\n }\n if (value.length > 3) {\n cipher.login.password = this.getValueOrDefault(value[3]);\n }\n if (value.length > 1) {\n cipher.login.uris = this.makeUriArray(value[1]);\n }\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { CipherType } from '../enums/cipherType';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CardView } from '../models/view/cardView';\n\nexport class RememBearCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (value.trash === 'true') {\n return;\n }\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.name);\n cipher.notes = this.getValueOrDefault(value.notes);\n if (value.type === 'LoginItem') {\n cipher.login.uris = this.makeUriArray(value.website);\n cipher.login.password = this.getValueOrDefault(value.password);\n cipher.login.username = this.getValueOrDefault(value.username);\n } else if (value.type === 'CreditCardItem') {\n cipher.type = CipherType.Card;\n cipher.card = new CardView();\n cipher.card.cardholderName = this.getValueOrDefault(value.cardholder);\n cipher.card.number = this.getValueOrDefault(value.number);\n cipher.card.brand = this.getCardBrand(cipher.card.number);\n cipher.card.code = this.getValueOrDefault(value.verification);\n\n try {\n const expMonth = this.getValueOrDefault(value.expiryMonth);\n if (expMonth != null) {\n const expMonthNumber = parseInt(expMonth, null);\n if (expMonthNumber != null && expMonthNumber >= 1 && expMonthNumber <= 12) {\n cipher.card.expMonth = expMonthNumber.toString();\n }\n }\n } catch {\n // Ignore error\n }\n try {\n const expYear = this.getValueOrDefault(value.expiryYear);\n if (expYear != null) {\n const expYearNumber = parseInt(expYear, null);\n if (expYearNumber != null) {\n cipher.card.expYear = expYearNumber.toString();\n }\n }\n } catch {\n // Ignore error\n }\n\n const pin = this.getValueOrDefault(value.pin);\n if (pin != null) {\n this.processKvp(cipher, 'PIN', pin);\n }\n const zip = this.getValueOrDefault(value.zipCode);\n if (zip != null) {\n this.processKvp(cipher, 'Zip Code', zip);\n }\n }\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class RoboFormCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n let i = 1;\n results.forEach(value => {\n const folder = !this.isNullOrWhitespace(value.Folder) && value.Folder.startsWith('/') ?\n value.Folder.replace('/', '') : value.Folder;\n const folderName = !this.isNullOrWhitespace(folder) ? folder : null;\n this.processFolder(result, folderName);\n\n const cipher = this.initLoginCipher();\n cipher.notes = this.getValueOrDefault(value.Note);\n cipher.name = this.getValueOrDefault(value.Name, '--');\n cipher.login.username = this.getValueOrDefault(value.Login);\n cipher.login.password = this.getValueOrDefault(value.Pwd);\n cipher.login.uris = this.makeUriArray(value.Url);\n\n if (!this.isNullOrWhitespace(value.Rf_fields)) {\n let fields: string[] = [value.Rf_fields];\n if (value.__parsed_extra != null && value.__parsed_extra.length > 0) {\n fields = fields.concat(value.__parsed_extra);\n }\n fields.forEach((field: string) => {\n const parts = field.split(':');\n if (parts.length < 3) {\n return;\n }\n const key = parts[0] === '-no-name-' ? null : parts[0];\n const val = parts.length === 4 && parts[2] === 'rck' ? parts[1] : parts[2];\n this.processKvp(cipher, key, val);\n });\n }\n\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n\n if (i === results.length && cipher.name === '--' && this.isNullOrWhitespace(cipher.login.password)) {\n return;\n }\n\n result.ciphers.push(cipher);\n i++;\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class SafariCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.Title, '--');\n cipher.login.username = this.getValueOrDefault(value.Username);\n cipher.login.password = this.getValueOrDefault(value.Password);\n cipher.login.uris = this.makeUriArray(value.Url);\n cipher.login.totp = this.getValueOrDefault(value.OTPAuth);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { FolderView } from '../models/view/folderView';\nimport { SecureNoteView } from '../models/view/secureNoteView';\n\nimport { CipherType } from '../enums/cipherType';\nimport { SecureNoteType } from '../enums/secureNoteType';\n\nimport { FieldType } from '../enums/fieldType';\nimport { CipherView } from '../models/view/cipherView';\nimport { FieldView } from '../models/view/fieldView';\n\nexport class SafeInCloudXmlImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const doc = this.parseXml(data);\n if (doc == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n const db = doc.querySelector('database');\n if (db == null) {\n result.errorMessage = 'Missing `database` node.';\n result.success = false;\n return Promise.resolve(result);\n }\n\n const foldersMap = new Map();\n\n Array.from(doc.querySelectorAll('database > label')).forEach(labelEl => {\n const name = labelEl.getAttribute('name');\n const id = labelEl.getAttribute('id');\n if (!this.isNullOrWhitespace(name) && !this.isNullOrWhitespace(id)) {\n foldersMap.set(id, result.folders.length);\n const folder = new FolderView();\n folder.name = name;\n result.folders.push(folder);\n }\n });\n\n Array.from(doc.querySelectorAll('database > card')).forEach(cardEl => {\n if (cardEl.getAttribute('template') === 'true' || cardEl.getAttribute('deleted') === 'true') {\n return;\n }\n\n const labelIdEl = this.querySelectorDirectChild(cardEl, 'label_id');\n if (labelIdEl != null) {\n const labelId = labelIdEl.textContent;\n if (!this.isNullOrWhitespace(labelId) && foldersMap.has(labelId)) {\n result.folderRelationships.push([result.ciphers.length, foldersMap.get(labelId)]);\n }\n }\n\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(cardEl.getAttribute('title'), '--');\n\n if (cardEl.getAttribute('star') === 'true') {\n cipher.favorite = true;\n }\n\n const cardType = cardEl.getAttribute('type');\n if (cardType === 'note') {\n cipher.type = CipherType.SecureNote;\n cipher.secureNote = new SecureNoteView();\n cipher.secureNote.type = SecureNoteType.Generic;\n } else {\n Array.from(this.querySelectorAllDirectChild(cardEl, 'field')).forEach(fieldEl => {\n const text = fieldEl.textContent;\n if (this.isNullOrWhitespace(text)) {\n return;\n }\n const name = fieldEl.getAttribute('name');\n const fieldType = this.getValueOrDefault(fieldEl.getAttribute('type'), '').toLowerCase();\n if (fieldType === 'login') {\n cipher.login.username = text;\n } else if (fieldType === 'password' || fieldType === 'secret') {\n // safeInCloud allows for more than one password. we just insert them here and find the one used as password later\n this.processKvp(cipher, name, text, FieldType.Hidden);\n } else if (fieldType === 'one_time_password') {\n cipher.login.totp = text;\n } else if (fieldType === 'notes') {\n cipher.notes += (text + '\\n');\n } else if (fieldType === 'weblogin' || fieldType === 'website') {\n cipher.login.uris = this.makeUriArray(text);\n }\n else {\n this.processKvp(cipher, name, text);\n }\n });\n }\n\n Array.from(this.querySelectorAllDirectChild(cardEl, 'notes')).forEach(notesEl => {\n cipher.notes += (notesEl.textContent + '\\n');\n });\n\n this.setPassword(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n\n // Choose a password from all passwords. Take one that has password in its name, or the first one if there is no such entry\n // if its name is password, we can safely remove it form the fields. otherwise, it would maybe be best to keep it as a hidden field\n setPassword(cipher: CipherView) {\n const candidates = cipher.fields.filter(field => field.type === FieldType.Hidden);\n if (!candidates.length) {\n return;\n }\n\n let choice: FieldView;\n for (const field of candidates) {\n if (this.passwordFieldNames.includes(field.name.toLowerCase())) {\n choice = field;\n cipher.fields = cipher.fields.filter(f => f !== choice);\n break;\n }\n }\n\n if (!choice) {\n choice = candidates[0];\n }\n\n cipher.login.password = choice.value;\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class SaferPassCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(this.nameFromUrl(value.url), '--');\n cipher.notes = this.getValueOrDefault(value.notes);\n cipher.login.username = this.getValueOrDefault(value.username);\n cipher.login.password = this.getValueOrDefault(value.password);\n cipher.login.uris = this.makeUriArray(value.url);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class SecureSafeCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.Title);\n cipher.notes = this.getValueOrDefault(value.Comment);\n cipher.login.uris = this.makeUriArray(value.Url);\n cipher.login.password = this.getValueOrDefault(value.Password);\n cipher.login.username = this.getValueOrDefault(value.Username);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\nimport { CipherView } from '../models/view/cipherView';\n\nexport class SplashIdCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, false);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (value.length < 3) {\n return;\n }\n\n this.processFolder(result, this.getValueOrDefault(value[value.length - 1]));\n const cipher = this.initLoginCipher();\n cipher.notes = this.getValueOrDefault(value[value.length - 2], '');\n cipher.name = this.getValueOrDefault(value[1], '--');\n\n if (value[0] === 'Web Logins' || value[0] === 'Servers' || value[0] === 'Email Accounts') {\n cipher.login.username = this.getValueOrDefault(value[2]);\n cipher.login.password = this.getValueOrDefault(value[3]);\n cipher.login.uris = this.makeUriArray(value[4]);\n this.parseFieldsToNotes(cipher, 5, value);\n } else {\n this.parseFieldsToNotes(cipher, 2, value);\n }\n\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n\n private parseFieldsToNotes(cipher: CipherView, startIndex: number, value: any) {\n // last 3 rows do not get parsed\n for (let i = startIndex; i < value.length - 3; i++) {\n if (this.isNullOrWhitespace(value[i])) {\n continue;\n }\n cipher.notes += (value[i] + '\\n');\n }\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class StickyPasswordXmlImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const doc = this.parseXml(data);\n if (doc == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n const loginNodes = doc.querySelectorAll('root > Database > Logins > Login');\n Array.from(loginNodes).forEach(loginNode => {\n const accountId = loginNode.getAttribute('ID');\n if (this.isNullOrWhitespace(accountId)) {\n return;\n }\n\n const usernameText = loginNode.getAttribute('Name');\n const passwordText = loginNode.getAttribute('Password');\n let titleText: string = null;\n let linkText: string = null;\n let notesText: string = null;\n let groupId: string = null;\n let groupText: string = null;\n\n const accountLogin = doc.querySelector('root > Database > Accounts > Account > ' +\n 'LoginLinks > Login[SourceLoginID=\"' + accountId + '\"]');\n if (accountLogin != null) {\n const account = accountLogin.parentElement.parentElement;\n if (account != null) {\n titleText = account.getAttribute('Name');\n linkText = account.getAttribute('Link');\n groupId = account.getAttribute('ParentID');\n notesText = account.getAttribute('Comments');\n if (!this.isNullOrWhitespace(notesText)) {\n notesText = notesText.split('/n').join('\\n');\n }\n }\n }\n\n if (!this.isNullOrWhitespace(groupId)) {\n groupText = this.buildGroupText(doc, groupId, '');\n this.processFolder(result, groupText);\n }\n\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(titleText, '--');\n cipher.notes = this.getValueOrDefault(notesText);\n cipher.login.username = this.getValueOrDefault(usernameText);\n cipher.login.password = this.getValueOrDefault(passwordText);\n cipher.login.uris = this.makeUriArray(linkText);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n\n buildGroupText(doc: Document, groupId: string, groupText: string): string {\n const group = doc.querySelector('root > Database > Groups > Group[ID=\"' + groupId + '\"]');\n if (group == null) {\n return groupText;\n }\n if (!this.isNullOrWhitespace(groupText)) {\n groupText = '/' + groupText;\n }\n groupText = group.getAttribute('Name') + groupText;\n return this.buildGroupText(doc, group.getAttribute('ParentID'), groupText);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nimport { CardView } from '../models/view/cardView';\nimport { SecureNoteView } from '../models/view/secureNoteView';\n\nimport { CipherType } from '../enums/cipherType';\nimport { SecureNoteType } from '../enums/secureNoteType';\n\nconst PropertiesToIgnore = ['kind', 'autologin', 'favorite', 'hexcolor', 'protectedwithpassword', 'subdomainonly',\n 'type', 'tk_export_version', 'note', 'title', 'document_content',\n];\n\nexport class TrueKeyCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n const cipher = this.initLoginCipher();\n cipher.favorite = this.getValueOrDefault(value.favorite, '').toLowerCase() === 'true';\n cipher.name = this.getValueOrDefault(value.name, '--');\n cipher.notes = this.getValueOrDefault(value.memo, '');\n cipher.login.username = this.getValueOrDefault(value.login);\n cipher.login.password = this.getValueOrDefault(value.password);\n cipher.login.uris = this.makeUriArray(value.url);\n\n if (value.kind !== 'login') {\n cipher.name = this.getValueOrDefault(value.title, '--');\n cipher.notes = this.getValueOrDefault(value.note, '');\n }\n\n if (value.kind === 'cc') {\n cipher.type = CipherType.Card;\n cipher.card = new CardView();\n cipher.card.cardholderName = this.getValueOrDefault(value.cardholder);\n cipher.card.number = this.getValueOrDefault(value.number);\n cipher.card.brand = this.getCardBrand(cipher.card.number);\n if (!this.isNullOrWhitespace(value.expiryDate)) {\n try {\n const expDate = new Date(value.expiryDate);\n cipher.card.expYear = expDate.getFullYear().toString();\n cipher.card.expMonth = (expDate.getMonth() + 1).toString();\n } catch {\n // Ignore error\n }\n }\n } else if (value.kind !== 'login') {\n cipher.type = CipherType.SecureNote;\n cipher.secureNote = new SecureNoteView();\n cipher.secureNote.type = SecureNoteType.Generic;\n if (!this.isNullOrWhitespace(cipher.notes)) {\n cipher.notes = this.getValueOrDefault(value.document_content, '');\n }\n for (const property in value) {\n if (value.hasOwnProperty(property) && PropertiesToIgnore.indexOf(property.toLowerCase()) < 0 &&\n !this.isNullOrWhitespace(value[property])) {\n this.processKvp(cipher, property, value[property]);\n }\n }\n }\n\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class UpmCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, false);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (value.length !== 5) {\n return;\n }\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value[0], '--');\n cipher.notes = this.getValueOrDefault(value[4]);\n cipher.login.username = this.getValueOrDefault(value[1]);\n cipher.login.password = this.getValueOrDefault(value[2]);\n cipher.login.uris = this.makeUriArray(value[3]);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\n\nexport class YotiCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n const cipher = this.initLoginCipher();\n cipher.name = this.getValueOrDefault(value.Name, '--');\n cipher.login.username = this.getValueOrDefault(value['User name']);\n cipher.login.password = this.getValueOrDefault(value.Password);\n cipher.login.uris = this.makeUriArray(value.URL);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n result.success = true;\n return Promise.resolve(result);\n }\n}\n","import { BaseImporter } from './baseImporter';\nimport { Importer } from './importer';\n\nimport { ImportResult } from '../models/domain/importResult';\nimport { CipherView } from '../models/view/cipherView';\n\nexport class ZohoVaultCsvImporter extends BaseImporter implements Importer {\n parse(data: string): Promise {\n const result = new ImportResult();\n const results = this.parseCsv(data, true);\n if (results == null) {\n result.success = false;\n return Promise.resolve(result);\n }\n\n results.forEach(value => {\n if (this.isNullOrWhitespace(value['Password Name']) && this.isNullOrWhitespace(value['Secret Name'])) {\n return;\n }\n this.processFolder(result, this.getValueOrDefault(value.ChamberName));\n const cipher = this.initLoginCipher();\n cipher.favorite = this.getValueOrDefault(value.Favorite, '0') === '1';\n cipher.notes = this.getValueOrDefault(value.Notes);\n cipher.name = this.getValueOrDefault(\n value['Password Name'], this.getValueOrDefault(value['Secret Name'], '--'));\n cipher.login.uris = this.makeUriArray(\n this.getValueOrDefault(value['Password URL'], this.getValueOrDefault(value['Secret URL'])));\n this.parseData(cipher, value.SecretData);\n this.parseData(cipher, value.CustomData);\n this.convertToNoteIfNeeded(cipher);\n this.cleanupCipher(cipher);\n result.ciphers.push(cipher);\n });\n\n if (this.organization) {\n this.moveFoldersToCollections(result);\n }\n\n result.success = true;\n return Promise.resolve(result);\n }\n\n private parseData(cipher: CipherView, data: string) {\n if (this.isNullOrWhitespace(data)) {\n return;\n }\n const dataLines = this.splitNewLine(data);\n dataLines.forEach(line => {\n const delimPosition = line.indexOf(':');\n if (delimPosition < 0) {\n return;\n }\n const field = line.substring(0, delimPosition);\n const value = line.length > delimPosition ? line.substring(delimPosition + 1) : null;\n if (this.isNullOrWhitespace(field) || this.isNullOrWhitespace(value) || field === 'SecretType') {\n return;\n }\n const fieldLower = field.toLowerCase();\n if (cipher.login.username == null && this.usernameFieldNames.indexOf(fieldLower) > -1) {\n cipher.login.username = value;\n } else if (cipher.login.password == null && this.passwordFieldNames.indexOf(fieldLower) > -1) {\n cipher.login.password = value;\n } else {\n this.processKvp(cipher, field, value);\n }\n });\n }\n}\n","import { ApiService } from '../abstractions/api.service';\nimport { CryptoService } from '../abstractions/crypto.service';\nimport { KeyConnectorService as KeyConnectorServiceAbstraction } from '../abstractions/keyConnector.service';\nimport { LogService } from '../abstractions/log.service';\nimport { StorageService } from '../abstractions/storage.service';\nimport { TokenService } from '../abstractions/token.service';\nimport { UserService } from '../abstractions/user.service';\n\nimport { OrganizationUserType } from '../enums/organizationUserType';\n\nimport { Utils } from '../misc/utils';\n\nimport { SymmetricCryptoKey } from '../models/domain/symmetricCryptoKey';\n\nimport { KeyConnectorUserKeyRequest } from '../models/request/keyConnectorUserKeyRequest';\n\nconst Keys = {\n usesKeyConnector: 'usesKeyConnector',\n convertAccountToKeyConnector: 'convertAccountToKeyConnector',\n};\n\nexport class KeyConnectorService implements KeyConnectorServiceAbstraction {\n private usesKeyConnector?: boolean = null;\n\n constructor(private storageService: StorageService, private userService: UserService,\n private cryptoService: CryptoService, private apiService: ApiService,\n private tokenService: TokenService, private logService: LogService) { }\n\n setUsesKeyConnector(usesKeyConnector: boolean) {\n this.usesKeyConnector = usesKeyConnector;\n return this.storageService.save(Keys.usesKeyConnector, usesKeyConnector);\n }\n\n async getUsesKeyConnector(): Promise {\n return this.usesKeyConnector ??= await this.storageService.get(Keys.usesKeyConnector);\n }\n\n async userNeedsMigration() {\n const loggedInUsingSso = this.tokenService.getIsExternal();\n const requiredByOrganization = await this.getManagingOrganization() != null;\n const userIsNotUsingKeyConnector = !await this.getUsesKeyConnector();\n\n return loggedInUsingSso && requiredByOrganization && userIsNotUsingKeyConnector;\n }\n\n async migrateUser() {\n const organization = await this.getManagingOrganization();\n const key = await this.cryptoService.getKey();\n\n try {\n const keyConnectorRequest = new KeyConnectorUserKeyRequest(key.encKeyB64);\n await this.apiService.postUserKeyToKeyConnector(organization.keyConnectorUrl, keyConnectorRequest);\n } catch (e) {\n throw new Error('Unable to reach key connector');\n }\n\n await this.apiService.postConvertToKeyConnector();\n }\n\n async getAndSetKey(url: string) {\n try {\n const userKeyResponse = await this.apiService.getUserKeyFromKeyConnector(url);\n const keyArr = Utils.fromB64ToArray(userKeyResponse.key);\n const k = new SymmetricCryptoKey(keyArr);\n await this.cryptoService.setKey(k);\n } catch (e) {\n this.logService.error(e);\n throw new Error('Unable to reach key connector');\n }\n }\n\n async getManagingOrganization() {\n const orgs = await this.userService.getAllOrganizations();\n return orgs.find(o =>\n o.keyConnectorEnabled &&\n o.type !== OrganizationUserType.Admin &&\n o.type !== OrganizationUserType.Owner &&\n !o.isProviderUser);\n }\n\n async setConvertAccountRequired(status: boolean) {\n await this.storageService.save(Keys.convertAccountToKeyConnector, status);\n }\n\n async getConvertAccountRequired(): Promise {\n return await this.storageService.get(Keys.convertAccountToKeyConnector);\n }\n\n async removeConvertAccountRequired() {\n await this.storageService.remove(Keys.convertAccountToKeyConnector);\n }\n\n async clear() {\n await this.removeConvertAccountRequired();\n }\n}\n","import * as signalR from '@microsoft/signalr';\nimport * as signalRMsgPack from '@microsoft/signalr-protocol-msgpack';\n\nimport { NotificationType } from '../enums/notificationType';\n\nimport { ApiService } from '../abstractions/api.service';\nimport { AppIdService } from '../abstractions/appId.service';\nimport { EnvironmentService } from '../abstractions/environment.service';\nimport { LogService } from '../abstractions/log.service';\nimport { NotificationsService as NotificationsServiceAbstraction } from '../abstractions/notifications.service';\nimport { SyncService } from '../abstractions/sync.service';\nimport { UserService } from '../abstractions/user.service';\nimport { VaultTimeoutService } from '../abstractions/vaultTimeout.service';\n\nimport {\n NotificationResponse,\n SyncCipherNotification,\n SyncFolderNotification,\n SyncSendNotification,\n} from '../models/response/notificationResponse';\n\nexport class NotificationsService implements NotificationsServiceAbstraction {\n private signalrConnection: signalR.HubConnection;\n private url: string;\n private connected = false;\n private inited = false;\n private inactive = false;\n private reconnectTimer: any = null;\n\n constructor(private userService: UserService, private syncService: SyncService,\n private appIdService: AppIdService, private apiService: ApiService,\n private vaultTimeoutService: VaultTimeoutService, private environmentService: EnvironmentService,\n private logoutCallback: () => Promise, private logService: LogService) {\n this.environmentService.urls.subscribe(() => {\n if (!this.inited) {\n return;\n }\n\n this.init();\n });\n }\n\n async init(): Promise {\n this.inited = false;\n this.url = this.environmentService.getNotificationsUrl();\n\n // Set notifications server URL to `https://-` to effectively disable communication\n // with the notifications server from the client app\n if (this.url === 'https://-') {\n return;\n }\n\n if (this.signalrConnection != null) {\n this.signalrConnection.off('ReceiveMessage');\n this.signalrConnection.off('Heartbeat');\n await this.signalrConnection.stop();\n this.connected = false;\n this.signalrConnection = null;\n }\n\n this.signalrConnection = new signalR.HubConnectionBuilder()\n .withUrl(this.url + '/hub', {\n accessTokenFactory: () => this.apiService.getActiveBearerToken(),\n skipNegotiation: true,\n transport: signalR.HttpTransportType.WebSockets,\n })\n .withHubProtocol(new signalRMsgPack.MessagePackHubProtocol() as signalR.IHubProtocol)\n // .configureLogging(signalR.LogLevel.Trace)\n .build();\n\n this.signalrConnection.on('ReceiveMessage',\n (data: any) => this.processNotification(new NotificationResponse(data)));\n this.signalrConnection.on('Heartbeat',\n (data: any) => { /*console.log('Heartbeat!');*/ });\n this.signalrConnection.onclose(() => {\n this.connected = false;\n this.reconnect(true);\n });\n this.inited = true;\n if (await this.isAuthedAndUnlocked()) {\n await this.reconnect(false);\n }\n }\n\n async updateConnection(sync = false): Promise {\n if (!this.inited) {\n return;\n }\n try {\n if (await this.isAuthedAndUnlocked()) {\n await this.reconnect(sync);\n } else {\n await this.signalrConnection.stop();\n }\n } catch (e) {\n this.logService.error(e.toString());\n }\n }\n\n async reconnectFromActivity(): Promise {\n this.inactive = false;\n if (this.inited && !this.connected) {\n await this.reconnect(true);\n }\n }\n\n async disconnectFromInactivity(): Promise {\n this.inactive = true;\n if (this.inited && this.connected) {\n await this.signalrConnection.stop();\n }\n }\n\n private async processNotification(notification: NotificationResponse) {\n const appId = await this.appIdService.getAppId();\n if (notification == null || notification.contextId === appId) {\n return;\n }\n\n const isAuthenticated = await this.userService.isAuthenticated();\n const payloadUserId = notification.payload.userId || notification.payload.UserId;\n const myUserId = await this.userService.getUserId();\n if (isAuthenticated && payloadUserId != null && payloadUserId !== myUserId) {\n return;\n }\n\n switch (notification.type) {\n case NotificationType.SyncCipherCreate:\n case NotificationType.SyncCipherUpdate:\n await this.syncService.syncUpsertCipher(notification.payload as SyncCipherNotification,\n notification.type === NotificationType.SyncCipherUpdate);\n break;\n case NotificationType.SyncCipherDelete:\n case NotificationType.SyncLoginDelete:\n await this.syncService.syncDeleteCipher(notification.payload as SyncCipherNotification);\n break;\n case NotificationType.SyncFolderCreate:\n case NotificationType.SyncFolderUpdate:\n await this.syncService.syncUpsertFolder(notification.payload as SyncFolderNotification,\n notification.type === NotificationType.SyncFolderUpdate);\n break;\n case NotificationType.SyncFolderDelete:\n await this.syncService.syncDeleteFolder(notification.payload as SyncFolderNotification);\n break;\n case NotificationType.SyncVault:\n case NotificationType.SyncCiphers:\n case NotificationType.SyncSettings:\n if (isAuthenticated) {\n await this.syncService.fullSync(false);\n }\n break;\n case NotificationType.SyncOrgKeys:\n if (isAuthenticated) {\n await this.syncService.fullSync(true);\n // Stop so a reconnect can be made\n await this.signalrConnection.stop();\n }\n break;\n case NotificationType.LogOut:\n if (isAuthenticated) {\n this.logoutCallback();\n }\n break;\n case NotificationType.SyncSendCreate:\n case NotificationType.SyncSendUpdate:\n await this.syncService.syncUpsertSend(notification.payload as SyncSendNotification,\n notification.type === NotificationType.SyncSendUpdate);\n break;\n case NotificationType.SyncSendDelete:\n await this.syncService.syncDeleteSend(notification.payload as SyncSendNotification);\n default:\n break;\n }\n }\n\n private async reconnect(sync: boolean) {\n if (this.reconnectTimer != null) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.connected || !this.inited || this.inactive) {\n return;\n }\n const authedAndUnlocked = await this.isAuthedAndUnlocked();\n if (!authedAndUnlocked) {\n return;\n }\n\n try {\n await this.signalrConnection.start();\n this.connected = true;\n if (sync) {\n await this.syncService.fullSync(false);\n }\n } catch (e) {\n this.logService.error(e);\n }\n\n if (!this.connected) {\n this.reconnectTimer = setTimeout(() => this.reconnect(sync), this.random(120000, 300000));\n }\n }\n\n private async isAuthedAndUnlocked() {\n if (await this.userService.isAuthenticated()) {\n const locked = await this.vaultTimeoutService.isLocked();\n return !locked;\n }\n return false;\n }\n\n private random(min: number, max: number) {\n min = Math.ceil(min);\n max = Math.floor(max);\n return Math.floor(Math.random() * (max - min + 1)) + min;\n }\n}\n","import { BaseResponse } from './baseResponse';\n\nimport { NotificationType } from '../../enums/notificationType';\n\nexport class NotificationResponse extends BaseResponse {\n contextId: string;\n type: NotificationType;\n payload: any;\n\n constructor(response: any) {\n super(response);\n this.contextId = this.getResponseProperty('ContextId');\n this.type = this.getResponseProperty('Type');\n\n const payload = this.getResponseProperty('Payload');\n switch (this.type) {\n case NotificationType.SyncCipherCreate:\n case NotificationType.SyncCipherDelete:\n case NotificationType.SyncCipherUpdate:\n case NotificationType.SyncLoginDelete:\n this.payload = new SyncCipherNotification(payload);\n break;\n case NotificationType.SyncFolderCreate:\n case NotificationType.SyncFolderDelete:\n case NotificationType.SyncFolderUpdate:\n this.payload = new SyncFolderNotification(payload);\n break;\n case NotificationType.SyncVault:\n case NotificationType.SyncCiphers:\n case NotificationType.SyncOrgKeys:\n case NotificationType.SyncSettings:\n case NotificationType.LogOut:\n this.payload = new UserNotification(payload);\n break;\n case NotificationType.SyncSendCreate:\n case NotificationType.SyncSendUpdate:\n case NotificationType.SyncSendDelete:\n this.payload = new SyncSendNotification(payload);\n default:\n break;\n }\n }\n}\n\nexport class SyncCipherNotification extends BaseResponse {\n id: string;\n userId: string;\n organizationId: string;\n collectionIds: string[];\n revisionDate: Date;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.userId = this.getResponseProperty('UserId');\n this.organizationId = this.getResponseProperty('OrganizationId');\n this.collectionIds = this.getResponseProperty('CollectionIds');\n this.revisionDate = new Date(this.getResponseProperty('RevisionDate'));\n }\n}\n\nexport class SyncFolderNotification extends BaseResponse {\n id: string;\n userId: string;\n revisionDate: Date;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.userId = this.getResponseProperty('UserId');\n this.revisionDate = new Date(this.getResponseProperty('RevisionDate'));\n }\n}\n\nexport class UserNotification extends BaseResponse {\n userId: string;\n date: Date;\n\n constructor(response: any) {\n super(response);\n this.userId = this.getResponseProperty('UserId');\n this.date = new Date(this.getResponseProperty('Date'));\n }\n}\n\nexport class SyncSendNotification extends BaseResponse {\n id: string;\n userId: string;\n revisionDate: Date;\n\n constructor(response: any) {\n super(response);\n this.id = this.getResponseProperty('Id');\n this.userId = this.getResponseProperty('UserId');\n this.revisionDate = new Date(this.getResponseProperty('RevisionDate'));\n }\n}\n","import * as zxcvbn from 'zxcvbn';\n\nimport { EncString } from '../models/domain/encString';\nimport { GeneratedPasswordHistory } from '../models/domain/generatedPasswordHistory';\nimport { PasswordGeneratorPolicyOptions } from '../models/domain/passwordGeneratorPolicyOptions';\nimport { Policy } from '../models/domain/policy';\n\nimport { CryptoService } from '../abstractions/crypto.service';\nimport {\n PasswordGenerationService as PasswordGenerationServiceAbstraction,\n} from '../abstractions/passwordGeneration.service';\nimport { PolicyService } from '../abstractions/policy.service';\nimport { StorageService } from '../abstractions/storage.service';\n\nimport { EEFLongWordList } from '../misc/wordlist';\n\nimport { PolicyType } from '../enums/policyType';\n\nconst DefaultOptions = {\n length: 14,\n ambiguous: false,\n number: true,\n minNumber: 1,\n uppercase: true,\n minUppercase: 0,\n lowercase: true,\n minLowercase: 0,\n special: false,\n minSpecial: 1,\n type: 'password',\n numWords: 3,\n wordSeparator: '-',\n capitalize: false,\n includeNumber: false,\n};\n\nconst Keys = {\n options: 'passwordGenerationOptions',\n history: 'generatedPasswordHistory',\n};\n\nconst MaxPasswordsInHistory = 100;\n\nexport class PasswordGenerationService implements PasswordGenerationServiceAbstraction {\n private optionsCache: any;\n private history: GeneratedPasswordHistory[];\n\n constructor(private cryptoService: CryptoService, private storageService: StorageService,\n private policyService: PolicyService) { }\n\n async generatePassword(options: any): Promise {\n // overload defaults with given options\n const o = Object.assign({}, DefaultOptions, options);\n\n if (o.type === 'passphrase') {\n return this.generatePassphrase(options);\n }\n\n // sanitize\n this.sanitizePasswordLength(o, true);\n\n const minLength: number = o.minUppercase + o.minLowercase + o.minNumber + o.minSpecial;\n if (o.length < minLength) {\n o.length = minLength;\n }\n\n const positions: string[] = [];\n if (o.lowercase && o.minLowercase > 0) {\n for (let i = 0; i < o.minLowercase; i++) {\n positions.push('l');\n }\n }\n if (o.uppercase && o.minUppercase > 0) {\n for (let i = 0; i < o.minUppercase; i++) {\n positions.push('u');\n }\n }\n if (o.number && o.minNumber > 0) {\n for (let i = 0; i < o.minNumber; i++) {\n positions.push('n');\n }\n }\n if (o.special && o.minSpecial > 0) {\n for (let i = 0; i < o.minSpecial; i++) {\n positions.push('s');\n }\n }\n while (positions.length < o.length) {\n positions.push('a');\n }\n\n // shuffle\n await this.shuffleArray(positions);\n\n // build out the char sets\n let allCharSet = '';\n\n let lowercaseCharSet = 'abcdefghijkmnopqrstuvwxyz';\n if (o.ambiguous) {\n lowercaseCharSet += 'l';\n }\n if (o.lowercase) {\n allCharSet += lowercaseCharSet;\n }\n\n let uppercaseCharSet = 'ABCDEFGHJKLMNPQRSTUVWXYZ';\n if (o.ambiguous) {\n uppercaseCharSet += 'IO';\n }\n if (o.uppercase) {\n allCharSet += uppercaseCharSet;\n }\n\n let numberCharSet = '23456789';\n if (o.ambiguous) {\n numberCharSet += '01';\n }\n if (o.number) {\n allCharSet += numberCharSet;\n }\n\n const specialCharSet = '!@#$%^&*';\n if (o.special) {\n allCharSet += specialCharSet;\n }\n\n let password = '';\n for (let i = 0; i < o.length; i++) {\n let positionChars: string;\n switch (positions[i]) {\n case 'l':\n positionChars = lowercaseCharSet;\n break;\n case 'u':\n positionChars = uppercaseCharSet;\n break;\n case 'n':\n positionChars = numberCharSet;\n break;\n case 's':\n positionChars = specialCharSet;\n break;\n case 'a':\n positionChars = allCharSet;\n break;\n default:\n break;\n }\n\n const randomCharIndex = await this.cryptoService.randomNumber(0, positionChars.length - 1);\n password += positionChars.charAt(randomCharIndex);\n }\n\n return password;\n }\n\n async generatePassphrase(options: any): Promise {\n const o = Object.assign({}, DefaultOptions, options);\n\n if (o.numWords == null || o.numWords <= 2) {\n o.numWords = DefaultOptions.numWords;\n }\n if (o.wordSeparator == null || o.wordSeparator.length === 0 || o.wordSeparator.length > 1) {\n o.wordSeparator = ' ';\n }\n if (o.capitalize == null) {\n o.capitalize = false;\n }\n if (o.includeNumber == null) {\n o.includeNumber = false;\n }\n\n const listLength = EEFLongWordList.length - 1;\n const wordList = new Array(o.numWords);\n for (let i = 0; i < o.numWords; i++) {\n const wordIndex = await this.cryptoService.randomNumber(0, listLength);\n if (o.capitalize) {\n wordList[i] = this.capitalize(EEFLongWordList[wordIndex]);\n } else {\n wordList[i] = EEFLongWordList[wordIndex];\n }\n }\n\n if (o.includeNumber) {\n await this.appendRandomNumberToRandomWord(wordList);\n }\n return wordList.join(o.wordSeparator);\n }\n\n async getOptions(): Promise<[any, PasswordGeneratorPolicyOptions]> {\n if (this.optionsCache == null) {\n const options = await this.storageService.get(Keys.options);\n if (options == null) {\n this.optionsCache = DefaultOptions;\n } else {\n this.optionsCache = Object.assign({}, DefaultOptions, options);\n }\n }\n const enforcedOptions = await this.enforcePasswordGeneratorPoliciesOnOptions(this.optionsCache);\n this.optionsCache = enforcedOptions[0];\n return [this.optionsCache, enforcedOptions[1]];\n }\n\n async enforcePasswordGeneratorPoliciesOnOptions(options: any): Promise<[any, PasswordGeneratorPolicyOptions]> {\n let enforcedPolicyOptions = await this.getPasswordGeneratorPolicyOptions();\n if (enforcedPolicyOptions != null) {\n if (options.length < enforcedPolicyOptions.minLength) {\n options.length = enforcedPolicyOptions.minLength;\n }\n\n if (enforcedPolicyOptions.useUppercase) {\n options.uppercase = true;\n }\n\n if (enforcedPolicyOptions.useLowercase) {\n options.lowercase = true;\n }\n\n if (enforcedPolicyOptions.useNumbers) {\n options.number = true;\n }\n\n if (options.minNumber < enforcedPolicyOptions.numberCount) {\n options.minNumber = enforcedPolicyOptions.numberCount;\n }\n\n if (enforcedPolicyOptions.useSpecial) {\n options.special = true;\n }\n\n if (options.minSpecial < enforcedPolicyOptions.specialCount) {\n options.minSpecial = enforcedPolicyOptions.specialCount;\n }\n\n // Must normalize these fields because the receiving call expects all options to pass the current rules\n if (options.minSpecial + options.minNumber > options.length) {\n options.minSpecial = options.length - options.minNumber;\n }\n\n if (options.numWords < enforcedPolicyOptions.minNumberWords) {\n options.numWords = enforcedPolicyOptions.minNumberWords;\n }\n\n if (enforcedPolicyOptions.capitalize) {\n options.capitalize = true;\n }\n\n if (enforcedPolicyOptions.includeNumber) {\n options.includeNumber = true;\n }\n\n // Force default type if password/passphrase selected via policy\n if (enforcedPolicyOptions.defaultType === 'password' ||\n enforcedPolicyOptions.defaultType === 'passphrase') {\n options.type = enforcedPolicyOptions.defaultType;\n }\n } else { // UI layer expects an instantiated object to prevent more explicit null checks\n enforcedPolicyOptions = new PasswordGeneratorPolicyOptions();\n }\n return [options, enforcedPolicyOptions];\n }\n\n async getPasswordGeneratorPolicyOptions(): Promise {\n const policies: Policy[] = this.policyService == null ? null :\n await this.policyService.getAll(PolicyType.PasswordGenerator);\n let enforcedOptions: PasswordGeneratorPolicyOptions = null;\n\n if (policies == null || policies.length === 0) {\n return enforcedOptions;\n }\n\n policies.forEach(currentPolicy => {\n if (!currentPolicy.enabled || currentPolicy.data == null) {\n return;\n }\n\n if (enforcedOptions == null) {\n enforcedOptions = new PasswordGeneratorPolicyOptions();\n }\n\n // Password wins in multi-org collisions\n if (currentPolicy.data.defaultType != null && enforcedOptions.defaultType !== 'password') {\n enforcedOptions.defaultType = currentPolicy.data.defaultType;\n }\n\n if (currentPolicy.data.minLength != null\n && currentPolicy.data.minLength > enforcedOptions.minLength) {\n enforcedOptions.minLength = currentPolicy.data.minLength;\n }\n\n if (currentPolicy.data.useUpper) {\n enforcedOptions.useUppercase = true;\n }\n\n if (currentPolicy.data.useLower) {\n enforcedOptions.useLowercase = true;\n }\n\n if (currentPolicy.data.useNumbers) {\n enforcedOptions.useNumbers = true;\n }\n\n if (currentPolicy.data.minNumbers != null\n && currentPolicy.data.minNumbers > enforcedOptions.numberCount) {\n enforcedOptions.numberCount = currentPolicy.data.minNumbers;\n }\n\n if (currentPolicy.data.useSpecial) {\n enforcedOptions.useSpecial = true;\n }\n\n if (currentPolicy.data.minSpecial != null\n && currentPolicy.data.minSpecial > enforcedOptions.specialCount) {\n enforcedOptions.specialCount = currentPolicy.data.minSpecial;\n }\n\n if (currentPolicy.data.minNumberWords != null\n && currentPolicy.data.minNumberWords > enforcedOptions.minNumberWords) {\n enforcedOptions.minNumberWords = currentPolicy.data.minNumberWords;\n }\n\n if (currentPolicy.data.capitalize) {\n enforcedOptions.capitalize = true;\n }\n\n if (currentPolicy.data.includeNumber) {\n enforcedOptions.includeNumber = true;\n }\n });\n\n return enforcedOptions;\n }\n\n async saveOptions(options: any) {\n await this.storageService.save(Keys.options, options);\n this.optionsCache = options;\n }\n\n async getHistory(): Promise {\n const hasKey = await this.cryptoService.hasKey();\n if (!hasKey) {\n return new Array();\n }\n\n if (!this.history) {\n const encrypted = await this.storageService.get(Keys.history);\n this.history = await this.decryptHistory(encrypted);\n }\n\n return this.history || new Array();\n }\n\n async addHistory(password: string): Promise {\n // Cannot add new history if no key is available\n const hasKey = await this.cryptoService.hasKey();\n if (!hasKey) {\n return;\n }\n\n const currentHistory = await this.getHistory();\n\n // Prevent duplicates\n if (this.matchesPrevious(password, currentHistory)) {\n return;\n }\n\n currentHistory.unshift(new GeneratedPasswordHistory(password, Date.now()));\n\n // Remove old items.\n if (currentHistory.length > MaxPasswordsInHistory) {\n currentHistory.pop();\n }\n\n const newHistory = await this.encryptHistory(currentHistory);\n return await this.storageService.save(Keys.history, newHistory);\n }\n\n async clear(): Promise {\n this.history = [];\n return await this.storageService.remove(Keys.history);\n }\n\n passwordStrength(password: string, userInputs: string[] = null): zxcvbn.ZXCVBNResult {\n if (password == null || password.length === 0) {\n return null;\n }\n let globalUserInputs = ['bitwarden', 'bit', 'warden'];\n if (userInputs != null && userInputs.length > 0) {\n globalUserInputs = globalUserInputs.concat(userInputs);\n }\n // Use a hash set to get rid of any duplicate user inputs\n const finalUserInputs = Array.from(new Set(globalUserInputs));\n const result = zxcvbn(password, finalUserInputs);\n return result;\n }\n\n normalizeOptions(options: any, enforcedPolicyOptions: PasswordGeneratorPolicyOptions) {\n options.minLowercase = 0;\n options.minUppercase = 0;\n\n if (!options.length || options.length < 5) {\n options.length = 5;\n } else if (options.length > 128) {\n options.length = 128;\n }\n\n if (options.length < enforcedPolicyOptions.minLength) {\n options.length = enforcedPolicyOptions.minLength;\n }\n\n if (!options.minNumber) {\n options.minNumber = 0;\n } else if (options.minNumber > options.length) {\n options.minNumber = options.length;\n } else if (options.minNumber > 9) {\n options.minNumber = 9;\n }\n\n if (options.minNumber < enforcedPolicyOptions.numberCount) {\n options.minNumber = enforcedPolicyOptions.numberCount;\n }\n\n if (!options.minSpecial) {\n options.minSpecial = 0;\n } else if (options.minSpecial > options.length) {\n options.minSpecial = options.length;\n } else if (options.minSpecial > 9) {\n options.minSpecial = 9;\n }\n\n if (options.minSpecial < enforcedPolicyOptions.specialCount) {\n options.minSpecial = enforcedPolicyOptions.specialCount;\n }\n\n if (options.minSpecial + options.minNumber > options.length) {\n options.minSpecial = options.length - options.minNumber;\n }\n\n if (options.numWords == null || options.length < 3) {\n options.numWords = 3;\n } else if (options.numWords > 20) {\n options.numWords = 20;\n }\n\n if (options.numWords < enforcedPolicyOptions.minNumberWords) {\n options.numWords = enforcedPolicyOptions.minNumberWords;\n }\n\n if (options.wordSeparator != null && options.wordSeparator.length > 1) {\n options.wordSeparator = options.wordSeparator[0];\n }\n\n this.sanitizePasswordLength(options, false);\n }\n\n private capitalize(str: string) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n }\n\n private async appendRandomNumberToRandomWord(wordList: string[]) {\n if (wordList == null || wordList.length <= 0) {\n return;\n }\n const index = await this.cryptoService.randomNumber(0, wordList.length - 1);\n const num = await this.cryptoService.randomNumber(0, 9);\n wordList[index] = wordList[index] + num;\n }\n\n private async encryptHistory(history: GeneratedPasswordHistory[]): Promise {\n if (history == null || history.length === 0) {\n return Promise.resolve([]);\n }\n\n const promises = history.map(async item => {\n const encrypted = await this.cryptoService.encrypt(item.password);\n return new GeneratedPasswordHistory(encrypted.encryptedString, item.date);\n });\n\n return await Promise.all(promises);\n }\n\n private async decryptHistory(history: GeneratedPasswordHistory[]): Promise {\n if (history == null || history.length === 0) {\n return Promise.resolve([]);\n }\n\n const promises = history.map(async item => {\n const decrypted = await this.cryptoService.decryptToUtf8(new EncString(item.password));\n return new GeneratedPasswordHistory(decrypted, item.date);\n });\n\n return await Promise.all(promises);\n }\n\n private matchesPrevious(password: string, history: GeneratedPasswordHistory[]): boolean {\n if (history == null || history.length === 0) {\n return false;\n }\n\n return history[history.length - 1].password === password;\n }\n\n // ref: https://stackoverflow.com/a/12646864/1090359\n private async shuffleArray(array: string[]) {\n for (let i = array.length - 1; i > 0; i--) {\n const j = await this.cryptoService.randomNumber(0, i);\n [array[i], array[j]] = [array[j], array[i]];\n }\n }\n\n private sanitizePasswordLength(options: any, forGeneration: boolean) {\n let minUppercaseCalc = 0;\n let minLowercaseCalc = 0;\n let minNumberCalc: number = options.minNumber;\n let minSpecialCalc: number = options.minSpecial;\n\n if (options.uppercase && options.minUppercase <= 0) {\n minUppercaseCalc = 1;\n } else if (!options.uppercase) {\n minUppercaseCalc = 0;\n }\n\n if (options.lowercase && options.minLowercase <= 0) {\n minLowercaseCalc = 1;\n } else if (!options.lowercase) {\n minLowercaseCalc = 0;\n }\n\n if (options.number && options.minNumber <= 0) {\n minNumberCalc = 1;\n } else if (!options.number) {\n minNumberCalc = 0;\n }\n\n if (options.special && options.minSpecial <= 0) {\n minSpecialCalc = 1;\n } else if (!options.special) {\n minSpecialCalc = 0;\n }\n\n // This should never happen but is a final safety net\n if (!options.length || options.length < 1) {\n options.length = 10;\n }\n\n const minLength: number = minUppercaseCalc + minLowercaseCalc + minNumberCalc + minSpecialCalc;\n // Normalize and Generation both require this modification\n if (options.length < minLength) {\n options.length = minLength;\n }\n\n // Apply other changes if the options object passed in is for generation\n if (forGeneration) {\n options.minUppercase = minUppercaseCalc;\n options.minLowercase = minLowercaseCalc;\n options.minNumber = minNumberCalc;\n options.minSpecial = minSpecialCalc;\n }\n }\n}\n","export class GeneratedPasswordHistory {\n password: string;\n date: number;\n\n constructor(password: string, date: number) {\n this.password = password;\n this.date = date;\n }\n}\n","import Domain from './domainBase';\n\nexport class PasswordGeneratorPolicyOptions extends Domain {\n defaultType: string = '';\n minLength: number = 0;\n useUppercase: boolean = false;\n useLowercase: boolean = false;\n useNumbers: boolean = false;\n numberCount: number = 0;\n useSpecial: boolean = false;\n specialCount: number = 0;\n minNumberWords: number = 0;\n capitalize: boolean = false;\n includeNumber: boolean = false;\n\n inEffect() {\n return this.defaultType !== '' ||\n this.minLength > 0 ||\n this.numberCount > 0 ||\n this.specialCount > 0 ||\n this.useUppercase ||\n this.useLowercase ||\n this.useNumbers ||\n this.useSpecial ||\n this.minNumberWords > 0 ||\n this.capitalize ||\n this.includeNumber;\n }\n}\n","import { PolicyService as PolicyServiceAbstraction } from '../abstractions/policy.service';\nimport { StorageService } from '../abstractions/storage.service';\nimport { UserService } from '../abstractions/user.service';\n\nimport { PolicyData } from '../models/data/policyData';\n\nimport { MasterPasswordPolicyOptions } from '../models/domain/masterPasswordPolicyOptions';\nimport { Organization } from '../models/domain/organization';\nimport { Policy } from '../models/domain/policy';\nimport { ResetPasswordPolicyOptions } from '../models/domain/resetPasswordPolicyOptions';\n\nimport { OrganizationUserStatusType } from '../enums/organizationUserStatusType';\nimport { OrganizationUserType } from '../enums/organizationUserType';\nimport { PolicyType } from '../enums/policyType';\n\nimport { ApiService } from '../abstractions/api.service';\nimport { ListResponse } from '../models/response/listResponse';\nimport { PolicyResponse } from '../models/response/policyResponse';\n\nconst Keys = {\n policiesPrefix: 'policies_',\n};\n\nexport class PolicyService implements PolicyServiceAbstraction {\n policyCache: Policy[];\n\n constructor(private userService: UserService, private storageService: StorageService,\n private apiService: ApiService) {\n }\n\n clearCache(): void {\n this.policyCache = null;\n }\n\n async getAll(type?: PolicyType): Promise {\n if (this.policyCache == null) {\n const userId = await this.userService.getUserId();\n const policies = await this.storageService.get<{ [id: string]: PolicyData; }>(\n Keys.policiesPrefix + userId);\n const response: Policy[] = [];\n for (const id in policies) {\n if (policies.hasOwnProperty(id)) {\n response.push(new Policy(policies[id]));\n }\n }\n this.policyCache = response;\n }\n if (type != null) {\n return this.policyCache.filter(p => p.type === type);\n } else {\n return this.policyCache;\n }\n }\n\n async getPolicyForOrganization(policyType: PolicyType, organizationId: string): Promise {\n const org = await this.userService.getOrganization(organizationId);\n if (org?.isProviderUser) {\n const orgPolicies = await this.apiService.getPolicies(organizationId);\n const policy = orgPolicies.data.find(p => p.organizationId === organizationId);\n\n if (policy == null) {\n return null;\n }\n\n return new Policy(new PolicyData(policy));\n }\n\n const policies = await this.getAll(policyType);\n return policies.find(p => p.organizationId === organizationId);\n }\n\n async replace(policies: { [id: string]: PolicyData; }): Promise {\n const userId = await this.userService.getUserId();\n await this.storageService.save(Keys.policiesPrefix + userId, policies);\n this.policyCache = null;\n }\n\n async clear(userId: string): Promise {\n await this.storageService.remove(Keys.policiesPrefix + userId);\n this.policyCache = null;\n }\n\n async getMasterPasswordPoliciesForInvitedUsers(\n orgId: string\n ): Promise {\n const userId = await this.userService.getUserId();\n const response = await this.apiService.getPoliciesByInvitedUser(orgId, userId);\n const policies = await this.mapPoliciesFromToken(response);\n return this.getMasterPasswordPolicyOptions(policies);\n }\n\n async getMasterPasswordPolicyOptions(policies?: Policy[]): Promise {\n let enforcedOptions: MasterPasswordPolicyOptions = null;\n\n if (policies == null) {\n policies = await this.getAll(PolicyType.MasterPassword);\n } else {\n policies = policies.filter(p => p.type === PolicyType.MasterPassword);\n }\n\n if (policies == null || policies.length === 0) {\n return enforcedOptions;\n }\n\n policies.forEach(currentPolicy => {\n if (!currentPolicy.enabled || currentPolicy.data == null) {\n return;\n }\n\n if (enforcedOptions == null) {\n enforcedOptions = new MasterPasswordPolicyOptions();\n }\n\n if (currentPolicy.data.minComplexity != null\n && currentPolicy.data.minComplexity > enforcedOptions.minComplexity) {\n enforcedOptions.minComplexity = currentPolicy.data.minComplexity;\n }\n\n if (currentPolicy.data.minLength != null\n && currentPolicy.data.minLength > enforcedOptions.minLength) {\n enforcedOptions.minLength = currentPolicy.data.minLength;\n }\n\n if (currentPolicy.data.requireUpper) {\n enforcedOptions.requireUpper = true;\n }\n\n if (currentPolicy.data.requireLower) {\n enforcedOptions.requireLower = true;\n }\n\n if (currentPolicy.data.requireNumbers) {\n enforcedOptions.requireNumbers = true;\n }\n\n if (currentPolicy.data.requireSpecial) {\n enforcedOptions.requireSpecial = true;\n }\n });\n\n return enforcedOptions;\n }\n\n evaluateMasterPassword(passwordStrength: number, newPassword: string,\n enforcedPolicyOptions: MasterPasswordPolicyOptions): boolean {\n if (enforcedPolicyOptions == null) {\n return true;\n }\n\n if (enforcedPolicyOptions.minComplexity > 0 && enforcedPolicyOptions.minComplexity > passwordStrength) {\n return false;\n }\n\n if (enforcedPolicyOptions.minLength > 0 && enforcedPolicyOptions.minLength > newPassword.length) {\n return false;\n }\n\n if (enforcedPolicyOptions.requireUpper && newPassword.toLocaleLowerCase() === newPassword) {\n return false;\n }\n\n if (enforcedPolicyOptions.requireLower && newPassword.toLocaleUpperCase() === newPassword) {\n return false;\n }\n\n if (enforcedPolicyOptions.requireNumbers && !(/[0-9]/.test(newPassword))) {\n return false;\n }\n\n if (enforcedPolicyOptions.requireSpecial && !(/[!@#$%\\^&*]/g.test(newPassword))) {\n return false;\n }\n\n return true;\n }\n\n getResetPasswordPolicyOptions(policies: Policy[], orgId: string): [ResetPasswordPolicyOptions, boolean] {\n const resetPasswordPolicyOptions = new ResetPasswordPolicyOptions();\n\n if (policies == null || orgId == null) {\n return [resetPasswordPolicyOptions, false];\n }\n\n const policy = policies.find(p => p.organizationId === orgId && p.type === PolicyType.ResetPassword && p.enabled);\n resetPasswordPolicyOptions.autoEnrollEnabled = policy?.data?.autoEnrollEnabled ?? false;\n\n return [resetPasswordPolicyOptions, policy?.enabled ?? false];\n }\n\n mapPoliciesFromToken(policiesResponse: ListResponse): Policy[] {\n if (policiesResponse == null || policiesResponse.data == null) {\n return null;\n }\n\n const policiesData = policiesResponse.data.map(p => new PolicyData(p));\n return policiesData.map(p => new Policy(p));\n }\n\n async policyAppliesToUser(policyType: PolicyType, policyFilter?: (policy: Policy) => boolean) {\n const policies = await this.getAll(policyType);\n const organizations = await this.userService.getAllOrganizations();\n let filteredPolicies;\n\n if (policyFilter != null) {\n filteredPolicies = policies.filter(p => p.enabled && policyFilter(p));\n }\n else {\n filteredPolicies = policies.filter(p => p.enabled);\n }\n\n const policySet = new Set(filteredPolicies.map(p => p.organizationId));\n\n return organizations.some(o =>\n o.enabled &&\n o.status >= OrganizationUserStatusType.Accepted &&\n o.usePolicies &&\n !this.isExcemptFromPolicies(o, policyType) &&\n policySet.has(o.id));\n }\n\n private isExcemptFromPolicies(organization: Organization, policyType: PolicyType) {\n if (policyType === PolicyType.MaximumVaultTimeout) {\n return organization.type === OrganizationUserType.Owner;\n }\n\n return organization.isExemptFromPolicies;\n }\n}\n","import Domain from './domainBase';\n\nexport class ResetPasswordPolicyOptions extends Domain {\n autoEnrollEnabled: boolean = false;\n}\n","import * as lunr from 'lunr';\n\nimport { CipherView } from '../models/view/cipherView';\n\nimport { CipherService } from '../abstractions/cipher.service';\nimport { I18nService } from '../abstractions/i18n.service';\nimport { LogService } from '../abstractions/log.service';\nimport { SearchService as SearchServiceAbstraction } from '../abstractions/search.service';\n\nimport { CipherType } from '../enums/cipherType';\nimport { FieldType } from '../enums/fieldType';\nimport { UriMatchType } from '../enums/uriMatchType';\nimport { SendView } from '../models/view/sendView';\n\nexport class SearchService implements SearchServiceAbstraction {\n indexedEntityId?: string = null;\n private indexing = false;\n private index: lunr.Index = null;\n private searchableMinLength = 2;\n\n constructor(private cipherService: CipherService, private logService: LogService,\n private i18nService: I18nService) {\n if (['zh-CN', 'zh-TW'].indexOf(i18nService.locale) !== -1) {\n this.searchableMinLength = 1;\n }\n }\n\n clearIndex(): void {\n this.indexedEntityId = null;\n this.index = null;\n }\n\n isSearchable(query: string): boolean {\n const notSearchable = query == null || (this.index == null && query.length < this.searchableMinLength) ||\n (this.index != null && query.length < this.searchableMinLength && query.indexOf('>') !== 0);\n return !notSearchable;\n }\n\n async indexCiphers(indexedEntityId?: string, ciphers?: CipherView[]): Promise {\n if (this.indexing) {\n return;\n }\n\n this.logService.time('search indexing');\n this.indexing = true;\n this.indexedEntityId = indexedEntityId;\n this.index = null;\n const builder = new lunr.Builder();\n builder.ref('id');\n builder.field('shortid', { boost: 100, extractor: (c: CipherView) => c.id.substr(0, 8) });\n builder.field('name', { boost: 10 });\n builder.field('subtitle', {\n boost: 5,\n extractor: (c: CipherView) => {\n if (c.subTitle != null && c.type === CipherType.Card) {\n return c.subTitle.replace(/\\*/g, '');\n }\n return c.subTitle;\n },\n });\n builder.field('notes');\n builder.field('login.username', {\n extractor: (c: CipherView) => c.type === CipherType.Login && c.login != null ? c.login.username : null,\n });\n builder.field('login.uris', { boost: 2, extractor: (c: CipherView) => this.uriExtractor(c) });\n builder.field('fields', { extractor: (c: CipherView) => this.fieldExtractor(c, false) });\n builder.field('fields_joined', { extractor: (c: CipherView) => this.fieldExtractor(c, true) });\n builder.field('attachments', { extractor: (c: CipherView) => this.attachmentExtractor(c, false) });\n builder.field('attachments_joined',\n { extractor: (c: CipherView) => this.attachmentExtractor(c, true) });\n builder.field('organizationid', { extractor: (c: CipherView) => c.organizationId });\n ciphers = ciphers || await this.cipherService.getAllDecrypted();\n ciphers.forEach(c => builder.add(c));\n this.index = builder.build();\n\n this.indexing = false;\n\n this.logService.timeEnd('search indexing');\n }\n\n async searchCiphers(query: string,\n filter: (((cipher: CipherView) => boolean) | (((cipher: CipherView) => boolean)[])) = null,\n ciphers: CipherView[] = null):\n Promise {\n const results: CipherView[] = [];\n if (query != null) {\n query = query.trim().toLowerCase();\n }\n if (query === '') {\n query = null;\n }\n\n if (ciphers == null) {\n ciphers = await this.cipherService.getAllDecrypted();\n }\n\n if (filter != null && Array.isArray(filter) && filter.length > 0) {\n ciphers = ciphers.filter(c => filter.every(f => f == null || f(c)));\n } else if (filter != null) {\n ciphers = ciphers.filter(filter as (cipher: CipherView) => boolean);\n }\n\n if (!this.isSearchable(query)) {\n return ciphers;\n }\n\n if (this.indexing) {\n await new Promise(r => setTimeout(r, 250));\n if (this.indexing) {\n await new Promise(r => setTimeout(r, 500));\n }\n }\n\n const index = this.getIndexForSearch();\n if (index == null) {\n // Fall back to basic search if index is not available\n return this.searchCiphersBasic(ciphers, query);\n }\n\n const ciphersMap = new Map();\n ciphers.forEach(c => ciphersMap.set(c.id, c));\n\n let searchResults: lunr.Index.Result[] = null;\n const isQueryString = query != null && query.length > 1 && query.indexOf('>') === 0;\n if (isQueryString) {\n try {\n searchResults = index.search(query.substr(1).trim());\n } catch (e) {\n this.logService.error(e);\n }\n } else {\n // tslint:disable-next-line\n const soWild = lunr.Query.wildcard.LEADING | lunr.Query.wildcard.TRAILING;\n searchResults = index.query(q => {\n lunr.tokenizer(query).forEach(token => {\n const t = token.toString();\n q.term(t, { fields: ['name'], wildcard: soWild });\n q.term(t, { fields: ['subtitle'], wildcard: soWild });\n q.term(t, { fields: ['login.uris'], wildcard: soWild });\n q.term(t, {});\n });\n });\n }\n\n if (searchResults != null) {\n searchResults.forEach(r => {\n if (ciphersMap.has(r.ref)) {\n results.push(ciphersMap.get(r.ref));\n }\n });\n }\n return results;\n }\n\n searchCiphersBasic(ciphers: CipherView[], query: string, deleted: boolean = false) {\n query = query.trim().toLowerCase();\n return ciphers.filter(c => {\n if (deleted !== c.isDeleted) {\n return false;\n }\n if (c.name != null && c.name.toLowerCase().indexOf(query) > -1) {\n return true;\n }\n if (query.length >= 8 && c.id.startsWith(query)) {\n return true;\n }\n if (c.subTitle != null && c.subTitle.toLowerCase().indexOf(query) > -1) {\n return true;\n }\n if (c.login && c.login.uri != null && c.login.uri.toLowerCase().indexOf(query) > -1) {\n return true;\n }\n return false;\n });\n }\n\n searchSends(sends: SendView[], query: string) {\n query = query.trim().toLocaleLowerCase();\n\n return sends.filter(s => {\n if (s.name != null && s.name.toLowerCase().indexOf(query) > -1) {\n return true;\n }\n if (query.length >= 8 && (s.id.startsWith(query) || s.accessId.toLocaleLowerCase().startsWith(query) || (s.file?.id != null && s.file.id.startsWith(query)))) {\n return true;\n }\n if (s.notes != null && s.notes.toLowerCase().indexOf(query) > -1) {\n return true;\n }\n if (s.text?.text != null && s.text.text.toLowerCase().indexOf(query) > -1) {\n return true;\n }\n if (s.file?.fileName != null && s.file.fileName.toLowerCase().indexOf(query) > -1) {\n return true;\n }\n });\n }\n\n getIndexForSearch(): lunr.Index {\n return this.index;\n }\n\n private fieldExtractor(c: CipherView, joined: boolean) {\n if (!c.hasFields) {\n return null;\n }\n let fields: string[] = [];\n c.fields.forEach(f => {\n if (f.name != null) {\n fields.push(f.name);\n }\n if (f.type === FieldType.Text && f.value != null) {\n fields.push(f.value);\n }\n });\n fields = fields.filter(f => f.trim() !== '');\n if (fields.length === 0) {\n return null;\n }\n return joined ? fields.join(' ') : fields;\n }\n\n private attachmentExtractor(c: CipherView, joined: boolean) {\n if (!c.hasAttachments) {\n return null;\n }\n let attachments: string[] = [];\n c.attachments.forEach(a => {\n if (a != null && a.fileName != null) {\n if (joined && a.fileName.indexOf('.') > -1) {\n attachments.push(a.fileName.substr(0, a.fileName.lastIndexOf('.')));\n } else {\n attachments.push(a.fileName);\n }\n }\n });\n attachments = attachments.filter(f => f.trim() !== '');\n if (attachments.length === 0) {\n return null;\n }\n return joined ? attachments.join(' ') : attachments;\n }\n\n private uriExtractor(c: CipherView) {\n if (c.type !== CipherType.Login || c.login == null || !c.login.hasUris) {\n return null;\n }\n const uris: string[] = [];\n c.login.uris.forEach(u => {\n if (u.uri == null || u.uri === '') {\n return;\n }\n if (u.hostname != null) {\n uris.push(u.hostname);\n return;\n }\n let uri = u.uri;\n if (u.match !== UriMatchType.RegularExpression) {\n const protocolIndex = uri.indexOf('://');\n if (protocolIndex > -1) {\n uri = uri.substr(protocolIndex + 3);\n }\n const queryIndex = uri.search(/\\?|&|#/);\n if (queryIndex > -1) {\n uri = uri.substring(0, queryIndex);\n }\n }\n uris.push(uri);\n });\n return uris.length > 0 ? uris : null;\n }\n}\n","import { SendData } from '../models/data/sendData';\n\nimport { SendRequest } from '../models/request/sendRequest';\n\nimport { ErrorResponse } from '../models/response/errorResponse';\nimport { SendResponse } from '../models/response/sendResponse';\n\nimport { EncArrayBuffer } from '../models/domain/encArrayBuffer';\nimport { EncString } from '../models/domain/encString';\nimport { Send } from '../models/domain/send';\nimport { SendFile } from '../models/domain/sendFile';\nimport { SendText } from '../models/domain/sendText';\nimport { SymmetricCryptoKey } from '../models/domain/symmetricCryptoKey';\n\nimport { FileUploadType } from '../enums/fileUploadType';\nimport { SendType } from '../enums/sendType';\n\nimport { SendView } from '../models/view/sendView';\n\nimport { ApiService } from '../abstractions/api.service';\nimport { CryptoService } from '../abstractions/crypto.service';\nimport { CryptoFunctionService } from '../abstractions/cryptoFunction.service';\nimport { FileUploadService } from '../abstractions/fileUpload.service';\nimport { I18nService } from '../abstractions/i18n.service';\nimport { SendService as SendServiceAbstraction } from '../abstractions/send.service';\nimport { StorageService } from '../abstractions/storage.service';\nimport { UserService } from '../abstractions/user.service';\n\nimport { Utils } from '../misc/utils';\n\nconst Keys = {\n sendsPrefix: 'sends_',\n};\n\nexport class SendService implements SendServiceAbstraction {\n decryptedSendCache: SendView[];\n\n constructor(private cryptoService: CryptoService, private userService: UserService,\n private apiService: ApiService, private fileUploadService: FileUploadService,\n private storageService: StorageService, private i18nService: I18nService,\n private cryptoFunctionService: CryptoFunctionService) { }\n\n clearCache(): void {\n this.decryptedSendCache = null;\n }\n\n async encrypt(model: SendView, file: File | ArrayBuffer, password: string,\n key?: SymmetricCryptoKey): Promise<[Send, EncArrayBuffer]> {\n let fileData: EncArrayBuffer = null;\n const send = new Send();\n send.id = model.id;\n send.type = model.type;\n send.disabled = model.disabled;\n send.hideEmail = model.hideEmail;\n send.maxAccessCount = model.maxAccessCount;\n if (model.key == null) {\n model.key = await this.cryptoFunctionService.randomBytes(16);\n model.cryptoKey = await this.cryptoService.makeSendKey(model.key);\n }\n if (password != null) {\n const passwordHash = await this.cryptoFunctionService.pbkdf2(password, model.key, 'sha256', 100000);\n send.password = Utils.fromBufferToB64(passwordHash);\n }\n send.key = await this.cryptoService.encrypt(model.key, key);\n send.name = await this.cryptoService.encrypt(model.name, model.cryptoKey);\n send.notes = await this.cryptoService.encrypt(model.notes, model.cryptoKey);\n if (send.type === SendType.Text) {\n send.text = new SendText();\n send.text.text = await this.cryptoService.encrypt(model.text.text, model.cryptoKey);\n send.text.hidden = model.text.hidden;\n } else if (send.type === SendType.File) {\n send.file = new SendFile();\n if (file != null) {\n if (file instanceof ArrayBuffer) {\n const [name, data] = await this.encryptFileData(model.file.fileName, file, model.cryptoKey);\n send.file.fileName = name;\n fileData = data;\n } else {\n fileData = await this.parseFile(send, file, model.cryptoKey);\n }\n }\n }\n\n return [send, fileData];\n }\n\n async get(id: string): Promise {\n const userId = await this.userService.getUserId();\n const sends = await this.storageService.get<{ [id: string]: SendData; }>(\n Keys.sendsPrefix + userId);\n if (sends == null || !sends.hasOwnProperty(id)) {\n return null;\n }\n\n return new Send(sends[id]);\n }\n\n async getAll(): Promise {\n const userId = await this.userService.getUserId();\n const sends = await this.storageService.get<{ [id: string]: SendData; }>(\n Keys.sendsPrefix + userId);\n const response: Send[] = [];\n for (const id in sends) {\n if (sends.hasOwnProperty(id)) {\n response.push(new Send(sends[id]));\n }\n }\n return response;\n }\n\n async getAllDecrypted(): Promise {\n if (this.decryptedSendCache != null) {\n return this.decryptedSendCache;\n }\n\n const hasKey = await this.cryptoService.hasKey();\n if (!hasKey) {\n throw new Error('No key.');\n }\n\n const decSends: SendView[] = [];\n const promises: Promise[] = [];\n const sends = await this.getAll();\n sends.forEach(send => {\n promises.push(send.decrypt().then(f => decSends.push(f)));\n });\n\n await Promise.all(promises);\n decSends.sort(Utils.getSortFunction(this.i18nService, 'name'));\n\n this.decryptedSendCache = decSends;\n return this.decryptedSendCache;\n }\n\n async saveWithServer(sendData: [Send, EncArrayBuffer]): Promise {\n const request = new SendRequest(sendData[0], sendData[1]?.buffer.byteLength);\n let response: SendResponse;\n if (sendData[0].id == null) {\n if (sendData[0].type === SendType.Text) {\n response = await this.apiService.postSend(request);\n } else {\n try {\n const uploadDataResponse = await this.apiService.postFileTypeSend(request);\n response = uploadDataResponse.sendResponse;\n\n await this.fileUploadService.uploadSendFile(uploadDataResponse, sendData[0].file.fileName, sendData[1]);\n } catch (e) {\n if (e instanceof ErrorResponse && (e as ErrorResponse).statusCode === 404) {\n response = await this.legacyServerSendFileUpload(sendData, request);\n } else if (e instanceof ErrorResponse) {\n throw new Error((e as ErrorResponse).getSingleMessage());\n } else {\n throw e;\n }\n }\n }\n sendData[0].id = response.id;\n sendData[0].accessId = response.accessId;\n } else {\n response = await this.apiService.putSend(sendData[0].id, request);\n }\n\n const userId = await this.userService.getUserId();\n const data = new SendData(response, userId);\n await this.upsert(data);\n }\n\n /**\n * @deprecated Mar 25 2021: This method has been deprecated in favor of direct uploads.\n * This method still exists for backward compatibility with old server versions.\n */\n async legacyServerSendFileUpload(sendData: [Send, EncArrayBuffer], request: SendRequest): Promise\n {\n const fd = new FormData();\n try {\n const blob = new Blob([sendData[1].buffer], { type: 'application/octet-stream' });\n fd.append('model', JSON.stringify(request));\n fd.append('data', blob, sendData[0].file.fileName.encryptedString);\n } catch (e) {\n if (Utils.isNode && !Utils.isBrowser) {\n fd.append('model', JSON.stringify(request));\n fd.append('data', Buffer.from(sendData[1].buffer) as any, {\n filepath: sendData[0].file.fileName.encryptedString,\n contentType: 'application/octet-stream',\n } as any);\n } else {\n throw e;\n }\n }\n return await this.apiService.postSendFileLegacy(fd);\n }\n\n async upsert(send: SendData | SendData[]): Promise {\n const userId = await this.userService.getUserId();\n let sends = await this.storageService.get<{ [id: string]: SendData; }>(\n Keys.sendsPrefix + userId);\n if (sends == null) {\n sends = {};\n }\n\n if (send instanceof SendData) {\n const s = send as SendData;\n sends[s.id] = s;\n } else {\n (send as SendData[]).forEach(s => {\n sends[s.id] = s;\n });\n }\n\n await this.storageService.save(Keys.sendsPrefix + userId, sends);\n this.decryptedSendCache = null;\n }\n\n async replace(sends: { [id: string]: SendData; }): Promise {\n const userId = await this.userService.getUserId();\n await this.storageService.save(Keys.sendsPrefix + userId, sends);\n this.decryptedSendCache = null;\n }\n\n async clear(userId: string): Promise {\n await this.storageService.remove(Keys.sendsPrefix + userId);\n this.decryptedSendCache = null;\n }\n\n async delete(id: string | string[]): Promise {\n const userId = await this.userService.getUserId();\n const sends = await this.storageService.get<{ [id: string]: SendData; }>(\n Keys.sendsPrefix + userId);\n if (sends == null) {\n return;\n }\n\n if (typeof id === 'string') {\n if (sends[id] == null) {\n return;\n }\n delete sends[id];\n } else {\n (id as string[]).forEach(i => {\n delete sends[i];\n });\n }\n\n await this.storageService.save(Keys.sendsPrefix + userId, sends);\n this.decryptedSendCache = null;\n }\n\n async deleteWithServer(id: string): Promise {\n await this.apiService.deleteSend(id);\n await this.delete(id);\n }\n\n async removePasswordWithServer(id: string): Promise {\n const response = await this.apiService.putSendRemovePassword(id);\n const userId = await this.userService.getUserId();\n const data = new SendData(response, userId);\n await this.upsert(data);\n }\n\n private parseFile(send: Send, file: File, key: SymmetricCryptoKey): Promise {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.readAsArrayBuffer(file);\n reader.onload = async evt => {\n try {\n const [name, data] = await this.encryptFileData(file.name, evt.target.result as ArrayBuffer, key);\n send.file.fileName = name;\n resolve(data);\n } catch (e) {\n reject(e);\n }\n };\n reader.onerror = evt => {\n reject('Error reading file.');\n };\n });\n }\n\n private async encryptFileData(fileName: string, data: ArrayBuffer,\n key: SymmetricCryptoKey): Promise<[EncString, EncArrayBuffer]> {\n const encFileName = await this.cryptoService.encrypt(fileName, key);\n const encFileData = await this.cryptoService.encryptToBytes(data, key);\n return [encFileName, encFileData];\n }\n}\n","import { SendFileApi } from '../api/sendFileApi';\n\nexport class SendFileData {\n id: string;\n fileName: string;\n key: string;\n size: string;\n sizeName: string;\n\n constructor(data?: SendFileApi) {\n if (data == null) {\n return;\n }\n\n this.id = data.id;\n this.fileName = data.fileName;\n this.key = data.key;\n this.size = data.size;\n this.sizeName = data.sizeName;\n }\n}\n","import { SendTextApi } from '../api/sendTextApi';\n\nexport class SendTextData {\n text: string;\n hidden: boolean;\n\n constructor(data?: SendTextApi) {\n if (data == null) {\n return;\n }\n\n this.text = data.text;\n this.hidden = data.hidden;\n }\n}\n","import { CryptoService } from '../../abstractions/crypto.service';\n\nimport { SendType } from '../../enums/sendType';\n\nimport { Utils } from '../../misc/utils';\n\nimport { SendData } from '../data/sendData';\n\nimport { SendView } from '../view/sendView';\n\nimport Domain from './domainBase';\nimport { EncString } from './encString';\nimport { SendFile } from './sendFile';\nimport { SendText } from './sendText';\n\nexport class Send extends Domain {\n id: string;\n accessId: string;\n userId: string;\n type: SendType;\n name: EncString;\n notes: EncString;\n file: SendFile;\n text: SendText;\n key: EncString;\n maxAccessCount?: number;\n accessCount: number;\n revisionDate: Date;\n expirationDate: Date;\n deletionDate: Date;\n password: string;\n disabled: boolean;\n hideEmail: boolean;\n\n constructor(obj?: SendData, alreadyEncrypted: boolean = false) {\n super();\n if (obj == null) {\n return;\n }\n\n this.buildDomainModel(this, obj, {\n id: null,\n accessId: null,\n userId: null,\n name: null,\n notes: null,\n key: null,\n }, alreadyEncrypted, ['id', 'accessId', 'userId']);\n\n this.type = obj.type;\n this.maxAccessCount = obj.maxAccessCount;\n this.accessCount = obj.accessCount;\n this.password = obj.password;\n this.disabled = obj.disabled;\n this.revisionDate = obj.revisionDate != null ? new Date(obj.revisionDate) : null;\n this.deletionDate = obj.deletionDate != null ? new Date(obj.deletionDate) : null;\n this.expirationDate = obj.expirationDate != null ? new Date(obj.expirationDate) : null;\n this.hideEmail = obj.hideEmail;\n\n switch (this.type) {\n case SendType.Text:\n this.text = new SendText(obj.text, alreadyEncrypted);\n break;\n case SendType.File:\n this.file = new SendFile(obj.file, alreadyEncrypted);\n break;\n default:\n break;\n }\n }\n\n async decrypt(): Promise {\n const model = new SendView(this);\n\n let cryptoService: CryptoService;\n const containerService = (Utils.global as any).bitwardenContainerService;\n if (containerService) {\n cryptoService = containerService.getCryptoService();\n } else {\n throw new Error('global bitwardenContainerService not initialized.');\n }\n\n try {\n model.key = await cryptoService.decryptToBytes(this.key, null);\n model.cryptoKey = await cryptoService.makeSendKey(model.key);\n } catch (e) {\n // TODO: error?\n }\n\n await this.decryptObj(model, {\n name: null,\n notes: null,\n }, null, model.cryptoKey);\n\n switch (this.type) {\n case SendType.File:\n model.file = await this.file.decrypt(model.cryptoKey);\n break;\n case SendType.Text:\n model.text = await this.text.decrypt(model.cryptoKey);\n break;\n default:\n break;\n }\n\n return model;\n }\n}\n","import { SettingsService as SettingsServiceAbstraction } from '../abstractions/settings.service';\nimport { StorageService } from '../abstractions/storage.service';\nimport { UserService } from '../abstractions/user.service';\n\nconst Keys = {\n settingsPrefix: 'settings_',\n equivalentDomains: 'equivalentDomains',\n};\n\nexport class SettingsService implements SettingsServiceAbstraction {\n private settingsCache: any;\n\n constructor(private userService: UserService, private storageService: StorageService) {\n }\n\n clearCache(): void {\n this.settingsCache = null;\n }\n\n getEquivalentDomains(): Promise {\n return this.getSettingsKey(Keys.equivalentDomains);\n }\n\n async setEquivalentDomains(equivalentDomains: string[][]): Promise {\n await this.setSettingsKey(Keys.equivalentDomains, equivalentDomains);\n }\n\n async clear(userId: string): Promise {\n await this.storageService.remove(Keys.settingsPrefix + userId);\n this.clearCache();\n }\n\n // Helpers\n\n private async getSettings(): Promise {\n if (this.settingsCache == null) {\n const userId = await this.userService.getUserId();\n this.settingsCache = this.storageService.get(Keys.settingsPrefix + userId);\n }\n return this.settingsCache;\n }\n\n private async getSettingsKey(key: string): Promise {\n const settings = await this.getSettings();\n if (settings != null && settings[key]) {\n return settings[key];\n }\n return null;\n }\n\n private async setSettingsKey(key: string, value: any): Promise {\n const userId = await this.userService.getUserId();\n let settings = await this.getSettings();\n if (!settings) {\n settings = {};\n }\n\n settings[key] = value;\n await this.storageService.save(Keys.settingsPrefix + userId, settings);\n this.settingsCache = settings;\n }\n}\n","import { StateService as StateServiceAbstraction } from '../abstractions/state.service';\n\nexport class StateService implements StateServiceAbstraction {\n private state: any = {};\n\n get(key: string): Promise {\n if (this.state.hasOwnProperty(key)) {\n return Promise.resolve(this.state[key]);\n }\n return Promise.resolve(null);\n }\n\n save(key: string, obj: any): Promise {\n this.state[key] = obj;\n return Promise.resolve();\n }\n\n remove(key: string): Promise {\n delete this.state[key];\n return Promise.resolve();\n }\n\n purge(): Promise {\n this.state = {};\n return Promise.resolve();\n }\n}\n","import { ApiService } from '../abstractions/api.service';\nimport { CipherService } from '../abstractions/cipher.service';\nimport { CollectionService } from '../abstractions/collection.service';\nimport { CryptoService } from '../abstractions/crypto.service';\nimport { FolderService } from '../abstractions/folder.service';\nimport { KeyConnectorService } from '../abstractions/keyConnector.service';\nimport { LogService } from '../abstractions/log.service';\nimport { MessagingService } from '../abstractions/messaging.service';\nimport { PolicyService } from '../abstractions/policy.service';\nimport { SendService } from '../abstractions/send.service';\nimport { SettingsService } from '../abstractions/settings.service';\nimport { StorageService } from '../abstractions/storage.service';\nimport { SyncService as SyncServiceAbstraction } from '../abstractions/sync.service';\nimport { TokenService } from '../abstractions/token.service';\nimport { UserService } from '../abstractions/user.service';\n\nimport { CipherData } from '../models/data/cipherData';\nimport { CollectionData } from '../models/data/collectionData';\nimport { FolderData } from '../models/data/folderData';\nimport { OrganizationData } from '../models/data/organizationData';\nimport { PolicyData } from '../models/data/policyData';\nimport { ProviderData } from '../models/data/providerData';\nimport { SendData } from '../models/data/sendData';\n\nimport { CipherResponse } from '../models/response/cipherResponse';\nimport { CollectionDetailsResponse } from '../models/response/collectionResponse';\nimport { DomainsResponse } from '../models/response/domainsResponse';\nimport { FolderResponse } from '../models/response/folderResponse';\nimport {\n SyncCipherNotification,\n SyncFolderNotification,\n SyncSendNotification,\n} from '../models/response/notificationResponse';\nimport { PolicyResponse } from '../models/response/policyResponse';\nimport { ProfileResponse } from '../models/response/profileResponse';\nimport { SendResponse } from '../models/response/sendResponse';\n\nconst Keys = {\n lastSyncPrefix: 'lastSync_',\n};\n\nexport class SyncService implements SyncServiceAbstraction {\n syncInProgress: boolean = false;\n\n constructor(private userService: UserService, private apiService: ApiService,\n private settingsService: SettingsService, private folderService: FolderService,\n private cipherService: CipherService, private cryptoService: CryptoService,\n private collectionService: CollectionService, private storageService: StorageService,\n private messagingService: MessagingService, private policyService: PolicyService,\n private sendService: SendService, private logService: LogService,\n private tokenService: TokenService, private keyConnectorService: KeyConnectorService,\n private logoutCallback: (expired: boolean) => Promise) {\n }\n\n async getLastSync(): Promise {\n const userId = await this.userService.getUserId();\n if (userId == null) {\n return null;\n }\n\n const lastSync = await this.storageService.get(Keys.lastSyncPrefix + userId);\n if (lastSync) {\n return new Date(lastSync);\n }\n\n return null;\n }\n\n async setLastSync(date: Date): Promise {\n const userId = await this.userService.getUserId();\n if (userId == null) {\n return;\n }\n\n await this.storageService.save(Keys.lastSyncPrefix + userId, date.toJSON());\n }\n\n async fullSync(forceSync: boolean, allowThrowOnError = false): Promise {\n this.syncStarted();\n const isAuthenticated = await this.userService.isAuthenticated();\n if (!isAuthenticated) {\n return this.syncCompleted(false);\n }\n\n const now = new Date();\n let needsSync = false;\n try {\n needsSync = await this.needsSyncing(forceSync);\n } catch (e) {\n if (allowThrowOnError) {\n throw e;\n }\n }\n\n if (!needsSync) {\n await this.setLastSync(now);\n return this.syncCompleted(false);\n }\n\n const userId = await this.userService.getUserId();\n try {\n await this.apiService.refreshIdentityToken();\n const response = await this.apiService.getSync();\n\n await this.syncProfile(response.profile);\n await this.syncFolders(userId, response.folders);\n await this.syncCollections(response.collections);\n await this.syncCiphers(userId, response.ciphers);\n await this.syncSends(userId, response.sends);\n await this.syncSettings(userId, response.domains);\n await this.syncPolicies(response.policies);\n\n await this.setLastSync(now);\n return this.syncCompleted(true);\n } catch (e) {\n if (allowThrowOnError) {\n throw e;\n } else {\n return this.syncCompleted(false);\n }\n }\n }\n\n async syncUpsertFolder(notification: SyncFolderNotification, isEdit: boolean): Promise {\n this.syncStarted();\n if (await this.userService.isAuthenticated()) {\n try {\n const localFolder = await this.folderService.get(notification.id);\n if ((!isEdit && localFolder == null) ||\n (isEdit && localFolder != null && localFolder.revisionDate < notification.revisionDate)) {\n const remoteFolder = await this.apiService.getFolder(notification.id);\n if (remoteFolder != null) {\n const userId = await this.userService.getUserId();\n await this.folderService.upsert(new FolderData(remoteFolder, userId));\n this.messagingService.send('syncedUpsertedFolder', { folderId: notification.id });\n return this.syncCompleted(true);\n }\n }\n } catch (e) {\n this.logService.error(e);\n }\n }\n return this.syncCompleted(false);\n }\n\n async syncDeleteFolder(notification: SyncFolderNotification): Promise {\n this.syncStarted();\n if (await this.userService.isAuthenticated()) {\n await this.folderService.delete(notification.id);\n this.messagingService.send('syncedDeletedFolder', { folderId: notification.id });\n this.syncCompleted(true);\n return true;\n }\n return this.syncCompleted(false);\n }\n\n async syncUpsertCipher(notification: SyncCipherNotification, isEdit: boolean): Promise {\n this.syncStarted();\n if (await this.userService.isAuthenticated()) {\n try {\n let shouldUpdate = true;\n const localCipher = await this.cipherService.get(notification.id);\n if (localCipher != null && localCipher.revisionDate >= notification.revisionDate) {\n shouldUpdate = false;\n }\n\n let checkCollections = false;\n if (shouldUpdate) {\n if (isEdit) {\n shouldUpdate = localCipher != null;\n checkCollections = true;\n } else {\n if (notification.collectionIds == null || notification.organizationId == null) {\n shouldUpdate = localCipher == null;\n } else {\n shouldUpdate = false;\n checkCollections = true;\n }\n }\n }\n\n if (!shouldUpdate && checkCollections && notification.organizationId != null &&\n notification.collectionIds != null && notification.collectionIds.length > 0) {\n const collections = await this.collectionService.getAll();\n if (collections != null) {\n for (let i = 0; i < collections.length; i++) {\n if (notification.collectionIds.indexOf(collections[i].id) > -1) {\n shouldUpdate = true;\n break;\n }\n }\n }\n }\n\n if (shouldUpdate) {\n const remoteCipher = await this.apiService.getCipher(notification.id);\n if (remoteCipher != null) {\n const userId = await this.userService.getUserId();\n await this.cipherService.upsert(new CipherData(remoteCipher, userId));\n this.messagingService.send('syncedUpsertedCipher', { cipherId: notification.id });\n return this.syncCompleted(true);\n }\n }\n } catch (e) {\n if (e != null && e.statusCode === 404 && isEdit) {\n await this.cipherService.delete(notification.id);\n this.messagingService.send('syncedDeletedCipher', { cipherId: notification.id });\n return this.syncCompleted(true);\n }\n }\n }\n return this.syncCompleted(false);\n }\n\n async syncDeleteCipher(notification: SyncCipherNotification): Promise {\n this.syncStarted();\n if (await this.userService.isAuthenticated()) {\n await this.cipherService.delete(notification.id);\n this.messagingService.send('syncedDeletedCipher', { cipherId: notification.id });\n return this.syncCompleted(true);\n }\n return this.syncCompleted(false);\n }\n\n async syncUpsertSend(notification: SyncSendNotification, isEdit: boolean): Promise {\n this.syncStarted();\n if (await this.userService.isAuthenticated()) {\n try {\n const localSend = await this.sendService.get(notification.id);\n if ((!isEdit && localSend == null) ||\n (isEdit && localSend != null && localSend.revisionDate < notification.revisionDate)) {\n const remoteSend = await this.apiService.getSend(notification.id);\n if (remoteSend != null) {\n const userId = await this.userService.getUserId();\n await this.sendService.upsert(new SendData(remoteSend, userId));\n this.messagingService.send('syncedUpsertedSend', { sendId: notification.id });\n return this.syncCompleted(true);\n }\n }\n } catch (e) {\n this.logService.error(e);\n }\n }\n return this.syncCompleted(false);\n }\n\n async syncDeleteSend(notification: SyncSendNotification): Promise {\n this.syncStarted();\n if (await this.userService.isAuthenticated()) {\n await this.sendService.delete(notification.id);\n this.messagingService.send('syncedDeletedSend', { sendId: notification.id });\n this.syncCompleted(true);\n return true;\n }\n return this.syncCompleted(false);\n }\n\n // Helpers\n\n private syncStarted() {\n this.syncInProgress = true;\n this.messagingService.send('syncStarted');\n }\n\n private syncCompleted(successfully: boolean): boolean {\n this.syncInProgress = false;\n this.messagingService.send('syncCompleted', { successfully: successfully });\n return successfully;\n }\n\n private async needsSyncing(forceSync: boolean) {\n if (forceSync) {\n return true;\n }\n\n const lastSync = await this.getLastSync();\n if (lastSync == null || lastSync.getTime() === 0) {\n return true;\n }\n\n const response = await this.apiService.getAccountRevisionDate();\n if (new Date(response) <= lastSync) {\n return false;\n }\n return true;\n }\n\n private async syncProfile(response: ProfileResponse) {\n const stamp = await this.userService.getSecurityStamp();\n if (stamp != null && stamp !== response.securityStamp) {\n if (this.logoutCallback != null) {\n await this.logoutCallback(true);\n }\n\n throw new Error('Stamp has changed');\n }\n\n await this.cryptoService.setEncKey(response.key);\n await this.cryptoService.setEncPrivateKey(response.privateKey);\n await this.cryptoService.setProviderKeys(response.providers);\n await this.cryptoService.setOrgKeys(response.organizations, response.providerOrganizations);\n await this.userService.setSecurityStamp(response.securityStamp);\n await this.userService.setEmailVerified(response.emailVerified);\n await this.userService.setForcePasswordReset(response.forcePasswordReset);\n await this.keyConnectorService.setUsesKeyConnector(response.usesKeyConnector);\n\n const organizations: { [id: string]: OrganizationData; } = {};\n response.organizations.forEach(o => {\n organizations[o.id] = new OrganizationData(o);\n });\n\n const providers: { [id: string]: ProviderData; } = {};\n response.providers.forEach(p => {\n providers[p.id] = new ProviderData(p);\n });\n\n response.providerOrganizations.forEach(o => {\n if (organizations[o.id] == null) {\n organizations[o.id] = new OrganizationData(o);\n organizations[o.id].isProviderUser = true;\n }\n });\n\n await Promise.all([\n this.userService.replaceOrganizations(organizations),\n this.userService.replaceProviders(providers),\n ]);\n\n if (await this.keyConnectorService.userNeedsMigration()) {\n this.messagingService.send('convertAccountToKeyConnector');\n } else {\n this.keyConnectorService.removeConvertAccountRequired();\n }\n }\n\n private async syncFolders(userId: string, response: FolderResponse[]) {\n const folders: { [id: string]: FolderData; } = {};\n response.forEach(f => {\n folders[f.id] = new FolderData(f, userId);\n });\n return await this.folderService.replace(folders);\n }\n\n private async syncCollections(response: CollectionDetailsResponse[]) {\n const collections: { [id: string]: CollectionData; } = {};\n response.forEach(c => {\n collections[c.id] = new CollectionData(c);\n });\n return await this.collectionService.replace(collections);\n }\n\n private async syncCiphers(userId: string, response: CipherResponse[]) {\n const ciphers: { [id: string]: CipherData; } = {};\n response.forEach(c => {\n ciphers[c.id] = new CipherData(c, userId);\n });\n return await this.cipherService.replace(ciphers);\n }\n\n private async syncSends(userId: string, response: SendResponse[]) {\n const sends: { [id: string]: SendData; } = {};\n response.forEach(s => {\n sends[s.id] = new SendData(s, userId);\n });\n return await this.sendService.replace(sends);\n }\n\n private async syncSettings(userId: string, response: DomainsResponse) {\n let eqDomains: string[][] = [];\n if (response != null && response.equivalentDomains != null) {\n eqDomains = eqDomains.concat(response.equivalentDomains);\n }\n\n if (response != null && response.globalEquivalentDomains != null) {\n response.globalEquivalentDomains.forEach(global => {\n if (global.domains.length > 0) {\n eqDomains.push(global.domains);\n }\n });\n }\n\n return this.settingsService.setEquivalentDomains(eqDomains);\n }\n\n private async syncPolicies(response: PolicyResponse[]) {\n const policies: { [id: string]: PolicyData; } = {};\n if (response != null) {\n response.forEach(p => {\n policies[p.id] = new PolicyData(p);\n });\n }\n return await this.policyService.replace(policies);\n }\n}\n","import { ProfileOrganizationResponse } from '../response/profileOrganizationResponse';\n\nimport { OrganizationUserStatusType } from '../../enums/organizationUserStatusType';\nimport { OrganizationUserType } from '../../enums/organizationUserType';\nimport { ProductType } from '../../enums/productType';\n\nimport { PermissionsApi } from '../api/permissionsApi';\n\nexport class OrganizationData {\n id: string;\n name: string;\n status: OrganizationUserStatusType;\n type: OrganizationUserType;\n enabled: boolean;\n usePolicies: boolean;\n useGroups: boolean;\n useDirectory: boolean;\n useEvents: boolean;\n useTotp: boolean;\n use2fa: boolean;\n useApi: boolean;\n useSso: boolean;\n useKeyConnector: boolean;\n useResetPassword: boolean;\n selfHost: boolean;\n usersGetPremium: boolean;\n seats: number;\n maxCollections: number;\n maxStorageGb?: number;\n ssoBound: boolean;\n identifier: string;\n permissions: PermissionsApi;\n resetPasswordEnrolled: boolean;\n userId: string;\n hasPublicAndPrivateKeys: boolean;\n providerId: string;\n providerName: string;\n isProviderUser: boolean;\n familySponsorshipFriendlyName: string;\n familySponsorshipAvailable: boolean;\n planProductType: ProductType;\n keyConnectorEnabled: boolean;\n keyConnectorUrl: string;\n\n constructor(response: ProfileOrganizationResponse) {\n this.id = response.id;\n this.name = response.name;\n this.status = response.status;\n this.type = response.type;\n this.enabled = response.enabled;\n this.usePolicies = response.usePolicies;\n this.useGroups = response.useGroups;\n this.useDirectory = response.useDirectory;\n this.useEvents = response.useEvents;\n this.useTotp = response.useTotp;\n this.use2fa = response.use2fa;\n this.useApi = response.useApi;\n this.useSso = response.useSso;\n this.useKeyConnector = response.useKeyConnector;\n this.useResetPassword = response.useResetPassword;\n this.selfHost = response.selfHost;\n this.usersGetPremium = response.usersGetPremium;\n this.seats = response.seats;\n this.maxCollections = response.maxCollections;\n this.maxStorageGb = response.maxStorageGb;\n this.ssoBound = response.ssoBound;\n this.identifier = response.identifier;\n this.permissions = response.permissions;\n this.resetPasswordEnrolled = response.resetPasswordEnrolled;\n this.userId = response.userId;\n this.hasPublicAndPrivateKeys = response.hasPublicAndPrivateKeys;\n this.providerId = response.providerId;\n this.providerName = response.providerName;\n this.familySponsorshipFriendlyName = response.familySponsorshipFriendlyName;\n this.familySponsorshipAvailable = response.familySponsorshipAvailable;\n this.planProductType = response.planProductType;\n this.keyConnectorEnabled = response.keyConnectorEnabled;\n this.keyConnectorUrl = response.keyConnectorUrl;\n }\n}\n","import { ProfileProviderResponse } from '../response/profileProviderResponse';\n\nimport { ProviderUserStatusType } from '../../enums/providerUserStatusType';\nimport { ProviderUserType } from '../../enums/providerUserType';\n\nexport class ProviderData {\n id: string;\n name: string;\n status: ProviderUserStatusType;\n type: ProviderUserType;\n enabled: boolean;\n userId: string;\n useEvents: boolean;\n\n constructor(response: ProfileProviderResponse) {\n this.id = response.id;\n this.name = response.name;\n this.status = response.status;\n this.type = response.type;\n this.enabled = response.enabled;\n this.userId = response.userId;\n this.useEvents = response.useEvents;\n }\n}\n","import { ConstantsService } from './constants.service';\n\nimport { StorageService } from '../abstractions/storage.service';\nimport { TokenService as TokenServiceAbstraction } from '../abstractions/token.service';\n\nimport { Utils } from '../misc/utils';\n\nconst Keys = {\n accessToken: 'accessToken',\n refreshToken: 'refreshToken',\n twoFactorTokenPrefix: 'twoFactorToken_',\n clientId: 'apikey_clientId',\n clientSecret: 'apikey_clientSecret',\n};\n\nexport class TokenService implements TokenServiceAbstraction {\n token: string;\n decodedToken: any;\n refreshToken: string;\n clientId: string;\n clientSecret: string;\n\n constructor(private storageService: StorageService) {\n }\n\n async setTokens(accessToken: string, refreshToken: string, clientIdClientSecret: [string, string]): Promise {\n await this.setToken(accessToken);\n await this.setRefreshToken(refreshToken);\n if (clientIdClientSecret != null) {\n await this.setClientId(clientIdClientSecret[0]);\n await this.setClientSecret(clientIdClientSecret[1]);\n }\n }\n\n async setClientId(clientId: string): Promise {\n this.clientId = clientId;\n return this.storeTokenValue(Keys.clientId, clientId);\n }\n\n async getClientId(): Promise {\n if (this.clientId != null) {\n return this.clientId;\n }\n\n this.clientId = await this.storageService.get(Keys.clientId);\n return this.clientId;\n }\n\n async setClientSecret(clientSecret: string): Promise {\n this.clientSecret = clientSecret;\n return this.storeTokenValue(Keys.clientSecret, clientSecret);\n }\n\n async getClientSecret(): Promise {\n if (this.clientSecret != null) {\n return this.clientSecret;\n }\n\n this.clientSecret = await this.storageService.get(Keys.clientSecret);\n return this.clientSecret;\n }\n\n async setToken(token: string): Promise {\n this.token = token;\n this.decodedToken = null;\n return this.storeTokenValue(Keys.accessToken, token);\n }\n\n async getToken(): Promise {\n if (this.token != null) {\n return this.token;\n }\n\n this.token = await this.storageService.get(Keys.accessToken);\n return this.token;\n }\n\n async setRefreshToken(refreshToken: string): Promise {\n this.refreshToken = refreshToken;\n return this.storeTokenValue(Keys.refreshToken, refreshToken);\n }\n\n async getRefreshToken(): Promise {\n if (this.refreshToken != null) {\n return this.refreshToken;\n }\n\n this.refreshToken = await this.storageService.get(Keys.refreshToken);\n return this.refreshToken;\n }\n\n async toggleTokens(): Promise {\n const token = await this.getToken();\n const refreshToken = await this.getRefreshToken();\n const clientId = await this.getClientId();\n const clientSecret = await this.getClientSecret();\n const timeout = await this.storageService.get(ConstantsService.vaultTimeoutKey);\n const action = await this.storageService.get(ConstantsService.vaultTimeoutActionKey);\n if ((timeout != null || timeout === 0) && action === 'logOut') {\n // if we have a vault timeout and the action is log out, reset tokens\n await this.clearToken();\n this.token = token;\n this.refreshToken = refreshToken;\n this.clientId = clientId;\n this.clientSecret = clientSecret;\n return;\n }\n\n await this.setToken(token);\n await this.setRefreshToken(refreshToken);\n await this.setClientId(clientId);\n await this.setClientSecret(clientSecret);\n }\n\n setTwoFactorToken(token: string, email: string): Promise {\n return this.storageService.save(Keys.twoFactorTokenPrefix + email, token);\n }\n\n getTwoFactorToken(email: string): Promise {\n return this.storageService.get(Keys.twoFactorTokenPrefix + email);\n }\n\n clearTwoFactorToken(email: string): Promise {\n return this.storageService.remove(Keys.twoFactorTokenPrefix + email);\n }\n\n async clearToken(): Promise {\n this.token = null;\n this.decodedToken = null;\n this.refreshToken = null;\n this.clientId = null;\n this.clientSecret = null;\n\n await this.storageService.remove(Keys.accessToken);\n await this.storageService.remove(Keys.refreshToken);\n await this.storageService.remove(Keys.clientId);\n await this.storageService.remove(Keys.clientSecret);\n }\n\n // jwthelper methods\n // ref https://github.com/auth0/angular-jwt/blob/master/src/angularJwt/services/jwt.js\n\n decodeToken(): any {\n if (this.decodedToken) {\n return this.decodedToken;\n }\n\n if (this.token == null) {\n throw new Error('Token not found.');\n }\n\n const parts = this.token.split('.');\n if (parts.length !== 3) {\n throw new Error('JWT must have 3 parts');\n }\n\n const decoded = Utils.fromUrlB64ToUtf8(parts[1]);\n if (decoded == null) {\n throw new Error('Cannot decode the token');\n }\n\n this.decodedToken = JSON.parse(decoded);\n return this.decodedToken;\n }\n\n getTokenExpirationDate(): Date {\n const decoded = this.decodeToken();\n if (typeof decoded.exp === 'undefined') {\n return null;\n }\n\n const d = new Date(0); // The 0 here is the key, which sets the date to the epoch\n d.setUTCSeconds(decoded.exp);\n return d;\n }\n\n tokenSecondsRemaining(offsetSeconds: number = 0): number {\n const d = this.getTokenExpirationDate();\n if (d == null) {\n return 0;\n }\n\n const msRemaining = d.valueOf() - (new Date().valueOf() + (offsetSeconds * 1000));\n return Math.round(msRemaining / 1000);\n }\n\n tokenNeedsRefresh(minutes: number = 5): boolean {\n const sRemaining = this.tokenSecondsRemaining();\n return sRemaining < (60 * minutes);\n }\n\n getUserId(): string {\n const decoded = this.decodeToken();\n if (typeof decoded.sub === 'undefined') {\n throw new Error('No user id found');\n }\n\n return decoded.sub as string;\n }\n\n getEmail(): string {\n const decoded = this.decodeToken();\n if (typeof decoded.email === 'undefined') {\n throw new Error('No email found');\n }\n\n return decoded.email as string;\n }\n\n getEmailVerified(): boolean {\n const decoded = this.decodeToken();\n if (typeof decoded.email_verified === 'undefined') {\n throw new Error('No email verification found');\n }\n\n return decoded.email_verified as boolean;\n }\n\n getName(): string {\n const decoded = this.decodeToken();\n if (typeof decoded.name === 'undefined') {\n return null;\n }\n\n return decoded.name as string;\n }\n\n getPremium(): boolean {\n const decoded = this.decodeToken();\n if (typeof decoded.premium === 'undefined') {\n return false;\n }\n\n return decoded.premium as boolean;\n }\n\n getIssuer(): string {\n const decoded = this.decodeToken();\n if (typeof decoded.iss === 'undefined') {\n throw new Error('No issuer found');\n }\n\n return decoded.iss as string;\n }\n\n getIsExternal(): boolean {\n const decoded = this.decodeToken();\n if (!Array.isArray(decoded.amr)) {\n throw new Error('No amr found');\n }\n\n return decoded.amr.includes('external');\n }\n\n private async storeTokenValue(key: string, value: string) {\n if (await this.skipTokenStorage()) {\n // if we have a vault timeout and the action is log out, don't store token\n return;\n }\n\n return this.storageService.save(key, value);\n }\n\n private async skipTokenStorage(): Promise {\n const timeout = await this.storageService.get(ConstantsService.vaultTimeoutKey);\n const action = await this.storageService.get(ConstantsService.vaultTimeoutActionKey);\n return timeout != null && action === 'logOut';\n }\n}\n","import { ConstantsService } from './constants.service';\n\nimport { CryptoFunctionService } from '../abstractions/cryptoFunction.service';\nimport { LogService } from '../abstractions/log.service';\nimport { StorageService } from '../abstractions/storage.service';\nimport { TotpService as TotpServiceAbstraction } from '../abstractions/totp.service';\n\nimport { Utils } from '../misc/utils';\n\nconst B32Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\nconst SteamChars = '23456789BCDFGHJKMNPQRTVWXY';\n\nexport class TotpService implements TotpServiceAbstraction {\n constructor(private storageService: StorageService, private cryptoFunctionService: CryptoFunctionService,\n private logService: LogService) { }\n\n async getCode(key: string): Promise {\n if (key == null) {\n return null;\n }\n let period = 30;\n let alg: 'sha1' | 'sha256' | 'sha512' = 'sha1';\n let digits = 6;\n let keyB32 = key;\n const isOtpAuth = key.toLowerCase().indexOf('otpauth://') === 0;\n const isSteamAuth = !isOtpAuth && key.toLowerCase().indexOf('steam://') === 0;\n if (isOtpAuth) {\n const params = Utils.getQueryParams(key);\n if (params.has('digits') && params.get('digits') != null) {\n try {\n const digitParams = parseInt(params.get('digits').trim(), null);\n if (digitParams > 10) {\n digits = 10;\n } else if (digitParams > 0) {\n digits = digitParams;\n }\n } catch {\n this.logService.error('Invalid digits param.');\n }\n }\n if (params.has('period') && params.get('period') != null) {\n try {\n const periodParam = parseInt(params.get('period').trim(), null);\n if (periodParam > 0) {\n period = periodParam;\n }\n } catch {\n this.logService.error('Invalid period param.');\n }\n }\n if (params.has('secret') && params.get('secret') != null) {\n keyB32 = params.get('secret');\n }\n if (params.has('algorithm') && params.get('algorithm') != null) {\n const algParam = params.get('algorithm').toLowerCase();\n if (algParam === 'sha1' || algParam === 'sha256' || algParam === 'sha512') {\n alg = algParam;\n }\n }\n } else if (isSteamAuth) {\n keyB32 = key.substr('steam://'.length);\n digits = 5;\n }\n\n const epoch = Math.round(new Date().getTime() / 1000.0);\n const timeHex = this.leftPad(this.decToHex(Math.floor(epoch / period)), 16, '0');\n const timeBytes = Utils.fromHexToArray(timeHex);\n const keyBytes = this.b32ToBytes(keyB32);\n\n if (!keyBytes.length || !timeBytes.length) {\n return null;\n }\n\n const hash = await this.sign(keyBytes, timeBytes, alg);\n if (hash.length === 0) {\n return null;\n }\n\n /* tslint:disable */\n const offset = (hash[hash.length - 1] & 0xf);\n const binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) |\n ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff);\n /* tslint:enable */\n\n let otp = '';\n if (isSteamAuth) {\n // tslint:disable-next-line\n let fullCode = binary & 0x7fffffff;\n for (let i = 0; i < digits; i++) {\n otp += SteamChars[fullCode % SteamChars.length];\n fullCode = Math.trunc(fullCode / SteamChars.length);\n }\n } else {\n otp = (binary % Math.pow(10, digits)).toString();\n otp = this.leftPad(otp, digits, '0');\n }\n\n return otp;\n }\n\n getTimeInterval(key: string): number {\n let period = 30;\n if (key != null && key.toLowerCase().indexOf('otpauth://') === 0) {\n const params = Utils.getQueryParams(key);\n if (params.has('period') && params.get('period') != null) {\n try {\n period = parseInt(params.get('period').trim(), null);\n } catch {\n this.logService.error('Invalid period param.');\n }\n }\n }\n return period;\n }\n\n async isAutoCopyEnabled(): Promise {\n return !(await this.storageService.get(ConstantsService.disableAutoTotpCopyKey));\n }\n\n // Helpers\n\n private leftPad(s: string, l: number, p: string): string {\n if (l + 1 >= s.length) {\n s = Array(l + 1 - s.length).join(p) + s;\n }\n return s;\n }\n\n private decToHex(d: number): string {\n return (d < 15.5 ? '0' : '') + Math.round(d).toString(16);\n }\n\n private b32ToHex(s: string): string {\n s = s.toUpperCase();\n let cleanedInput = '';\n\n for (let i = 0; i < s.length; i++) {\n if (B32Chars.indexOf(s[i]) < 0) {\n continue;\n }\n\n cleanedInput += s[i];\n }\n s = cleanedInput;\n\n let bits = '';\n let hex = '';\n for (let i = 0; i < s.length; i++) {\n const byteIndex = B32Chars.indexOf(s.charAt(i));\n if (byteIndex < 0) {\n continue;\n }\n bits += this.leftPad(byteIndex.toString(2), 5, '0');\n }\n for (let i = 0; i + 4 <= bits.length; i += 4) {\n const chunk = bits.substr(i, 4);\n hex = hex + parseInt(chunk, 2).toString(16);\n }\n return hex;\n }\n\n private b32ToBytes(s: string): Uint8Array {\n return Utils.fromHexToArray(this.b32ToHex(s));\n }\n\n private async sign(keyBytes: Uint8Array, timeBytes: Uint8Array, alg: 'sha1' | 'sha256' | 'sha512') {\n const signature = await this.cryptoFunctionService.hmac(timeBytes.buffer, keyBytes.buffer, alg);\n return new Uint8Array(signature);\n }\n}\n","import { StorageService } from '../abstractions/storage.service';\nimport { TokenService } from '../abstractions/token.service';\nimport { UserService as UserServiceAbstraction } from '../abstractions/user.service';\n\nimport { OrganizationData } from '../models/data/organizationData';\nimport { Organization } from '../models/domain/organization';\n\nimport { KdfType } from '../enums/kdfType';\n\nimport { ProviderData } from '../models/data/providerData';\nimport { Provider } from '../models/domain/provider';\n\nconst Keys = {\n userId: 'userId',\n userEmail: 'userEmail',\n stamp: 'securityStamp',\n kdf: 'kdf',\n kdfIterations: 'kdfIterations',\n organizationsPrefix: 'organizations_',\n providersPrefix: 'providers_',\n emailVerified: 'emailVerified',\n forcePasswordReset: 'forcePasswordReset',\n};\n\nexport class UserService implements UserServiceAbstraction {\n private userId: string;\n private email: string;\n private stamp: string;\n private kdf: KdfType;\n private kdfIterations: number;\n private emailVerified: boolean;\n private forcePasswordReset: boolean;\n\n constructor(private tokenService: TokenService, private storageService: StorageService) { }\n\n async setInformation(userId: string, email: string, kdf: KdfType, kdfIterations: number): Promise {\n this.email = email;\n this.userId = userId;\n this.kdf = kdf;\n this.kdfIterations = kdfIterations;\n\n await this.storageService.save(Keys.userEmail, email);\n await this.storageService.save(Keys.userId, userId);\n await this.storageService.save(Keys.kdf, kdf);\n await this.storageService.save(Keys.kdfIterations, kdfIterations);\n }\n\n setSecurityStamp(stamp: string): Promise {\n this.stamp = stamp;\n return this.storageService.save(Keys.stamp, stamp);\n }\n\n setEmailVerified(emailVerified: boolean) {\n this.emailVerified = emailVerified;\n return this.storageService.save(Keys.emailVerified, emailVerified);\n }\n\n setForcePasswordReset(forcePasswordReset: boolean) {\n this.forcePasswordReset = forcePasswordReset;\n return this.storageService.save(Keys.forcePasswordReset, forcePasswordReset);\n }\n\n async getUserId(): Promise {\n if (this.userId == null) {\n this.userId = await this.storageService.get(Keys.userId);\n }\n return this.userId;\n }\n\n async getEmail(): Promise {\n if (this.email == null) {\n this.email = await this.storageService.get(Keys.userEmail);\n }\n return this.email;\n }\n\n async getSecurityStamp(): Promise {\n if (this.stamp == null) {\n this.stamp = await this.storageService.get(Keys.stamp);\n }\n return this.stamp;\n }\n\n async getKdf(): Promise {\n if (this.kdf == null) {\n this.kdf = await this.storageService.get(Keys.kdf);\n }\n return this.kdf;\n }\n\n async getKdfIterations(): Promise {\n if (this.kdfIterations == null) {\n this.kdfIterations = await this.storageService.get(Keys.kdfIterations);\n }\n return this.kdfIterations;\n }\n\n async getEmailVerified(): Promise {\n if (this.emailVerified == null) {\n this.emailVerified = await this.storageService.get(Keys.emailVerified);\n }\n return this.emailVerified;\n }\n\n async getForcePasswordReset(): Promise {\n if (this.forcePasswordReset == null) {\n this.forcePasswordReset = await this.storageService.get(Keys.forcePasswordReset);\n }\n return this.forcePasswordReset;\n }\n\n async clear(): Promise {\n const userId = await this.getUserId();\n\n await this.storageService.remove(Keys.userId);\n await this.storageService.remove(Keys.userEmail);\n await this.storageService.remove(Keys.stamp);\n await this.storageService.remove(Keys.kdf);\n await this.storageService.remove(Keys.kdfIterations);\n await this.storageService.remove(Keys.forcePasswordReset);\n await this.clearOrganizations(userId);\n await this.clearProviders(userId);\n\n this.userId = this.email = this.stamp = null;\n this.kdf = null;\n this.kdfIterations = null;\n }\n\n async isAuthenticated(): Promise {\n const token = await this.tokenService.getToken();\n if (token == null) {\n return false;\n }\n\n const userId = await this.getUserId();\n return userId != null;\n }\n\n async canAccessPremium(): Promise {\n const authed = await this.isAuthenticated();\n if (!authed) {\n return false;\n }\n\n const tokenPremium = this.tokenService.getPremium();\n if (tokenPremium) {\n return true;\n }\n\n const orgs = await this.getAllOrganizations();\n for (let i = 0; i < orgs.length; i++) {\n if (orgs[i].usersGetPremium && orgs[i].enabled) {\n return true;\n }\n }\n return false;\n }\n\n async canManageSponsorships(): Promise {\n const orgs = await this.getAllOrganizations();\n return orgs.some(o => o.familySponsorshipAvailable || o.familySponsorshipFriendlyName !== null);\n }\n\n async getOrganization(id: string): Promise {\n const userId = await this.getUserId();\n const organizations = await this.storageService.get<{ [id: string]: OrganizationData; }>(\n Keys.organizationsPrefix + userId);\n if (organizations == null || !organizations.hasOwnProperty(id)) {\n return null;\n }\n\n return new Organization(organizations[id]);\n }\n\n async getOrganizationByIdentifier(identifier: string): Promise {\n const organizations = await this.getAllOrganizations();\n if (organizations == null || organizations.length === 0) {\n return null;\n }\n\n return organizations.find(o => o.identifier === identifier);\n }\n\n async getAllOrganizations(): Promise {\n const userId = await this.getUserId();\n const organizations = await this.storageService.get<{ [id: string]: OrganizationData; }>(\n Keys.organizationsPrefix + userId);\n const response: Organization[] = [];\n for (const id in organizations) {\n if (organizations.hasOwnProperty(id) && !organizations[id].isProviderUser) {\n response.push(new Organization(organizations[id]));\n }\n }\n return response;\n }\n\n async replaceOrganizations(organizations: { [id: string]: OrganizationData; }): Promise {\n const userId = await this.getUserId();\n await this.storageService.save(Keys.organizationsPrefix + userId, organizations);\n }\n\n async clearOrganizations(userId: string): Promise {\n await this.storageService.remove(Keys.organizationsPrefix + userId);\n }\n\n async getProvider(id: string): Promise {\n const userId = await this.getUserId();\n const providers = await this.storageService.get<{ [id: string]: ProviderData; }>(\n Keys.providersPrefix + userId);\n if (providers == null || !providers.hasOwnProperty(id)) {\n return null;\n }\n\n return new Provider(providers[id]);\n }\n\n async getAllProviders(): Promise {\n const userId = await this.getUserId();\n const providers = await this.storageService.get<{ [id: string]: ProviderData; }>(\n Keys.providersPrefix + userId);\n const response: Provider[] = [];\n for (const id in providers) {\n if (providers.hasOwnProperty(id)) {\n response.push(new Provider(providers[id]));\n }\n }\n return response;\n }\n\n async replaceProviders(providers: { [id: string]: ProviderData; }): Promise {\n const userId = await this.getUserId();\n await this.storageService.save(Keys.providersPrefix + userId, providers);\n }\n\n async clearProviders(userId: string): Promise {\n await this.storageService.remove(Keys.providersPrefix + userId);\n }\n}\n","import { ProviderUserStatusType } from '../../enums/providerUserStatusType';\nimport { ProviderUserType } from '../../enums/providerUserType';\nimport { ProviderData } from '../data/providerData';\n\nexport class Provider {\n id: string;\n name: string;\n status: ProviderUserStatusType;\n type: ProviderUserType;\n enabled: boolean;\n userId: string;\n useEvents: boolean;\n\n constructor(obj?: ProviderData) {\n if (obj == null) {\n return;\n }\n\n this.id = obj.id;\n this.name = obj.name;\n this.status = obj.status;\n this.type = obj.type;\n this.enabled = obj.enabled;\n this.userId = obj.userId;\n this.useEvents = obj.useEvents;\n }\n\n get canAccess() {\n if (this.isProviderAdmin) {\n return true;\n }\n return this.enabled && this.status === ProviderUserStatusType.Confirmed;\n }\n\n get canCreateOrganizations() {\n return this.enabled && this.isProviderAdmin;\n }\n\n get canManageUsers() {\n return this.isProviderAdmin;\n }\n\n get canAccessEventLogs() {\n return this.isProviderAdmin;\n }\n\n get isProviderAdmin() {\n return this.type === ProviderUserType.ProviderAdmin;\n }\n}\n","import { UserVerificationService as UserVerificationServiceAbstraction } from '../abstractions/userVerification.service';\n\nimport { ApiService } from '../abstractions/api.service';\nimport { CryptoService } from '../abstractions/crypto.service';\nimport { I18nService } from '../abstractions/i18n.service';\n\nimport { VerificationType } from '../enums/verificationType';\n\nimport { VerifyOTPRequest } from '../models/request/account/verifyOTPRequest';\nimport { SecretVerificationRequest } from '../models/request/secretVerificationRequest';\n\nimport { Verification } from '../types/verification';\n\nexport class UserVerificationService implements UserVerificationServiceAbstraction {\n constructor(private cryptoService: CryptoService, private i18nService: I18nService,\n private apiService: ApiService) { }\n\n async buildRequest(verification: Verification,\n requestClass?: new () => T, alreadyHashed?: boolean) {\n this.validateInput(verification);\n\n const request = requestClass != null\n ? new requestClass()\n : new SecretVerificationRequest() as T;\n\n if (verification.type === VerificationType.OTP) {\n request.otp = verification.secret;\n } else {\n request.masterPasswordHash = alreadyHashed\n ? verification.secret\n : await this.cryptoService.hashPassword(verification.secret, null);\n }\n\n return request;\n }\n\n async verifyUser(verification: Verification): Promise {\n this.validateInput(verification);\n\n if (verification.type === VerificationType.OTP) {\n const request = new VerifyOTPRequest(verification.secret);\n try {\n await this.apiService.postAccountVerifyOTP(request);\n } catch (e) {\n throw new Error(this.i18nService.t('invalidVerificationCode'));\n }\n } else {\n const passwordValid = await this.cryptoService.compareAndUpdateKeyHash(verification.secret, null);\n if (!passwordValid) {\n throw new Error(this.i18nService.t('invalidMasterPassword'));\n }\n }\n return true;\n }\n\n async requestOTP() {\n await this.apiService.postAccountRequestOTP();\n }\n\n private validateInput(verification: Verification) {\n if (verification?.secret == null || verification.secret === '') {\n if (verification.type === VerificationType.OTP) {\n throw new Error(this.i18nService.t('verificationCodeRequired'));\n } else {\n throw new Error(this.i18nService.t('masterPassRequired'));\n }\n }\n }\n}\n","export class VerifyOTPRequest {\n OTP: string;\n\n constructor(OTP: string) {\n this.OTP = OTP;\n }\n}\n","import { ConstantsService } from './constants.service';\n\nimport { CipherService } from '../abstractions/cipher.service';\nimport { CollectionService } from '../abstractions/collection.service';\nimport { CryptoService } from '../abstractions/crypto.service';\nimport { FolderService } from '../abstractions/folder.service';\nimport { KeyConnectorService } from '../abstractions/keyConnector.service';\nimport { MessagingService } from '../abstractions/messaging.service';\nimport { PlatformUtilsService } from '../abstractions/platformUtils.service';\nimport { PolicyService } from '../abstractions/policy.service';\nimport { SearchService } from '../abstractions/search.service';\nimport { StorageService } from '../abstractions/storage.service';\nimport { TokenService } from '../abstractions/token.service';\nimport { UserService } from '../abstractions/user.service';\nimport { VaultTimeoutService as VaultTimeoutServiceAbstraction } from '../abstractions/vaultTimeout.service';\n\nimport { PolicyType } from '../enums/policyType';\nimport { EncString } from '../models/domain/encString';\n\nexport class VaultTimeoutService implements VaultTimeoutServiceAbstraction {\n pinProtectedKey: EncString = null;\n biometricLocked: boolean = true;\n everBeenUnlocked: boolean = false;\n\n private inited = false;\n\n constructor(private cipherService: CipherService, private folderService: FolderService,\n private collectionService: CollectionService, private cryptoService: CryptoService,\n protected platformUtilsService: PlatformUtilsService, private storageService: StorageService,\n private messagingService: MessagingService, private searchService: SearchService,\n private userService: UserService, private tokenService: TokenService, private policyService: PolicyService,\n private keyConnectorService: KeyConnectorService,\n private lockedCallback: () => Promise = null, private loggedOutCallback: () => Promise = null) {\n }\n\n init(checkOnInterval: boolean) {\n if (this.inited) {\n return;\n }\n\n this.inited = true;\n if (checkOnInterval) {\n this.startCheck();\n }\n }\n\n startCheck() {\n this.checkVaultTimeout();\n setInterval(() => this.checkVaultTimeout(), 10 * 1000); // check every 10 seconds\n }\n\n // Keys aren't stored for a device that is locked or logged out.\n async isLocked(): Promise {\n // Handle never lock startup situation\n if (await this.cryptoService.hasKeyStored('auto') && !this.everBeenUnlocked) {\n await this.cryptoService.getKey('auto');\n }\n\n return !this.cryptoService.hasKeyInMemory();\n }\n\n async checkVaultTimeout(): Promise {\n if (await this.platformUtilsService.isViewOpen()) {\n // Do not lock\n return;\n }\n\n // \"is logged out check\" - similar to isLocked, below\n const authed = await this.userService.isAuthenticated();\n if (!authed) {\n return;\n }\n\n if (await this.isLocked()) {\n return;\n }\n\n const vaultTimeout = await this.getVaultTimeout();\n if (vaultTimeout == null || vaultTimeout < 0) {\n return;\n }\n\n const lastActive = await this.storageService.get(ConstantsService.lastActiveKey);\n if (lastActive == null) {\n return;\n }\n\n const vaultTimeoutSeconds = vaultTimeout * 60;\n const diffSeconds = ((new Date()).getTime() - lastActive) / 1000;\n if (diffSeconds >= vaultTimeoutSeconds) {\n // Pivot based on the saved vault timeout action\n const timeoutAction = await this.storageService.get(ConstantsService.vaultTimeoutActionKey);\n timeoutAction === 'logOut' ? await this.logOut() : await this.lock(true);\n }\n }\n\n async lock(allowSoftLock = false): Promise {\n const authed = await this.userService.isAuthenticated();\n if (!authed) {\n return;\n }\n\n if (await this.keyConnectorService.getUsesKeyConnector()) {\n const pinSet = await this.isPinLockSet();\n const pinLock = (pinSet[0] && this.pinProtectedKey != null) || pinSet[1];\n\n if (!pinLock && !await this.isBiometricLockSet()) {\n await this.logOut();\n }\n }\n\n this.biometricLocked = true;\n this.everBeenUnlocked = true;\n await this.cryptoService.clearKey(false);\n await this.cryptoService.clearOrgKeys(true);\n await this.cryptoService.clearKeyPair(true);\n await this.cryptoService.clearEncKey(true);\n\n this.folderService.clearCache();\n this.cipherService.clearCache();\n this.collectionService.clearCache();\n this.searchService.clearIndex();\n this.messagingService.send('locked');\n if (this.lockedCallback != null) {\n await this.lockedCallback();\n }\n }\n\n async logOut(): Promise {\n if (this.loggedOutCallback != null) {\n await this.loggedOutCallback();\n }\n }\n\n async setVaultTimeoutOptions(timeout: number, action: string): Promise {\n await this.storageService.save(ConstantsService.vaultTimeoutKey, timeout);\n await this.storageService.save(ConstantsService.vaultTimeoutActionKey, action);\n await this.cryptoService.toggleKey();\n await this.tokenService.toggleTokens();\n }\n\n async isPinLockSet(): Promise<[boolean, boolean]> {\n const protectedPin = await this.storageService.get(ConstantsService.protectedPin);\n const pinProtectedKey = await this.storageService.get(ConstantsService.pinProtectedKey);\n return [protectedPin != null, pinProtectedKey != null];\n }\n\n async isBiometricLockSet(): Promise {\n return await this.storageService.get(ConstantsService.biometricUnlockKey);\n }\n\n async getVaultTimeout(): Promise {\n const vaultTimeout = await this.storageService.get(ConstantsService.vaultTimeoutKey);\n\n if (await this.policyService.policyAppliesToUser(PolicyType.MaximumVaultTimeout)) {\n const policy = await this.policyService.getAll(PolicyType.MaximumVaultTimeout);\n // Remove negative values, and ensure it's smaller than maximum allowed value according to policy\n let timeout = Math.min(vaultTimeout, policy[0].data.minutes);\n\n if (vaultTimeout == null || timeout < 0) {\n timeout = policy[0].data.minutes;\n }\n\n // We really shouldn't need to set the value here, but multiple services relies on this value being correct.\n if (vaultTimeout !== timeout) {\n await this.storageService.save(ConstantsService.vaultTimeoutKey, timeout);\n }\n\n return timeout;\n }\n\n return vaultTimeout;\n }\n\n clear(): Promise {\n this.everBeenUnlocked = false;\n this.pinProtectedKey = null;\n return this.storageService.remove(ConstantsService.protectedPin);\n }\n}\n","import * as forge from 'node-forge';\n\nimport { CryptoFunctionService } from '../abstractions/cryptoFunction.service';\nimport { PlatformUtilsService } from '../abstractions/platformUtils.service';\n\nimport { Utils } from '../misc/utils';\n\nimport { DecryptParameters } from '../models/domain/decryptParameters';\nimport { SymmetricCryptoKey } from '../models/domain/symmetricCryptoKey';\n\nexport class WebCryptoFunctionService implements CryptoFunctionService {\n private crypto: Crypto;\n private subtle: SubtleCrypto;\n private isIE: boolean;\n private isOldSafari: boolean;\n\n constructor(private win: Window, private platformUtilsService: PlatformUtilsService) {\n this.crypto = typeof win.crypto !== 'undefined' ? win.crypto : null;\n this.subtle = (!!this.crypto && typeof win.crypto.subtle !== 'undefined') ? win.crypto.subtle : null;\n this.isIE = platformUtilsService.isIE();\n const ua = win.navigator.userAgent;\n this.isOldSafari = platformUtilsService.isSafari() &&\n (ua.indexOf(' Version/10.') > -1 || ua.indexOf(' Version/9.') > -1);\n }\n\n async pbkdf2(password: string | ArrayBuffer, salt: string | ArrayBuffer, algorithm: 'sha256' | 'sha512',\n iterations: number): Promise {\n if (this.isIE || this.isOldSafari) {\n const forgeLen = algorithm === 'sha256' ? 32 : 64;\n const passwordBytes = this.toByteString(password);\n const saltBytes = this.toByteString(salt);\n const derivedKeyBytes = (forge as any).pbkdf2(passwordBytes, saltBytes, iterations, forgeLen, algorithm);\n return Utils.fromByteStringToArray(derivedKeyBytes).buffer;\n }\n\n const wcLen = algorithm === 'sha256' ? 256 : 512;\n const passwordBuf = this.toBuf(password);\n const saltBuf = this.toBuf(salt);\n\n const pbkdf2Params: Pbkdf2Params = {\n name: 'PBKDF2',\n salt: saltBuf,\n iterations: iterations,\n hash: { name: this.toWebCryptoAlgorithm(algorithm) },\n };\n\n const impKey = await this.subtle.importKey('raw', passwordBuf, { name: 'PBKDF2' } as any,\n false, ['deriveBits']);\n return await this.subtle.deriveBits(pbkdf2Params, impKey, wcLen);\n }\n\n async hkdf(ikm: ArrayBuffer, salt: string | ArrayBuffer, info: string | ArrayBuffer,\n outputByteSize: number, algorithm: 'sha256' | 'sha512'): Promise {\n const saltBuf = this.toBuf(salt);\n const infoBuf = this.toBuf(info);\n\n const hkdfParams: HkdfParams = {\n name: 'HKDF',\n salt: saltBuf,\n info: infoBuf,\n hash: { name: this.toWebCryptoAlgorithm(algorithm) },\n };\n\n const impKey = await this.subtle.importKey('raw', ikm, { name: 'HKDF' } as any,\n false, ['deriveBits']);\n return await this.subtle.deriveBits(hkdfParams as any, impKey, outputByteSize * 8);\n }\n\n // ref: https://tools.ietf.org/html/rfc5869\n async hkdfExpand(prk: ArrayBuffer, info: string | ArrayBuffer, outputByteSize: number,\n algorithm: 'sha256' | 'sha512'): Promise {\n const hashLen = algorithm === 'sha256' ? 32 : 64;\n if (outputByteSize > 255 * hashLen) {\n throw new Error('outputByteSize is too large.');\n }\n const prkArr = new Uint8Array(prk);\n if (prkArr.length < hashLen) {\n throw new Error('prk is too small.');\n }\n const infoBuf = this.toBuf(info);\n const infoArr = new Uint8Array(infoBuf);\n let runningOkmLength = 0;\n let previousT = new Uint8Array(0);\n const n = Math.ceil(outputByteSize / hashLen);\n const okm = new Uint8Array(n * hashLen);\n for (let i = 0; i < n; i++) {\n const t = new Uint8Array(previousT.length + infoArr.length + 1);\n t.set(previousT);\n t.set(infoArr, previousT.length);\n t.set([i + 1], t.length - 1);\n previousT = new Uint8Array(await this.hmac(t.buffer, prk, algorithm));\n okm.set(previousT, runningOkmLength);\n runningOkmLength += previousT.length;\n if (runningOkmLength >= outputByteSize) {\n break;\n }\n }\n return okm.slice(0, outputByteSize).buffer;\n }\n\n async hash(value: string | ArrayBuffer, algorithm: 'sha1' | 'sha256' | 'sha512' | 'md5'): Promise {\n if ((this.isIE && algorithm === 'sha1') || algorithm === 'md5') {\n const md = algorithm === 'md5' ? forge.md.md5.create() : forge.md.sha1.create();\n const valueBytes = this.toByteString(value);\n md.update(valueBytes, 'raw');\n return Utils.fromByteStringToArray(md.digest().data).buffer;\n }\n\n const valueBuf = this.toBuf(value);\n return await this.subtle.digest({ name: this.toWebCryptoAlgorithm(algorithm) }, valueBuf);\n }\n\n async hmac(value: ArrayBuffer, key: ArrayBuffer, algorithm: 'sha1' | 'sha256' | 'sha512'): Promise {\n if (this.isIE && algorithm === 'sha512') {\n const hmac = (forge as any).hmac.create();\n const keyBytes = this.toByteString(key);\n const valueBytes = this.toByteString(value);\n hmac.start(algorithm, keyBytes);\n hmac.update(valueBytes, 'raw');\n return Utils.fromByteStringToArray(hmac.digest().data).buffer;\n }\n\n const signingAlgorithm = {\n name: 'HMAC',\n hash: { name: this.toWebCryptoAlgorithm(algorithm) },\n };\n\n const impKey = await this.subtle.importKey('raw', key, signingAlgorithm, false, ['sign']);\n return await this.subtle.sign(signingAlgorithm, impKey, value);\n }\n\n // Safely compare two values in a way that protects against timing attacks (Double HMAC Verification).\n // ref: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/\n // ref: https://paragonie.com/blog/2015/11/preventing-timing-attacks-on-string-comparison-with-double-hmac-strategy\n async compare(a: ArrayBuffer, b: ArrayBuffer): Promise {\n const macKey = await this.randomBytes(32);\n const signingAlgorithm = {\n name: 'HMAC',\n hash: { name: 'SHA-256' },\n };\n const impKey = await this.subtle.importKey('raw', macKey, signingAlgorithm, false, ['sign']);\n const mac1 = await this.subtle.sign(signingAlgorithm, impKey, a);\n const mac2 = await this.subtle.sign(signingAlgorithm, impKey, b);\n\n if (mac1.byteLength !== mac2.byteLength) {\n return false;\n }\n\n const arr1 = new Uint8Array(mac1);\n const arr2 = new Uint8Array(mac2);\n for (let i = 0; i < arr2.length; i++) {\n if (arr1[i] !== arr2[i]) {\n return false;\n }\n }\n\n return true;\n }\n\n hmacFast(value: string, key: string, algorithm: 'sha1' | 'sha256' | 'sha512'): Promise {\n const hmac = (forge as any).hmac.create();\n hmac.start(algorithm, key);\n hmac.update(value);\n const bytes = hmac.digest().getBytes();\n return Promise.resolve(bytes);\n }\n\n async compareFast(a: string, b: string): Promise {\n const rand = await this.randomBytes(32);\n const bytes = new Uint32Array(rand);\n const buffer = forge.util.createBuffer();\n for (let i = 0; i < bytes.length; i++) {\n buffer.putInt32(bytes[i]);\n }\n const macKey = buffer.getBytes();\n\n const hmac = (forge as any).hmac.create();\n hmac.start('sha256', macKey);\n hmac.update(a);\n const mac1 = hmac.digest().getBytes();\n\n hmac.start(null, null);\n hmac.update(b);\n const mac2 = hmac.digest().getBytes();\n\n const equals = mac1 === mac2;\n return equals;\n }\n\n async aesEncrypt(data: ArrayBuffer, iv: ArrayBuffer, key: ArrayBuffer): Promise {\n const impKey = await this.subtle.importKey('raw', key, { name: 'AES-CBC' } as any, false, ['encrypt']);\n return await this.subtle.encrypt({ name: 'AES-CBC', iv: iv }, impKey, data);\n }\n\n aesDecryptFastParameters(data: string, iv: string, mac: string, key: SymmetricCryptoKey):\n DecryptParameters {\n const p = new DecryptParameters();\n if (key.meta != null) {\n p.encKey = key.meta.encKeyByteString;\n p.macKey = key.meta.macKeyByteString;\n }\n\n if (p.encKey == null) {\n p.encKey = forge.util.decode64(key.encKeyB64);\n }\n p.data = forge.util.decode64(data);\n p.iv = forge.util.decode64(iv);\n p.macData = p.iv + p.data;\n if (p.macKey == null && key.macKeyB64 != null) {\n p.macKey = forge.util.decode64(key.macKeyB64);\n }\n if (mac != null) {\n p.mac = forge.util.decode64(mac);\n }\n\n // cache byte string keys for later\n if (key.meta == null) {\n key.meta = {};\n }\n if (key.meta.encKeyByteString == null) {\n key.meta.encKeyByteString = p.encKey;\n }\n if (p.macKey != null && key.meta.macKeyByteString == null) {\n key.meta.macKeyByteString = p.macKey;\n }\n\n return p;\n }\n\n aesDecryptFast(parameters: DecryptParameters): Promise {\n const dataBuffer = (forge as any).util.createBuffer(parameters.data);\n const decipher = (forge as any).cipher.createDecipher('AES-CBC', parameters.encKey);\n decipher.start({ iv: parameters.iv });\n decipher.update(dataBuffer);\n decipher.finish();\n const val = decipher.output.toString('utf8');\n return Promise.resolve(val);\n }\n\n async aesDecrypt(data: ArrayBuffer, iv: ArrayBuffer, key: ArrayBuffer): Promise {\n const impKey = await this.subtle.importKey('raw', key, { name: 'AES-CBC' } as any, false, ['decrypt']);\n return await this.subtle.decrypt({ name: 'AES-CBC', iv: iv }, impKey, data);\n }\n\n async rsaEncrypt(data: ArrayBuffer, publicKey: ArrayBuffer, algorithm: 'sha1' | 'sha256'): Promise {\n // Note: Edge browser requires that we specify name and hash for both key import and decrypt.\n // We cannot use the proper types here.\n const rsaParams = {\n name: 'RSA-OAEP',\n hash: { name: this.toWebCryptoAlgorithm(algorithm) },\n };\n const impKey = await this.subtle.importKey('spki', publicKey, rsaParams, false, ['encrypt']);\n return await this.subtle.encrypt(rsaParams, impKey, data);\n }\n\n async rsaDecrypt(data: ArrayBuffer, privateKey: ArrayBuffer, algorithm: 'sha1' | 'sha256'): Promise {\n // Note: Edge browser requires that we specify name and hash for both key import and decrypt.\n // We cannot use the proper types here.\n const rsaParams = {\n name: 'RSA-OAEP',\n hash: { name: this.toWebCryptoAlgorithm(algorithm) },\n };\n const impKey = await this.subtle.importKey('pkcs8', privateKey, rsaParams, false, ['decrypt']);\n return await this.subtle.decrypt(rsaParams, impKey, data);\n }\n\n async rsaExtractPublicKey(privateKey: ArrayBuffer): Promise {\n const rsaParams = {\n name: 'RSA-OAEP',\n // Have to specify some algorithm\n hash: { name: this.toWebCryptoAlgorithm('sha1') },\n };\n const impPrivateKey = await this.subtle.importKey('pkcs8', privateKey, rsaParams, true, ['decrypt']);\n const jwkPrivateKey = await this.subtle.exportKey('jwk', impPrivateKey);\n const jwkPublicKeyParams = {\n kty: 'RSA',\n e: jwkPrivateKey.e,\n n: jwkPrivateKey.n,\n alg: 'RSA-OAEP',\n ext: true,\n };\n const impPublicKey = await this.subtle.importKey('jwk', jwkPublicKeyParams, rsaParams, true, ['encrypt']);\n return await this.subtle.exportKey('spki', impPublicKey);\n }\n\n async rsaGenerateKeyPair(length: 1024 | 2048 | 4096): Promise<[ArrayBuffer, ArrayBuffer]> {\n const rsaParams = {\n name: 'RSA-OAEP',\n modulusLength: length,\n publicExponent: new Uint8Array([0x01, 0x00, 0x01]), // 65537\n // Have to specify some algorithm\n hash: { name: this.toWebCryptoAlgorithm('sha1') },\n };\n const keyPair = (await this.subtle.generateKey(rsaParams, true, ['encrypt', 'decrypt'])) as CryptoKeyPair;\n const publicKey = await this.subtle.exportKey('spki', keyPair.publicKey);\n const privateKey = await this.subtle.exportKey('pkcs8', keyPair.privateKey);\n return [publicKey, privateKey];\n }\n\n randomBytes(length: number): Promise {\n const arr = new Uint8Array(length);\n this.crypto.getRandomValues(arr);\n return Promise.resolve(arr.buffer);\n }\n\n private toBuf(value: string | ArrayBuffer): ArrayBuffer {\n let buf: ArrayBuffer;\n if (typeof (value) === 'string') {\n buf = Utils.fromUtf8ToArray(value).buffer;\n } else {\n buf = value;\n }\n return buf;\n }\n\n private toByteString(value: string | ArrayBuffer): string {\n let bytes: string;\n if (typeof (value) === 'string') {\n bytes = forge.util.encodeUtf8(value);\n } else {\n bytes = Utils.fromBufferToByteString(value);\n }\n return bytes;\n }\n\n private toWebCryptoAlgorithm(algorithm: 'sha1' | 'sha256' | 'sha512' | 'md5'): string {\n if (algorithm === 'md5') {\n throw new Error('MD5 is not supported in WebCrypto.');\n }\n return algorithm === 'sha1' ? 'SHA-1' : algorithm === 'sha256' ? 'SHA-256' : 'SHA-512';\n }\n}\n","export class DecryptParameters {\n encKey: T;\n data: T;\n iv: T;\n macKey: T;\n mac: T;\n macData: T;\n}\n","import { EncArrayBuffer } from '../models/domain/encArrayBuffer';\nimport { EncString } from '../models/domain/encString';\nimport { AttachmentUploadDataResponse } from '../models/response/attachmentUploadDataResponse';\nimport { SendFileUploadDataResponse } from '../models/response/sendFileUploadDataResponse';\n\nexport abstract class FileUploadService {\n uploadSendFile: (uploadData: SendFileUploadDataResponse, fileName: EncString,\n encryptedFileData: EncArrayBuffer) => Promise;\n uploadCipherAttachment: (admin: boolean, uploadData: AttachmentUploadDataResponse, fileName: EncString,\n encryptedFileData: EncArrayBuffer) => Promise;\n}\n","import {\n ApplicationRef,\n ComponentFactoryResolver,\n Injectable,\n Injector,\n} from '@angular/core';\nimport * as jq from 'jquery';\nimport { first } from 'rxjs/operators';\n\nimport { MessagingService } from 'jslib-common/abstractions/messaging.service';\n\nimport { ModalRef } from 'jslib-angular/components/modal/modal.ref';\nimport { ModalService as BaseModalService } from 'jslib-angular/services/modal.service';\n\nimport { Utils } from 'jslib-common/misc/utils';\n\n@Injectable()\nexport class ModalService extends BaseModalService {\n el: any = null;\n modalOpen: boolean = false;\n\n constructor(componentFactoryResolver: ComponentFactoryResolver, applicationRef: ApplicationRef,\n injector: Injector, private messagingService: MessagingService) {\n super(componentFactoryResolver, applicationRef, injector);\n }\n\n protected setupHandlers(modalRef: ModalRef) {\n modalRef.onCreated.pipe(first()).subscribe(() => {\n const modals = Array.from(document.querySelectorAll('.modal'));\n if (modals.length > 0) {\n this.el = jq(modals[0]);\n this.el.modal('show');\n\n this.el.on('show.bs.modal', () => {\n modalRef.show();\n this.messagingService.send('modalShow');\n });\n this.el.on('shown.bs.modal', () => {\n modalRef.shown();\n this.messagingService.send('modalShown');\n if (!Utils.isMobileBrowser) {\n this.el.find('*[appAutoFocus]').focus();\n }\n });\n this.el.on('hide.bs.modal', () => {\n this.messagingService.send('modalClose');\n });\n this.el.on('hidden.bs.modal', () => {\n modalRef.closed();\n this.messagingService.send('modalClosed');\n });\n }\n });\n\n modalRef.onClose.pipe(first()).subscribe(() => {\n if (this.el != null) {\n this.el.modal('hide');\n }\n });\n }\n}\n","import { NgModule } from '@angular/core';\nimport { RouterModule, Routes } from '@angular/router';\n\nconst routes: Routes = [\n { path: '**', redirectTo: '' },\n];\n\n@NgModule({\n imports: [RouterModule.forChild(routes)],\n exports: [RouterModule],\n})\nexport class WildcardRoutingModule { }\n"],"sourceRoot":""} \ No newline at end of file diff --git a/app/polyfills.656f1dffa218e8467958.js b/app/polyfills.656f1dffa218e8467958.js new file mode 100644 index 00000000..7eba52cc --- /dev/null +++ b/app/polyfills.656f1dffa218e8467958.js @@ -0,0 +1,3 @@ +/*! For license information please see polyfills.656f1dffa218e8467958.js.LICENSE.txt */ +!function(t){var e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)r.d(n,o,function(e){return t[e]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=741)}([,,,,,,,,,,function(t,e,r){var n=r(35),o=r(94).f,i=r(116),a=r(83),u=r(349),c=r(464),s=r(247);t.exports=function(t,e){var r,f,l,p,h,d=t.target,v=t.global,y=t.stat;if(r=v?n:y?n[d]||u(d,{}):(n[d]||{}).prototype)for(f in e){if(p=e[f],l=t.noTargetGet?(h=o(r,f))&&h.value:r[f],!s(v?f:d+(y?".":"#")+f,t.forced)&&void 0!==l){if(typeof p==typeof l)continue;c(p,l)}(t.sham||l&&l.sham)&&i(p,"sham",!0),a(r,f,p,t)}}},,,,,,,,,,,,,,function(t,e){t.exports=function(t){try{return!!t()}catch(e){return!0}}},,,,,,,,,,,function(t,e,r){(function(e){var r=function(t){return t&&t.Math==Math&&t};t.exports=r("object"==typeof globalThis&&globalThis)||r("object"==typeof window&&window)||r("object"==typeof self&&self)||r("object"==typeof e&&e)||function(){return this}()||Function("return this")()}).call(this,r(97))},,,,,,,,,,,,function(t,e,r){var n=r(60);t.exports=function(t){return"object"==typeof t?null!==t:n(t)}},function(t,e,r){var n=r(47);t.exports=function(t){if(n(t))return t;throw TypeError(String(t)+" is not an object")}},,,function(t,e,r){var n=r(89),o=Math.min;t.exports=function(t){return t>0?o(n(t),9007199254740991):0}},function(t,e,r){var n=r(24);t.exports=!n((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},function(t,e,r){var n=r(35),o=r(279),i=r(76),a=r(244),u=r(346),c=r(460),s=o("wks"),f=n.Symbol,l=c?f:f&&f.withoutSetter||a;t.exports=function(t){return i(s,t)&&(u||"string"==typeof s[t])||(u&&i(f,t)?s[t]=f[t]:s[t]=l("Symbol."+t)),s[t]}},,,,,,function(t,e,r){"use strict";var n,o,i,a=r(362),u=r(52),c=r(35),s=r(60),f=r(47),l=r(76),p=r(197),h=r(347),d=r(116),v=r(83),y=r(66).f,g=r(128),m=r(158),b=r(53),w=r(244),x=c.Int8Array,S=x&&x.prototype,E=c.Uint8ClampedArray,_=E&&E.prototype,k=x&&g(x),T=S&&g(S),A=Object.prototype,O=A.isPrototypeOf,M=b("toStringTag"),j=w("TYPED_ARRAY_TAG"),P=w("TYPED_ARRAY_CONSTRUCTOR"),R=a&&!!m&&"Opera"!==p(c.opera),D=!1,C={Int8Array:1,Uint8Array:1,Uint8ClampedArray:1,Int16Array:2,Uint16Array:2,Int32Array:4,Uint32Array:4,Float32Array:4,Float64Array:8},I={BigInt64Array:8,BigUint64Array:8},L=function(t){if(!f(t))return!1;var e=p(t);return l(C,e)||l(I,e)};for(n in C)(i=(o=c[n])&&o.prototype)?d(i,P,o):R=!1;for(n in I)(i=(o=c[n])&&o.prototype)&&d(i,P,o);if((!R||!s(k)||k===Function.prototype)&&(k=function(){throw TypeError("Incorrect invocation")},R))for(n in C)c[n]&&m(c[n],k);if((!R||!T||T===A)&&(T=k.prototype,R))for(n in C)c[n]&&m(c[n].prototype,T);if(R&&g(_)!==T&&m(_,T),u&&!l(T,M))for(n in D=!0,y(T,M,{get:function(){return f(this)?this[j]:void 0}}),C)c[n]&&d(c[n],j,n);t.exports={NATIVE_ARRAY_BUFFER_VIEWS:R,TYPED_ARRAY_CONSTRUCTOR:P,TYPED_ARRAY_TAG:D&&j,aTypedArray:function(t){if(L(t))return t;throw TypeError("Target is not a typed array")},aTypedArrayConstructor:function(t){if(s(t)&&(!m||O.call(k,t)))return t;throw TypeError(h(t)+" is not a typed array constructor")},exportTypedArrayMethod:function(t,e,r){if(u){if(r)for(var n in C){var o=c[n];if(o&&l(o.prototype,t))try{delete o.prototype[t]}catch(i){}}T[t]&&!r||v(T,t,r?e:R&&S[t]||e)}},exportTypedArrayStaticMethod:function(t,e,r){var n,o;if(u){if(m){if(r)for(n in C)if((o=c[n])&&l(o,t))try{delete o[t]}catch(i){}if(k[t]&&!r)return;try{return v(k,t,r?e:R&&k[t]||e)}catch(i){}}for(n in C)!(o=c[n])||o[t]&&!r||v(o,t,e)}},isView:function(t){if(!f(t))return!1;var e=p(t);return"DataView"===e||l(C,e)||l(I,e)},isTypedArray:L,TypedArray:k,TypedArrayPrototype:T}},function(t,e){t.exports=function(t){return"function"==typeof t}},function(t,e,r){var n=r(197);t.exports=function(t){if("Symbol"===n(t))throw TypeError("Cannot convert a Symbol value to a string");return String(t)}},,,,,function(t,e,r){var n=r(52),o=r(462),i=r(48),a=r(176),u=Object.defineProperty;e.f=n?u:function(t,e,r){if(i(t),e=a(e),i(r),o)try{return u(t,e,r)}catch(n){}if("get"in r||"set"in r)throw TypeError("Accessors not supported");return"value"in r&&(t[e]=r.value),t}},,,function(t,e,r){var n=r(87);t.exports=function(t){return Object(n(t))}},,,,,,,function(t,e,r){var n=r(69),o={}.hasOwnProperty;t.exports=Object.hasOwn||function(t,e){return o.call(n(t),e)}},,,,,,,function(t,e,r){var n=r(35),o=r(60),i=r(76),a=r(116),u=r(349),c=r(281),s=r(88),f=r(195).CONFIGURABLE,l=s.get,p=s.enforce,h=String(String).split("String");(t.exports=function(t,e,r,c){var s,l=!!c&&!!c.unsafe,d=!!c&&!!c.enumerable,v=!!c&&!!c.noTargetGet,y=c&&void 0!==c.name?c.name:e;o(r)&&("Symbol("===String(y).slice(0,7)&&(y="["+String(y).replace(/^Symbol\(([^)]*)\)/,"$1")+"]"),(!i(r,"name")||f&&r.name!==y)&&a(r,"name",y),(s=p(r)).source||(s.source=h.join("string"==typeof y?y:""))),t!==n?(l?!v&&t[e]&&(d=!0):delete t[e],d?t[e]=r:a(t,e,r)):d?t[e]=r:u(e,r)})(Function.prototype,"toString",(function(){return o(this)&&l(this).source||c(this)}))},,,,function(t,e){t.exports=function(t){if(null==t)throw TypeError("Can't call method on "+t);return t}},function(t,e,r){var n,o,i,a=r(463),u=r(35),c=r(47),s=r(116),f=r(76),l=r(348),p=r(282),h=r(245),d="Object already initialized",v=u.WeakMap;if(a||l.state){var y=l.state||(l.state=new v),g=y.get,m=y.has,b=y.set;n=function(t,e){if(m.call(y,t))throw new TypeError(d);return e.facade=t,b.call(y,t,e),e},o=function(t){return g.call(y,t)||{}},i=function(t){return m.call(y,t)}}else{var w=p("state");h[w]=!0,n=function(t,e){if(f(t,w))throw new TypeError(d);return e.facade=t,s(t,w,e),e},o=function(t){return f(t,w)?t[w]:{}},i=function(t){return f(t,w)}}t.exports={set:n,get:o,has:i,enforce:function(t){return i(t)?o(t):n(t,{})},getterFor:function(t){return function(e){var r;if(!c(e)||(r=o(e)).type!==t)throw TypeError("Incompatible receiver, "+t+" required");return r}}}},function(t,e){var r=Math.ceil,n=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?n:r)(t)}},function(t,e,r){var n=r(180),o=r(242),i=r(69),a=r(51),u=r(249),c=[].push,s=function(t){var e=1==t,r=2==t,s=3==t,f=4==t,l=6==t,p=7==t,h=5==t||l;return function(d,v,y,g){for(var m,b,w=i(d),x=o(w),S=n(v,y,3),E=a(x.length),_=0,k=g||u,T=e?k(d,E):r||p?k(d,0):void 0;E>_;_++)if((h||_ in x)&&(b=S(m=x[_],_,w),t))if(e)T[_]=b;else if(b)switch(t){case 3:return!0;case 5:return m;case 6:return _;case 2:c.call(T,m)}else switch(t){case 4:return!1;case 7:c.call(T,m)}return l?-1:s||f?f:T}};t.exports={forEach:s(0),map:s(1),filter:s(2),some:s(3),every:s(4),find:s(5),findIndex:s(6),filterReject:s(7)}},,,,function(t,e,r){var n=r(52),o=r(278),i=r(155),a=r(115),u=r(176),c=r(76),s=r(462),f=Object.getOwnPropertyDescriptor;e.f=n?f:function(t,e){if(t=a(t),e=u(e),s)try{return f(t,e)}catch(r){}if(c(t,e))return i(!o.f.call(t,e),t[e])}},,,function(t,e){var r;r=function(){return this}();try{r=r||new Function("return this")()}catch(n){"object"==typeof window&&(r=window)}t.exports=r},function(t,e,r){var n=r(35),o=r(60),i=function(t){return o(t)?t:void 0};t.exports=function(t,e){return arguments.length<2?i(n[t]):n[t]&&n[t][e]}},function(t,e,r){var n=r(60),o=r(347);t.exports=function(t){if(n(t))return t;throw TypeError(o(t)+" is not a function")}},,,,,,,function(t,e,r){var n=r(468),o=r(76),i=r(467),a=r(66).f;t.exports=function(t){var e=n.Symbol||(n.Symbol={});o(e,t)||a(e,t,{value:i.f(t)})}},,,,,,,,,function(t,e,r){var n=r(242),o=r(87);t.exports=function(t){return n(o(t))}},function(t,e,r){var n=r(52),o=r(66),i=r(155);t.exports=n?function(t,e,r){return o.f(t,e,i(1,r))}:function(t,e,r){return t[e]=r,t}},function(t,e,r){var n=r(87),o=r(61),i=/"/g;t.exports=function(t,e,r,a){var u=o(n(t)),c="<"+e;return""!==r&&(c+=" "+r+'="'+o(a).replace(i,""")+'"'),c+">"+u+""}},function(t,e,r){var n=r(24);t.exports=function(t){return n((function(){var e=""[t]('"');return e!==e.toLowerCase()||e.split('"').length>3}))}},,,,,,,,function(t,e){t.exports=!1},function(t,e,r){var n,o=r(48),i=r(354),a=r(351),u=r(245),c=r(466),s=r(280),f=r(282),l=f("IE_PROTO"),p=function(){},h=function(t){return" \ No newline at end of file +Bitwarden Captcha Connector
\ No newline at end of file diff --git a/captcha-mobile-connector.html b/captcha-mobile-connector.html index 8ffa5a1c..8b65506f 100644 --- a/captcha-mobile-connector.html +++ b/captcha-mobile-connector.html @@ -1 +1 @@ -Bitwarden Captcha Connector

Captcha Required

\ No newline at end of file +Bitwarden Captcha Connector

Captcha Required

\ No newline at end of file diff --git a/connectors/captcha.656f1dffa218e8467958.css b/connectors/captcha.656f1dffa218e8467958.css new file mode 100644 index 00000000..23ca2900 --- /dev/null +++ b/connectors/captcha.656f1dffa218e8467958.css @@ -0,0 +1,98 @@ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 300; + font-display: auto; + src: url(../fonts/Open_Sans-italic-300.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 400; + font-display: auto; + src: url(../fonts/Open_Sans-italic-400.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 600; + font-display: auto; + src: url(../fonts/Open_Sans-italic-600.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 700; + font-display: auto; + src: url(../fonts/Open_Sans-italic-700.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 800; + font-display: auto; + src: url(../fonts/Open_Sans-italic-800.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 300; + font-display: auto; + src: url(../fonts/Open_Sans-normal-300.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + font-display: auto; + src: url(../fonts/Open_Sans-normal-400.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 600; + font-display: auto; + src: url(../fonts/Open_Sans-normal-600.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + font-display: auto; + src: url(../fonts/Open_Sans-normal-700.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 800; + font-display: auto; + src: url(../fonts/Open_Sans-normal-800.woff) format('woff'); + unicode-range: U+0-10FFFF; +} + + +:root{--blue: #007bff;--indigo: #6610f2;--purple: #6f42c1;--pink: #e83e8c;--red: #dc3545;--orange: #fd7e14;--yellow: #ffc107;--green: #28a745;--teal: #20c997;--cyan: #17a2b8;--white: #FFFFFF;--gray: #6c757d;--gray-dark: #343a40;--primary: #175DDC;--secondary: #CED4DA;--success: #00A65A;--info: #555555;--warning: #BF7E16;--danger: #DD4B39;--light: #f8f9fa;--dark: #343a40;--primary-accent: #1252A3;--secondary-alt: #1A3B66;--breakpoint-xs: 0;--breakpoint-sm: 1px;--breakpoint-md: 2px;--breakpoint-lg: 3px;--breakpoint-xl: 4px;--font-family-sans-serif: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}*,*::before,*::after{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#333;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0 !important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-original-title]{text-decoration:underline;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}a{color:#175ddc;text-decoration:none;background-color:transparent}a:hover{color:#104097;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button:not(:disabled),[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled){cursor:pointer}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{padding:0;border-style:none}input[type=radio],input[type=checkbox]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none !important}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}h1,.h1{font-size:1.7rem}h2,.h2{font-size:1.3rem}h3,.h3{font-size:1rem}h4,.h4{font-size:1rem}h5,.h5{font-size:1rem}h6,.h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:normal}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}small,.small{font-size:90%;font-weight:400}mark,.mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:90%;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid,.table td.table-list-icon img{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:100%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:100%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:100%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-xl,.container-lg,.container-md,.container-sm{width:100%;padding-right:10px;padding-left:10px;margin-right:auto;margin-left:auto}@media(min-width: 1px){.container-sm,.container{max-width:540px}}@media(min-width: 2px){.container-md,.container-sm,.container{max-width:720px}}@media(min-width: 3px){.container-lg,.container-md,.container-sm,.container{max-width:960px}}@media(min-width: 4px){.container-xl,.container-lg,.container-md,.container-sm,.container{max-width:1140px}}.row{display:flex;flex-wrap:wrap;margin-right:-10px;margin-left:-10px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col-xl,.col-xl-auto,.col-xl-12,.col-xl-11,.col-xl-10,.col-xl-9,.col-xl-8,.col-xl-7,.col-xl-6,.col-xl-5,.col-xl-4,.col-xl-3,.col-xl-2,.col-xl-1,.col-lg,.col-lg-auto,.col-lg-12,.col-lg-11,.col-lg-10,.col-lg-9,.col-lg-8,.col-lg-7,.col-lg-6,.col-lg-5,.col-lg-4,.col-lg-3,.col-lg-2,.col-lg-1,.col-md,.col-md-auto,.col-md-12,.col-md-11,.col-md-10,.col-md-9,.col-md-8,.col-md-7,.col-md-6,.col-md-5,.col-md-4,.col-md-3,.col-md-2,.col-md-1,.col-sm,.col-sm-auto,.col-sm-12,.col-sm-11,.col-sm-10,.col-sm-9,.col-sm-8,.col-sm-7,.col-sm-6,.col-sm-5,.col-sm-4,.col-sm-3,.col-sm-2,.col-sm-1,.col,.col-auto,.col-12,.col-11,.col-10,.col-9,.col-8,.col-7,.col-6,.col-5,.col-4,.col-3,.col-2,.col-1{position:relative;width:100%;padding-right:10px;padding-left:10px}.col{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}@media(min-width: 1px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-sm-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-sm-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-sm-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-sm-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}}@media(min-width: 2px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-md-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-md-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-md-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-md-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}}@media(min-width: 3px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-lg-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-lg-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-lg-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-lg-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}}@media(min-width: 4px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-xl-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-xl-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-xl-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-xl-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}}.table{width:100%;margin-bottom:1rem;color:#333}.table th,.table td{padding:.75rem;vertical-align:top;border-top:1px solid #ced4da}.table thead th{vertical-align:bottom;border-bottom:2px solid #ced4da}.table tbody+tbody{border-top:2px solid #ced4da}.table-sm th,.table-sm td{padding:.3rem}.table-bordered{border:1px solid #ced4da}.table-bordered th,.table-bordered td{border:1px solid #ced4da}.table-bordered thead th,.table-bordered thead td{border-bottom-width:2px}.table-borderless th,.table-borderless td,.table-borderless thead th,.table-borderless tbody+tbody{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.02)}.table-hover tbody tr:hover{color:#333;background-color:rgba(0,0,0,.03)}.table-primary,.table-primary>th,.table-primary>td{background-color:#bed2f5}.table-primary th,.table-primary td,.table-primary thead th,.table-primary tbody+tbody{border-color:#86abed}.table-hover .table-primary:hover{background-color:#a8c3f2}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#a8c3f2}.table-secondary,.table-secondary>th,.table-secondary>td{background-color:#f1f3f5}.table-secondary th,.table-secondary td,.table-secondary thead th,.table-secondary tbody+tbody{border-color:#e6e9ec}.table-hover .table-secondary:hover{background-color:#e2e6ea}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#e2e6ea}.table-success,.table-success>th,.table-success>td{background-color:#b8e6d1}.table-success th,.table-success td,.table-success thead th,.table-success tbody+tbody{border-color:#7ad1a9}.table-hover .table-success:hover{background-color:#a5dfc5}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#a5dfc5}.table-info,.table-info>th,.table-info>td{background-color:#cfcfcf}.table-info th,.table-info td,.table-info thead th,.table-info tbody+tbody{border-color:#a7a7a7}.table-hover .table-info:hover{background-color:#c2c2c2}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#c2c2c2}.table-warning,.table-warning>th,.table-warning>td{background-color:#eddbbe}.table-warning th,.table-warning td,.table-warning thead th,.table-warning tbody+tbody{border-color:#debc86}.table-hover .table-warning:hover{background-color:#e7d0aa}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#e7d0aa}.table-danger,.table-danger>th,.table-danger>td{background-color:#f5cdc8}.table-danger th,.table-danger td,.table-danger thead th,.table-danger tbody+tbody{border-color:#eda198}.table-hover .table-danger:hover{background-color:#f1b9b2}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b9b2}.table-light,.table-light>th,.table-light>td{background-color:#fdfdfe}.table-light th,.table-light td,.table-light thead th,.table-light tbody+tbody{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>th,.table-dark>td{background-color:#c6c8ca}.table-dark th,.table-dark td,.table-dark thead th,.table-dark tbody+tbody{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-primary-accent,.table-primary-accent>th,.table-primary-accent>td{background-color:#bdcfe5}.table-primary-accent th,.table-primary-accent td,.table-primary-accent thead th,.table-primary-accent tbody+tbody{border-color:#84a5cf}.table-hover .table-primary-accent:hover{background-color:#abc2de}.table-hover .table-primary-accent:hover>td,.table-hover .table-primary-accent:hover>th{background-color:#abc2de}.table-secondary-alt,.table-secondary-alt>th,.table-secondary-alt>td{background-color:#bfc8d4}.table-secondary-alt th,.table-secondary-alt td,.table-secondary-alt thead th,.table-secondary-alt tbody+tbody{border-color:#8899af}.table-hover .table-secondary-alt:hover{background-color:#b0bbca}.table-hover .table-secondary-alt:hover>td,.table-hover .table-secondary-alt:hover>th{background-color:#b0bbca}.table-active,.table-active>th,.table-active>td{background-color:rgba(0,0,0,.03)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.03)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.03)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#ced4da}.table-dark{color:#fff;background-color:#343a40}.table-dark th,.table-dark td,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media(max-width: 0.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media(max-width: 1.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media(max-width: 2.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media(max-width: 3.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + 0.75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fbfbfb;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#81a9f2;outline:0;box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}.form-control::placeholder{color:#b4b4b4;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e0e0e0;opacity:1}input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fbfbfb}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(0.375rem + 1px);padding-bottom:calc(0.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(0.5rem + 1px);padding-bottom:calc(0.5rem + 1px);font-size:1.15rem;line-height:1.5}.col-form-label-sm{padding-top:calc(0.25rem + 1px);padding-bottom:calc(0.25rem + 1px);font-size:0.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#333;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + 0.5rem + 2px);padding:.25rem .5rem;font-size:0.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.15rem;line-height:1.5;border-radius:.3rem}select.form-control[size],select.form-control[multiple]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input[disabled]~.form-check-label,.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:90%;color:#00a65a}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;line-height:1.5;color:#fff;background-color:rgba(0,166,90,.9);border-radius:.25rem}.form-row>.col>.valid-tooltip,.form-row>[class*=col-]>.valid-tooltip{left:5px}.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip,.is-valid~.valid-feedback,.is-valid~.valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#00a65a;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2300A65A' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#00a65a;box-shadow:0 0 0 .2rem rgba(0,166,90,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .custom-select:valid,.custom-select.is-valid{border-color:#00a65a;padding-right:calc(0.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fbfbfb url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2300A65A' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat}.was-validated .custom-select:valid:focus,.custom-select.is-valid:focus{border-color:#00a65a;box-shadow:0 0 0 .2rem rgba(0,166,90,.25)}.was-validated .form-check-input:valid~.form-check-label,.form-check-input.is-valid~.form-check-label{color:#00a65a}.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip,.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip{display:block}.was-validated .custom-control-input:valid~.custom-control-label,.custom-control-input.is-valid~.custom-control-label{color:#00a65a}.was-validated .custom-control-input:valid~.custom-control-label::before,.custom-control-input.is-valid~.custom-control-label::before{border-color:#00a65a}.was-validated .custom-control-input:valid:checked~.custom-control-label::before,.custom-control-input.is-valid:checked~.custom-control-label::before{border-color:#00d976;background-color:#00d976}.was-validated .custom-control-input:valid:focus~.custom-control-label::before,.custom-control-input.is-valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,166,90,.25)}.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before,.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before{border-color:#00a65a}.was-validated .custom-file-input:valid~.custom-file-label,.custom-file-input.is-valid~.custom-file-label{border-color:#00a65a}.was-validated .custom-file-input:valid:focus~.custom-file-label,.custom-file-input.is-valid:focus~.custom-file-label{border-color:#00a65a;box-shadow:0 0 0 .2rem rgba(0,166,90,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:90%;color:#dd4b39}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;line-height:1.5;color:#fff;background-color:rgba(221,75,57,.9);border-radius:.25rem}.form-row>.col>.invalid-tooltip,.form-row>[class*=col-]>.invalid-tooltip{left:5px}.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip,.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#dd4b39;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23DD4B39' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23DD4B39' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#dd4b39;box-shadow:0 0 0 .2rem rgba(221,75,57,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .custom-select:invalid,.custom-select.is-invalid{border-color:#dd4b39;padding-right:calc(0.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fbfbfb url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23DD4B39' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23DD4B39' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat}.was-validated .custom-select:invalid:focus,.custom-select.is-invalid:focus{border-color:#dd4b39;box-shadow:0 0 0 .2rem rgba(221,75,57,.25)}.was-validated .form-check-input:invalid~.form-check-label,.form-check-input.is-invalid~.form-check-label{color:#dd4b39}.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip,.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip{display:block}.was-validated .custom-control-input:invalid~.custom-control-label,.custom-control-input.is-invalid~.custom-control-label{color:#dd4b39}.was-validated .custom-control-input:invalid~.custom-control-label::before,.custom-control-input.is-invalid~.custom-control-label::before{border-color:#dd4b39}.was-validated .custom-control-input:invalid:checked~.custom-control-label::before,.custom-control-input.is-invalid:checked~.custom-control-label::before{border-color:#e47365;background-color:#e47365}.was-validated .custom-control-input:invalid:focus~.custom-control-label::before,.custom-control-input.is-invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(221,75,57,.25)}.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before,.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dd4b39}.was-validated .custom-file-input:invalid~.custom-file-label,.custom-file-input.is-invalid~.custom-file-label{border-color:#dd4b39}.was-validated .custom-file-input:invalid:focus~.custom-file-label,.custom-file-input.is-invalid:focus~.custom-file-label{border-color:#dd4b39;box-shadow:0 0 0 .2rem rgba(221,75,57,.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media(min-width: 1px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn,.swal2-popup .swal2-actions button{display:inline-block;font-weight:600;color:#333;text-align:center;vertical-align:middle;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.btn,.swal2-popup .swal2-actions button{transition:none}}.btn:hover,.swal2-popup .swal2-actions button:hover{color:#333;text-decoration:none}.btn:focus,.swal2-popup .swal2-actions button:focus,.btn.focus,.swal2-popup .swal2-actions button.focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}.btn.disabled,.swal2-popup .swal2-actions button.disabled,.btn:disabled,.swal2-popup .swal2-actions button:disabled{opacity:.65}.btn:not(:disabled):not(.disabled),.swal2-popup .swal2-actions button:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#175ddc;border-color:#175ddc}.btn-primary:hover{color:#fff;background-color:#134eb9;border-color:#1249ae}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#134eb9;border-color:#1249ae;box-shadow:0 0 0 .2rem rgba(58,117,225,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#175ddc;border-color:#175ddc}.btn-primary:not(:disabled):not(.disabled):active,.btn-primary:not(:disabled):not(.disabled).active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#1249ae;border-color:#1145a2}.btn-primary:not(:disabled):not(.disabled):active:focus,.btn-primary:not(:disabled):not(.disabled).active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,117,225,.5)}.btn-secondary{color:#212529;background-color:#ced4da;border-color:#ced4da}.btn-secondary:hover{color:#212529;background-color:#b8c1ca;border-color:#b1bbc4}.btn-secondary:focus,.btn-secondary.focus{color:#212529;background-color:#b8c1ca;border-color:#b1bbc4;box-shadow:0 0 0 .2rem rgba(180,186,191,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#212529;background-color:#ced4da;border-color:#ced4da}.btn-secondary:not(:disabled):not(.disabled):active,.btn-secondary:not(:disabled):not(.disabled).active,.show>.btn-secondary.dropdown-toggle{color:#212529;background-color:#b1bbc4;border-color:#aab4bf}.btn-secondary:not(:disabled):not(.disabled):active:focus,.btn-secondary:not(:disabled):not(.disabled).active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(180,186,191,.5)}.btn-success{color:#fff;background-color:#00a65a;border-color:#00a65a}.btn-success:hover{color:#fff;background-color:#008045;border-color:#00733e}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#008045;border-color:#00733e;box-shadow:0 0 0 .2rem rgba(38,179,115,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#00a65a;border-color:#00a65a}.btn-success:not(:disabled):not(.disabled):active,.btn-success:not(:disabled):not(.disabled).active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#00733e;border-color:#006637}.btn-success:not(:disabled):not(.disabled):active:focus,.btn-success:not(:disabled):not(.disabled).active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,179,115,.5)}.btn-info{color:#fff;background-color:#555;border-color:#555}.btn-info:hover{color:#fff;background-color:#424242;border-color:#3c3c3c}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#424242;border-color:#3c3c3c;box-shadow:0 0 0 .2rem rgba(111,111,111,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#555;border-color:#555}.btn-info:not(:disabled):not(.disabled):active,.btn-info:not(:disabled):not(.disabled).active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#3c3c3c;border-color:#353535}.btn-info:not(:disabled):not(.disabled):active:focus,.btn-info:not(:disabled):not(.disabled).active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(111,111,111,.5)}.btn-warning{color:#fff;background-color:#bf7e16;border-color:#bf7e16}.btn-warning:hover{color:#fff;background-color:#9d6712;border-color:#916011}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#9d6712;border-color:#916011;box-shadow:0 0 0 .2rem rgba(201,145,57,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#fff;background-color:#bf7e16;border-color:#bf7e16}.btn-warning:not(:disabled):not(.disabled):active,.btn-warning:not(:disabled):not(.disabled).active,.show>.btn-warning.dropdown-toggle{color:#fff;background-color:#916011;border-color:#86580f}.btn-warning:not(:disabled):not(.disabled):active:focus,.btn-warning:not(:disabled):not(.disabled).active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(201,145,57,.5)}.btn-danger{color:#fff;background-color:#dd4b39;border-color:#dd4b39}.btn-danger:hover{color:#fff;background-color:#cd3623;border-color:#c23321}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#cd3623;border-color:#c23321;box-shadow:0 0 0 .2rem rgba(226,102,87,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dd4b39;border-color:#dd4b39}.btn-danger:not(:disabled):not(.disabled):active,.btn-danger:not(:disabled):not(.disabled).active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#c23321;border-color:#b7301f}.btn-danger:not(:disabled):not(.disabled):active:focus,.btn-danger:not(:disabled):not(.disabled).active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(226,102,87,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light:focus,.btn-light.focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled):active,.btn-light:not(:disabled):not(.disabled).active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled):active:focus,.btn-light:not(:disabled):not(.disabled).active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark:focus,.btn-dark.focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled):active,.btn-dark:not(:disabled):not(.disabled).active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled):active:focus,.btn-dark:not(:disabled):not(.disabled).active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-primary-accent{color:#fff;background-color:#1252a3;border-color:#1252a3}.btn-primary-accent:hover{color:#fff;background-color:#0e4181;border-color:#0d3b75}.btn-primary-accent:focus,.btn-primary-accent.focus{color:#fff;background-color:#0e4181;border-color:#0d3b75;box-shadow:0 0 0 .2rem rgba(54,108,177,.5)}.btn-primary-accent.disabled,.btn-primary-accent:disabled{color:#fff;background-color:#1252a3;border-color:#1252a3}.btn-primary-accent:not(:disabled):not(.disabled):active,.btn-primary-accent:not(:disabled):not(.disabled).active,.show>.btn-primary-accent.dropdown-toggle{color:#fff;background-color:#0d3b75;border-color:#0c356a}.btn-primary-accent:not(:disabled):not(.disabled):active:focus,.btn-primary-accent:not(:disabled):not(.disabled).active:focus,.show>.btn-primary-accent.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(54,108,177,.5)}.btn-secondary-alt{color:#fff;background-color:#1a3b66;border-color:#1a3b66}.btn-secondary-alt:hover{color:#fff;background-color:#122948;border-color:#10233d}.btn-secondary-alt:focus,.btn-secondary-alt.focus{color:#fff;background-color:#122948;border-color:#10233d;box-shadow:0 0 0 .2rem rgba(60,88,125,.5)}.btn-secondary-alt.disabled,.btn-secondary-alt:disabled{color:#fff;background-color:#1a3b66;border-color:#1a3b66}.btn-secondary-alt:not(:disabled):not(.disabled):active,.btn-secondary-alt:not(:disabled):not(.disabled).active,.show>.btn-secondary-alt.dropdown-toggle{color:#fff;background-color:#10233d;border-color:#0d1e33}.btn-secondary-alt:not(:disabled):not(.disabled):active:focus,.btn-secondary-alt:not(:disabled):not(.disabled).active:focus,.show>.btn-secondary-alt.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(60,88,125,.5)}.btn-outline-primary{color:#175ddc;border-color:#175ddc}.btn-outline-primary:hover{color:#fff;background-color:#175ddc;border-color:#175ddc}.btn-outline-primary:focus,.btn-outline-primary.focus{box-shadow:0 0 0 .2rem rgba(23,93,220,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#175ddc;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled):active,.btn-outline-primary:not(:disabled):not(.disabled).active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#175ddc;border-color:#175ddc}.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,93,220,.5)}.btn-outline-secondary{color:#ced4da;border-color:#ced4da}.btn-outline-secondary:hover{color:#212529;background-color:#ced4da;border-color:#ced4da}.btn-outline-secondary:focus,.btn-outline-secondary.focus{box-shadow:0 0 0 .2rem rgba(206,212,218,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#ced4da;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled):active,.btn-outline-secondary:not(:disabled):not(.disabled).active,.show>.btn-outline-secondary.dropdown-toggle{color:#212529;background-color:#ced4da;border-color:#ced4da}.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(206,212,218,.5)}.btn-outline-success{color:#00a65a;border-color:#00a65a}.btn-outline-success:hover{color:#fff;background-color:#00a65a;border-color:#00a65a}.btn-outline-success:focus,.btn-outline-success.focus{box-shadow:0 0 0 .2rem rgba(0,166,90,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#00a65a;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled):active,.btn-outline-success:not(:disabled):not(.disabled).active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#00a65a;border-color:#00a65a}.btn-outline-success:not(:disabled):not(.disabled):active:focus,.btn-outline-success:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,166,90,.5)}.btn-outline-info{color:#555;border-color:#555}.btn-outline-info:hover{color:#fff;background-color:#555;border-color:#555}.btn-outline-info:focus,.btn-outline-info.focus{box-shadow:0 0 0 .2rem rgba(85,85,85,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#555;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled):active,.btn-outline-info:not(:disabled):not(.disabled).active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#555;border-color:#555}.btn-outline-info:not(:disabled):not(.disabled):active:focus,.btn-outline-info:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(85,85,85,.5)}.btn-outline-warning{color:#bf7e16;border-color:#bf7e16}.btn-outline-warning:hover{color:#fff;background-color:#bf7e16;border-color:#bf7e16}.btn-outline-warning:focus,.btn-outline-warning.focus{box-shadow:0 0 0 .2rem rgba(191,126,22,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#bf7e16;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled):active,.btn-outline-warning:not(:disabled):not(.disabled).active,.show>.btn-outline-warning.dropdown-toggle{color:#fff;background-color:#bf7e16;border-color:#bf7e16}.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(191,126,22,.5)}.btn-outline-danger{color:#dd4b39;border-color:#dd4b39}.btn-outline-danger:hover{color:#fff;background-color:#dd4b39;border-color:#dd4b39}.btn-outline-danger:focus,.btn-outline-danger.focus{box-shadow:0 0 0 .2rem rgba(221,75,57,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dd4b39;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled):active,.btn-outline-danger:not(:disabled):not(.disabled).active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dd4b39;border-color:#dd4b39}.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(221,75,57,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:focus,.btn-outline-light.focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled):active,.btn-outline-light:not(:disabled):not(.disabled).active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled):active:focus,.btn-outline-light:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:focus,.btn-outline-dark.focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled):active,.btn-outline-dark:not(:disabled):not(.disabled).active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-primary-accent{color:#1252a3;border-color:#1252a3}.btn-outline-primary-accent:hover{color:#fff;background-color:#1252a3;border-color:#1252a3}.btn-outline-primary-accent:focus,.btn-outline-primary-accent.focus{box-shadow:0 0 0 .2rem rgba(18,82,163,.5)}.btn-outline-primary-accent.disabled,.btn-outline-primary-accent:disabled{color:#1252a3;background-color:transparent}.btn-outline-primary-accent:not(:disabled):not(.disabled):active,.btn-outline-primary-accent:not(:disabled):not(.disabled).active,.show>.btn-outline-primary-accent.dropdown-toggle{color:#fff;background-color:#1252a3;border-color:#1252a3}.btn-outline-primary-accent:not(:disabled):not(.disabled):active:focus,.btn-outline-primary-accent:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-primary-accent.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(18,82,163,.5)}.btn-outline-secondary-alt{color:#1a3b66;border-color:#1a3b66}.btn-outline-secondary-alt:hover{color:#fff;background-color:#1a3b66;border-color:#1a3b66}.btn-outline-secondary-alt:focus,.btn-outline-secondary-alt.focus{box-shadow:0 0 0 .2rem rgba(26,59,102,.5)}.btn-outline-secondary-alt.disabled,.btn-outline-secondary-alt:disabled{color:#1a3b66;background-color:transparent}.btn-outline-secondary-alt:not(:disabled):not(.disabled):active,.btn-outline-secondary-alt:not(:disabled):not(.disabled).active,.show>.btn-outline-secondary-alt.dropdown-toggle{color:#fff;background-color:#1a3b66;border-color:#1a3b66}.btn-outline-secondary-alt:not(:disabled):not(.disabled):active:focus,.btn-outline-secondary-alt:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-secondary-alt.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(26,59,102,.5)}.btn-link{font-weight:400;color:#175ddc;text-decoration:none}.btn-link:hover{color:#104097;text-decoration:underline}.btn-link:focus,.btn-link.focus{text-decoration:underline}.btn-link:disabled,.btn-link.disabled{color:#6c757d;pointer-events:none}.btn-lg,.btn-group-lg>.btn,.swal2-popup .swal2-actions .btn-group-lg>button{padding:.5rem 1rem;font-size:1.15rem;line-height:1.5;border-radius:.3rem}.btn-sm,.btn-group-sm>.btn,.swal2-popup .swal2-actions .btn-group-sm>button{padding:.25rem .5rem;font-size:0.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{transition:opacity .15s linear}@media(prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media(prefers-reduced-motion: reduce){.collapsing{transition:none}}.dropup,.dropright,.dropdown,.dropleft{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#333;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media(min-width: 1px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media(min-width: 2px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media(min-width: 3px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media(min-width: 4px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=top],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1rem;clear:both;font-weight:400;color:#333;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:hover,.dropdown-item:focus{color:#16181b;text-decoration:none;background-color:rgba(0,0,0,.06)}.dropdown-item.active,.dropdown-item:active{color:#333;text-decoration:none;background-color:rgba(0,0,0,.1)}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:0.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#333}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.swal2-popup .swal2-actions .btn-group>button,.btn-group-vertical>.btn,.swal2-popup .swal2-actions .btn-group-vertical>button{position:relative;flex:1 1 auto}.btn-group>.btn:hover,.swal2-popup .swal2-actions .btn-group>button:hover,.btn-group-vertical>.btn:hover,.swal2-popup .swal2-actions .btn-group-vertical>button:hover{z-index:1}.btn-group>.btn:focus,.swal2-popup .swal2-actions .btn-group>button:focus,.btn-group>.btn:active,.swal2-popup .swal2-actions .btn-group>button:active,.btn-group>.btn.active,.swal2-popup .swal2-actions .btn-group>button.active,.btn-group-vertical>.btn:focus,.swal2-popup .swal2-actions .btn-group-vertical>button:focus,.btn-group-vertical>.btn:active,.swal2-popup .swal2-actions .btn-group-vertical>button:active,.btn-group-vertical>.btn.active,.swal2-popup .swal2-actions .btn-group-vertical>button.active{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.swal2-popup .swal2-actions .btn-group>button:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.swal2-popup .swal2-actions .btn-group>button:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn,.swal2-popup .swal2-actions .btn-group>.btn-group:not(:last-child)>button{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:not(:first-child),.swal2-popup .swal2-actions .btn-group>button:not(:first-child),.btn-group>.btn-group:not(:first-child)>.btn,.swal2-popup .swal2-actions .btn-group>.btn-group:not(:first-child)>button{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split,.swal2-popup .swal2-actions .btn-group-sm>button+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split,.swal2-popup .swal2-actions .btn-group-lg>button+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.swal2-popup .swal2-actions .btn-group-vertical>button,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.swal2-popup .swal2-actions .btn-group-vertical>button:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.swal2-popup .swal2-actions .btn-group-vertical>button:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn,.swal2-popup .swal2-actions .btn-group-vertical>.btn-group:not(:last-child)>button{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:not(:first-child),.swal2-popup .swal2-actions .btn-group-vertical>button:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child)>.btn,.swal2-popup .swal2-actions .btn-group-vertical>.btn-group:not(:first-child)>button{border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.swal2-popup .swal2-actions .btn-group-toggle>button,.btn-group-toggle>.btn-group>.btn,.swal2-popup .swal2-actions .btn-group-toggle>.btn-group>button{margin-bottom:0}.btn-group-toggle>.btn input[type=radio],.swal2-popup .swal2-actions .btn-group-toggle>button input[type=radio],.btn-group-toggle>.btn input[type=checkbox],.swal2-popup .swal2-actions .btn-group-toggle>button input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-control-plaintext,.input-group>.custom-select,.input-group>.custom-file{position:relative;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.form-control+.form-control,.input-group>.form-control+.custom-select,.input-group>.form-control+.custom-file,.input-group>.form-control-plaintext+.form-control,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.custom-file,.input-group>.custom-select+.form-control,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.custom-file,.input-group>.custom-file+.form-control,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.custom-file{margin-left:-1px}.input-group>.form-control:focus,.input-group>.custom-select:focus,.input-group>.custom-file .custom-file-input:focus~.custom-file-label{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.form-control:not(:first-child),.input-group>.custom-select:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group:not(.has-validation)>.form-control:not(:last-child),.input-group:not(.has-validation)>.custom-select:not(:last-child),.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.form-control:nth-last-child(n+3),.input-group.has-validation>.custom-select:nth-last-child(n+3),.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-prepend,.input-group-append{display:flex}.input-group-prepend .btn,.input-group-prepend .swal2-popup .swal2-actions button,.swal2-popup .swal2-actions .input-group-prepend button,.input-group-append .btn,.input-group-append .swal2-popup .swal2-actions button,.swal2-popup .swal2-actions .input-group-append button{position:relative;z-index:2}.input-group-prepend .btn:focus,.input-group-prepend .swal2-popup .swal2-actions button:focus,.swal2-popup .swal2-actions .input-group-prepend button:focus,.input-group-append .btn:focus,.input-group-append .swal2-popup .swal2-actions button:focus,.swal2-popup .swal2-actions .input-group-append button:focus{z-index:3}.input-group-prepend .btn+.btn,.input-group-prepend .swal2-popup .swal2-actions button+.btn,.swal2-popup .swal2-actions .input-group-prepend button+.btn,.input-group-prepend .swal2-popup .swal2-actions .btn+button,.swal2-popup .swal2-actions .input-group-prepend .btn+button,.input-group-prepend .swal2-popup .swal2-actions button+button,.swal2-popup .swal2-actions .input-group-prepend button+button,.input-group-prepend .btn+.input-group-text,.input-group-prepend .swal2-popup .swal2-actions button+.input-group-text,.swal2-popup .swal2-actions .input-group-prepend button+.input-group-text,.input-group-prepend .input-group-text+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .swal2-popup .swal2-actions .input-group-text+button,.swal2-popup .swal2-actions .input-group-prepend .input-group-text+button,.input-group-append .btn+.btn,.input-group-append .swal2-popup .swal2-actions button+.btn,.swal2-popup .swal2-actions .input-group-append button+.btn,.input-group-append .swal2-popup .swal2-actions .btn+button,.swal2-popup .swal2-actions .input-group-append .btn+button,.input-group-append .swal2-popup .swal2-actions button+button,.swal2-popup .swal2-actions .input-group-append button+button,.input-group-append .btn+.input-group-text,.input-group-append .swal2-popup .swal2-actions button+.input-group-text,.swal2-popup .swal2-actions .input-group-append button+.input-group-text,.input-group-append .input-group-text+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .swal2-popup .swal2-actions .input-group-text+button,.swal2-popup .swal2-actions .input-group-append .input-group-text+button{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=radio],.input-group-text input[type=checkbox]{margin-top:0}.input-group-lg>.form-control:not(textarea),.input-group-lg>.custom-select{height:calc(1.5em + 1rem + 2px)}.input-group-lg>.form-control,.input-group-lg>.custom-select,.input-group-lg>.input-group-prepend>.input-group-text,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.swal2-popup .swal2-actions .input-group-lg>.input-group-prepend>button,.input-group-lg>.input-group-append>.btn,.swal2-popup .swal2-actions .input-group-lg>.input-group-append>button{padding:.5rem 1rem;font-size:1.15rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.form-control:not(textarea),.input-group-sm>.custom-select{height:calc(1.5em + 0.5rem + 2px)}.input-group-sm>.form-control,.input-group-sm>.custom-select,.input-group-sm>.input-group-prepend>.input-group-text,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.swal2-popup .swal2-actions .input-group-sm>.input-group-prepend>button,.input-group-sm>.input-group-append>.btn,.swal2-popup .swal2-actions .input-group-sm>.input-group-append>button{padding:.25rem .5rem;font-size:0.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-prepend>.btn,.swal2-popup .swal2-actions .input-group>.input-group-prepend>button,.input-group>.input-group-prepend>.input-group-text,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.swal2-popup .swal2-actions .input-group:not(.has-validation)>.input-group-append:not(:last-child)>button,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.swal2-popup .swal2-actions .input-group.has-validation>.input-group-append:nth-last-child(n+3)>button,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.swal2-popup .swal2-actions .input-group>.input-group-append:last-child>button:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.swal2-popup .swal2-actions .input-group>.input-group-append>button,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:not(:first-child)>.btn,.swal2-popup .swal2-actions .input-group>.input-group-prepend:not(:first-child)>button,.input-group>.input-group-prepend:not(:first-child)>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.swal2-popup .swal2-actions .input-group>.input-group-prepend:first-child>button:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;color-adjust:exact}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#175ddc;background-color:#175ddc}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#81a9f2}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#afc8f7;border-color:#afc8f7}.custom-control-input[disabled]~.custom-control-label,.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input[disabled]~.custom-control-label::before,.custom-control-input:disabled~.custom-control-label::before{background-color:#e0e0e0}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fbfbfb;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:50%/50% 50% no-repeat}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23FFFFFF' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#175ddc;background-color:#175ddc}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23FFFFFF' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(23,93,220,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(23,93,220,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23FFFFFF'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(23,93,220,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(0.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fbfbfb;transform:translateX(0.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(23,93,220,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + 0.75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fbfbfb url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;appearance:none}.custom-select:focus{border-color:#81a9f2;outline:0;box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fbfbfb}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + 0.5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:0.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.15rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + 0.75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + 0.75rem + 2px);margin:0;overflow:hidden;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#81a9f2;box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}.custom-file-input[disabled]~.custom-file-label,.custom-file-input:disabled~.custom-file-label{background-color:#e0e0e0}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + 0.75rem + 2px);padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;background-color:#fbfbfb;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + 0.75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(23,93,220,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(23,93,220,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(23,93,220,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-0.25rem;background-color:#175ddc;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media(prefers-reduced-motion: reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#afc8f7}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#175ddc;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media(prefers-reduced-motion: reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#afc8f7}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#175ddc;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media(prefers-reduced-motion: reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#afc8f7}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:hover,.nav-link:focus{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#175ddc}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:.75rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-sm,.navbar .container-md,.navbar .container-lg,.navbar .container-xl{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:0;padding-bottom:0;margin-right:1rem;font-size:2.1875rem;line-height:inherit;white-space:nowrap}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.15rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:hover,.navbar-toggler:focus{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:50%/100% 100% no-repeat}.navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media(max-width: 0.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media(min-width: 1px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.8rem;padding-left:.8rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-xl{flex-wrap:nowrap}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media(max-width: 1.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-md,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media(min-width: 2px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.8rem;padding-left:.8rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-md,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-xl{flex-wrap:nowrap}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media(max-width: 2.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media(min-width: 3px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.8rem;padding-left:.8rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-xl{flex-wrap:nowrap}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media(max-width: 3.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media(min-width: 4px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.8rem;padding-left:.8rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-xl{flex-wrap:nowrap}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-sm,.navbar-expand>.container-md,.navbar-expand>.container-lg,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.8rem;padding-left:.8rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-sm,.navbar-expand>.container-md,.navbar-expand>.container-lg,.navbar-expand>.container-xl{flex-wrap:nowrap}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .nav-link.active{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.7)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:rgba(255,255,255,.9)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .nav-link.active{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.7);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.7%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.7)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(0.25rem - 1px);border-bottom-left-radius:calc(0.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.6rem}.card-subtitle{margin-top:-0.3rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.6rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.card-footer{padding:.6rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.card-header-tabs{margin-right:-0.625rem;margin-bottom:-0.6rem;margin-left:-0.625rem;border-bottom:0}.card-header-pills{margin-right:-0.625rem;margin-left:-0.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(0.25rem - 1px)}.card-img,.card-img-top,.card-img-bottom{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(0.25rem - 1px);border-bottom-left-radius:calc(0.25rem - 1px)}.card-deck .card{margin-bottom:10px}@media(min-width: 1px){.card-deck{display:flex;flex-flow:row wrap;margin-right:-10px;margin-left:-10px}.card-deck .card{flex:1 0 0%;margin-right:10px;margin-bottom:0;margin-left:10px}}.card-group>.card{margin-bottom:10px}@media(min-width: 1px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.6rem}@media(min-width: 1px){.card-columns{column-count:3;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#175ddc;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#104097;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#175ddc;border-color:#175ddc}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.15rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:0.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.badge{transition:none}}a.badge:hover,a.badge:focus{text-decoration:none}.badge:empty{display:none}.btn .badge,.swal2-popup .swal2-actions button .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#175ddc}a.badge-primary:hover,a.badge-primary:focus{color:#fff;background-color:#1249ae}a.badge-primary:focus,a.badge-primary.focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,93,220,.5)}.badge-secondary{color:#212529;background-color:#ced4da}a.badge-secondary:hover,a.badge-secondary:focus{color:#212529;background-color:#b1bbc4}a.badge-secondary:focus,a.badge-secondary.focus{outline:0;box-shadow:0 0 0 .2rem rgba(206,212,218,.5)}.badge-success{color:#fff;background-color:#00a65a}a.badge-success:hover,a.badge-success:focus{color:#fff;background-color:#00733e}a.badge-success:focus,a.badge-success.focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,166,90,.5)}.badge-info{color:#fff;background-color:#555}a.badge-info:hover,a.badge-info:focus{color:#fff;background-color:#3c3c3c}a.badge-info:focus,a.badge-info.focus{outline:0;box-shadow:0 0 0 .2rem rgba(85,85,85,.5)}.badge-warning{color:#fff;background-color:#bf7e16}a.badge-warning:hover,a.badge-warning:focus{color:#fff;background-color:#916011}a.badge-warning:focus,a.badge-warning.focus{outline:0;box-shadow:0 0 0 .2rem rgba(191,126,22,.5)}.badge-danger{color:#fff;background-color:#dd4b39}a.badge-danger:hover,a.badge-danger:focus{color:#fff;background-color:#c23321}a.badge-danger:focus,a.badge-danger.focus{outline:0;box-shadow:0 0 0 .2rem rgba(221,75,57,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:hover,a.badge-light:focus{color:#212529;background-color:#dae0e5}a.badge-light:focus,a.badge-light.focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:hover,a.badge-dark:focus{color:#fff;background-color:#1d2124}a.badge-dark:focus,a.badge-dark.focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.badge-primary-accent{color:#fff;background-color:#1252a3}a.badge-primary-accent:hover,a.badge-primary-accent:focus{color:#fff;background-color:#0d3b75}a.badge-primary-accent:focus,a.badge-primary-accent.focus{outline:0;box-shadow:0 0 0 .2rem rgba(18,82,163,.5)}.badge-secondary-alt{color:#fff;background-color:#1a3b66}a.badge-secondary-alt:hover,a.badge-secondary-alt:focus{color:#fff;background-color:#10233d}a.badge-secondary-alt:focus,a.badge-secondary-alt.focus{outline:0;box-shadow:0 0 0 .2rem rgba(26,59,102,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media(min-width: 1px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#0c3072;background-color:#d1dff8;border-color:#bed2f5}.alert-primary hr{border-top-color:#a8c3f2}.alert-primary .alert-link{color:#071d44}.alert-secondary{color:#6b6e71;background-color:#f5f6f8;border-color:#f1f3f5}.alert-secondary hr{border-top-color:#e2e6ea}.alert-secondary .alert-link{color:#525557}.alert-success{color:#00562f;background-color:#ccedde;border-color:#b8e6d1}.alert-success hr{border-top-color:#a5dfc5}.alert-success .alert-link{color:#002313}.alert-info{color:#2c2c2c;background-color:#ddd;border-color:#cfcfcf}.alert-info hr{border-top-color:#c2c2c2}.alert-info .alert-link{color:#131313}.alert-warning{color:#63420b;background-color:#f2e5d0;border-color:#eddbbe}.alert-warning hr{border-top-color:#e7d0aa}.alert-warning .alert-link{color:#352306}.alert-danger{color:#73271e;background-color:#f8dbd7;border-color:#f5cdc8}.alert-danger hr{border-top-color:#f1b9b2}.alert-danger .alert-link{color:#4b1913}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}.alert-primary-accent{color:#092b55;background-color:#d0dced;border-color:#bdcfe5}.alert-primary-accent hr{border-top-color:#abc2de}.alert-primary-accent .alert-link{color:#041427}.alert-secondary-alt{color:#0e1f35;background-color:#d1d8e0;border-color:#bfc8d4}.alert-secondary-alt hr{border-top-color:#b0bbca}.alert-secondary-alt .alert-link{color:#03070d}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:flex;height:1rem;overflow:hidden;line-height:0;font-size:0.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#175ddc;transition:width .6s ease}@media(prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-size:1rem 1rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media(prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#333;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.6rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#333;background-color:#fff;border-color:rgba(0,0,0,.125)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media(min-width: 1px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 2px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 3px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 4px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#0c3072;background-color:#bed2f5}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#0c3072;background-color:#a8c3f2}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#0c3072;border-color:#0c3072}.list-group-item-secondary{color:#6b6e71;background-color:#f1f3f5}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#6b6e71;background-color:#e2e6ea}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#6b6e71;border-color:#6b6e71}.list-group-item-success{color:#00562f;background-color:#b8e6d1}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#00562f;background-color:#a5dfc5}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#00562f;border-color:#00562f}.list-group-item-info{color:#2c2c2c;background-color:#cfcfcf}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#2c2c2c;background-color:#c2c2c2}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#2c2c2c;border-color:#2c2c2c}.list-group-item-warning{color:#63420b;background-color:#eddbbe}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#63420b;background-color:#e7d0aa}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#63420b;border-color:#63420b}.list-group-item-danger{color:#73271e;background-color:#f5cdc8}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#73271e;background-color:#f1b9b2}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#73271e;border-color:#73271e}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.list-group-item-primary-accent{color:#092b55;background-color:#bdcfe5}.list-group-item-primary-accent.list-group-item-action:hover,.list-group-item-primary-accent.list-group-item-action:focus{color:#092b55;background-color:#abc2de}.list-group-item-primary-accent.list-group-item-action.active{color:#fff;background-color:#092b55;border-color:#092b55}.list-group-item-secondary-alt{color:#0e1f35;background-color:#bfc8d4}.list-group-item-secondary-alt.list-group-item-action:hover,.list-group-item-secondary-alt.list-group-item-action:focus{color:#0e1f35;background-color:#b0bbca}.list-group-item-secondary-alt.list-group-item-action.active{color:#fff;background-color:#0e1f35;border-color:#0e1f35}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):hover,.close:not(:disabled):not(.disabled):focus{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0, -50px)}@media(prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-header,.modal-dialog-scrollable .modal-footer{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.3}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #ced4da;border-top-left-radius:calc(0.3rem - 1px);border-top-right-radius:calc(0.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #ced4da;border-bottom-right-radius:calc(0.3rem - 1px);border-bottom-left-radius:calc(0.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media(min-width: 1px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:min-content}.modal-sm{max-width:300px}}@media(min-width: 3px){.modal-lg,.modal-xl{max-width:800px}}@media(min-width: 4px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[x-placement^=top]{padding:.4rem 0}.bs-tooltip-top .arrow,.bs-tooltip-auto[x-placement^=top] .arrow{bottom:0}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[x-placement^=top] .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-right,.bs-tooltip-auto[x-placement^=right]{padding:0 .4rem}.bs-tooltip-right .arrow,.bs-tooltip-auto[x-placement^=right] .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-right .arrow::before,.bs-tooltip-auto[x-placement^=right] .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-bottom,.bs-tooltip-auto[x-placement^=bottom]{padding:.4rem 0}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[x-placement^=bottom] .arrow{top:0}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[x-placement^=bottom] .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-left,.bs-tooltip-auto[x-placement^=left]{padding:0 .4rem}.bs-tooltip-left .arrow,.bs-tooltip-auto[x-placement^=left] .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-left .arrow::before,.bs-tooltip-auto[x-placement^=left] .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::before,.popover .arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top,.bs-popover-auto[x-placement^=top]{margin-bottom:.5rem}.bs-popover-top>.arrow,.bs-popover-auto[x-placement^=top]>.arrow{bottom:calc(-0.5rem - 1px)}.bs-popover-top>.arrow::before,.bs-popover-auto[x-placement^=top]>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-top>.arrow::after,.bs-popover-auto[x-placement^=top]>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-right,.bs-popover-auto[x-placement^=right]{margin-left:.5rem}.bs-popover-right>.arrow,.bs-popover-auto[x-placement^=right]>.arrow{left:calc(-0.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-right>.arrow::before,.bs-popover-auto[x-placement^=right]>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-right>.arrow::after,.bs-popover-auto[x-placement^=right]>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-bottom,.bs-popover-auto[x-placement^=bottom]{margin-top:.5rem}.bs-popover-bottom>.arrow,.bs-popover-auto[x-placement^=bottom]>.arrow{top:calc(-0.5rem - 1px)}.bs-popover-bottom>.arrow::before,.bs-popover-auto[x-placement^=bottom]>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-bottom>.arrow::after,.bs-popover-auto[x-placement^=bottom]>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-bottom .popover-header::before,.bs-popover-auto[x-placement^=bottom] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-0.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-left,.bs-popover-auto[x-placement^=left]{margin-right:.5rem}.bs-popover-left>.arrow,.bs-popover-auto[x-placement^=left]>.arrow{right:calc(-0.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-left>.arrow::before,.bs-popover-auto[x-placement^=left]>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-left>.arrow::after,.bs-popover-auto[x-placement^=left]>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(0.3rem - 1px);border-top-right-radius:calc(0.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#333}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;transition:transform .6s ease-in-out}@media(prefers-reduced-motion: reduce){.carousel-item{transition:none}}.carousel-item.active,.carousel-item-next,.carousel-item-prev{display:block}.carousel-item-next:not(.carousel-item-left),.active.carousel-item-right{transform:translateX(100%)}.carousel-item-prev:not(.carousel-item-right),.active.carousel-item-left{transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item.active,.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media(prefers-reduced-motion: reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-prev,.carousel-control-next{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media(prefers-reduced-motion: reduce){.carousel-control-prev,.carousel-control-next{transition:none}}.carousel-control-prev:hover,.carousel-control-prev:focus,.carousel-control-next:hover,.carousel-control-next:focus{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-prev-icon,.carousel-control-next-icon{display:inline-block;width:20px;height:20px;background:50%/100% 100% no-repeat}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23FFFFFF' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23FFFFFF' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media(prefers-reduced-motion: reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media(prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s}}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.bg-primary{background-color:#175ddc !important}a.bg-primary:hover,a.bg-primary:focus,button.bg-primary:hover,button.bg-primary:focus{background-color:#1249ae !important}.bg-secondary{background-color:#ced4da !important}a.bg-secondary:hover,a.bg-secondary:focus,button.bg-secondary:hover,button.bg-secondary:focus{background-color:#b1bbc4 !important}.bg-success{background-color:#00a65a !important}a.bg-success:hover,a.bg-success:focus,button.bg-success:hover,button.bg-success:focus{background-color:#00733e !important}.bg-info{background-color:#555 !important}a.bg-info:hover,a.bg-info:focus,button.bg-info:hover,button.bg-info:focus{background-color:#3c3c3c !important}.bg-warning{background-color:#bf7e16 !important}a.bg-warning:hover,a.bg-warning:focus,button.bg-warning:hover,button.bg-warning:focus{background-color:#916011 !important}.bg-danger{background-color:#dd4b39 !important}a.bg-danger:hover,a.bg-danger:focus,button.bg-danger:hover,button.bg-danger:focus{background-color:#c23321 !important}.bg-light{background-color:#f8f9fa !important}a.bg-light:hover,a.bg-light:focus,button.bg-light:hover,button.bg-light:focus{background-color:#dae0e5 !important}.bg-dark{background-color:#343a40 !important}a.bg-dark:hover,a.bg-dark:focus,button.bg-dark:hover,button.bg-dark:focus{background-color:#1d2124 !important}.bg-primary-accent{background-color:#1252a3 !important}a.bg-primary-accent:hover,a.bg-primary-accent:focus,button.bg-primary-accent:hover,button.bg-primary-accent:focus{background-color:#0d3b75 !important}.bg-secondary-alt{background-color:#1a3b66 !important}a.bg-secondary-alt:hover,a.bg-secondary-alt:focus,button.bg-secondary-alt:hover,button.bg-secondary-alt:focus{background-color:#10233d !important}.bg-white{background-color:#fff !important}.bg-transparent{background-color:transparent !important}.border{border:1px solid #ced4da !important}.border-top{border-top:1px solid #ced4da !important}.border-right{border-right:1px solid #ced4da !important}.border-bottom{border-bottom:1px solid #ced4da !important}.border-left{border-left:1px solid #ced4da !important}.border-0{border:0 !important}.border-top-0{border-top:0 !important}.border-right-0{border-right:0 !important}.border-bottom-0{border-bottom:0 !important}.border-left-0{border-left:0 !important}.border-primary{border-color:#175ddc !important}.border-secondary{border-color:#ced4da !important}.border-success{border-color:#00a65a !important}.border-info{border-color:#555 !important}.border-warning{border-color:#bf7e16 !important}.border-danger{border-color:#dd4b39 !important}.border-light{border-color:#f8f9fa !important}.border-dark{border-color:#343a40 !important}.border-primary-accent{border-color:#1252a3 !important}.border-secondary-alt{border-color:#1a3b66 !important}.border-white{border-color:#fff !important}.rounded-sm{border-radius:.2rem !important}.rounded,.table td.table-list-icon img,app-avatar img{border-radius:.25rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-right{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-left{border-top-left-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-lg{border-radius:.3rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-0{border-radius:0 !important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}@media(min-width: 1px){.d-sm-none{display:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}}@media(min-width: 2px){.d-md-none{display:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}}@media(min-width: 3px){.d-lg-none{display:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}}@media(min-width: 4px){.d-xl-none{display:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}}@media print{.d-print-none{display:none !important}.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.8571428571%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-fill{flex:1 1 auto !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}@media(min-width: 1px){.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}}@media(min-width: 2px){.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}}@media(min-width: 3px){.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}}@media(min-width: 4px){.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}}.float-left{float:left !important}.float-right{float:right !important}.float-none{float:none !important}@media(min-width: 1px){.float-sm-left{float:left !important}.float-sm-right{float:right !important}.float-sm-none{float:none !important}}@media(min-width: 2px){.float-md-left{float:left !important}.float-md-right{float:right !important}.float-md-none{float:none !important}}@media(min-width: 3px){.float-lg-left{float:left !important}.float-lg-right{float:right !important}.float-lg-none{float:none !important}}@media(min-width: 4px){.float-xl-left{float:left !important}.float-xl-right{float:right !important}.float-xl-none{float:none !important}}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports(position: sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only,.table tr:not(:hover) td.table-list-options>.dropdown:not(.show) button:not(:focus):not(:active),.table tr:not(:hover) td.table-list-options>button:not(:focus):not(:active){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075) !important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175) !important}.shadow-none{box-shadow:none !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mw-100{max-width:100% !important}.mh-100{max-height:100% !important}.min-vw-100{min-width:100vw !important}.min-vh-100{min-height:100vh !important}.vw-100{width:100vw !important}.vh-100{height:100vh !important}.m-0{margin:0 !important}.mt-0,.my-0{margin-top:0 !important}.mr-0,.mx-0{margin-right:0 !important}.mb-0,.my-0{margin-bottom:0 !important}.ml-0,.mx-0{margin-left:0 !important}.m-1{margin:.25rem !important}.mt-1,.my-1{margin-top:.25rem !important}.mr-1,.mx-1{margin-right:.25rem !important}.mb-1,.my-1{margin-bottom:.25rem !important}.ml-1,.mx-1{margin-left:.25rem !important}.m-2{margin:.5rem !important}.mt-2,.form-check-block .form-check-label>span,.my-2{margin-top:.5rem !important}.mr-2,.mx-2{margin-right:.5rem !important}.mb-2,.my-2{margin-bottom:.5rem !important}.ml-2,.mx-2{margin-left:.5rem !important}.m-3{margin:1rem !important}.mt-3,.form-check-block+.form-check-block:not(.mt-2),.my-3{margin-top:1rem !important}.mr-3,.mx-3{margin-right:1rem !important}.mb-3,.my-3{margin-bottom:1rem !important}.ml-3,.mx-3{margin-left:1rem !important}.m-4{margin:1.5rem !important}.mt-4,.my-4{margin-top:1.5rem !important}.mr-4,.mx-4{margin-right:1.5rem !important}.mb-4,.card-body-header,.my-4{margin-bottom:1.5rem !important}.ml-4,.form-group .form-group-child-check,.mx-4{margin-left:1.5rem !important}.m-5{margin:3rem !important}.mt-5,.my-5{margin-top:3rem !important}.mr-5,.mx-5{margin-right:3rem !important}.mb-5,.my-5{margin-bottom:3rem !important}.ml-5,.mx-5{margin-left:3rem !important}.p-0{padding:0 !important}.pt-0,.py-0{padding-top:0 !important}.pr-0,.px-0{padding-right:0 !important}.pb-0,.py-0{padding-bottom:0 !important}.pl-0,.px-0{padding-left:0 !important}.p-1{padding:.25rem !important}.pt-1,.py-1{padding-top:.25rem !important}.pr-1,.px-1{padding-right:.25rem !important}.pb-1,.py-1{padding-bottom:.25rem !important}.pl-1,.px-1{padding-left:.25rem !important}.p-2{padding:.5rem !important}.pt-2,.py-2{padding-top:.5rem !important}.pr-2,.px-2{padding-right:.5rem !important}.pb-2,.py-2{padding-bottom:.5rem !important}.pl-2,.px-2{padding-left:.5rem !important}.p-3{padding:1rem !important}.pt-3,.py-3{padding-top:1rem !important}.pr-3,.px-3{padding-right:1rem !important}.pb-3,.py-3{padding-bottom:1rem !important}.pl-3,.px-3{padding-left:1rem !important}.p-4{padding:1.5rem !important}.pt-4,.py-4{padding-top:1.5rem !important}.pr-4,.px-4{padding-right:1.5rem !important}.pb-4,.py-4{padding-bottom:1.5rem !important}.pl-4,.px-4{padding-left:1.5rem !important}.p-5{padding:3rem !important}.pt-5,.py-5{padding-top:3rem !important}.pr-5,.px-5{padding-right:3rem !important}.pb-5,.py-5{padding-bottom:3rem !important}.pl-5,.px-5{padding-left:3rem !important}.m-n1{margin:-0.25rem !important}.mt-n1,.my-n1{margin-top:-0.25rem !important}.mr-n1,.mx-n1{margin-right:-0.25rem !important}.mb-n1,.my-n1{margin-bottom:-0.25rem !important}.ml-n1,.mx-n1{margin-left:-0.25rem !important}.m-n2{margin:-0.5rem !important}.mt-n2,.my-n2{margin-top:-0.5rem !important}.mr-n2,.mx-n2{margin-right:-0.5rem !important}.mb-n2,.my-n2{margin-bottom:-0.5rem !important}.ml-n2,.mx-n2{margin-left:-0.5rem !important}.m-n3{margin:-1rem !important}.mt-n3,.my-n3{margin-top:-1rem !important}.mr-n3,.mx-n3{margin-right:-1rem !important}.mb-n3,.my-n3{margin-bottom:-1rem !important}.ml-n3,.mx-n3{margin-left:-1rem !important}.m-n4{margin:-1.5rem !important}.mt-n4,.my-n4{margin-top:-1.5rem !important}.mr-n4,.mx-n4{margin-right:-1.5rem !important}.mb-n4,.my-n4{margin-bottom:-1.5rem !important}.ml-n4,.mx-n4{margin-left:-1.5rem !important}.m-n5{margin:-3rem !important}.mt-n5,.my-n5{margin-top:-3rem !important}.mr-n5,.mx-n5{margin-right:-3rem !important}.mb-n5,.my-n5{margin-bottom:-3rem !important}.ml-n5,.mx-n5{margin-left:-3rem !important}.m-auto{margin:auto !important}.mt-auto,.my-auto{margin-top:auto !important}.mr-auto,.mx-auto{margin-right:auto !important}.mb-auto,.my-auto{margin-bottom:auto !important}.ml-auto,.mx-auto{margin-left:auto !important}@media(min-width: 1px){.m-sm-0{margin:0 !important}.mt-sm-0,.my-sm-0{margin-top:0 !important}.mr-sm-0,.mx-sm-0{margin-right:0 !important}.mb-sm-0,.my-sm-0{margin-bottom:0 !important}.ml-sm-0,.mx-sm-0{margin-left:0 !important}.m-sm-1{margin:.25rem !important}.mt-sm-1,.my-sm-1{margin-top:.25rem !important}.mr-sm-1,.mx-sm-1{margin-right:.25rem !important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem !important}.ml-sm-1,.mx-sm-1{margin-left:.25rem !important}.m-sm-2{margin:.5rem !important}.mt-sm-2,.my-sm-2{margin-top:.5rem !important}.mr-sm-2,.mx-sm-2{margin-right:.5rem !important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem !important}.ml-sm-2,.mx-sm-2{margin-left:.5rem !important}.m-sm-3{margin:1rem !important}.mt-sm-3,.my-sm-3{margin-top:1rem !important}.mr-sm-3,.mx-sm-3{margin-right:1rem !important}.mb-sm-3,.my-sm-3{margin-bottom:1rem !important}.ml-sm-3,.mx-sm-3{margin-left:1rem !important}.m-sm-4{margin:1.5rem !important}.mt-sm-4,.my-sm-4{margin-top:1.5rem !important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem !important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem !important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem !important}.m-sm-5{margin:3rem !important}.mt-sm-5,.my-sm-5{margin-top:3rem !important}.mr-sm-5,.mx-sm-5{margin-right:3rem !important}.mb-sm-5,.my-sm-5{margin-bottom:3rem !important}.ml-sm-5,.mx-sm-5{margin-left:3rem !important}.p-sm-0{padding:0 !important}.pt-sm-0,.py-sm-0{padding-top:0 !important}.pr-sm-0,.px-sm-0{padding-right:0 !important}.pb-sm-0,.py-sm-0{padding-bottom:0 !important}.pl-sm-0,.px-sm-0{padding-left:0 !important}.p-sm-1{padding:.25rem !important}.pt-sm-1,.py-sm-1{padding-top:.25rem !important}.pr-sm-1,.px-sm-1{padding-right:.25rem !important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem !important}.pl-sm-1,.px-sm-1{padding-left:.25rem !important}.p-sm-2{padding:.5rem !important}.pt-sm-2,.py-sm-2{padding-top:.5rem !important}.pr-sm-2,.px-sm-2{padding-right:.5rem !important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem !important}.pl-sm-2,.px-sm-2{padding-left:.5rem !important}.p-sm-3{padding:1rem !important}.pt-sm-3,.py-sm-3{padding-top:1rem !important}.pr-sm-3,.px-sm-3{padding-right:1rem !important}.pb-sm-3,.py-sm-3{padding-bottom:1rem !important}.pl-sm-3,.px-sm-3{padding-left:1rem !important}.p-sm-4{padding:1.5rem !important}.pt-sm-4,.py-sm-4{padding-top:1.5rem !important}.pr-sm-4,.px-sm-4{padding-right:1.5rem !important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem !important}.pl-sm-4,.px-sm-4{padding-left:1.5rem !important}.p-sm-5{padding:3rem !important}.pt-sm-5,.py-sm-5{padding-top:3rem !important}.pr-sm-5,.px-sm-5{padding-right:3rem !important}.pb-sm-5,.py-sm-5{padding-bottom:3rem !important}.pl-sm-5,.px-sm-5{padding-left:3rem !important}.m-sm-n1{margin:-0.25rem !important}.mt-sm-n1,.my-sm-n1{margin-top:-0.25rem !important}.mr-sm-n1,.mx-sm-n1{margin-right:-0.25rem !important}.mb-sm-n1,.my-sm-n1{margin-bottom:-0.25rem !important}.ml-sm-n1,.mx-sm-n1{margin-left:-0.25rem !important}.m-sm-n2{margin:-0.5rem !important}.mt-sm-n2,.my-sm-n2{margin-top:-0.5rem !important}.mr-sm-n2,.mx-sm-n2{margin-right:-0.5rem !important}.mb-sm-n2,.my-sm-n2{margin-bottom:-0.5rem !important}.ml-sm-n2,.mx-sm-n2{margin-left:-0.5rem !important}.m-sm-n3{margin:-1rem !important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem !important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem !important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem !important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem !important}.m-sm-n4{margin:-1.5rem !important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem !important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem !important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem !important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem !important}.m-sm-n5{margin:-3rem !important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem !important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem !important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem !important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem !important}.m-sm-auto{margin:auto !important}.mt-sm-auto,.my-sm-auto{margin-top:auto !important}.mr-sm-auto,.mx-sm-auto{margin-right:auto !important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto !important}.ml-sm-auto,.mx-sm-auto{margin-left:auto !important}}@media(min-width: 2px){.m-md-0{margin:0 !important}.mt-md-0,.my-md-0{margin-top:0 !important}.mr-md-0,.mx-md-0{margin-right:0 !important}.mb-md-0,.my-md-0{margin-bottom:0 !important}.ml-md-0,.mx-md-0{margin-left:0 !important}.m-md-1{margin:.25rem !important}.mt-md-1,.my-md-1{margin-top:.25rem !important}.mr-md-1,.mx-md-1{margin-right:.25rem !important}.mb-md-1,.my-md-1{margin-bottom:.25rem !important}.ml-md-1,.mx-md-1{margin-left:.25rem !important}.m-md-2{margin:.5rem !important}.mt-md-2,.my-md-2{margin-top:.5rem !important}.mr-md-2,.mx-md-2{margin-right:.5rem !important}.mb-md-2,.my-md-2{margin-bottom:.5rem !important}.ml-md-2,.mx-md-2{margin-left:.5rem !important}.m-md-3{margin:1rem !important}.mt-md-3,.my-md-3{margin-top:1rem !important}.mr-md-3,.mx-md-3{margin-right:1rem !important}.mb-md-3,.my-md-3{margin-bottom:1rem !important}.ml-md-3,.mx-md-3{margin-left:1rem !important}.m-md-4{margin:1.5rem !important}.mt-md-4,.my-md-4{margin-top:1.5rem !important}.mr-md-4,.mx-md-4{margin-right:1.5rem !important}.mb-md-4,.my-md-4{margin-bottom:1.5rem !important}.ml-md-4,.mx-md-4{margin-left:1.5rem !important}.m-md-5{margin:3rem !important}.mt-md-5,.my-md-5{margin-top:3rem !important}.mr-md-5,.mx-md-5{margin-right:3rem !important}.mb-md-5,.my-md-5{margin-bottom:3rem !important}.ml-md-5,.mx-md-5{margin-left:3rem !important}.p-md-0{padding:0 !important}.pt-md-0,.py-md-0{padding-top:0 !important}.pr-md-0,.px-md-0{padding-right:0 !important}.pb-md-0,.py-md-0{padding-bottom:0 !important}.pl-md-0,.px-md-0{padding-left:0 !important}.p-md-1{padding:.25rem !important}.pt-md-1,.py-md-1{padding-top:.25rem !important}.pr-md-1,.px-md-1{padding-right:.25rem !important}.pb-md-1,.py-md-1{padding-bottom:.25rem !important}.pl-md-1,.px-md-1{padding-left:.25rem !important}.p-md-2{padding:.5rem !important}.pt-md-2,.py-md-2{padding-top:.5rem !important}.pr-md-2,.px-md-2{padding-right:.5rem !important}.pb-md-2,.py-md-2{padding-bottom:.5rem !important}.pl-md-2,.px-md-2{padding-left:.5rem !important}.p-md-3{padding:1rem !important}.pt-md-3,.py-md-3{padding-top:1rem !important}.pr-md-3,.px-md-3{padding-right:1rem !important}.pb-md-3,.py-md-3{padding-bottom:1rem !important}.pl-md-3,.px-md-3{padding-left:1rem !important}.p-md-4{padding:1.5rem !important}.pt-md-4,.py-md-4{padding-top:1.5rem !important}.pr-md-4,.px-md-4{padding-right:1.5rem !important}.pb-md-4,.py-md-4{padding-bottom:1.5rem !important}.pl-md-4,.px-md-4{padding-left:1.5rem !important}.p-md-5{padding:3rem !important}.pt-md-5,.py-md-5{padding-top:3rem !important}.pr-md-5,.px-md-5{padding-right:3rem !important}.pb-md-5,.py-md-5{padding-bottom:3rem !important}.pl-md-5,.px-md-5{padding-left:3rem !important}.m-md-n1{margin:-0.25rem !important}.mt-md-n1,.my-md-n1{margin-top:-0.25rem !important}.mr-md-n1,.mx-md-n1{margin-right:-0.25rem !important}.mb-md-n1,.my-md-n1{margin-bottom:-0.25rem !important}.ml-md-n1,.mx-md-n1{margin-left:-0.25rem !important}.m-md-n2{margin:-0.5rem !important}.mt-md-n2,.my-md-n2{margin-top:-0.5rem !important}.mr-md-n2,.mx-md-n2{margin-right:-0.5rem !important}.mb-md-n2,.my-md-n2{margin-bottom:-0.5rem !important}.ml-md-n2,.mx-md-n2{margin-left:-0.5rem !important}.m-md-n3{margin:-1rem !important}.mt-md-n3,.my-md-n3{margin-top:-1rem !important}.mr-md-n3,.mx-md-n3{margin-right:-1rem !important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem !important}.ml-md-n3,.mx-md-n3{margin-left:-1rem !important}.m-md-n4{margin:-1.5rem !important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem !important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem !important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem !important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem !important}.m-md-n5{margin:-3rem !important}.mt-md-n5,.my-md-n5{margin-top:-3rem !important}.mr-md-n5,.mx-md-n5{margin-right:-3rem !important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem !important}.ml-md-n5,.mx-md-n5{margin-left:-3rem !important}.m-md-auto{margin:auto !important}.mt-md-auto,.my-md-auto{margin-top:auto !important}.mr-md-auto,.mx-md-auto{margin-right:auto !important}.mb-md-auto,.my-md-auto{margin-bottom:auto !important}.ml-md-auto,.mx-md-auto{margin-left:auto !important}}@media(min-width: 3px){.m-lg-0{margin:0 !important}.mt-lg-0,.my-lg-0{margin-top:0 !important}.mr-lg-0,.mx-lg-0{margin-right:0 !important}.mb-lg-0,.my-lg-0{margin-bottom:0 !important}.ml-lg-0,.mx-lg-0{margin-left:0 !important}.m-lg-1{margin:.25rem !important}.mt-lg-1,.my-lg-1{margin-top:.25rem !important}.mr-lg-1,.mx-lg-1{margin-right:.25rem !important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem !important}.ml-lg-1,.mx-lg-1{margin-left:.25rem !important}.m-lg-2{margin:.5rem !important}.mt-lg-2,.my-lg-2{margin-top:.5rem !important}.mr-lg-2,.mx-lg-2{margin-right:.5rem !important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem !important}.ml-lg-2,.mx-lg-2{margin-left:.5rem !important}.m-lg-3{margin:1rem !important}.mt-lg-3,.my-lg-3{margin-top:1rem !important}.mr-lg-3,.mx-lg-3{margin-right:1rem !important}.mb-lg-3,.my-lg-3{margin-bottom:1rem !important}.ml-lg-3,.mx-lg-3{margin-left:1rem !important}.m-lg-4{margin:1.5rem !important}.mt-lg-4,.my-lg-4{margin-top:1.5rem !important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem !important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem !important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem !important}.m-lg-5{margin:3rem !important}.mt-lg-5,.my-lg-5{margin-top:3rem !important}.mr-lg-5,.mx-lg-5{margin-right:3rem !important}.mb-lg-5,.my-lg-5{margin-bottom:3rem !important}.ml-lg-5,.mx-lg-5{margin-left:3rem !important}.p-lg-0{padding:0 !important}.pt-lg-0,.py-lg-0{padding-top:0 !important}.pr-lg-0,.px-lg-0{padding-right:0 !important}.pb-lg-0,.py-lg-0{padding-bottom:0 !important}.pl-lg-0,.px-lg-0{padding-left:0 !important}.p-lg-1{padding:.25rem !important}.pt-lg-1,.py-lg-1{padding-top:.25rem !important}.pr-lg-1,.px-lg-1{padding-right:.25rem !important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem !important}.pl-lg-1,.px-lg-1{padding-left:.25rem !important}.p-lg-2{padding:.5rem !important}.pt-lg-2,.py-lg-2{padding-top:.5rem !important}.pr-lg-2,.px-lg-2{padding-right:.5rem !important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem !important}.pl-lg-2,.px-lg-2{padding-left:.5rem !important}.p-lg-3{padding:1rem !important}.pt-lg-3,.py-lg-3{padding-top:1rem !important}.pr-lg-3,.px-lg-3{padding-right:1rem !important}.pb-lg-3,.py-lg-3{padding-bottom:1rem !important}.pl-lg-3,.px-lg-3{padding-left:1rem !important}.p-lg-4{padding:1.5rem !important}.pt-lg-4,.py-lg-4{padding-top:1.5rem !important}.pr-lg-4,.px-lg-4{padding-right:1.5rem !important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem !important}.pl-lg-4,.px-lg-4{padding-left:1.5rem !important}.p-lg-5{padding:3rem !important}.pt-lg-5,.py-lg-5{padding-top:3rem !important}.pr-lg-5,.px-lg-5{padding-right:3rem !important}.pb-lg-5,.py-lg-5{padding-bottom:3rem !important}.pl-lg-5,.px-lg-5{padding-left:3rem !important}.m-lg-n1{margin:-0.25rem !important}.mt-lg-n1,.my-lg-n1{margin-top:-0.25rem !important}.mr-lg-n1,.mx-lg-n1{margin-right:-0.25rem !important}.mb-lg-n1,.my-lg-n1{margin-bottom:-0.25rem !important}.ml-lg-n1,.mx-lg-n1{margin-left:-0.25rem !important}.m-lg-n2{margin:-0.5rem !important}.mt-lg-n2,.my-lg-n2{margin-top:-0.5rem !important}.mr-lg-n2,.mx-lg-n2{margin-right:-0.5rem !important}.mb-lg-n2,.my-lg-n2{margin-bottom:-0.5rem !important}.ml-lg-n2,.mx-lg-n2{margin-left:-0.5rem !important}.m-lg-n3{margin:-1rem !important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem !important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem !important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem !important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem !important}.m-lg-n4{margin:-1.5rem !important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem !important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem !important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem !important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem !important}.m-lg-n5{margin:-3rem !important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem !important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem !important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem !important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem !important}.m-lg-auto{margin:auto !important}.mt-lg-auto,.my-lg-auto{margin-top:auto !important}.mr-lg-auto,.mx-lg-auto{margin-right:auto !important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto !important}.ml-lg-auto,.mx-lg-auto{margin-left:auto !important}}@media(min-width: 4px){.m-xl-0{margin:0 !important}.mt-xl-0,.my-xl-0{margin-top:0 !important}.mr-xl-0,.mx-xl-0{margin-right:0 !important}.mb-xl-0,.my-xl-0{margin-bottom:0 !important}.ml-xl-0,.mx-xl-0{margin-left:0 !important}.m-xl-1{margin:.25rem !important}.mt-xl-1,.my-xl-1{margin-top:.25rem !important}.mr-xl-1,.mx-xl-1{margin-right:.25rem !important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem !important}.ml-xl-1,.mx-xl-1{margin-left:.25rem !important}.m-xl-2{margin:.5rem !important}.mt-xl-2,.my-xl-2{margin-top:.5rem !important}.mr-xl-2,.mx-xl-2{margin-right:.5rem !important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem !important}.ml-xl-2,.mx-xl-2{margin-left:.5rem !important}.m-xl-3{margin:1rem !important}.mt-xl-3,.my-xl-3{margin-top:1rem !important}.mr-xl-3,.mx-xl-3{margin-right:1rem !important}.mb-xl-3,.my-xl-3{margin-bottom:1rem !important}.ml-xl-3,.mx-xl-3{margin-left:1rem !important}.m-xl-4{margin:1.5rem !important}.mt-xl-4,.my-xl-4{margin-top:1.5rem !important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem !important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem !important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem !important}.m-xl-5{margin:3rem !important}.mt-xl-5,.my-xl-5{margin-top:3rem !important}.mr-xl-5,.mx-xl-5{margin-right:3rem !important}.mb-xl-5,.my-xl-5{margin-bottom:3rem !important}.ml-xl-5,.mx-xl-5{margin-left:3rem !important}.p-xl-0{padding:0 !important}.pt-xl-0,.py-xl-0{padding-top:0 !important}.pr-xl-0,.px-xl-0{padding-right:0 !important}.pb-xl-0,.py-xl-0{padding-bottom:0 !important}.pl-xl-0,.px-xl-0{padding-left:0 !important}.p-xl-1{padding:.25rem !important}.pt-xl-1,.py-xl-1{padding-top:.25rem !important}.pr-xl-1,.px-xl-1{padding-right:.25rem !important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem !important}.pl-xl-1,.px-xl-1{padding-left:.25rem !important}.p-xl-2{padding:.5rem !important}.pt-xl-2,.py-xl-2{padding-top:.5rem !important}.pr-xl-2,.px-xl-2{padding-right:.5rem !important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem !important}.pl-xl-2,.px-xl-2{padding-left:.5rem !important}.p-xl-3{padding:1rem !important}.pt-xl-3,.py-xl-3{padding-top:1rem !important}.pr-xl-3,.px-xl-3{padding-right:1rem !important}.pb-xl-3,.py-xl-3{padding-bottom:1rem !important}.pl-xl-3,.px-xl-3{padding-left:1rem !important}.p-xl-4{padding:1.5rem !important}.pt-xl-4,.py-xl-4{padding-top:1.5rem !important}.pr-xl-4,.px-xl-4{padding-right:1.5rem !important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem !important}.pl-xl-4,.px-xl-4{padding-left:1.5rem !important}.p-xl-5{padding:3rem !important}.pt-xl-5,.py-xl-5{padding-top:3rem !important}.pr-xl-5,.px-xl-5{padding-right:3rem !important}.pb-xl-5,.py-xl-5{padding-bottom:3rem !important}.pl-xl-5,.px-xl-5{padding-left:3rem !important}.m-xl-n1{margin:-0.25rem !important}.mt-xl-n1,.my-xl-n1{margin-top:-0.25rem !important}.mr-xl-n1,.mx-xl-n1{margin-right:-0.25rem !important}.mb-xl-n1,.my-xl-n1{margin-bottom:-0.25rem !important}.ml-xl-n1,.mx-xl-n1{margin-left:-0.25rem !important}.m-xl-n2{margin:-0.5rem !important}.mt-xl-n2,.my-xl-n2{margin-top:-0.5rem !important}.mr-xl-n2,.mx-xl-n2{margin-right:-0.5rem !important}.mb-xl-n2,.my-xl-n2{margin-bottom:-0.5rem !important}.ml-xl-n2,.mx-xl-n2{margin-left:-0.5rem !important}.m-xl-n3{margin:-1rem !important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem !important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem !important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem !important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem !important}.m-xl-n4{margin:-1.5rem !important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem !important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem !important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem !important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem !important}.m-xl-n5{margin:-3rem !important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem !important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem !important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem !important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem !important}.m-xl-auto{margin:auto !important}.mt-xl-auto,.my-xl-auto{margin-top:auto !important}.mr-xl-auto,.mx-xl-auto{margin-right:auto !important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto !important}.ml-xl-auto,.mx-xl-auto{margin-left:auto !important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace,.totp .totp-code{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace !important}.text-justify{text-align:justify !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}@media(min-width: 1px){.text-sm-left{text-align:left !important}.text-sm-right{text-align:right !important}.text-sm-center{text-align:center !important}}@media(min-width: 2px){.text-md-left{text-align:left !important}.text-md-right{text-align:right !important}.text-md-center{text-align:center !important}}@media(min-width: 3px){.text-lg-left{text-align:left !important}.text-lg-right{text-align:right !important}.text-lg-center{text-align:center !important}}@media(min-width: 4px){.text-xl-left{text-align:left !important}.text-xl-right{text-align:right !important}.text-xl-center{text-align:center !important}}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.font-weight-light{font-weight:300 !important}.font-weight-lighter{font-weight:lighter !important}.font-weight-normal{font-weight:400 !important}.font-weight-bold{font-weight:700 !important}.font-weight-bolder{font-weight:bolder !important}.font-italic{font-style:italic !important}.text-white{color:#fff !important}.text-primary{color:#175ddc !important}a.text-primary:hover,a.text-primary:focus{color:#104097 !important}.text-secondary{color:#ced4da !important}a.text-secondary:hover,a.text-secondary:focus{color:#a2aeb9 !important}.text-success{color:#00a65a !important}a.text-success:hover,a.text-success:focus{color:#005a31 !important}.text-info{color:#555 !important}a.text-info:hover,a.text-info:focus{color:#2f2f2f !important}.text-warning{color:#bf7e16 !important}a.text-warning:hover,a.text-warning:focus{color:#7a510e !important}.text-danger{color:#dd4b39 !important}a.text-danger:hover,a.text-danger:focus{color:#ac2d1e !important}.text-light{color:#f8f9fa !important}a.text-light:hover,a.text-light:focus{color:#cbd3da !important}.text-dark{color:#343a40 !important}a.text-dark:hover,a.text-dark:focus{color:#121416 !important}.text-primary-accent{color:#1252a3 !important}a.text-primary-accent:hover,a.text-primary-accent:focus{color:#0a2f5e !important}.text-secondary-alt{color:#1a3b66 !important}a.text-secondary-alt:hover,a.text-secondary-alt:focus{color:#0a1829 !important}.text-body{color:#333 !important}.text-muted,.card-header small,.modal-header small{color:#6c757d !important}.text-black-50{color:rgba(0,0,0,.5) !important}.text-white-50{color:rgba(255,255,255,.5) !important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none !important}.text-break{word-break:break-word !important;word-wrap:break-word !important}.text-reset{color:inherit !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media print{*,*::before,*::after{text-shadow:none !important;box-shadow:none !important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap !important}pre,blockquote{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:3px !important}.container{min-width:3px !important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #dee2e6 !important}.table-dark{color:inherit}.table-dark th,.table-dark td,.table-dark thead th,.table-dark tbody+tbody{border-color:#ced4da}.table .thead-dark th{color:inherit;border-color:#ced4da}}.toast{display:flex;flex-direction:row;align-content:center;justify-content:center;position:relative;background-color:#030303}.toast-success{background-color:#51a351}.toast-error{background-color:#bd362f}.toast-info{background-color:#2f96b4}.toast-wait{background-color:#2f96b4}.toast-warning{background-color:#f89406}.icon-success{background-repeat:no-repeat;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important}.icon-error{background-repeat:no-repeat;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important}.icon-info{background-repeat:no-repeat;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important}.icon-wait{background-repeat:no-repeat;background-image:url("data:image/gif;base64,R0lGODlhIAAgAIQAAAQCBISGhMzKzERCROTm5CQiJKyurHx+fPz+/ExOTOzu7Dw+PIyOjCwqLFRWVAwKDIyKjMzOzOzq7CQmJLy6vFRSVPTy9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCQAXACwAAAAAIAAgAAAF3eAljmRpnmh6VRSVqLDpIDTixOdUlFSNUDhSQUAT7ES9GnD0SFQAKWItMqr4bqKHVPDI+WiTkaOFFVlrFe83rDrT0qeIjwrT0iLdU0GOiBxhAA4VeSk6QYeIOAsQEAuJKgw+EI8nA18IA48JBAQvFxCXDI8SNAQikV+iiaQIpheWX5mJmxKeF6g0qpQmA4yOu8C7EwYWCgZswRcTFj4KyMAGlwYxDwcHhCXMXxYxBzQHKNo+3DDeCOAn0V/TddbYJA0K48gAEAFQicMWFsfwNA3JSgAIAAFfwIMIL4QAACH5BAkJABoALAAAAAAgACAAhAQCBIyKjERCRMzOzCQiJPTy9DQyNGRmZMTCxOTm5CwqLHx+fBQWFJyenNTW1Pz6/Dw6PGxubAwKDIyOjNTS1CQmJCwuLPz+/Dw+PHRydAAAAAAAAAAAAAAAAAAAAAAAAAXboCaOZGmeaKoxWcSosMkk15W8cZ7VdZaXkcEgQtrxfD9RhHchima1GwlCGUBSFCaFxMrgRtnLFhWujWHhs2nJc8KoVlWGQnEn7/i8XgOwWAB7JwoONQ4KgSQAZRcOgHgSCwsSIhZMNRZ5CzULIgaWF5h4mhecfIQ8jXmQkiODhYeIiRYGjrG2PxgBARi3IhNMAbcCnwI5BAQpAZ8TIwK6vCQVDwUVKL+WzAANTA210g/VJ8OWxQefByQE4dZMzBoInwh4zrtgn2p725YNthUFTNRuGYB3AYGBHCEAACH5BAkJAB0ALAAAAAAgACAAhAQCBISChFRWVMzKzCQiJOTm5GxqbCwuLJSWlPz6/NTW1AwODJSSlGRmZCwqLOzu7HR2dDQ2NAQGBISGhFxaXNTS1CQmJOzq7GxubDQyNKSmpPz+/Nza3AAAAAAAAAAAAAXfYCeOZGmeaKqurHBdAiuP17Zdc0lMAVHWt9yI8LA9fCPB4xEjARoNSWpis01kBpshFahurqzsZosiGpErScMAUO0maKF8Tq/bTQCIQgFp30cQXhB1BHEcXhx0FgkJFiOHVYlzi42AgoRxeRx8fn+en3UABwedKgsBAwMBCygOCjYKDisLFV4VrCUAtVUKpSZdXl8mB8EbByQWcQPFAyYZxccdB7sV0cvBzbmvvG0LBV4FrFTBYCWuNhyyHRTFFB20trh4BxmdYl4YIqepq0IRxRE+IfDCAFQHARo0NGERAgAh+QQJCQAgACwAAAAAIAAgAIUEAgSEgoRMTkzMyswcHhzk5uR0cnQUFhRcXlwsKiz09vQMCgyMiozU1tQkJiR8fnxkZmT8/vwEBgSEhoRcWlzU0tQkIiT08vR0dnQcGhxkYmQ0MjT8+vwMDgyMjozc2twAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG+UCQcEgsGo/IpHLJXDweC6Z0+IhEHlOjRGIMWLHZoUZx0RQlAajxkFFKFFYFl5m5KNpIySU+X2bIBEoQZBBZGQdMElFhjI2Oj5AgHQEDAw8dQxYeDBaNHRVWVhWYCXsRFwmMXqFWEyAerB6MA6xWA6+xs7URt6VWqIwTu64gDh4eDp6goaORQ5OVAZjO1EgEGhB4RwAYDQ0YAEwIcBEKFEgYrBhLBORxgUYfrB9LELuF8fNDAAaVBuEg7NXCVyRdqHVCGLBiIIQAB1Yc4BXh9uEbwAXuyi2iQI7DuSwHdiFqCEGDtizLRFUDsaGAlQIbVoJYIEDAIiZBAAAh+QQJCQAbACwAAAAAIAAgAIQEAgSMioxcWlz08vQcHhysqqwMDgx8enwsKiykoqRkZmT8+vzEwsQMCgyUlpQkJiS0srQEBgSMjoxcXlz09vQkIiSsrqwUEhQ0MjRsamz8/vwAAAAAAAAAAAAAAAAAAAAF7+AmjmRpnmiqruz2PG0sIssCj4CQJAIgj4/abRNJaI6agu9kCAQaphdJgEQKUIFjgGWsahJYLdf7RTWfLKr3+jsBClVlG5Xb9eb4fImgUBBKDVB4ExRHFGwbGRQLGXMEhUgUfw2QC4IyCmSNDQtHlm2ZXgoiGQsUjW0EnUgLfyKBeYSeiHojfH61uS0GBisVEgEVLRcWRxAXKAgDRwMILMVIECgSVRIrBmS9JtRI1iMVBweuGxerSNolyszOIhjLGs0jEFXSKA8SEkMbcEgWIxfzNBxrw6AKgxIGkM05UOWALhERHJhysOThBgAVWYQAACH5BAkJABkALAAAAAAgACAAhAQGBIyKjERCRMzOzCwuLGRiZPz6/OTm5AwODLSytFRSVNTW1Dw6PHx6fAwKDJSSlERGRNTS1DQyNGxqbPz+/BQSFLy6vFRWVNza3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAXqYCaO5FgFwxBUZeu61ULNFMa+eBvQdJD/owFvFhkBBAwHsBQZUooZyWF2YOQkBNJu6ANMaQeli0AxSEwymi0DcUJeEgPlbEJFAghRe/h+Eeg/Dl9UYks5DF9VhksOAgKFi5GSSwh5kzgVCXIJNxknD5aSCTwJIw8zD5MITpanFKmSCHI8NxUPoJejNKWXLZkznL0vCJ3CxsckDpA/ChYJFzkTBgYTSxc80C4OswbLLhY8Fi/bMwYAJVgl4DTiL9LUJADrFuci1zTZLwD1IwU8BSQuWLCQb1EDHg2QiSDALYvCDAISJLDy8FIIACH5BAkJAB4ALAAAAAAgACAAhAQGBISGhFRSVNTW1CQiJKyqrGRmZOzu7CwuLIyOjGxubPz6/BQSFGRiZOTi5CwqLLy6vDQ2NIyKjFRWVCQmJKyurGxqbPT29DQyNJSSlHRydPz+/BQWFOzq7AAAAAAAAAXhoCeOJElYClGubOs117YtjWuvxCLLi3qbhc6h4FPsdorfiNI5dige43GT9AAkHUcCwCpMNxVP7tgTJY4J1uF7EBl0M8Ooueuo2SOCIkVa11kVX2E2EmgsFH4yBz4uAAkdHVstBAUHQ4xKmZqbnJ2bAhAQAiURGJ4eE0cTIxgzpp0QRxCsrp6xO7MjpaepO6unKxOhv8DFxsfIJBwaChw2DAkZDEocDjIOzi0ZMhlKUjIaLtsb3T8aR+EtDBkJ0yQUBQVQI9XX2ZsDMgMlyxr3mzE2XEgmotCGAARFIHiQ0FMIACH5BAkJABgALAAAAAAgACAAhAQCBISGhDw+POTi5CwuLLS2tPTy9BQSFJyenGRiZDQ2NIyOjLy+vPz6/BweHIyKjFRSVOzq7DQyNLy6vBQWFHRydDw6PPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXXICaOZHkcZaquIjVd10SxtFrAcFGrVhBYIwoON9uNAsOA6DCEFTEKBEKxEjQvAtELNxkpGrAGNfW4Plpb2QgxRKjKzfPoVGLj3CnLNUv7hscpSDhKOxJSgDwPP0ZGAACMjAQFDQYFBJA0BAZDBpeYGBQVFUU3TV2YFAMwAzNgTQ2PkBVDFRiuQ7CYszi1pUOnkKmrM5qcnqiiTwQTDQ2Wn9DR0tPUfRKQEBEREDQSFw3XRhEwEd3f4TvjF+XWKgJ8JNnb0QkwCdUlCzAL+CQODAwc9BtIMAQAOw==") !important}.icon-warning{background-repeat:no-repeat;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important}.toaster-icon{font-weight:normal;color:#fff}.toast-content{flex-grow:1;padding:15px 15px 15px 50px}.toast-title{font-weight:bold}.toast-message{word-wrap:break-word}.toast-message a,.toast-message label{color:#fff}.toast-message a:hover{color:#ccc;text-decoration:none}.toast-close-button,button.toast-close-button{align-self:flex-start;padding:3px;font-size:23px;line-height:90%;font-weight:bold;color:#fff;text-shadow:0 1px 0 #fff;opacity:.7;z-index:999;cursor:pointer;background:transparent;border:0}.toast-close-button:hover,.toast-close-button:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;border:none}.toast-close-button span{display:flex;flex-direction:column;align-items:flex-start}.toast-progress-bar{position:absolute;left:0;bottom:0;height:4px;background-color:#000;opacity:.4}.toast-container{position:fixed;z-index:999999;pointer-events:auto}.toast-container.toast-center,.toast-container.toast-top-center,.toast-container.toast-bottom-center{width:100%;pointer-events:none;left:0;right:0}.toast-container.toast-center>div,.toast-container.toast-top-center>div,.toast-container.toast-bottom-center>div{margin:6px auto;pointer-events:auto}.toast-container.toast-center>button,.toast-container.toast-top-center>button,.toast-container.toast-bottom-center>button{pointer-events:auto}.toast-container *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.toast-container>div{margin:0 0 6px;width:300px;border-radius:3px 3px 3px 3px;background-position:15px center;background-repeat:no-repeat;box-shadow:0 0 12px #999;color:#fff;opacity:.8}.toast-container>:hover{box-shadow:0 0 12px #000;opacity:1;cursor:pointer}.toast-container.toast-top-full-width>div,.toast-container.toast-bottom-full-width>div{width:96%;margin:auto}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-center{top:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-center{bottom:12px}.toast-bottom-left{bottom:12px;left:12px}.toast-center{top:45%}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:"FontAwesome";src:url(../fonts/fontawesome-webfont.eot);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0) format("embedded-opentype"),url(../fonts/fontawesome-webfont.woff2) format("woff2"),url(../fonts/fontawesome-webfont.woff) format("woff"),url(../fonts/fontawesome-webfont.ttf) format("truetype"),url(../fonts/fontawesome-webfont.svg#fontawesomeregular) format("svg");font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857em;text-align:center}.fa-ul{padding-left:0;margin-left:2.1428571429em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1428571429em;width:2.1428571429em;top:.1428571429em;text-align:center}.fa-li.fa-lg{left:-1.8571428571em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before{content:""}.fa-check-circle:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:""}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-signing:before,.fa-sign-language:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-vcard:before,.fa-address-card:before{content:""}.fa-vcard-o:before,.fa-address-card-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only,.table tr:not(:hover) td.table-list-options>.dropdown:not(.show) button:not(:focus):not(:active),.table tr:not(:hover) td.table-list-options>button:not(:focus):not(:active){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.swal2-popup.swal2-toast{flex-direction:column;align-items:stretch;width:auto;padding:1.25em;overflow-y:hidden;background:#fff;box-shadow:0 0 .625em #d9d9d9}.swal2-popup.swal2-toast .swal2-header{flex-direction:row;padding:0}.swal2-popup.swal2-toast .swal2-title{flex-grow:1;justify-content:flex-start;margin:0 .625em;font-size:1em}.swal2-popup.swal2-toast .swal2-loading{justify-content:center}.swal2-popup.swal2-toast .swal2-input{height:2em;margin:.3125em auto;font-size:1em}.swal2-popup.swal2-toast .swal2-validation-message{font-size:1em}.swal2-popup.swal2-toast .swal2-footer{margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-popup.swal2-toast .swal2-close{position:static;width:.8em;height:.8em;line-height:.8}.swal2-popup.swal2-toast .swal2-content{justify-content:flex-start;margin:0 .625em;padding:0;font-size:1em;text-align:initial}.swal2-popup.swal2-toast .swal2-html-container{padding:.625em 0 0}.swal2-popup.swal2-toast .swal2-html-container:empty{padding:0}.swal2-popup.swal2-toast .swal2-icon{width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-popup.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}@media all and (-ms-high-contrast: none),(-ms-high-contrast: active){.swal2-popup.swal2-toast .swal2-icon .swal2-icon-content{font-size:.25em}}.swal2-popup.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-popup.swal2-toast .swal2-actions{flex:1;flex-basis:auto !important;align-self:stretch;width:auto;height:2.2em;height:auto;margin:0 .3125em;margin-top:.3125em;padding:0}.swal2-popup.swal2-toast .swal2-styled{margin:.125em .3125em;padding:.3125em .625em;font-size:1em}.swal2-popup.swal2-toast .swal2-styled:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px rgba(100,150,200,.5)}.swal2-popup.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;transform:rotate(45deg);border-radius:50%}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-popup.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}.swal2-popup.swal2-toast.swal2-show{animation:swal2-toast-show .5s}.swal2-popup.swal2-toast.swal2-hide{animation:swal2-toast-hide .1s forwards}.swal2-container{display:flex;position:fixed;z-index:1060;top:0;right:0;bottom:0;left:0;flex-direction:row;align-items:center;justify-content:center;padding:.625em;overflow-x:hidden;transition:background-color .1s;-webkit-overflow-scrolling:touch}.swal2-container.swal2-backdrop-show,.swal2-container.swal2-noanimation{background:rgba(0,0,0,.4)}.swal2-container.swal2-backdrop-hide{background:transparent !important}.swal2-container.swal2-top{align-items:flex-start}.swal2-container.swal2-top-start,.swal2-container.swal2-top-left{align-items:flex-start;justify-content:flex-start}.swal2-container.swal2-top-end,.swal2-container.swal2-top-right{align-items:flex-start;justify-content:flex-end}.swal2-container.swal2-center{align-items:center}.swal2-container.swal2-center-start,.swal2-container.swal2-center-left{align-items:center;justify-content:flex-start}.swal2-container.swal2-center-end,.swal2-container.swal2-center-right{align-items:center;justify-content:flex-end}.swal2-container.swal2-bottom{align-items:flex-end}.swal2-container.swal2-bottom-start,.swal2-container.swal2-bottom-left{align-items:flex-end;justify-content:flex-start}.swal2-container.swal2-bottom-end,.swal2-container.swal2-bottom-right{align-items:flex-end;justify-content:flex-end}.swal2-container.swal2-bottom>:first-child,.swal2-container.swal2-bottom-start>:first-child,.swal2-container.swal2-bottom-left>:first-child,.swal2-container.swal2-bottom-end>:first-child,.swal2-container.swal2-bottom-right>:first-child{margin-top:auto}.swal2-container.swal2-grow-fullscreen>.swal2-modal{display:flex !important;flex:1;align-self:stretch;justify-content:center}.swal2-container.swal2-grow-row>.swal2-modal{display:flex !important;flex:1;align-content:center;justify-content:center}.swal2-container.swal2-grow-column{flex:1;flex-direction:column}.swal2-container.swal2-grow-column.swal2-top,.swal2-container.swal2-grow-column.swal2-center,.swal2-container.swal2-grow-column.swal2-bottom{align-items:center}.swal2-container.swal2-grow-column.swal2-top-start,.swal2-container.swal2-grow-column.swal2-center-start,.swal2-container.swal2-grow-column.swal2-bottom-start,.swal2-container.swal2-grow-column.swal2-top-left,.swal2-container.swal2-grow-column.swal2-center-left,.swal2-container.swal2-grow-column.swal2-bottom-left{align-items:flex-start}.swal2-container.swal2-grow-column.swal2-top-end,.swal2-container.swal2-grow-column.swal2-center-end,.swal2-container.swal2-grow-column.swal2-bottom-end,.swal2-container.swal2-grow-column.swal2-top-right,.swal2-container.swal2-grow-column.swal2-center-right,.swal2-container.swal2-grow-column.swal2-bottom-right{align-items:flex-end}.swal2-container.swal2-grow-column>.swal2-modal{display:flex !important;flex:1;align-content:center;justify-content:center}.swal2-container.swal2-no-transition{transition:none !important}.swal2-container:not(.swal2-top):not(.swal2-top-start):not(.swal2-top-end):not(.swal2-top-left):not(.swal2-top-right):not(.swal2-center-start):not(.swal2-center-end):not(.swal2-center-left):not(.swal2-center-right):not(.swal2-bottom):not(.swal2-bottom-start):not(.swal2-bottom-end):not(.swal2-bottom-left):not(.swal2-bottom-right):not(.swal2-grow-fullscreen)>.swal2-modal{margin:auto}@media all and (-ms-high-contrast: none),(-ms-high-contrast: active){.swal2-container .swal2-modal{margin:0 !important}}.swal2-popup{display:none;position:relative;box-sizing:border-box;flex-direction:column;justify-content:center;width:32em;max-width:100%;padding:1.25em;border:none;border-radius:5px;background:#fff;font-family:inherit;font-size:1rem}.swal2-popup:focus{outline:none}.swal2-popup.swal2-loading{overflow-y:hidden}.swal2-header{display:flex;flex-direction:column;align-items:center;padding:0 1.8em}.swal2-title{position:relative;max-width:100%;margin:0 0 .4em;padding:0;color:#595959;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word}.swal2-actions{display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:100%;margin:1.25em auto 0;padding:0}.swal2-actions:not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}.swal2-actions:not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1))}.swal2-actions:not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2))}.swal2-loader{display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 transparent #2778c4 transparent}.swal2-styled{margin:.3125em;padding:.625em 1.1em;box-shadow:none;font-weight:500}.swal2-styled:not([disabled]){cursor:pointer}.swal2-styled.swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:#2778c4;color:#fff;font-size:1em}.swal2-styled.swal2-deny{border:0;border-radius:.25em;background:initial;background-color:#d14529;color:#fff;font-size:1em}.swal2-styled.swal2-cancel{border:0;border-radius:.25em;background:initial;background-color:#757575;color:#fff;font-size:1em}.swal2-styled:focus{outline:none;box-shadow:0 0 0 3px rgba(100,150,200,.5)}.swal2-styled::-moz-focus-inner{border:0}.swal2-footer{justify-content:center;margin:1.25em 0 0;padding:1em 0 0;border-top:1px solid #eee;color:#545454;font-size:1em}.swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;height:.25em;overflow:hidden;border-bottom-right-radius:5px;border-bottom-left-radius:5px}.swal2-timer-progress-bar{width:100%;height:.25em;background:rgba(0,0,0,.2)}.swal2-image{max-width:100%;margin:1.25em auto}.swal2-close{position:absolute;z-index:2;top:0;right:0;align-items:center;justify-content:center;width:1.2em;height:1.2em;padding:0;overflow:hidden;transition:color .1s ease-out;border:none;border-radius:5px;background:transparent;color:#ccc;font-family:serif;font-size:2.5em;line-height:1.2;cursor:pointer}.swal2-close:hover{transform:none;background:transparent;color:#f27474}.swal2-close:focus{outline:none;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}.swal2-close::-moz-focus-inner{border:0}.swal2-content{z-index:1;justify-content:center;margin:0;padding:0 1.6em;color:#545454;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;word-wrap:break-word}.swal2-input,.swal2-file,.swal2-textarea,.swal2-select,.swal2-radio,.swal2-checkbox{margin:1em auto}.swal2-input,.swal2-file,.swal2-textarea{box-sizing:border-box;width:100%;transition:border-color .3s,box-shadow .3s;border:1px solid #d9d9d9;border-radius:.1875em;background:inherit;box-shadow:inset 0 1px 1px rgba(0,0,0,.06);color:inherit;font-size:1.125em}.swal2-input.swal2-inputerror,.swal2-file.swal2-inputerror,.swal2-textarea.swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}.swal2-input:focus,.swal2-file:focus,.swal2-textarea:focus{border:1px solid #b4dbed;outline:none;box-shadow:0 0 0 3px rgba(100,150,200,.5)}.swal2-input::placeholder,.swal2-file::placeholder,.swal2-textarea::placeholder{color:#ccc}.swal2-range{margin:1em auto;background:#fff}.swal2-range input{width:80%}.swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}.swal2-range input,.swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}.swal2-input{height:2.625em;padding:0 .75em}.swal2-input[type=number]{max-width:10em}.swal2-file{background:inherit;font-size:1.125em}.swal2-textarea{height:6.75em;padding:.75em}.swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:inherit;color:inherit;font-size:1.125em}.swal2-radio,.swal2-checkbox{align-items:center;justify-content:center;background:#fff;color:inherit}.swal2-radio label,.swal2-checkbox label{margin:0 .6em;font-size:1.125em}.swal2-radio input,.swal2-checkbox input{flex-shrink:0;margin:0 .4em}.swal2-input-label{display:flex;justify-content:center;margin:1em auto}.swal2-validation-message{align-items:center;justify-content:center;margin:0 -2.7em;padding:.625em;overflow:hidden;background:#f0f0f0;color:#666;font-size:1em;font-weight:300}.swal2-validation-message::before{content:"!";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}.swal2-icon{position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:1.25em auto 1.875em;border:0.25em solid transparent;border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}.swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}.swal2-icon.swal2-error{border-color:#f27474;color:#f27474}.swal2-icon.swal2-error .swal2-x-mark{position:relative;flex-grow:1}.swal2-icon.swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}.swal2-icon.swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}.swal2-icon.swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}.swal2-icon.swal2-warning{border-color:#facea8;color:#f8bb86}.swal2-icon.swal2-info{border-color:#9de0f6;color:#3fc3ee}.swal2-icon.swal2-question{border-color:#c9dae1;color:#87adbd}.swal2-icon.swal2-success{border-color:#a5dc86;color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;transform:rotate(45deg);border-radius:50%}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}.swal2-icon.swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}.swal2-icon.swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}.swal2-icon.swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}.swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}.swal2-icon.swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}.swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:0 0 1.25em;padding:0;background:inherit;font-weight:600}.swal2-progress-steps li{display:inline-block;position:relative}.swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:#add8e6;color:#fff}.swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:#add8e6}.swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}[class^=swal2]{-webkit-tap-highlight-color:transparent}.swal2-show{animation:swal2-show .3s}.swal2-hide{animation:swal2-hide .15s forwards}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{right:auto;left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}@supports(-ms-accelerator: true){.swal2-range input{width:100% !important}.swal2-range output{display:none}}@media all and (-ms-high-contrast: none),(-ms-high-contrast: active){.swal2-range input{width:100% !important}.swal2-range output{display:none}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}@keyframes swal2-show{0%{transform:scale(0.7)}45%{transform:scale(1.05)}80%{transform:scale(0.95)}100%{transform:scale(1)}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(0.5);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{top:auto;right:auto;bottom:auto;left:auto;max-width:calc(100% - 0.625em * 2);background-color:transparent !important}body.swal2-no-backdrop .swal2-container>.swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}body.swal2-no-backdrop .swal2-container.swal2-top{top:0;left:50%;transform:translateX(-50%)}body.swal2-no-backdrop .swal2-container.swal2-top-start,body.swal2-no-backdrop .swal2-container.swal2-top-left{top:0;left:0}body.swal2-no-backdrop .swal2-container.swal2-top-end,body.swal2-no-backdrop .swal2-container.swal2-top-right{top:0;right:0}body.swal2-no-backdrop .swal2-container.swal2-center{top:50%;left:50%;transform:translate(-50%, -50%)}body.swal2-no-backdrop .swal2-container.swal2-center-start,body.swal2-no-backdrop .swal2-container.swal2-center-left{top:50%;left:0;transform:translateY(-50%)}body.swal2-no-backdrop .swal2-container.swal2-center-end,body.swal2-no-backdrop .swal2-container.swal2-center-right{top:50%;right:0;transform:translateY(-50%)}body.swal2-no-backdrop .swal2-container.swal2-bottom{bottom:0;left:50%;transform:translateX(-50%)}body.swal2-no-backdrop .swal2-container.swal2-bottom-start,body.swal2-no-backdrop .swal2-container.swal2-bottom-left{bottom:0;left:0}body.swal2-no-backdrop .swal2-container.swal2-bottom-end,body.swal2-no-backdrop .swal2-container.swal2-bottom-right{right:0;bottom:0}@media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:static !important}}body.swal2-toast-shown .swal2-container{background-color:transparent}body.swal2-toast-shown .swal2-container.swal2-top{top:0;right:auto;bottom:auto;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{top:0;right:0;bottom:auto;left:auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{top:0;right:auto;bottom:auto;left:0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{top:50%;right:auto;bottom:auto;left:0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{top:50%;right:auto;bottom:auto;left:50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{top:50%;right:0;bottom:auto;left:auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{top:auto;right:auto;bottom:0;left:0}body.swal2-toast-shown .swal2-container.swal2-bottom{top:auto;right:auto;bottom:0;left:50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{top:auto;right:0;bottom:0;left:auto}html{font-size:14px}body{min-width:1010px}@media(prefers-color-scheme: dark){body.layout_frontend{background-color:#1f242e}}@media(prefers-color-scheme: light){body.layout_frontend{background-color:#fff}}html.theme_light body.layout_frontend{background-color:#ecf0f5;color:#333}html.theme_dark body.layout_frontend{background-color:#1f242e;color:#fff}html.theme_light body{background-color:#fff;color:#333}html.theme_dark body{background-color:#1f242e;color:#bac0ce}body.full-width:not(.layout_frontend) .container{min-width:980px;width:90%}.container{margin:0 auto;max-width:none !important;padding:0;width:980px}.page-header,.secondary-header{margin-bottom:.5rem;padding-bottom:.6rem}html.theme_light .page-header,html.theme_light .secondary-header{border-bottom:1px solid #ced4da}html.theme_dark .page-header,html.theme_dark .secondary-header{border-bottom:1px solid #4c525f}.page-header:not(.text-danger) h1,.page-header:not(.text-danger) h2,.page-header:not(.text-danger) h3,.page-header:not(.text-danger) h4,.secondary-header:not(.text-danger) h1,.secondary-header:not(.text-danger) h2,.secondary-header:not(.text-danger) h3,.secondary-header:not(.text-danger) h4{margin:0}html.theme_light .page-header:not(.text-danger) h1,html.theme_light .page-header:not(.text-danger) h2,html.theme_light .page-header:not(.text-danger) h3,html.theme_light .page-header:not(.text-danger) h4,html.theme_light .secondary-header:not(.text-danger) h1,html.theme_light .secondary-header:not(.text-danger) h2,html.theme_light .secondary-header:not(.text-danger) h3,html.theme_light .secondary-header:not(.text-danger) h4{color:#333}html.theme_dark .page-header:not(.text-danger) h1,html.theme_dark .page-header:not(.text-danger) h2,html.theme_dark .page-header:not(.text-danger) h3,html.theme_dark .page-header:not(.text-danger) h4,html.theme_dark .secondary-header:not(.text-danger) h1,html.theme_dark .secondary-header:not(.text-danger) h2,html.theme_dark .secondary-header:not(.text-danger) h3,html.theme_dark .secondary-header:not(.text-danger) h4{color:#fff}.secondary-header,.spaced-header{margin-top:4rem}img.logo{display:block;height:43px;margin:0 auto;width:284px}html.theme_light img.logo.logo-themed{content:url(../images/logo-dark@2x.png)}html.theme_dark img.logo.logo-themed{content:url(../images/logo-white@2x.png)}.page-content{margin-top:20px}.footer{margin-top:40px;padding:40px 0 40px 0}html.theme_light .footer{border-top:1px solid #ced4da}html.theme_dark .footer{border-top:1px solid #4c525f}html.theme_light hr,html.theme_light .dropdown-divider{border-top:1px solid rgba(0,0,0,.1)}html.theme_dark hr,html.theme_dark .dropdown-divider{border-top:1px solid #4c525f}.min-height-fix{min-height:1px}.overflow-hidden{overflow:hidden}.cursor-move{cursor:move !important}html.theme_light h1,html.theme_light h2,html.theme_light h3,html.theme_light h4,html.theme_light h5{color:#333}html.theme_dark h1,html.theme_dark h2,html.theme_dark h3,html.theme_dark h4,html.theme_dark h5{color:#fff}h1 small,h2 small,h3 small,h4 small,h5 small{font-size:80%}html.theme_light h1.spaced-header,html.theme_light h2.spaced-header,html.theme_light h3.spaced-header,html.theme_light h4.spaced-header,html.theme_light h5.spaced-header{color:#333}html.theme_dark h1.spaced-header,html.theme_dark h2.spaced-header,html.theme_dark h3.spaced-header,html.theme_dark h4.spaced-header,html.theme_dark h5.spaced-header{color:#fff}html.theme_light a{color:#175ddc}html.theme_dark a{color:#6a99f0}html.theme_light a.text-body{color:#333 !important;font-weight:400}html.theme_dark a.text-body{color:#fff !important;font-weight:600}html.theme_light code{color:#e83e8c}html.theme_dark code{color:#e83e8c}.fa-icon-above-input{height:1.5em}.text-lg{font-size:1.15rem}.text-strike{text-decoration:line-through}.font-weight-semibold{font-weight:600}html.theme_light .btn:focus,.swal2-popup .swal2-actions html.theme_light button:focus,html.theme_light .swal2-popup .swal2-actions button:focus,html.theme_light .btn.focus,.swal2-popup .swal2-actions html.theme_light button.focus,html.theme_light .swal2-popup .swal2-actions button.focus,html.theme_light .form-control:focus{box-shadow:0 0 0 .2rem rgba(23,93,220,.25)}html.theme_dark .btn:focus,.swal2-popup .swal2-actions html.theme_dark button:focus,html.theme_dark .swal2-popup .swal2-actions button:focus,html.theme_dark .btn.focus,.swal2-popup .swal2-actions html.theme_dark button.focus,html.theme_dark .swal2-popup .swal2-actions button.focus,html.theme_dark .form-control:focus{box-shadow:0 0 0 .2rem rgba(106,153,240,.25)}html.theme_light .bg-primary{background-color:#175ddc}html.theme_dark .bg-primary{background-color:#6a99f0}html.theme_light .bg-light{background-color:#f8f9fa !important}html.theme_dark .bg-light{background-color:#1f242e !important}html.theme_light .bg-success{background-color:#00a65a !important;color:#fff !important}html.theme_dark .bg-success{background-color:#52e07c !important;color:#1f242e !important}html.theme_light .bg-warning{background-color:#bf7e16 !important;color:#fff !important}html.theme_dark .bg-warning{background-color:#ffeb66 !important;color:#1f242e !important}html.theme_light .bg-error,html.theme_light .bg-danger{background-color:#dd4b39 !important;color:#fff !important}html.theme_dark .bg-error,html.theme_dark .bg-danger{background-color:#ff8d85 !important;color:#1f242e !important}html.theme_light .bg-info{background-color:#343a40 !important;color:#fff !important}html.theme_dark .bg-info{background-color:#a4b0c6 !important;color:#1f242e !important}html.theme_light .border-primary{border-color:#175ddc !important}html.theme_dark .border-primary{border-color:#6a99f0 !important}html.theme_light .border-warning{border-color:#bf7e16 !important}html.theme_dark .border-warning{border-color:#ffeb66 !important}html.theme_light .border-danger{border-color:#dd4b39 !important}html.theme_dark .border-danger{border-color:#ff8d85 !important}html.theme_light .border-info{border-color:#343a40 !important}html.theme_dark .border-info{border-color:#a4b0c6 !important}html.theme_light .text-success{color:#00a65a !important}html.theme_dark .text-success{color:#52e07c !important}html.theme_light .text-success>h1,html.theme_light .text-success h2,html.theme_light .text-success h3,html.theme_light .text-success h4{color:#00a65a !important}html.theme_dark .text-success>h1,html.theme_dark .text-success h2,html.theme_dark .text-success h3,html.theme_dark .text-success h4{color:#52e07c !important}html.theme_light .text-warning{color:#bf7e16 !important}html.theme_dark .text-warning{color:#ffeb66 !important}html.theme_light .text-warning>h1,html.theme_light .text-warning h2,html.theme_light .text-warning h3,html.theme_light .text-warning h4{color:#bf7e16 !important}html.theme_dark .text-warning>h1,html.theme_dark .text-warning h2,html.theme_dark .text-warning h3,html.theme_dark .text-warning h4{color:#ffeb66 !important}html.theme_light .text-danger:not(.dropdown-item){color:#dd4b39 !important}html.theme_dark .text-danger:not(.dropdown-item){color:#ff8d85 !important}html.theme_light .text-danger:not(.dropdown-item)>h1,html.theme_light .text-danger:not(.dropdown-item) h2,html.theme_light .text-danger:not(.dropdown-item) h3,html.theme_light .text-danger:not(.dropdown-item) h4{color:#dd4b39 !important}html.theme_dark .text-danger:not(.dropdown-item)>h1,html.theme_dark .text-danger:not(.dropdown-item) h2,html.theme_dark .text-danger:not(.dropdown-item) h3,html.theme_dark .text-danger:not(.dropdown-item) h4{color:#ff8d85 !important}html.theme_light .text-muted,html.theme_light .card-header small,.card-header html.theme_light small,html.theme_light .modal-header small,.modal-header html.theme_light small{color:#6c757d !important}html.theme_dark .text-muted,html.theme_dark .card-header small,.card-header html.theme_dark small,html.theme_dark .modal-header small,.modal-header html.theme_dark small{color:#bac0ce !important}html.theme_light .btn-primary,html.theme_light .swal2-confirm{background-color:#175ddc;border-color:#175ddc;color:#fff}html.theme_dark .btn-primary,html.theme_dark .swal2-confirm{background-color:#6a99f0;border-color:#6a99f0;color:#1f242e}html.theme_light .btn-primary:hover:not(:disabled),html.theme_light .btn-primary:active:not(:disabled),html.theme_light .swal2-confirm:hover:not(:disabled),html.theme_light .swal2-confirm:active:not(:disabled){background-color:#134eb9;border-color:#1249ae;color:#fff}html.theme_dark .btn-primary:hover:not(:disabled),html.theme_dark .btn-primary:active:not(:disabled),html.theme_dark .swal2-confirm:hover:not(:disabled),html.theme_dark .swal2-confirm:active:not(:disabled){background-color:#b4ccf9;border-color:#b4ccf9;color:#1f242e}.btn-primary:disabled,.swal2-confirm:disabled{opacity:.65}html.theme_light .btn-outline-primary{background-color:#fbfbfb;border-color:#ced4da;color:#175ddc}html.theme_dark .btn-outline-primary{background-color:#6a99f0;border-color:#6a99f0;color:#1f242e}html.theme_light .btn-outline-primary:hover:not(:disabled),html.theme_light .btn-outline-primary:active{background-color:#175ddc;border-color:#175ddc;color:#fff}html.theme_dark .btn-outline-primary:hover:not(:disabled),html.theme_dark .btn-outline-primary:active{background-color:#b4ccf9;border-color:#b4ccf9;color:#1f242e}html.theme_light .btn-secondary,html.theme_light .swal2-cancel{background-color:#ced4da;border-color:#ced4da;color:#212529}html.theme_dark .btn-secondary,html.theme_dark .swal2-cancel{background-color:transparent;border-color:#bac0ce;color:#fff}html.theme_light .btn-secondary:hover:not(:disabled),html.theme_light .btn-secondary:active:not(:disabled),html.theme_light .swal2-cancel:hover:not(:disabled),html.theme_light .swal2-cancel:active:not(:disabled){background-color:#b8c1ca;border-color:#b1bbc4;color:#212529}html.theme_dark .btn-secondary:hover:not(:disabled),html.theme_dark .btn-secondary:active:not(:disabled),html.theme_dark .swal2-cancel:hover:not(:disabled),html.theme_dark .swal2-cancel:active:not(:disabled){background-color:transparent;border-color:#8d94a5;color:#8d94a5}.btn-secondary:disabled,.swal2-cancel:disabled{opacity:.65}html.theme_light .btn-secondary:focus,html.theme_light .btn-secondary.focus,html.theme_light .swal2-cancel:focus,html.theme_light .swal2-cancel.focus{box-shadow:0 0 0 .2rem rgba(58,117,225,.5)}html.theme_dark .btn-secondary:focus,html.theme_dark .btn-secondary.focus,html.theme_dark .swal2-cancel:focus,html.theme_dark .swal2-cancel.focus{box-shadow:0 0 0 .2rem rgba(128,168,242,.5)}html.theme_light .btn-outline-secondary{background-color:#fbfbfb;border-color:#ced4da;color:#6c757d}html.theme_dark .btn-outline-secondary{background-color:transparent;border-color:#bac0ce;color:#fff}html.theme_light .btn-outline-secondary:hover:not(:disabled),html.theme_light .btn-outline-secondary:active{background-color:#ced4da;border-color:#ced4da;color:#333}html.theme_dark .btn-outline-secondary:hover:not(:disabled),html.theme_dark .btn-outline-secondary:active{background-color:transparent;border-color:#8d94a5;color:#8d94a5}html.theme_light .show>.btn-outline-secondary.dropdown-toggle,html.theme_light .show>.btn-outline-secondary:focus{background-color:#fbfbfb;border-color:#ced4da;color:#6c757d}html.theme_dark .show>.btn-outline-secondary.dropdown-toggle,html.theme_dark .show>.btn-outline-secondary:focus{background-color:transparent;border-color:#bac0ce;color:#fff}html.theme_light .show>.btn-outline-secondary:hover{background-color:#ced4da;border-color:#ced4da;color:#333}html.theme_dark .show>.btn-outline-secondary:hover{background-color:transparent;border-color:#8d94a5;color:#8d94a5}html.theme_light .btn-danger,html.theme_light .swal2-deny{background-color:#dd4b39;border-color:#dd4b39;color:#fff}html.theme_dark .btn-danger,html.theme_dark .swal2-deny{background-color:#ff8d85;border-color:#ff8d85;color:#1f242e}html.theme_light .btn-danger:hover:not(:disabled),html.theme_light .btn-danger:active:not(:disabled),html.theme_light .swal2-deny:hover:not(:disabled),html.theme_light .swal2-deny:active:not(:disabled){background-color:#c43421;border-color:#c43421;color:#fff}html.theme_dark .btn-danger:hover:not(:disabled),html.theme_dark .btn-danger:active:not(:disabled),html.theme_dark .swal2-deny:hover:not(:disabled),html.theme_dark .swal2-deny:active:not(:disabled){background-color:#ffbfbb;border-color:#ffbfbb;color:#1f242e}html.theme_light .btn-outline-danger{background-color:#fbfbfb;border-color:#ced4da;color:#dd4b39}html.theme_dark .btn-outline-danger{background-color:#ff8d85;border-color:#ff8d85;color:#1f242e}html.theme_light .btn-outline-danger:hover:not(:disabled),html.theme_light .btn-outline-danger:active{background-color:#dd4b39;border-color:#dd4b39;color:#fff}html.theme_dark .btn-outline-danger:hover:not(:disabled),html.theme_dark .btn-outline-danger:active{background-color:#ffbfbb;border-color:#ffbfbb;color:#1f242e}.btn-link:focus,.btn-link.focus{outline-color:-webkit-focus-ring-color;outline-offset:1px;outline-style:auto;outline-width:1px}html.theme_dark .btn-link:not(.text-danger):not(.cursor-move){color:#fff}html.theme_dark .btn-link:hover:not(.text-danger):not(.cursor-move){color:#bac0ce}.btn-submit{position:relative}.btn-submit .fa-spinner{align-items:center;bottom:0;display:none;justify-content:center;left:0;position:absolute;right:0;top:0}.btn-submit:disabled:not(.manual) .fa-spinner,.btn-submit.loading .fa-spinner{display:flex}.btn-submit:disabled:not(.manual) span,.btn-submit.loading span{visibility:hidden}html.theme_light .badge-primary{background-color:#175ddc;color:#fff}html.theme_dark .badge-primary{background-color:#6a99f0;color:#1f242e}html.theme_light .badge-primary:hover{background-color:#134eb9;color:#fff}html.theme_dark .badge-primary:hover{background-color:#b4ccf9;color:#1f242e}html.theme_light .badge-secondary{background-color:#ced4da;color:#212529}html.theme_dark .badge-secondary{background-color:#8d94a5;color:#1f242e}html.theme_light .badge-info{background-color:#555;color:#fff}html.theme_dark .badge-info{background-color:#a4b0c6;color:#1f242e}html.theme_light .badge-danger{background-color:#dd4b39;color:#fff}html.theme_dark .badge-danger{background-color:#ff8d85;color:#1f242e}html.theme_light .badge-warning{background-color:#bf7e16;color:#fff}html.theme_dark .badge-warning{background-color:#ffeb66;color:#1f242e}html.theme_light .badge-success{background-color:#00a65a;color:#fff}html.theme_dark .badge-success{background-color:#52e07c;color:#1f242e}.callout{border-left-width:5px !important;border-radius:calc(0.25rem - 1px);margin-bottom:1rem;padding:.75rem 1.25rem}html.theme_light .callout{background-color:#fafafa;border:1px solid #ced4da;color:#212529}html.theme_dark .callout{background-color:#3c424e;border:1px solid #4c525f;color:#fff}.callout .callout-heading{margin-top:0}.callout h3.callout-heading{font-weight:bold;text-transform:uppercase}html.theme_light .callout.callout-primary{border-left-color:#175ddc}html.theme_dark .callout.callout-primary{border-left-color:#6a99f0}html.theme_light .callout.callout-primary .callout-heading{color:#175ddc}html.theme_dark .callout.callout-primary .callout-heading{color:#6a99f0}html.theme_light .callout.callout-info{border-left-color:#343a40}html.theme_dark .callout.callout-info{border-left-color:#a4b0c6}html.theme_light .callout.callout-info .callout-heading{color:#343a40}html.theme_dark .callout.callout-info .callout-heading{color:#a4b0c6}html.theme_light .callout.callout-danger{border-left-color:#dd4b39}html.theme_dark .callout.callout-danger{border-left-color:#ff8d85}html.theme_light .callout.callout-danger .callout-heading{color:#dd4b39}html.theme_dark .callout.callout-danger .callout-heading{color:#ff8d85}html.theme_light .callout.callout-success{border-left-color:#00a65a}html.theme_dark .callout.callout-success{border-left-color:#52e07c}html.theme_light .callout.callout-success .callout-heading{color:#00a65a}html.theme_dark .callout.callout-success .callout-heading{color:#52e07c}html.theme_light .callout.callout-warning{border-left-color:#bf7e16}html.theme_dark .callout.callout-warning{border-left-color:#ffeb66}html.theme_light .callout.callout-warning .callout-heading{color:#bf7e16}html.theme_dark .callout.callout-warning .callout-heading{color:#ffeb66}.callout .enforced-policy-options ul{margin-bottom:0px}html.theme_light .card{background-color:#fff;border-color:#ced4da;color:#333}html.theme_dark .card{background-color:#2f343d;border-color:#4c525f;color:#bac0ce}html.theme_light .card.text-danger.text-danger>.card-body{color:#dd4b39}html.theme_dark .card.text-danger.text-danger>.card-body{color:#ff8d85}.card-header,.modal-header{font-weight:bold;text-transform:uppercase}.card-header small,.modal-header small{font-weight:normal;text-transform:none}html.theme_light .card-header{background-color:rgba(0,0,0,.03);color:#333}html.theme_dark .card-header{background-color:#4c525f;color:#fff}html.theme_light .card-header a:hover:not(.badge){color:#104097}html.theme_dark .card-header a:hover:not(.badge){color:#b4ccf9}.card-body-header{font-size:1.15rem}.card ul.fa-ul.card-ul{margin-left:1.9em}.card ul.fa-ul.card-ul li{word-break:break-all}.card ul.fa-ul.card-ul .fa-li{top:4px}.card ul.fa-ul.card-ul.carets{margin-left:1.1em}.card ul.fa-ul.card-ul.carets .fa-li{left:-17px;width:1.1em}.card ul.fa-ul.card-ul ul.carets{margin-left:.85em}.card-org-plans h2{font-size:1.15rem}html.theme_light .card-body:not(.bg-light>.card-body){background-color:#fff;color:#333}html.theme_dark .card-body:not(.bg-light>.card-body){background-color:#2f343d;color:#bac0ce}html.theme_light .card-body:not(.bg-light>.card-body).card-body a:not(li a){font-weight:400}html.theme_dark .card-body:not(.bg-light>.card-body).card-body a:not(li a){font-weight:600}::-ms-reveal{display:none}html.theme_light ::placeholder{color:#b6b8b8}html.theme_dark ::placeholder{color:#bac0ce}input:required,select:required,textarea:required{box-shadow:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:-cancel-button}label:not(.form-check-label):not(.btn),label.bold{font-weight:600}html.theme_light label:not(.form-check-label):not(.btn),html.theme_light label.bold{color:#333}html.theme_dark label:not(.form-check-label):not(.btn),html.theme_dark label.bold{color:#fff}html.theme_light label.form-check-label,html.theme_light .form-control-file{color:#333}html.theme_dark label.form-check-label,html.theme_dark .form-control-file{color:#fff}.form-check-block .form-check-label{font-weight:600}.form-check-block .form-check-label>small{display:block;font-weight:normal}html.theme_light .form-check-block .form-check-label>small{color:#6c757d}html.theme_dark .form-check-block .form-check-label>small{color:#bac0ce}.form-check-block .form-check-label>span{display:block;font-weight:normal}.form-inline input[type=datetime-local]{width:200px}html.theme_light .form-control{background-color:#fbfbfb;border-color:#ced4da;color:#465057}html.theme_dark .form-control{background-color:transparent;border-color:#bac0ce;color:#fff}html.theme_light .form-control:disabled,html.theme_light .form-control[readonly]{background-color:#e0e0e0;color:#6c757d}html.theme_dark .form-control:disabled,html.theme_dark .form-control[readonly]{background-color:#3c424e;color:#bac0ce}input[type=radio],input[type=checkbox]{cursor:pointer}.form-control.stripe-form-control{padding-top:.55rem}.form-control.stripe-form-control.is-focused{outline:0}html.theme_light .form-control.stripe-form-control.is-focused{background-color:#fbfbfb;border-color:#ced4da;box-shadow:0 0 0 .2rem rgba(58,117,225,.5);color:#465057}html.theme_dark .form-control.stripe-form-control.is-focused{background-color:transparent;border-color:#bac0ce;box-shadow:0 0 0 .2rem rgba(128,168,242,.5);color:#fff}.form-control.stripe-form-control.is-focused.is-invalid{opacity:.75}html.theme_light .form-control.stripe-form-control.is-focused.is-invalid{box-shadow:0 0 0 .2rem #dd4b39}html.theme_dark .form-control.stripe-form-control.is-focused.is-invalid{box-shadow:0 0 0 .2rem #ff8d85}html.theme_light .form-control.stripe-form-control.is-invalid{border-color:#dd4b39}html.theme_dark .form-control.stripe-form-control.is-invalid{border-color:#ff8d85}html.theme_light .dropdown-menu,html.theme_light .dropdown-item{background-color:#fff;color:#333}html.theme_dark .dropdown-menu,html.theme_dark .dropdown-item{background-color:#2f343d;color:#fff}html.theme_light .dropdown-item{color:#333}html.theme_dark .dropdown-item{color:#fff}html.theme_light .dropdown-item.text-danger{color:#dd4b39 !important}html.theme_dark .dropdown-item.text-danger{color:#ff8d85 !important}html.theme_light .dropdown-item:hover{background-color:rgba(0,0,0,.06)}html.theme_dark .dropdown-item:hover{background-color:rgba(255,255,255,.03)}.dropdown-item:active{background-color:rgba(0,0,0,.1) !important}.dropdown-menu button{cursor:pointer}html.theme_light .dropdown-menu{border:1px solid rgba(0,0,0,.125)}html.theme_dark .dropdown-menu{border:1px solid #4c525f}.list-group-item:focus,.list-group-item.focus{z-index:100}html.theme_light .list-group-item{background-color:#fff;border-color:rgba(0,0,0,.125);color:#333}html.theme_dark .list-group-item{background-color:#2f343d;border-color:#4c525f;color:#bac0ce}.list-group-item>.two-factor-content{justify-content:center;flex-direction:row;display:flex}.list-group-item>.two-factor-content>.text-col{flex-direction:column;flex:1}.list-group-item>.two-factor-content>.logo-col{min-width:100px;margin-right:20px;display:flex;align-items:center;justify-content:center}.list-group-item>.two-factor-content>.logo-col img{height:fit-content}.list-group-item>.two-factor-content>.btn-col{width:85px;display:flex;align-items:center;justify-content:center}.list-group-item.active{font-weight:bold !important;padding-left:calc(1.25rem - 3px)}html.theme_light .list-group-item.active{border-color:#ced4da;border-left:3px solid #175ddc;color:#333}html.theme_dark .list-group-item.active{border-color:#4c525f;border-left:3px solid #6a99f0;color:#6a99f0}html.theme_light ::-webkit-calendar-picker-indicator,html.theme_light input::-webkit-caps-lock-indicator,html.theme_light input::-webkit-credentials-auto-fill-button{filter:invert(0)}html.theme_dark ::-webkit-calendar-picker-indicator,html.theme_dark input::-webkit-caps-lock-indicator,html.theme_dark input::-webkit-credentials-auto-fill-button{filter:invert(1)}.navbar{padding-left:0;padding-right:0}html.theme_light .navbar{background-color:#175ddc}html.theme_dark .navbar{background-color:#2f343d}html.theme_light .navbar.nav-background-alt{background-color:#1a3b66}html.theme_dark .navbar.nav-background-alt{background-color:#2f343d}.navbar .dropdown-menu{max-width:300px;min-width:200px}.navbar .dropdown-menu .dropdown-item-text{line-height:1.3}html.theme_light .navbar .dropdown-menu .dropdown-item-text{color:#333}html.theme_dark .navbar .dropdown-menu .dropdown-item-text{color:#fff}.navbar .dropdown-menu .dropdown-item-text span,.navbar .dropdown-menu .dropdown-item-text small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}html.theme_light .navbar .dropdown-menu .dropdown-item-text span.text-muted,html.theme_light .navbar .dropdown-menu .dropdown-item-text small.text-muted,html.theme_light .navbar .dropdown-menu .dropdown-item-text .card-header small,.card-header html.theme_light .navbar .dropdown-menu .dropdown-item-text small,html.theme_light .navbar .dropdown-menu .dropdown-item-text .modal-header small,.modal-header html.theme_light .navbar .dropdown-menu .dropdown-item-text small{color:#6c757d !important}html.theme_dark .navbar .dropdown-menu .dropdown-item-text span.text-muted,html.theme_dark .navbar .dropdown-menu .dropdown-item-text small.text-muted,html.theme_dark .navbar .dropdown-menu .dropdown-item-text .card-header small,.card-header html.theme_dark .navbar .dropdown-menu .dropdown-item-text small,html.theme_dark .navbar .dropdown-menu .dropdown-item-text .modal-header small,.modal-header html.theme_dark .navbar .dropdown-menu .dropdown-item-text small{color:#bec6cf !important}html.theme_light .navbar .nav-item>.nav-link{font-weight:600}html.theme_dark .navbar .nav-item>.nav-link{font-weight:400}html.theme_light .navbar .nav-item.active>.nav-link{font-weight:600}html.theme_dark .navbar .nav-item.active>.nav-link{font-weight:600}.navbar-brand{margin-bottom:-20px;margin-top:-20px}html.theme_light .nav-tabs .nav-link.active{background:#fff;border-color:#ced4da}html.theme_dark .nav-tabs .nav-link.active{background:#1f242e;border-color:#4c525f}.org-nav{height:100px;min-height:100px}html.theme_light .org-nav{background-color:#fbfbfb;border-bottom:1px solid #ced4da;color:#333}html.theme_dark .org-nav{background-color:#161c26;border-bottom:1px solid #4c525f;color:#bac0ce}.org-nav .container{height:100%}.org-nav .nav-tabs{border-bottom:none}.org-nav .nav-tabs a:not(.active){border-color:transparent}html.theme_light .org-nav .nav-tabs a:not(.active){color:#333}html.theme_dark .org-nav .nav-tabs a:not(.active){color:#bac0ce}.org-nav .nav-tabs a.active{font-weight:bold;padding-top:calc(0.5rem - 2px)}html.theme_light .org-nav .nav-tabs a.active{border-top:3px solid #175ddc;color:#175ddc}html.theme_dark .org-nav .nav-tabs a.active{border-top:3px solid #6a99f0;color:#6a99f0}html.theme_light .org-nav .nav-tabs a.disabled{color:#6c757d}html.theme_dark .org-nav .nav-tabs a.disabled{color:#bac0ce}.org-nav .org-name{line-height:1}.org-nav .org-name span{display:block;font-size:1.15rem}html.theme_light .org-nav .org-name span{color:#333}html.theme_dark .org-nav .org-name span{color:#fff}.modal-content{border:none;border-radius:none}html.theme_light .modal-content{background-color:#fff}html.theme_dark .modal-content{background-color:#1f242e}.modal-dialog{border:1px solid rgba(0,0,0,.2);border-radius:.3rem;width:500px}.modal-sm{width:300px}.modal-lg{width:800px}html.theme_light .modal-header{background-color:#fff;border-bottom:1px solid #ced4da;color:#333}html.theme_dark .modal-header{background-color:#2f343d;border-bottom:1px solid #4c525f;color:#bac0ce}html.theme_light .modal-body{background-color:#fff;color:#333}html.theme_dark .modal-body{background-color:#2f343d;color:#bac0ce}.modal-body h3,.modal-body .section-header>*{font-weight:normal;text-transform:uppercase}html.theme_light .modal-body h3,html.theme_light .modal-body .section-header>*{color:#6c757d}html.theme_dark .modal-body h3,html.theme_dark .modal-body .section-header>*{color:#bac0ce}.modal .list-group-flush :first-child{border-top:none}.modal .list-group-flush :last-child{border-bottom:none}.modal .list-group-flush-2fa div{border-left:none;border-right:none}.modal .list-group-flush-2fa div:first-child{border-top:none}.modal .list-group-flush-2fa div:last-child{border-bottom:none}.modal-footer{border-radius:.3rem .3rem 0 0;justify-content:flex-start}html.theme_light .modal-footer{background-color:#fbfbfb;border-top:1px solid #ced4da}html.theme_dark .modal-footer{background-color:#4c525f;border-top:1px solid #4c525f}html.theme_light .close{color:#333}html.theme_dark .close{color:#bac0ce}html.theme_light #totpImage{filter:invert(0) grayscale(0)}html.theme_dark #totpImage{filter:invert(1) grayscale(1)}.totp .totp-code{font-size:1.2rem}.totp .totp-countdown{display:block;margin:3px 3px 0 0;user-select:none}.totp .totp-countdown .totp-sec{font-size:.85em;line-height:32px;position:absolute;text-align:center;width:32px}.totp .totp-countdown svg{height:32px;transform:rotate(-90deg);width:32px}.totp .totp-countdown .totp-circle{fill:none}html.theme_light .totp .totp-countdown .totp-circle{stroke:#175ddc}html.theme_dark .totp .totp-countdown .totp-circle{stroke:#6a99f0}.totp .totp-countdown .totp-circle.inner{stroke-dasharray:78.6;stroke-dashoffset:0;stroke-width:3}.totp .totp-countdown .totp-circle.outer{stroke-dasharray:88;stroke-dashoffset:0;stroke-width:2}.totp>.align-items-center{margin-bottom:-5px}html.theme_light .totp.low .totp-sec,html.theme_light .totp.low .totp-code{color:#dd4b39}html.theme_dark .totp.low .totp-sec,html.theme_dark .totp.low .totp-code{color:#ff8d85}html.theme_light .totp.low .totp-circle{stroke:#dd4b39}html.theme_dark .totp.low .totp-circle{stroke:#ff8d85}.cdk-drag-preview{border-radius:.25rem;opacity:.8;z-index:1070 !important}html.theme_light .cdk-drag-preview{background:#fff}html.theme_dark .cdk-drag-preview{background:#2f343d}.password-wrapper{min-width:0;white-space:pre-wrap;word-break:break-all}.password-row{min-width:0}html.theme_light .password-letter{color:#333}html.theme_dark .password-letter{color:#fff}html.theme_light .password-number{color:#007fde}html.theme_dark .password-number{color:#52bdfb}html.theme_light .password-special{color:#c40800}html.theme_dark .password-special{color:#ff7c70}app-vault-groupings .card #search,app-org-vault-groupings .card #search,.groupings .card #search{margin-bottom:1rem}html.theme_light app-vault-groupings .card #search,html.theme_light app-org-vault-groupings .card #search,html.theme_light .groupings .card #search{background-color:#fbfbfb;border-color:#ced4da;color:#465057}html.theme_dark app-vault-groupings .card #search,html.theme_dark app-org-vault-groupings .card #search,html.theme_dark .groupings .card #search{background-color:transparent;border-color:#bac0ce;color:#fff}html.theme_light app-vault-groupings .card #search::placeholder,html.theme_light app-org-vault-groupings .card #search::placeholder,html.theme_light .groupings .card #search::placeholder{color:#b6b8b8}html.theme_dark app-vault-groupings .card #search::placeholder,html.theme_dark app-org-vault-groupings .card #search::placeholder,html.theme_dark .groupings .card #search::placeholder{color:#bac0ce}app-vault-groupings .card h3,app-org-vault-groupings .card h3,.groupings .card h3{font-weight:normal;text-transform:uppercase}html.theme_light app-vault-groupings .card h3,html.theme_light app-org-vault-groupings .card h3,html.theme_light .groupings .card h3{color:#6c757d}html.theme_dark app-vault-groupings .card h3,html.theme_dark app-org-vault-groupings .card h3,html.theme_dark .groupings .card h3{color:#bac0ce}app-vault-groupings .card ul:last-child,app-org-vault-groupings .card ul:last-child,.groupings .card ul:last-child{margin-bottom:0}html.theme_light app-vault-groupings .card .card-body a,html.theme_light app-org-vault-groupings .card .card-body a,html.theme_light .groupings .card .card-body a{color:#333;font-weight:400}html.theme_dark app-vault-groupings .card .card-body a,html.theme_dark app-org-vault-groupings .card .card-body a,html.theme_dark .groupings .card .card-body a{color:#fff;font-weight:600}html.theme_light app-vault-groupings .card .card-body a:hover.text-muted,html.theme_light app-org-vault-groupings .card .card-body a:hover.text-muted,html.theme_light .groupings .card .card-body a:hover.text-muted{color:#333 !important}html.theme_dark app-vault-groupings .card .card-body a:hover.text-muted,html.theme_dark app-org-vault-groupings .card .card-body a:hover.text-muted,html.theme_dark .groupings .card .card-body a:hover.text-muted{color:#8d94a5 !important}app-vault-groupings .card .show-active,app-org-vault-groupings .card .show-active,.groupings .card .show-active{display:none}app-vault-groupings .card li>.fa,app-vault-groupings .card li>div>.fa,app-org-vault-groupings .card li>.fa,app-org-vault-groupings .card li>div>.fa,.groupings .card li>.fa,.groupings .card li>div>.fa{cursor:pointer}app-vault-groupings .card li.active>.show-active,app-vault-groupings .card li.active>div .show-active,app-org-vault-groupings .card li.active>.show-active,app-org-vault-groupings .card li.active>div .show-active,.groupings .card li.active>.show-active,.groupings .card li.active>div .show-active{display:inline}app-vault-groupings .card li.active>a:first-of-type,app-vault-groupings .card li.active>div a:first-of-type,app-org-vault-groupings .card li.active>a:first-of-type,app-org-vault-groupings .card li.active>div a:first-of-type,.groupings .card li.active>a:first-of-type,.groupings .card li.active>div a:first-of-type{font-weight:bold}html.theme_light app-vault-groupings .card li.active>a:first-of-type,html.theme_light app-vault-groupings .card li.active>div a:first-of-type,html.theme_light app-org-vault-groupings .card li.active>a:first-of-type,html.theme_light app-org-vault-groupings .card li.active>div a:first-of-type,html.theme_light .groupings .card li.active>a:first-of-type,html.theme_light .groupings .card li.active>div a:first-of-type{color:#175ddc}html.theme_dark app-vault-groupings .card li.active>a:first-of-type,html.theme_dark app-vault-groupings .card li.active>div a:first-of-type,html.theme_dark app-org-vault-groupings .card li.active>a:first-of-type,html.theme_dark app-org-vault-groupings .card li.active>div a:first-of-type,html.theme_dark .groupings .card li.active>a:first-of-type,html.theme_dark .groupings .card li.active>div a:first-of-type{color:#6a99f0}html.theme_light app-vault-groupings .card li.active>.fa,html.theme_light app-vault-groupings .card li.active>div>.fa,html.theme_light app-org-vault-groupings .card li.active>.fa,html.theme_light app-org-vault-groupings .card li.active>div>.fa,html.theme_light .groupings .card li.active>.fa,html.theme_light .groupings .card li.active>div>.fa{color:#175ddc}html.theme_dark app-vault-groupings .card li.active>.fa,html.theme_dark app-vault-groupings .card li.active>div>.fa,html.theme_dark app-org-vault-groupings .card li.active>.fa,html.theme_dark app-org-vault-groupings .card li.active>div>.fa,html.theme_dark .groupings .card li.active>.fa,html.theme_dark .groupings .card li.active>div>.fa{color:#6a99f0}app-password-generator #lengthRange{width:100%}app-password-generator .card-password .card-body{align-items:center;display:flex;flex-wrap:wrap;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1.15rem;justify-content:center;text-align:center}html.theme_light app-password-generator .card-password .card-body{background:#fff}html.theme_dark app-password-generator .card-password .card-body{background:#2f343d}app-password-generator-history .list-group-item{line-height:1}html.theme_light app-password-generator-history .list-group-item{background:#fff}html.theme_dark app-password-generator-history .list-group-item{background:#1f242e}app-password-generator-history .list-group-item .password{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}app-import textarea{height:150px}app-user-billing .progress{height:20px}app-user-billing .progress .progress-bar{min-width:50px}app-sponsored-families .inset-list{padding-left:1.5rem}.layout.enterprise2 header{background:#175ddc;color:#ced4da}.layout.enterprise2 header:before{background:#175ddc;content:"";height:416px;left:0;position:absolute;top:-76px;transform:skewY(-3deg);width:100%;z-index:-1}.layout.enterprise2 header img.logo{height:57px;margin:12px 0 0;max-width:284px;width:284px}.layout.enterprise2 h2{color:#fff;font-size:1.8rem;margin:100px 0 150px 0}.layout.enterprise2 p{font-size:1.4rem;margin:20px 0 40px 0}.layout.enterprise2 p:before{content:"/";padding-right:12px}.layout.enterprise2 p:not(.highlight):before{color:#1252a3}.layout.enterprise2 p b:after{content:"⟶";font-size:2rem;padding-left:6px}.layout.enterprise2 blockquote{font-size:1.4rem;margin:20px 0 0 0;padding-right:40px}#duo-frame{height:330px}html.theme_light #duo-frame{background:0 0 no-repeat}html.theme_dark #duo-frame{background:0 0 no-repeat}#duo-frame iframe{border:none;height:100%;width:100%}#web-authn-frame{height:290px}html.theme_light #web-authn-frame{background:0 0 no-repeat}html.theme_dark #web-authn-frame{background:0 0 no-repeat}#web-authn-frame iframe{border:none;height:100%;width:100%}#hcaptcha_iframe{border:none;transition:height .25s linear;width:100%}.list-group-2fa .logo-2fa{min-width:100px}.mfaType0{content:url(../images/0.png);max-width:100px}.mfaType2{content:url(../images/2.png);max-width:100px}.mfaType3{content:url(../images/3.png);max-width:100px}.mfaType4{content:url(../images/4.png);max-width:100px}.mfaType6{content:url(../images/6.png);max-width:100px}html.theme_light .mfaType1{content:url(../images/1.png);max-width:100px;max-height:45px}html.theme_dark .mfaType1{content:url(../images/1-w.png);max-width:100px;max-height:45px}html.theme_light .mfaType7{content:url(../images/7.png);max-width:100px}html.theme_dark .mfaType7{content:url(../images/7-w.png);max-width:100px}html.theme_light .recovery-code-img{content:url(../images/rc.png);max-width:100px;max-height:45px}html.theme_dark .recovery-code-img{content:url(../images/rc-w.png);max-width:100px;max-height:45px}html.theme_light .progress{background-color:#e9ecef}html.theme_dark .progress{background-color:#3c424e}#bt-dropin-container{min-height:50px}html.theme_light #bt-dropin-container{background:url(../images/loading.svg) center center no-repeat}html.theme_dark #bt-dropin-container{background:url(../images/loading-white.svg) center center no-repeat}.braintree-placeholder,.braintree-sheet__header{display:none}.braintree-sheet__content--button{min-height:0;padding:0;text-align:left}.braintree-sheet__container{margin-bottom:0}.braintree-sheet{border:none}html.theme_light [data-braintree-id=upper-container]::before{background-color:#fff}html.theme_dark [data-braintree-id=upper-container]::before{background-color:#1f242e}html.theme_light .card [data-braintree-id=upper-container]::before{background-color:#fff}html.theme_dark .card [data-braintree-id=upper-container]::before{background-color:#2f343d}html.theme_light [data-braintree-id=paypal-button]{background-color:#fff}html.theme_dark [data-braintree-id=paypal-button]{background-color:#1f242e}html.theme_light .card [data-braintree-id=paypal-button]{background-color:#fff}html.theme_dark .card [data-braintree-id=paypal-button]{background-color:#2f343d}html.theme_light .paypal-button-text{color:#333}html.theme_dark .paypal-button-text{color:#bac0ce}html.theme_light [class*=swal2-]:not(.swal2-container,.swal2-confirm,.swal2-cancel,.swal2-deny){background-color:#fff;color:#333}html.theme_dark [class*=swal2-]:not(.swal2-container,.swal2-confirm,.swal2-cancel,.swal2-deny){background-color:#1f242e;color:#bac0ce}.swal2-container{background-color:rgba(0,0,0,.3)}.swal2-popup{border:1px solid #9a9a9a;border-radius:.3rem;padding:15px 0 0;width:34em}html.theme_light .swal2-popup{background-color:#fff;color:#333}html.theme_dark .swal2-popup{background-color:#1f242e;color:#bac0ce}.swal2-popup .swal2-header{padding:0 15px}.swal2-popup .swal2-icon{border:none;height:auto;margin:0 auto;width:auto}.swal2-popup .swal2-content{font-size:1rem;padding-bottom:15px}html.theme_light .swal2-popup .swal2-content{border-bottom:1px solid #ced4da}html.theme_dark .swal2-popup .swal2-content{border-bottom:1px solid #4c525f}.swal2-popup i.swal-custom-icon{display:block;font-size:35px;margin:0 auto}.swal2-popup .swal2-title{font-size:1.15rem;margin:0;padding:10px 0 15px}html.theme_light .swal2-popup .swal2-title{color:#333}html.theme_dark .swal2-popup .swal2-title{color:#fff}.swal2-popup .swal2-content{font-size:1rem;padding:0 15px 15px}html.theme_light .swal2-popup .swal2-content{color:#333}html.theme_dark .swal2-popup .swal2-content{color:#bac0ce}.swal2-popup .swal2-actions{border-radius:.3rem;display:flex;flex-direction:row;font-size:1rem;justify-content:flex-start;margin:0;padding:15px}html.theme_light .swal2-popup .swal2-actions{background-color:#fff}html.theme_dark .swal2-popup .swal2-actions{background-color:#1f242e}.swal2-popup .swal2-actions button{margin-right:10px}.swal2-popup .swal2-validation-message{margin:0 -15px}date-input-polyfill[data-open=true]{z-index:10000 !important}html.theme_light .table{color:#333}html.theme_dark .table{color:#bac0ce}.table td{vertical-align:middle}html.theme_light .table td{color:#333}html.theme_dark .table td{color:#bac0ce}html.theme_light .table td>a:not(.badge){color:#175ddc}html.theme_dark .table td>a:not(.badge){color:#fff}html.theme_light .table td>a:not(.badge):hover{color:#104097}html.theme_dark .table td>a:not(.badge):hover{color:#fff}.table td.reduced-lh{line-height:1}.table td.reduced-lh small{font-size:80%}html.theme_light .table td small,html.theme_light .table td>.fa,html.theme_light .table td .icon{color:#6c757d}html.theme_dark .table td small,html.theme_dark .table td>.fa,html.theme_dark .table td .icon{color:#bac0ce}html.theme_light .table td .fa-globe{color:#777}html.theme_dark .table td .fa-globe{color:#777}.table td.wrap{word-break:break-all}.table td.table-list-options{height:50px;max-width:76px;text-align:right;width:76px}.table td.table-list-options.wider{max-width:100px;width:100px}.table td.table-list-options .btn,.table td.table-list-options .swal2-popup .swal2-actions button,.swal2-popup .swal2-actions .table td.table-list-options button{line-height:1;transition:initial}.table td.table-list-options .dropdown-menu{line-height:1.5}.table td.table-action-right{text-align:right}.table td.table-list-icon{max-width:45px;text-align:center;width:45px}.table td.table-list-icon img{max-height:24px}.table td.table-list-checkbox{max-width:35px;width:35px}.table td.table-list-strike{text-decoration:line-through}html.theme_light .table td.table-list-strike{color:#6c757d}html.theme_dark .table td.table-list-strike{color:#bac0ce}html.theme_light .table.table-list.table td:not(tr:first-child td),html.theme_light .table.table-list .table th:not(tr:first-child td){border-top:1px solid #dee2e6}html.theme_dark .table.table-list.table td:not(tr:first-child td),html.theme_dark .table.table-list .table th:not(tr:first-child td){border-top:1px solid #4c525f}.table.table-list thead th{border-top:none}.table.table-list tr:first-child td{border:none}html.theme_light .table-hover tbody tr:hover{background-color:rgba(0,0,0,.03);color:#333}html.theme_dark .table-hover tbody tr:hover{background-color:rgba(255,255,255,.03);color:#bac0ce}.toast-container.toast-top-right{top:76px}.toast-container .toast-close-button{font-size:18px;margin-right:4px}.toast-container .toast{align-items:center;background-image:none !important;border-radius:.25rem;box-shadow:0 0 8px rgba(0,0,0,.35);display:flex;opacity:1 !important}.toast-container .toast:hover{box-shadow:0 0 10px rgba(0,0,0,.6)}.toast-container .toast:before{color:#fff;float:left;font-family:FontAwesome;font-size:25px;line-height:20px;margin:auto 0 auto 15px}.toast-container .toast .toast-content{padding:15px}.toast-container .toast .toaster-icon{display:none}.toast-container .toast .toast-message p{margin-bottom:.5rem}.toast-container .toast .toast-message p:last-child{margin-bottom:0}.toast-container .toast.toast-danger,.toast-container .toast.toast-error{background-image:none !important}html.theme_light .toast-container .toast.toast-danger,html.theme_light .toast-container .toast.toast-error{background-color:#dd4b39}html.theme_dark .toast-container .toast.toast-danger,html.theme_dark .toast-container .toast.toast-error{background-color:#ff8d85}html.theme_light .toast-container .toast.toast-danger,html.theme_light .toast-container .toast.toast-danger:before,html.theme_light .toast-container .toast.toast-danger .toast-close-button,html.theme_light .toast-container .toast.toast-error,html.theme_light .toast-container .toast.toast-error:before,html.theme_light .toast-container .toast.toast-error .toast-close-button{color:#fff !important}html.theme_dark .toast-container .toast.toast-danger,html.theme_dark .toast-container .toast.toast-danger:before,html.theme_dark .toast-container .toast.toast-danger .toast-close-button,html.theme_dark .toast-container .toast.toast-error,html.theme_dark .toast-container .toast.toast-error:before,html.theme_dark .toast-container .toast.toast-error .toast-close-button{color:#1f242e !important}.toast-container .toast.toast-danger:before,.toast-container .toast.toast-error:before{content:""}.toast-container .toast.toast-warning{background-image:none !important}html.theme_light .toast-container .toast.toast-warning{background-color:#bf7e16}html.theme_dark .toast-container .toast.toast-warning{background-color:#ffeb66}html.theme_light .toast-container .toast.toast-warning,html.theme_light .toast-container .toast.toast-warning:before,html.theme_light .toast-container .toast.toast-warning .toast-close-button{color:#fff !important}html.theme_dark .toast-container .toast.toast-warning,html.theme_dark .toast-container .toast.toast-warning:before,html.theme_dark .toast-container .toast.toast-warning .toast-close-button{color:#1f242e !important}.toast-container .toast.toast-warning:before{content:""}.toast-container .toast.toast-info{background-image:none !important}html.theme_light .toast-container .toast.toast-info{background-color:#343a40}html.theme_dark .toast-container .toast.toast-info{background-color:#a4b0c6}html.theme_light .toast-container .toast.toast-info,html.theme_light .toast-container .toast.toast-info:before,html.theme_light .toast-container .toast.toast-info .toast-close-button{color:#fff !important}html.theme_dark .toast-container .toast.toast-info,html.theme_dark .toast-container .toast.toast-info:before,html.theme_dark .toast-container .toast.toast-info .toast-close-button{color:#1f242e !important}.toast-container .toast.toast-info:before{content:""}.toast-container .toast.toast-success{background-image:none !important}html.theme_light .toast-container .toast.toast-success{background-color:#00a65a}html.theme_dark .toast-container .toast.toast-success{background-color:#52e07c}html.theme_light .toast-container .toast.toast-success,html.theme_light .toast-container .toast.toast-success:before,html.theme_light .toast-container .toast.toast-success .toast-close-button{color:#fff !important}html.theme_dark .toast-container .toast.toast-success,html.theme_dark .toast-container .toast.toast-success:before,html.theme_dark .toast-container .toast.toast-success .toast-close-button{color:#1f242e !important}.toast-container .toast.toast-success:before{content:""}.toast-container .layout_frontend .toast-top-right{top:20px}.layout_frontend .toast-top-right{top:20px} +body{min-width:0px !important;padding:0;margin:0;background:transparent} + +/*# sourceMappingURL=captcha.656f1dffa218e8467958.css.map*/ \ No newline at end of file diff --git a/connectors/captcha.656f1dffa218e8467958.css.map b/connectors/captcha.656f1dffa218e8467958.css.map new file mode 100644 index 00000000..b06b68b1 --- /dev/null +++ b/connectors/captcha.656f1dffa218e8467958.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///./jslib/angular/src/scss/webfonts.css","webpack:///./src/scss/styles.scss","webpack:///./node_modules/bootstrap/scss/_root.scss","webpack:///./node_modules/bootstrap/scss/_reboot.scss","webpack:///./src/scss/variables.scss","webpack:///./node_modules/bootstrap/scss/vendor/_rfs.scss","webpack:///./node_modules/bootstrap/scss/_variables.scss","webpack:///./node_modules/bootstrap/scss/mixins/_hover.scss","webpack:///./node_modules/bootstrap/scss/_type.scss","webpack:///./node_modules/bootstrap/scss/mixins/_lists.scss","webpack:///./node_modules/bootstrap/scss/_images.scss","webpack:///./node_modules/bootstrap/scss/mixins/_image.scss","webpack:///./node_modules/bootstrap/scss/mixins/_border-radius.scss","webpack:///./node_modules/bootstrap/scss/_code.scss","webpack:///./node_modules/bootstrap/scss/_grid.scss","webpack:///./node_modules/bootstrap/scss/mixins/_grid.scss","webpack:///./node_modules/bootstrap/scss/mixins/_breakpoints.scss","webpack:///./node_modules/bootstrap/scss/mixins/_grid-framework.scss","webpack:///./node_modules/bootstrap/scss/_tables.scss","webpack:///./node_modules/bootstrap/scss/mixins/_table-row.scss","webpack:///./node_modules/bootstrap/scss/_forms.scss","webpack:///./node_modules/bootstrap/scss/mixins/_transition.scss","webpack:///./node_modules/bootstrap/scss/mixins/_forms.scss","webpack:///./node_modules/bootstrap/scss/_buttons.scss","webpack:///./node_modules/bootstrap/scss/mixins/_buttons.scss","webpack:///./node_modules/bootstrap/scss/_transitions.scss","webpack:///./node_modules/bootstrap/scss/_dropdown.scss","webpack:///./node_modules/bootstrap/scss/mixins/_caret.scss","webpack:///./node_modules/bootstrap/scss/mixins/_nav-divider.scss","webpack:///./node_modules/bootstrap/scss/_button-group.scss","webpack:///./node_modules/bootstrap/scss/_input-group.scss","webpack:///./node_modules/bootstrap/scss/_custom-forms.scss","webpack:///./node_modules/bootstrap/scss/_nav.scss","webpack:///./node_modules/bootstrap/scss/_navbar.scss","webpack:///./node_modules/bootstrap/scss/_card.scss","webpack:///./node_modules/bootstrap/scss/_breadcrumb.scss","webpack:///./node_modules/bootstrap/scss/_pagination.scss","webpack:///./node_modules/bootstrap/scss/mixins/_pagination.scss","webpack:///./node_modules/bootstrap/scss/_badge.scss","webpack:///./node_modules/bootstrap/scss/mixins/_badge.scss","webpack:///./node_modules/bootstrap/scss/_jumbotron.scss","webpack:///./node_modules/bootstrap/scss/_alert.scss","webpack:///./node_modules/bootstrap/scss/mixins/_alert.scss","webpack:///./node_modules/bootstrap/scss/_progress.scss","webpack:///./node_modules/bootstrap/scss/mixins/_gradients.scss","webpack:///./node_modules/bootstrap/scss/_media.scss","webpack:///./node_modules/bootstrap/scss/_list-group.scss","webpack:///./node_modules/bootstrap/scss/mixins/_list-group.scss","webpack:///./node_modules/bootstrap/scss/_close.scss","webpack:///./node_modules/bootstrap/scss/_modal.scss","webpack:///./node_modules/bootstrap/scss/_tooltip.scss","webpack:///./node_modules/bootstrap/scss/mixins/_reset-text.scss","webpack:///./node_modules/bootstrap/scss/_popover.scss","webpack:///./node_modules/bootstrap/scss/_carousel.scss","webpack:///./node_modules/bootstrap/scss/mixins/_clearfix.scss","webpack:///./node_modules/bootstrap/scss/_spinners.scss","webpack:///./node_modules/bootstrap/scss/utilities/_align.scss","webpack:///./node_modules/bootstrap/scss/mixins/_background-variant.scss","webpack:///./node_modules/bootstrap/scss/utilities/_background.scss","webpack:///./node_modules/bootstrap/scss/utilities/_borders.scss","webpack:///./node_modules/bootstrap/scss/utilities/_display.scss","webpack:///./node_modules/bootstrap/scss/utilities/_embed.scss","webpack:///./node_modules/bootstrap/scss/utilities/_flex.scss","webpack:///./node_modules/bootstrap/scss/utilities/_float.scss","webpack:///./node_modules/bootstrap/scss/utilities/_interactions.scss","webpack:///./node_modules/bootstrap/scss/utilities/_position.scss","webpack:///./node_modules/bootstrap/scss/utilities/_screenreaders.scss","webpack:///./node_modules/bootstrap/scss/mixins/_screen-reader.scss","webpack:///./node_modules/bootstrap/scss/utilities/_shadows.scss","webpack:///./node_modules/bootstrap/scss/utilities/_sizing.scss","webpack:///./node_modules/bootstrap/scss/utilities/_spacing.scss","webpack:///./node_modules/bootstrap/scss/utilities/_stretched-link.scss","webpack:///./node_modules/bootstrap/scss/utilities/_text.scss","webpack:///./node_modules/bootstrap/scss/mixins/_text-truncate.scss","webpack:///./node_modules/bootstrap/scss/mixins/_text-emphasis.scss","webpack:///./node_modules/bootstrap/scss/mixins/_text-hide.scss","webpack:///./node_modules/bootstrap/scss/utilities/_visibility.scss","webpack:///./node_modules/bootstrap/scss/_print.scss","webpack:///./node_modules/angular2-toaster/toaster.scss","webpack:///./node_modules/font-awesome/scss/font-awesome.scss","webpack:///./node_modules/font-awesome/scss/_path.scss","webpack:///./node_modules/font-awesome/scss/_core.scss","webpack:///./node_modules/font-awesome/scss/_larger.scss","webpack:///./node_modules/font-awesome/scss/_fixed-width.scss","webpack:///./node_modules/font-awesome/scss/_list.scss","webpack:///./node_modules/font-awesome/scss/_variables.scss","webpack:///./node_modules/font-awesome/scss/_bordered-pulled.scss","webpack:///./node_modules/font-awesome/scss/_animated.scss","webpack:///./node_modules/font-awesome/scss/_rotated-flipped.scss","webpack:///./node_modules/font-awesome/scss/_mixins.scss","webpack:///./node_modules/font-awesome/scss/_stacked.scss","webpack:///./node_modules/font-awesome/scss/_icons.scss","webpack:///./node_modules/font-awesome/scss/_screen-reader.scss","webpack:///./node_modules/sweetalert2/src/scss/_toasts.scss","webpack:///./node_modules/sweetalert2/src/variables.scss","webpack:///./node_modules/sweetalert2/src/scss/_mixins.scss","webpack:///./node_modules/sweetalert2/src/scss/_core.scss","webpack:///./node_modules/sweetalert2/src/scss/_polyfills.scss","webpack:///./node_modules/sweetalert2/src/scss/_toasts-animations.scss","webpack:///./node_modules/sweetalert2/src/scss/_animations.scss","webpack:///./node_modules/sweetalert2/src/scss/_body.scss","webpack:///./node_modules/sweetalert2/src/scss/_toasts-body.scss","webpack:///./src/scss/base.scss","webpack:///./src/scss/buttons.scss","webpack:///./src/scss/callouts.scss","webpack:///./src/scss/cards.scss","webpack:///./src/scss/forms.scss","webpack:///./src/scss/navigation.scss","webpack:///./src/scss/modals.scss","webpack:///./src/scss/pages.scss","webpack:///./src/scss/plugins.scss","webpack:///./src/scss/tables.scss","webpack:///./src/scss/toasts.scss","webpack:///./src/connectors/captcha.scss"],"names":[],"mappings":"AAAA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;AAEA;CACC,wBAAwB;CACxB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,2DAA2D;CAC3D,yBAAyB;AAC1B;;;ACxFQ,qBCGJ,iOAIA,oMAIA,oOAKF,8GACA,sBCCF,qBAGE,MAGF,sBACE,iBACA,8BACA,0CACA,uEAMF,aACE,MAUF,QACE,2HC5BuB,eCuEN,gBCsMW,gBAKA,WFpRjB,gBDoCX,sBC5CM,2CDyDR,oBACE,IASF,sBACE,SACA,iBACA,mBAaF,YACE,oBGiN4B,GHzM9B,YACE,mBGqF0B,uCHzE5B,yBAEE,iCACA,YACA,gBACA,8BACA,SAGF,kBACE,kBACA,oBACA,UAGF,YAGE,mBACA,yBAGF,eAIE,IAGF,eGkJ8B,IH9I9B,mBACE,cACA,YAGF,eACE,UAGF,kBGsI8B,OHjI9B,aExFI,SFiGJ,iBAEE,cEnGE,cFqGF,wBACA,KAGF,mBACA,aAOA,aGV0C,qBACA,6BHYxC,SIhLA,aDqKwC,0BACA,4BHuB1C,aACE,qBACA,kCI/LA,aJkME,qBACA,mBASJ,0FG6D8B,cD7M1B,KFwJJ,YAEE,mBAEA,cAEA,6BAGA,QAQF,eAEE,KAQF,qBACE,kBACA,KAGF,eAGE,sBACA,OAQF,wBACE,SAGF,kBG8E8B,oCAjVnB,gBHuQT,oBACA,IAOF,kBAEE,gCACA,OAQF,oBAEE,oBG4JsC,QHrJxC,eAEE,kCAQF,SACE,uCAGF,QAKE,oBACA,kBE5PE,oBF8PF,cAGF,gBAEE,eAGF,mBAEE,eAMF,cACE,QAMF,gBACE,iDAOF,yBAIE,6GASE,cACE,yHAMN,SAIE,kBACA,wCAGF,qBAEE,UACA,UAIF,aACE,gBAEA,UAGF,WAME,UAEA,SACA,SACA,QAKF,aACE,WACA,eACA,UACA,oBACA,iBEzUiB,oBF2UjB,cACA,mBACA,UAGF,uBACE,mFAIF,WAEE,eAGF,mBAKE,wBACA,0CAOF,uBACE,8BAQF,YACE,0BACA,QAOF,oBACE,SAGF,iBACE,eACA,UAGF,YACE,UAKF,uBACE,2CK5dF,mBFuS8B,gBAEA,gBACA,QEjS9B,gBH0EmB,QGzEnB,gBHyEmB,QGxEnB,cHwEmB,QGvEnB,cHuEmB,QGtEnB,cHsEmB,QGrEnB,cHqEmB,OGnEnB,iBHmEmB,mBDzBA,YIpCnB,cH6DmB,gBC+NW,gBARA,YE/Q9B,gBHwDmB,gBCgOW,gBATA,YE1Q9B,gBHmDmB,gBCiOW,gBAVA,YErQ9B,gBH8CmB,gBCkOW,gBAXA,IE1P9B,eFiFS,4BE9EP,oCACA,cAQF,aHMI,gBCuN0B,YEvN9B,YFoQ8B,yBASA,gBElQ9B,cC/EE,gBACA,cDmFF,cCpFE,gBACA,mBDsFF,oBACE,oCAEA,kBFqP4B,aE1O9B,aHjCI,yBGmCF,aAIF,kBFwBS,kBD9CU,oBG2BnB,aACE,cH7CE,cC3DO,4BE4GT,YACE,0CEnHJ,cCIE,YAGA,gBDDF,cJogCoC,sBFzgC5B,yBMQN,qBEEE,eDPF,YAGA,SDcF,oBAEE,aAGF,mBACE,cACA,iBAGF,aLkCI,cC3DO,MOZX,cRuEI,cClCM,qBOlCR,QAGA,aACE,KAKJ,mBACE,eR0DE,WDhEI,yBEQG,oBMEP,SCGF,SACE,eRkDA,gBCwN0B,KOlQ9B,aACE,eRyCE,cCxDO,UOoBT,iBRoCE,cQlCA,kBACA,iBAKJ,gBP+jCoC,kBO7jClC,qFCxCA,UCDA,mBACA,kBACA,kBACA,iBACA,wBCmDE,yBFzCE,eR+LiB,yBUtJnB,uCFzCE,eR+LiB,yBUtJnB,qDFzCE,eR+LiB,yBUtJnB,mEFzCE,gBR+LiB,OQlKrB,YCnCA,eACA,mBACA,kBACA,aDsCA,cACE,cACA,4CAEA,eAEE,eACA,uqBGtDJ,iBACE,WACA,mBACA,kBACA,MAsBE,YACE,YACA,eACA,eF4BN,aACE,eACA,eAFF,YACE,cACA,eAFF,uBACE,yBACA,eAFF,YACE,cACA,eAFF,YACE,cACA,eAFF,uBACE,yBACA,WEnBE,aFCJ,WACA,eACA,QEGQ,sBFbR,wBAIA,QESQ,uBFbR,yBAIA,QESQ,YFbR,cAIA,QESQ,uBFbR,yBAIA,QESQ,uBFbR,yBAIA,QESQ,YFbR,cAIA,QESQ,uBFbR,yBAIA,QESQ,uBFbR,yBAIA,QESQ,YFbR,cAIA,SESQ,uBFbR,yBAIA,SESQ,uBFbR,yBAIA,SESQ,aFbR,eAIA,cEeI,qBAEA,kBAGE,OADW,UACX,OADW,UACX,OADW,UACX,OADW,UACX,OADW,UACX,OADW,UACX,OADW,UACX,OADW,UACX,OADW,UACX,OADW,WACX,QADW,WACX,QADW,WACX,QADW,WAQP,yBFhBV,WEgBU,0BFhBV,WEgBU,eFhBV,WEgBU,0BFhBV,WEgBU,0BFhBV,WEgBU,eFhBV,WEgBU,0BFhBV,WEgBU,0BFhBV,WEgBU,eFhBV,YEgBU,0BFhBV,YEgBU,0BFhBV,wBCKE,QC3BE,YACE,YACA,eACA,kBF4BN,aACE,eACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,kBAFF,YACE,cACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,cEnBE,aFCJ,WACA,eACA,WEGQ,sBFbR,wBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,YESQ,uBFbR,yBAIA,YESQ,uBFbR,yBAIA,YESQ,aFbR,eAIA,iBEeI,wBAEA,qBAGE,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,cACX,QADW,cACX,QADW,cACX,QADW,cAQP,aFhBV,cEgBU,yBFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,eEgBU,0BFhBV,eEgBU,0BFhBV,yBCKE,QC3BE,YACE,YACA,eACA,kBF4BN,aACE,eACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,kBAFF,YACE,cACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,cEnBE,aFCJ,WACA,eACA,WEGQ,sBFbR,wBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,YESQ,uBFbR,yBAIA,YESQ,uBFbR,yBAIA,YESQ,aFbR,eAIA,iBEeI,wBAEA,qBAGE,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,cACX,QADW,cACX,QADW,cACX,QADW,cAQP,aFhBV,cEgBU,yBFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,eEgBU,0BFhBV,eEgBU,0BFhBV,yBCKE,QC3BE,YACE,YACA,eACA,kBF4BN,aACE,eACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,kBAFF,YACE,cACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,cEnBE,aFCJ,WACA,eACA,WEGQ,sBFbR,wBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,YESQ,uBFbR,yBAIA,YESQ,uBFbR,yBAIA,YESQ,aFbR,eAIA,iBEeI,wBAEA,qBAGE,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,cACX,QADW,cACX,QADW,cACX,QADW,cAQP,aFhBV,cEgBU,yBFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,eEgBU,0BFhBV,eEgBU,0BFhBV,yBCKE,QC3BE,YACE,YACA,eACA,kBF4BN,aACE,eACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,kBAFF,YACE,cACA,kBAFF,YACE,cACA,kBAFF,uBACE,yBACA,cEnBE,aFCJ,WACA,eACA,WEGQ,sBFbR,wBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,WESQ,uBFbR,yBAIA,WESQ,uBFbR,yBAIA,WESQ,YFbR,cAIA,YESQ,uBFbR,yBAIA,YESQ,uBFbR,yBAIA,YESQ,aFbR,eAIA,iBEeI,wBAEA,qBAGE,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,aACX,OADW,cACX,QADW,cACX,QADW,cACX,QADW,cAQP,aFhBV,cEgBU,yBFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,cEgBU,0BFhBV,cEgBU,0BFhBV,cEgBU,eFhBV,eEgBU,0BFhBV,eEgBU,0BFhBV,SGnDF,UACE,mBZkIO,WFvHI,qBcNX,cZoV4B,mBYjV1B,6BACA,iBAGF,qBACE,gCACA,oBAGF,4BACE,2BAUF,aZ8T4B,iBYnT9B,wBACE,uCAEA,wBAEE,mDAIA,uBAEE,oGAMJ,QAIE,0CASF,gCdfgB,6BG/ChB,UHIW,iCA4CI,oDetDb,wBD8FiC,wFCvF/B,oBDuF2E,mCXxF/E,wBYaqB,2EAMf,wBANe,0DAnBnB,wBD8FiC,gGCvF/B,oBDuF2E,qCXxF/E,wBYaqB,+EAMf,wBANe,oDAnBnB,wBD8FiC,wFCvF/B,oBDuF2E,mCXxF/E,wBYaqB,2EAMf,wBANe,2CAnBnB,wBD8FiC,4ECvF/B,oBDuF2E,gCXxF/E,wBYaqB,qEAMf,wBANe,oDAnBnB,wBD8FiC,wFCvF/B,oBDuF2E,mCXxF/E,wBYaqB,2EAMf,wBANe,iDAnBnB,wBD8FiC,oFCvF/B,oBDuF2E,kCXxF/E,wBYaqB,yEAMf,wBANe,8CAnBnB,wBD8FiC,gFCvF/B,oBDuF2E,iCXxF/E,wBYaqB,uEAMf,wBANe,2CAnBnB,wBD8FiC,4ECvF/B,oBDuF2E,gCXxF/E,wBYaqB,qEAMf,wBANe,yEAnBnB,wBD8FiC,oHCvF/B,oBDuF2E,0CXxF/E,wBYaqB,yFAMf,wBANe,sEAnBnB,wBD8FiC,gHCvF/B,oBDuF2E,yCXxF/E,wBYaqB,uFAMf,wBANe,iDAnBnB,gCfsDa,kCGhDf,gCYaqB,yEAMf,gCANe,uBDwFnB,UdzGI,yBEOG,qBAqWmB,wBY3P1B,aZ3GO,yBALA,qBFPC,ac+HZ,UdzHQ,yBEOG,oDYsHT,oBZ+O4B,4BYzO5B,QACE,qDAIA,sCZiO0B,wCCrW5B,UHJM,wCE2WsB,2BU1S1B,qBEiGA,aAEI,WACA,gBACA,iCACA,sCAGA,QACE,4BF1GN,qBEiGA,aAEI,WACA,gBACA,iCACA,sCAGA,QACE,4BF1GN,qBEiGA,aAEI,WACA,gBACA,iCACA,sCAGA,QACE,4BF1GN,qBEiGA,aAEI,WACA,gBACA,iCACA,sCAGA,QACE,oBATN,aAEI,WACA,gBACA,iCACA,mCAGA,QACE,eE7KV,aACE,WACA,mCd2esC,uBczetC,ef+EiB,gBCsMW,gBAKA,cAtRnB,yBFwCA,4BgBrCT,yBACA,0FAMA,wCCJI,cDdN,eCeQ,4BDMN,4BACE,SACA,8BAIF,iBACE,0BACA,qBEtBF,aACE,sBlBNI,qBE6dgC,UgBpdpC,2ChByX0B,4BchW5B,ahBewB,UgBZtB,gDAQF,wBhBGkB,UgBChB,oIAQF,eACE,sCAKF,adzDS,yBFwCA,wCgB6BX,aAEE,WACA,iBAUF,gCACE,oCACA,gBACA,kBf3BE,gBC4N0B,oBc5L9B,8BACE,kCACA,kBfjBiB,gBCgJW,oBc1H9B,+BACE,mCACA,mBfxBiB,gBCiJW,yBc9G9B,aACE,WACA,kBACA,gBACA,efvCiB,gBC2MW,WFpRjB,6BgBoHX,yBACA,mBACA,iFAEA,eAEE,eACA,kBAYJ,iCd6VwC,qBc3VtC,mBfhEiB,gBCiJW,oBMxN1B,kBQ6IJ,+BdsVwC,mBcpVtC,kBfxEiB,gBCgJW,oBMvN1B,yDQuJF,WAEE,uBAIJ,WACE,aAQF,kBd2UwC,YcvUxC,aACE,kBd4TsC,WcnTxC,YACE,eACA,kBACA,iBACA,wCAEA,iBAEE,iBACA,aASJ,iBACE,cACA,qBdiSsC,mBc7RxC,iBACE,iBd6RsC,qBc3RtC,4FAGA,advNS,mBc6NX,eACE,oBAGF,mBACE,mBACA,eACA,oBd8QsC,sCc1QtC,eACE,aACA,sBdyQoC,ccvQpC,iBE7MF,YACE,WACA,kBhB2coC,cDjbpC,ce8LqC,gBElNvC,iBACE,SACA,OACA,UACA,aACA,eACA,qBACA,iBACA,mBjB6Be,gBC2MW,WgBrO1B,mCACA,qBV9CA,sEUmDA,QAEE,+HAKF,aAEE,2DA9CF,oBFsOqC,oCdyOD,iRgBvZhC,4BACA,2DACA,gEACA,uEAGF,oBFwKmC,0CEtKjC,2EAhEJ,mChB+coC,kFgBrYhC,6DA1EJ,oBFsOqC,uCdqUG,wjBgBtdpC,yEAGF,oBF8ImC,0CE5IjC,uGAOF,aFqImC,mMEjInC,aAEE,uHAOF,aFwHmC,uIErHjC,oBFqHiC,uJE/GjC,oBACE,yBACqB,mJAKvB,yCACE,+KAGF,oBATuB,2GAmBzB,oBAnByB,uHAwBvB,oBAxBuB,0CA0BrB,mBAvIR,YACE,WACA,kBhB2coC,cDjbpC,ce8LqC,kBElNvC,iBACE,SACA,OACA,UACA,aACA,eACA,qBACA,iBACA,mBjB6Be,gBC2MW,WgBrO1B,oCACA,qBV9CA,0EUmDA,QAEE,+IAKF,aAEE,+DA9CF,oBFsOqC,oCdyOD,4UgBvZhC,4BACA,2DACA,gEACA,2EAGF,oBFwKmC,2CEtKjC,+EAhEJ,mChB+coC,kFgBrYhC,iEA1EJ,oBFsOqC,uCdqUG,mnBgBtdpC,6EAGF,oBF8ImC,2CE5IjC,2GAOF,aFqImC,mNEjInC,aAEE,2HAOF,aFwHmC,2IErHjC,oBFqHiC,2JE/GjC,oBACE,yBACqB,uJAKvB,0CACE,mLAGF,oBATuB,+GAmBzB,oBAnByB,2HAwBvB,oBAxBuB,2CA0BrB,cF+FV,YACE,mBACA,mBACA,0BAKA,UACE,wBJ/NA,mBIoOA,YACE,mBACA,uBACA,gBACA,0BAIF,YACE,cACA,mBACA,mBACA,gBACA,4BAIF,oBACE,WACA,sBACA,sCAIF,oBACE,uDAGF,UAEE,0BAKF,YACE,mBACA,uBACA,WACA,eACA,gCAEF,iBACE,cACA,aACA,oBdgLkC,cc9KlC,8BAGF,kBACE,uBACA,oCAEF,eACE,0CGjVN,oBACE,gBnBwDgB,WA/CL,kBmBLX,sBAGA,iBACA,6BACA,6BACA,uBCuFA,enBfiB,gBC2MW,qBMlR1B,8HWCF,wCFCI,wCEdN,eFeQ,sDdTN,UHIW,qBmBOT,yGAGF,SAEE,2CjB8W0B,qHiBzW5B,WjBmZ4B,qGiB7Y5B,cACE,wCAcJ,mBAEE,cASA,UC3DA,yBlBsEa,yCChEb,mCiBP6D,qBAA0C,uCAYvG,UAEE,yBAd2D,qBAA0C,2CAqBnG,6CAKJ,UAEE,yBlB2CW,6JkBlCb,UAGE,yBAxC+I,qBAA0C,0JA+CzL,0CAKI,gBDQN,aC3DA,yBlBsEa,2CChEb,sCiBP6D,qBAA0C,2CAYvG,aAEE,yBAd2D,qBAA0C,4CAqBnG,iDAKJ,aAEE,yBlB2CW,mKkBlCb,aAGE,yBAxC+I,qBAA0C,gKA+CzL,2CAKI,cDQN,UC3DA,yBlBsEa,yCChEb,mCiBP6D,qBAA0C,uCAYvG,UAEE,yBAd2D,qBAA0C,2CAqBnG,6CAKJ,UAEE,yBlB2CW,6JkBlCb,UAGE,yBAxC+I,qBAA0C,0JA+CzL,0CAKI,WDQN,UC3DA,sBlBsEa,mCChEb,mCiBP6D,qBAA0C,iCAYvG,UAEE,yBAd2D,qBAA0C,4CAqBnG,uCAKJ,UAEE,sBlB2CW,iJkBlCb,UAGE,yBAxC+I,qBAA0C,iJA+CzL,2CAKI,cDQN,UC3DA,yBlBsEa,yCChEb,mCiBP6D,qBAA0C,uCAYvG,UAEE,yBAd2D,qBAA0C,2CAqBnG,6CAKJ,UAEE,yBlB2CW,6JkBlCb,UAGE,yBAxC+I,qBAA0C,0JA+CzL,0CAKI,aDQN,UC3DA,yBlBsEa,wCChEb,mCiBP6D,qBAA0C,qCAYvG,UAEE,yBAd2D,qBAA0C,2CAqBnG,2CAKJ,UAEE,yBlB2CW,0JkBlCb,UAGE,yBAxC+I,qBAA0C,uJA+CzL,0CAKI,YDQN,aC3DA,yBlBsEa,uCChEb,sCiBP6D,qBAA0C,mCAYvG,aAEE,yBAd2D,qBAA0C,4CAqBnG,yCAKJ,aAEE,yBlB2CW,uJkBlCb,aAGE,yBAxC+I,qBAA0C,oJA+CzL,2CAKI,WDQN,UC3DA,yBlBsEa,sCChEb,mCiBP6D,qBAA0C,iCAYvG,UAEE,yBAd2D,qBAA0C,yCAqBnG,uCAKJ,UAEE,yBlB2CW,oJkBlCb,UAGE,yBAxC+I,qBAA0C,iJA+CzL,wCAKI,qBDQN,UC3DA,yBlBsEa,gDChEb,mCiBP6D,qBAA0C,qDAYvG,UAEE,yBAd2D,qBAA0C,2CAqBnG,2DAKJ,UAEE,yBlB2CW,kLkBlCb,UAGE,yBAxC+I,qBAA0C,+KA+CzL,0CAKI,oBDQN,UC3DA,yBlBsEa,+CChEb,mCiBP6D,qBAA0C,mDAYvG,UAEE,yBAd2D,qBAA0C,0CAqBnG,yDAKJ,UAEE,yBlB2CW,+KkBlCb,UAGE,yBAxC+I,qBAA0C,4KA+CzL,yCAKI,sBDcN,ajBKa,iDChEb,UiBmDkD,yBlBarC,4EkBHb,yCAEE,6DAGF,alBFa,6BkBKX,gKAGF,UAGE,yBlBXW,uMkBeX,yCAKI,wBDzBN,ajBKa,mDChEb,aiBmDkD,yBlBarC,gFkBHb,2CAEE,iEAGF,alBFa,6BkBKX,sKAGF,aAGE,yBlBXW,6MkBeX,2CAKI,sBDzBN,ajBKa,iDChEb,UiBmDkD,yBlBarC,4EkBHb,wCAEE,6DAGF,alBFa,6BkBKX,gKAGF,UAGE,yBlBXW,uMkBeX,wCAKI,mBDzBN,UjBKa,2CChEb,UiBmDkD,sBlBarC,mEkBHb,wCAEE,uDAGF,UlBFa,6BkBKX,uJAGF,UAGE,sBlBXW,2LkBeX,wCAKI,sBDzBN,ajBKa,iDChEb,UiBmDkD,yBlBarC,4EkBHb,0CAEE,6DAGF,alBFa,6BkBKX,gKAGF,UAGE,yBlBXW,uMkBeX,0CAKI,qBDzBN,ajBKa,gDChEb,UiBmDkD,yBlBarC,0EkBHb,yCAEE,2DAGF,alBFa,6BkBKX,6JAGF,UAGE,yBlBXW,oMkBeX,yCAKI,oBDzBN,ajBKa,+CChEb,aiBmDkD,yBlBarC,wEkBHb,2CAEE,yDAGF,alBFa,6BkBKX,0JAGF,aAGE,yBlBXW,iMkBeX,2CAKI,mBDzBN,ajBKa,8CChEb,UiBmDkD,yBlBarC,sEkBHb,wCAEE,uDAGF,alBFa,6BkBKX,uJAGF,UAGE,yBlBXW,8LkBeX,wCAKI,6BDzBN,ajBKa,wDChEb,UiBmDkD,yBlBarC,0FkBHb,yCAEE,2EAGF,alBFa,6BkBKX,qLAGF,UAGE,yBlBXW,4NkBeX,yCAKI,4BDzBN,ajBKa,uDChEb,UiBmDkD,yBlBarC,wFkBHb,yCAEE,yEAGF,alBFa,6BkBKX,kLAGF,UAGE,yBlBXW,yNkBeX,yCAKI,WDdR,ejB6M8B,cAhHY,qBACA,iBCpKxC,aDqKwC,0BACA,iCiBtFxC,yBjBsFwC,uCiBjFxC,ajBpFS,oBiBuFP,6EAWJ,kBCPE,kBnBfiB,gBCgJW,oBMvN1B,6EWiGJ,oBCXE,mBnBfiB,gBCiJW,oBMxN1B,YW0GJ,aACE,WACA,uBAGA,gBjBwT4B,uFiB/S5B,UACE,OE3IJ,8BACE,wCJmBI,MIpBN,eJqBQ,mBIlBN,SACE,sBAKF,YACE,aAIJ,iBACE,SACA,gBACA,4BACA,wCJEI,YINN,eJOQ,yCKpBR,iBAIE,kBAGF,kBACE,yBCoBE,oBACE,mBrBgOwB,sBADA,WqB5NxB,sBAhCJ,oCACA,gBACA,mCACA,+BAqDE,aACE,gBD1CN,iBACE,SACA,OACA,apBypBkC,aoBvpBlC,WACA,gBpBiuBkC,gBoB/tBlC,mBACA,erBgEiB,WDzEN,gBsBYX,gBACA,sBtBrBM,4BsBuBN,iCACA,qBddE,qBcuBA,UACE,OACA,sBAGF,OACE,UACA,wBVYF,uBUnBA,UACE,OACA,yBAGF,OACE,UACA,yBVYF,uBUnBA,UACE,OACA,yBAGF,OACE,UACA,yBVYF,uBUnBA,UACE,OACA,yBAGF,OACE,UACA,yBVYF,uBUnBA,UACE,OACA,yBAGF,OACE,UACA,yBAQJ,QACE,YACA,aACA,sBpB+rBgC,iCqB7tBhC,oBACE,mBrBgOwB,sBADA,WqB5NxB,aAzBJ,oCACA,yBACA,mCACA,uCA8CE,aACE,2BDWJ,KACE,WACA,UACA,aACA,oBpBirBgC,oCqB7tBhC,oBACE,mBrBgOwB,sBADA,WqB5NxB,kCAlBJ,eACA,qCACA,uBACA,0CAuCE,aACE,oCDqBF,gBACE,0BAMJ,KACE,WACA,UACA,aACA,qBpBgqBgC,mCqB7tBhC,oBACE,mBrBgOwB,sBADA,WqB5NxB,mCAWA,YACE,oCAGF,oBACE,oBrB6MsB,sBADA,WqBzMtB,kCA9BN,wBACA,qCACA,yCAiCE,aACE,oCDsCF,gBACE,2IAQJ,UAIE,YACA,mBAKJ,QE9GE,eACA,gBACA,6BACA,gBFkHF,aACE,WACA,oBACA,WACA,gBpBiK4B,WF/QjB,mBsBiHX,mBAEA,6BACA,SACA,2CnBrHA,aDuvBkC,qBoBlnBhC,iCtB3GqB,6CsB+GvB,UtBzIW,qBsB4IT,gCtBhHsB,iDsBoHxB,apBpJS,oBoBuJP,6BACA,qBAQJ,aACE,kBAIF,aACE,mBpBimBkC,gBoB/lBlC,mBrB3FiB,cC5ER,mBoB0KT,qBAIF,aACE,oBACA,WtB7KW,gCyBbb,iBAEE,oBACA,sBACA,+IAEA,iBACE,cACA,uKtBCF,SsBII,2fAEF,SAGE,cAMN,YACE,eACA,2BACA,2BAEA,UACE,2IAMF,gBAEE,mQAIF,yBjBXE,6BACA,2NiBeF,wBjBFE,4BACA,wBiBmBJ,sBACE,sBACA,8GAEA,aAGE,0CAGF,cACE,kJAIJ,qBACE,qBACA,kJAGF,oBACE,oBACA,qBAoBF,qBACE,uBACA,uBACA,gHAEA,UAEE,sKAGF,eAEE,uSAIF,4BjBrFE,4BACA,+PiByFF,wBjBxGE,0BACA,+KiB2HF,eAEE,kVAEA,iBAEE,sBACA,oBACA,cCzJN,iBACE,aACA,eACA,oBACA,WACA,uHAEA,iBAIE,cACA,SACA,YACA,gBACA,2gBAEA,gBAGE,0IAKJ,SAGE,oDAIF,SACE,4FAKA,wBlBIA,4BACA,uCkBCA,mBACA,8HAEA,wBlBLA,4BACA,8NkBSA,yBlBxBA,6BACA,qNkB+BA,yBlBhCA,6BACA,0CkB8CJ,YAEE,kRAKA,iBACE,UACA,sTAEA,SACE,uoDAIJ,gBAIE,sBAIJ,sCACA,mCAQA,YACE,mBACA,uBACA,gBACA,ezB7BiB,gBCsMW,gBAKA,cAtRnB,kBwB6GT,mBACA,yBxBnHS,yBwBqHT,qBlB5GE,4EkBgHF,YAEE,4EAUJ,+BxBuWwC,6YwBlWxC,kBAME,kBzBhEiB,gBCgJW,oBMvN1B,4EkB6IJ,iCxBqVwC,6YwBhVxC,oBAME,mBzBjFiB,gBCiJW,oBMxN1B,+DkB8JJ,qBAEE,m9BAWF,yBlB3JI,6BACA,8mBkBqKJ,wBlBxJI,4BACA,iBmBxCJ,iBACE,UACA,cACA,kBACA,oBACA,mBACA,wBAGF,mBACE,kBzByfsC,uByBrfxC,iBACE,OACA,WACA,WzBqfsC,eyBnftC,UACA,6DAEA,U3BvBM,qBEkPsB,oFyBpN5B,0CzBoW4B,yEyB3V5B,oBzBsbsC,2EyBlbtC,U3B3CM,yBE8hBwC,iIyBze5C,azBhDO,4HyBmDL,wB3BRc,uB2BmBpB,iBACE,gBACA,mBAEA,+BAIA,iBACE,WACA,aACA,cACA,WzBwboC,gCyBrbpC,WACA,yB3BrCO,yB2BuCP,8BAKF,iBACE,WACA,aACA,cACA,WzByaoC,uByBtapC,iCACA,gDAUF,oBnBlGE,6EmBuGA,oOACE,oFAKF,oBzB2H0B,4GyBtH1B,iLACE,uFAKF,mCzBoZ4C,6FyBjZ5C,mCzBiZ4C,6CyBtY9C,iBzB2Z8C,0EyBrZ5C,gLACE,oFAKF,mCzB0X4C,gByB/WhD,oBACE,8CAGE,aACE,czBkY0C,mByBhY1C,oBzBiY0C,6CyB5X5C,uBACE,0BACA,uBzB2X0C,iDA5iBrC,oBA2iBqC,kIyBpX1C,wCV/KA,4CUuKF,eVtKI,4EUmLJ,wB3BlJO,8B2BoJL,qFAKF,mCzB+U4C,gByBlUhD,oBACE,WACA,mCzBqRsC,uCyBnRtC,e1BvIiB,gBCsMW,gBAKA,cAtRnB,sByBwNT,yOACA,yBACA,qBnBtNE,gBmByNF,sBAEA,oBzBwPsC,UyBtPpC,2CzBuWgC,iCyB/VhC,azBzOO,yBFwCA,+D2B4MT,WAEE,qBzB+H0B,sByB7H1B,yBAGF,azB5PS,yBAJA,4ByBsQT,YACE,+BAIF,iBACE,0BACA,mBAIJ,iCzB0NwC,mBAxGV,yCACA,mBDpTX,mB0ByMnB,+BzBmNwC,kBApGV,uCACA,kBDzTX,c0BsNnB,iBACE,qBACA,WACA,mCzBiMsC,gByB/LtC,oBAGF,iBACE,UACA,WACA,mCzByLsC,SyBvLtC,gBACA,UACA,6CAEA,oBzBqKsC,2CA3FV,gGyBpE5B,wB3B9QkB,uD2BoRhB,gBzB2Te,2DyBtTjB,yBACE,oBAIJ,iBACE,MACA,QACA,OACA,UACA,mCzBwJsC,uByBtJtC,gBACA,gBzB/D4B,gBAKA,cAtRnB,yBFwCA,yB2B8ST,qBnBlVE,2BmBsVF,iBACE,MACA,QACA,SACA,UACA,cACA,6BzBiIoC,uByB/HpC,gBzB5E0B,cAtRnB,iByBqWP,yBzB1WO,oByB4WP,gCnBnWA,emB8WJ,UACE,cACA,UACA,6BACA,gBACA,qBAEA,SACE,2CAIA,yDzBmOyC,uCyBlOzC,yDzBkOyC,gCyBjOzC,yDzBiOyC,iCyB9N3C,QACE,qCAGF,UzBoN2C,gCyBjNzC,yBzB9J0B,SAkXe,mBM1lBzC,uGmB2YA,gBACA,wCV1YE,oCUiYJ,eVhYM,6CU2YJ,wBzBiNyC,8CyB5M3C,UzB6LkC,aACA,kByB3LhC,ezB4LgC,yBA1lBzB,yByBiaP,mBnBzZA,iCmB8ZF,UzByL2C,qCA/Wf,SAkXe,mBM1lBzC,uGmBqaA,gBACA,wCVpaE,gCU4ZJ,eV3ZM,yCUqaJ,wBzBuLyC,iCyBlL3C,UzBmKkC,aACA,kByBjKhC,ezBkKgC,yBA1lBzB,yByB2bP,mBnBnbA,0BmBwbF,UzB+J2C,yByB5JzC,mBzBrE0B,2CA9IA,SAkXe,mBM1lBzC,uGmBkcA,gBACA,wCVjcE,yBUsbJ,eVrbM,kCUkcJ,wBzB0JyC,0ByBrJ3C,UzBsIkC,aACA,kByBpIhC,ezBqIgC,6ByBnIhC,yBACA,mBACA,+BAIF,wBzB7dS,mBMQP,+BmB0dF,iBACE,yBzBneO,mBMQP,8CmBieA,wBzBveO,uDyB2eP,cACE,0CAGF,wBzB/eO,0CyBmfP,cACE,mCAGF,wBzBvfO,iEyB6fX,sGAGE,wCVxfI,gEUqfN,eVpfQ,OWhBR,YACE,eACA,eACA,gBACA,gBACA,WAGF,aACE,mBACA,iCzBCA,oByBGE,oBAIF,a1BVS,oB0BYP,eACA,WAQJ,+BACE,qBAEA,kBACE,6BACA,8BpBZA,+BACA,qDLZF,oCD8qBkC,8B0BhpBhC,a1BjCO,6B0BmCL,yBACA,+DAIJ,a1BvCS,sBFNH,kCEyrB4B,0B0BroBlC,eAEE,yBpBnCA,0BACA,sBoB8CF,oBpBxDE,wDoB4DF,U5BtEM,yBEkPsB,yC0B/J5B,aAEE,kBACA,mDAKF,YAEE,YACA,kBACA,wBAUF,YACE,sBAEF,aACE,SCpGJ,iBACE,aACA,eACA,mBACA,8BACA,oBACA,qIAIA,YACE,eACA,mBACA,8BACA,eAoBJ,oBACE,c7BHuB,mCEsFhB,oBD9CU,oB4BhCjB,mBACA,yC1B1CA,oB0B6CE,aASJ,YACE,sBACA,eACA,gBACA,gBACA,uBAEA,eACE,eACA,4BAGF,eACE,WACA,cASJ,oBACE,kB3BylBkC,uC2B3kBpC,eACE,YACA,mBAGA,iBAIF,qBACE,kB5B7BiB,c4B+BjB,6BACA,6BACA,qBrBxGE,6CLFF,oB0B8GE,sBAMJ,oBACE,YACA,aACA,sBACA,WACA,mCACA,oBAGF,e3BglBoC,gB2B9kBlC,2BjBtEE,gMiBkFI,eACE,eACA,yBjBjGN,kBiB6FA,oBAoBI,2BACA,+BAEA,kBACE,8CAEA,iBACE,yCAGF,mB7BnIkB,oN6B0IpB,gBACE,sCAcF,gBACE,oCAGF,uBACE,gBAGA,mCAGF,YACE,4BjBhJN,gMiBkFI,eACE,eACA,yBjBjGN,kBiB6FA,oBAoBI,2BACA,+BAEA,kBACE,8CAEA,iBACE,yCAGF,mB7BnIkB,oN6B0IpB,gBACE,sCAcF,gBACE,oCAGF,uBACE,gBAGA,mCAGF,YACE,4BjBhJN,gMiBkFI,eACE,eACA,yBjBjGN,kBiB6FA,oBAoBI,2BACA,+BAEA,kBACE,8CAEA,iBACE,yCAGF,mB7BnIkB,oN6B0IpB,gBACE,sCAcF,gBACE,oCAGF,uBACE,gBAGA,mCAGF,YACE,4BjBhJN,gMiBkFI,eACE,eACA,yBjBjGN,kBiB6FA,oBAoBI,2BACA,+BAEA,kBACE,8CAEA,iBACE,yCAGF,mB7BnIkB,oN6B0IpB,gBACE,sCAcF,gBACE,oCAGF,uBACE,gBAGA,mCAGF,YACE,iBAhEN,oBAoBI,2BACA,+KAnBA,eACE,eACA,4BAmBF,kBACE,2CAEA,iBACE,sCAGF,mB7BnIkB,kM6B0IpB,gBACE,mCAcF,gBACE,iCAGF,uBACE,gBAGA,gCAGF,YACE,6BAcR,oB3BigBkC,qECxtBlC,oBDwtBkC,qC2BxfhC,oB3BsfgC,qFCttBlC,oBDutBkC,8C2Bhf9B,oB3Bkf8B,2K2B7ehC,oB3B4egC,+B2BpelC,oB3BkekC,4BAKA,oC2BlelC,kRACE,4BAGF,oB3BydkC,8B2BvdhC,oB3BydgC,uECxtBlC,oBDwtBkC,4B2B7clC,U7BnRM,mEGQN,UHRM,oC6B4RJ,0B7BlPgB,mFGlClB,0BHmCwB,6C6BwPpB,2B3Bub8B,uK2BlbhC,U7BxSI,8B6BgTN,0B7BtQkB,kCEkrBgB,mC2BvalC,wRACE,2BAGF,0B7B/QkB,6B6BiRhB,U7B3TI,qEGQN,UHRM,O8BJR,iBACE,aACA,sBACA,YACA,qBAEA,sB9BFM,2B8BIN,kCACA,qBtBKE,UsBFF,cACE,cACA,mBAGF,kBACE,sBACA,+BAEA,kBACE,2CtBCF,4CACA,8BsBEA,qBACE,+CtBUF,8CACA,+DsBJF,YAEE,YAIJ,aAGE,eAGA,gB5B+wBkC,a4B1wBpC,mB9BrBgB,gB8ByBhB,kBACE,gBACA,uBAGF,eACE,kB3BrDA,oB2B0DE,uBAGF,mB5BwvBkC,c4B/uBpC,qBACE,gBACA,iC5BkvBkC,yC4B/uBlC,0BAEA,yDtBvEE,csB4EJ,qBACE,iC5BuuBkC,sC4BpuBlC,yBAEA,yDtBlFE,mBsB4FJ,sBACE,sBACA,sBACA,gBACA,oBAGF,sBACE,sBACA,mBAIF,iBACE,MACA,QACA,SACA,OACA,gB5B4sBkC,kCM1zBhC,0CsBmHJ,aAGE,WACA,yBAGF,0CtBjHI,4CACA,4BsBqHJ,8CtBxGI,8CACA,kBsBgHF,kB5BorBkC,wBUlxBhC,WkB6FJ,YAMI,mBACA,mBACA,kBACA,kBAEA,WAEE,kB5BwqB8B,gB4BtqB9B,iB5BsqB8B,oB4BxpBlC,kB5BwpBkC,wBUlxBhC,YkBuHJ,YAQI,mBACA,mBAGA,WAEE,gBACA,yBAEA,aACE,cACA,oCAKA,yBtBzKJ,6BACA,kGsB2KM,yBAGE,qGAEF,4BAGE,qCAIJ,wBtB1KJ,4BACA,oGsB4KM,wBAGE,uGAEF,2BAGE,sBAcV,mB9BjNc,wBY0BZ,ckBsLJ,c5B+lBoC,mBACA,U4BxlBhC,SACA,qBAEA,oBACE,WACA,aAUN,oBACE,kBAEA,eACE,qCAEA,eACE,6BtBvOF,4BACA,sCsB0OA,wBtBzPA,0BACA,+BsB4PA,etBtQA,mBsBwQE,aC1RN,YACE,eACA,oBACA,mB7BoiCkC,gB6BjiClC,yB7BGS,qBMSP,mCuBLF,kB7BwhCkC,2C6BrhChC,UACE,oB7BohC8B,cAxhCzB,Y6BOL,iDAUJ,yBACE,iDAGF,oBACE,yBAGF,a7BzBS,a8BbX,YACE,e3BGA,gBACA,qBGaE,YwBZJ,iBACE,cACA,qBACA,iBACA,iB9BoxBkC,cA/mBM,sBFvKlC,yBgCON,kBAEA,SACE,c9B+JsC,qB8B7JtC,yB9BXO,qBACA,kB8BeT,SACE,U9B4wBgC,2CA5ZN,mC8BxW1B,aACE,8BxBaF,iCACA,kCwBTA,8BxBNA,kCACA,8BwBUF,SACE,WhCtCI,yBEkPsB,qD8BtM5B,a9BvCS,oB8ByCP,YAEA,sBhChDI,qBEEG,2B+BPT,qBACE,kBhCqFe,gBCgJW,kD+B9NxB,4BzBqCF,gCACA,iDyBjCE,6BzBkBF,iCACA,2ByBhCF,oBACE,mBhCqFe,gBCiJW,kD+B/NxB,4BzBqCF,gCACA,iDyBjCE,6BzBkBF,iCACA,Q0B9BJ,oBACE,mBACA,cjCiEE,gBCwN0B,cgCtR5B,kBACA,mBACA,wBACA,qB1BKE,8H0BHF,wCjBKI,OiBfN,ejBgBQ,8BdLN,oB+BGI,cAKJ,YACE,uDAKJ,iBACE,SACA,aAOF,kBhCg4BoC,sCMr5BhC,gB0BgCF,UCjDA,yBjC2Ea,6CC5Db,UgCVI,yBACA,6CAGF,SAEE,0CACA,kBDqCJ,aCjDA,yBjC2Ea,iDC5Db,agCVI,yBACA,iDAGF,SAEE,4CACA,gBDqCJ,UCjDA,yBjC2Ea,6CC5Db,UgCVI,yBACA,6CAGF,SAEE,yCACA,aDqCJ,UCjDA,sBjC2Ea,uCC5Db,UgCVI,yBACA,uCAGF,SAEE,yCACA,gBDqCJ,UCjDA,yBjC2Ea,6CC5Db,UgCVI,yBACA,6CAGF,SAEE,2CACA,eDqCJ,UCjDA,yBjC2Ea,2CC5Db,UgCVI,yBACA,2CAGF,SAEE,0CACA,cDqCJ,aCjDA,yBjC2Ea,yCC5Db,agCVI,yBACA,yCAGF,SAEE,4CACA,aDqCJ,UCjDA,yBjC2Ea,uCC5Db,UgCVI,yBACA,uCAGF,SAEE,yCACA,uBDqCJ,UCjDA,yBjC2Ea,2DC5Db,UgCVI,yBACA,2DAGF,SAEE,0CACA,sBDqCJ,UCjDA,yBjC2Ea,yDC5Db,UgCVI,yBACA,yDAGF,SAEE,0CACA,YCbN,iBACE,mBlCwzBkC,yBAhzBzB,oBMSP,wBI0CA,WwB5DJ,iBAQI,mBAIJ,eACE,eACA,gB5BIE,Q6BdJ,iBACE,uBACA,mBnCw9BkC,6BmCt9BlC,qB7BUE,gB6BLJ,aAEE,aAIF,enC6Q8B,oBmCpQ9B,kBACE,2BAGA,iBACE,MACA,QACA,UACA,uBACA,cACA,gBAUF,aACqH,yBAA5F,qBAA4C,mBC5CrE,wBACE,4BAGF,aACE,kBDsCF,aACqH,yBAA5F,qBAA4C,qBC5CrE,wBACE,8BAGF,aACE,gBDsCF,aACqH,yBAA5F,qBAA4C,mBC5CrE,wBACE,4BAGF,aACE,aDsCF,aACqH,sBAA5F,qBAA4C,gBC5CrE,wBACE,yBAGF,aACE,gBDsCF,aACqH,yBAA5F,qBAA4C,mBC5CrE,wBACE,4BAGF,aACE,eDsCF,aACqH,yBAA5F,qBAA4C,kBC5CrE,wBACE,2BAGF,aACE,cDsCF,aACqH,yBAA5F,qBAA4C,iBC5CrE,wBACE,0BAGF,aACE,aDsCF,aACqH,yBAA5F,qBAA4C,gBC5CrE,wBACE,yBAGF,aACE,uBDsCF,aACqH,yBAA5F,qBAA4C,0BC5CrE,wBACE,mCAGF,aACE,sBDsCF,aACqH,yBAA5F,qBAA4C,yBC5CrE,wBACE,kCAGF,aACE,iCCRF,KACE,8BACA,mCAIJ,YACE,YrCi+BkC,gBqC/9BlC,cACA,kBtC6EiB,yBChFR,qBMSP,e+BCJ,YACE,sBACA,uBACA,gBACA,WvCfM,kBuCiBN,mBACA,yBrCs9BkC,0BqCp9BlC,wCtBRI,csBDN,etBEQ,wBsBUR,oMCYE,0BDVA,wBAIA,iDACE,wCAGE,uBAJJ,cAKM,SE1CR,YACE,uBACA,aAGF,MACE,aCFF,YACE,sBACA,eAGA,gBACA,qBlCQE,yBkCEJ,UACE,cxCPS,mBwCST,6DvCPA,SuCWE,cxCbO,qBwCeP,yBxCrBO,gCwCyBT,U1CjBW,yBEPF,kBwCmCX,iBACE,cACA,sBACA,sB1CvCM,kC0C2CN,8BAEA,8BlC1BE,gCACA,6BkC6BF,kClChBE,kCACA,qDkCmBF,axChDS,oBwCmDP,sB1CxDI,yB0C6DN,SACE,W1CtDS,sBARL,8BA+ByB,mC0CqC/B,kBACE,0CAEA,eACE,qBxC4JwB,wBwC7I1B,kBACE,qDAGE,gClC1BJ,0BAZA,oDkC2CI,8BlC3CJ,4BAYA,gDkCoCI,YACE,0DAGF,oBxC2HsB,oBwCzHpB,iEAEA,gBACE,sBxCsHkB,wBUhL1B,0B8BmCA,kBACE,wDAGE,gClC1BJ,0BAZA,uDkC2CI,8BlC3CJ,4BAYA,mDkCoCI,YACE,6DAGF,oBxC2HsB,oBwCzHpB,oEAEA,gBACE,sBxCsHkB,yBUhL1B,0B8BmCA,kBACE,wDAGE,gClC1BJ,0BAZA,uDkC2CI,8BlC3CJ,4BAYA,mDkCoCI,YACE,6DAGF,oBxC2HsB,oBwCzHpB,oEAEA,gBACE,sBxCsHkB,yBUhL1B,0B8BmCA,kBACE,wDAGE,gClC1BJ,0BAZA,uDkC2CI,8BlC3CJ,4BAYA,mDkCoCI,YACE,6DAGF,oBxC2HsB,oBwCzHpB,oEAEA,gBACE,sBxCsHkB,yBUhL1B,0B8BmCA,kBACE,wDAGE,gClC1BJ,0BAZA,uDkC2CI,8BlC3CJ,4BAYA,mDkCoCI,YACE,6DAGF,oBxC2HsB,oBwCzHpB,oEAEA,gBACE,sBxCsHkB,oBwCvG9B,elCnHI,oCkCsHF,oBACE,+CAEA,qBACE,0BCzIJ,aDqJwE,yBAA/B,6GvCxIzC,auCwIwE,yBC9IlE,wDAGF,U3CLE,yB0CgJkE,iDCrJxE,aDqJwE,yBAA/B,iHvCxIzC,auCwIwE,yBC9IlE,0DAGF,U3CLE,yB0CgJkE,+CCrJxE,aDqJwE,yBAA/B,6GvCxIzC,auCwIwE,yBC9IlE,wDAGF,U3CLE,yB0CgJkE,4CCrJxE,aDqJwE,yBAA/B,uGvCxIzC,auCwIwE,yBC9IlE,qDAGF,U3CLE,yB0CgJkE,+CCrJxE,aDqJwE,yBAA/B,6GvCxIzC,auCwIwE,yBC9IlE,wDAGF,U3CLE,yB0CgJkE,8CCrJxE,aDqJwE,yBAA/B,2GvCxIzC,auCwIwE,yBC9IlE,uDAGF,U3CLE,yB0CgJkE,6CCrJxE,aDqJwE,yBAA/B,yGvCxIzC,auCwIwE,yBC9IlE,sDAGF,U3CLE,yB0CgJkE,4CCrJxE,aDqJwE,yBAA/B,uGvCxIzC,auCwIwE,yBC9IlE,qDAGF,U3CLE,yB0CgJkE,sDCrJxE,aDqJwE,yBAA/B,2HvCxIzC,auCwIwE,yBC9IlE,+DAGF,U3CLE,yB0CgJkE,qDCrJxE,aDqJwE,yBAA/B,yHvCxIzC,auCwIwE,yBC9IlE,8DAGF,U3CLE,yB0CgJkE,6BExJ1E,WACE,iB3CwFiB,gBCuMW,c0C5R5B,W1CaS,yBA2kCyB,W0CrlClC,czCKA,UDKS,qB0CLP,uFzCIF,WyCCI,cAWN,SACE,6BACA,SACA,kBAMF,mBACE,aChCF,eAEE,oBAEA,iBACE,gBACA,QAKJ,cACE,MACA,OACA,a3C4pBkC,a2C1pBlC,WACA,YACA,gBACA,UAGA,eAOF,iBACE,WACA,a3Cg5BkC,oB2C74BlC,2BAGA,iCACE,8B3Cs6BgC,wCe97B9B,0B4BuBJ,e5BtBM,4B4B0BN,c3Co6BkC,mC2C/5BlC,qB3Ci6BkC,0B2C55BpC,YACE,6BACA,yCAEA,6BACE,gBACA,+EAGF,aAEE,sCAGF,eACE,wBAIJ,YACE,mBACA,6BACA,gCAGA,aACE,0BACA,mBACA,WACA,gDAIF,qBACE,uBACA,YACA,+DAEA,eACE,wDAGF,YACE,gBAMN,iBACE,aACA,sBACA,WACA,oBAGA,sB7CzGM,4B6C2GN,gCACA,oBrClGE,UqCsGF,iBAIF,cACE,MACA,OACA,a3CgjBkC,Y2C9iBlC,aACA,sB3CjHS,sB2CqHT,+BACA,U7CzEuB,e6C8EzB,YACE,uBACA,8BACA,kB3C4zBkC,gC2C1zBlC,0CrCtHE,2CACA,sBqCwHF,iB3CuzBkC,8B2CpzBhC,cAKJ,eACE,gB3CuI4B,a2CjI9B,iBACE,cAGA,a3CywBkC,e2CpwBpC,YACE,eACA,mBACA,yBACA,eACA,6BACA,8CrCzIE,6CACA,iBqC8IF,aACE,0BAKJ,iBACE,YACA,WACA,YACA,gBACA,wBjCvIE,ciC6IF,e3CswBkC,oB2CpwBhC,0BAGF,8BACE,yCAEA,+BACE,wBAIJ,8BACE,gCAEA,2BACE,mBACA,WAQJ,e3C6uBkC,yBUp5BhC,oBiC2KF,e3CuuBkC,yBUl5BhC,UiCkLF,gB3C+tBkC,W4C58BpC,iBACE,a5CgrBkC,c4C9qBlC,S5C41BkC,2HF90BX,kB+CfvB,gB7C4R4B,gBAKA,gB6C9R5B,iBACA,qBACA,iBACA,oBACA,sBACA,kBACA,oBACA,mBACA,gBACA,mB9C0EiB,qB6C9EjB,UACA,eAEA,U5C+0BkC,iB4C70BlC,iBACE,cACA,Y5Cg1BgC,aACA,yB4C70BhC,iBACE,WACA,yBACA,mBACA,oDAKN,eACE,kEAEA,QACE,kFAEA,KACE,2BACA,sB5CtBK,wD4C4BX,eACE,sEAEA,MACE,Y5CkzBgC,aADA,sF4C7yBhC,OACE,iCACA,wB5CtCK,0D4C4CX,eACE,wEAEA,KACE,wFAEA,QACE,2BACA,yB5CpDK,sD4C0DX,eACE,oEAEA,OACE,Y5CoxBgC,aADA,oF4C/wBhC,MACE,iCACA,uB5CpEK,gB4C0FX,e5C8uBoC,qB4C5uBlC,W9CrGM,kB8CuGN,sB5C9FS,qBMCP,UwClBJ,iBACE,MACA,OACA,a9C8qBkC,c8C5qBlC,gB9C82BkC,2HFj2BX,kB+CfvB,gB7C4R4B,gBAKA,gB6C9R5B,iBACA,qBACA,iBACA,oBACA,sBACA,kBACA,oBACA,mBACA,gBACA,mB9C0EiB,qB+C7EjB,sBhDJM,4BgDMN,gCACA,oBxCGE,iBwCCF,iBACE,cACA,W9C82BgC,aACA,e8C52BhC,gDAEA,iBAEE,cACA,WACA,yBACA,mBACA,oDAKN,mB9C+1BoC,kE8C51BlC,0BACE,kFAEA,QACE,2BACA,iC9C01B8B,gF8Ct1BhC,U9C2L0B,2B8CzLxB,sBhD3CE,wDgDiDR,iB9C20BoC,sE8Cx0BlC,wBACE,Y9Cu0BgC,YADA,e8Cn0BhC,sFAEA,MACE,iCACA,mC9Cm0B8B,oF8C/zBhC,Q9CoK0B,iC8ClKxB,wBhDlEE,0DgDwER,gB9CozBoC,wE8CjzBlC,uBACE,wFAEA,KACE,iCACA,oC9C+yB8B,sF8C3yBhC,O9CgJ0B,iC8C9IxB,yBhDtFE,0GgD4FN,iBACE,MACA,SACA,cACA,W9C2xBgC,oB8CzxBhC,WACA,gCACA,sDAIJ,kB9CoxBoC,oE8CjxBlC,yBACE,Y9CgxBgC,YADA,e8C5wBhC,oFAEA,OACE,iCACA,kC9C4wB8B,kF8CxwBhC,S9C6G0B,iC8C3GxB,uBhDzHE,iBgDgJR,oBACE,gBACA,e/CjEiB,yBCiyBiB,gC8C5tBlC,0CxCnIE,2CACA,uBwCqIF,YACE,eAIJ,oBACE,WhDvJW,WiDHb,iBACE,yBAGF,kBACE,iBAGF,iBACE,WACA,gBACA,wBCvBA,aACE,WACA,WACA,gBDwBJ,iBACE,aACA,WACA,WACA,mBACA,2BACA,qCACA,wChCfI,egCQN,ehCPQ,gEgCiBR,aAGE,0EAGF,0BAEE,0EAGF,2BAEE,+BASA,SACE,4BACA,eACA,mJAGF,SAGE,UACA,sFAGF,SAEE,UACA,0BACA,wChCzDE,qFgCqDJ,ehCpDM,gDgCiER,iBAEE,MACA,SACA,UACA,aAEA,mBACA,uBACA,U/Cq9BmC,WF5iC7B,kBiD0FN,W/Cm9BmC,6B+Cj9BnC,wChChFI,8CgCkEN,ehCjEQ,sHdLN,UHRM,qBiDiGJ,UACA,W/C48BiC,wB+Cx8BrC,MACE,wBAKF,OACE,yDAOF,oBAEE,W/Cq8BmC,+C+Cl8BnC,6BAEF,wNACE,6BAEF,yNACE,sBASF,iBACE,QACA,SACA,OACA,WACA,aACA,uBACA,eACA,iB/C45BmC,gC+Cx5BnC,yBAEA,sBACE,cACA,W/Cy5BiC,WACA,iBAEA,mC+Cv5BjC,eACA,sBjD9JI,4BiDgKJ,kCAEA,qCACA,WACA,4BACA,wChCzJE,wBgC0IJ,ehCzIM,+BgC2JN,SACE,mBASJ,iBACE,UACA,YACA,SACA,WACA,iBACA,oBACA,WjDzLM,kBiD2LN,2BE/LF,GACE,0CAGF,oBACE,WjDqkCsB,uCiDlkCtB,gCACA,+BACA,kBAEA,8CACA,oBAGF,UjD8jC0B,8BAEA,yBiDtjC1B,GACE,kBACE,KAEF,SACE,eACA,gBAIJ,oBACE,WjDqiCsB,uCiDliCtB,8BACA,kBAEA,UACA,4CACA,kBAGF,UjD8hC0B,oDiDxhCxB,8BACE,uBAEE,kBC3DN,8CACA,4CACA,+CACA,oDACA,sDACA,+CCFE,mCACE,uFlDUF,mCkDLI,eANJ,mCACE,+FlDUF,mCkDLI,aANJ,mCACE,uFlDUF,mCkDLI,UANJ,gCACE,2ElDUF,mCkDLI,aANJ,mCACE,uFlDUF,mCkDLI,YANJ,mCACE,mFlDUF,mCkDLI,WANJ,mCACE,+ElDUF,mCkDLI,UANJ,mCACE,2ElDUF,mCkDLI,oBANJ,mCACE,mHlDUF,mCkDLI,mBANJ,mCACE,+GlDUF,mCkDLI,WCCN,gCACE,iBAGF,uCACE,SCXF,gDACA,sDACA,yDACA,wDACA,mDAEA,kCACA,wCACA,2CACA,0CACA,yCAGE,+BACE,mBADF,+BACE,iBADF,+BACE,cADF,4BACE,iBADF,+BACE,gBADF,+BACE,eADF,+BACE,cADF,+BACE,wBADF,+BACE,uBADF,+BACE,eAIJ,4BACE,aAOF,8BACE,uDAGF,+BACE,cAGF,wCACE,0CACA,gBAGF,yCACE,6CACA,iBAGF,4CACE,4CACA,eAGF,wCACE,4CACA,aAGF,8BACE,iBAGF,4BACE,eAGF,8BACE,YAGF,0BACE,kBLxEA,aACE,WACA,WACA,SMOE,2W5CiDF,W4CjDE,oY5CiDF,W4CjDE,oY5CiDF,W4CjDE,oY5CiDF,W4CjDE,0XAUN,cAEI,uZCrBJ,iBACE,cACA,WACA,UACA,gBACA,2BAEA,aACE,WACA,4IAGF,iBAKE,MACA,SACA,OACA,WACA,YACA,SACA,iCASA,0BACE,iCADF,kBACE,gCADF,eACE,gCADF,gBACE,WCzBF,2CACA,mDACA,2DACA,oDAEA,uCACA,+CACA,6CACA,sCACA,oCACA,sCACA,wCACA,gDAEA,2DACA,4DACA,2DACA,iEACA,2DAEA,mDACA,oDACA,oDACA,qDACA,oDAEA,uDACA,wDACA,uDACA,6DACA,6DACA,kDAEA,6CACA,iDACA,kDACA,kDACA,mDACA,qD9CYA,a8ClDA,8CACA,sDACA,8DACA,uDAEA,0CACA,kDACA,gDACA,yCACA,uCACA,yCACA,2CACA,mDAEA,8DACA,+DACA,8DACA,oEACA,8DAEA,sDACA,uDACA,uDACA,wDACA,uDAEA,0DACA,2DACA,0DACA,gEACA,gEACA,qDAEA,gDACA,oDACA,qDACA,qDACA,sDACA,sD9CYA,a8ClDA,8CACA,sDACA,8DACA,uDAEA,0CACA,kDACA,gDACA,yCACA,uCACA,yCACA,2CACA,mDAEA,8DACA,+DACA,8DACA,oEACA,8DAEA,sDACA,uDACA,uDACA,wDACA,uDAEA,0DACA,2DACA,0DACA,gEACA,gEACA,qDAEA,gDACA,oDACA,qDACA,qDACA,sDACA,sD9CYA,a8ClDA,8CACA,sDACA,8DACA,uDAEA,0CACA,kDACA,gDACA,yCACA,uCACA,yCACA,2CACA,mDAEA,8DACA,+DACA,8DACA,oEACA,8DAEA,sDACA,uDACA,uDACA,wDACA,uDAEA,0DACA,2DACA,0DACA,gEACA,gEACA,qDAEA,gDACA,oDACA,qDACA,qDACA,sDACA,sD9CYA,a8ClDA,8CACA,sDACA,8DACA,uDAEA,0CACA,kDACA,gDACA,yCACA,uCACA,yCACA,2CACA,mDAEA,8DACA,+DACA,8DACA,oEACA,8DAEA,sDACA,uDACA,uDACA,wDACA,uDAEA,0DACA,2DACA,0DACA,gEACA,gEACA,qDAEA,gDACA,oDACA,qDACA,qDACA,sDACA,2CC1CA,mCACA,mCACA,6C/CoDA,e+CtDA,sCACA,sCACA,8C/CoDA,e+CtDA,sCACA,sCACA,8C/CoDA,e+CtDA,sCACA,sCACA,8C/CoDA,e+CtDA,sCACA,sCACA,wCCLF,4NCCA,4NAKF,cACE,MACA,QACA,OACA,a3DiqBkC,e2D7pBpC,cACE,QACA,SACA,OACA,a3DypBkC,6B2DppBlC,YADF,eAEI,MACA,a3DipBgC,wL4DzqBpC,iBCEE,UACA,WACA,UACA,YACA,gBACA,sBACA,mBACA,SACA,oDAUA,eAEE,WACA,YACA,iBACA,UACA,mBACA,YC7BJ,gEACA,8DACA,gEACA,iCCCI,+RAIJ,kCACA,uCAIA,uCACA,oCAEA,+BACA,6BCTQ,gCACA,uBAEE,aAEF,yBAEE,aAEF,0BAEE,aAEF,wBAEE,MAfF,qCACA,4BAEE,aAEF,8BAEE,aAEF,+BAEE,aAEF,6BAEE,MAfF,6EACA,2BAEE,aAEF,6BAEE,aAEF,8BAEE,aAEF,4BAEE,MAfF,kFACA,0BAEE,aAEF,4BAEE,aAEF,6BAEE,aAEF,2BAEE,MAfF,qCACA,4BAEE,aAEF,8BAEE,+BAEF,+BAEE,iDAEF,6BAEE,MAfF,mCACA,0BAEE,aAEF,4BAEE,aAEF,6BAEE,aAEF,2BAEE,MAfF,iCACA,wBAEE,aAEF,0BAEE,aAEF,2BAEE,aAEF,yBAEE,MAfF,sCACA,6BAEE,aAEF,+BAEE,aAEF,gCAEE,aAEF,8BAEE,MAfF,qCACA,4BAEE,aAEF,8BAEE,aAEF,+BAEE,aAEF,6BAEE,MAfF,oCACA,2BAEE,aAEF,6BAEE,aAEF,8BAEE,aAEF,4BAEE,MAfF,sCACA,6BAEE,aAEF,+BAEE,aAEF,gCAEE,aAEF,8BAEE,MAfF,oCACA,2BAEE,aAEF,6BAEE,aAEF,8BAEE,aAEF,4BAEE,OAQF,yCACA,8BAEE,eAEF,gCAEE,eAEF,iCAEE,eAEF,+BAEE,OAfF,wCACA,6BAEE,eAEF,+BAEE,eAEF,gCAEE,eAEF,8BAEE,OAfF,sCACA,2BAEE,eAEF,6BAEE,eAEF,8BAEE,eAEF,4BAEE,OAfF,wCACA,6BAEE,eAEF,+BAEE,eAEF,gCAEE,eAEF,8BAEE,OAfF,sCACA,2BAEE,eAEF,6BAEE,eAEF,8BAEE,eAEF,4BAEE,SAMN,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,wBtDTF,QsDlDI,sCACA,uBAEE,mBAEF,yBAEE,mBAEF,0BAEE,mBAEF,wBAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,uCACA,wBAEE,mBAEF,0BAEE,mBAEF,2BAEE,mBAEF,yBAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,UAQF,+CACA,8BAEE,qBAEF,gCAEE,qBAEF,iCAEE,qBAEF,+BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,YAMN,+CACA,0BAEE,yBAEF,4BAEE,yBAEF,6BAEE,yBAEF,2BAEE,yBtDTF,QsDlDI,sCACA,uBAEE,mBAEF,yBAEE,mBAEF,0BAEE,mBAEF,wBAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,uCACA,wBAEE,mBAEF,0BAEE,mBAEF,2BAEE,mBAEF,yBAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,UAQF,+CACA,8BAEE,qBAEF,gCAEE,qBAEF,iCAEE,qBAEF,+BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,YAMN,+CACA,0BAEE,yBAEF,4BAEE,yBAEF,6BAEE,yBAEF,2BAEE,yBtDTF,QsDlDI,sCACA,uBAEE,mBAEF,yBAEE,mBAEF,0BAEE,mBAEF,wBAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,uCACA,wBAEE,mBAEF,0BAEE,mBAEF,2BAEE,mBAEF,yBAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,UAQF,+CACA,8BAEE,qBAEF,gCAEE,qBAEF,iCAEE,qBAEF,+BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,YAMN,+CACA,0BAEE,yBAEF,4BAEE,yBAEF,6BAEE,yBAEF,2BAEE,yBtDTF,QsDlDI,sCACA,uBAEE,mBAEF,yBAEE,mBAEF,0BAEE,mBAEF,wBAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,yCACA,0BAEE,mBAEF,4BAEE,mBAEF,6BAEE,mBAEF,2BAEE,SAfF,uCACA,wBAEE,mBAEF,0BAEE,mBAEF,2BAEE,mBAEF,yBAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,2CACA,4BAEE,mBAEF,8BAEE,mBAEF,+BAEE,mBAEF,6BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,SAfF,4CACA,6BAEE,mBAEF,+BAEE,mBAEF,gCAEE,mBAEF,8BAEE,SAfF,0CACA,2BAEE,mBAEF,6BAEE,mBAEF,8BAEE,mBAEF,4BAEE,UAQF,+CACA,8BAEE,qBAEF,gCAEE,qBAEF,iCAEE,qBAEF,+BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,UAfF,8CACA,6BAEE,qBAEF,+BAEE,qBAEF,gCAEE,qBAEF,8BAEE,UAfF,4CACA,2BAEE,qBAEF,6BAEE,qBAEF,8BAEE,qBAEF,4BAEE,YAMN,+CACA,0BAEE,yBAEF,4BAEE,yBAEF,6BAEE,yBAEF,2BAEE,yBChEJ,iBACE,MACA,QACA,SACA,OACA,UACA,oBAEA,WACA,+BAEA,kCCVJ,oHAIA,yCACA,2CACA,6CACA,eCTE,uBACA,mBACA,YDeE,uCACA,yCACA,oDxDqCA,cwDvCA,0CACA,4CACA,qDxDqCA,cwDvCA,0CACA,4CACA,qDxDqCA,cwDvCA,0CACA,4CACA,qDxDqCA,cwDvCA,0CACA,4CACA,8CAMJ,oDACA,qDACA,wDAIA,gDACA,mDACA,6CACA,+CACA,2CACA,yCAIA,oCEvCE,wBACE,2CnEUF,wBmELM,iBANN,wBACE,+CnEUF,wBmELM,eANN,wBACE,2CnEUF,wBmELM,YANN,qBACE,qCnEUF,wBmELM,eANN,wBACE,2CnEUF,wBmELM,cANN,wBACE,yCnEUF,wBmELM,aANN,wBACE,uCnEUF,wBmELM,YANN,wBACE,qCnEUF,wBmELM,sBANN,wBACE,yDnEUF,wBmELM,qBANN,wBACE,uDnEUF,wBmELM,YFuCR,yEACA,wCAEA,+CACA,iDAIA,UGvDE,kBACA,iBACA,6BACA,SACA,uBHuDF,4CAEA,gCACE,gCACA,aAKF,kCIjEA,6BACE,YAGF,4BACE,mCCCE,2BAKE,2BAEA,aAIA,yBACE,oBASJ,4BACE,KAcF,+BACE,gBAEF,wBAEE,wBACA,OAQF,0BACE,QAGF,uBAEE,SAGF,SAGE,SACA,OAGF,sBAEE,OAQF,OvEgiCgC,MuE7hChC,wBACE,YAEF,wBACE,SAIF,YACE,QAEF,qBACE,QAGF,mCACE,qBAEA,gCAEE,uCAKF,mCAEE,aAIJ,aACE,4EAEA,oBzE3HM,uByEmIR,aACE,qBzEpIM,S0EoCZ,YACE,mBACA,qBACA,uBACA,kBACA,yBAzCgB,gBA8ChB,wBApCe,cAoCf,wBApCe,aAoCf,wBApCe,aAoCf,wBApCe,gBAoCf,wBApCe,eA0Cf,2BACE,sgBACA,aAFF,2BACE,kzBACA,YAFF,2BACE,0wBACA,YAFF,2BACE,00HACA,eAFF,2BACE,0uBACA,eAIJ,kBACE,WApDmB,gBAwDrB,WACE,4BACA,cAGF,gBACE,gBAGF,oBACE,uCAEA,UApEmB,wBAyEnB,UACE,qBACA,+CAIJ,qBACE,YACA,eACA,gBACA,iBACA,WApFmB,yBAsFnB,WACA,YACA,eACA,uBACA,SACA,qDAEA,UAEE,qBACA,eACA,WACA,YACA,0BAGF,YACE,sBACA,uBACA,qBAIJ,iBACE,OACA,SACA,WACA,sBACA,WACA,kBAWF,cACE,eACA,oBAEA,sGAEF,UAGE,oBACA,OACA,QACA,kHAEF,eAGE,oBACA,2HAEF,mBAGE,oBAEF,0BACE,8BACA,sBACA,sBAEF,cACE,YACA,8BACA,gCACA,4BACA,yBACA,WAlKmB,WAoKnB,yBAEF,wBACE,UACA,eACA,wFAGF,SAEE,YACA,uBAIF,KACE,QACA,WACA,0BAEF,QACE,QACA,WACA,iBAEF,QAnKiB,6BAuKjB,QAvKiB,kBA0KjB,QA1KiB,gCA8KjB,UA9KiB,kCAkLjB,WAlLiB,oBAqLjB,WArLiB,yBAyLjB,OACE;;;EC7NF,CCGA,WACE,0BACA,4CACA,wSAMA,mBACA,kBCVF,IACE,qBACA,6CACA,kBACA,oBACA,mCACA,kCCLF,OACE,yBACA,kBACA,oBAEF,qBACA,qBACA,qBACA,qBCVA,OACE,qBACA,kBCDF,OACE,eACA,0BCMoB,CDLpB,qBACA,4BAEF,OACE,kBACA,qBACA,oBCDoB,CDEpB,kBACA,kBACA,aACE,qBEbJ,WACE,yBACA,wBACA,mBAGF,yBACA,2BAGE,mCACA,mCAIF,wBACA,sBAGE,gCACA,gCCpBF,SACE,6CACQ,qCAGV,UACE,+CACQ,uCAGV,2BACE,GACE,+BACQ,uBAEV,KACE,iCACQ,0BAIZ,mBACE,GACE,+BACQ,uBAEV,KACE,iCACQ,0BC5BZ,cCWE,sEACA,gCACI,4BACI,wBDbV,eCUE,sEACA,iCACI,6BACI,yBDZV,eCSE,sEACA,iCACI,6BACI,yBDVV,oBCcE,gFACA,+BACI,2BACI,uBDhBV,kBCaE,gFACA,+BACI,2BACI,uBDXV,gHAKE,YEfF,UACE,kBACA,qBACA,UACA,WACA,gBACA,sBAEF,0BACE,kBACA,OACA,WACA,kBAEF,iCACA,2BACA,sBLTsB,CMPtB,4BNwUe,CMvUf,4BN2de,CM1df,6BN0jBgB,CMzjBhB,iCNsOoB,CMrOpB,4BNuWe,CMtWf,2BNknBc,CMjnBd,6BNsnBgB,CMrnBhB,2BNytBc,CMxtBd,2BNmRc,CMlRd,+BNupBkB,CMtpBlB,yBNqpBY,CMppBZ,8BNspBiB,CMrpBjB,4BNyIe,CMxIf,oDAEkC,WNqqBnB,CMpqBf,kCN8iBqB,CM7iBrB,mCN4iBsB,CM3iBtB,gCN4fmB,CM3fnB,6BNikBgB,CMhkBhB,+BACgC,WNgKnB,CM/Jb,8BN+qBiB,CM9qBjB,2BNwVc,CMvVd,6BNuPgB,CMtPhB,8BNgJiB,CM/IjB,2BNmhBc,CMlhBd,+BNgMkB,CM/LlB,0CNY6B,CMX7B,wCNc2B,CMb3B,4BNqWe,CMpWf,oCNweuB,CMvevB,0CACmC,WNsgBnB,CMrgBhB,8BNggBiB,CM/fjB,+BNwYkB,CMvYlB,2BN2Yc,CM1Yd,2BN4Pc,CM3Pd,iCNoUoB,CMnUpB,iCNitBoB,CMhtBpB,kCN+sBqB,CM9sBrB,gCNgtBmB,CM/sBnB,6BNyegB,CMxehB,8BNwBiB,CMvBjB,0BNymBa,CMxmBb,2BNymBc,CMxmBd,2BNyDc,CMxDd,+BNyDkB,CMxDlB,4BN+de,CM9df,6BN2EgB,CM1EhB,2BN0Pc,CMzPd,2BNiDc,CMhDd,6BN0VgB,CMzVhB,kCNwmBqB,CMvmBrB,iCNwmBoB,CMvmBpB,iCNpCoB,CMqCpB,mCNvCsB,CMwCtB,kCNrCqB,CMsCrB,oCNxCuB,CMyCvB,2BN+Wc,CM9Wd,qCACoC,WN2anB,CM1ajB,6BNsUgB,CMrUhB,mCNkrBsB,CMjrBtB,uDAEsC,WN0bnB,CMzbnB,6BNkbgB,CMjbhB,iCNwXoB,CMvXpB,6BNtDgB,CMuDhB,2BNmnBc,CMlnBd,2CAC4C,WN+anB,CM9azB,qCN8fwB,CM7fxB,qCN+EwB,CM9ExB,6BNzBgB,CM0BhB,oCNmjBuB,CMljBvB,oCNqLuB,CMpLvB,+BNlBkB,CMmBlB,2BNsbc,CMrbd,4BNgae,CM/Zf,2BNmjBc,CMljBd,8BN+NiB,CM9NjB,mCNgLsB,CM/KtB,mCN4iBsB,CM3iBtB,4BN+Ie,CM9If,mCNyEsB,CMxEtB,oCNyEuB,CMxEvB,kCNkbqB,CMjbrB,mCNuXsB,CMtXtB,mCN2lBsB,CM1lBtB,mCN2DsB,CM1DtB,sCNybyB,CMxbzB,kCN0SqB,CMzSrB,iCN0GoB,CMzGpB,qCNulBwB,CMtlBxB,qCNuDwB,CMtDxB,0BNnCa,CMoCb,iCNnDoB,CMoDpB,kCNnDqB,CMoDrB,+BNnDkB,CMoDlB,iCNvDoB,CMwDpB,yCACkC,WN4dnB,CM3df,6BN8IgB,CM7IhB,+BNsFkB,CMrFlB,2BN+Zc,CM9Zd,4BNoWe,CMnWf,+BNpDkB,CMqDlB,yCNuI4B,CMtI5B,2BNkNc,CMjNd,2BN0Sc,CMzSd,2BN6Kc,CM5Kd,0BNyIa,CMxIb,gCNyImB,CMxInB,mDACiD,WNiInB,CMhI9B,4BN+Ye,CM9Yf,gCACA,6BNoagB,CMnahB,8BNgEiB,CM/DjB,6BN6TgB,CM5ThB,iCNuCoB,CMtCpB,mCNmCsB,CMlCtB,8BN+aiB,CM9ajB,oCNkduB,CMjdvB,6BN0KgB,CMzKhB,kCN2KqB,CM1KrB,+BN3EkB,CM4ElB,+BN7EkB,CM8ElB,4CACsC,WNlEnB,CMmEnB,qCN+kBwB,CM9kBxB,sCN4HyB,CM3HzB,mCNTsB,CMUtB,0BN2Qa,CM1Qb,iCACiC,WN6CnB,CM5Cd,+BNkDkB,CMjDlB,kCNsiBqB,CMriBrB,oCNoiBuB,CMniBvB,gCN2emB,CM1enB,8BN8NiB,CM7NjB,+BNockB,CMnclB,sCNuRyB,CMtRzB,iCN6hBoB,CM5hBpB,oCNsGuB,CMrGvB,8BN8biB,CM7bjB,6BNqjBgB,CMpjBhB,oCNgLuB,CM/KvB,6BNukBgB,CMtkBhB,8BNqQiB,CMpQjB,4BNiWe,CMhWf,+BN2dkB,CM1dlB,iCNjDoB,CMkDpB,mCN+VsB,CM9VtB,8BNsjBiB,CMrjBjB,0CACqC,WNgGnB,CM/FlB,6BNoKgB,CMnKhB,6BN0jBgB,CMzjBhB,kCNoCqB,CMnCrB,+BACgC,WN+YnB,CM9Yb,4BNoMe,CMnMf,+BNrDkB,CMsDlB,2BNhFc,CMiFd,kCNrBqB,CMsBrB,mCNoLsB,CMnLtB,kCNkLqB,CMjLrB,gCNmLmB,CMlLnB,kCN+KqB,CM9KrB,wCNrI2B,CMsI3B,yCNjI4B,CMkI5B,sCNjIyB,CMkIzB,wCNzI2B,CM0I3B,4BN2Je,CM1Jf,6BN6lBgB,CM5lBhB,4BNqee,CMpef,6BNyGgB,CMxGhB,gCNzEmB,CM0EnB,iCNlIoB,CMmIpB,kCACkC,WNijBnB,CMhjBf,iCACiC,WN4OnB,CM3Od,4BNde,CMef,4BN0Ge,CMzGf,mCACqC,WN6XnB,CM5XlB,mCACoC,WN2FnB,CM1FjB,gCN6SmB,CM5SnB,oCACqC,WNqGnB,CMpGlB,6BNgbgB,CM/ahB,sDAEiC,WNlInB,CMmId,8BNsOiB,CMrOjB,8BNoOiB,CMnOjB,oCN+buB,CM9bvB,gCN2gBmB,CM1gBnB,4BNuce,CMtcf,4BNyOe,CMxOf,4BN6fe,CM5ff,gCNmTmB,CMlTnB,uCNoT0B,CMnT1B,yCNgI4B,CM/H5B,kCN4HqB,CM3HrB,4BNqQe,CMpQf,iCNpFoB,CMqFpB,+BN9EkB,CM+ElB,iCNrFoB,CMsFpB,kCNrFqB,CMsFrB,8BNhCiB,CMiCjB,oCACiC,WN0YnB,CMzYd,0CACsC,WN8YnB,CM7YnB,uCACqC,WN2YnB,CM1YlB,+BNUkB,CMTlB,+BNuMkB,CMtMlB,uCACiC,WNqfnB,CMpfd,kCACkC,WNoFnB,CMnFf,2CACuC,WN+anB,CM9apB,gCN7CmB,CM8CnB,iCN1CoB,CM2CpB,iCACiC,WNpInB,CMqId,8BN6WiB,CM5WjB,+BNyekB,CMxelB,sCACsC,WNrEnB,CMsEnB,kCNqLqB,CMpLrB,+BNGkB,CMFlB,qCNnEwB,CMoExB,mCNnEsB,CMoEtB,8BNifiB,CMhfjB,kCN8YqB,CM7YrB,+BNyZkB,CMxZlB,6BN9JgB,CM+JhB,6BNlEgB,CMmEhB,8BN1CiB,CM2CjB,kCN8BqB,CM7BrB,iCN1IoB,CM2IpB,iCNsHoB,CMrHpB,gCNrOmB,CMsOnB,6BN4MgB,CM3MhB,kCNUqB,CMTrB,2BN3Kc,CM4Kd,+BNuFkB,CMtFlB,kCN2QqB,CM1QrB,wCNrO2B,CMsO3B,yCNrO4B,CMsO5B,sCNrOyB,CMsOzB,wCNzO2B,CM0O3B,iCNrOoB,CMsOpB,kCNrOqB,CMsOrB,+BNrOkB,CMsOlB,iCNzOoB,CM0OpB,8BNpDiB,CMqDjB,6BN4IgB,CM3IhB,6BNwYgB,CMvYhB,0CACmC,WNuMnB,CMtMhB,+BNzGkB,CM0GlB,iCNyQoB,CMxQpB,kCNyQqB,CMxQrB,8BN+ViB,CM9VjB,6BN9GgB,CM+GhB,uCACkC,WNoRnB,CMnRf,iCN+CoB,CM9CpB,+BNmBkB,CMlBlB,oCNoBuB,CMnBvB,8BNqUiB,CMpUjB,8BN2BiB,CM1BjB,4BNgLe,CM/Kf,8BN2BiB,CM1BjB,iCNuHoB,CMtHpB,6BNMgB,CMLhB,qCNIwB,CMHxB,+BN6XkB,CM5XlB,2BNhHc,CMiHd,+CACsC,WNuQnB,CMtQnB,4EAEwC,WNsVnB,CMrVrB,qCNwIwB,CMvIxB,2BNhGc,CMiGd,gCNvHmB,CMwHnB,0CACyC,WNtJnB,CMuJtB,+BNyOkB,CMxOlB,2BN0Fc,CMzFd,kCN1DqB,CM2DrB,kCNkWqB,CMjWrB,gCN4VmB,CM3VnB,6BNlEgB,CMmEhB,mCNgOsB,CM/NtB,iCN2JoB,CM1JpB,uCN2J0B,CM1J1B,6BNsRgB,CMrRhB,iCN5LoB,CM6LpB,wCNxB2B,CMyB3B,6BNuPgB,CMtPhB,6BN6IgB,CM5IhB,0CN9J6B,CM+J7B,2CN9J8B,CM+J9B,wCN9J2B,CM+J3B,0CNlK6B,CMmK7B,4BN8De,CM7Df,2BNrHc,CMsHd,6BNvSgB,CMwShB,iCN2ZoB,CM1ZpB,+BNhNkB,CMiNlB,iCN7FoB,CM8FpB,iCN7FoB,CM8FpB,iCN+OoB,CM9OpB,kCNiMqB,CMhMrB,6BN6WgB,CM5WhB,mCN0IsB,CMzItB,qCN0IwB,CMzIxB,+BNqFkB,CMpFlB,iCNmFoB,CMlFpB,mCNnLsB,CMoLtB,oCN0KuB,CMzKvB,2CNpF8B,CMqF9B,mCNwPsB,CMvPtB,8BNjJiB,CMkJjB,sDACgD,WN/MnB,CMgN7B,kDAC8C,WN9MnB,CM+M3B,wDACiD,WNjNnB,CMkN9B,+BACgC,WNvGnB,CMwGb,0BNhCa,CMiCb,iCACgC,WNqYnB,CMpYb,gCACgC,WN4CnB,CM3Cb,4DAGgC,WNgDnB,CM/Cb,kDAEgC,WNiNnB,CMhNb,8BACgC,WN+CnB,CM9Cb,kCACgC,WN3PnB,CM4Pb,2BNhGc,CMiGd,gCNpFmB,CMqFnB,qCN0PwB,CMzPxB,sCN0PyB,CMzPzB,sCN0PyB,CMzPzB,uCN0P0B,CMzP1B,uCN6P0B,CM5P1B,wCN6P2B,CM5P3B,gCNkUmB,CMjUnB,kCN8TqB,CM7TrB,qCNyawB,CMxaxB,8BNsaiB,CMrajB,2BN2Zc,CM1Zd,kCN2ZqB,CM1ZrB,mCNoasB,CMnatB,8BNxJiB,CMyJjB,qCN8PwB,CM7PxB,gCNgBmB,CMfnB,6BNpFgB,CMqFhB,0BN3Wa,CM4Wb,gCN/RmB,CMgSnB,uCN/R0B,CMgS1B,6BN+UgB,CM9UhB,oCN+UuB,CM9UvB,sCNgDyB,CM/CzB,oCNkDuB,CMjDvB,sCN+CyB,CM9CzB,uCN+C0B,CM9C1B,4BNjWe,CMkWf,8BNmYiB,CMlYjB,8BN7WiB,CM8WjB,4BNkCe,CMjCf,+BN5KkB,CM6KlB,4BNgNe,CM/Mf,iCNxFoB,CMyFpB,6BN4TgB,CM3ThB,6BNtIgB,CMuIhB,2BN6Cc,CM5Cd,sCACqC,WN5DnB,CM6DlB,4BN8Pe,CM7Pf,6BNuEgB,CMtEhB,8BN9WiB,CM+WjB,0BNtSa,CMuSb,yBNiWY,CMhWZ,4BNuWe,CMtWf,6BN+IgB,CM9IhB,gCNkFmB,CMjFnB,qCN6NwB,CM5NxB,2CN/W8B,CMgX9B,0CNjX6B,CMkX7B,sDACgD,WNzRnB,CM0R7B,mCNnMsB,CMoMtB,iCNiWoB,CMhWpB,mCNoVsB,CMnVtB,uCACgC,WN0SnB,CMzSb,oCN0GuB,CMzGvB,oCN4MuB,CM3MvB,4BNsLe,CMrLf,sCNzLyB,CM0LzB,gCNoWmB,CMnWnB,6BN8DgB,CM7DhB,6DAEuC,WN8SnB,CM7SpB,kDAC2C,WN1FnB,CM2FxB,4BNsWe,CMrWf,6BNlGgB,CMmGhB,6BNgHgB,CM/GhB,oCNiHuB,CMhHvB,yCNyN4B,CMxN5B,kCNuNqB,CMtNrB,gCN/NmB,CMgOnB,2BN5Nc,CM6Nd,oCN2EuB,CM1EvB,qCNyEwB,CMxExB,6BNvNgB,CMwNhB,6BNzCgB,CM0ChB,+BNpCkB,CMqClB,0BNtLa,CMuLb,+BN7UkB,CM8UlB,4BN1Re,CM2Rf,0BNsDa,CMrDb,4BNmLe,CMlLf,2BNrPc,CMsPd,4BNrPe,CMsPf,8BN7WiB,CM8WjB,qCN7WwB,CM8WxB,4BN0Le,CMzLf,mCN0LsB,CMzLtB,8BNyFiB,CMxFjB,qCACgC,WNzUnB,CM0Ub,+BACiC,WN+MnB,CM9Md,2BN4Pc,CM3Pd,8BNuKiB,CMtKjB,iCNtPoB,CMuPpB,iCNiKoB,CMhKpB,+BN9PkB,CM+PlB,iCN/LoB,CMgMpB,kCNxLqB,CMyLrB,mCNrMsB,CMsMtB,wCN/L2B,CMgM3B,0EAEyC,WNxMnB,CMyMtB,gDAC2C,WN9MnB,CM+MxB,gDACyC,WN/MnB,CMgNtB,gDACyC,WNpMnB,CMqMtB,kCNjNqB,CMkNrB,2BNuRc,CMtRd,8BN5SiB,CM6SjB,+BN9EkB,CM+ElB,wGAIsC,WNnEnB,CMoEnB,qCN/TwB,CMgUxB,qDAEkC,WNqDnB,CMpDf,gCACmC,WNnQnB,CMoQhB,iCNzKoB,CM0KpB,0BN3Ka,CM4Kb,2EAEwC,WNxJnB,CMyJrB,oCN2KuB,CM1KvB,yBNiCY,CMhCZ,oCACmC,WN0QnB,CMzQhB,uCACwC,WNVnB,CMWrB,2CAC0C,WNXnB,CMYvB,8BN1IiB,CM2IjB,kCNlVqB,CMmVrB,6BNjJgB,CMkJhB,gCNbmB,CMcnB,8BN+FiB,CM9FjB,gCNuEmB,CMtEnB,uCNuE0B,CMtE1B,2BNzZc,CM0Zd,6CACqC,WN5MnB,CM6MlB,0BN0Ma,CMzMb,iCNxaoB,CMyapB,2BNIc,CMHd,iCNuFoB,CMtFpB,6BN2MgB,CM1MhB,2BN+Qc,CM9Qd,kCNzCqB,CM0CrB,2BNwPc,CMvPd,iCNrZoB,CMsZpB,6BNvBgB,CMwBhB,oCN3LuB,CM4LvB,8BN5XiB,CM6XjB,oCNhYuB,CMiYvB,kCNnYqB,CMoYrB,8BNtYiB,CMuYjB,gCNlYmB,CMmYnB,gCNlYmB,CMmYnB,iCN3boB,CM4bpB,mCN3bsB,CM4btB,4BN+Ke,CM9Kf,gCNnVmB,CMoVnB,yBN9dY,CM+dZ,iCN5RoB,CM6RpB,kCN/CqB,CMgDrB,oCN9buB,CM+bvB,iCNtfoB,CMufpB,gCN/BmB,CMgCnB,iCNzHoB,CM0HpB,6BNvIgB,CMwIhB,oCNvIuB,CMwIvB,iCN4JoB,CM3JpB,gCN4JmB,CM3JnB,8BNxciB,CMycjB,0BNjba,CMkbb,8BNvJiB,CMwJjB,gCN3gBmB,CM4gBnB,yBN7ZY,CM8ZZ,mDAEgC,WNzKnB,CM0Kb,+BNpGkB,CMqGlB,iCNxboB,CMybpB,qCN5WwB,CM6WxB,+BN9VkB,CM+VlB,+BN9PkB,CM+PlB,8BNrJiB,CMsJjB,6BNegB,CMdhB,mCN2BsB,CM1BtB,kCNoCqB,CMnCrB,+BNqCkB,CMpClB,gCN5amB,CM6anB,sCN9ayB,CM+azB,8BN/ViB,CMgWjB,2BNoBc,CMnBd,kCN8KqB,CM7KrB,iCN/FoB,CMgGpB,kCN6EqB,CM5ErB,gCN9MmB,CM+MnB,4BN+Ke,CM9Kf,2BN7Hc,CM8Hd,8BNnHiB,CMoHjB,2CACwC,WNkInB,CMjIrB,sCNkIyB,CMjIzB,mCN0KsB,CMzKtB,kCNlIqB,CMmIrB,iCNyKoB,CMxKpB,kCNnIqB,CMoIrB,oCNlIuB,CMmIvB,oCNpIuB,CMqIvB,6BN1GgB,CM2GhB,iCN7QoB,CM8QpB,wCN1U2B,CM2U3B,kCNzEqB,CM0ErB,+BNkLkB,CMjLlB,6BNXgB,CMYhB,gCNuJmB,CMtJnB,iCNwJoB,CMvJpB,gCACgC,WN/fnB,CMggBb,8BN4JiB,CM3JjB,4BN8Ge,CM7Gf,6BNwDgB,CMvDhB,6BN9IgB,CM+IhB,sCACyC,WN0LnB,CMzLtB,oCNjHuB,CMkHvB,+BNrHkB,CMsHlB,mCNnWsB,CMoWtB,gEAEyC,WN/gBnB,CMghBtB,uDACmD,WN9gBnB,CM+gBhC,6CACyC,WNlhBnB,CMmhBtB,gDAC4C,WNnhBnB,CMohBzB,8CAC0C,WNxhBnB,CMyhBvB,oCN3IuB,CM4IvB,+BN3OkB,CM4OlB,mCNxIsB,CMyItB,qCNxIwB,CMyIxB,kCNwBqB,CMvBrB,oCNwBuB,CMvBvB,6BN/dgB,CMgehB,qCNlewB,CMmexB,4BNpce,CMqcf,oCNljBuB,CMmjBvB,kCNxPqB,CMyPrB,kDAC4C,WNzPnB,CM0PzB,iDAC2C,WN7PnB,CM8PxB,gDAC0C,WNhQnB,CMiQvB,gCNrQmB,CMsQnB,8CACwC,WNxRnB,CMyRrB,+CACyC,WN7RnB,CM8RtB,sCN1RyB,CM2RzB,oCNpSuB,CMqSvB,mCN3RsB,CM4RtB,qCN/RwB,CMgSxB,mCNjSsB,CMkStB,gCN+DmB,CM9DnB,iCN/FoB,CMgGpB,uCN/b0B,CMgc1B,yBNtUY,CMuUZ,gCNtUmB,CMuUnB,kCNkEqB,CMjErB,oCNrKuB,CMsKvB,2CNrK8B,CMsK9B,iCN5UoB,CM6UpB,kCNwHqB,CMvHrB,6BNnFgB,CMoFhB,6BNzegB,CM0ehB,8BN9WiB,CM+WjB,4BNxKe,CMyKf,wCNpQ2B,CMqQ3B,oCACuC,WNSnB,CMRpB,6BNjdgB,CMkdhB,4BNzoBe,CM0oBf,6BN/nBgB,CMgoBhB,sCN3hByB,CM4hBzB,uCN9hB0B,CM+hB1B,uCN5hB0B,CM6hB1B,uCNjiB0B,CMkiB1B,+BNpRkB,CMqRlB,8BN5NiB,CM6NjB,gCN5NmB,CM6NnB,4BN/Ne,CMgOf,0BNlOa,CMmOb,iCNpeoB,CMqepB,mCNpesB,CMqetB,4BNtSe,CMuSf,4BNiFe,CMhFf,gCNlkBmB,CMmkBnB,gCNrXmB,CMsXnB,mCNpIsB,CMqItB,2BNpcc,CMqcd,sCNheyB,CMiezB,+BNpfkB,CMqflB,2BNlNc,CMmNd,mCN1XsB,CM2XtB,0BNoDa,CMnDb,mCN3JsB,CM4JtB,+BNzNkB,CM0NlB,6BNlHgB,CMmHhB,mCN7LsB,CM8LtB,qCN7LwB,CM8LxB,kCN3CqB,CM4CrB,oCN3CuB,CM4CvB,mCNrGsB,CMsGtB,sCNrGyB,CMsGzB,8BN7UiB,CM8UjB,gCNnlBmB,CMolBnB,kCNnlBqB,CMolBrB,8BN/LiB,CMgMjB,6BNlXgB,CMmXhB,iCNkFoB,CMjFpB,8BNmFiB,CMlFjB,6BN9cgB,CM+chB,uCN2B0B,CM1B1B,qCNmEwB,CMlExB,wCNxK2B,CMyK3B,4BN9lBe,CM+lBf,wCNtoB2B,CMuoB3B,2CNqD8B,CMpD9B,8BNxlBiB,CMylBjB,kDN5oBqC,CM6oBrC,2EACgE,WN9qBnB,CM+qB7C,+DAEiC,WNvfnB,CMwfd,4BNhYe,CMiYf,8BNhYiB,CMiYjB,4CAC0C,WN1HnB,CM2HvB,iCNzRoB,CM0RpB,6BNiCgB,CMhChB,oCNiCuB,CMhCvB,+BNlHkB,CMmHlB,qCNlHwB,CMmHxB,sCNlHyB,CMmHzB,iCNrNoB,CMsNpB,kCNpbqB,CMqbrB,4BNmEe,CMlEf,gCNpDmB,CMqDnB,8DACiD,WNzYnB,CM0Y9B,sCACyC,WN7anB,CM8atB,kCNtXqB,CMuXrB,oCNlfuB,CMmfvB,sCNlfyB,CMmfzB,6BNtTgB,CMuThB,mCNptBsB,CMqtBtB,qCNptBwB,CMqtBxB,yCACyC,WNrtBnB,CMstBtB,6CAC2C,WNttBnB,CMutBxB,kCNJqB,CMKrB,oCNJuB,CMKvB,6BNHgB,CMIhB,+BN3WkB,CM4WlB,8CACoC,WN5WnB,CM6WjB,kDACsC,WN7WnB,CM8WnB,4BNtNe,CMuNf,qCN3bwB,CM4bxB,+BNtFkB,CMuFlB,4EAE6C,WNxEnB,CMyE1B,+DACuD,WNvEnB,CMwEpC,qDAC6C,WN3EnB,CM4E1B,wDACgD,WN5EnB,CM6E7B,sDAC8C,WNjFnB,CMkF3B,6BN3KgB,CM4KhB,kDAEiC,WNzrBnB,CM0rBd,8BNlPiB,CMmPjB,sCNKyB,CMJzB,sCNKyB,CMJzB,qCNKwB,CMJxB,mDACyC,WNDnB,CMEtB,uDAC2C,WNFnB,CMGxB,+BNxsBkB,CMysBlB,2BNpbc,CMqbd,2BN1hBc,CM2hBd,2BNxYc,CMyYd,8BN/OiB,CMgPjB,8BNziBiB,CM0iBjB,gCNjUmB,CMkUnB,kCN7KqB,CM8KrB,kCNhIqB,CMiIrB,iCNJoB,CMKpB,6BNxUgB,COzchB,sLH8BE,kBACA,UACA,WACA,UACA,YACA,gBACA,sBACA,SAUA,mDAEE,gBACA,WACA,YACA,SACA,iBACA,UIxDF,yBACE,sBACA,oBACA,UC2NgB,CD1NhB,cC2NkB,CD1NlB,kBACA,eCPkB,CDQlB,6BCkNqB,CDhNrB,uCACE,mBACA,SCqNuB,CDlNzB,sCACE,YACA,2BACA,eCgNqB,CD/MrB,aCgNwB,CD7M1B,wCACE,uBAGF,sCACE,WACA,oBACA,aC2MwB,CDxM1B,mDACE,aCwM6B,CDrM/B,uCACE,eCuMsB,CDtMtB,gBCsMsB,CDrMtB,cCuMyB,CDpM3B,sCACE,gBACA,UCgL2B,CD/K3B,WCgL4B,CD/K5B,cCgLiC,CD7KnC,wCACE,2BACA,eCkLuB,CDjLvB,SCkLwB,CDjLxB,aCkL0B,CDjL1B,mBAGF,+CACE,mBAEA,qDACE,UAIJ,qCACE,UACA,cACA,WACA,kBAEA,yDACE,aACA,mBACA,eC0JqB,CDzJrB,iBE1EN,qEFsEI,yDAOI,iBAKF,uEACE,UACA,WAKF,4EACE,WACA,cAEA,yFACE,aAGF,0FACE,cAMR,wCACE,OACA,2BACA,mBACA,WACA,aACA,YACA,iBACA,mBACA,UAGF,uCACE,sBACA,uBACA,aCkH0B,CDhH1B,6CACE,wDCgH8B,CD5GlC,wCACE,oBCxFU,CD0FV,6EACE,kBACA,YACA,WACA,wBACA,kBAEA,0FACE,WACA,YACA,yBACA,yBACA,0BAGF,2FACE,YACA,aACA,yBACA,0BAIJ,4DACE,UACA,WAGF,2DACE,MACA,aACA,cACA,gBAGF,oEACE,eAEA,gFACE,YACA,aACA,YAGF,iFACE,YACA,cACA,cAMA,gFACE,oDAGF,iFACE,qDAMR,oCACE,8BCoBuB,CDjBzB,oCACE,uCCiBuB,CExN7B,iBAEE,aACA,eACA,aACA,MACA,QACA,SACA,OACA,mBACA,mBACA,uBACA,cFPwB,CEQxB,kBACA,+BFa0B,CEV1B,iCAEA,wEAEE,yBFKa,CEFf,qCACE,kCAGF,2BACE,uBAGF,iEAEE,uBACA,2BAGF,gEAEE,uBACA,yBAGF,8BACE,mBAGF,uEAEE,mBACA,2BAGF,sEAEE,mBACA,yBAGF,8BACE,qBAGF,uEAEE,qBACA,2BAGF,sEAEE,qBACA,yBAGF,4OAKE,gBAGF,oDACE,wBACA,OACA,mBACA,uBAGF,6CACE,wBACA,OACA,qBACA,uBAGF,mCACE,OACA,sBAEA,6IAGE,mBAGF,2TAME,uBAGF,wTAME,qBAGF,gDACE,wBACA,OACA,qBACA,uBAIJ,qCACE,2BAkBA,oXACE,YDzJJ,qEC8JE,8BACE,qBAKN,aACE,aACA,kBACA,sBACA,sBACA,uBACA,UFnKY,CEoKZ,eACA,cFpKc,CEqKd,WFpKa,CEqKb,iBFpKoB,CEqKpB,eFhLoB,CEiLpB,mBF3JW,CE4JX,cF3JgB,CE6JhB,mBACE,aAGF,2BACE,kBAIJ,cACE,aACA,sBACA,mBACA,eFnKqB,CEsKvB,aACE,kBACA,eACA,eFpJmB,CEqJnB,UACA,aFrJkB,CEsJlB,iBFrJsB,CEsJtB,gBACA,kBACA,oBACA,qBAGF,eACE,aACA,UACA,sBACA,cFrDwB,CEsDxB,kBFrD0B,CEsD1B,sBFrD8B,CEsD9B,UFrDoB,CEsDpB,oBFrDqB,CEsDrB,SFrDsB,CEyDlB,2DACE,WAGF,uDACE,yEAGF,wDACE,yEAMR,cACE,aACA,kBFpCyB,CEqCzB,sBFpC6B,CEqC7B,WFpCmB,CEqCnB,YFpCoB,CEqCpB,gBFpCoB,CEqCpB,6DFpCuB,CEqCvB,kBFpC0B,CEqC1B,kBFpC0B,CEqC1B,kBFpC2B,CEqC3B,oDFpC0B,CEuC5B,cACE,cF5DoB,CE6DpB,oBF5DqB,CE6DrB,eF5DwB,CE6DxB,eF5DyB,CE8DzB,8BACE,eAGF,4BAEE,QF9F0B,CE+F1B,mBF9FiC,CE+FjC,mBACA,wBF/FoC,CEgGpC,UF3QkB,CE4QlB,aF/F6B,CEkG/B,yBAEE,QFhGuB,CEiGvB,mBFhG8B,CEiG9B,mBACA,wBFjGiC,CEkGjC,UFrRkB,CEsRlB,aFjG0B,CEoG5B,2BAEE,QFlGyB,CEmGzB,mBFlGgC,CEmGhC,mBACA,wBFnGmC,CEoGnC,UF/RkB,CEgSlB,aFnG4B,CEsG9B,oBACE,YF9FyB,CEgGzB,yCF9F4B,CEiG9B,gCACE,SAIJ,cACE,uBACA,iBFrLoB,CEsLpB,eFrLqB,CEsLrB,0BACA,aFrLmB,CEsLnB,aFrLuB,CEwLzB,oCACE,kBACA,QACA,SACA,OACA,YF1LgC,CE2LhC,gBACA,8BFnToB,CEoTpB,6BFpToB,CEuTtB,0BACE,WACA,YFlMgC,CEmMhC,yBFlMoC,CEqMtC,aACE,eACA,kBF1RmB,CE6RrB,aACE,iBFnM4B,CEoM5B,UACA,KFpMuB,CEqMvB,OFrMuB,CEsMvB,kBF5M+B,CE6M/B,sBF5MmC,CE6MnC,WF5MyB,CE6MzB,YF5M0B,CE6M1B,UACA,gBACA,6BF3M8B,CE4M9B,WF3M0B,CE4M1B,iBF/UoB,CEiVpB,sBF3M8B,CE4M9B,UF3MyB,CE4MzB,iBF3M+B,CE4M/B,eF3M6B,CE4M7B,eFtN+B,CEuN/B,eAEA,mBACE,cF7MiC,CE8MjC,sBF5MkC,CE6MlC,aF5TU,CE+TZ,mBACE,YF9M+B,CE+M/B,+CF9MkC,CEiNpC,+BACE,SAIJ,eACE,UACA,sBF7T8B,CE8T9B,QF7TqB,CE8TrB,eF7TsB,CE8TtB,aF7ToB,CE8TpB,iBF7TwB,CE8TxB,kBF7T0B,CE8T1B,kBF7T0B,CE8T1B,iBF7TyB,CE8TzB,oBF7TwB,CEgU1B,oFAME,eFnUmB,CEsUrB,yCAGE,sBACA,UFzUkB,CE0UlB,0CFjUuB,CEkUvB,wBFxUmB,CEyUnB,qBFxU0B,CEyU1B,kBFtUuB,CEuUvB,0CFzUuB,CE0UvB,aFvUkB,CEwUlB,iBF1UsB,CE4UtB,4FACE,gCACA,sCAGF,2DACE,wBF5UuB,CE6UvB,YF5UwB,CE6UxB,yCF5U2B,CE+U7B,gFACE,WAIJ,aACE,eFpWmB,CEqWnB,eFxaoB,CE0apB,mBACE,UAGF,oBACE,UACA,aFpWgB,CEqWhB,gBACA,kBAGF,uCAEE,cFlXiB,CEmXjB,UACA,iBF/WoB,CEgXpB,mBFrXiB,CEyXrB,aACE,cF1XmB,CE2XnB,eF1XoB,CE4XpB,0BACE,eAIJ,YACE,kBF7XuB,CE8XvB,iBF/XsB,CEkYxB,gBACE,aFxXsB,CEyXtB,aFxXuB,CE2XzB,cACE,cACA,eACA,sBACA,kBF1YuB,CE2YvB,aF1YkB,CE2YlB,iBF7YsB,CEgZxB,6BAEE,mBACA,uBACA,eF9doB,CE+dpB,aFnZkB,CEqZlB,yCACE,cACA,iBFzZoB,CE4ZtB,yCACE,cACA,cAIJ,mBACE,aACA,sBFpZkC,CEqZlC,eFtZyB,CEyZ3B,0BACE,kBFtZqC,CEuZrC,sBFtZyC,CEuZzC,eFtZgC,CEuZhC,cFtZiC,CEuZjC,gBACA,kBFvZoC,CEwZpC,UFvZ+B,CEwZ/B,aFvZmC,CEwZnC,eFvZqC,CEyZrC,kCACE,YACA,qBACA,YACA,gBACA,aACA,gBAEA,kBACA,wBF5dU,CE6dV,UFvgBkB,CEwgBlB,gBACA,kBACA,kBAUJ,YACE,kBACA,uBACA,uBACA,SFvfgB,CEwfhB,UFxfgB,CEyfhB,0BFvfkB,CEyflB,gCACA,kBACA,iBFxfwB,CEyfxB,mBF3fuB,CE4fvB,eF/fgB,CEggBhB,eACA,iBAEA,gCACE,aACA,mBACA,gBFlgBmB,CEqgBrB,wBACE,oBFjgBU,CEkgBV,aFlgBU,CEogBV,sCACE,kBACA,YAOF,mDACE,cACA,kBACA,aACA,eACA,eACA,qBACA,wBFphBQ,CEshBR,gEACE,cACA,wBAGF,iEACE,UACA,yBAKJ,wCAEI,uCAEA,sDACE,yCAMR,0BACE,qBACA,aF9iBY,CEijBd,uBACE,qBACA,aFljBS,CEqjBX,2BACE,qBACA,aFtjBa,CEyjBf,0BACE,oBF/jBY,CEgkBZ,aFhkBY,CEkkBZ,+DAEE,kBACA,aACA,aACA,wBACA,kBAEA,4EACE,cACA,eACA,yBACA,+BACA,8BAOF,6EACE,cACA,aACA,yBACA,0BACA,8BAQJ,8CAEE,kBACA,UACA,YACA,aACA,uBACA,WACA,YACA,wCACA,kBAOF,6CAEE,kBACA,UACA,SACA,aACA,cACA,eACA,yBAOF,sDACE,cACA,kBACA,UACA,eACA,qBACA,wBFzoBU,CE2oBV,kEACE,YACA,aACA,eACA,wBAGF,mEACE,YACA,WACA,eACA,yBAWA,kEACE,8CAGF,mEACE,+CAGF,6EACE,2DAOV,sBACE,cFhnB+B,CEinB/B,kBFhnBiC,CEinBjC,cFhnB+B,CEinB/B,iBF/mB4B,CEgnB5B,SF/mB6B,CEgnB7B,kBFlnBgC,CEmnBhC,eFhnBiC,CEknBjC,yBACE,qBACA,kBAGF,2CACE,WACA,cACA,SFxnBwB,CEynBxB,UFxnByB,CEynBzB,iBFxnBgC,CEynBhC,kBFtnB2B,CEunB3B,UF9uBkB,CE+uBlB,eF5nByB,CE6nBzB,kBAEA,sEACE,kBF5nByB,CE8nBzB,2FACE,kBFjoByB,CEkoBzB,UFvvBc,CE0vBhB,gGACE,kBFtoByB,CE2oB/B,gDACE,WACA,cACA,WFlpB4B,CEmpB5B,YACA,cACA,kBF/oB2B,CEopB/B,eACE,wCAGF,YACE,wBFjwBqB,CEowBvB,YACE,kCFpwBqB,CEuwBvB,mBACE,gBAIF,yBACE,kBACA,YACA,WACA,YACA,gBAKA,wBACE,WACA,MF5pBqB,CE+pBvB,qCACE,QACA,UC5yBJ,iCAEI,mBACE,sBAGF,oBACE,cAMN,qEAGI,mBACE,sBAGF,oBACE,cCrBN,4BACE,GACE,6CAGF,IACE,uCAGF,IACE,6CAGF,KACE,uCAIJ,4BACE,KACE,wBACA,WAIJ,gDACE,GACE,YACA,aACA,QAGF,IACE,WACA,YACA,QAGF,IACE,WACA,aACA,cAGF,IACE,aACA,WACA,WAGF,KACE,YACA,aACA,aAIJ,iDACE,GACE,YACA,cACA,QAGF,IACE,WACA,cACA,QAGF,IACE,YACA,QACA,cAGF,KACE,YACA,cACA,eC7EJ,sBACE,GACE,qBAGF,IACE,sBAGF,IACE,sBAGF,KACE,oBAKJ,sBACE,GACE,mBACA,UAGF,KACE,qBACA,WAKJ,0CACE,GACE,aACA,aACA,QAGF,IACE,aACA,YACA,QAGF,IACE,aACA,cACA,cAGF,IACE,QACA,cACA,eAGF,KACE,aACA,aACA,gBAIJ,2CACE,GACE,YACA,cACA,QAGF,IACE,YACA,cACA,QAGF,IACE,aACA,QACA,eAGF,KACE,YACA,WACA,gBAIJ,8CACE,GACE,yBAGF,GACE,yBAGF,IACE,0BAGF,KACE,2BAKJ,sCACE,GACE,mBACA,qBACA,UAGF,IACE,mBACA,qBACA,UAGF,IACE,oBACA,sBAGF,KACE,aACA,mBACA,WAIJ,oCACE,GACE,0BACA,UAGF,KACE,wBACA,WAIJ,gCACE,GACE,uBAGF,KACE,0BJzIF,iEKbI,gBAIJ,uBACE,uBAIA,wCACE,SACA,WACA,YACA,UACA,mCACA,wCAEA,qDACE,mCAGF,kDACE,MACA,SACA,2BAGF,+GAEE,MACA,OAGF,8GAEE,MACA,QAGF,qDACE,QACA,SACA,gCAGF,qHAEE,QACA,OACA,2BAGF,oHAEE,QACA,QACA,2BAGF,qDACE,SACA,SACA,2BAGF,qHAEE,SACA,OAGF,oHAEE,QACA,SAKN,aLlEA,iEKqEM,6BAEA,oFACE,aAGF,kFACE,4BC5FN,wCACE,6BAEA,kDACE,MACA,WACA,YACA,SACA,2BAGF,8GAEE,MACA,QACA,YACA,UAGF,+GAEE,MACA,WACA,YACA,OAGF,qHAEE,QACA,WACA,YACA,OACA,2BAGF,qDACE,QACA,WACA,YACA,SACA,gCAGF,oHAEE,QACA,QACA,YACA,UACA,2BAGF,qHAEE,SACA,WACA,SACA,OAGF,qDACE,SACA,WACA,SACA,SACA,2BAGF,oHAEE,SACA,QACA,SACA,UC5ER,KACI,eAGJ,KACI,iBAGI,mCADJ,qBAEQ,wBlG2FI,EkGzFR,oCAJJ,qBAKQ,qBlGJJ,EAgVA,sCkGzUI,yBACA,WlGwUJ,qCkGzUI,yBACA,WlGwUJ,sBkGnUA,sBACA,WlGkUA,qBkGnUA,yBACA,cAIA,iDACI,gBACA,UAKZ,WACI,cACA,0BACA,UACA,YAGJ,+BACI,oBACA,qBlG8SI,iEkG5SA,gClG4SA,+DkG5SA,gCAIA,oSACI,SlGuSJ,4akGrSQ,WlGqSR,oakGrSQ,WAMhB,iCACI,gBAGJ,SACI,cACA,YACA,cACA,YlGuRI,sCkGnRI,gDlGmRJ,qCkGnRI,gDAKZ,cACI,gBAGJ,QACI,gBACA,sBlGwQI,yBkGtQA,6BlGsQA,wBkGtQA,6BlGsQA,uDkGhQA,oClGgQA,qDkGhQA,6BAIR,gBACI,eAGJ,iBACI,gBAGJ,aACI,uBlGmPI,oGkG7OA,WlG6OA,+FkG7OA,WAGJ,6CACI,clGyOA,0KkGpOI,WlGoOJ,qKkGpOI,WlGoOJ,mBkG7NA,clG6NA,kBkG7NA,clG6NA,6BkGxNI,sBACA,gBlGuNJ,4BkGxNI,sBACA,gBlGuNJ,sBkGhNA,clGgNA,qBkGhNA,cAIR,qBACI,aAGJ,SACI,iBlGpHW,CkGuHf,aACI,6BAGJ,sBACI,gBlG+LI,qUkG1LA,2ClG0LA,8TkG1LA,6ClG0LA,6BkGlLA,yBlGkLA,4BkGlLA,yBlGkLA,2BkG5KA,oClG4KA,0BkG5KA,oClG4KA,6BkGtKA,oCACA,sBlGqKA,4BkGtKA,oCACA,yBlGqKA,6BkG/JA,oCACA,sBlG8JA,4BkG/JA,oCACA,yBlG8JA,uDkGxJA,oCACA,sBlGuJA,qDkGxJA,oCACA,yBlGuJA,0BkGjJA,oCACA,sBlGgJA,yBkGjJA,oCACA,yBlGgJA,iCkG1IA,gClG0IA,gCkG1IA,gClG0IA,iCkGpIA,gClGoIA,gCkGpIA,gClGoIA,gCkG9HA,gClG8HA,+BkG9HA,gClG8HA,8BkGxHA,gClGwHA,6BkGxHA,gClGwHA,+BkGlHA,yBlGkHA,8BkGlHA,yBlGkHA,wIkG7GI,yBlG6GJ,oIkG7GI,yBlG6GJ,+BkGtGA,yBlGsGA,8BkGtGA,yBlGsGA,wIkGjGI,yBlGiGJ,oIkGjGI,yBlGiGJ,kDkGzFI,yBlGyFJ,iDkGzFI,yBlGyFJ,oNkGpFQ,yBlGoFR,gNkGpFQ,yBlGoFR,+KkG5EA,yBlG4EA,0KkG5EA,yBlG4EA,8DmGtVA,yBACA,qBACA,WnGoVA,4DmGtVA,yBACA,qBACA,cnGoVA,kNmG/UI,yBACA,qBACA,WnG6UJ,8MmG/UI,yBACA,qBACA,cAIR,8CACI,YnGwUA,sCmGlUA,yBACA,qBACA,cnGgUA,qCmGlUA,yBACA,qBACA,cnGgUA,wGmG3TI,yBACA,qBACA,WnGyTJ,sGmG3TI,yBACA,qBACA,cnGyTJ,+DmGlTA,yBACA,qBACA,cnGgTA,6DmGlTA,6BACA,qBACA,WnGgTA,oNmG3SI,yBACA,qBACA,cnGySJ,gNmG3SI,6BACA,qBACA,cAIR,+CACI,YnGoSA,sJmG9RI,2CnG8RJ,kJmG9RI,4CnG8RJ,wCmGvRA,yBACA,qBACA,cnGqRA,uCmGvRA,6BACA,qBACA,WnGqRA,4GmGhRI,yBACA,qBACA,WnG8QJ,0GmGhRI,6BACA,qBACA,cnG8QJ,kHmGtQI,yBACA,qBACA,cnGoQJ,gHmGtQI,6BACA,qBACA,WnGoQJ,oDmG9PI,yBACA,qBACA,WnG4PJ,mDmG9PI,6BACA,qBACA,cnG4PJ,0DmGrPA,yBACA,qBACA,WnGmPA,wDmGrPA,yBACA,qBACA,cnGmPA,0MmG9OI,yBACA,qBACA,WnG4OJ,sMmG9OI,yBACA,qBACA,cnG4OJ,qCmGrOA,yBACA,qBACA,cnGmOA,oCmGrOA,yBACA,qBACA,cnGmOA,sGmG9NI,yBACA,qBACA,WnG4NJ,oGmG9NI,yBACA,qBACA,cAMR,gCAEI,uCACA,mBACA,mBACA,kBnGiNA,8DmG5MI,WnG4MJ,oEmGtMI,cAKZ,YACI,kBAEA,wBACI,mBACA,SACA,aACA,uBACA,OACA,kBACA,QACA,MAIA,8EACI,aAGJ,gEACI,kBnG6KJ,gCmGtKA,yBACA,WnGqKA,+BmGtKA,yBACA,cnGqKA,sCmGhKI,yBACA,WnG+JJ,qCmGhKI,yBACA,cnG+JJ,kCmGxJA,yBACA,cnGuJA,iCmGxJA,yBACA,cnGuJA,6BmGjJA,sBACA,WnGgJA,4BmGjJA,yBACA,cnGgJA,+BmG1IA,yBACA,WnGyIA,8BmG1IA,yBACA,cnGyIA,gCmGnIA,yBACA,WnGkIA,+BmGnIA,yBACA,cnGkIA,gCmG5HA,yBACA,WnG2HA,+BmG5HA,yBACA,cC7NR,SACI,iCACA,iClGm0BgC,CkGl0BhC,kBlG29BgC,CkG19BhC,uBpGoVI,0BoGlVA,yBACA,yBACA,cpGgVA,yBoGlVA,yBACA,yBACA,WAGJ,0BACI,aAGJ,4BACI,iBACA,yBpGuUA,0CoGlUI,0BpGkUJ,yCoGlUI,0BpGkUJ,2DoG9TQ,cpG8TR,0DoG9TQ,cpG8TR,uCoGvTI,0BpGuTJ,sCoGvTI,0BpGuTJ,wDoGlTQ,cpGkTR,uDoGlTQ,cpGkTR,yCoG3SI,0BpG2SJ,wCoG3SI,0BpG2SJ,0DoGtSQ,cpGsSR,yDoGtSQ,cpGsSR,0CoG/RI,0BpG+RJ,yCoG/RI,0BpG+RJ,2DoG1RQ,cpG0RR,0DoG1RQ,cpG0RR,0CoGnRI,0BpGmRJ,yCoGnRI,0BpGmRJ,2DoG9QQ,cpG8QR,0DoG9QQ,cAKZ,qCACI,kBpGwQA,uBqGtVA,sBACA,qBACA,WrGoVA,sBqGtVA,yBACA,qBACA,crGoVA,0DqG9UQ,crG8UR,yDqG9UQ,cAMhB,2BACI,iBACA,yBAEA,uCACI,mBACA,oBrGkUA,8BqG3TA,iCACA,WrG0TA,6BqG3TA,yBACA,WrG0TA,kDqGpTQ,crGoTR,iDqGpTQ,cAMhB,kBACI,iBrGdW,CqGkBf,uBACI,kBAEA,0BACI,qBAGJ,8BACI,QAGJ,8BACI,kBAEA,qCACI,WACA,YAKJ,iCACI,kBAMR,mBACI,iBrG/CO,CA2TP,sDqGrQI,sBACA,WrGoQJ,qDqGrQI,yBACA,crGoQJ,4EqGhQQ,gBrGgQR,2EqGhQQ,gBCxFhB,aACI,atGuVI,+BsGlVA,ctGkVA,8BsGlVA,cAKJ,iDACI,gBAIR,iDACI,iCACA,CAGJ,kDACI,gBtGkUI,oFsGhUA,WtGgUA,kFsGhUA,WtGgUA,4EsG1TA,WtG0TA,0EsG1TA,WAKJ,oCACI,gBAEA,0CACI,cACA,mBtGgTJ,2DsG9SQ,ctG8SR,0DsG9SQ,cAIR,yCACI,cACA,mBAmBR,wCACI,YtGoRA,+BsG9QA,yBACA,qBACA,ctG4QA,8BsG9QA,6BACA,qBACA,WtG4QA,iFsGvQI,yBACA,ctGsQJ,+EsGvQI,yBACA,cAKZ,uCACI,eAGJ,kCACI,mBAEA,6CACI,UtGyPA,8DsGvPI,yBACA,qBACA,2CACA,ctGoPJ,6DsGvPI,6BACA,qBACA,4CACA,WAGJ,wDACI,YtGgPJ,yEsG9OQ,+BtG8OR,wEsG9OQ,+BtG8OR,8DsGvOI,qBtGuOJ,6DsGvOI,qBtGuOJ,gEsGhOA,sBACA,WtG+NA,8DsGhOA,yBACA,WtG+NA,gCsGzNA,WtGyNA,+BsGzNA,WtGyNA,4CsGpNI,yBtGoNJ,2CsGpNI,yBtGoNJ,sCsG/MI,iCtG+MJ,qCsG/MI,uCAGR,sBACI,2CAKJ,sBACI,etGqMA,gCsGlMA,kCtGkMA,+BsGlMA,yBAKJ,8CAEI,YtG2LA,kCsGxLA,sBACA,8BACA,WtGsLA,iCsGxLA,yBACA,qBACA,cAEJ,qCACI,uBACA,mBACA,aACA,+CACI,sBACA,OAEJ,+CACI,gBACA,kBACA,aACA,mBACA,uBACA,mDACI,mBAGR,8CACI,WACA,aACA,mBACA,uBAKZ,wBACI,4BACA,iCtGuJI,yCsGrJA,qBACA,8BACA,WtGmJA,wCsGrJA,qBACA,8BACA,ctGmJA,sKsG5IA,iBtG4IA,mKsG5IA,iBC5MR,QACI,eACA,gBvGsVI,yBuGpVA,yBvGoVA,wBuGpVA,yBvGoVA,4CuG/UI,yBvG+UJ,2CuG/UI,yBAIR,uBACI,gBACA,gBAEA,2CACI,gBvGsUJ,4DuGpUQ,WvGoUR,2DuGpUQ,WAGJ,iGACI,cACA,gBACA,uBACA,mBvG6TR,uduG1TgB,yBvG0ThB,iduG1TgB,yBvG0ThB,6CuGjTQ,gBvGiTR,4CuGjTQ,gBvGiTR,oDuG5SQ,gBvG4SR,mDuG5SQ,gBAMhB,cACI,oBACA,iBvGoSI,4CuG/RA,gBACA,qBvG8RA,2CuG/RA,mBACA,qBAIR,SACI,aACA,iBvGwRI,0BuGtRA,yBACA,gCACA,WvGoRA,yBuGtRA,yBACA,gCACA,cAGJ,oBACI,YAGJ,mBACI,mBAGI,kCACI,yBvGwQR,mDuGtQY,WvGsQZ,kDuGtQY,cAIR,4BACI,iBACA,+BvGgQR,6CuG9PY,6BACA,cvG6PZ,4CuG9PY,6BACA,cvG6PZ,+CuGvPY,cvGuPZ,8CuGvPY,cAMhB,mBACI,cACA,wBACI,cACA,iBvG9EG,CA2TP,yCuG3OQ,WvG2OR,wCuG3OQ,WC7GhB,eACI,YACA,mBxGsVI,gCwGpVA,sBxGoVA,+BwGpVA,yBAIR,cACI,gCACA,oBACA,WtGo8BgC,CsGj8BpC,UACI,WtGi8BgC,CsG97BpC,UACI,WtG27BgC,CFtnB5B,+BwGhUA,sBACA,gCACA,WxG8TA,8BwGhUA,yBACA,gCACA,cxG8TA,6BwGxTA,sBACA,WxGuTA,4BwGxTA,yBACA,cAGJ,6CACI,mBACA,yBxGkTA,+EwGhTI,cxGgTJ,6EwGhTI,cAKR,sCACI,gBAGJ,qCACI,mBAKJ,iCACI,iBACA,kBAEJ,6CACI,gBAGJ,4CACI,mBAIR,cACI,8BACA,2BxGkRI,+BwGhRA,yBACA,6BxG+QA,8BwGhRA,yBACA,6BxG+QA,wBwGzQA,WxGyQA,uBwGzQA,cxGyQA,4BwGnQA,8BxGmQA,2BwGnQA,8BAKJ,iBAEI,iBAGJ,sBACI,cACA,mBACA,iBAEA,gCACI,gBACA,iBACA,kBACA,kBACA,WAGJ,0BACI,YACA,yBACA,WAGJ,mCACI,UxGqOJ,oDwGnOQ,exGmOR,mDwGnOQ,eAGJ,yCACI,sBACA,oBACA,eAGJ,yCACI,oBACA,oBACA,eAKZ,0BACI,mBxGiNA,2EwG3MQ,cxG2MR,yEwG3MQ,cxG2MR,wCwGrMQ,exGqMR,uCwGrMQ,eAMhB,kBACI,oBtGqF0B,CsGpF1B,WACA,wBxG4LI,mCwG1LA,gBxG0LA,kCwG1LA,mBC9JR,kBACI,YACA,qBACA,qBAGJ,cACI,YzGiVI,kCyG5UA,WzG4UA,iCyG5UA,WzG4UA,kCyGtUA,czGsUA,iCyGtUA,czGsUA,mCyGhUA,czGgUA,kCyGhUA,cAMA,iGACI,mBzGyTJ,oJyGvTQ,yBACA,qBACA,czGqTR,iJyGvTQ,6BACA,qBACA,WzGqTR,2LyGhTY,czGgTZ,wLyGhTY,cAKZ,kFACI,mBACA,yBzGySJ,qIyGvSQ,czGuSR,kIyGvSQ,cAIR,mHACI,gBzGkSJ,mKyG7RQ,WACA,gBzG4RR,gKyG7RQ,WACA,gBzG4RR,sNyGtRgB,sBzGsRhB,mNyGtRgB,yBAMhB,gHACI,aAIA,wMACI,eAKJ,wSACI,eAKJ,0TACI,iBzG8PR,gayG5PY,czG4PZ,0ZyG5PY,czG4PZ,wVyGtPY,czGsPZ,kVyGtPY,cAQhB,oCACI,WAIA,iDAII,mBACA,aACA,eACA,0FvG+JkB,CuG9JlB,iBzG1FG,CyG2FH,uBACA,kBzG+NJ,kEyGvOQ,gBzGuOR,iEyGvOQ,mBAcZ,gDACI,czGwNA,iEyGtNI,gBzGsNJ,gEyGtNI,mBAGJ,0DACI,0FvG+IkB,CuGzI1B,oBACI,aAWJ,2BACI,YAEA,yCACI,eAMR,mCACI,oBAQA,2BACI,mBACA,cAEA,kCACI,mBACA,WACA,aACA,OACA,kBACA,UACA,uBACA,WACA,WAEJ,oCACI,YACA,gBACA,gBACA,YAIR,uBACI,WACA,iBACA,uBAGJ,sBACI,iBACA,qBAEA,6BACI,YACA,mBAGA,6CACI,cAKJ,8BACI,YACA,eACA,iBAKZ,+BACI,iBACA,kBACA,mBClOZ,WACI,a1GuVI,4B0GrVA,yB1GqVA,2B0GrVA,yBAGJ,kBACI,YACA,YACA,WAIR,iBACI,a1G0UI,kC0GxUA,yB1GwUA,iC0GxUA,yBAGJ,wBACI,YACA,YACA,WAIR,iBACI,YACA,8BACA,WAIA,0BACI,gBAKJ,UACI,gDACA,gBAFJ,UACI,gDACA,gBAFJ,UACI,iDACA,gBAFJ,UACI,iDACA,gBAFJ,UACI,iDACA,gB1G+SA,2B0GzSA,iDACA,gBACA,gB1GuSA,0B0GzSA,iDACA,gBACA,gB1GuSA,2B0GjSA,iDACA,gB1GgSA,0B0GjSA,iDACA,gB1GgSA,oC0G1RA,iDACA,gBACA,gB1GwRA,mC0G1RA,iDACA,gBACA,gB1GwRA,2B0GlRA,yB1GkRA,0B0GlRA,yBAMR,qBACI,gB1G2QI,sC0GzQA,4E1GyQA,qC0GzQA,4EAIR,gDACI,aAGJ,kCACI,aACA,UACA,gBAGJ,4BACI,gBAGJ,iBACI,Y1GsPI,6D0GjPA,sB1GiPA,4D0GjPA,yB1GiPA,mE0G3OA,sB1G2OA,kE0G3OA,yB1G2OA,mD0GrOA,sB1GqOA,kD0GrOA,yB1GqOA,yD0G/NA,sB1G+NA,wD0G/NA,yB1G+NA,qC0GzNA,W1GyNA,oC0GzNA,c1GyNA,gG0GhNI,sBACA,W1G+MJ,+F0GhNI,yBACA,cAKZ,iBACI,gCAGJ,aAKI,yBlGrIA,oBkGuIA,iBACA,W1G8LI,8B0GpMA,sBACA,W1GmMA,6B0GpMA,yBACA,cAOJ,2BACI,eAGJ,yBACI,YACA,YACA,cACA,WAGJ,4BACI,cxGiHsB,CwGhHtB,oB1G+KA,6C0G7KI,gC1G6KJ,4C0G7KI,gCAIR,gCACI,cACA,eACA,cAGJ,0BACI,iB1GzJO,C0G0JP,SACA,oB1GgKA,2C0G9JI,W1G8JJ,0C0G9JI,WAIR,4BACI,cxG0FsB,CwGzFtB,oB1GwJA,6C0GtJI,W1GsJJ,4C0GtJI,cAIR,4BlGpLA,oBkGsLI,aACA,mBACA,cxG+EsB,CwG9EtB,2BACA,SACA,a1G2IA,6C0GzII,sB1GyIJ,4C0GzII,yBAGJ,mCACI,kBAKR,uCACI,eAKJ,oCACI,yB1GyHA,wB2GtVA,W3GsVA,uB2GtVA,cAGJ,UACI,sB3GkVA,2B2GhVI,W3GgVJ,0B2GhVI,c3GgVJ,yC2G1UY,c3G0UZ,wC2G1UY,W3G0UZ,+C2GtUgB,c3GsUhB,8C2GtUgB,WAMhB,qBACI,cAEA,2BACI,c3G4TR,iG2GtTQ,c3GsTR,8F2GtTQ,c3GsTR,qC2GhTQ,W3GgTR,oC2GhTQ,WAKZ,eACI,qBAGJ,6BACI,YACA,eACA,iBACA,WAEA,mCACI,gBACA,YAGJ,kKACI,cACA,mBAGJ,4CACI,ezGkOkB,CyG9N1B,6BACI,iBASJ,0BACI,eACA,kBACA,WAEA,8BAGI,gBAIR,8BACI,eACA,WAGJ,4BACI,6B3GsPA,6C2GpPI,c3GoPJ,4C2GpPI,c3GoPJ,uI2G5OY,6B3G4OZ,qI2G5OY,6BAKZ,2BACI,gBAIA,oCACI,Y3GiOR,6C2GzNA,iCACA,W3GwNA,4C2GzNA,uCACA,cC/HJ,iCACI,SAGJ,qCACI,eACA,iBAGJ,wBACI,mBACA,iCACA,oB1GkOsB,C0GjOtB,mCACA,aACA,qBAEA,8BACI,mCAGJ,+BACI,WACA,WACA,wBACA,eACA,iBACA,wBAGJ,uCACI,aAGJ,sCACI,aAIA,yCACI,oBAEA,oDACI,gBAKZ,yEACI,iC5GsSJ,2G4GpSQ,yB5GoSR,yG4GpSQ,yB5GoSR,uX4G/RY,sB5G+RZ,iX4G/RY,yBAIR,uFACI,YAIR,sCACI,iC5GqRJ,uD4GnRQ,yB5GmRR,sD4GnRQ,yB5GmRR,gM4G9QY,sB5G8QZ,6L4G9QY,yBAIR,6CACI,YAIR,mCACI,iC5GoQJ,oD4GlQQ,yB5GkQR,mD4GlQQ,yB5GkQR,uL4G7PY,sB5G6PZ,oL4G7PY,yBAIR,0CACI,YAIR,sCACI,iC5GmPJ,uD4GjPQ,yB5GiPR,sD4GjPQ,yB5GiPR,gM4G5OY,sB5G4OZ,wJ;A6GxVR,KACI,yBACA,UACA,SACA,uB","file":"connectors/captcha.656f1dffa218e8467958.css","sourcesContent":["@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: italic;\n\tfont-weight: 300;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-italic-300.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: italic;\n\tfont-weight: 400;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-italic-400.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: italic;\n\tfont-weight: 600;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-italic-600.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: italic;\n\tfont-weight: 700;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-italic-700.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: italic;\n\tfont-weight: 800;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-italic-800.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: normal;\n\tfont-weight: 300;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-normal-300.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: normal;\n\tfont-weight: 400;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-normal-400.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: normal;\n\tfont-weight: 600;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-normal-600.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: normal;\n\tfont-weight: 700;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-normal-700.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n@font-face {\n\tfont-family: 'Open Sans';\n\tfont-style: normal;\n\tfont-weight: 800;\n\tfont-display: auto;\n\tsrc: url(webfonts/Open_Sans-normal-800.woff) format('woff');\n\tunicode-range: U+0-10FFFF;\n}\n\n","@import \"../../jslib/angular/src/scss/webfonts.css\";\n@import \"./variables\";\n\n//@import \"~bootstrap/scss/bootstrap\";\n@import \"~bootstrap/scss/_functions\";\n@import \"~bootstrap/scss/_variables\";\n@import \"~bootstrap/scss/_mixins\";\n@import \"~bootstrap/scss/_root\";\n@import \"~bootstrap/scss/_reboot\";\n@import \"~bootstrap/scss/_type\";\n@import \"~bootstrap/scss/_images\";\n@import \"~bootstrap/scss/_code\";\n@import \"~bootstrap/scss/_grid\";\n@import \"~bootstrap/scss/_tables\";\n@import \"~bootstrap/scss/_forms\";\n@import \"~bootstrap/scss/_buttons\";\n@import \"~bootstrap/scss/_transitions\";\n@import \"~bootstrap/scss/_dropdown\";\n@import \"~bootstrap/scss/_button-group\";\n@import \"~bootstrap/scss/_input-group\";\n@import \"~bootstrap/scss/_custom-forms\";\n@import \"~bootstrap/scss/_nav\";\n@import \"~bootstrap/scss/_navbar\";\n@import \"~bootstrap/scss/_card\";\n@import \"~bootstrap/scss/_breadcrumb\";\n@import \"~bootstrap/scss/_pagination\";\n@import \"~bootstrap/scss/_badge\";\n@import \"~bootstrap/scss/_jumbotron\";\n@import \"~bootstrap/scss/_alert\";\n@import \"~bootstrap/scss/_progress\";\n@import \"~bootstrap/scss/_media\";\n@import \"~bootstrap/scss/_list-group\";\n@import \"~bootstrap/scss/_close\";\n//@import \"~bootstrap/scss/_toasts\";\n@import \"~bootstrap/scss/_modal\";\n@import \"~bootstrap/scss/_tooltip\";\n@import \"~bootstrap/scss/_popover\";\n@import \"~bootstrap/scss/_carousel\";\n@import \"~bootstrap/scss/_spinners\";\n@import \"~bootstrap/scss/_utilities\";\n@import \"~bootstrap/scss/_print\";\n\n@import \"~angular2-toaster/toaster\";\n@import \"~font-awesome/scss/font-awesome.scss\";\n@import \"~sweetalert2/src/sweetalert2.scss\";\n\n@import \"./base\";\n@import \"./buttons\";\n@import \"./callouts\";\n@import \"./cards\";\n@import \"./forms\";\n@import \"./navigation\";\n@import \"./modals\";\n@import \"./pages\";\n@import \"./plugins\";\n@import \"./tables\";\n@import \"./toasts\";\n",":root {\n // Custom variable values only support SassScript inside `#{}`.\n @each $color, $value in $colors {\n --#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$color}: #{$value};\n }\n\n @each $bp, $value in $grid-breakpoints {\n --breakpoint-#{$bp}: #{$value};\n }\n\n // Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --font-family-sans-serif: #{inspect($font-family-sans-serif)};\n --font-family-monospace: #{inspect($font-family-monospace)};\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline\n// on elements that programmatically receive focus but wouldn't normally show a visible\n// focus outline. In general, this would mean that the outline is only applied if the\n// interaction that led to the element receiving programmatic focus was a keyboard interaction,\n// or the browser has somehow determined that the user is primarily a keyboard user and/or\n// wants focus outlines to always be presented.\n//\n// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible\n// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `

`-`

` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `

`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover() {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n color: inherit;\n text-decoration: none;\n\n @include hover() {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,\n // making it impossible to interact with the content\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// Set the cursor for non-` \ No newline at end of file +Bitwarden WebAuthn Connector

\ No newline at end of file diff --git a/webauthn-fallback-connector.html b/webauthn-fallback-connector.html index b7d0044e..1fad4586 100644 --- a/webauthn-fallback-connector.html +++ b/webauthn-fallback-connector.html @@ -1 +1 @@ -Bitwarden WebAuthn Connector


\ No newline at end of file +Bitwarden WebAuthn Connector


\ No newline at end of file diff --git a/webauthn-mobile-connector.html b/webauthn-mobile-connector.html index 7f72bb14..4735b930 100644 --- a/webauthn-mobile-connector.html +++ b/webauthn-mobile-connector.html @@ -1 +1 @@ -Bitwarden WebAuthn Connector

\ No newline at end of file +Bitwarden WebAuthn Connector

\ No newline at end of file