aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorivarlovlie <ivar.lovlie@gmail.com>2020-07-12 19:25:48 +0200
committerivarlovlie <ivar.lovlie@gmail.com>2020-07-12 19:25:48 +0200
commit25f512633704d3a1020a77addb77c3b9217f10fa (patch)
tree19a11f675d66a8895ccba37571d809d765c4219f /src/lib
downloadstartpage-25f512633704d3a1020a77addb77c3b9217f10fa.tar.xz
startpage-25f512633704d3a1020a77addb77c3b9217f10fa.zip
init
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/bootstrap.css6
-rw-r--r--src/lib/bootstrap.js6
-rw-r--r--src/lib/liquid.js3651
-rw-r--r--src/lib/popper.js5
-rw-r--r--src/lib/pouchdb.js12245
-rw-r--r--src/lib/toaster.js146
6 files changed, 16059 insertions, 0 deletions
diff --git a/src/lib/bootstrap.css b/src/lib/bootstrap.css
new file mode 100644
index 0000000..a44ed29
--- /dev/null
+++ b/src/lib/bootstrap.css
@@ -0,0 +1,6 @@
+/*!
+ * Bootstrap v5.0.0-alpha1 (https://getbootstrap.com/)
+ * Copyright 2011-2020 The Bootstrap Authors
+ * Copyright 2011-2020 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#28a745;--bs-teal:#20c997;--bs-cyan:#17a2b8;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#28a745;--bs-info:#17a2b8;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#343a40;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}body{margin:0;font-family:var(--bs-font-sans-serif);font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{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,small{font-size:.875em}.mark,mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#024dbc}a:not([href]),a:not([href]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em;-ms-overflow-style:scrollbar}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit;white-space:normal}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.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:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{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:.875em;color:#6c757d}.container{width:100%;padding-right:1rem;padding-left:1rem;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}@media (min-width:1400px){.container{max-width:1320px}}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{width:100%;padding-right:1rem;padding-left:1rem;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(var(--bs-gutter-y) * -1);margin-right:calc(var(--bs-gutter-x)/ -2);margin-left:calc(var(--bs-gutter-x)/ -2)}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x)/ 2);padding-left:calc(var(--bs-gutter-x)/ 2);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%;min-width:0}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.333333%}.col-2{flex:0 0 auto;width:16.666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.333333%}.col-5{flex:0 0 auto;width:41.666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.333333%}.col-8{flex:0 0 auto;width:66.666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.333333%}.col-11{flex:0 0 auto;width:91.666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%;min-width:0}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.333333%}.col-sm-2{flex:0 0 auto;width:16.666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.333333%}.col-sm-5{flex:0 0 auto;width:41.666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.333333%}.col-sm-8{flex:0 0 auto;width:66.666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.333333%}.col-sm-11{flex:0 0 auto;width:91.666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%;min-width:0}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.333333%}.col-md-2{flex:0 0 auto;width:16.666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.333333%}.col-md-5{flex:0 0 auto;width:41.666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.333333%}.col-md-8{flex:0 0 auto;width:66.666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.333333%}.col-md-11{flex:0 0 auto;width:91.666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%;min-width:0}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.333333%}.col-lg-2{flex:0 0 auto;width:16.666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.333333%}.col-lg-5{flex:0 0 auto;width:41.666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.333333%}.col-lg-8{flex:0 0 auto;width:66.666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.333333%}.col-lg-11{flex:0 0 auto;width:91.666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%;min-width:0}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.333333%}.col-xl-2{flex:0 0 auto;width:16.666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.333333%}.col-xl-5{flex:0 0 auto;width:41.666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.333333%}.col-xl-8{flex:0 0 auto;width:66.666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.333333%}.col-xl-11{flex:0 0 auto;width:91.666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%;min-width:0}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.333333%}.col-xxl-2{flex:0 0 auto;width:16.666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.333333%}.col-xxl-5{flex:0 0 auto;width:41.666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.333333%}.col-xxl-8{flex:0 0 auto;width:66.666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.333333%}.col-xxl-11{flex:0 0 auto;width:91.666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.333333%}.offset-xxl-2{margin-left:16.666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.333333%}.offset-xxl-5{margin-left:41.666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.333333%}.offset-xxl-8{margin-left:66.666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.333333%}.offset-xxl-11{margin-left:91.666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-bg:transparent;--bs-table-accent-bg:transparent;--bs-table-striped-color:#212529;--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:#212529;--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:#212529;--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:#212529;vertical-align:top;border-color:#dee2e6}.table>:not(caption)>*>*{padding:.5rem;background-color:var(--bs-table-bg);background-image:linear-gradient(var(--bs-table-accent-bg),var(--bs-table-accent-bg));border-bottom-width:1px}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:last-child)>:last-child>*{border-bottom-color:currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-striped>tbody>tr:nth-of-type(odd){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg:#bbd6fe;--bs-table-striped-bg:#b3cdf3;--bs-table-striped-color:#212529;--bs-table-active-bg:#acc4e9;--bs-table-active-color:#212529;--bs-table-hover-bg:#afc9ee;--bs-table-hover-color:#212529;color:#212529;border-color:#acc4e9}.table-secondary{--bs-table-bg:#d6d8db;--bs-table-striped-bg:#cdcfd2;--bs-table-striped-color:#212529;--bs-table-active-bg:#c4c6c9;--bs-table-active-color:#212529;--bs-table-hover-bg:#c8cbce;--bs-table-hover-color:#212529;color:#212529;border-color:#c4c6c9}.table-success{--bs-table-bg:#c3e6cb;--bs-table-striped-bg:#bbdcc3;--bs-table-striped-color:#212529;--bs-table-active-bg:#b3d3bb;--bs-table-active-color:#212529;--bs-table-hover-bg:#b7d8bf;--bs-table-hover-color:#212529;color:#212529;border-color:#b3d3bb}.table-info{--bs-table-bg:#bee5eb;--bs-table-striped-bg:#b6dbe1;--bs-table-striped-color:#212529;--bs-table-active-bg:#aed2d8;--bs-table-active-color:#212529;--bs-table-hover-bg:#b2d7dc;--bs-table-hover-color:#212529;color:#212529;border-color:#aed2d8}.table-warning{--bs-table-bg:#ffeeba;--bs-table-striped-bg:#f4e4b3;--bs-table-striped-color:#212529;--bs-table-active-bg:#e9daac;--bs-table-active-color:#212529;--bs-table-hover-bg:#eedfaf;--bs-table-hover-color:#212529;color:#212529;border-color:#e9daac}.table-danger{--bs-table-bg:#f5c6cb;--bs-table-striped-bg:#eabec3;--bs-table-striped-color:#212529;--bs-table-active-bg:#e0b6bb;--bs-table-active-color:#212529;--bs-table-hover-bg:#e5babf;--bs-table-hover-color:#212529;color:#212529;border-color:#e0b6bb}.table-light{--bs-table-bg:#f8f9fa;--bs-table-striped-bg:#edeef0;--bs-table-striped-color:#212529;--bs-table-active-bg:#e3e4e5;--bs-table-active-color:#212529;--bs-table-hover-bg:#e8e9ea;--bs-table-hover-color:#212529;color:#212529;border-color:#e3e4e5}.table-dark{--bs-table-bg:#343a40;--bs-table-striped-bg:#3e444a;--bs-table-striped-color:#fff;--bs-table-active-bg:#484e53;--bs-table-active-color:#fff;--bs-table-hover-bg:#43494e;--bs-table-hover-color:#fff;color:#fff;border-color:#484e53}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#6c757d}.form-control{display:block;width:100%;min-height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;-webkit-appearance:none;-moz-appearance:none;appearance:none;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:focus{color:#495057;background-color:#fff;border-color:#8bbafe;outline:0;box-shadow:0 0 0 .2rem rgba(13,110,253,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.form-control-color{max-width:3rem;padding:.375rem}.form-control-color::-moz-color-swatch{border-radius:.25rem}.form-control-color::-webkit-color-swatch{border-radius:.25rem}.form-select{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-select:focus{border-color:#8bbafe;outline:0;box-shadow:0 0 0 .2rem rgba(13,110,253,.25)}.form-select:focus::-ms-value{color:#495057;background-color:#fff}.form-select[multiple],.form-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.form-select:disabled{color:#6c757d;background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.form-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.form-check{display:block;min-height:1.5rem;padding-left:1.75em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.75em}.form-check-input{width:1.25em;height:1.25em;margin-top:.125em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,.25);-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;transition:background-color .15s ease-in-out,background-position .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-check-input{transition:none}}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{-webkit-filter:brightness(90%);filter:brightness(90%)}.form-check-input:focus{border-color:#8bbafe;outline:0;box-shadow:0 0 0 .2rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;-webkit-filter:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2380bdff'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.form-file{--bs-form-file-height:calc(1.5em + 0.75rem + 2px);position:relative}.form-file-input{position:relative;z-index:2;width:100%;height:var(--bs-form-file-height);margin:0;opacity:0}.form-file-input:focus-within~.form-file-label{border-color:#8bbafe;box-shadow:0 0 0 .2rem rgba(13,110,253,.25)}.form-file-input:disabled~.form-file-label .form-file-text,.form-file-input[disabled]~.form-file-label .form-file-text{background-color:#e9ecef}.form-file-label{position:absolute;top:0;right:0;left:0;z-index:1;display:flex;height:var(--bs-form-file-height);border-color:#ced4da;border-radius:.25rem}.form-file-text{display:block;flex-grow:1;padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;text-overflow:ellipsis;white-space:nowrap;background-color:#fff;border-color:inherit;border-style:solid;border-width:1px;border-top-left-radius:inherit;border-bottom-left-radius:inherit}.form-file-button{display:block;flex-shrink:0;padding:.375rem .75rem;margin-left:-1px;line-height:1.5;color:#495057;background-color:#e9ecef;border-color:inherit;border-style:solid;border-width:1px;border-top-right-radius:inherit;border-bottom-right-radius:inherit}.form-file-sm{--bs-form-file-height:calc(1.5em + 0.5rem + 2px);font-size:.875rem}.form-file-sm .form-file-button,.form-file-sm .form-file-text{padding:.25rem .5rem}.form-file-lg{--bs-form-file-height:calc(1.5em + 1rem + 2px);font-size:1.25rem}.form-file-lg .form-file-button,.form-file-lg .form-file-text{padding:.5rem 1rem}.form-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(13,110,253,.25)}.form-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#bed8fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#bed8fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#0d6efd;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;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){.form-range::-ms-thumb{-ms-transition:none;transition:none}}.form-range::-ms-thumb:active{background-color:#bed8fe}.form-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.form-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.form-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-range:disabled::-ms-thumb{background-color:#adb5bd}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-file,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-file .form-file-input:focus~.form-file-label,.input-group>.form-select:focus{z-index:3}.input-group>.form-file>.form-file-input:focus{z-index:4}.input-group>.form-file:not(:last-child)>.form-file-label{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.form-file:not(:first-child)>.form-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;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-lg>.form-control{min-height:calc(1.5em + 1rem + 2px)}.input-group-lg>.form-select{height:calc(1.5em + 1rem + 2px)}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.input-group-sm>.form-control{min-height:calc(1.5em + .5rem + 2px)}.input-group-sm>.form-select{height:calc(1.5em + .5rem + 2px)}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:1.75rem}.input-group>.dropdown-toggle:nth-last-child(n+3),.input-group>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' 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(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' 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-position:right .75rem center,center right 1.75rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#28a745}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#34ce57}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.form-file-input.is-valid~.form-file-label,.was-validated .form-file-input:valid~.form-file-label{border-color:#28a745}.form-file-input.is-valid:focus~.form-file-label,.was-validated .form-file-input:valid:focus~.form-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' 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='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' 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='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 1.75rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#dc3545}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#e4606d}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.form-file-input.is-invalid~.form-file-label,.was-validated .form-file-input:invalid~.form-file-label{border-color:#dc3545}.form-file-input.is-invalid:focus~.form-file-label,.was-validated .form-file-input:invalid:focus~.form-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;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{transition:none}}.btn:hover{color:#212529}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(13,110,253,.25)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{pointer-events:none;opacity:.65}.btn-primary{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-primary:hover{color:#fff;background-color:#025ce2;border-color:#0257d5}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#025ce2;border-color:#0257d5;box-shadow:0 0 0 .2rem rgba(49,132,253,.5)}.btn-primary.active,.btn-primary:active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0257d5;border-color:#0252c9}.btn-primary.active:focus,.btn-primary:active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(49,132,253,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.active,.btn-secondary:active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary.active:focus,.btn-secondary:active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.active,.btn-success:active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success.active:focus,.btn-success:active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.active,.btn-info:active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info.active:focus,.btn-info:active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.active,.btn-warning:active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning.active:focus,.btn-warning:active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.active,.btn-danger:active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger.active:focus,.btn-danger:active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.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.active,.btn-light:active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light.active:focus,.btn-light:active:focus,.show>.btn-light.dropdown-toggle:focus{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-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.active,.btn-dark:active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark.active:focus,.btn-dark:active:focus,.show>.btn-dark.dropdown-toggle:focus{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-outline-primary{color:#0d6efd;border-color:#0d6efd}.btn-outline-primary:hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(13,110,253,.5)}.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show,.btn-outline-primary:active{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus,.btn-outline-primary:active:focus{box-shadow:0 0 0 .2rem rgba(13,110,253,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#0d6efd;background-color:transparent}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show,.btn-outline-secondary:active{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus,.btn-outline-secondary:active:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show,.btn-outline-success:active{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus,.btn-outline-success:active:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show,.btn-outline-info:active{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus,.btn-outline-info:active:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show,.btn-outline-warning:active{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus,.btn-outline-warning:active:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show,.btn-outline-danger:active{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus,.btn-outline-danger:active:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.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.active,.btn-outline-light.dropdown-toggle.show,.btn-outline-light:active{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus,.btn-outline-light:active: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-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.active,.btn-outline-dark.dropdown-toggle.show,.btn-outline-dark:active{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus,.btn-outline-dark:active: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-link{font-weight:400;color:#0d6efd;text-decoration:underline}.btn-link:hover{color:#024dbc}.btn-link.disabled,.btn-link:disabled{color:#6c757d}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{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;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;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:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-left{right:auto;left:0}.dropdown-menu-xxl-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^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{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:#212529;text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#0d6efd}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.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,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition: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:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{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:#0d6efd}.nav-fill .nav-item{flex:1 1 auto;text-align:center}.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-top:.5rem;padding-bottom:.5rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.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}.navbar-text{padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{align-items:center;width:100%}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem;transition:box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 .2rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}@media (min-width:576px){.navbar-expand-sm{flex-wrap: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:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-collapse{display:flex!important}.navbar-expand-sm .navbar-toggler{display:none}}@media (min-width:768px){.navbar-expand-md{flex-wrap: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:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-collapse{display:flex!important}.navbar-expand-md .navbar-toggler{display:none}}@media (min-width:992px){.navbar-expand-lg{flex-wrap: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:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-collapse{display:flex!important}.navbar-expand-lg .navbar-toggler{display:none}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap: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:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-collapse{display:flex!important}.navbar-expand-xl .navbar-toggler{display:none}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-collapse{display:flex!important}.navbar-expand-xxl .navbar-toggler{display:none}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-collapse{display:flex!important}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.55)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.55);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' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%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,.55)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.55)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.55);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' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%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,.55)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{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(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-body{flex:1 1 auto;padding:1rem 1rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1rem}.card-header{padding:.5rem 1rem;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(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.5rem 1rem;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(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.5rem;margin-bottom:-.5rem;margin-left:-.5rem;border-bottom:0}.card-header-pills{margin-right:-.5rem;margin-left:-.5rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-group>.card{margin-bottom:.75rem}@media (min-width:576px){.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-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{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-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.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:.5rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item{display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:#0d6efd;text-decoration:none;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#024dbc;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(13,110,253,.25)}.page-item:not(:first-child) .page-link{margin-left:-1px}.page-item.active .page-link{z-index:3;color:#fff;background-color:#0d6efd;border-color:#0d6efd}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;background-color:#fff;border-color:#dee2e6}.page-link{padding:.375rem .75rem}.page-item:first-child .page-link{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}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem}.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:.875rem}.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 .5em;font-size:.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{position:relative;padding:1rem 1rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3.5rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:1rem 1rem;color:inherit}.alert-primary{color:#073984;background-color:#cfe2ff;border-color:#bbd6fe}.alert-primary .alert-link{color:#042454}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.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:#0d6efd;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,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.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:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.5rem 1rem;text-decoration:none;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:#fff;background-color:#0d6efd;border-color:#0d6efd}.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:576px){.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:768px){.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:992px){.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:1200px){.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}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.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:#073984;background-color:#bbd6fe}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#073984;background-color:#a2c7fe}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#073984;border-color:#073984}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{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:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{font-size:calc(1.275rem + .3vw);font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}@media (min-width:1200px){.close{font-size:1.5rem}}.close:hover{color:#000;text-decoration:none}.close:focus,.close:hover{opacity:.75}.close.disabled,.close:disabled{pointer-events:none}button.close{padding:0;background-color:transparent;border:0}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.15);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:flex;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.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{max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.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:.5}.modal-header{display:flex;flex-shrink:0;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.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;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:var(--bs-font-sans-serif);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:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .tooltip-arrow,.bs-tooltip-right .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .tooltip-arrow::before,.bs-tooltip-right .tooltip-arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .tooltip-arrow,.bs-tooltip-left .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .tooltip-arrow::before,.bs-tooltip-left .tooltip-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:var(--bs-font-sans-serif);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:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.popover-arrow,.bs-popover-right>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.popover-arrow::before,.bs-popover-right>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.popover-arrow::after,.bs-popover-right>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.popover-arrow,.bs-popover-left>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.popover-arrow::before,.bs-popover-left>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.popover-arrow::after,.bs-popover-left>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem 1rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:#212529}.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%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{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-next,.carousel-control-prev{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-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' 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='%23fff' 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:2;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:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@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%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@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;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#0d6efd}.link-primary:focus,.link-primary:hover{color:#024dbc}.link-secondary{color:#6c757d}.link-secondary:focus,.link-secondary:hover{color:#494f54}.link-success{color:#28a745}.link-success:focus,.link-success:hover{color:#19692c}.link-info{color:#17a2b8}.link-info:focus,.link-info:hover{color:#0f6674}.link-warning{color:#ffc107}.link-warning:focus,.link-warning:hover{color:#ba8b00}.link-danger{color:#dc3545}.link-danger:focus,.link-danger:hover{color:#a71d2a}.link-light{color:#f8f9fa}.link-light:focus,.link-light:hover{color:#cbd3da}.link-dark{color:#343a40}.link-dark:focus,.link-dark:hover{color:#121416}.embed-responsive{position:relative;width:100%}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;left:0;width:100%;height:100%}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.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}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only,.sr-only-focusable:not(:focus){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.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}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.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}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.border{border:1px solid #dee2e6!important}.border-0{border:0!important}.border-top{border-top:1px solid #dee2e6!important}.border-top-0{border-top:0!important}.border-right{border-right:1px solid #dee2e6!important}.border-right-0{border-right:0!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-bottom-0{border-bottom:0!important}.border-left{border-left:1px solid #dee2e6!important}.border-left-0{border-left:0!important}.border-primary{border-color:#0d6efd!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!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}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!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}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.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-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}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!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}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.mr-0{margin-right:0!important}.mr-1{margin-right:.25rem!important}.mr-2{margin-right:.5rem!important}.mr-3{margin-right:1rem!important}.mr-4{margin-right:1.5rem!important}.mr-5{margin-right:3rem!important}.mr-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ml-0{margin-left:0!important}.ml-1{margin-left:.25rem!important}.ml-2{margin-left:.5rem!important}.ml-3{margin-left:1rem!important}.ml-4{margin-left:1.5rem!important}.ml-5{margin-left:3rem!important}.ml-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pr-0{padding-right:0!important}.pr-1{padding-right:.25rem!important}.pr-2{padding-right:.5rem!important}.pr-3{padding-right:1rem!important}.pr-4{padding-right:1.5rem!important}.pr-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.pl-0{padding-left:0!important}.pl-1{padding-left:.25rem!important}.pl-2{padding-left:.5rem!important}.pl-3{padding-left:1rem!important}.pl-4{padding-left:1.5rem!important}.pl-5{padding-left:3rem!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}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}.text-primary{color:#0d6efd!important}.text-secondary{color:#6c757d!important}.text-success{color:#28a745!important}.text-info{color:#17a2b8!important}.text-warning{color:#ffc107!important}.text-danger{color:#dc3545!important}.text-light{color:#f8f9fa!important}.text-dark{color:#343a40!important}.text-white{color:#fff!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-reset{color:inherit!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.bg-primary{background-color:#0d6efd!important}.bg-secondary{background-color:#6c757d!important}.bg-success{background-color:#28a745!important}.bg-info{background-color:#17a2b8!important}.bg-warning{background-color:#ffc107!important}.bg-danger{background-color:#dc3545!important}.bg-light{background-color:#f8f9fa!important}.bg-dark{background-color:#343a40!important}.bg-body{background-color:#fff!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.font-italic{font-style:italic!important}.font-normal{font-style:normal!important}.text-break{word-wrap:break-word!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:.25rem!important}.rounded-sm{border-radius:.2rem!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}.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-bottom-left-radius:.25rem!important;border-top-left-radius:.25rem!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}.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}.flex-sm-fill{flex:1 1 auto!important}.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-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}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!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}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.mr-sm-0{margin-right:0!important}.mr-sm-1{margin-right:.25rem!important}.mr-sm-2{margin-right:.5rem!important}.mr-sm-3{margin-right:1rem!important}.mr-sm-4{margin-right:1.5rem!important}.mr-sm-5{margin-right:3rem!important}.mr-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ml-sm-0{margin-left:0!important}.ml-sm-1{margin-left:.25rem!important}.ml-sm-2{margin-left:.5rem!important}.ml-sm-3{margin-left:1rem!important}.ml-sm-4{margin-left:1.5rem!important}.ml-sm-5{margin-left:3rem!important}.ml-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pr-sm-0{padding-right:0!important}.pr-sm-1{padding-right:.25rem!important}.pr-sm-2{padding-right:.5rem!important}.pr-sm-3{padding-right:1rem!important}.pr-sm-4{padding-right:1.5rem!important}.pr-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.pl-sm-0{padding-left:0!important}.pl-sm-1{padding-left:.25rem!important}.pl-sm-2{padding-left:.5rem!important}.pl-sm-3{padding-left:1rem!important}.pl-sm-4{padding-left:1.5rem!important}.pl-sm-5{padding-left:3rem!important}.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}.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}.flex-md-fill{flex:1 1 auto!important}.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-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}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!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}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.mr-md-0{margin-right:0!important}.mr-md-1{margin-right:.25rem!important}.mr-md-2{margin-right:.5rem!important}.mr-md-3{margin-right:1rem!important}.mr-md-4{margin-right:1.5rem!important}.mr-md-5{margin-right:3rem!important}.mr-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ml-md-0{margin-left:0!important}.ml-md-1{margin-left:.25rem!important}.ml-md-2{margin-left:.5rem!important}.ml-md-3{margin-left:1rem!important}.ml-md-4{margin-left:1.5rem!important}.ml-md-5{margin-left:3rem!important}.ml-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pr-md-0{padding-right:0!important}.pr-md-1{padding-right:.25rem!important}.pr-md-2{padding-right:.5rem!important}.pr-md-3{padding-right:1rem!important}.pr-md-4{padding-right:1.5rem!important}.pr-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.pl-md-0{padding-left:0!important}.pl-md-1{padding-left:.25rem!important}.pl-md-2{padding-left:.5rem!important}.pl-md-3{padding-left:1rem!important}.pl-md-4{padding-left:1.5rem!important}.pl-md-5{padding-left:3rem!important}.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}.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}.flex-lg-fill{flex:1 1 auto!important}.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-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}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!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}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.mr-lg-0{margin-right:0!important}.mr-lg-1{margin-right:.25rem!important}.mr-lg-2{margin-right:.5rem!important}.mr-lg-3{margin-right:1rem!important}.mr-lg-4{margin-right:1.5rem!important}.mr-lg-5{margin-right:3rem!important}.mr-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ml-lg-0{margin-left:0!important}.ml-lg-1{margin-left:.25rem!important}.ml-lg-2{margin-left:.5rem!important}.ml-lg-3{margin-left:1rem!important}.ml-lg-4{margin-left:1.5rem!important}.ml-lg-5{margin-left:3rem!important}.ml-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pr-lg-0{padding-right:0!important}.pr-lg-1{padding-right:.25rem!important}.pr-lg-2{padding-right:.5rem!important}.pr-lg-3{padding-right:1rem!important}.pr-lg-4{padding-right:1.5rem!important}.pr-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.pl-lg-0{padding-left:0!important}.pl-lg-1{padding-left:.25rem!important}.pl-lg-2{padding-left:.5rem!important}.pl-lg-3{padding-left:1rem!important}.pl-lg-4{padding-left:1.5rem!important}.pl-lg-5{padding-left:3rem!important}.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}.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}.flex-xl-fill{flex:1 1 auto!important}.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-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}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!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}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.mr-xl-0{margin-right:0!important}.mr-xl-1{margin-right:.25rem!important}.mr-xl-2{margin-right:.5rem!important}.mr-xl-3{margin-right:1rem!important}.mr-xl-4{margin-right:1.5rem!important}.mr-xl-5{margin-right:3rem!important}.mr-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ml-xl-0{margin-left:0!important}.ml-xl-1{margin-left:.25rem!important}.ml-xl-2{margin-left:.5rem!important}.ml-xl-3{margin-left:1rem!important}.ml-xl-4{margin-left:1.5rem!important}.ml-xl-5{margin-left:3rem!important}.ml-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pr-xl-0{padding-right:0!important}.pr-xl-1{padding-right:.25rem!important}.pr-xl-2{padding-right:.5rem!important}.pr-xl-3{padding-right:1rem!important}.pr-xl-4{padding-right:1.5rem!important}.pr-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.pl-xl-0{padding-left:0!important}.pl-xl-1{padding-left:.25rem!important}.pl-xl-2{padding-left:.5rem!important}.pl-xl-3{padding-left:1rem!important}.pl-xl-4{padding-left:1.5rem!important}.pl-xl-5{padding-left:3rem!important}.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-left{float:left!important}.float-xxl-right{float:right!important}.float-xxl-none{float:none!important}.d-xxl-none{display:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.mr-xxl-0{margin-right:0!important}.mr-xxl-1{margin-right:.25rem!important}.mr-xxl-2{margin-right:.5rem!important}.mr-xxl-3{margin-right:1rem!important}.mr-xxl-4{margin-right:1.5rem!important}.mr-xxl-5{margin-right:3rem!important}.mr-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ml-xxl-0{margin-left:0!important}.ml-xxl-1{margin-left:.25rem!important}.ml-xxl-2{margin-left:.5rem!important}.ml-xxl-3{margin-left:1rem!important}.ml-xxl-4{margin-left:1.5rem!important}.ml-xxl-5{margin-left:3rem!important}.ml-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pr-xxl-0{padding-right:0!important}.pr-xxl-1{padding-right:.25rem!important}.pr-xxl-2{padding-right:.5rem!important}.pr-xxl-3{padding-right:1rem!important}.pr-xxl-4{padding-right:1.5rem!important}.pr-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.pl-xxl-0{padding-left:0!important}.pl-xxl-1{padding-left:.25rem!important}.pl-xxl-2{padding-left:.5rem!important}.pl-xxl-3{padding-left:1rem!important}.pl-xxl-4{padding-left:1.5rem!important}.pl-xxl-5{padding-left:3rem!important}.text-xxl-left{text-align:left!important}.text-xxl-right{text-align:right!important}.text-xxl-center{text-align:center!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}}
diff --git a/src/lib/bootstrap.js b/src/lib/bootstrap.js
new file mode 100644
index 0000000..d2e2cf4
--- /dev/null
+++ b/src/lib/bootstrap.js
@@ -0,0 +1,6 @@
+/*!
+ * Bootstrap v5.0.0-alpha1 (https://getbootstrap.com/)
+ * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).bootstrap=e()}(this,(function(){"use strict";function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function e(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function i(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function o(t){for(var e=1;e<arguments.length;e++){var o=null!=arguments[e]?arguments[e]:{};e%2?i(Object(o),!0).forEach((function(e){n(t,e,o[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(o)):i(Object(o)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(o,e))}))}return t}var r,s,a,l,c=function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},u=function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():null}return e},f=function(t){var e=u(t);return e&&document.querySelector(e)?e:null},d=function(t){var e=u(t);return e?document.querySelector(e):null},h=function(t){if(!t)return 0;var e=window.getComputedStyle(t),n=e.transitionDuration,i=e.transitionDelay,o=parseFloat(n),r=parseFloat(i);return o||r?(n=n.split(",")[0],i=i.split(",")[0],1e3*(parseFloat(n)+parseFloat(i))):0},p=function(t){t.dispatchEvent(new Event("transitionend"))},g=function(t){return(t[0]||t).nodeType},m=function(t,e){var n=!1,i=e+5;t.addEventListener("transitionend",(function e(){n=!0,t.removeEventListener("transitionend",e)})),setTimeout((function(){n||p(t)}),i)},v=function(t,e,n){Object.keys(n).forEach((function(i){var o,r=n[i],s=e[i],a=s&&g(s)?"element":null==(o=s)?""+o:{}.toString.call(o).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(r).test(a))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+a+'" but expected type "'+r+'".')}))},_=function(t){if(!t)return!1;if(t.style&&t.parentNode&&t.parentNode.style){var e=getComputedStyle(t),n=getComputedStyle(t.parentNode);return"none"!==e.display&&"none"!==n.display&&"hidden"!==e.visibility}return!1},b=function(){return function(){}},y=function(t){return t.offsetHeight},w=function(){var t=window.jQuery;return t&&!document.body.hasAttribute("data-no-jquery")?t:null},E=(r={},s=1,{set:function(t,e,n){void 0===t.key&&(t.key={key:e,id:s},s++),r[t.key.id]=n},get:function(t,e){if(!t||void 0===t.key)return null;var n=t.key;return n.key===e?r[n.id]:null},delete:function(t,e){if(void 0!==t.key){var n=t.key;n.key===e&&(delete r[n.id],delete t.key)}}}),T=function(t,e,n){E.set(t,e,n)},L=function(t,e){return E.get(t,e)},k=function(t,e){E.delete(t,e)},O=Element.prototype.querySelectorAll,C=Element.prototype.querySelector,A=(a=new CustomEvent("Bootstrap",{cancelable:!0}),(l=document.createElement("div")).addEventListener("Bootstrap",(function(){return null})),a.preventDefault(),l.dispatchEvent(a),a.defaultPrevented),D=/:scope\b/;(function(){var t=document.createElement("div");try{t.querySelectorAll(":scope *")}catch(t){return!1}return!0})()||(O=function(t){if(!D.test(t))return this.querySelectorAll(t);var e=Boolean(this.id);e||(this.id=c("scope"));var n=null;try{t=t.replace(D,"#"+this.id),n=this.querySelectorAll(t)}finally{e||this.removeAttribute("id")}return n},C=function(t){if(!D.test(t))return this.querySelector(t);var e=O.call(this,t);return void 0!==e[0]?e[0]:null});var S=w(),x=/[^.]*(?=\..*)\.|.*/,N=/\..*/,I=/::\d+$/,j={},P=1,M={mouseenter:"mouseover",mouseleave:"mouseout"},H=["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"];function B(t,e){return e&&e+"::"+P++||t.uidEvent||P++}function R(t){var e=B(t);return t.uidEvent=e,j[e]=j[e]||{},j[e]}function F(t,e,n){void 0===n&&(n=null);for(var i=Object.keys(t),o=0,r=i.length;o<r;o++){var s=t[i[o]];if(s.originalHandler===e&&s.delegationSelector===n)return s}return null}function W(t,e,n){var i="string"==typeof e,o=i?n:e,r=t.replace(N,""),s=M[r];return s&&(r=s),H.indexOf(r)>-1||(r=t),[i,o,r]}function U(t,e,n,i,o){if("string"==typeof e&&t){n||(n=i,i=null);var r=W(e,n,i),s=r[0],a=r[1],l=r[2],c=R(t),u=c[l]||(c[l]={}),f=F(u,a,s?n:null);if(f)f.oneOff=f.oneOff&&o;else{var d=B(a,e.replace(x,"")),h=s?function(t,e,n){return function i(o){for(var r=t.querySelectorAll(e),s=o.target;s&&s!==this;s=s.parentNode)for(var a=r.length;a--;)if(r[a]===s)return i.oneOff&&V.off(t,o.type,n),n.apply(s,[o]);return null}}(t,n,i):function(t,e){return function n(i){return n.oneOff&&V.off(t,i.type,e),e.apply(t,[i])}}(t,n);h.delegationSelector=s?n:null,h.originalHandler=a,h.oneOff=o,h.uidEvent=d,u[d]=h,t.addEventListener(l,h,s)}}}function Q(t,e,n,i,o){var r=F(e[n],i,o);r&&(t.removeEventListener(n,r,Boolean(o)),delete e[n][r.uidEvent])}var V={on:function(t,e,n,i){U(t,e,n,i,!1)},one:function(t,e,n,i){U(t,e,n,i,!0)},off:function(t,e,n,i){if("string"==typeof e&&t){var o=W(e,n,i),r=o[0],s=o[1],a=o[2],l=a!==e,c=R(t),u="."===e.charAt(0);if(void 0===s){u&&Object.keys(c).forEach((function(n){!function(t,e,n,i){var o=e[n]||{};Object.keys(o).forEach((function(r){if(r.indexOf(i)>-1){var s=o[r];Q(t,e,n,s.originalHandler,s.delegationSelector)}}))}(t,c,n,e.slice(1))}));var f=c[a]||{};Object.keys(f).forEach((function(n){var i=n.replace(I,"");if(!l||e.indexOf(i)>-1){var o=f[n];Q(t,c,a,o.originalHandler,o.delegationSelector)}}))}else{if(!c||!c[a])return;Q(t,c,a,s,r?n:null)}}},trigger:function(t,e,n){if("string"!=typeof e||!t)return null;var i,o=e.replace(N,""),r=e!==o,s=H.indexOf(o)>-1,a=!0,l=!0,c=!1,u=null;return r&&S&&(i=S.Event(e,n),S(t).trigger(i),a=!i.isPropagationStopped(),l=!i.isImmediatePropagationStopped(),c=i.isDefaultPrevented()),s?(u=document.createEvent("HTMLEvents")).initEvent(o,a,!0):u=new CustomEvent(e,{bubbles:a,cancelable:!0}),void 0!==n&&Object.keys(n).forEach((function(t){Object.defineProperty(u,t,{get:function(){return n[t]}})})),c&&(u.preventDefault(),A||Object.defineProperty(u,"defaultPrevented",{get:function(){return!0}})),l&&t.dispatchEvent(u),u.defaultPrevented&&void 0!==i&&i.preventDefault(),u}},q="alert",Y=function(){function t(t){this._element=t,this._element&&T(t,"bs.alert",this)}var n=t.prototype;return n.close=function(t){var e=this._element;t&&(e=this._getRootElement(t));var n=this._triggerCloseEvent(e);null===n||n.defaultPrevented||this._removeElement(e)},n.dispose=function(){k(this._element,"bs.alert"),this._element=null},n._getRootElement=function(t){return d(t)||t.closest(".alert")},n._triggerCloseEvent=function(t){return V.trigger(t,"close.bs.alert")},n._removeElement=function(t){var e=this;if(t.classList.remove("show"),t.classList.contains("fade")){var n=h(t);V.one(t,"transitionend",(function(){return e._destroyElement(t)})),m(t,n)}else this._destroyElement(t)},n._destroyElement=function(t){t.parentNode&&t.parentNode.removeChild(t),V.trigger(t,"closed.bs.alert")},t.jQueryInterface=function(e){return this.each((function(){var n=L(this,"bs.alert");n||(n=new t(this)),"close"===e&&n[e](this)}))},t.handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},t.getInstance=function(t){return L(t,"bs.alert")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}}]),t}();V.on(document,"click.bs.alert.data-api",'[data-dismiss="alert"]',Y.handleDismiss(new Y));var z=w();if(z){var K=z.fn[q];z.fn[q]=Y.jQueryInterface,z.fn[q].Constructor=Y,z.fn[q].noConflict=function(){return z.fn[q]=K,Y.jQueryInterface}}var X={matches:function(t,e){return t.matches(e)},find:function(t,e){var n;return void 0===e&&(e=document.documentElement),(n=[]).concat.apply(n,O.call(e,t))},findOne:function(t,e){return void 0===e&&(e=document.documentElement),C.call(e,t)},children:function(t,e){var n,i=(n=[]).concat.apply(n,t.children);return i.filter((function(t){return t.matches(e)}))},parents:function(t,e){for(var n=[],i=t.parentNode;i&&i.nodeType===Node.ELEMENT_NODE&&3!==i.nodeType;)this.matches(i,e)&&n.push(i),i=i.parentNode;return n},prev:function(t,e){for(var n=t.previousElementSibling;n;){if(n.matches(e))return[n];n=n.previousElementSibling}return[]},next:function(t,e){for(var n=t.nextElementSibling;n;){if(this.matches(n,e))return[n];n=n.nextElementSibling}return[]}},G=function(){function t(t){this._element=t,T(t,"bs.button",this)}var n=t.prototype;return n.toggle=function(){var t=!0,e=!0,n=this._element.closest('[data-toggle="buttons"]');if(n){var i=X.findOne('input:not([type="hidden"])',this._element);if(i&&"radio"===i.type){if(i.checked&&this._element.classList.contains("active"))t=!1;else{var o=X.findOne(".active",n);o&&o.classList.remove("active")}if(t){if(i.hasAttribute("disabled")||n.hasAttribute("disabled")||i.classList.contains("disabled")||n.classList.contains("disabled"))return;i.checked=!this._element.classList.contains("active"),V.trigger(i,"change")}i.focus(),e=!1}}e&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&this._element.classList.toggle("active")},n.dispose=function(){k(this._element,"bs.button"),this._element=null},t.jQueryInterface=function(e){return this.each((function(){var n=L(this,"bs.button");n||(n=new t(this)),"toggle"===e&&n[e]()}))},t.getInstance=function(t){return L(t,"bs.button")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}}]),t}();V.on(document,"click.bs.button.data-api",'[data-toggle^="button"]',(function(t){t.preventDefault();var e=t.target.closest(".btn"),n=L(e,"bs.button");n||(n=new G(e)),n.toggle()})),V.on(document,"focus.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=t.target.closest(".btn");e&&e.classList.add("focus")})),V.on(document,"blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=t.target.closest(".btn");e&&e.classList.remove("focus")}));var $=w();if($){var Z=$.fn.button;$.fn.button=G.jQueryInterface,$.fn.button.Constructor=G,$.fn.button.noConflict=function(){return $.fn.button=Z,G.jQueryInterface}}function J(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function tt(t){return t.replace(/[A-Z]/g,(function(t){return"-"+t.toLowerCase()}))}var et={setDataAttribute:function(t,e,n){t.setAttribute("data-"+tt(e),n)},removeDataAttribute:function(t,e){t.removeAttribute("data-"+tt(e))},getDataAttributes:function(t){if(!t)return{};var e=o({},t.dataset);return Object.keys(e).forEach((function(t){e[t]=J(e[t])})),e},getDataAttribute:function(t,e){return J(t.getAttribute("data-"+tt(e)))},offset:function(t){var e=t.getBoundingClientRect();return{top:e.top+document.body.scrollTop,left:e.left+document.body.scrollLeft}},position:function(t){return{top:t.offsetTop,left:t.offsetLeft}},toggleClass:function(t,e){t&&(t.classList.contains(e)?t.classList.remove(e):t.classList.add(e))}},nt="carousel",it=".bs.carousel",ot={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},rt={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},st={TOUCH:"touch",PEN:"pen"},at=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=X.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners(),T(t,"bs.carousel",this)}var n=t.prototype;return n.next=function(){this._isSliding||this._slide("next")},n.nextWhenVisible=function(){!document.hidden&&_(this._element)&&this.next()},n.prev=function(){this._isSliding||this._slide("prev")},n.pause=function(t){t||(this._isPaused=!0),X.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(p(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},n.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},n.to=function(t){var e=this;this._activeElement=X.findOne(".active.carousel-item",this._element);var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)V.one(this._element,"slid.bs.carousel",(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var i=t>n?"next":"prev";this._slide(i,this._items[t])}},n.dispose=function(){V.off(this._element,it),k(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},n._getConfig=function(t){return t=o(o({},ot),t),v(nt,t,rt),t},n._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},n._addEventListeners=function(){var t=this;this._config.keyboard&&V.on(this._element,"keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&(V.on(this._element,"mouseenter.bs.carousel",(function(e){return t.pause(e)})),V.on(this._element,"mouseleave.bs.carousel",(function(e){return t.cycle(e)}))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()},n._addTouchEventListeners=function(){var t=this,e=function(e){t._pointerEvent&&st[e.pointerType.toUpperCase()]?t.touchStartX=e.clientX:t._pointerEvent||(t.touchStartX=e.touches[0].clientX)},n=function(e){t._pointerEvent&&st[e.pointerType.toUpperCase()]&&(t.touchDeltaX=e.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};X.find(".carousel-item img",this._element).forEach((function(t){V.on(t,"dragstart.bs.carousel",(function(t){return t.preventDefault()}))})),this._pointerEvent?(V.on(this._element,"pointerdown.bs.carousel",(function(t){return e(t)})),V.on(this._element,"pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(V.on(this._element,"touchstart.bs.carousel",(function(t){return e(t)})),V.on(this._element,"touchmove.bs.carousel",(function(e){return function(e){e.touches&&e.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.touches[0].clientX-t.touchStartX}(e)})),V.on(this._element,"touchend.bs.carousel",(function(t){return n(t)})))},n._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.key){case"ArrowLeft":t.preventDefault(),this.prev();break;case"ArrowRight":t.preventDefault(),this.next()}},n._getItemIndex=function(t){return this._items=t&&t.parentNode?X.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)},n._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),r=this._items.length-1;if((i&&0===o||n&&o===r)&&!this._config.wrap)return e;var s=(o+("prev"===t?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},n._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),i=this._getItemIndex(X.findOne(".active.carousel-item",this._element));return V.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:i,to:n})},n._setActiveIndicatorElement=function(t){if(this._indicatorsElement){for(var e=X.find(".active",this._indicatorsElement),n=0;n<e.length;n++)e[n].classList.remove("active");var i=this._indicatorsElement.children[this._getItemIndex(t)];i&&i.classList.add("active")}},n._slide=function(t,e){var n,i,o,r=this,s=X.findOne(".active.carousel-item",this._element),a=this._getItemIndex(s),l=e||s&&this._getItemByDirection(t,s),c=this._getItemIndex(l),u=Boolean(this._interval);if("next"===t?(n="carousel-item-left",i="carousel-item-next",o="left"):(n="carousel-item-right",i="carousel-item-prev",o="right"),l&&l.classList.contains("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(l,o).defaultPrevented&&s&&l){if(this._isSliding=!0,u&&this.pause(),this._setActiveIndicatorElement(l),this._element.classList.contains("slide")){l.classList.add(i),y(l),s.classList.add(n),l.classList.add(n);var f=parseInt(l.getAttribute("data-interval"),10);f?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=f):this._config.interval=this._config.defaultInterval||this._config.interval;var d=h(s);V.one(s,"transitionend",(function(){l.classList.remove(n,i),l.classList.add("active"),s.classList.remove("active",i,n),r._isSliding=!1,setTimeout((function(){V.trigger(r._element,"slid.bs.carousel",{relatedTarget:l,direction:o,from:a,to:c})}),0)})),m(s,d)}else s.classList.remove("active"),l.classList.add("active"),this._isSliding=!1,V.trigger(this._element,"slid.bs.carousel",{relatedTarget:l,direction:o,from:a,to:c});u&&this.cycle()}},t.carouselInterface=function(e,n){var i=L(e,"bs.carousel"),r=o(o({},ot),et.getDataAttributes(e));"object"==typeof n&&(r=o(o({},r),n));var s="string"==typeof n?n:r.slide;if(i||(i=new t(e,r)),"number"==typeof n)i.to(n);else if("string"==typeof s){if(void 0===i[s])throw new TypeError('No method named "'+s+'"');i[s]()}else r.interval&&r.ride&&(i.pause(),i.cycle())},t.jQueryInterface=function(e){return this.each((function(){t.carouselInterface(this,e)}))},t.dataApiClickHandler=function(e){var n=d(this);if(n&&n.classList.contains("carousel")){var i=o(o({},et.getDataAttributes(n)),et.getDataAttributes(this)),r=this.getAttribute("data-slide-to");r&&(i.interval=!1),t.carouselInterface(n,i),r&&L(n,"bs.carousel").to(r),e.preventDefault()}},t.getInstance=function(t){return L(t,"bs.carousel")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return ot}}]),t}();V.on(document,"click.bs.carousel.data-api","[data-slide], [data-slide-to]",at.dataApiClickHandler),V.on(window,"load.bs.carousel.data-api",(function(){for(var t=X.find('[data-ride="carousel"]'),e=0,n=t.length;e<n;e++)at.carouselInterface(t[e],L(t[e],"bs.carousel"))}));var lt=w();if(lt){var ct=lt.fn[nt];lt.fn[nt]=at.jQueryInterface,lt.fn[nt].Constructor=at,lt.fn[nt].noConflict=function(){return lt.fn[nt]=ct,at.jQueryInterface}}var ut="collapse",ft={toggle:!0,parent:""},dt={toggle:"boolean",parent:"(string|element)"},ht=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=X.find('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]');for(var n=X.find('[data-toggle="collapse"]'),i=0,o=n.length;i<o;i++){var r=n[i],s=f(r),a=X.find(s).filter((function(e){return e===t}));null!==s&&a.length&&(this._selector=s,this._triggerArray.push(r))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle(),T(t,"bs.collapse",this)}var n=t.prototype;return n.toggle=function(){this._element.classList.contains("show")?this.hide():this.show()},n.show=function(){var e=this;if(!this._isTransitioning&&!this._element.classList.contains("show")){var n,i;this._parent&&0===(n=X.find(".show, .collapsing",this._parent).filter((function(t){return"string"==typeof e._config.parent?t.getAttribute("data-parent")===e._config.parent:t.classList.contains("collapse")}))).length&&(n=null);var o=X.findOne(this._selector);if(n){var r=n.filter((function(t){return o!==t}));if((i=r[0]?L(r[0],"bs.collapse"):null)&&i._isTransitioning)return}if(!V.trigger(this._element,"show.bs.collapse").defaultPrevented){n&&n.forEach((function(e){o!==e&&t.collapseInterface(e,"hide"),i||T(e,"bs.collapse",null)}));var s=this._getDimension();this._element.classList.remove("collapse"),this._element.classList.add("collapsing"),this._element.style[s]=0,this._triggerArray.length&&this._triggerArray.forEach((function(t){t.classList.remove("collapsed"),t.setAttribute("aria-expanded",!0)})),this.setTransitioning(!0);var a="scroll"+(s[0].toUpperCase()+s.slice(1)),l=h(this._element);V.one(this._element,"transitionend",(function(){e._element.classList.remove("collapsing"),e._element.classList.add("collapse","show"),e._element.style[s]="",e.setTransitioning(!1),V.trigger(e._element,"shown.bs.collapse")})),m(this._element,l),this._element.style[s]=this._element[a]+"px"}}},n.hide=function(){var t=this;if(!this._isTransitioning&&this._element.classList.contains("show")&&!V.trigger(this._element,"hide.bs.collapse").defaultPrevented){var e=this._getDimension();this._element.style[e]=this._element.getBoundingClientRect()[e]+"px",y(this._element),this._element.classList.add("collapsing"),this._element.classList.remove("collapse","show");var n=this._triggerArray.length;if(n>0)for(var i=0;i<n;i++){var o=this._triggerArray[i],r=d(o);r&&!r.classList.contains("show")&&(o.classList.add("collapsed"),o.setAttribute("aria-expanded",!1))}this.setTransitioning(!0);this._element.style[e]="";var s=h(this._element);V.one(this._element,"transitionend",(function(){t.setTransitioning(!1),t._element.classList.remove("collapsing"),t._element.classList.add("collapse"),V.trigger(t._element,"hidden.bs.collapse")})),m(this._element,s)}},n.setTransitioning=function(t){this._isTransitioning=t},n.dispose=function(){k(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},n._getConfig=function(t){return(t=o(o({},ft),t)).toggle=Boolean(t.toggle),v(ut,t,dt),t},n._getDimension=function(){return this._element.classList.contains("width")?"width":"height"},n._getParent=function(){var t=this,e=this._config.parent;g(e)?void 0===e.jquery&&void 0===e[0]||(e=e[0]):e=X.findOne(e);var n='[data-toggle="collapse"][data-parent="'+e+'"]';return X.find(n,e).forEach((function(e){var n=d(e);t._addAriaAndCollapsedClass(n,[e])})),e},n._addAriaAndCollapsedClass=function(t,e){if(t){var n=t.classList.contains("show");e.length&&e.forEach((function(t){n?t.classList.remove("collapsed"):t.classList.add("collapsed"),t.setAttribute("aria-expanded",n)}))}},t.collapseInterface=function(e,n){var i=L(e,"bs.collapse"),r=o(o(o({},ft),et.getDataAttributes(e)),"object"==typeof n&&n?n:{});if(!i&&r.toggle&&"string"==typeof n&&/show|hide/.test(n)&&(r.toggle=!1),i||(i=new t(e,r)),"string"==typeof n){if(void 0===i[n])throw new TypeError('No method named "'+n+'"');i[n]()}},t.jQueryInterface=function(e){return this.each((function(){t.collapseInterface(this,e)}))},t.getInstance=function(t){return L(t,"bs.collapse")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return ft}}]),t}();V.on(document,"click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(t){"A"===t.target.tagName&&t.preventDefault();var e=et.getDataAttributes(this),n=f(this);X.find(n).forEach((function(t){var n,i=L(t,"bs.collapse");i?(null===i._parent&&"string"==typeof e.parent&&(i._config.parent=e.parent,i._parent=i._getParent()),n="toggle"):n=e,ht.collapseInterface(t,n)}))}));var pt=w();if(pt){var gt=pt.fn[ut];pt.fn[ut]=ht.jQueryInterface,pt.fn[ut].Constructor=ht,pt.fn[ut].noConflict=function(){return pt.fn[ut]=gt,ht.jQueryInterface}}var mt="undefined"!=typeof window&&"undefined"!=typeof document&&"undefined"!=typeof navigator,vt=function(){for(var t=["Edge","Trident","Firefox"],e=0;e<t.length;e+=1)if(mt&&navigator.userAgent.indexOf(t[e])>=0)return 1;return 0}();var _t=mt&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then((function(){e=!1,t()})))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout((function(){e=!1,t()}),vt))}};function bt(t){return t&&"[object Function]"==={}.toString.call(t)}function yt(t,e){if(1!==t.nodeType)return[];var n=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?n[e]:n}function wt(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function Et(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=yt(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/(auto|scroll|overlay)/.test(n+o+i)?t:Et(wt(t))}function Tt(t){return t&&t.referenceNode?t.referenceNode:t}var Lt=mt&&!(!window.MSInputMethodContext||!document.documentMode),kt=mt&&/MSIE 10/.test(navigator.userAgent);function Ot(t){return 11===t?Lt:10===t?kt:Lt||kt}function Ct(t){if(!t)return document.documentElement;for(var e=Ot(10)?document.body:null,n=t.offsetParent||null;n===e&&t.nextElementSibling;)n=(t=t.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&"BODY"!==i&&"HTML"!==i?-1!==["TH","TD","TABLE"].indexOf(n.nodeName)&&"static"===yt(n,"position")?Ct(n):n:t?t.ownerDocument.documentElement:document.documentElement}function At(t){return null!==t.parentNode?At(t.parentNode):t}function Dt(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,i=n?t:e,o=n?e:t,r=document.createRange();r.setStart(i,0),r.setEnd(o,0);var s=r.commonAncestorContainer;if(t!==s&&e!==s||i.contains(o))return function(t){var e=t.nodeName;return"BODY"!==e&&("HTML"===e||Ct(t.firstElementChild)===t)}(s)?s:Ct(s);var a=At(t);return a.host?Dt(a.host,e):Dt(t,At(e).host)}function St(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top",n="top"===e?"scrollTop":"scrollLeft",i=t.nodeName;if("BODY"===i||"HTML"===i){var o=t.ownerDocument.documentElement,r=t.ownerDocument.scrollingElement||o;return r[n]}return t[n]}function xt(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=St(e,"top"),o=St(e,"left"),r=n?-1:1;return t.top+=i*r,t.bottom+=i*r,t.left+=o*r,t.right+=o*r,t}function Nt(t,e){var n="x"===e?"Left":"Top",i="Left"===n?"Right":"Bottom";return parseFloat(t["border"+n+"Width"],10)+parseFloat(t["border"+i+"Width"],10)}function It(t,e,n,i){return Math.max(e["offset"+t],e["scroll"+t],n["client"+t],n["offset"+t],n["scroll"+t],Ot(10)?parseInt(n["offset"+t])+parseInt(i["margin"+("Height"===t?"Top":"Left")])+parseInt(i["margin"+("Height"===t?"Bottom":"Right")]):0)}function jt(t){var e=t.body,n=t.documentElement,i=Ot(10)&&getComputedStyle(n);return{height:It("Height",e,n,i),width:It("Width",e,n,i)}}var Pt=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},Mt=function(){function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}}(),Ht=function(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t},Bt=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t};function Rt(t){return Bt({},t,{right:t.left+t.width,bottom:t.top+t.height})}function Ft(t){var e={};try{if(Ot(10)){e=t.getBoundingClientRect();var n=St(t,"top"),i=St(t,"left");e.top+=n,e.left+=i,e.bottom+=n,e.right+=i}else e=t.getBoundingClientRect()}catch(t){}var o={left:e.left,top:e.top,width:e.right-e.left,height:e.bottom-e.top},r="HTML"===t.nodeName?jt(t.ownerDocument):{},s=r.width||t.clientWidth||o.width,a=r.height||t.clientHeight||o.height,l=t.offsetWidth-s,c=t.offsetHeight-a;if(l||c){var u=yt(t);l-=Nt(u,"x"),c-=Nt(u,"y"),o.width-=l,o.height-=c}return Rt(o)}function Wt(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=Ot(10),o="HTML"===e.nodeName,r=Ft(t),s=Ft(e),a=Et(t),l=yt(e),c=parseFloat(l.borderTopWidth,10),u=parseFloat(l.borderLeftWidth,10);n&&o&&(s.top=Math.max(s.top,0),s.left=Math.max(s.left,0));var f=Rt({top:r.top-s.top-c,left:r.left-s.left-u,width:r.width,height:r.height});if(f.marginTop=0,f.marginLeft=0,!i&&o){var d=parseFloat(l.marginTop,10),h=parseFloat(l.marginLeft,10);f.top-=c-d,f.bottom-=c-d,f.left-=u-h,f.right-=u-h,f.marginTop=d,f.marginLeft=h}return(i&&!n?e.contains(a):e===a&&"BODY"!==a.nodeName)&&(f=xt(f,e)),f}function Ut(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t.ownerDocument.documentElement,i=Wt(t,n),o=Math.max(n.clientWidth,window.innerWidth||0),r=Math.max(n.clientHeight,window.innerHeight||0),s=e?0:St(n),a=e?0:St(n,"left"),l={top:s-i.top+i.marginTop,left:a-i.left+i.marginLeft,width:o,height:r};return Rt(l)}function Qt(t){var e=t.nodeName;if("BODY"===e||"HTML"===e)return!1;if("fixed"===yt(t,"position"))return!0;var n=wt(t);return!!n&&Qt(n)}function Vt(t){if(!t||!t.parentElement||Ot())return document.documentElement;for(var e=t.parentElement;e&&"none"===yt(e,"transform");)e=e.parentElement;return e||document.documentElement}function qt(t,e,n,i){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4],r={top:0,left:0},s=o?Vt(t):Dt(t,Tt(e));if("viewport"===i)r=Ut(s,o);else{var a=void 0;"scrollParent"===i?"BODY"===(a=Et(wt(e))).nodeName&&(a=t.ownerDocument.documentElement):a="window"===i?t.ownerDocument.documentElement:i;var l=Wt(a,s,o);if("HTML"!==a.nodeName||Qt(s))r=l;else{var c=jt(t.ownerDocument),u=c.height,f=c.width;r.top+=l.top-l.marginTop,r.bottom=u+l.top,r.left+=l.left-l.marginLeft,r.right=f+l.left}}var d="number"==typeof(n=n||0);return r.left+=d?n:n.left||0,r.top+=d?n:n.top||0,r.right-=d?n:n.right||0,r.bottom-=d?n:n.bottom||0,r}function Yt(t){return t.width*t.height}function zt(t,e,n,i,o){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var s=qt(n,i,r,o),a={top:{width:s.width,height:e.top-s.top},right:{width:s.right-e.right,height:s.height},bottom:{width:s.width,height:s.bottom-e.bottom},left:{width:e.left-s.left,height:s.height}},l=Object.keys(a).map((function(t){return Bt({key:t},a[t],{area:Yt(a[t])})})).sort((function(t,e){return e.area-t.area})),c=l.filter((function(t){var e=t.width,i=t.height;return e>=n.clientWidth&&i>=n.clientHeight})),u=c.length>0?c[0].key:l[0].key,f=t.split("-")[1];return u+(f?"-"+f:"")}function Kt(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,o=i?Vt(e):Dt(e,Tt(n));return Wt(n,o,i)}function Xt(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),n=parseFloat(e.marginTop||0)+parseFloat(e.marginBottom||0),i=parseFloat(e.marginLeft||0)+parseFloat(e.marginRight||0);return{width:t.offsetWidth+i,height:t.offsetHeight+n}}function Gt(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,(function(t){return e[t]}))}function $t(t,e,n){n=n.split("-")[0];var i=Xt(t),o={width:i.width,height:i.height},r=-1!==["right","left"].indexOf(n),s=r?"top":"left",a=r?"left":"top",l=r?"height":"width",c=r?"width":"height";return o[s]=e[s]+e[l]/2-i[l]/2,o[a]=n===a?e[a]-i[c]:e[Gt(a)],o}function Zt(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function Jt(t,e,n){return(void 0===n?t:t.slice(0,function(t,e,n){if(Array.prototype.findIndex)return t.findIndex((function(t){return t[e]===n}));var i=Zt(t,(function(t){return t[e]===n}));return t.indexOf(i)}(t,"name",n))).forEach((function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var n=t.function||t.fn;t.enabled&&bt(n)&&(e.offsets.popper=Rt(e.offsets.popper),e.offsets.reference=Rt(e.offsets.reference),e=n(e,t))})),e}function te(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=Kt(this.state,this.popper,this.reference,this.options.positionFixed),t.placement=zt(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.positionFixed=this.options.positionFixed,t.offsets.popper=$t(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",t=Jt(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}function ee(t,e){return t.some((function(t){var n=t.name;return t.enabled&&n===e}))}function ne(t){for(var e=[!1,"ms","Webkit","Moz","O"],n=t.charAt(0).toUpperCase()+t.slice(1),i=0;i<e.length;i++){var o=e[i],r=o?""+o+n:t;if(void 0!==document.body.style[r])return r}return null}function ie(){return this.state.isDestroyed=!0,ee(this.modifiers,"applyStyle")&&(this.popper.removeAttribute("x-placement"),this.popper.style.position="",this.popper.style.top="",this.popper.style.left="",this.popper.style.right="",this.popper.style.bottom="",this.popper.style.willChange="",this.popper.style[ne("transform")]=""),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function oe(t){var e=t.ownerDocument;return e?e.defaultView:window}function re(t,e,n,i){n.updateBound=i,oe(t).addEventListener("resize",n.updateBound,{passive:!0});var o=Et(t);return function t(e,n,i,o){var r="BODY"===e.nodeName,s=r?e.ownerDocument.defaultView:e;s.addEventListener(n,i,{passive:!0}),r||t(Et(s.parentNode),n,i,o),o.push(s)}(o,"scroll",n.updateBound,n.scrollParents),n.scrollElement=o,n.eventsEnabled=!0,n}function se(){this.state.eventsEnabled||(this.state=re(this.reference,this.options,this.state,this.scheduleUpdate))}function ae(){var t,e;this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=(t=this.reference,e=this.state,oe(t).removeEventListener("resize",e.updateBound),e.scrollParents.forEach((function(t){t.removeEventListener("scroll",e.updateBound)})),e.updateBound=null,e.scrollParents=[],e.scrollElement=null,e.eventsEnabled=!1,e))}function le(t){return""!==t&&!isNaN(parseFloat(t))&&isFinite(t)}function ce(t,e){Object.keys(e).forEach((function(n){var i="";-1!==["width","height","top","right","bottom","left"].indexOf(n)&&le(e[n])&&(i="px"),t.style[n]=e[n]+i}))}var ue=mt&&/Firefox/i.test(navigator.userAgent);function fe(t,e,n){var i=Zt(t,(function(t){return t.name===e})),o=!!i&&t.some((function(t){return t.name===n&&t.enabled&&t.order<i.order}));if(!o){var r="`"+e+"`",s="`"+n+"`";console.warn(s+" modifier is required by "+r+" modifier in order to work, be sure to include it before "+r+"!")}return o}var de=["auto-start","auto","auto-end","top-start","top","top-end","right-start","right","right-end","bottom-end","bottom","bottom-start","left-end","left","left-start"],he=de.slice(3);function pe(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=he.indexOf(t),i=he.slice(n+1).concat(he.slice(0,n));return e?i.reverse():i}var ge="flip",me="clockwise",ve="counterclockwise";function _e(t,e,n,i){var o=[0,0],r=-1!==["right","left"].indexOf(i),s=t.split(/(\+|\-)/).map((function(t){return t.trim()})),a=s.indexOf(Zt(s,(function(t){return-1!==t.search(/,|\s/)})));s[a]&&-1===s[a].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var l=/\s*,\s*|\s+/,c=-1!==a?[s.slice(0,a).concat([s[a].split(l)[0]]),[s[a].split(l)[1]].concat(s.slice(a+1))]:[s];return(c=c.map((function(t,i){var o=(1===i?!r:r)?"height":"width",s=!1;return t.reduce((function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,s=!0,t):s?(t[t.length-1]+=e,s=!1,t):t.concat(e)}),[]).map((function(t){return function(t,e,n,i){var o=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+o[1],s=o[2];if(!r)return t;if(0===s.indexOf("%")){var a=void 0;switch(s){case"%p":a=n;break;case"%":case"%r":default:a=i}return Rt(a)[e]/100*r}if("vh"===s||"vw"===s){return("vh"===s?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*r}return r}(t,o,e,n)}))}))).forEach((function(t,e){t.forEach((function(n,i){le(n)&&(o[e]+=n*("-"===t[i-1]?-1:1))}))})),o}var be={placement:"bottom",positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,n=e.split("-")[0],i=e.split("-")[1];if(i){var o=t.offsets,r=o.reference,s=o.popper,a=-1!==["bottom","top"].indexOf(n),l=a?"left":"top",c=a?"width":"height",u={start:Ht({},l,r[l]),end:Ht({},l,r[l]+r[c]-s[c])};t.offsets.popper=Bt({},s,u[i])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var n=e.offset,i=t.placement,o=t.offsets,r=o.popper,s=o.reference,a=i.split("-")[0],l=void 0;return l=le(+n)?[+n,0]:_e(n,r,s,a),"left"===a?(r.top+=l[0],r.left-=l[1]):"right"===a?(r.top+=l[0],r.left+=l[1]):"top"===a?(r.left+=l[0],r.top-=l[1]):"bottom"===a&&(r.left+=l[0],r.top+=l[1]),t.popper=r,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var n=e.boundariesElement||Ct(t.instance.popper);t.instance.reference===n&&(n=Ct(n));var i=ne("transform"),o=t.instance.popper.style,r=o.top,s=o.left,a=o[i];o.top="",o.left="",o[i]="";var l=qt(t.instance.popper,t.instance.reference,e.padding,n,t.positionFixed);o.top=r,o.left=s,o[i]=a,e.boundaries=l;var c=e.priority,u=t.offsets.popper,f={primary:function(t){var n=u[t];return u[t]<l[t]&&!e.escapeWithReference&&(n=Math.max(u[t],l[t])),Ht({},t,n)},secondary:function(t){var n="right"===t?"left":"top",i=u[n];return u[t]>l[t]&&!e.escapeWithReference&&(i=Math.min(u[n],l[t]-("right"===t?u.width:u.height))),Ht({},n,i)}};return c.forEach((function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";u=Bt({},u,f[e](t))})),t.offsets.popper=u,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,o=t.placement.split("-")[0],r=Math.floor,s=-1!==["top","bottom"].indexOf(o),a=s?"right":"bottom",l=s?"left":"top",c=s?"width":"height";return n[a]<r(i[l])&&(t.offsets.popper[l]=r(i[l])-n[c]),n[l]>r(i[a])&&(t.offsets.popper[l]=r(i[a])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!fe(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],r=t.offsets,s=r.popper,a=r.reference,l=-1!==["left","right"].indexOf(o),c=l?"height":"width",u=l?"Top":"Left",f=u.toLowerCase(),d=l?"left":"top",h=l?"bottom":"right",p=Xt(i)[c];a[h]-p<s[f]&&(t.offsets.popper[f]-=s[f]-(a[h]-p)),a[f]+p>s[h]&&(t.offsets.popper[f]+=a[f]+p-s[h]),t.offsets.popper=Rt(t.offsets.popper);var g=a[f]+a[c]/2-p/2,m=yt(t.instance.popper),v=parseFloat(m["margin"+u],10),_=parseFloat(m["border"+u+"Width"],10),b=g-t.offsets.popper[f]-v-_;return b=Math.max(Math.min(s[c]-p,b),0),t.arrowElement=i,t.offsets.arrow=(Ht(n={},f,Math.round(b)),Ht(n,d,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(ee(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var n=qt(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement,t.positionFixed),i=t.placement.split("-")[0],o=Gt(i),r=t.placement.split("-")[1]||"",s=[];switch(e.behavior){case ge:s=[i,o];break;case me:s=pe(i);break;case ve:s=pe(i,!0);break;default:s=e.behavior}return s.forEach((function(a,l){if(i!==a||s.length===l+1)return t;i=t.placement.split("-")[0],o=Gt(i);var c=t.offsets.popper,u=t.offsets.reference,f=Math.floor,d="left"===i&&f(c.right)>f(u.left)||"right"===i&&f(c.left)<f(u.right)||"top"===i&&f(c.bottom)>f(u.top)||"bottom"===i&&f(c.top)<f(u.bottom),h=f(c.left)<f(n.left),p=f(c.right)>f(n.right),g=f(c.top)<f(n.top),m=f(c.bottom)>f(n.bottom),v="left"===i&&h||"right"===i&&p||"top"===i&&g||"bottom"===i&&m,_=-1!==["top","bottom"].indexOf(i),b=!!e.flipVariations&&(_&&"start"===r&&h||_&&"end"===r&&p||!_&&"start"===r&&g||!_&&"end"===r&&m),y=!!e.flipVariationsByContent&&(_&&"start"===r&&p||_&&"end"===r&&h||!_&&"start"===r&&m||!_&&"end"===r&&g),w=b||y;(d||v||w)&&(t.flipped=!0,(d||v)&&(i=s[l+1]),w&&(r=function(t){return"end"===t?"start":"start"===t?"end":t}(r)),t.placement=i+(r?"-"+r:""),t.offsets.popper=Bt({},t.offsets.popper,$t(t.instance.popper,t.offsets.reference,t.placement)),t=Jt(t.instance.modifiers,t,"flip"))})),t},behavior:"flip",padding:5,boundariesElement:"viewport",flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,o=i.popper,r=i.reference,s=-1!==["left","right"].indexOf(n),a=-1===["top","left"].indexOf(n);return o[s?"left":"top"]=r[n]-(a?o[s?"width":"height"]:0),t.placement=Gt(e),t.offsets.popper=Rt(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!fe(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=Zt(t.instance.modifiers,(function(t){return"preventOverflow"===t.name})).boundaries;if(e.bottom<n.top||e.left>n.right||e.top>n.bottom||e.right<n.left){if(!0===t.hide)return t;t.hide=!0,t.attributes["x-out-of-boundaries"]=""}else{if(!1===t.hide)return t;t.hide=!1,t.attributes["x-out-of-boundaries"]=!1}return t}},computeStyle:{order:850,enabled:!0,fn:function(t,e){var n=e.x,i=e.y,o=t.offsets.popper,r=Zt(t.instance.modifiers,(function(t){return"applyStyle"===t.name})).gpuAcceleration;void 0!==r&&console.warn("WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!");var s=void 0!==r?r:e.gpuAcceleration,a=Ct(t.instance.popper),l=Ft(a),c={position:o.position},u=function(t,e){var n=t.offsets,i=n.popper,o=n.reference,r=Math.round,s=Math.floor,a=function(t){return t},l=r(o.width),c=r(i.width),u=-1!==["left","right"].indexOf(t.placement),f=-1!==t.placement.indexOf("-"),d=e?u||f||l%2==c%2?r:s:a,h=e?r:a;return{left:d(l%2==1&&c%2==1&&!f&&e?i.left-1:i.left),top:h(i.top),bottom:h(i.bottom),right:d(i.right)}}(t,window.devicePixelRatio<2||!ue),f="bottom"===n?"top":"bottom",d="right"===i?"left":"right",h=ne("transform"),p=void 0,g=void 0;if(g="bottom"===f?"HTML"===a.nodeName?-a.clientHeight+u.bottom:-l.height+u.bottom:u.top,p="right"===d?"HTML"===a.nodeName?-a.clientWidth+u.right:-l.width+u.right:u.left,s&&h)c[h]="translate3d("+p+"px, "+g+"px, 0)",c[f]=0,c[d]=0,c.willChange="transform";else{var m="bottom"===f?-1:1,v="right"===d?-1:1;c[f]=g*m,c[d]=p*v,c.willChange=f+", "+d}var _={"x-placement":t.placement};return t.attributes=Bt({},_,t.attributes),t.styles=Bt({},c,t.styles),t.arrowStyles=Bt({},t.offsets.arrow,t.arrowStyles),t},gpuAcceleration:!0,x:"bottom",y:"right"},applyStyle:{order:900,enabled:!0,fn:function(t){return ce(t.instance.popper,t.styles),function(t,e){Object.keys(e).forEach((function(n){!1!==e[n]?t.setAttribute(n,e[n]):t.removeAttribute(n)}))}(t.instance.popper,t.attributes),t.arrowElement&&Object.keys(t.arrowStyles).length&&ce(t.arrowElement,t.arrowStyles),t},onLoad:function(t,e,n,i,o){var r=Kt(o,e,t,n.positionFixed),s=zt(n.placement,r,e,t,n.modifiers.flip.boundariesElement,n.modifiers.flip.padding);return e.setAttribute("x-placement",s),ce(e,{position:n.positionFixed?"fixed":"absolute"}),n},gpuAcceleration:void 0}}},ye=function(){function t(e,n){var i=this,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};Pt(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=_t(this.update.bind(this)),this.options=Bt({},t.Defaults,o),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(Bt({},t.Defaults.modifiers,o.modifiers)).forEach((function(e){i.options.modifiers[e]=Bt({},t.Defaults.modifiers[e]||{},o.modifiers?o.modifiers[e]:{})})),this.modifiers=Object.keys(this.options.modifiers).map((function(t){return Bt({name:t},i.options.modifiers[t])})).sort((function(t,e){return t.order-e.order})),this.modifiers.forEach((function(t){t.enabled&&bt(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)})),this.update();var r=this.options.eventsEnabled;r&&this.enableEventListeners(),this.state.eventsEnabled=r}return Mt(t,[{key:"update",value:function(){return te.call(this)}},{key:"destroy",value:function(){return ie.call(this)}},{key:"enableEventListeners",value:function(){return se.call(this)}},{key:"disableEventListeners",value:function(){return ae.call(this)}}]),t}();ye.Utils=("undefined"!=typeof window?window:global).PopperUtils,ye.placements=de,ye.Defaults=be;var we="dropdown",Ee=new RegExp("ArrowUp|ArrowDown|Escape"),Te={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},Le={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},ke=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners(),T(t,"bs.dropdown",this)}var n=t.prototype;return n.toggle=function(){if(!this._element.disabled&&!this._element.classList.contains("disabled")){var e=this._element.classList.contains("show");t.clearMenus(),e||this.show()}},n.show=function(){if(!(this._element.disabled||this._element.classList.contains("disabled")||this._menu.classList.contains("show"))){var e=t.getParentFromElement(this._element),n={relatedTarget:this._element};if(!V.trigger(this._element,"show.bs.dropdown",n).defaultPrevented){if(!this._inNavbar){if(void 0===ye)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org)");var i=this._element;"parent"===this._config.reference?i=e:g(this._config.reference)&&(i=this._config.reference,void 0!==this._config.reference.jquery&&(i=this._config.reference[0])),"scrollParent"!==this._config.boundary&&e.classList.add("position-static"),this._popper=new ye(i,this._menu,this._getPopperConfig())}var o;if("ontouchstart"in document.documentElement&&!e.closest(".navbar-nav"))(o=[]).concat.apply(o,document.body.children).forEach((function(t){return V.on(t,"mouseover",null,(function(){}))}));this._element.focus(),this._element.setAttribute("aria-expanded",!0),et.toggleClass(this._menu,"show"),et.toggleClass(this._element,"show"),V.trigger(e,"shown.bs.dropdown",n)}}},n.hide=function(){if(!this._element.disabled&&!this._element.classList.contains("disabled")&&this._menu.classList.contains("show")){var e=t.getParentFromElement(this._element),n={relatedTarget:this._element};V.trigger(e,"hide.bs.dropdown",n).defaultPrevented||(this._popper&&this._popper.destroy(),et.toggleClass(this._menu,"show"),et.toggleClass(this._element,"show"),V.trigger(e,"hidden.bs.dropdown",n))}},n.dispose=function(){k(this._element,"bs.dropdown"),V.off(this._element,".bs.dropdown"),this._element=null,this._menu=null,this._popper&&(this._popper.destroy(),this._popper=null)},n.update=function(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.scheduleUpdate()},n._addEventListeners=function(){var t=this;V.on(this._element,"click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},n._getConfig=function(t){return t=o(o(o({},this.constructor.Default),et.getDataAttributes(this._element)),t),v(we,t,this.constructor.DefaultType),t},n._getMenuElement=function(){return X.next(this._element,".dropdown-menu")[0]},n._getPlacement=function(){var t=this._element.parentNode,e="bottom-start";return t.classList.contains("dropup")?(e="top-start",this._menu.classList.contains("dropdown-menu-right")&&(e="top-end")):t.classList.contains("dropright")?e="right-start":t.classList.contains("dropleft")?e="left-start":this._menu.classList.contains("dropdown-menu-right")&&(e="bottom-end"),e},n._detectNavbar=function(){return Boolean(this._element.closest(".navbar"))},n._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=o(o({},e.offsets),t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},n._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),o(o({},t),this._config.popperConfig)},t.dropdownInterface=function(e,n){var i=L(e,"bs.dropdown");if(i||(i=new t(e,"object"==typeof n?n:null)),"string"==typeof n){if(void 0===i[n])throw new TypeError('No method named "'+n+'"');i[n]()}},t.jQueryInterface=function(e){return this.each((function(){t.dropdownInterface(this,e)}))},t.clearMenus=function(e){if(!e||2!==e.button&&("keyup"!==e.type||"Tab"===e.key))for(var n=X.find('[data-toggle="dropdown"]'),i=0,o=n.length;i<o;i++){var r=t.getParentFromElement(n[i]),s=L(n[i],"bs.dropdown"),a={relatedTarget:n[i]};if(e&&"click"===e.type&&(a.clickEvent=e),s){var l=s._menu;if(n[i].classList.contains("show"))if(!(e&&("click"===e.type&&/input|textarea/i.test(e.target.tagName)||"keyup"===e.type&&"Tab"===e.key)&&l.contains(e.target)))if(!V.trigger(r,"hide.bs.dropdown",a).defaultPrevented){var c;if("ontouchstart"in document.documentElement)(c=[]).concat.apply(c,document.body.children).forEach((function(t){return V.off(t,"mouseover",null,(function(){}))}));n[i].setAttribute("aria-expanded","false"),s._popper&&s._popper.destroy(),l.classList.remove("show"),n[i].classList.remove("show"),V.trigger(r,"hidden.bs.dropdown",a)}}}},t.getParentFromElement=function(t){return d(t)||t.parentNode},t.dataApiKeydownHandler=function(e){if(!(/input|textarea/i.test(e.target.tagName)?"Space"===e.key||"Escape"!==e.key&&("ArrowDown"!==e.key&&"ArrowUp"!==e.key||e.target.closest(".dropdown-menu")):!Ee.test(e.key))&&(e.preventDefault(),e.stopPropagation(),!this.disabled&&!this.classList.contains("disabled"))){var n=t.getParentFromElement(this),i=this.classList.contains("show");if("Escape"===e.key)return(this.matches('[data-toggle="dropdown"]')?this:X.prev(this,'[data-toggle="dropdown"]')[0]).focus(),void t.clearMenus();if(i&&"Space"!==e.key){var o=X.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",n).filter(_);if(o.length){var r=o.indexOf(e.target);"ArrowUp"===e.key&&r>0&&r--,"ArrowDown"===e.key&&r<o.length-1&&r++,o[r=-1===r?0:r].focus()}}else t.clearMenus()}},t.getInstance=function(t){return L(t,"bs.dropdown")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return Te}},{key:"DefaultType",get:function(){return Le}}]),t}();V.on(document,"keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',ke.dataApiKeydownHandler),V.on(document,"keydown.bs.dropdown.data-api",".dropdown-menu",ke.dataApiKeydownHandler),V.on(document,"click.bs.dropdown.data-api",ke.clearMenus),V.on(document,"keyup.bs.dropdown.data-api",ke.clearMenus),V.on(document,"click.bs.dropdown.data-api",'[data-toggle="dropdown"]',(function(t){t.preventDefault(),t.stopPropagation(),ke.dropdownInterface(this,"toggle")})),V.on(document,"click.bs.dropdown.data-api",".dropdown form",(function(t){return t.stopPropagation()}));var Oe=w();if(Oe){var Ce=Oe.fn[we];Oe.fn[we]=ke.jQueryInterface,Oe.fn[we].Constructor=ke,Oe.fn[we].noConflict=function(){return Oe.fn[we]=Ce,ke.jQueryInterface}}var Ae={backdrop:!0,keyboard:!0,focus:!0,show:!0},De={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},Se=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=X.findOne(".modal-dialog",t),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0,T(t,"bs.modal",this)}var n=t.prototype;return n.toggle=function(t){return this._isShown?this.hide():this.show(t)},n.show=function(t){var e=this;if(!this._isShown&&!this._isTransitioning){this._element.classList.contains("fade")&&(this._isTransitioning=!0);var n=V.trigger(this._element,"show.bs.modal",{relatedTarget:t});this._isShown||n.defaultPrevented||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),V.on(this._element,"click.dismiss.bs.modal",'[data-dismiss="modal"]',(function(t){return e.hide(t)})),V.on(this._dialog,"mousedown.dismiss.bs.modal",(function(){V.one(e._element,"mouseup.dismiss.bs.modal",(function(t){t.target===e._element&&(e._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return e._showElement(t)})))}},n.hide=function(t){var e=this;if((t&&t.preventDefault(),this._isShown&&!this._isTransitioning)&&!V.trigger(this._element,"hide.bs.modal").defaultPrevented){this._isShown=!1;var n=this._element.classList.contains("fade");if(n&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),V.off(document,"focusin.bs.modal"),this._element.classList.remove("show"),V.off(this._element,"click.dismiss.bs.modal"),V.off(this._dialog,"mousedown.dismiss.bs.modal"),n){var i=h(this._element);V.one(this._element,"transitionend",(function(t){return e._hideModal(t)})),m(this._element,i)}else this._hideModal()}},n.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return V.off(t,".bs.modal")})),V.off(document,"focusin.bs.modal"),k(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},n.handleUpdate=function(){this._adjustDialog()},n._getConfig=function(t){return t=o(o({},Ae),t),v("modal",t,De),t},n._showElement=function(t){var e=this,n=this._element.classList.contains("fade"),i=X.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.scrollTop=0,i&&(i.scrollTop=0),n&&y(this._element),this._element.classList.add("show"),this._config.focus&&this._enforceFocus();var o=function(){e._config.focus&&e._element.focus(),e._isTransitioning=!1,V.trigger(e._element,"shown.bs.modal",{relatedTarget:t})};if(n){var r=h(this._dialog);V.one(this._dialog,"transitionend",o),m(this._dialog,r)}else o()},n._enforceFocus=function(){var t=this;V.off(document,"focusin.bs.modal"),V.on(document,"focusin.bs.modal",(function(e){document===e.target||t._element===e.target||t._element.contains(e.target)||t._element.focus()}))},n._setEscapeEvent=function(){var t=this;this._isShown?V.on(this._element,"keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&"Escape"===e.key?(e.preventDefault(),t.hide()):t._config.keyboard||"Escape"!==e.key||t._triggerBackdropTransition()})):V.off(this._element,"keydown.dismiss.bs.modal")},n._setResizeEvent=function(){var t=this;this._isShown?V.on(window,"resize.bs.modal",(function(){return t._adjustDialog()})):V.off(window,"resize.bs.modal")},n._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._isTransitioning=!1,this._showBackdrop((function(){document.body.classList.remove("modal-open"),t._resetAdjustments(),t._resetScrollbar(),V.trigger(t._element,"hidden.bs.modal")}))},n._removeBackdrop=function(){this._backdrop.parentNode.removeChild(this._backdrop),this._backdrop=null},n._showBackdrop=function(t){var e=this,n=this._element.classList.contains("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",n&&this._backdrop.classList.add(n),document.body.appendChild(this._backdrop),V.on(this._element,"click.dismiss.bs.modal",(function(t){e._ignoreBackdropClick?e._ignoreBackdropClick=!1:t.target===t.currentTarget&&e._triggerBackdropTransition()})),n&&y(this._backdrop),this._backdrop.classList.add("show"),!n)return void t();var i=h(this._backdrop);V.one(this._backdrop,"transitionend",t),m(this._backdrop,i)}else if(!this._isShown&&this._backdrop){this._backdrop.classList.remove("show");var o=function(){e._removeBackdrop(),t()};if(this._element.classList.contains("fade")){var r=h(this._backdrop);V.one(this._backdrop,"transitionend",o),m(this._backdrop,r)}else o()}else t()},n._triggerBackdropTransition=function(){var t=this;if("static"===this._config.backdrop){if(V.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;this._element.classList.add("modal-static");var e=h(this._element);V.one(this._element,"transitionend",(function(){t._element.classList.remove("modal-static")})),m(this._element,e),this._element.focus()}else this.hide()},n._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},n._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},n._checkScrollbar=function(){var t=document.body.getBoundingClientRect(),e=t.left,n=t.right;this._isBodyOverflowing=Math.floor(e+n)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},n._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){X.find(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top").forEach((function(e){var n=e.style.paddingRight,i=window.getComputedStyle(e)["padding-right"];et.setDataAttribute(e,"padding-right",n),e.style.paddingRight=parseFloat(i)+t._scrollbarWidth+"px"})),X.find(".sticky-top").forEach((function(e){var n=e.style.marginRight,i=window.getComputedStyle(e)["margin-right"];et.setDataAttribute(e,"margin-right",n),e.style.marginRight=parseFloat(i)-t._scrollbarWidth+"px"}));var e=document.body.style.paddingRight,n=window.getComputedStyle(document.body)["padding-right"];et.setDataAttribute(document.body,"padding-right",e),document.body.style.paddingRight=parseFloat(n)+this._scrollbarWidth+"px"}document.body.classList.add("modal-open")},n._resetScrollbar=function(){X.find(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top").forEach((function(t){var e=et.getDataAttribute(t,"padding-right");void 0!==e&&(et.removeDataAttribute(t,"padding-right"),t.style.paddingRight=e)})),X.find(".sticky-top").forEach((function(t){var e=et.getDataAttribute(t,"margin-right");void 0!==e&&(et.removeDataAttribute(t,"margin-right"),t.style.marginRight=e)}));var t=et.getDataAttribute(document.body,"padding-right");void 0===t?document.body.style.paddingRight="":(et.removeDataAttribute(document.body,"padding-right"),document.body.style.paddingRight=t)},n._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t.jQueryInterface=function(e,n){return this.each((function(){var i=L(this,"bs.modal"),r=o(o(o({},Ae),et.getDataAttributes(this)),"object"==typeof e&&e?e:{});if(i||(i=new t(this,r)),"string"==typeof e){if(void 0===i[e])throw new TypeError('No method named "'+e+'"');i[e](n)}else r.show&&i.show(n)}))},t.getInstance=function(t){return L(t,"bs.modal")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return Ae}}]),t}();V.on(document,"click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var e=this,n=d(this);"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault(),V.one(n,"show.bs.modal",(function(t){t.defaultPrevented||V.one(n,"hidden.bs.modal",(function(){_(e)&&e.focus()}))}));var i=L(n,"bs.modal");if(!i){var r=o(o({},et.getDataAttributes(n)),et.getDataAttributes(this));i=new Se(n,r)}i.show(this)}));var xe=w();if(xe){var Ne=xe.fn.modal;xe.fn.modal=Se.jQueryInterface,xe.fn.modal.Constructor=Se,xe.fn.modal.noConflict=function(){return xe.fn.modal=Ne,Se.jQueryInterface}}var Ie=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],je=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,Pe=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Me={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]};function He(t,e,n){var i;if(!t.length)return t;if(n&&"function"==typeof n)return n(t);for(var o=(new window.DOMParser).parseFromString(t,"text/html"),r=Object.keys(e),s=(i=[]).concat.apply(i,o.body.querySelectorAll("*")),a=function(t,n){var i,o=s[t],a=o.nodeName.toLowerCase();if(-1===r.indexOf(a))return o.parentNode.removeChild(o),"continue";var l=(i=[]).concat.apply(i,o.attributes),c=[].concat(e["*"]||[],e[a]||[]);l.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===Ie.indexOf(n)||(je.test(t.nodeValue)||Pe.test(t.nodeValue));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,r=i.length;o<r;o++)if(i[o].test(n))return!0;return!1})(t,c)||o.removeAttribute(t.nodeName)}))},l=0,c=s.length;l<c;l++)a(l);return o.body.innerHTML}var Be="tooltip",Re=new RegExp("(^|\\s)bs-tooltip\\S+","g"),Fe=["sanitize","whiteList","sanitizeFn"],We={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},Ue={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},Qe={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:Me,popperConfig:null},Ve={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},qe=function(){function t(t,e){if(void 0===ye)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners(),T(t,this.constructor.DATA_KEY,this)}var n=t.prototype;return n.enable=function(){this._isEnabled=!0},n.disable=function(){this._isEnabled=!1},n.toggleEnabled=function(){this._isEnabled=!this._isEnabled},n.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=L(t.target,e);n||(n=new this.constructor(t.target,this._getDelegateConfig()),T(t.target,e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(this.getTipElement().classList.contains("show"))return void this._leave(null,this);this._enter(null,this)}},n.dispose=function(){clearTimeout(this._timeout),k(this.element,this.constructor.DATA_KEY),V.off(this.element,this.constructor.EVENT_KEY),V.off(this.element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.tip&&this.tip.parentNode.removeChild(this.tip),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},n.show=function(){var t=this;if("none"===this.element.style.display)throw new Error("Please use show on visible elements");if(this.isWithContent()&&this._isEnabled){var e=V.trigger(this.element,this.constructor.Event.SHOW),n=function t(e){if(!document.documentElement.attachShadow)return null;if("function"==typeof e.getRootNode){var n=e.getRootNode();return n instanceof ShadowRoot?n:null}return e instanceof ShadowRoot?e:e.parentNode?t(e.parentNode):null}(this.element),i=null===n?this.element.ownerDocument.documentElement.contains(this.element):n.contains(this.element);if(e.defaultPrevented||!i)return;var o=this.getTipElement(),r=c(this.constructor.NAME);o.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&o.classList.add("fade");var s="function"==typeof this.config.placement?this.config.placement.call(this,o,this.element):this.config.placement,a=this._getAttachment(s);this._addAttachmentClass(a);var l,u=this._getContainer();if(T(o,this.constructor.DATA_KEY,this),this.element.ownerDocument.documentElement.contains(this.tip)||u.appendChild(o),V.trigger(this.element,this.constructor.Event.INSERTED),this._popper=new ye(this.element,o,this._getPopperConfig(a)),o.classList.add("show"),"ontouchstart"in document.documentElement)(l=[]).concat.apply(l,document.body.children).forEach((function(t){V.on(t,"mouseover",(function(){}))}));var f=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,V.trigger(t.element,t.constructor.Event.SHOWN),"out"===e&&t._leave(null,t)};if(this.tip.classList.contains("fade")){var d=h(this.tip);V.one(this.tip,"transitionend",f),m(this.tip,d)}else f()}},n.hide=function(){var t=this,e=this.getTipElement(),n=function(){"show"!==t._hoverState&&e.parentNode&&e.parentNode.removeChild(e),t._cleanTipClass(),t.element.removeAttribute("aria-describedby"),V.trigger(t.element,t.constructor.Event.HIDDEN),t._popper.destroy()};if(!V.trigger(this.element,this.constructor.Event.HIDE).defaultPrevented){var i;if(e.classList.remove("show"),"ontouchstart"in document.documentElement)(i=[]).concat.apply(i,document.body.children).forEach((function(t){return V.off(t,"mouseover",b)}));if(this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this.tip.classList.contains("fade")){var o=h(e);V.one(e,"transitionend",n),m(e,o)}else n();this._hoverState=""}},n.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},n.isWithContent=function(){return Boolean(this.getTitle())},n.getTipElement=function(){if(this.tip)return this.tip;var t=document.createElement("div");return t.innerHTML=this.config.template,this.tip=t.children[0],this.tip},n.setContent=function(){var t=this.getTipElement();this.setElementContent(X.findOne(".tooltip-inner",t),this.getTitle()),t.classList.remove("fade","show")},n.setElementContent=function(t,e){if(null!==t)return"object"==typeof e&&g(e)?(e.jquery&&(e=e[0]),void(this.config.html?e.parentNode!==t&&(t.innerHTML="",t.appendChild(e)):t.textContent=e.textContent)):void(this.config.html?(this.config.sanitize&&(e=He(e,this.config.whiteList,this.config.sanitizeFn)),t.innerHTML=e):t.textContent=e)},n.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},n._getPopperConfig=function(t){var e=this;return o(o({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:"."+this.constructor.NAME+"-arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}}),this.config.popperConfig)},n._addAttachmentClass=function(t){this.getTipElement().classList.add("bs-tooltip-"+t)},n._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=o(o({},e.offsets),t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},n._getContainer=function(){return!1===this.config.container?document.body:g(this.config.container)?this.config.container:X.findOne(this.config.container)},n._getAttachment=function(t){return Ue[t.toUpperCase()]},n._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)V.on(t.element,t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n="hover"===e?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,i="hover"===e?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;V.on(t.element,n,t.config.selector,(function(e){return t._enter(e)})),V.on(t.element,i,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},V.on(this.element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=o(o({},this.config),{},{trigger:"manual",selector:""}):this._fixTitle()},n._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},n._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||L(t.target,n))||(e=new this.constructor(t.target,this._getDelegateConfig()),T(t.target,n,e)),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e.getTipElement().classList.contains("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){"show"===e._hoverState&&e.show()}),e.config.delay.show):e.show())},n._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||L(t.target,n))||(e=new this.constructor(t.target,this._getDelegateConfig()),T(t.target,n,e)),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){"out"===e._hoverState&&e.hide()}),e.config.delay.hide):e.hide())},n._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},n._getConfig=function(t){var e=et.getDataAttributes(this.element);return Object.keys(e).forEach((function(t){-1!==Fe.indexOf(t)&&delete e[t]})),t&&"object"==typeof t.container&&t.container.jquery&&(t.container=t.container[0]),"number"==typeof(t=o(o(o({},this.constructor.Default),e),"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),v(Be,t,this.constructor.DefaultType),t.sanitize&&(t.template=He(t.template,t.whiteList,t.sanitizeFn)),t},n._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},n._cleanTipClass=function(){var t=this.getTipElement(),e=t.getAttribute("class").match(Re);null!==e&&e.length>0&&e.map((function(t){return t.trim()})).forEach((function(e){return t.classList.remove(e)}))},n._handlePopperPlacementChange=function(t){var e=t.instance;this.tip=e.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(t.placement))},n._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(t.classList.remove("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},t.jQueryInterface=function(e){return this.each((function(){var n=L(this,"bs.tooltip"),i="object"==typeof e&&e;if((n||!/dispose|hide/.test(e))&&(n||(n=new t(this,i)),"string"==typeof e)){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t.getInstance=function(t){return L(t,"bs.tooltip")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return Qe}},{key:"NAME",get:function(){return Be}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return Ve}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return We}}]),t}(),Ye=w();if(Ye){var ze=Ye.fn[Be];Ye.fn[Be]=qe.jQueryInterface,Ye.fn[Be].Constructor=qe,Ye.fn[Be].noConflict=function(){return Ye.fn[Be]=ze,qe.jQueryInterface}}var Ke="popover",Xe=new RegExp("(^|\\s)bs-popover\\S+","g"),Ge=o(o({},qe.Default),{},{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),$e=o(o({},qe.DefaultType),{},{content:"(string|element|function)"}),Ze={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},Je=function(t){var n,i;function o(){return t.apply(this,arguments)||this}i=t,(n=o).prototype=Object.create(i.prototype),n.prototype.constructor=n,n.__proto__=i;var r=o.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.setContent=function(){var t=this.getTipElement();this.setElementContent(X.findOne(".popover-header",t),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(X.findOne(".popover-body",t),e),t.classList.remove("fade","show")},r._addAttachmentClass=function(t){this.getTipElement().classList.add("bs-popover-"+t)},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=this.getTipElement(),e=t.getAttribute("class").match(Xe);null!==e&&e.length>0&&e.map((function(t){return t.trim()})).forEach((function(e){return t.classList.remove(e)}))},o.jQueryInterface=function(t){return this.each((function(){var e=L(this,"bs.popover"),n="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new o(this,n),T(this,"bs.popover",e)),"string"==typeof t)){if(void 0===e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},o.getInstance=function(t){return L(t,"bs.popover")},e(o,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return Ge}},{key:"NAME",get:function(){return Ke}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return Ze}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return $e}}]),o}(qe),tn=w();if(tn){var en=tn.fn[Ke];tn.fn[Ke]=Je.jQueryInterface,tn.fn[Ke].Constructor=Je,tn.fn[Ke].noConflict=function(){return tn.fn[Ke]=en,Je.jQueryInterface}}var nn="scrollspy",on={offset:10,method:"auto",target:""},rn={offset:"number",method:"string",target:"(string|element)"},sn=function(){function t(t,e){var n=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(e),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,V.on(this._scrollElement,"scroll.bs.scrollspy",(function(t){return n._process(t)})),this.refresh(),this._process(),T(t,"bs.scrollspy",this)}var n=t.prototype;return n.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":"position",n="auto"===this._config.method?e:this._config.method,i="position"===n?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),X.find(this._selector).map((function(t){var e,o=f(t);if(o&&(e=X.findOne(o)),e){var r=e.getBoundingClientRect();if(r.width||r.height)return[et[n](e).top+i,o]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},n.dispose=function(){k(this._element,"bs.scrollspy"),V.off(this._scrollElement,".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},n._getConfig=function(t){if("string"!=typeof(t=o(o({},on),"object"==typeof t&&t?t:{})).target){var e=t.target.id;e||(e=c(nn),t.target.id=e),t.target="#"+e}return v(nn,t,rn),t},n._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},n._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},n._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},n._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&(void 0===this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},n._activate=function(t){this._activeTarget=t,this._clear();var e=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),n=X.findOne(e.join(","));n.classList.contains("dropdown-item")?(X.findOne(".dropdown-toggle",n.closest(".dropdown")).classList.add("active"),n.classList.add("active")):(n.classList.add("active"),X.parents(n,".nav, .list-group").forEach((function(t){X.prev(t,".nav-link, .list-group-item").forEach((function(t){return t.classList.add("active")})),X.prev(t,".nav-item").forEach((function(t){X.children(t,".nav-link").forEach((function(t){return t.classList.add("active")}))}))}))),V.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})},n._clear=function(){X.find(this._selector).filter((function(t){return t.classList.contains("active")})).forEach((function(t){return t.classList.remove("active")}))},t.jQueryInterface=function(e){return this.each((function(){var n=L(this,"bs.scrollspy");if(n||(n=new t(this,"object"==typeof e&&e)),"string"==typeof e){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t.getInstance=function(t){return L(t,"bs.scrollspy")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"Default",get:function(){return on}}]),t}();V.on(window,"load.bs.scrollspy.data-api",(function(){X.find('[data-spy="scroll"]').forEach((function(t){return new sn(t,et.getDataAttributes(t))}))}));var an=w();if(an){var ln=an.fn[nn];an.fn[nn]=sn.jQueryInterface,an.fn[nn].Constructor=sn,an.fn[nn].noConflict=function(){return an.fn[nn]=ln,sn.jQueryInterface}}var cn=function(){function t(t){this._element=t,T(this._element,"bs.tab",this)}var n=t.prototype;return n.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains("active")||this._element.classList.contains("disabled"))){var e,n=d(this._element),i=this._element.closest(".nav, .list-group");if(i){var o="UL"===i.nodeName||"OL"===i.nodeName?":scope > li > .active":".active";e=(e=X.find(o,i))[e.length-1]}var r=null;if(e&&(r=V.trigger(e,"hide.bs.tab",{relatedTarget:this._element})),!(V.trigger(this._element,"show.bs.tab",{relatedTarget:e}).defaultPrevented||null!==r&&r.defaultPrevented)){this._activate(this._element,i);var s=function(){V.trigger(e,"hidden.bs.tab",{relatedTarget:t._element}),V.trigger(t._element,"shown.bs.tab",{relatedTarget:e})};n?this._activate(n,n.parentNode,s):s()}}},n.dispose=function(){k(this._element,"bs.tab"),this._element=null},n._activate=function(t,e,n){var i=this,o=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?X.children(e,".active"):X.find(":scope > li > .active",e))[0],r=n&&o&&o.classList.contains("fade"),s=function(){return i._transitionComplete(t,o,n)};if(o&&r){var a=h(o);o.classList.remove("show"),V.one(o,"transitionend",s),m(o,a)}else s()},n._transitionComplete=function(t,e,n){if(e){e.classList.remove("active");var i=X.findOne(":scope > .dropdown-menu .active",e.parentNode);i&&i.classList.remove("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}(t.classList.add("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),y(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&t.parentNode.classList.contains("dropdown-menu"))&&(t.closest(".dropdown")&&X.find(".dropdown-toggle").forEach((function(t){return t.classList.add("active")})),t.setAttribute("aria-expanded",!0));n&&n()},t.jQueryInterface=function(e){return this.each((function(){var n=L(this,"bs.tab")||new t(this);if("string"==typeof e){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t.getInstance=function(t){return L(t,"bs.tab")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}}]),t}();V.on(document,"click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),(L(this,"bs.tab")||new cn(this)).show()}));var un=w();if(un){var fn=un.fn.tab;un.fn.tab=cn.jQueryInterface,un.fn.tab.Constructor=cn,un.fn.tab.noConflict=function(){return un.fn.tab=fn,cn.jQueryInterface}}var dn={animation:"boolean",autohide:"boolean",delay:"number"},hn={animation:!0,autohide:!0,delay:500},pn=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners(),T(t,"bs.toast",this)}var n=t.prototype;return n.show=function(){var t=this;if(!V.trigger(this._element,"show.bs.toast").defaultPrevented){this._config.animation&&this._element.classList.add("fade");var e=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),V.trigger(t._element,"shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),y(this._element),this._element.classList.add("showing"),this._config.animation){var n=h(this._element);V.one(this._element,"transitionend",e),m(this._element,n)}else e()}},n.hide=function(){var t=this;if(this._element.classList.contains("show")&&!V.trigger(this._element,"hide.bs.toast").defaultPrevented){var e=function(){t._element.classList.add("hide"),V.trigger(t._element,"hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var n=h(this._element);V.one(this._element,"transitionend",e),m(this._element,n)}else e()}},n.dispose=function(){clearTimeout(this._timeout),this._timeout=null,this._element.classList.contains("show")&&this._element.classList.remove("show"),V.off(this._element,"click.dismiss.bs.toast"),k(this._element,"bs.toast"),this._element=null,this._config=null},n._getConfig=function(t){return t=o(o(o({},hn),et.getDataAttributes(this._element)),"object"==typeof t&&t?t:{}),v("toast",t,this.constructor.DefaultType),t},n._setListeners=function(){var t=this;V.on(this._element,"click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},t.jQueryInterface=function(e){return this.each((function(){var n=L(this,"bs.toast");if(n||(n=new t(this,"object"==typeof e&&e)),"string"==typeof e){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e](this)}}))},t.getInstance=function(t){return L(t,"bs.toast")},e(t,null,[{key:"VERSION",get:function(){return"5.0.0-alpha1"}},{key:"DefaultType",get:function(){return dn}},{key:"Default",get:function(){return hn}}]),t}(),gn=w();if(gn){var mn=gn.fn.toast;gn.fn.toast=pn.jQueryInterface,gn.fn.toast.Constructor=pn,gn.fn.toast.noConflict=function(){return gn.fn.toast=mn,pn.jQueryInterface}}return{Alert:Y,Button:G,Carousel:at,Collapse:ht,Dropdown:ke,Modal:Se,Popover:Je,ScrollSpy:sn,Tab:cn,Toast:pn,Tooltip:qe}}));
diff --git a/src/lib/liquid.js b/src/lib/liquid.js
new file mode 100644
index 0000000..118b044
--- /dev/null
+++ b/src/lib/liquid.js
@@ -0,0 +1,3651 @@
+/*
+ * liquidjs@9.11.10, https://github.com/harttle/liquidjs
+ * (c) 2016-2020 harttle
+ * Released under the MIT License.
+ */
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
+ (global = global || self, factory(global.liquidjs = {}));
+}(this, function (exports) { 'use strict';
+
+ /*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+ /* global Reflect, Promise */
+
+ var extendStatics = function(d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ };
+
+ function __extends(d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ }
+
+ var __assign = function() {
+ __assign = Object.assign || function __assign(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+ };
+
+ function __awaiter(thisArg, _arguments, P, generator) {
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+ }
+
+ function __generator(thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (_) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+ }
+
+ function __values(o) {
+ var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
+ if (m) return m.call(o);
+ return {
+ next: function () {
+ if (o && i >= o.length) o = void 0;
+ return { value: o && o[i++], done: !o };
+ }
+ };
+ }
+
+ function __read(o, n) {
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
+ if (!m) return o;
+ var i = m.call(o), r, ar = [], e;
+ try {
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
+ }
+ catch (error) { e = { error: error }; }
+ finally {
+ try {
+ if (r && !r.done && (m = i["return"])) m.call(i);
+ }
+ finally { if (e) throw e.error; }
+ }
+ return ar;
+ }
+
+ function __spread() {
+ for (var ar = [], i = 0; i < arguments.length; i++)
+ ar = ar.concat(__read(arguments[i]));
+ return ar;
+ }
+
+ var Drop = /** @class */ (function () {
+ function Drop() {
+ }
+ Drop.prototype.valueOf = function () {
+ return undefined;
+ };
+ Drop.prototype.liquidMethodMissing = function (key) {
+ return undefined;
+ };
+ return Drop;
+ }());
+
+ var toStr = Object.prototype.toString;
+ var toLowerCase = String.prototype.toLowerCase;
+ /*
+ * Checks if value is classified as a String primitive or object.
+ * @param {any} value The value to check.
+ * @return {Boolean} Returns true if value is a string, else false.
+ */
+ function isString(value) {
+ return toStr.call(value) === '[object String]';
+ }
+ function isFunction(value) {
+ return typeof value === 'function';
+ }
+ function stringify(value) {
+ value = toValue(value);
+ return isNil(value) ? '' : String(value);
+ }
+ function toValue(value) {
+ return value instanceof Drop ? value.valueOf() : value;
+ }
+ function isNumber(value) {
+ return typeof value === 'number';
+ }
+ function toLiquid(value) {
+ if (value && isFunction(value.toLiquid))
+ return toLiquid(value.toLiquid());
+ return value;
+ }
+ function isNil(value) {
+ return value === null || value === undefined;
+ }
+ function isArray(value) {
+ // be compatible with IE 8
+ return toStr.call(value) === '[object Array]';
+ }
+ /*
+ * Iterates over own enumerable string keyed properties of an object and invokes iteratee for each property.
+ * The iteratee is invoked with three arguments: (value, key, object).
+ * Iteratee functions may exit iteration early by explicitly returning false.
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @return {Object} Returns object.
+ */
+ function forOwn(object, iteratee) {
+ object = object || {};
+ for (var k in object) {
+ if (object.hasOwnProperty(k)) {
+ if (iteratee(object[k], k, object) === false)
+ break;
+ }
+ }
+ return object;
+ }
+ function last(arr) {
+ return arr[arr.length - 1];
+ }
+ /*
+ * Checks if value is the language type of Object.
+ * (e.g. arrays, functions, objects, regexes, new Number(0), and new String(''))
+ * @param {any} value The value to check.
+ * @return {Boolean} Returns true if value is an object, else false.
+ */
+ function isObject(value) {
+ var type = typeof value;
+ return value !== null && (type === 'object' || type === 'function');
+ }
+ function range(start, stop, step) {
+ if (step === void 0) { step = 1; }
+ var arr = [];
+ for (var i = start; i < stop; i += step) {
+ arr.push(i);
+ }
+ return arr;
+ }
+ function padStart(str, length, ch) {
+ if (ch === void 0) { ch = ' '; }
+ return pad(str, length, ch, function (str, ch) { return ch + str; });
+ }
+ function padEnd(str, length, ch) {
+ if (ch === void 0) { ch = ' '; }
+ return pad(str, length, ch, function (str, ch) { return str + ch; });
+ }
+ function pad(str, length, ch, add) {
+ str = String(str);
+ var n = length - str.length;
+ while (n-- > 0)
+ str = add(str, ch);
+ return str;
+ }
+ function identify(val) {
+ return val;
+ }
+ function snakeCase(str) {
+ return str.replace(/(\w?)([A-Z])/g, function (_, a, b) { return (a ? a + '_' : '') + b.toLowerCase(); });
+ }
+ function changeCase(str) {
+ var hasLowerCase = __spread(str).some(function (ch) { return ch >= 'a' && ch <= 'z'; });
+ return hasLowerCase ? str.toUpperCase() : str.toLowerCase();
+ }
+ function ellipsis(str, N) {
+ return str.length > N ? str.substr(0, N - 3) + '...' : str;
+ }
+ // compare string in case-insensitive way, undefined values to the tail
+ function caseInsensitiveCompare(a, b) {
+ if (a == null && b == null)
+ return 0;
+ if (a == null)
+ return 1;
+ if (b == null)
+ return -1;
+ a = toLowerCase.call(a);
+ b = toLowerCase.call(b);
+ if (a < b)
+ return -1;
+ if (a > b)
+ return 1;
+ return 0;
+ }
+
+ var Node = /** @class */ (function () {
+ function Node(key, value, next, prev) {
+ this.key = key;
+ this.value = value;
+ this.next = next;
+ this.prev = prev;
+ }
+ return Node;
+ }());
+ var LRU = /** @class */ (function () {
+ function LRU(limit, size) {
+ if (size === void 0) { size = 0; }
+ this.limit = limit;
+ this.size = size;
+ this.cache = {};
+ this.head = new Node('HEAD', null, null, null);
+ this.tail = new Node('TAIL', null, null, null);
+ this.head.next = this.tail;
+ this.tail.prev = this.head;
+ }
+ LRU.prototype.write = function (key, value) {
+ if (this.cache[key]) {
+ this.cache[key].value = value;
+ }
+ else {
+ var node = new Node(key, value, this.head.next, this.head);
+ this.head.next.prev = node;
+ this.head.next = node;
+ this.cache[key] = node;
+ this.size++;
+ this.ensureLimit();
+ }
+ };
+ LRU.prototype.read = function (key) {
+ if (!this.cache[key])
+ return;
+ var value = this.cache[key].value;
+ this.remove(key);
+ this.write(key, value);
+ return value;
+ };
+ LRU.prototype.remove = function (key) {
+ var node = this.cache[key];
+ node.prev.next = node.next;
+ node.next.prev = node.prev;
+ delete this.cache[key];
+ this.size--;
+ };
+ LRU.prototype.clear = function () {
+ this.head.next = this.tail;
+ this.tail.prev = this.head;
+ this.size = 0;
+ this.cache = {};
+ };
+ LRU.prototype.ensureLimit = function () {
+ if (this.size > this.limit)
+ this.remove(this.tail.prev.key);
+ };
+ return LRU;
+ }());
+
+ var defaultOptions = {
+ root: ['.'],
+ cache: undefined,
+ extname: '',
+ dynamicPartials: true,
+ trimTagRight: false,
+ trimTagLeft: false,
+ trimOutputRight: false,
+ trimOutputLeft: false,
+ greedy: true,
+ tagDelimiterLeft: '{%',
+ tagDelimiterRight: '%}',
+ outputDelimiterLeft: '{{',
+ outputDelimiterRight: '}}',
+ strictFilters: false,
+ strictVariables: false,
+ globals: {}
+ };
+ function normalize(options) {
+ options = options || {};
+ if (options.hasOwnProperty('root')) {
+ options.root = normalizeStringArray(options.root);
+ }
+ if (options.hasOwnProperty('cache')) {
+ var cache = void 0;
+ if (typeof options.cache === 'number')
+ cache = options.cache > 0 ? new LRU(options.cache) : undefined;
+ else if (typeof options.cache === 'object')
+ cache = options.cache;
+ else
+ cache = options.cache ? new LRU(1024) : undefined;
+ options.cache = cache;
+ }
+ return options;
+ }
+ function applyDefault(options) {
+ return __assign({}, defaultOptions, options);
+ }
+ function normalizeStringArray(value) {
+ if (isArray(value))
+ return value;
+ if (isString(value))
+ return [value];
+ return [];
+ }
+
+ var Context = /** @class */ (function () {
+ function Context(env, opts, sync) {
+ if (env === void 0) { env = {}; }
+ if (opts === void 0) { opts = defaultOptions; }
+ if (sync === void 0) { sync = false; }
+ this.scopes = [{}];
+ this.registers = {};
+ this.sync = sync;
+ this.opts = opts;
+ this.globals = opts.globals;
+ this.environments = env;
+ }
+ Context.prototype.getRegister = function (key, defaultValue) {
+ if (defaultValue === void 0) { defaultValue = {}; }
+ return (this.registers[key] = this.registers[key] || defaultValue);
+ };
+ Context.prototype.setRegister = function (key, value) {
+ return (this.registers[key] = value);
+ };
+ Context.prototype.saveRegister = function () {
+ var _this = this;
+ var keys = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ keys[_i] = arguments[_i];
+ }
+ return keys.map(function (key) { return [key, _this.getRegister(key)]; });
+ };
+ Context.prototype.restoreRegister = function (keyValues) {
+ var _this = this;
+ return keyValues.forEach(function (_a) {
+ var _b = __read(_a, 2), key = _b[0], value = _b[1];
+ return _this.setRegister(key, value);
+ });
+ };
+ Context.prototype.getAll = function () {
+ return __spread([this.globals, this.environments], this.scopes).reduce(function (ctx, val) { return __assign(ctx, val); }, {});
+ };
+ Context.prototype.get = function (paths) {
+ var scope = this.findScope(paths[0]);
+ return this.getFromScope(scope, paths);
+ };
+ Context.prototype.getFromScope = function (scope, paths) {
+ var _this = this;
+ if (typeof paths === 'string')
+ paths = paths.split('.');
+ return paths.reduce(function (scope, path) {
+ scope = readProperty(scope, path);
+ if (isNil(scope) && _this.opts.strictVariables) {
+ throw new TypeError("undefined variable: " + path);
+ }
+ return scope;
+ }, scope);
+ };
+ Context.prototype.push = function (ctx) {
+ return this.scopes.push(ctx);
+ };
+ Context.prototype.pop = function () {
+ return this.scopes.pop();
+ };
+ Context.prototype.bottom = function () {
+ return this.scopes[0];
+ };
+ Context.prototype.findScope = function (key) {
+ for (var i = this.scopes.length - 1; i >= 0; i--) {
+ var candidate = this.scopes[i];
+ if (key in candidate)
+ return candidate;
+ }
+ if (key in this.environments)
+ return this.environments;
+ return this.globals;
+ };
+ return Context;
+ }());
+ function readProperty(obj, key) {
+ if (isNil(obj))
+ return obj;
+ obj = toLiquid(obj);
+ if (obj instanceof Drop) {
+ if (isFunction(obj[key]))
+ return obj[key]();
+ if (obj.hasOwnProperty(key))
+ return obj[key];
+ return obj.liquidMethodMissing(key);
+ }
+ if (key === 'size')
+ return readSize(obj);
+ if (key === 'first')
+ return readFirst(obj);
+ if (key === 'last')
+ return readLast(obj);
+ return obj[key];
+ }
+ function readFirst(obj) {
+ if (isArray(obj))
+ return obj[0];
+ return obj['first'];
+ }
+ function readLast(obj) {
+ if (isArray(obj))
+ return obj[obj.length - 1];
+ return obj['last'];
+ }
+ function readSize(obj) {
+ if (isArray(obj) || isString(obj))
+ return obj.length;
+ return obj['size'];
+ }
+
+ function domResolve(root, path) {
+ var base = document.createElement('base');
+ base.href = root;
+ var head = document.getElementsByTagName('head')[0];
+ head.insertBefore(base, head.firstChild);
+ var a = document.createElement('a');
+ a.href = path;
+ var resolved = a.href;
+ head.removeChild(base);
+ return resolved;
+ }
+ function resolve(root, filepath, ext) {
+ if (root.length && last(root) !== '/')
+ root += '/';
+ var url = domResolve(root, filepath);
+ return url.replace(/^(\w+:\/\/[^/]+)(\/[^?]+)/, function (str, origin, path) {
+ var last = path.split('/').pop();
+ if (/\.\w+$/.test(last))
+ return str;
+ return origin + path + ext;
+ });
+ }
+ function readFile(url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, new Promise(function (resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.onload = function () {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ resolve(xhr.responseText);
+ }
+ else {
+ reject(new Error(xhr.statusText));
+ }
+ };
+ xhr.onerror = function () {
+ reject(new Error('An error occurred whilst receiving the response.'));
+ };
+ xhr.open('GET', url);
+ xhr.send();
+ })];
+ });
+ });
+ }
+ function readFileSync(url) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', url, false);
+ xhr.send();
+ if (xhr.status < 200 || xhr.status >= 300) {
+ throw new Error(xhr.statusText);
+ }
+ return xhr.responseText;
+ }
+ function exists(filepath) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, true];
+ });
+ });
+ }
+ function existsSync(filepath) {
+ return true;
+ }
+
+ var fs = /*#__PURE__*/Object.freeze({
+ resolve: resolve,
+ readFile: readFile,
+ readFileSync: readFileSync,
+ exists: exists,
+ existsSync: existsSync
+ });
+
+ var TokenKind;
+ (function (TokenKind) {
+ TokenKind[TokenKind["Number"] = 1] = "Number";
+ TokenKind[TokenKind["Literal"] = 2] = "Literal";
+ TokenKind[TokenKind["Tag"] = 4] = "Tag";
+ TokenKind[TokenKind["Output"] = 8] = "Output";
+ TokenKind[TokenKind["HTML"] = 16] = "HTML";
+ TokenKind[TokenKind["Filter"] = 32] = "Filter";
+ TokenKind[TokenKind["Hash"] = 64] = "Hash";
+ TokenKind[TokenKind["PropertyAccess"] = 128] = "PropertyAccess";
+ TokenKind[TokenKind["Word"] = 256] = "Word";
+ TokenKind[TokenKind["Range"] = 512] = "Range";
+ TokenKind[TokenKind["Quoted"] = 1024] = "Quoted";
+ TokenKind[TokenKind["Operator"] = 2048] = "Operator";
+ TokenKind[TokenKind["Delimited"] = 12] = "Delimited";
+ })(TokenKind || (TokenKind = {}));
+
+ function isDelimitedToken(val) {
+ return !!(getKind(val) & TokenKind.Delimited);
+ }
+ function isOperatorToken(val) {
+ return getKind(val) === TokenKind.Operator;
+ }
+ function isHTMLToken(val) {
+ return getKind(val) === TokenKind.HTML;
+ }
+ function isOutputToken(val) {
+ return getKind(val) === TokenKind.Output;
+ }
+ function isTagToken(val) {
+ return getKind(val) === TokenKind.Tag;
+ }
+ function isQuotedToken(val) {
+ return getKind(val) === TokenKind.Quoted;
+ }
+ function isLiteralToken(val) {
+ return getKind(val) === TokenKind.Literal;
+ }
+ function isNumberToken(val) {
+ return getKind(val) === TokenKind.Number;
+ }
+ function isPropertyAccessToken(val) {
+ return getKind(val) === TokenKind.PropertyAccess;
+ }
+ function isWordToken(val) {
+ return getKind(val) === TokenKind.Word;
+ }
+ function isRangeToken(val) {
+ return getKind(val) === TokenKind.Range;
+ }
+ function getKind(val) {
+ return val ? val.kind : -1;
+ }
+
+ var typeGuards = /*#__PURE__*/Object.freeze({
+ isDelimitedToken: isDelimitedToken,
+ isOperatorToken: isOperatorToken,
+ isHTMLToken: isHTMLToken,
+ isOutputToken: isOutputToken,
+ isTagToken: isTagToken,
+ isQuotedToken: isQuotedToken,
+ isLiteralToken: isLiteralToken,
+ isNumberToken: isNumberToken,
+ isPropertyAccessToken: isPropertyAccessToken,
+ isWordToken: isWordToken,
+ isRangeToken: isRangeToken
+ });
+
+ // **DO NOT CHANGE THIS FILE**
+ //
+ // This file is generated by bin/character-gen.js
+ // bitmask character types to boost performance
+ var TYPES = [0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 4, 4, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 2, 8, 0, 0, 0, 0, 8, 0, 0, 0, 64, 0, 65, 0, 0, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 0, 0, 2, 2, 2, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0];
+ var VARIABLE = 1;
+ var BLANK = 4;
+ var QUOTE = 8;
+ var INLINE_BLANK = 16;
+ var NUMBER = 32;
+ var SIGN = 64;
+ TYPES[160] = TYPES[5760] = TYPES[6158] = TYPES[8192] = TYPES[8193] = TYPES[8194] = TYPES[8195] = TYPES[8196] = TYPES[8197] = TYPES[8198] = TYPES[8199] = TYPES[8200] = TYPES[8201] = TYPES[8202] = TYPES[8232] = TYPES[8233] = TYPES[8239] = TYPES[8287] = TYPES[12288] = BLANK;
+
+ function whiteSpaceCtrl(tokens, options) {
+ options = __assign({ greedy: true }, options);
+ var inRaw = false;
+ for (var i = 0; i < tokens.length; i++) {
+ var token = tokens[i];
+ if (!isDelimitedToken(token))
+ continue;
+ if (!inRaw && token.trimLeft) {
+ trimLeft(tokens[i - 1], options.greedy);
+ }
+ if (isTagToken(token)) {
+ if (token.name === 'raw')
+ inRaw = true;
+ else if (token.name === 'endraw')
+ inRaw = false;
+ }
+ if (!inRaw && token.trimRight) {
+ trimRight(tokens[i + 1], options.greedy);
+ }
+ }
+ }
+ function trimLeft(token, greedy) {
+ if (!token || !isHTMLToken(token))
+ return;
+ var mask = greedy ? BLANK : INLINE_BLANK;
+ while (TYPES[token.input.charCodeAt(token.end - 1 - token.trimRight)] & mask)
+ token.trimRight++;
+ }
+ function trimRight(token, greedy) {
+ if (!token || !isHTMLToken(token))
+ return;
+ var mask = greedy ? BLANK : INLINE_BLANK;
+ while (TYPES[token.input.charCodeAt(token.begin + token.trimLeft)] & mask)
+ token.trimLeft++;
+ if (token.input.charAt(token.begin + token.trimLeft) === '\n')
+ token.trimLeft++;
+ }
+
+ var Token = /** @class */ (function () {
+ function Token(kind, input, begin, end, file) {
+ this.kind = kind;
+ this.input = input;
+ this.begin = begin;
+ this.end = end;
+ this.file = file;
+ }
+ Token.prototype.getText = function () {
+ return this.input.slice(this.begin, this.end);
+ };
+ Token.prototype.getPosition = function () {
+ var _a = __read([1, 1], 2), row = _a[0], col = _a[1];
+ for (var i = 0; i < this.begin; i++) {
+ if (this.input[i] === '\n') {
+ row++;
+ col = 1;
+ }
+ else
+ col++;
+ }
+ return [row, col];
+ };
+ Token.prototype.size = function () {
+ return this.end - this.begin;
+ };
+ return Token;
+ }());
+
+ var NumberToken = /** @class */ (function (_super) {
+ __extends(NumberToken, _super);
+ function NumberToken(whole, decimal) {
+ var _this = _super.call(this, TokenKind.Number, whole.input, whole.begin, decimal ? decimal.end : whole.end, whole.file) || this;
+ _this.whole = whole;
+ _this.decimal = decimal;
+ return _this;
+ }
+ return NumberToken;
+ }(Token));
+
+ // a word can be an identifier, a number, a keyword or a single-word-literal
+ var WordToken = /** @class */ (function (_super) {
+ __extends(WordToken, _super);
+ function WordToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Word, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ _this.content = _this.getText();
+ return _this;
+ }
+ WordToken.prototype.isNumber = function (allowSign) {
+ if (allowSign === void 0) { allowSign = false; }
+ var begin = allowSign && TYPES[this.input.charCodeAt(this.begin)] & SIGN
+ ? this.begin + 1
+ : this.begin;
+ for (var i = begin; i < this.end; i++) {
+ if (!(TYPES[this.input.charCodeAt(i)] & NUMBER))
+ return false;
+ }
+ return true;
+ };
+ return WordToken;
+ }(Token));
+
+ var EmptyDrop = /** @class */ (function (_super) {
+ __extends(EmptyDrop, _super);
+ function EmptyDrop() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ EmptyDrop.prototype.equals = function (value) {
+ if (isString(value) || isArray(value))
+ return value.length === 0;
+ if (isObject(value))
+ return Object.keys(value).length === 0;
+ return false;
+ };
+ EmptyDrop.prototype.gt = function () {
+ return false;
+ };
+ EmptyDrop.prototype.geq = function () {
+ return false;
+ };
+ EmptyDrop.prototype.lt = function () {
+ return false;
+ };
+ EmptyDrop.prototype.leq = function () {
+ return false;
+ };
+ EmptyDrop.prototype.valueOf = function () {
+ return '';
+ };
+ return EmptyDrop;
+ }(Drop));
+
+ var BlankDrop = /** @class */ (function (_super) {
+ __extends(BlankDrop, _super);
+ function BlankDrop() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ BlankDrop.prototype.equals = function (value) {
+ if (value === false)
+ return true;
+ if (isNil(toValue(value)))
+ return true;
+ if (isString(value))
+ return /^\s*$/.test(value);
+ return _super.prototype.equals.call(this, value);
+ };
+ return BlankDrop;
+ }(EmptyDrop));
+
+ var NullDrop = /** @class */ (function (_super) {
+ __extends(NullDrop, _super);
+ function NullDrop() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ NullDrop.prototype.equals = function (value) {
+ return isNil(toValue(value)) || value instanceof BlankDrop;
+ };
+ NullDrop.prototype.gt = function () {
+ return false;
+ };
+ NullDrop.prototype.geq = function () {
+ return false;
+ };
+ NullDrop.prototype.lt = function () {
+ return false;
+ };
+ NullDrop.prototype.leq = function () {
+ return false;
+ };
+ NullDrop.prototype.valueOf = function () {
+ return null;
+ };
+ return NullDrop;
+ }(Drop));
+
+ var literalValues = {
+ 'true': true,
+ 'false': false,
+ 'nil': new NullDrop(),
+ 'null': new NullDrop(),
+ 'empty': new EmptyDrop(),
+ 'blank': new BlankDrop()
+ };
+
+ var LiteralToken = /** @class */ (function (_super) {
+ __extends(LiteralToken, _super);
+ function LiteralToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Literal, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ _this.literal = _this.getText();
+ return _this;
+ }
+ return LiteralToken;
+ }(Token));
+
+ var precedence = {
+ '==': 1,
+ '!=': 1,
+ '>': 1,
+ '<': 1,
+ '>=': 1,
+ '<=': 1,
+ 'contains': 1,
+ 'and': 0,
+ 'or': 0
+ };
+ var OperatorToken = /** @class */ (function (_super) {
+ __extends(OperatorToken, _super);
+ function OperatorToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Operator, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ _this.operator = _this.getText();
+ return _this;
+ }
+ OperatorToken.prototype.getPrecedence = function () {
+ return precedence[this.getText()];
+ };
+ return OperatorToken;
+ }(Token));
+
+ var PropertyAccessToken = /** @class */ (function (_super) {
+ __extends(PropertyAccessToken, _super);
+ function PropertyAccessToken(variable, props, end) {
+ var _this = _super.call(this, TokenKind.PropertyAccess, variable.input, variable.begin, end, variable.file) || this;
+ _this.variable = variable;
+ _this.props = props;
+ return _this;
+ }
+ return PropertyAccessToken;
+ }(Token));
+
+ var LiquidError = /** @class */ (function (_super) {
+ __extends(LiquidError, _super);
+ function LiquidError(err, token) {
+ var _this = _super.call(this, err.message) || this;
+ _this.originalError = err;
+ _this.token = token;
+ return _this;
+ }
+ LiquidError.prototype.update = function () {
+ var err = this.originalError;
+ var context = mkContext(this.token);
+ this.message = mkMessage(err.message, this.token);
+ this.stack = this.message + '\n' + context +
+ '\n' + this.stack + '\nFrom ' + err.stack;
+ };
+ return LiquidError;
+ }(Error));
+ var TokenizationError = /** @class */ (function (_super) {
+ __extends(TokenizationError, _super);
+ function TokenizationError(message, token) {
+ var _this = _super.call(this, new Error(message), token) || this;
+ _this.name = 'TokenizationError';
+ _super.prototype.update.call(_this);
+ return _this;
+ }
+ return TokenizationError;
+ }(LiquidError));
+ var ParseError = /** @class */ (function (_super) {
+ __extends(ParseError, _super);
+ function ParseError(err, token) {
+ var _this = _super.call(this, err, token) || this;
+ _this.name = 'ParseError';
+ _this.message = err.message;
+ _super.prototype.update.call(_this);
+ return _this;
+ }
+ return ParseError;
+ }(LiquidError));
+ var RenderError = /** @class */ (function (_super) {
+ __extends(RenderError, _super);
+ function RenderError(err, tpl) {
+ var _this = _super.call(this, err, tpl.token) || this;
+ _this.name = 'RenderError';
+ _this.message = err.message;
+ _super.prototype.update.call(_this);
+ return _this;
+ }
+ RenderError.is = function (obj) {
+ return obj instanceof RenderError;
+ };
+ return RenderError;
+ }(LiquidError));
+ var AssertionError = /** @class */ (function (_super) {
+ __extends(AssertionError, _super);
+ function AssertionError(message) {
+ var _this = _super.call(this, message) || this;
+ _this.name = 'AssertionError';
+ _this.message = message + '';
+ return _this;
+ }
+ return AssertionError;
+ }(Error));
+ function mkContext(token) {
+ var _a = __read(token.getPosition(), 1), line = _a[0];
+ var lines = token.input.split('\n');
+ var begin = Math.max(line - 2, 1);
+ var end = Math.min(line + 3, lines.length);
+ var context = range(begin, end + 1)
+ .map(function (lineNumber) {
+ var indicator = (lineNumber === line) ? '>> ' : ' ';
+ var num = padStart(String(lineNumber), String(end).length);
+ var text = lines[lineNumber - 1];
+ return "" + indicator + num + "| " + text;
+ })
+ .join('\n');
+ return context;
+ }
+ function mkMessage(msg, token) {
+ if (token.file)
+ msg += ", file:" + token.file;
+ var _a = __read(token.getPosition(), 2), line = _a[0], col = _a[1];
+ msg += ", line:" + line + ", col:" + col;
+ return msg;
+ }
+
+ function assert(predicate, message) {
+ if (!predicate) {
+ var msg = message ? message() : "expect " + predicate + " to be true";
+ throw new AssertionError(msg);
+ }
+ }
+
+ var FilterToken = /** @class */ (function (_super) {
+ __extends(FilterToken, _super);
+ function FilterToken(name, args, input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Filter, input, begin, end, file) || this;
+ _this.name = name;
+ _this.args = args;
+ return _this;
+ }
+ return FilterToken;
+ }(Token));
+
+ var HashToken = /** @class */ (function (_super) {
+ __extends(HashToken, _super);
+ function HashToken(input, begin, end, name, value, file) {
+ var _this = _super.call(this, TokenKind.Hash, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.name = name;
+ _this.value = value;
+ _this.file = file;
+ return _this;
+ }
+ return HashToken;
+ }(Token));
+
+ var QuotedToken = /** @class */ (function (_super) {
+ __extends(QuotedToken, _super);
+ function QuotedToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Quoted, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ return _this;
+ }
+ return QuotedToken;
+ }(Token));
+
+ var HTMLToken = /** @class */ (function (_super) {
+ __extends(HTMLToken, _super);
+ function HTMLToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.HTML, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ _this.trimLeft = 0;
+ _this.trimRight = 0;
+ return _this;
+ }
+ HTMLToken.prototype.getContent = function () {
+ return this.input.slice(this.begin + this.trimLeft, this.end - this.trimRight);
+ };
+ return HTMLToken;
+ }(Token));
+
+ var DelimitedToken = /** @class */ (function (_super) {
+ __extends(DelimitedToken, _super);
+ function DelimitedToken(kind, content, input, begin, end, trimLeft, trimRight, file) {
+ var _this = _super.call(this, kind, input, begin, end, file) || this;
+ _this.trimLeft = false;
+ _this.trimRight = false;
+ _this.content = _this.getText();
+ var tl = content[0] === '-';
+ var tr = last(content) === '-';
+ _this.content = content
+ .slice(tl ? 1 : 0, tr ? -1 : content.length)
+ .trim();
+ _this.trimLeft = tl || trimLeft;
+ _this.trimRight = tr || trimRight;
+ return _this;
+ }
+ return DelimitedToken;
+ }(Token));
+
+ var TagToken = /** @class */ (function (_super) {
+ __extends(TagToken, _super);
+ function TagToken(input, begin, end, options, file) {
+ var _this = this;
+ var trimTagLeft = options.trimTagLeft, trimTagRight = options.trimTagRight, tagDelimiterLeft = options.tagDelimiterLeft, tagDelimiterRight = options.tagDelimiterRight;
+ var value = input.slice(begin + tagDelimiterLeft.length, end - tagDelimiterRight.length);
+ _this = _super.call(this, TokenKind.Tag, value, input, begin, end, trimTagLeft, trimTagRight, file) || this;
+ var nameEnd = 0;
+ while (TYPES[_this.content.charCodeAt(nameEnd)] & VARIABLE)
+ nameEnd++;
+ _this.name = _this.content.slice(0, nameEnd);
+ if (!_this.name)
+ throw new TokenizationError("illegal tag syntax", _this);
+ var argsBegin = nameEnd;
+ while (TYPES[_this.content.charCodeAt(argsBegin)] & BLANK)
+ argsBegin++;
+ _this.args = _this.content.slice(argsBegin);
+ return _this;
+ }
+ return TagToken;
+ }(DelimitedToken));
+
+ var RangeToken = /** @class */ (function (_super) {
+ __extends(RangeToken, _super);
+ function RangeToken(input, begin, end, lhs, rhs, file) {
+ var _this = _super.call(this, TokenKind.Range, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.lhs = lhs;
+ _this.rhs = rhs;
+ _this.file = file;
+ return _this;
+ }
+ return RangeToken;
+ }(Token));
+
+ var OutputToken = /** @class */ (function (_super) {
+ __extends(OutputToken, _super);
+ function OutputToken(input, begin, end, options, file) {
+ var _this = this;
+ var trimOutputLeft = options.trimOutputLeft, trimOutputRight = options.trimOutputRight, outputDelimiterLeft = options.outputDelimiterLeft, outputDelimiterRight = options.outputDelimiterRight;
+ var value = input.slice(begin + outputDelimiterLeft.length, end - outputDelimiterRight.length);
+ _this = _super.call(this, TokenKind.Output, value, input, begin, end, trimOutputLeft, trimOutputRight, file) || this;
+ return _this;
+ }
+ return OutputToken;
+ }(DelimitedToken));
+
+ var trie = {
+ a: { n: { d: { end: true, needBoundary: true } } },
+ o: { r: { end: true, needBoundary: true } },
+ c: { o: { n: { t: { a: { i: { n: { s: { end: true, needBoundary: true } } } } } } } },
+ '=': { '=': { end: true } },
+ '!': { '=': { end: true } },
+ '>': { end: true, '=': { end: true } },
+ '<': { end: true, '=': { end: true } }
+ };
+ function matchOperator(str, begin, end) {
+ if (end === void 0) { end = str.length; }
+ var node = trie;
+ var i = begin;
+ var info;
+ while (node[str[i]] && i < end) {
+ node = node[str[i++]];
+ if (node['end'])
+ info = node;
+ }
+ if (!info)
+ return -1;
+ if (info['needBoundary'] && str.charCodeAt(i) & VARIABLE)
+ return -1;
+ return i;
+ }
+
+ var Tokenizer = /** @class */ (function () {
+ function Tokenizer(input, file) {
+ if (file === void 0) { file = ''; }
+ this.input = input;
+ this.file = file;
+ this.p = 0;
+ this.N = input.length;
+ }
+ Tokenizer.prototype.readExpression = function () {
+ var operand, operator, operand_1;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ operand = this.readValue();
+ if (!operand)
+ return [2 /*return*/];
+ return [4 /*yield*/, operand];
+ case 1:
+ _a.sent();
+ _a.label = 2;
+ case 2:
+ if (!(this.p < this.N)) return [3 /*break*/, 5];
+ operator = this.readOperator();
+ if (!operator)
+ return [2 /*return*/];
+ operand_1 = this.readValue();
+ if (!operand_1)
+ return [2 /*return*/];
+ return [4 /*yield*/, operator];
+ case 3:
+ _a.sent();
+ return [4 /*yield*/, operand_1];
+ case 4:
+ _a.sent();
+ return [3 /*break*/, 2];
+ case 5: return [2 /*return*/];
+ }
+ });
+ };
+ Tokenizer.prototype.readOperator = function () {
+ this.skipBlank();
+ var end = matchOperator(this.input, this.p, this.p + 8);
+ if (end === -1)
+ return;
+ return new OperatorToken(this.input, this.p, (this.p = end), this.file);
+ };
+ Tokenizer.prototype.readFilters = function () {
+ var filters = [];
+ while (true) {
+ var filter = this.readFilter();
+ if (!filter)
+ return filters;
+ filters.push(filter);
+ }
+ };
+ Tokenizer.prototype.readFilter = function () {
+ var _this = this;
+ this.skipBlank();
+ if (this.end())
+ return null;
+ assert(this.peek() === '|', function () { return "unexpected token at " + _this.snapshot(); });
+ this.p++;
+ var begin = this.p;
+ var name = this.readWord();
+ if (!name.size())
+ return null;
+ var args = [];
+ this.skipBlank();
+ if (this.peek() === ':') {
+ do {
+ ++this.p;
+ var arg = this.readFilterArg();
+ arg && args.push(arg);
+ while (this.p < this.N && this.peek() !== ',' && this.peek() !== '|')
+ ++this.p;
+ } while (this.peek() === ',');
+ }
+ return new FilterToken(name.getText(), args, this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.readFilterArg = function () {
+ var key = this.readValue();
+ if (!key)
+ return;
+ this.skipBlank();
+ if (this.peek() !== ':')
+ return key;
+ ++this.p;
+ var value = this.readValue();
+ return [key.getText(), value];
+ };
+ Tokenizer.prototype.readTopLevelTokens = function (options) {
+ if (options === void 0) { options = defaultOptions; }
+ var tokens = [];
+ while (this.p < this.N) {
+ var token = this.readTopLevelToken(options);
+ tokens.push(token);
+ }
+ whiteSpaceCtrl(tokens, options);
+ return tokens;
+ };
+ Tokenizer.prototype.readTopLevelToken = function (options) {
+ var tagDelimiterLeft = options.tagDelimiterLeft, outputDelimiterLeft = options.outputDelimiterLeft;
+ if (this.matchWord(tagDelimiterLeft))
+ return this.readTagToken(options);
+ if (this.matchWord(outputDelimiterLeft))
+ return this.readOutputToken(options);
+ return this.readHTMLToken(options);
+ };
+ Tokenizer.prototype.readHTMLToken = function (options) {
+ var begin = this.p;
+ while (this.p < this.N) {
+ var tagDelimiterLeft = options.tagDelimiterLeft, outputDelimiterLeft = options.outputDelimiterLeft;
+ if (this.matchWord(tagDelimiterLeft))
+ break;
+ if (this.matchWord(outputDelimiterLeft))
+ break;
+ ++this.p;
+ }
+ return new HTMLToken(this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.readTagToken = function (options) {
+ var _a = this, file = _a.file, input = _a.input;
+ var tagDelimiterRight = options.tagDelimiterRight;
+ var begin = this.p;
+ if (this.readTo(tagDelimiterRight) === -1) {
+ this.mkError("tag " + this.snapshot(begin) + " not closed", begin);
+ }
+ return new TagToken(input, begin, this.p, options, file);
+ };
+ Tokenizer.prototype.readOutputToken = function (options) {
+ var _a = this, file = _a.file, input = _a.input;
+ var outputDelimiterRight = options.outputDelimiterRight;
+ var begin = this.p;
+ if (this.readTo(outputDelimiterRight) === -1) {
+ this.mkError("output " + this.snapshot(begin) + " not closed", begin);
+ }
+ return new OutputToken(input, begin, this.p, options, file);
+ };
+ Tokenizer.prototype.mkError = function (msg, begin) {
+ throw new TokenizationError(msg, new WordToken(this.input, begin, this.N, this.file));
+ };
+ Tokenizer.prototype.snapshot = function (begin) {
+ if (begin === void 0) { begin = this.p; }
+ return JSON.stringify(ellipsis(this.input.slice(begin), 16));
+ };
+ Tokenizer.prototype.readWord = function () {
+ this.skipBlank();
+ var begin = this.p;
+ while (this.peekType() & VARIABLE)
+ ++this.p;
+ return new WordToken(this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.readHashes = function () {
+ var hashes = [];
+ while (true) {
+ var hash = this.readHash();
+ if (!hash)
+ return hashes;
+ hashes.push(hash);
+ }
+ };
+ Tokenizer.prototype.readHash = function () {
+ this.skipBlank();
+ if (this.peek() === ',')
+ ++this.p;
+ var begin = this.p;
+ var name = this.readWord();
+ if (!name.size())
+ return;
+ var value;
+ this.skipBlank();
+ if (this.peek() === ':') {
+ ++this.p;
+ value = this.readValue();
+ }
+ return new HashToken(this.input, begin, this.p, name, value, this.file);
+ };
+ Tokenizer.prototype.remaining = function () {
+ return this.input.slice(this.p);
+ };
+ Tokenizer.prototype.advance = function (i) {
+ if (i === void 0) { i = 1; }
+ this.p += i;
+ };
+ Tokenizer.prototype.end = function () {
+ return this.p >= this.N;
+ };
+ Tokenizer.prototype.readTo = function (end) {
+ while (this.p < this.N) {
+ ++this.p;
+ if (this.reverseMatchWord(end))
+ return this.p;
+ }
+ return -1;
+ };
+ Tokenizer.prototype.readValue = function () {
+ var value = this.readQuoted() || this.readRange();
+ if (value)
+ return value;
+ var variable = this.readWord();
+ if (!variable.size())
+ return;
+ var isNumber = variable.isNumber(true);
+ var props = [];
+ while (true) {
+ if (this.peek() === '[') {
+ isNumber = false;
+ this.p++;
+ var prop = this.readValue() || new WordToken(this.input, this.p, this.p, this.file);
+ this.readTo(']');
+ props.push(prop);
+ }
+ else if (this.peek() === '.' && this.peek(1) !== '.') { // skip range syntax
+ this.p++;
+ var prop = this.readWord();
+ if (!prop.size())
+ break;
+ if (!prop.isNumber())
+ isNumber = false;
+ props.push(prop);
+ }
+ else
+ break;
+ }
+ if (!props.length && literalValues.hasOwnProperty(variable.content)) {
+ return new LiteralToken(this.input, variable.begin, variable.end, this.file);
+ }
+ if (isNumber)
+ return new NumberToken(variable, props[0]);
+ return new PropertyAccessToken(variable, props, this.p);
+ };
+ Tokenizer.prototype.readRange = function () {
+ this.skipBlank();
+ var begin = this.p;
+ if (this.peek() !== '(')
+ return;
+ ++this.p;
+ var lhs = this.readValueOrThrow();
+ this.p += 2;
+ var rhs = this.readValueOrThrow();
+ ++this.p;
+ return new RangeToken(this.input, begin, this.p, lhs, rhs, this.file);
+ };
+ Tokenizer.prototype.readValueOrThrow = function () {
+ var _this = this;
+ var value = this.readValue();
+ assert(value, function () { return "unexpected token " + _this.snapshot() + ", value expected"; });
+ return value;
+ };
+ Tokenizer.prototype.readQuoted = function () {
+ this.skipBlank();
+ var begin = this.p;
+ if (!(this.peekType() & QUOTE))
+ return;
+ ++this.p;
+ var escaped = false;
+ while (this.p < this.N) {
+ ++this.p;
+ if (this.input[this.p - 1] === this.input[begin] && !escaped)
+ break;
+ if (escaped)
+ escaped = false;
+ else if (this.input[this.p - 1] === '\\')
+ escaped = true;
+ }
+ return new QuotedToken(this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.readFileName = function () {
+ var begin = this.p;
+ while (!(this.peekType() & BLANK) && this.peek() !== ',' && this.p < this.N)
+ this.p++;
+ return new WordToken(this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.matchWord = function (word) {
+ for (var i = 0; i < word.length; i++) {
+ if (word[i] !== this.input[this.p + i])
+ return false;
+ }
+ return true;
+ };
+ Tokenizer.prototype.reverseMatchWord = function (word) {
+ for (var i = 0; i < word.length; i++) {
+ if (word[word.length - 1 - i] !== this.input[this.p - 1 - i])
+ return false;
+ }
+ return true;
+ };
+ Tokenizer.prototype.peekType = function (n) {
+ if (n === void 0) { n = 0; }
+ return TYPES[this.input.charCodeAt(this.p + n)];
+ };
+ Tokenizer.prototype.peek = function (n) {
+ if (n === void 0) { n = 0; }
+ return this.input[this.p + n];
+ };
+ Tokenizer.prototype.skipBlank = function () {
+ while (this.peekType() & BLANK)
+ ++this.p;
+ };
+ return Tokenizer;
+ }());
+
+ var Emitter = /** @class */ (function () {
+ function Emitter() {
+ this.html = '';
+ this.break = false;
+ this.continue = false;
+ }
+ Emitter.prototype.write = function (html) {
+ this.html += html;
+ };
+ return Emitter;
+ }());
+
+ var Render = /** @class */ (function () {
+ function Render() {
+ }
+ Render.prototype.renderTemplates = function (templates, ctx, emitter) {
+ var templates_1, templates_1_1, tpl, html, e_1, err, e_2_1;
+ var e_2, _a;
+ if (emitter === void 0) { emitter = new Emitter(); }
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ _b.trys.push([0, 7, 8, 9]);
+ templates_1 = __values(templates), templates_1_1 = templates_1.next();
+ _b.label = 1;
+ case 1:
+ if (!!templates_1_1.done) return [3 /*break*/, 6];
+ tpl = templates_1_1.value;
+ _b.label = 2;
+ case 2:
+ _b.trys.push([2, 4, , 5]);
+ return [4 /*yield*/, tpl.render(ctx, emitter)];
+ case 3:
+ html = _b.sent();
+ html && emitter.write(html);
+ if (emitter.break || emitter.continue)
+ return [3 /*break*/, 6];
+ return [3 /*break*/, 5];
+ case 4:
+ e_1 = _b.sent();
+ err = RenderError.is(e_1) ? e_1 : new RenderError(e_1, tpl);
+ throw err;
+ case 5:
+ templates_1_1 = templates_1.next();
+ return [3 /*break*/, 1];
+ case 6: return [3 /*break*/, 9];
+ case 7:
+ e_2_1 = _b.sent();
+ e_2 = { error: e_2_1 };
+ return [3 /*break*/, 9];
+ case 8:
+ try {
+ if (templates_1_1 && !templates_1_1.done && (_a = templates_1.return)) _a.call(templates_1);
+ }
+ finally { if (e_2) throw e_2.error; }
+ return [7 /*endfinally*/];
+ case 9: return [2 /*return*/, emitter.html];
+ }
+ });
+ };
+ return Render;
+ }());
+
+ var ParseStream = /** @class */ (function () {
+ function ParseStream(tokens, parseToken) {
+ this.handlers = {};
+ this.stopRequested = false;
+ this.tokens = tokens;
+ this.parseToken = parseToken;
+ }
+ ParseStream.prototype.on = function (name, cb) {
+ this.handlers[name] = cb;
+ return this;
+ };
+ ParseStream.prototype.trigger = function (event, arg) {
+ var h = this.handlers[event];
+ return h ? (h(arg), true) : false;
+ };
+ ParseStream.prototype.start = function () {
+ this.trigger('start');
+ var token;
+ while (!this.stopRequested && (token = this.tokens.shift())) {
+ if (this.trigger('token', token))
+ continue;
+ if (isTagToken(token) && this.trigger("tag:" + token.name, token)) {
+ continue;
+ }
+ var template = this.parseToken(token, this.tokens);
+ this.trigger('template', template);
+ }
+ if (!this.stopRequested)
+ this.trigger('end');
+ return this;
+ };
+ ParseStream.prototype.stop = function () {
+ this.stopRequested = true;
+ return this;
+ };
+ return ParseStream;
+ }());
+
+ var TemplateImpl = /** @class */ (function () {
+ function TemplateImpl(token) {
+ this.token = token;
+ }
+ return TemplateImpl;
+ }());
+
+ var rHex = /[\da-fA-F]/;
+ var rOct = /[0-7]/;
+ var escapeChar = {
+ b: '\b',
+ f: '\f',
+ n: '\n',
+ r: '\r',
+ t: '\t',
+ v: '\x0B'
+ };
+ function hexVal(c) {
+ var code = c.charCodeAt(0);
+ if (code >= 97)
+ return code - 87;
+ if (code >= 65)
+ return code - 55;
+ return code - 48;
+ }
+ function parseStringLiteral(str) {
+ var ret = '';
+ for (var i = 1; i < str.length - 1; i++) {
+ if (str[i] !== '\\') {
+ ret += str[i];
+ continue;
+ }
+ if (escapeChar[str[i + 1]] !== undefined) {
+ ret += escapeChar[str[++i]];
+ }
+ else if (str[i + 1] === 'u') {
+ var val = 0;
+ var j = i + 2;
+ while (j <= i + 5 && rHex.test(str[j])) {
+ val = val * 16 + hexVal(str[j++]);
+ }
+ i = j - 1;
+ ret += String.fromCharCode(val);
+ }
+ else if (!rOct.test(str[i + 1])) {
+ ret += str[++i];
+ }
+ else {
+ var j = i + 1;
+ var val = 0;
+ while (j <= i + 3 && rOct.test(str[j])) {
+ val = val * 8 + hexVal(str[j++]);
+ }
+ i = j - 1;
+ ret += String.fromCharCode(val);
+ }
+ }
+ return ret;
+ }
+
+ function isComparable(arg) {
+ return arg && isFunction(arg.equals);
+ }
+
+ function isTruthy(val) {
+ return !isFalsy(val);
+ }
+ function isFalsy(val) {
+ return val === false || undefined === val || val === null;
+ }
+
+ var operatorImpls = {
+ '==': function (l, r) {
+ if (isComparable(l))
+ return l.equals(r);
+ if (isComparable(r))
+ return r.equals(l);
+ return l === r;
+ },
+ '!=': function (l, r) {
+ if (isComparable(l))
+ return !l.equals(r);
+ if (isComparable(r))
+ return !r.equals(l);
+ return l !== r;
+ },
+ '>': function (l, r) {
+ if (isComparable(l))
+ return l.gt(r);
+ if (isComparable(r))
+ return r.lt(l);
+ return l > r;
+ },
+ '<': function (l, r) {
+ if (isComparable(l))
+ return l.lt(r);
+ if (isComparable(r))
+ return r.gt(l);
+ return l < r;
+ },
+ '>=': function (l, r) {
+ if (isComparable(l))
+ return l.geq(r);
+ if (isComparable(r))
+ return r.leq(l);
+ return l >= r;
+ },
+ '<=': function (l, r) {
+ if (isComparable(l))
+ return l.leq(r);
+ if (isComparable(r))
+ return r.geq(l);
+ return l <= r;
+ },
+ 'contains': function (l, r) {
+ return l && isFunction(l.indexOf) ? l.indexOf(r) > -1 : false;
+ },
+ 'and': function (l, r) { return isTruthy(l) && isTruthy(r); },
+ 'or': function (l, r) { return isTruthy(l) || isTruthy(r); }
+ };
+
+ var Expression = /** @class */ (function () {
+ function Expression(str) {
+ this.operands = [];
+ var tokenizer = new Tokenizer(str);
+ this.postfix = toPostfix(tokenizer.readExpression());
+ }
+ Expression.prototype.evaluate = function (ctx) {
+ var e_1, _a;
+ try {
+ for (var _b = __values(this.postfix), _c = _b.next(); !_c.done; _c = _b.next()) {
+ var token = _c.value;
+ if (isOperatorToken(token)) {
+ var r = this.operands.pop();
+ var l = this.operands.pop();
+ var result = evalOperatorToken(token, l, r);
+ this.operands.push(result);
+ }
+ else {
+ this.operands.push(evalToken(token, ctx));
+ }
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ return this.operands[0];
+ };
+ Expression.prototype.value = function (ctx) {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toValue(this.evaluate(ctx))];
+ });
+ };
+ return Expression;
+ }());
+ function evalToken(token, ctx) {
+ assert(ctx, function () { return 'unable to evaluate: context not defined'; });
+ if (isPropertyAccessToken(token)) {
+ var variable = token.variable.getText();
+ var props = token.props.map(function (prop) { return evalToken(prop, ctx); });
+ return ctx.get(__spread([variable], props));
+ }
+ if (isRangeToken(token))
+ return evalRangeToken(token, ctx);
+ if (isLiteralToken(token))
+ return evalLiteralToken(token);
+ if (isNumberToken(token))
+ return evalNumberToken(token);
+ if (isWordToken(token))
+ return token.getText();
+ if (isQuotedToken(token))
+ return evalQuotedToken(token);
+ }
+ function evalNumberToken(token) {
+ var str = token.whole.content + '.' + (token.decimal ? token.decimal.content : '');
+ return Number(str);
+ }
+ function evalQuotedToken(token) {
+ return parseStringLiteral(token.getText());
+ }
+ function evalOperatorToken(token, lhs, rhs) {
+ var impl = operatorImpls[token.operator];
+ return impl(lhs, rhs);
+ }
+ function evalLiteralToken(token) {
+ return literalValues[token.literal];
+ }
+ function evalRangeToken(token, ctx) {
+ var low = evalToken(token.lhs, ctx);
+ var high = evalToken(token.rhs, ctx);
+ return range(+low, +high + 1);
+ }
+ function toPostfix(tokens) {
+ var ops, tokens_1, tokens_1_1, token, e_2_1;
+ var e_2, _a;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ ops = [];
+ _b.label = 1;
+ case 1:
+ _b.trys.push([1, 10, 11, 12]);
+ tokens_1 = __values(tokens), tokens_1_1 = tokens_1.next();
+ _b.label = 2;
+ case 2:
+ if (!!tokens_1_1.done) return [3 /*break*/, 9];
+ token = tokens_1_1.value;
+ if (!isOperatorToken(token)) return [3 /*break*/, 6];
+ _b.label = 3;
+ case 3:
+ if (!(ops.length && ops[ops.length - 1].getPrecedence() > token.getPrecedence())) return [3 /*break*/, 5];
+ return [4 /*yield*/, ops.pop()];
+ case 4:
+ _b.sent();
+ return [3 /*break*/, 3];
+ case 5:
+ ops.push(token);
+ return [3 /*break*/, 8];
+ case 6: return [4 /*yield*/, token];
+ case 7:
+ _b.sent();
+ _b.label = 8;
+ case 8:
+ tokens_1_1 = tokens_1.next();
+ return [3 /*break*/, 2];
+ case 9: return [3 /*break*/, 12];
+ case 10:
+ e_2_1 = _b.sent();
+ e_2 = { error: e_2_1 };
+ return [3 /*break*/, 12];
+ case 11:
+ try {
+ if (tokens_1_1 && !tokens_1_1.done && (_a = tokens_1.return)) _a.call(tokens_1);
+ }
+ finally { if (e_2) throw e_2.error; }
+ return [7 /*endfinally*/];
+ case 12:
+ if (!ops.length) return [3 /*break*/, 14];
+ return [4 /*yield*/, ops.pop()];
+ case 13:
+ _b.sent();
+ return [3 /*break*/, 12];
+ case 14: return [2 /*return*/];
+ }
+ });
+ }
+
+ /**
+ * Key-Value Pairs Representing Tag Arguments
+ * Example:
+ * For the markup `, foo:'bar', coo:2 reversed %}`,
+ * hash['foo'] === 'bar'
+ * hash['coo'] === 2
+ * hash['reversed'] === undefined
+ */
+ var Hash = /** @class */ (function () {
+ function Hash(markup) {
+ var e_1, _a;
+ this.hash = {};
+ var tokenizer = new Tokenizer(markup);
+ try {
+ for (var _b = __values(tokenizer.readHashes()), _c = _b.next(); !_c.done; _c = _b.next()) {
+ var hash = _c.value;
+ this.hash[hash.name.content] = hash.value;
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ }
+ Hash.prototype.render = function (ctx) {
+ var hash, _a, _b, key;
+ var e_2, _c;
+ return __generator(this, function (_d) {
+ hash = {};
+ try {
+ for (_a = __values(Object.keys(this.hash)), _b = _a.next(); !_b.done; _b = _a.next()) {
+ key = _b.value;
+ hash[key] = evalToken(this.hash[key], ctx);
+ }
+ }
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
+ finally {
+ try {
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
+ }
+ finally { if (e_2) throw e_2.error; }
+ }
+ return [2 /*return*/, hash];
+ });
+ };
+ return Hash;
+ }());
+
+ var Tag = /** @class */ (function (_super) {
+ __extends(Tag, _super);
+ function Tag(token, tokens, liquid) {
+ var _this = _super.call(this, token) || this;
+ _this.name = token.name;
+ var impl = liquid.tags.get(token.name);
+ _this.impl = Object.create(impl);
+ _this.impl.liquid = liquid;
+ if (_this.impl.parse) {
+ _this.impl.parse(token, tokens);
+ }
+ return _this;
+ }
+ Tag.prototype.render = function (ctx, emitter) {
+ var hash, impl;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, new Hash(this.token.args).render(ctx)];
+ case 1:
+ hash = _a.sent();
+ impl = this.impl;
+ if (!isFunction(impl.render)) return [3 /*break*/, 3];
+ return [4 /*yield*/, impl.render(ctx, emitter, hash)];
+ case 2: return [2 /*return*/, _a.sent()];
+ case 3: return [2 /*return*/];
+ }
+ });
+ };
+ Tag.impls = {};
+ return Tag;
+ }(TemplateImpl));
+
+ function isKeyValuePair(arr) {
+ return isArray(arr);
+ }
+
+ var Filter = /** @class */ (function () {
+ function Filter(name, impl, args) {
+ this.name = name;
+ this.impl = impl || identify;
+ this.args = args;
+ }
+ Filter.prototype.render = function (value, context) {
+ var argv, _a, _b, arg, _c, _d, _e, _f, _g, e_1_1;
+ var e_1, _h;
+ return __generator(this, function (_j) {
+ switch (_j.label) {
+ case 0:
+ argv = [];
+ _j.label = 1;
+ case 1:
+ _j.trys.push([1, 8, 9, 10]);
+ _a = __values(this.args), _b = _a.next();
+ _j.label = 2;
+ case 2:
+ if (!!_b.done) return [3 /*break*/, 7];
+ arg = _b.value;
+ if (!isKeyValuePair(arg)) return [3 /*break*/, 4];
+ _d = (_c = argv).push;
+ _e = [arg[0]];
+ return [4 /*yield*/, evalToken(arg[1], context)];
+ case 3:
+ _d.apply(_c, [_e.concat([_j.sent()])]);
+ return [3 /*break*/, 6];
+ case 4:
+ _g = (_f = argv).push;
+ return [4 /*yield*/, evalToken(arg, context)];
+ case 5:
+ _g.apply(_f, [_j.sent()]);
+ _j.label = 6;
+ case 6:
+ _b = _a.next();
+ return [3 /*break*/, 2];
+ case 7: return [3 /*break*/, 10];
+ case 8:
+ e_1_1 = _j.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 10];
+ case 9:
+ try {
+ if (_b && !_b.done && (_h = _a.return)) _h.call(_a);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 10: return [2 /*return*/, this.impl.apply({ context: context }, __spread([value], argv))];
+ }
+ });
+ };
+ return Filter;
+ }());
+
+ var Value = /** @class */ (function () {
+ /**
+ * @param str the value to be valuated, eg.: "foobar" | truncate: 3
+ */
+ function Value(str, filterMap) {
+ var _this = this;
+ this.filterMap = filterMap;
+ this.filters = [];
+ var tokenizer = new Tokenizer(str);
+ this.initial = tokenizer.readValue();
+ this.filters = tokenizer.readFilters().map(function (_a) {
+ var name = _a.name, args = _a.args;
+ return new Filter(name, _this.filterMap.get(name), args);
+ });
+ }
+ Value.prototype.value = function (ctx) {
+ var val, _a, _b, filter, e_1_1;
+ var e_1, _c;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0: return [4 /*yield*/, evalToken(this.initial, ctx)];
+ case 1:
+ val = _d.sent();
+ _d.label = 2;
+ case 2:
+ _d.trys.push([2, 7, 8, 9]);
+ _a = __values(this.filters), _b = _a.next();
+ _d.label = 3;
+ case 3:
+ if (!!_b.done) return [3 /*break*/, 6];
+ filter = _b.value;
+ return [4 /*yield*/, filter.render(val, ctx)];
+ case 4:
+ val = _d.sent();
+ _d.label = 5;
+ case 5:
+ _b = _a.next();
+ return [3 /*break*/, 3];
+ case 6: return [3 /*break*/, 9];
+ case 7:
+ e_1_1 = _d.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 9];
+ case 8:
+ try {
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 9: return [2 /*return*/, val];
+ }
+ });
+ };
+ return Value;
+ }());
+
+ var Output = /** @class */ (function (_super) {
+ __extends(Output, _super);
+ function Output(token, filters) {
+ var _this = _super.call(this, token) || this;
+ _this.value = new Value(token.content, filters);
+ return _this;
+ }
+ Output.prototype.render = function (ctx, emitter) {
+ var val;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, this.value.value(ctx)];
+ case 1:
+ val = _a.sent();
+ emitter.write(stringify(toValue(val)));
+ return [2 /*return*/];
+ }
+ });
+ };
+ return Output;
+ }(TemplateImpl));
+
+ var HTML = /** @class */ (function (_super) {
+ __extends(HTML, _super);
+ function HTML(token) {
+ var _this = _super.call(this, token) || this;
+ _this.str = token.getContent();
+ return _this;
+ }
+ HTML.prototype.render = function (ctx, emitter) {
+ return __generator(this, function (_a) {
+ emitter.write(this.str);
+ return [2 /*return*/];
+ });
+ };
+ return HTML;
+ }(TemplateImpl));
+
+ var Parser = /** @class */ (function () {
+ function Parser(liquid) {
+ this.liquid = liquid;
+ }
+ Parser.prototype.parse = function (tokens) {
+ var token;
+ var templates = [];
+ while ((token = tokens.shift())) {
+ templates.push(this.parseToken(token, tokens));
+ }
+ return templates;
+ };
+ Parser.prototype.parseToken = function (token, remainTokens) {
+ try {
+ if (isTagToken(token)) {
+ return new Tag(token, remainTokens, this.liquid);
+ }
+ if (isOutputToken(token)) {
+ return new Output(token, this.liquid.filters);
+ }
+ return new HTML(token);
+ }
+ catch (e) {
+ throw new ParseError(e, token);
+ }
+ };
+ Parser.prototype.parseStream = function (tokens) {
+ var _this = this;
+ return new ParseStream(tokens, function (token, tokens) { return _this.parseToken(token, tokens); });
+ };
+ return Parser;
+ }());
+
+ var assign = {
+ parse: function (token) {
+ var tokenizer = new Tokenizer(token.args);
+ this.key = tokenizer.readWord().content;
+ tokenizer.skipBlank();
+ assert(tokenizer.peek() === '=', function () { return "illegal token " + token.getText(); });
+ tokenizer.advance();
+ this.value = tokenizer.remaining();
+ },
+ render: function (ctx) {
+ var _a, _b;
+ return __generator(this, function (_c) {
+ switch (_c.label) {
+ case 0:
+ _a = ctx.bottom();
+ _b = this.key;
+ return [4 /*yield*/, this.liquid._evalValue(this.value, ctx)];
+ case 1:
+ _a[_b] = _c.sent();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ function toEnumerable(val) {
+ if (isArray(val))
+ return val;
+ if (isString(val) && val.length > 0)
+ return [val];
+ if (isObject(val))
+ return Object.keys(val).map(function (key) { return [key, val[key]]; });
+ return [];
+ }
+ function toArray(val) {
+ if (isArray(val))
+ return val;
+ return [val];
+ }
+
+ var ForloopDrop = /** @class */ (function (_super) {
+ __extends(ForloopDrop, _super);
+ function ForloopDrop(length) {
+ var _this = _super.call(this) || this;
+ _this.i = 0;
+ _this.length = length;
+ return _this;
+ }
+ ForloopDrop.prototype.next = function () {
+ this.i++;
+ };
+ ForloopDrop.prototype.index0 = function () {
+ return this.i;
+ };
+ ForloopDrop.prototype.index = function () {
+ return this.i + 1;
+ };
+ ForloopDrop.prototype.first = function () {
+ return this.i === 0;
+ };
+ ForloopDrop.prototype.last = function () {
+ return this.i === this.length - 1;
+ };
+ ForloopDrop.prototype.rindex = function () {
+ return this.length - this.i;
+ };
+ ForloopDrop.prototype.rindex0 = function () {
+ return this.length - this.i - 1;
+ };
+ ForloopDrop.prototype.valueOf = function () {
+ return JSON.stringify(this);
+ };
+ return ForloopDrop;
+ }(Drop));
+
+ var For = {
+ type: 'block',
+ parse: function (token, remainTokens) {
+ var _this = this;
+ var toknenizer = new Tokenizer(token.args);
+ var variable = toknenizer.readWord();
+ var inStr = toknenizer.readWord();
+ var collection = toknenizer.readValue();
+ assert(variable.size() && inStr.content === 'in' && collection, function () { return "illegal tag: " + token.getText(); });
+ this.variable = variable.content;
+ this.collection = collection;
+ this.hash = new Hash(toknenizer.remaining());
+ this.templates = [];
+ this.elseTemplates = [];
+ var p;
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('start', function () { return (p = _this.templates); })
+ .on('tag:else', function () { return (p = _this.elseTemplates); })
+ .on('tag:endfor', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + token.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var r, collection, hash, offset, limit, scope, collection_1, collection_1_1, item, e_1_1;
+ var e_1, _a;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ r = this.liquid.renderer;
+ collection = toEnumerable(evalToken(this.collection, ctx));
+ if (!!collection.length) return [3 /*break*/, 2];
+ return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
+ case 1:
+ _b.sent();
+ return [2 /*return*/];
+ case 2: return [4 /*yield*/, this.hash.render(ctx)];
+ case 3:
+ hash = _b.sent();
+ offset = hash.offset || 0;
+ limit = (hash.limit === undefined) ? collection.length : hash.limit;
+ collection = collection.slice(offset, offset + limit);
+ if ('reversed' in hash)
+ collection.reverse();
+ scope = { forloop: new ForloopDrop(collection.length) };
+ ctx.push(scope);
+ _b.label = 4;
+ case 4:
+ _b.trys.push([4, 9, 10, 11]);
+ collection_1 = __values(collection), collection_1_1 = collection_1.next();
+ _b.label = 5;
+ case 5:
+ if (!!collection_1_1.done) return [3 /*break*/, 8];
+ item = collection_1_1.value;
+ scope[this.variable] = item;
+ return [4 /*yield*/, r.renderTemplates(this.templates, ctx, emitter)];
+ case 6:
+ _b.sent();
+ if (emitter.break) {
+ emitter.break = false;
+ return [3 /*break*/, 8];
+ }
+ emitter.continue = false;
+ scope.forloop.next();
+ _b.label = 7;
+ case 7:
+ collection_1_1 = collection_1.next();
+ return [3 /*break*/, 5];
+ case 8: return [3 /*break*/, 11];
+ case 9:
+ e_1_1 = _b.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 11];
+ case 10:
+ try {
+ if (collection_1_1 && !collection_1_1.done && (_a = collection_1.return)) _a.call(collection_1);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 11:
+ ctx.pop();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var capture = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ var tokenizer = new Tokenizer(tagToken.args);
+ this.variable = tokenizer.readWord().content;
+ assert(this.variable, function () { return tagToken.args + " not valid identifier"; });
+ this.templates = [];
+ var stream = this.liquid.parser.parseStream(remainTokens);
+ stream.on('tag:endcapture', function () { return stream.stop(); })
+ .on('template', function (tpl) { return _this.templates.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx) {
+ var r, html;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ r = this.liquid.renderer;
+ return [4 /*yield*/, r.renderTemplates(this.templates, ctx)];
+ case 1:
+ html = _a.sent();
+ ctx.bottom()[this.variable] = html;
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var Case = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ this.cond = tagToken.args;
+ this.cases = [];
+ this.elseTemplates = [];
+ var p = [];
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('tag:when', function (token) {
+ _this.cases.push({
+ val: token.args,
+ templates: p = []
+ });
+ })
+ .on('tag:else', function () { return (p = _this.elseTemplates); })
+ .on('tag:endcase', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var r, cond, i, branch, val;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ r = this.liquid.renderer;
+ return [4 /*yield*/, new Expression(this.cond).value(ctx)];
+ case 1:
+ cond = _a.sent();
+ i = 0;
+ _a.label = 2;
+ case 2:
+ if (!(i < this.cases.length)) return [3 /*break*/, 6];
+ branch = this.cases[i];
+ return [4 /*yield*/, new Expression(branch.val).value(ctx)];
+ case 3:
+ val = _a.sent();
+ if (!(val === cond)) return [3 /*break*/, 5];
+ return [4 /*yield*/, r.renderTemplates(branch.templates, ctx, emitter)];
+ case 4:
+ _a.sent();
+ return [2 /*return*/];
+ case 5:
+ i++;
+ return [3 /*break*/, 2];
+ case 6: return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
+ case 7:
+ _a.sent();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var comment = {
+ parse: function (tagToken, remainTokens) {
+ var stream = this.liquid.parser.parseStream(remainTokens);
+ stream
+ .on('token', function (token) {
+ if (token.name === 'endcomment')
+ stream.stop();
+ })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ }
+ };
+
+ var BlockMode;
+ (function (BlockMode) {
+ /* store rendered html into blocks */
+ BlockMode[BlockMode["OUTPUT"] = 0] = "OUTPUT";
+ /* output rendered html directly */
+ BlockMode[BlockMode["STORE"] = 1] = "STORE";
+ })(BlockMode || (BlockMode = {}));
+ var BlockMode$1 = BlockMode;
+
+ var include = {
+ parse: function (token) {
+ var args = token.args;
+ var tokenizer = new Tokenizer(args);
+ this.file = this.liquid.options.dynamicPartials
+ ? tokenizer.readValue()
+ : tokenizer.readFileName();
+ assert(this.file, function () { return "illegal argument \"" + token.args + "\""; });
+ var begin = tokenizer.p;
+ var withStr = tokenizer.readWord();
+ if (withStr.content === 'with') {
+ tokenizer.skipBlank();
+ if (tokenizer.peek() !== ':') {
+ this.withVar = tokenizer.readValue();
+ }
+ else
+ tokenizer.p = begin;
+ }
+ else
+ tokenizer.p = begin;
+ this.hash = new Hash(tokenizer.remaining());
+ },
+ render: function (ctx, emitter) {
+ var _a, liquid, hash, withVar, file, renderer, filepath, _b, _c, saved, scope, templates;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0:
+ _a = this, liquid = _a.liquid, hash = _a.hash, withVar = _a.withVar, file = _a.file;
+ renderer = liquid.renderer;
+ if (!ctx.opts.dynamicPartials) return [3 /*break*/, 5];
+ if (!isQuotedToken(file)) return [3 /*break*/, 2];
+ return [4 /*yield*/, renderer.renderTemplates(liquid.parse(evalQuotedToken(file)), ctx)];
+ case 1:
+ _c = _d.sent();
+ return [3 /*break*/, 4];
+ case 2: return [4 /*yield*/, evalToken(file, ctx)];
+ case 3:
+ _c = _d.sent();
+ _d.label = 4;
+ case 4:
+ _b = (_c);
+ return [3 /*break*/, 6];
+ case 5:
+ _b = file.getText();
+ _d.label = 6;
+ case 6:
+ filepath = _b;
+ assert(filepath, function () { return "illegal filename \"" + file.getText() + "\":\"" + filepath + "\""; });
+ saved = ctx.saveRegister('blocks', 'blockMode');
+ ctx.setRegister('blocks', {});
+ ctx.setRegister('blockMode', BlockMode$1.OUTPUT);
+ return [4 /*yield*/, hash.render(ctx)];
+ case 7:
+ scope = _d.sent();
+ if (withVar)
+ scope[filepath] = evalToken(withVar, ctx);
+ return [4 /*yield*/, liquid._parseFile(filepath, ctx.opts, ctx.sync)];
+ case 8:
+ templates = _d.sent();
+ ctx.push(scope);
+ return [4 /*yield*/, renderer.renderTemplates(templates, ctx, emitter)];
+ case 9:
+ _d.sent();
+ ctx.pop();
+ ctx.restoreRegister(saved);
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var render = {
+ parse: function (token) {
+ var args = token.args;
+ var tokenizer = new Tokenizer(args);
+ this.file = this.liquid.options.dynamicPartials
+ ? tokenizer.readValue()
+ : tokenizer.readFileName();
+ assert(this.file, function () { return "illegal argument \"" + token.args + "\""; });
+ while (!tokenizer.end()) {
+ tokenizer.skipBlank();
+ var begin = tokenizer.p;
+ var keyword = tokenizer.readWord();
+ if (keyword.content === 'with' || keyword.content === 'for') {
+ tokenizer.skipBlank();
+ if (tokenizer.peek() !== ':') {
+ var value = tokenizer.readValue();
+ if (value) {
+ var beforeAs = tokenizer.p;
+ var asStr = tokenizer.readWord();
+ var alias = void 0;
+ if (asStr.content === 'as')
+ alias = tokenizer.readWord();
+ else
+ tokenizer.p = beforeAs;
+ this[keyword.content] = { value: value, alias: alias && alias.content };
+ tokenizer.skipBlank();
+ if (tokenizer.peek() === ',')
+ tokenizer.advance();
+ continue;
+ }
+ }
+ }
+ tokenizer.p = begin;
+ break;
+ }
+ this.hash = new Hash(tokenizer.remaining());
+ },
+ render: function (ctx, emitter) {
+ var _a, liquid, file, hash, renderer, filepath, _b, _c, childCtx, scope, _d, value, alias, _e, value, alias, collection, collection_1, collection_1_1, item, templates, e_1_1, templates;
+ var e_1, _f;
+ return __generator(this, function (_g) {
+ switch (_g.label) {
+ case 0:
+ _a = this, liquid = _a.liquid, file = _a.file, hash = _a.hash;
+ renderer = liquid.renderer;
+ if (!ctx.opts.dynamicPartials) return [3 /*break*/, 4];
+ if (!isQuotedToken(file)) return [3 /*break*/, 2];
+ return [4 /*yield*/, renderer.renderTemplates(liquid.parse(evalQuotedToken(file)), ctx)];
+ case 1:
+ _c = _g.sent();
+ return [3 /*break*/, 3];
+ case 2:
+ _c = evalToken(file, ctx);
+ _g.label = 3;
+ case 3:
+ _b = (_c);
+ return [3 /*break*/, 5];
+ case 4:
+ _b = file.getText();
+ _g.label = 5;
+ case 5:
+ filepath = _b;
+ assert(filepath, function () { return "illegal filename \"" + file.getText() + "\":\"" + filepath + "\""; });
+ childCtx = new Context({}, ctx.opts, ctx.sync);
+ return [4 /*yield*/, hash.render(ctx)];
+ case 6:
+ scope = _g.sent();
+ if (this['with']) {
+ _d = this['with'], value = _d.value, alias = _d.alias;
+ scope[alias || filepath] = evalToken(value, ctx);
+ }
+ childCtx.push(scope);
+ if (!this['for']) return [3 /*break*/, 16];
+ _e = this['for'], value = _e.value, alias = _e.alias;
+ collection = evalToken(value, ctx);
+ collection = toEnumerable(collection);
+ scope['forloop'] = new ForloopDrop(collection.length);
+ _g.label = 7;
+ case 7:
+ _g.trys.push([7, 13, 14, 15]);
+ collection_1 = __values(collection), collection_1_1 = collection_1.next();
+ _g.label = 8;
+ case 8:
+ if (!!collection_1_1.done) return [3 /*break*/, 12];
+ item = collection_1_1.value;
+ scope[alias] = item;
+ return [4 /*yield*/, liquid._parseFile(filepath, childCtx.opts, childCtx.sync)];
+ case 9:
+ templates = _g.sent();
+ return [4 /*yield*/, renderer.renderTemplates(templates, childCtx, emitter)];
+ case 10:
+ _g.sent();
+ scope.forloop.next();
+ _g.label = 11;
+ case 11:
+ collection_1_1 = collection_1.next();
+ return [3 /*break*/, 8];
+ case 12: return [3 /*break*/, 15];
+ case 13:
+ e_1_1 = _g.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 15];
+ case 14:
+ try {
+ if (collection_1_1 && !collection_1_1.done && (_f = collection_1.return)) _f.call(collection_1);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 15: return [3 /*break*/, 19];
+ case 16: return [4 /*yield*/, liquid._parseFile(filepath, childCtx.opts, childCtx.sync)];
+ case 17:
+ templates = _g.sent();
+ return [4 /*yield*/, renderer.renderTemplates(templates, childCtx, emitter)];
+ case 18:
+ _g.sent();
+ _g.label = 19;
+ case 19: return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var decrement = {
+ parse: function (token) {
+ var tokenizer = new Tokenizer(token.args);
+ this.variable = tokenizer.readWord().content;
+ },
+ render: function (context, emitter) {
+ var scope = context.environments;
+ if (!isNumber(scope[this.variable])) {
+ scope[this.variable] = 0;
+ }
+ emitter.write(stringify(--scope[this.variable]));
+ }
+ };
+
+ var cycle = {
+ parse: function (tagToken) {
+ var tokenizer = new Tokenizer(tagToken.args);
+ var group = tokenizer.readValue();
+ tokenizer.skipBlank();
+ this.candidates = [];
+ if (group) {
+ if (tokenizer.peek() === ':') {
+ this.group = group;
+ tokenizer.advance();
+ }
+ else
+ this.candidates.push(group);
+ }
+ while (!tokenizer.end()) {
+ var value = tokenizer.readValue();
+ if (value)
+ this.candidates.push(value);
+ tokenizer.readTo(',');
+ }
+ assert(this.candidates.length, function () { return "empty candidates: " + tagToken.getText(); });
+ },
+ render: function (ctx, emitter) {
+ var group = evalToken(this.group, ctx);
+ var fingerprint = "cycle:" + group + ":" + this.candidates.join(',');
+ var groups = ctx.getRegister('cycle');
+ var idx = groups[fingerprint];
+ if (idx === undefined) {
+ idx = groups[fingerprint] = 0;
+ }
+ var candidate = this.candidates[idx];
+ idx = (idx + 1) % this.candidates.length;
+ groups[fingerprint] = idx;
+ var html = evalToken(candidate, ctx);
+ emitter.write(html);
+ }
+ };
+
+ var If = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ this.branches = [];
+ this.elseTemplates = [];
+ var p;
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('start', function () { return _this.branches.push({
+ cond: tagToken.args,
+ templates: (p = [])
+ }); })
+ .on('tag:elsif', function (token) {
+ _this.branches.push({
+ cond: token.args,
+ templates: p = []
+ });
+ })
+ .on('tag:else', function () { return (p = _this.elseTemplates); })
+ .on('tag:endif', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var r, _a, _b, branch, cond, e_1_1;
+ var e_1, _c;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0:
+ r = this.liquid.renderer;
+ _d.label = 1;
+ case 1:
+ _d.trys.push([1, 7, 8, 9]);
+ _a = __values(this.branches), _b = _a.next();
+ _d.label = 2;
+ case 2:
+ if (!!_b.done) return [3 /*break*/, 6];
+ branch = _b.value;
+ return [4 /*yield*/, new Expression(branch.cond).value(ctx)];
+ case 3:
+ cond = _d.sent();
+ if (!isTruthy(cond)) return [3 /*break*/, 5];
+ return [4 /*yield*/, r.renderTemplates(branch.templates, ctx, emitter)];
+ case 4:
+ _d.sent();
+ return [2 /*return*/];
+ case 5:
+ _b = _a.next();
+ return [3 /*break*/, 2];
+ case 6: return [3 /*break*/, 9];
+ case 7:
+ e_1_1 = _d.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 9];
+ case 8:
+ try {
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 9: return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
+ case 10:
+ _d.sent();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var increment = {
+ parse: function (token) {
+ var tokenizer = new Tokenizer(token.args);
+ this.variable = tokenizer.readWord().content;
+ },
+ render: function (context, emitter) {
+ var scope = context.environments;
+ if (!isNumber(scope[this.variable])) {
+ scope[this.variable] = 0;
+ }
+ var val = scope[this.variable];
+ scope[this.variable]++;
+ emitter.write(stringify(val));
+ }
+ };
+
+ var layout = {
+ parse: function (token, remainTokens) {
+ var tokenizer = new Tokenizer(token.args);
+ var file = this.liquid.options.dynamicPartials ? tokenizer.readValue() : tokenizer.readFileName();
+ assert(file, function () { return "illegal argument \"" + token.args + "\""; });
+ this.file = file;
+ this.hash = new Hash(tokenizer.remaining());
+ this.tpls = this.liquid.parser.parse(remainTokens);
+ },
+ render: function (ctx, emitter) {
+ var _a, liquid, hash, file, renderer, filepath, _b, _c, blocks, html, templates, _d, _e, partial;
+ return __generator(this, function (_f) {
+ switch (_f.label) {
+ case 0:
+ _a = this, liquid = _a.liquid, hash = _a.hash, file = _a.file;
+ renderer = liquid.renderer;
+ if (!ctx.opts.dynamicPartials) return [3 /*break*/, 4];
+ if (!isQuotedToken(file)) return [3 /*break*/, 2];
+ return [4 /*yield*/, renderer.renderTemplates(liquid.parse(evalQuotedToken(file)), ctx)];
+ case 1:
+ _c = _f.sent();
+ return [3 /*break*/, 3];
+ case 2:
+ _c = evalToken(this.file, ctx);
+ _f.label = 3;
+ case 3:
+ _b = (_c);
+ return [3 /*break*/, 5];
+ case 4:
+ _b = file.getText();
+ _f.label = 5;
+ case 5:
+ filepath = _b;
+ assert(filepath, function () { return "illegal filename \"" + file.getText() + "\":\"" + filepath + "\""; });
+ // render the remaining tokens immediately
+ ctx.setRegister('blockMode', BlockMode$1.STORE);
+ blocks = ctx.getRegister('blocks');
+ return [4 /*yield*/, renderer.renderTemplates(this.tpls, ctx)];
+ case 6:
+ html = _f.sent();
+ if (blocks[''] === undefined)
+ blocks[''] = html;
+ return [4 /*yield*/, liquid._parseFile(filepath, ctx.opts, ctx.sync)];
+ case 7:
+ templates = _f.sent();
+ _e = (_d = ctx).push;
+ return [4 /*yield*/, hash.render(ctx)];
+ case 8:
+ _e.apply(_d, [_f.sent()]);
+ ctx.setRegister('blockMode', BlockMode$1.OUTPUT);
+ return [4 /*yield*/, renderer.renderTemplates(templates, ctx)];
+ case 9:
+ partial = _f.sent();
+ ctx.pop();
+ emitter.write(partial);
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var block = {
+ parse: function (token, remainTokens) {
+ var _this = this;
+ var match = /\w+/.exec(token.args);
+ this.block = match ? match[0] : '';
+ this.tpls = [];
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('tag:endblock', function () { return stream.stop(); })
+ .on('template', function (tpl) { return _this.tpls.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + token.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var blocks, childDefined, r, html, _a;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ blocks = ctx.getRegister('blocks');
+ childDefined = blocks[this.block];
+ r = this.liquid.renderer;
+ if (!(childDefined !== undefined)) return [3 /*break*/, 1];
+ _a = childDefined;
+ return [3 /*break*/, 3];
+ case 1: return [4 /*yield*/, r.renderTemplates(this.tpls, ctx)];
+ case 2:
+ _a = _b.sent();
+ _b.label = 3;
+ case 3:
+ html = _a;
+ if (ctx.getRegister('blockMode', BlockMode$1.OUTPUT) === BlockMode$1.STORE) {
+ blocks[this.block] = html;
+ return [2 /*return*/];
+ }
+ emitter.write(html);
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var raw = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ this.tokens = [];
+ var stream = this.liquid.parser.parseStream(remainTokens);
+ stream
+ .on('token', function (token) {
+ if (token.name === 'endraw')
+ stream.stop();
+ else
+ _this.tokens.push(token);
+ })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function () {
+ return this.tokens.map(function (token) { return token.getText(); }).join('');
+ }
+ };
+
+ var TablerowloopDrop = /** @class */ (function (_super) {
+ __extends(TablerowloopDrop, _super);
+ function TablerowloopDrop(length, cols) {
+ var _this = _super.call(this, length) || this;
+ _this.length = length;
+ _this.cols = cols;
+ return _this;
+ }
+ TablerowloopDrop.prototype.row = function () {
+ return Math.floor(this.i / this.cols) + 1;
+ };
+ TablerowloopDrop.prototype.col0 = function () {
+ return (this.i % this.cols);
+ };
+ TablerowloopDrop.prototype.col = function () {
+ return this.col0() + 1;
+ };
+ TablerowloopDrop.prototype.col_first = function () {
+ return this.col0() === 0;
+ };
+ TablerowloopDrop.prototype.col_last = function () {
+ return this.col() === this.cols;
+ };
+ return TablerowloopDrop;
+ }(ForloopDrop));
+
+ var tablerow = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ var tokenizer = new Tokenizer(tagToken.args);
+ this.variable = tokenizer.readWord();
+ tokenizer.skipBlank();
+ var tmp = tokenizer.readWord();
+ assert(tmp && tmp.content === 'in', function () { return "illegal tag: " + tagToken.getText(); });
+ this.collection = tokenizer.readValue();
+ this.hash = new Hash(tokenizer.remaining());
+ this.templates = [];
+ var p;
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('start', function () { return (p = _this.templates); })
+ .on('tag:endtablerow', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var collection, hash, offset, limit, cols, r, tablerowloop, scope, idx;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ collection = toEnumerable(evalToken(this.collection, ctx));
+ return [4 /*yield*/, this.hash.render(ctx)];
+ case 1:
+ hash = _a.sent();
+ offset = hash.offset || 0;
+ limit = (hash.limit === undefined) ? collection.length : hash.limit;
+ collection = collection.slice(offset, offset + limit);
+ cols = hash.cols || collection.length;
+ r = this.liquid.renderer;
+ tablerowloop = new TablerowloopDrop(collection.length, cols);
+ scope = { tablerowloop: tablerowloop };
+ ctx.push(scope);
+ idx = 0;
+ _a.label = 2;
+ case 2:
+ if (!(idx < collection.length)) return [3 /*break*/, 5];
+ scope[this.variable.content] = collection[idx];
+ if (tablerowloop.col0() === 0) {
+ if (tablerowloop.row() !== 1)
+ emitter.write('</tr>');
+ emitter.write("<tr class=\"row" + tablerowloop.row() + "\">");
+ }
+ emitter.write("<td class=\"col" + tablerowloop.col() + "\">");
+ return [4 /*yield*/, r.renderTemplates(this.templates, ctx, emitter)];
+ case 3:
+ _a.sent();
+ emitter.write('</td>');
+ _a.label = 4;
+ case 4:
+ idx++, tablerowloop.next();
+ return [3 /*break*/, 2];
+ case 5:
+ if (collection.length)
+ emitter.write('</tr>');
+ ctx.pop();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var unless = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ this.templates = [];
+ this.elseTemplates = [];
+ var p;
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('start', function () {
+ p = _this.templates;
+ _this.cond = tagToken.args;
+ })
+ .on('tag:else', function () { return (p = _this.elseTemplates); })
+ .on('tag:endunless', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var r, cond;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ r = this.liquid.renderer;
+ return [4 /*yield*/, new Expression(this.cond).value(ctx)];
+ case 1:
+ cond = _a.sent();
+ return [4 /*yield*/, (isFalsy(cond)
+ ? r.renderTemplates(this.templates, ctx, emitter)
+ : r.renderTemplates(this.elseTemplates, ctx, emitter))];
+ case 2:
+ _a.sent();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var Break = {
+ render: function (ctx, emitter) {
+ emitter.break = true;
+ }
+ };
+
+ var Continue = {
+ render: function (ctx, emitter) {
+ emitter.continue = true;
+ }
+ };
+
+ var tags = {
+ assign: assign, 'for': For, capture: capture, 'case': Case, comment: comment, include: include, render: render, decrement: decrement, increment: increment, cycle: cycle, 'if': If, layout: layout, block: block, raw: raw, tablerow: tablerow, unless: unless, 'break': Break, 'continue': Continue
+ };
+
+ var escapeMap = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&#34;',
+ "'": '&#39;'
+ };
+ var unescapeMap = {
+ '&amp;': '&',
+ '&lt;': '<',
+ '&gt;': '>',
+ '&#34;': '"',
+ '&#39;': "'"
+ };
+ function escape(str) {
+ return stringify(str).replace(/&|<|>|"|'/g, function (m) { return escapeMap[m]; });
+ }
+ function unescape(str) {
+ return String(str).replace(/&(amp|lt|gt|#34|#39);/g, function (m) { return unescapeMap[m]; });
+ }
+ function escapeOnce(str) {
+ return escape(unescape(str));
+ }
+ function newlineToBr(v) {
+ return v.replace(/\n/g, '<br/>');
+ }
+ function stripHtml(v) {
+ return v.replace(/<script.*?<\/script>|<!--.*?-->|<style.*?<\/style>|<.*?>/g, '');
+ }
+
+ var abs = Math.abs;
+ var atLeast = Math.max;
+ var atMost = Math.min;
+ var ceil = Math.ceil;
+ var dividedBy = function (v, arg) { return v / arg; };
+ var floor = Math.floor;
+ var minus = function (v, arg) { return v - arg; };
+ var modulo = function (v, arg) { return v % arg; };
+ var times = function (v, arg) { return v * arg; };
+ function round(v, arg) {
+ if (arg === void 0) { arg = 0; }
+ var amp = Math.pow(10, arg);
+ return Math.round(v * amp) / amp;
+ }
+ function plus(v, arg) {
+ return Number(v) + Number(arg);
+ }
+ function sortNatural(input, property) {
+ if (!input || !input.sort)
+ return [];
+ if (property !== undefined) {
+ return __spread(input).sort(function (lhs, rhs) { return caseInsensitiveCompare(lhs[property], rhs[property]); });
+ }
+ return __spread(input).sort(caseInsensitiveCompare);
+ }
+
+ var urlDecode = function (x) { return x.split('+').map(decodeURIComponent).join(' '); };
+ var urlEncode = function (x) { return x.split(' ').map(encodeURIComponent).join('+'); };
+
+ var join = function (v, arg) { return v.join(arg === undefined ? ' ' : arg); };
+ var last$1 = function (v) { return isArray(v) ? last(v) : ''; };
+ var first = function (v) { return isArray(v) ? v[0] : ''; };
+ var reverse = function (v) { return __spread(v).reverse(); };
+ var sort = function (v, arg) { return v.sort(arg); };
+ var size = function (v) { return (v && v.length) || 0; };
+ function map(arr, arg) {
+ return toArray(arr).map(function (v) { return v[arg]; });
+ }
+ function concat(v, arg) {
+ return toArray(v).concat(arg);
+ }
+ function slice(v, begin, length) {
+ if (length === void 0) { length = 1; }
+ begin = begin < 0 ? v.length + begin : begin;
+ return v.slice(begin, begin + length);
+ }
+ function where(arr, property, expected) {
+ var _this = this;
+ return toArray(arr).filter(function (obj) {
+ var value = _this.context.getFromScope(obj, String(property).split('.'));
+ return expected === undefined ? isTruthy(value) : value === expected;
+ });
+ }
+ function uniq(arr) {
+ var u = {};
+ return (arr || []).filter(function (val) {
+ if (u.hasOwnProperty(String(val)))
+ return false;
+ u[String(val)] = true;
+ return true;
+ });
+ }
+
+ var rFormat = /%([-_0^#:]+)?(\d+)?([EO])?(.)/;
+ var monthNames = [
+ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
+ 'September', 'October', 'November', 'December'
+ ];
+ var dayNames = [
+ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'
+ ];
+ var monthNamesShort = monthNames.map(abbr);
+ var dayNamesShort = dayNames.map(abbr);
+ var suffixes = {
+ 1: 'st',
+ 2: 'nd',
+ 3: 'rd',
+ 'default': 'th'
+ };
+ function abbr(str) {
+ return str.slice(0, 3);
+ }
+ // prototype extensions
+ function daysInMonth(d) {
+ var feb = isLeapYear(d) ? 29 : 28;
+ return [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+ }
+ function getDayOfYear(d) {
+ var num = 0;
+ for (var i = 0; i < d.getMonth(); ++i) {
+ num += daysInMonth(d)[i];
+ }
+ return num + d.getDate();
+ }
+ function getWeekOfYear(d, startDay) {
+ // Skip to startDay of this week
+ var now = getDayOfYear(d) + (startDay - d.getDay());
+ // Find the first startDay of the year
+ var jan1 = new Date(d.getFullYear(), 0, 1);
+ var then = (7 - jan1.getDay() + startDay);
+ return String(Math.floor((now - then) / 7) + 1);
+ }
+ function isLeapYear(d) {
+ var year = d.getFullYear();
+ return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year)));
+ }
+ function getSuffix(d) {
+ var str = d.getDate().toString();
+ var index = parseInt(str.slice(-1));
+ return suffixes[index] || suffixes['default'];
+ }
+ function century(d) {
+ return parseInt(d.getFullYear().toString().substring(0, 2), 10);
+ }
+ // default to 0
+ var padWidths = {
+ d: 2,
+ e: 2,
+ H: 2,
+ I: 2,
+ j: 3,
+ k: 2,
+ l: 2,
+ L: 3,
+ m: 2,
+ M: 2,
+ S: 2,
+ U: 2,
+ W: 2
+ };
+ // default to '0'
+ var padChars = {
+ a: ' ',
+ A: ' ',
+ b: ' ',
+ B: ' ',
+ c: ' ',
+ e: ' ',
+ k: ' ',
+ l: ' ',
+ p: ' ',
+ P: ' '
+ };
+ var formatCodes = {
+ a: function (d) { return dayNamesShort[d.getDay()]; },
+ A: function (d) { return dayNames[d.getDay()]; },
+ b: function (d) { return monthNamesShort[d.getMonth()]; },
+ B: function (d) { return monthNames[d.getMonth()]; },
+ c: function (d) { return d.toLocaleString(); },
+ C: function (d) { return century(d); },
+ d: function (d) { return d.getDate(); },
+ e: function (d) { return d.getDate(); },
+ H: function (d) { return d.getHours(); },
+ I: function (d) { return String(d.getHours() % 12 || 12); },
+ j: function (d) { return getDayOfYear(d); },
+ k: function (d) { return d.getHours(); },
+ l: function (d) { return String(d.getHours() % 12 || 12); },
+ L: function (d) { return d.getMilliseconds(); },
+ m: function (d) { return d.getMonth() + 1; },
+ M: function (d) { return d.getMinutes(); },
+ N: function (d, opts) {
+ var width = Number(opts.width) || 9;
+ var str = String(d.getMilliseconds()).substr(0, width);
+ return padEnd(str, width, '0');
+ },
+ p: function (d) { return (d.getHours() < 12 ? 'AM' : 'PM'); },
+ P: function (d) { return (d.getHours() < 12 ? 'am' : 'pm'); },
+ q: function (d) { return getSuffix(d); },
+ s: function (d) { return Math.round(d.valueOf() / 1000); },
+ S: function (d) { return d.getSeconds(); },
+ u: function (d) { return d.getDay() || 7; },
+ U: function (d) { return getWeekOfYear(d, 0); },
+ w: function (d) { return d.getDay(); },
+ W: function (d) { return getWeekOfYear(d, 1); },
+ x: function (d) { return d.toLocaleDateString(); },
+ X: function (d) { return d.toLocaleTimeString(); },
+ y: function (d) { return d.getFullYear().toString().substring(2, 4); },
+ Y: function (d) { return d.getFullYear(); },
+ z: function (d, opts) {
+ var offset = d.getTimezoneOffset();
+ var nOffset = Math.abs(offset);
+ var h = Math.floor(nOffset / 60);
+ var m = nOffset % 60;
+ return (offset > 0 ? '-' : '+') +
+ padStart(h, 2, '0') +
+ (opts.flags[':'] ? ':' : '') +
+ padStart(m, 2, '0');
+ },
+ 't': function () { return '\t'; },
+ 'n': function () { return '\n'; },
+ '%': function () { return '%'; }
+ };
+ formatCodes.h = formatCodes.b;
+ function strftime (d, formatStr) {
+ var output = '';
+ var remaining = formatStr;
+ var match;
+ while ((match = rFormat.exec(remaining))) {
+ output += remaining.slice(0, match.index);
+ remaining = remaining.slice(match.index + match[0].length);
+ output += format(d, match);
+ }
+ return output + remaining;
+ }
+ function format(d, match) {
+ var e_1, _a;
+ var _b = __read(match, 5), input = _b[0], _c = _b[1], flagStr = _c === void 0 ? '' : _c, width = _b[2], modifier = _b[3], conversion = _b[4];
+ var convert = formatCodes[conversion];
+ if (!convert)
+ return input;
+ var flags = {};
+ try {
+ for (var flagStr_1 = __values(flagStr), flagStr_1_1 = flagStr_1.next(); !flagStr_1_1.done; flagStr_1_1 = flagStr_1.next()) {
+ var flag = flagStr_1_1.value;
+ flags[flag] = true;
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (flagStr_1_1 && !flagStr_1_1.done && (_a = flagStr_1.return)) _a.call(flagStr_1);
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ var ret = String(convert(d, { flags: flags, width: width, modifier: modifier }));
+ var padChar = padChars[conversion] || '0';
+ var padWidth = width || padWidths[conversion] || 0;
+ if (flags['^'])
+ ret = ret.toUpperCase();
+ else if (flags['#'])
+ ret = changeCase(ret);
+ if (flags['_'])
+ padChar = ' ';
+ else if (flags['0'])
+ padChar = '0';
+ if (flags['-'])
+ padWidth = 0;
+ return padStart(ret, padWidth, padChar);
+ }
+
+ function date(v, arg) {
+ var date = v;
+ if (v === 'now' || v === 'today') {
+ date = new Date();
+ }
+ else if (isNumber(v)) {
+ date = new Date(v * 1000);
+ }
+ else if (isString(v)) {
+ date = /^\d+$/.test(v) ? new Date(+v * 1000) : new Date(v);
+ }
+ return isValidDate(date) ? strftime(date, arg) : v;
+ }
+ function isValidDate(date) {
+ return date instanceof Date && !isNaN(date.getTime());
+ }
+
+ function Default(v, arg) {
+ if (isArray(v) || isString(v))
+ return v.length ? v : arg;
+ return isFalsy(toValue(v)) ? arg : v;
+ }
+ function json(v) {
+ return JSON.stringify(v);
+ }
+
+ /**
+ * String related filters
+ *
+ * * prefer stringify() to String() since `undefined`, `null` should eval ''
+ */
+ function append(v, arg) {
+ assert(arg !== undefined, function () { return 'append expect 2 arguments'; });
+ return stringify(v) + stringify(arg);
+ }
+ function prepend(v, arg) {
+ assert(arg !== undefined, function () { return 'prepend expect 2 arguments'; });
+ return stringify(arg) + stringify(v);
+ }
+ function lstrip(v) {
+ return stringify(v).replace(/^\s+/, '');
+ }
+ function downcase(v) {
+ return stringify(v).toLowerCase();
+ }
+ function upcase(str) {
+ return stringify(str).toUpperCase();
+ }
+ function remove(v, arg) {
+ return stringify(v).split(arg).join('');
+ }
+ function removeFirst(v, l) {
+ return stringify(v).replace(l, '');
+ }
+ function rstrip(str) {
+ return stringify(str).replace(/\s+$/, '');
+ }
+ function split(v, arg) {
+ return stringify(v).split(arg);
+ }
+ function strip(v) {
+ return stringify(v).trim();
+ }
+ function stripNewlines(v) {
+ return stringify(v).replace(/\n/g, '');
+ }
+ function capitalize(str) {
+ str = stringify(str);
+ return str.charAt(0).toUpperCase() + str.slice(1);
+ }
+ function replace(v, pattern, replacement) {
+ return stringify(v).split(pattern).join(replacement);
+ }
+ function replaceFirst(v, arg1, arg2) {
+ return stringify(v).replace(arg1, arg2);
+ }
+ function truncate(v, l, o) {
+ if (l === void 0) { l = 50; }
+ if (o === void 0) { o = '...'; }
+ v = stringify(v);
+ if (v.length <= l)
+ return v;
+ return v.substr(0, l - o.length) + o;
+ }
+ function truncatewords(v, l, o) {
+ if (l === void 0) { l = 15; }
+ if (o === void 0) { o = '...'; }
+ var arr = v.split(/\s+/);
+ var ret = arr.slice(0, l).join(' ');
+ if (arr.length >= l)
+ ret += o;
+ return ret;
+ }
+
+
+
+ var builtinFilters = /*#__PURE__*/Object.freeze({
+ escape: escape,
+ escapeOnce: escapeOnce,
+ newlineToBr: newlineToBr,
+ stripHtml: stripHtml,
+ abs: abs,
+ atLeast: atLeast,
+ atMost: atMost,
+ ceil: ceil,
+ dividedBy: dividedBy,
+ floor: floor,
+ minus: minus,
+ modulo: modulo,
+ times: times,
+ round: round,
+ plus: plus,
+ sortNatural: sortNatural,
+ urlDecode: urlDecode,
+ urlEncode: urlEncode,
+ join: join,
+ last: last$1,
+ first: first,
+ reverse: reverse,
+ sort: sort,
+ size: size,
+ map: map,
+ concat: concat,
+ slice: slice,
+ where: where,
+ uniq: uniq,
+ date: date,
+ Default: Default,
+ json: json,
+ append: append,
+ prepend: prepend,
+ lstrip: lstrip,
+ downcase: downcase,
+ upcase: upcase,
+ remove: remove,
+ removeFirst: removeFirst,
+ rstrip: rstrip,
+ split: split,
+ strip: strip,
+ stripNewlines: stripNewlines,
+ capitalize: capitalize,
+ replace: replace,
+ replaceFirst: replaceFirst,
+ truncate: truncate,
+ truncatewords: truncatewords
+ });
+
+ var TagMap = /** @class */ (function () {
+ function TagMap() {
+ this.impls = {};
+ }
+ TagMap.prototype.get = function (name) {
+ var impl = this.impls[name];
+ assert(impl, function () { return "tag \"" + name + "\" not found"; });
+ return impl;
+ };
+ TagMap.prototype.set = function (name, impl) {
+ this.impls[name] = impl;
+ };
+ return TagMap;
+ }());
+
+ var FilterMap = /** @class */ (function () {
+ function FilterMap(strictFilters) {
+ this.strictFilters = strictFilters;
+ this.impls = {};
+ }
+ FilterMap.prototype.get = function (name) {
+ var impl = this.impls[name];
+ assert(impl || !this.strictFilters, function () { return "undefined filter: " + name; });
+ return impl;
+ };
+ FilterMap.prototype.set = function (name, impl) {
+ this.impls[name] = impl;
+ };
+ FilterMap.prototype.create = function (name, args) {
+ return new Filter(name, this.get(name), args);
+ };
+ return FilterMap;
+ }());
+
+ function mkResolve(value) {
+ var ret = {
+ then: function (resolve) { return resolve(value); },
+ catch: function () { return ret; }
+ };
+ return ret;
+ }
+ function mkReject(err) {
+ var ret = {
+ then: function (resolve, reject) {
+ if (reject)
+ return reject(err);
+ return ret;
+ },
+ catch: function (reject) { return reject(err); }
+ };
+ return ret;
+ }
+ function isThenable(val) {
+ return val && isFunction(val.then);
+ }
+ function isCustomIterable(val) {
+ return val && isFunction(val.next) && isFunction(val.throw) && isFunction(val.return);
+ }
+ function toThenable(val) {
+ if (isThenable(val))
+ return val;
+ if (isCustomIterable(val))
+ return reduce();
+ return mkResolve(val);
+ function reduce(prev) {
+ var state;
+ try {
+ state = val.next(prev);
+ }
+ catch (err) {
+ return mkReject(err);
+ }
+ if (state.done)
+ return mkResolve(state.value);
+ return toThenable(state.value).then(reduce, function (err) {
+ var state;
+ try {
+ state = val.throw(err);
+ }
+ catch (e) {
+ return mkReject(e);
+ }
+ if (state.done)
+ return mkResolve(state.value);
+ return reduce(state.value);
+ });
+ }
+ }
+ function toValue$1(val) {
+ var ret;
+ toThenable(val)
+ .then(function (x) {
+ ret = x;
+ return mkResolve(ret);
+ })
+ .catch(function (err) {
+ throw err;
+ });
+ return ret;
+ }
+
+ var Liquid = /** @class */ (function () {
+ function Liquid(opts) {
+ var _this = this;
+ if (opts === void 0) { opts = {}; }
+ this.options = applyDefault(normalize(opts));
+ this.parser = new Parser(this);
+ this.renderer = new Render();
+ this.fs = opts.fs || fs;
+ this.filters = new FilterMap(this.options.strictFilters);
+ this.tags = new TagMap();
+ forOwn(tags, function (conf, name) { return _this.registerTag(snakeCase(name), conf); });
+ forOwn(builtinFilters, function (handler, name) { return _this.registerFilter(snakeCase(name), handler); });
+ }
+ Liquid.prototype.parse = function (html, filepath) {
+ var tokenizer = new Tokenizer(html, filepath);
+ var tokens = tokenizer.readTopLevelTokens(this.options);
+ return this.parser.parse(tokens);
+ };
+ Liquid.prototype._render = function (tpl, scope, opts, sync) {
+ var options = __assign({}, this.options, normalize(opts));
+ var ctx = new Context(scope, options, sync);
+ return this.renderer.renderTemplates(tpl, ctx);
+ };
+ Liquid.prototype.render = function (tpl, scope, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toThenable(this._render(tpl, scope, opts, false))];
+ });
+ });
+ };
+ Liquid.prototype.renderSync = function (tpl, scope, opts) {
+ return toValue$1(this._render(tpl, scope, opts, true));
+ };
+ Liquid.prototype._parseAndRender = function (html, scope, opts, sync) {
+ var tpl = this.parse(html);
+ return this._render(tpl, scope, opts, sync);
+ };
+ Liquid.prototype.parseAndRender = function (html, scope, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toThenable(this._parseAndRender(html, scope, opts, false))];
+ });
+ });
+ };
+ Liquid.prototype.parseAndRenderSync = function (html, scope, opts) {
+ return toValue$1(this._parseAndRender(html, scope, opts, true));
+ };
+ Liquid.prototype._parseFile = function (file, opts, sync) {
+ var options, paths, filepath, paths_1, paths_1_1, filepath, cache, tpls, _a, tpl, _b, _c, e_1_1;
+ var e_1, _d;
+ var _this = this;
+ return __generator(this, function (_e) {
+ switch (_e.label) {
+ case 0:
+ options = __assign({}, this.options, normalize(opts));
+ paths = options.root.map(function (root) { return _this.fs.resolve(root, file, options.extname); });
+ if (this.fs.fallback !== undefined) {
+ filepath = this.fs.fallback(file);
+ if (filepath !== undefined)
+ paths.push(filepath);
+ }
+ _e.label = 1;
+ case 1:
+ _e.trys.push([1, 13, 14, 15]);
+ paths_1 = __values(paths), paths_1_1 = paths_1.next();
+ _e.label = 2;
+ case 2:
+ if (!!paths_1_1.done) return [3 /*break*/, 12];
+ filepath = paths_1_1.value;
+ cache = options.cache;
+ if (!cache) return [3 /*break*/, 4];
+ return [4 /*yield*/, cache.read(filepath)];
+ case 3:
+ tpls = _e.sent();
+ if (tpls)
+ return [2 /*return*/, tpls];
+ _e.label = 4;
+ case 4:
+ if (!sync) return [3 /*break*/, 5];
+ _a = this.fs.existsSync(filepath);
+ return [3 /*break*/, 7];
+ case 5: return [4 /*yield*/, this.fs.exists(filepath)];
+ case 6:
+ _a = _e.sent();
+ _e.label = 7;
+ case 7:
+ if (!(_a))
+ return [3 /*break*/, 11];
+ _b = this.parse;
+ if (!sync) return [3 /*break*/, 8];
+ _c = this.fs.readFileSync(filepath);
+ return [3 /*break*/, 10];
+ case 8: return [4 /*yield*/, this.fs.readFile(filepath)];
+ case 9:
+ _c = _e.sent();
+ _e.label = 10;
+ case 10:
+ tpl = _b.apply(this, [_c, filepath]);
+ if (cache)
+ cache.write(filepath, tpl);
+ return [2 /*return*/, tpl];
+ case 11:
+ paths_1_1 = paths_1.next();
+ return [3 /*break*/, 2];
+ case 12: return [3 /*break*/, 15];
+ case 13:
+ e_1_1 = _e.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 15];
+ case 14:
+ try {
+ if (paths_1_1 && !paths_1_1.done && (_d = paths_1.return)) _d.call(paths_1);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 15: throw this.lookupError(file, options.root);
+ }
+ });
+ };
+ Liquid.prototype.parseFile = function (file, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toThenable(this._parseFile(file, opts, false))];
+ });
+ });
+ };
+ Liquid.prototype.parseFileSync = function (file, opts) {
+ return toValue$1(this._parseFile(file, opts, true));
+ };
+ Liquid.prototype.renderFile = function (file, ctx, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ var templates;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, this.parseFile(file, opts)];
+ case 1:
+ templates = _a.sent();
+ return [2 /*return*/, this.render(templates, ctx, opts)];
+ }
+ });
+ });
+ };
+ Liquid.prototype.renderFileSync = function (file, ctx, opts) {
+ var options = normalize(opts);
+ var templates = this.parseFileSync(file, options);
+ return this.renderSync(templates, ctx, opts);
+ };
+ Liquid.prototype._evalValue = function (str, ctx) {
+ var value = new Value(str, this.filters);
+ return value.value(ctx);
+ };
+ Liquid.prototype.evalValue = function (str, ctx) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toThenable(this._evalValue(str, ctx))];
+ });
+ });
+ };
+ Liquid.prototype.evalValueSync = function (str, ctx) {
+ return toValue$1(this._evalValue(str, ctx));
+ };
+ Liquid.prototype.registerFilter = function (name, filter) {
+ this.filters.set(name, filter);
+ };
+ Liquid.prototype.registerTag = function (name, tag) {
+ this.tags.set(name, tag);
+ };
+ Liquid.prototype.plugin = function (plugin) {
+ return plugin.call(this, Liquid);
+ };
+ Liquid.prototype.express = function () {
+ var self = this; // eslint-disable-line
+ return function (filePath, ctx, callback) {
+ var opts = { root: __spread(normalizeStringArray(this.root), self.options.root) };
+ self.renderFile(filePath, ctx, opts).then(function (html) { return callback(null, html); }, callback);
+ };
+ };
+ Liquid.prototype.lookupError = function (file, roots) {
+ var err = new Error('ENOENT');
+ err.message = "ENOENT: Failed to lookup \"" + file + "\" in \"" + roots + "\"";
+ err.code = 'ENOENT';
+ return err;
+ };
+ /**
+ * @deprecated use parseFile instead
+ */
+ Liquid.prototype.getTemplate = function (file, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, this.parseFile(file, opts)];
+ });
+ });
+ };
+ /**
+ * @deprecated use parseFileSync instead
+ */
+ Liquid.prototype.getTemplateSync = function (file, opts) {
+ return this.parseFileSync(file, opts);
+ };
+ return Liquid;
+ }());
+
+ exports.AssertionError = AssertionError;
+ exports.Context = Context;
+ exports.Drop = Drop;
+ exports.Emitter = Emitter;
+ exports.Expression = Expression;
+ exports.Hash = Hash;
+ exports.Liquid = Liquid;
+ exports.ParseError = ParseError;
+ exports.ParseStream = ParseStream;
+ exports.TagToken = TagToken;
+ exports.Token = Token;
+ exports.TokenizationError = TokenizationError;
+ exports.Tokenizer = Tokenizer;
+ exports.TypeGuards = typeGuards;
+ exports.assert = assert;
+ exports.evalQuotedToken = evalQuotedToken;
+ exports.evalToken = evalToken;
+ exports.isFalsy = isFalsy;
+ exports.isTruthy = isTruthy;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
+//# sourceMappingURL=liquid.js.map
diff --git a/src/lib/popper.js b/src/lib/popper.js
new file mode 100644
index 0000000..8a17212
--- /dev/null
+++ b/src/lib/popper.js
@@ -0,0 +1,5 @@
+/*
+ Copyright (C) Federico Zivolo 2019
+ Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
+ */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function i(e){return e&&e.referenceNode?e.referenceNode:e}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',o='top'===t?'scrollTop':'scrollLeft',n=e.nodeName;if('BODY'===n||'HTML'===n){var i=e.ownerDocument.documentElement,r=e.ownerDocument.scrollingElement||i;return r[o]}return e[o]}function f(e,t){var o=2<arguments.length&&void 0!==arguments[2]&&arguments[2],n=l(t,'top'),i=l(t,'left'),r=o?-1:1;return e.top+=n*r,e.bottom+=n*r,e.left+=i*r,e.right+=i*r,e}function m(e,t){var o='x'===t?'Left':'Top',n='Left'==o?'Right':'Bottom';return parseFloat(e['border'+o+'Width'],10)+parseFloat(e['border'+n+'Width'],10)}function h(e,t,o,n){return ee(t['offset'+e],t['scroll'+e],o['client'+e],o['offset'+e],o['scroll'+e],r(10)?parseInt(o['offset'+e])+parseInt(n['margin'+('Height'===e?'Top':'Left')])+parseInt(n['margin'+('Height'===e?'Bottom':'Right')]):0)}function c(e){var t=e.body,o=e.documentElement,n=r(10)&&getComputedStyle(o);return{height:h('Height',t,o,n),width:h('Width',t,o,n)}}function g(e){return le({},e,{right:e.left+e.width,bottom:e.top+e.height})}function u(e){var o={};try{if(r(10)){o=e.getBoundingClientRect();var n=l(e,'top'),i=l(e,'left');o.top+=n,o.left+=i,o.bottom+=n,o.right+=i}else o=e.getBoundingClientRect()}catch(t){}var p={left:o.left,top:o.top,width:o.right-o.left,height:o.bottom-o.top},s='HTML'===e.nodeName?c(e.ownerDocument):{},d=s.width||e.clientWidth||p.width,a=s.height||e.clientHeight||p.height,f=e.offsetWidth-d,h=e.offsetHeight-a;if(f||h){var u=t(e);f-=m(u,'x'),h-=m(u,'y'),p.width-=f,p.height-=h}return g(p)}function b(e,o){var i=2<arguments.length&&void 0!==arguments[2]&&arguments[2],p=r(10),s='HTML'===o.nodeName,d=u(e),a=u(o),l=n(e),m=t(o),h=parseFloat(m.borderTopWidth,10),c=parseFloat(m.borderLeftWidth,10);i&&s&&(a.top=ee(a.top,0),a.left=ee(a.left,0));var b=g({top:d.top-a.top-h,left:d.left-a.left-c,width:d.width,height:d.height});if(b.marginTop=0,b.marginLeft=0,!p&&s){var w=parseFloat(m.marginTop,10),y=parseFloat(m.marginLeft,10);b.top-=h-w,b.bottom-=h-w,b.left-=c-y,b.right-=c-y,b.marginTop=w,b.marginLeft=y}return(p&&!i?o.contains(l):o===l&&'BODY'!==l.nodeName)&&(b=f(b,o)),b}function w(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=e.ownerDocument.documentElement,n=b(e,o),i=ee(o.clientWidth,window.innerWidth||0),r=ee(o.clientHeight,window.innerHeight||0),p=t?0:l(o),s=t?0:l(o,'left'),d={top:p-n.top+n.marginTop,left:s-n.left+n.marginLeft,width:i,height:r};return g(d)}function y(e){var n=e.nodeName;if('BODY'===n||'HTML'===n)return!1;if('fixed'===t(e,'position'))return!0;var i=o(e);return!!i&&y(i)}function E(e){if(!e||!e.parentElement||r())return document.documentElement;for(var o=e.parentElement;o&&'none'===t(o,'transform');)o=o.parentElement;return o||document.documentElement}function v(e,t,r,p){var s=4<arguments.length&&void 0!==arguments[4]&&arguments[4],d={top:0,left:0},l=s?E(e):a(e,i(t));if('viewport'===p)d=w(l,s);else{var f;'scrollParent'===p?(f=n(o(t)),'BODY'===f.nodeName&&(f=e.ownerDocument.documentElement)):'window'===p?f=e.ownerDocument.documentElement:f=p;var m=b(f,l,s);if('HTML'===f.nodeName&&!y(l)){var h=c(e.ownerDocument),g=h.height,u=h.width;d.top+=m.top-m.marginTop,d.bottom=g+m.top,d.left+=m.left-m.marginLeft,d.right=u+m.left}else d=m}r=r||0;var v='number'==typeof r;return d.left+=v?r:r.left||0,d.top+=v?r:r.top||0,d.right-=v?r:r.right||0,d.bottom-=v?r:r.bottom||0,d}function x(e){var t=e.width,o=e.height;return t*o}function O(e,t,o,n,i){var r=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===e.indexOf('auto'))return e;var p=v(o,n,r,i),s={top:{width:p.width,height:t.top-p.top},right:{width:p.right-t.right,height:p.height},bottom:{width:p.width,height:p.bottom-t.bottom},left:{width:t.left-p.left,height:p.height}},d=Object.keys(s).map(function(e){return le({key:e},s[e],{area:x(s[e])})}).sort(function(e,t){return t.area-e.area}),a=d.filter(function(e){var t=e.width,n=e.height;return t>=o.clientWidth&&n>=o.clientHeight}),l=0<a.length?a[0].key:d[0].key,f=e.split('-')[1];return l+(f?'-'+f:'')}function L(e,t,o){var n=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,r=n?E(t):a(t,i(o));return b(o,r,n)}function S(e){var t=e.ownerDocument.defaultView,o=t.getComputedStyle(e),n=parseFloat(o.marginTop||0)+parseFloat(o.marginBottom||0),i=parseFloat(o.marginLeft||0)+parseFloat(o.marginRight||0),r={width:e.offsetWidth+i,height:e.offsetHeight+n};return r}function T(e){var t={left:'right',right:'left',bottom:'top',top:'bottom'};return e.replace(/left|right|bottom|top/g,function(e){return t[e]})}function C(e,t,o){o=o.split('-')[0];var n=S(e),i={width:n.width,height:n.height},r=-1!==['right','left'].indexOf(o),p=r?'top':'left',s=r?'left':'top',d=r?'height':'width',a=r?'width':'height';return i[p]=t[p]+t[d]/2-n[d]/2,i[s]=o===s?t[s]-n[a]:t[T(s)],i}function D(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function N(e,t,o){if(Array.prototype.findIndex)return e.findIndex(function(e){return e[t]===o});var n=D(e,function(e){return e[t]===o});return e.indexOf(n)}function P(t,o,n){var i=void 0===n?t:t.slice(0,N(t,'name',n));return i.forEach(function(t){t['function']&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var n=t['function']||t.fn;t.enabled&&e(n)&&(o.offsets.popper=g(o.offsets.popper),o.offsets.reference=g(o.offsets.reference),o=n(o,t))}),o}function k(){if(!this.state.isDestroyed){var e={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=L(this.state,this.popper,this.reference,this.options.positionFixed),e.placement=O(this.options.placement,e.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),e.originalPlacement=e.placement,e.positionFixed=this.options.positionFixed,e.offsets.popper=C(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position=this.options.positionFixed?'fixed':'absolute',e=P(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function W(e,t){return e.some(function(e){var o=e.name,n=e.enabled;return n&&o===t})}function B(e){for(var t=[!1,'ms','Webkit','Moz','O'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length;n++){var i=t[n],r=i?''+i+o:e;if('undefined'!=typeof document.body.style[r])return r}return null}function H(){return this.state.isDestroyed=!0,W(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.position='',this.popper.style.top='',this.popper.style.left='',this.popper.style.right='',this.popper.style.bottom='',this.popper.style.willChange='',this.popper.style[B('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function A(e){var t=e.ownerDocument;return t?t.defaultView:window}function M(e,t,o,i){var r='BODY'===e.nodeName,p=r?e.ownerDocument.defaultView:e;p.addEventListener(t,o,{passive:!0}),r||M(n(p.parentNode),t,o,i),i.push(p)}function F(e,t,o,i){o.updateBound=i,A(e).addEventListener('resize',o.updateBound,{passive:!0});var r=n(e);return M(r,'scroll',o.updateBound,o.scrollParents),o.scrollElement=r,o.eventsEnabled=!0,o}function I(){this.state.eventsEnabled||(this.state=F(this.reference,this.options,this.state,this.scheduleUpdate))}function R(e,t){return A(e).removeEventListener('resize',t.updateBound),t.scrollParents.forEach(function(e){e.removeEventListener('scroll',t.updateBound)}),t.updateBound=null,t.scrollParents=[],t.scrollElement=null,t.eventsEnabled=!1,t}function U(){this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=R(this.reference,this.state))}function Y(e){return''!==e&&!isNaN(parseFloat(e))&&isFinite(e)}function V(e,t){Object.keys(t).forEach(function(o){var n='';-1!==['width','height','top','right','bottom','left'].indexOf(o)&&Y(t[o])&&(n='px'),e.style[o]=t[o]+n})}function j(e,t){Object.keys(t).forEach(function(o){var n=t[o];!1===n?e.removeAttribute(o):e.setAttribute(o,t[o])})}function q(e,t){var o=e.offsets,n=o.popper,i=o.reference,r=$,p=function(e){return e},s=r(i.width),d=r(n.width),a=-1!==['left','right'].indexOf(e.placement),l=-1!==e.placement.indexOf('-'),f=t?a||l||s%2==d%2?r:Z:p,m=t?r:p;return{left:f(1==s%2&&1==d%2&&!l&&t?n.left-1:n.left),top:m(n.top),bottom:m(n.bottom),right:f(n.right)}}function K(e,t,o){var n=D(e,function(e){var o=e.name;return o===t}),i=!!n&&e.some(function(e){return e.name===o&&e.enabled&&e.order<n.order});if(!i){var r='`'+t+'`';console.warn('`'+o+'`'+' modifier is required by '+r+' modifier in order to work, be sure to include it before '+r+'!')}return i}function z(e){return'end'===e?'start':'start'===e?'end':e}function G(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=he.indexOf(e),n=he.slice(o+1).concat(he.slice(0,o));return t?n.reverse():n}function _(e,t,o,n){var i=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+i[1],p=i[2];if(!r)return e;if(0===p.indexOf('%')){var s;switch(p){case'%p':s=o;break;case'%':case'%r':default:s=n;}var d=g(s);return d[t]/100*r}if('vh'===p||'vw'===p){var a;return a='vh'===p?ee(document.documentElement.clientHeight,window.innerHeight||0):ee(document.documentElement.clientWidth,window.innerWidth||0),a/100*r}return r}function X(e,t,o,n){var i=[0,0],r=-1!==['right','left'].indexOf(n),p=e.split(/(\+|\-)/).map(function(e){return e.trim()}),s=p.indexOf(D(p,function(e){return-1!==e.search(/,|\s/)}));p[s]&&-1===p[s].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var d=/\s*,\s*|\s+/,a=-1===s?[p]:[p.slice(0,s).concat([p[s].split(d)[0]]),[p[s].split(d)[1]].concat(p.slice(s+1))];return a=a.map(function(e,n){var i=(1===n?!r:r)?'height':'width',p=!1;return e.reduce(function(e,t){return''===e[e.length-1]&&-1!==['+','-'].indexOf(t)?(e[e.length-1]=t,p=!0,e):p?(e[e.length-1]+=t,p=!1,e):e.concat(t)},[]).map(function(e){return _(e,i,t,o)})}),a.forEach(function(e,t){e.forEach(function(o,n){Y(o)&&(i[t]+=o*('-'===e[n-1]?-1:1))})}),i}function J(e,t){var o,n=t.offset,i=e.placement,r=e.offsets,p=r.popper,s=r.reference,d=i.split('-')[0];return o=Y(+n)?[+n,0]:X(n,p,s,d),'left'===d?(p.top+=o[0],p.left-=o[1]):'right'===d?(p.top+=o[0],p.left+=o[1]):'top'===d?(p.left+=o[0],p.top-=o[1]):'bottom'===d&&(p.left+=o[0],p.top+=o[1]),e.popper=p,e}var Q=Math.min,Z=Math.floor,$=Math.round,ee=Math.max,te='undefined'!=typeof window&&'undefined'!=typeof document&&'undefined'!=typeof navigator,oe=function(){for(var e=['Edge','Trident','Firefox'],t=0;t<e.length;t+=1)if(te&&0<=navigator.userAgent.indexOf(e[t]))return 1;return 0}(),ne=te&&window.Promise,ie=ne?function(e){var t=!1;return function(){t||(t=!0,window.Promise.resolve().then(function(){t=!1,e()}))}}:function(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},oe))}},re=te&&!!(window.MSInputMethodContext&&document.documentMode),pe=te&&/MSIE 10/.test(navigator.userAgent),se=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},de=function(){function e(e,t){for(var o,n=0;n<t.length;n++)o=t[n],o.enumerable=o.enumerable||!1,o.configurable=!0,'value'in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}return function(t,o,n){return o&&e(t.prototype,o),n&&e(t,n),t}}(),ae=function(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e},le=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var n in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e},fe=te&&/Firefox/i.test(navigator.userAgent),me=['auto-start','auto','auto-end','top-start','top','top-end','right-start','right','right-end','bottom-end','bottom','bottom-start','left-end','left','left-start'],he=me.slice(3),ce={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},ge=function(){function t(o,n){var i=this,r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};se(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=ie(this.update.bind(this)),this.options=le({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=o&&o.jquery?o[0]:o,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(le({},t.Defaults.modifiers,r.modifiers)).forEach(function(e){i.options.modifiers[e]=le({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(e){return le({name:e},i.options.modifiers[e])}).sort(function(e,t){return e.order-t.order}),this.modifiers.forEach(function(t){t.enabled&&e(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)}),this.update();var p=this.options.eventsEnabled;p&&this.enableEventListeners(),this.state.eventsEnabled=p}return de(t,[{key:'update',value:function(){return k.call(this)}},{key:'destroy',value:function(){return H.call(this)}},{key:'enableEventListeners',value:function(){return I.call(this)}},{key:'disableEventListeners',value:function(){return U.call(this)}}]),t}();return ge.Utils=('undefined'==typeof window?global:window).PopperUtils,ge.placements=me,ge.Defaults={placement:'bottom',positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(e){var t=e.placement,o=t.split('-')[0],n=t.split('-')[1];if(n){var i=e.offsets,r=i.reference,p=i.popper,s=-1!==['bottom','top'].indexOf(o),d=s?'left':'top',a=s?'width':'height',l={start:ae({},d,r[d]),end:ae({},d,r[d]+r[a]-p[a])};e.offsets.popper=le({},p,l[n])}return e}},offset:{order:200,enabled:!0,fn:J,offset:0},preventOverflow:{order:300,enabled:!0,fn:function(e,t){var o=t.boundariesElement||p(e.instance.popper);e.instance.reference===o&&(o=p(o));var n=B('transform'),i=e.instance.popper.style,r=i.top,s=i.left,d=i[n];i.top='',i.left='',i[n]='';var a=v(e.instance.popper,e.instance.reference,t.padding,o,e.positionFixed);i.top=r,i.left=s,i[n]=d,t.boundaries=a;var l=t.priority,f=e.offsets.popper,m={primary:function(e){var o=f[e];return f[e]<a[e]&&!t.escapeWithReference&&(o=ee(f[e],a[e])),ae({},e,o)},secondary:function(e){var o='right'===e?'left':'top',n=f[o];return f[e]>a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]<r(n[d])&&(e.offsets.popper[d]=r(n[d])-o[a]),o[d]>r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-u<s[m]&&(e.offsets.popper[m]-=s[m]-(d[c]-u)),d[m]+u>s[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,$(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ce.FLIP:p=[n,i];break;case ce.CLOCKWISE:p=G(n);break;case ce.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)<f(l.right)||'top'===n&&f(a.bottom)>f(l.top)||'bottom'===n&&f(a.top)<f(l.bottom),h=f(a.left)<f(o.left),c=f(a.right)>f(o.right),g=f(a.top)<f(o.top),u=f(a.bottom)>f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u),E=!!t.flipVariationsByContent&&(w&&'start'===r&&c||w&&'end'===r&&h||!w&&'start'===r&&u||!w&&'end'===r&&g),v=y||E;(m||b||v)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),v&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport',flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottom<o.top||t.left>o.right||t.top>o.bottom||t.right<o.left){if(!0===e.hide)return e;e.hide=!0,e.attributes['x-out-of-boundaries']=''}else{if(!1===e.hide)return e;e.hide=!1,e.attributes['x-out-of-boundaries']=!1}return e}},computeStyle:{order:850,enabled:!0,fn:function(e,t){var o=t.x,n=t.y,i=e.offsets.popper,r=D(e.instance.modifiers,function(e){return'applyStyle'===e.name}).gpuAcceleration;void 0!==r&&console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');var s,d,a=void 0===r?t.gpuAcceleration:r,l=p(e.instance.popper),f=u(l),m={position:i.position},h=q(e,2>window.devicePixelRatio||!fe),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=le({},E,e.attributes),e.styles=le({},m,e.styles),e.arrowStyles=le({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return V(e.instance.popper,e.styles),j(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&V(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),V(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ge});
+//# sourceMappingURL=popper.min.js.map
diff --git a/src/lib/pouchdb.js b/src/lib/pouchdb.js
new file mode 100644
index 0000000..9e2812b
--- /dev/null
+++ b/src/lib/pouchdb.js
@@ -0,0 +1,12245 @@
+// PouchDB 7.1.1
+//
+// (c) 2012-2019 Dale Harvey and the PouchDB team
+// PouchDB may be freely distributed under the Apache license, version 2.0.
+// For all details and documentation:
+// http://pouchdb.com
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.PouchDB = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){
+'use strict';
+
+module.exports = argsArray;
+
+function argsArray(fun) {
+ return function () {
+ var len = arguments.length;
+ if (len) {
+ var args = [];
+ var i = -1;
+ while (++i < len) {
+ args[i] = arguments[i];
+ }
+ return fun.call(this, args);
+ } else {
+ return fun.call(this, []);
+ }
+ };
+}
+},{}],2:[function(_dereq_,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var objectCreate = Object.create || objectCreatePolyfill
+var objectKeys = Object.keys || objectKeysPolyfill
+var bind = Function.prototype.bind || functionBindPolyfill
+
+function EventEmitter() {
+ if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) {
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ }
+
+ this._maxListeners = this._maxListeners || undefined;
+}
+module.exports = EventEmitter;
+
+// Backwards-compat with node 0.10.x
+EventEmitter.EventEmitter = EventEmitter;
+
+EventEmitter.prototype._events = undefined;
+EventEmitter.prototype._maxListeners = undefined;
+
+// By default EventEmitters will print a warning if more than 10 listeners are
+// added to it. This is a useful default which helps finding memory leaks.
+var defaultMaxListeners = 10;
+
+var hasDefineProperty;
+try {
+ var o = {};
+ if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 });
+ hasDefineProperty = o.x === 0;
+} catch (err) { hasDefineProperty = false }
+if (hasDefineProperty) {
+ Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
+ enumerable: true,
+ get: function() {
+ return defaultMaxListeners;
+ },
+ set: function(arg) {
+ // check whether the input is a positive number (whose value is zero or
+ // greater and not a NaN).
+ if (typeof arg !== 'number' || arg < 0 || arg !== arg)
+ throw new TypeError('"defaultMaxListeners" must be a positive number');
+ defaultMaxListeners = arg;
+ }
+ });
+} else {
+ EventEmitter.defaultMaxListeners = defaultMaxListeners;
+}
+
+// Obviously not all Emitters should be limited to 10. This function allows
+// that to be increased. Set to zero for unlimited.
+EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
+ if (typeof n !== 'number' || n < 0 || isNaN(n))
+ throw new TypeError('"n" argument must be a positive number');
+ this._maxListeners = n;
+ return this;
+};
+
+function $getMaxListeners(that) {
+ if (that._maxListeners === undefined)
+ return EventEmitter.defaultMaxListeners;
+ return that._maxListeners;
+}
+
+EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
+ return $getMaxListeners(this);
+};
+
+// These standalone emit* functions are used to optimize calling of event
+// handlers for fast cases because emit() itself often has a variable number of
+// arguments and can be deoptimized because of that. These functions always have
+// the same number of arguments and thus do not get deoptimized, so the code
+// inside them can execute faster.
+function emitNone(handler, isFn, self) {
+ if (isFn)
+ handler.call(self);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self);
+ }
+}
+function emitOne(handler, isFn, self, arg1) {
+ if (isFn)
+ handler.call(self, arg1);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self, arg1);
+ }
+}
+function emitTwo(handler, isFn, self, arg1, arg2) {
+ if (isFn)
+ handler.call(self, arg1, arg2);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self, arg1, arg2);
+ }
+}
+function emitThree(handler, isFn, self, arg1, arg2, arg3) {
+ if (isFn)
+ handler.call(self, arg1, arg2, arg3);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self, arg1, arg2, arg3);
+ }
+}
+
+function emitMany(handler, isFn, self, args) {
+ if (isFn)
+ handler.apply(self, args);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].apply(self, args);
+ }
+}
+
+EventEmitter.prototype.emit = function emit(type) {
+ var er, handler, len, args, i, events;
+ var doError = (type === 'error');
+
+ events = this._events;
+ if (events)
+ doError = (doError && events.error == null);
+ else if (!doError)
+ return false;
+
+ // If there is no 'error' event listener then throw.
+ if (doError) {
+ if (arguments.length > 1)
+ er = arguments[1];
+ if (er instanceof Error) {
+ throw er; // Unhandled 'error' event
+ } else {
+ // At least give some kind of context to the user
+ var err = new Error('Unhandled "error" event. (' + er + ')');
+ err.context = er;
+ throw err;
+ }
+ return false;
+ }
+
+ handler = events[type];
+
+ if (!handler)
+ return false;
+
+ var isFn = typeof handler === 'function';
+ len = arguments.length;
+ switch (len) {
+ // fast cases
+ case 1:
+ emitNone(handler, isFn, this);
+ break;
+ case 2:
+ emitOne(handler, isFn, this, arguments[1]);
+ break;
+ case 3:
+ emitTwo(handler, isFn, this, arguments[1], arguments[2]);
+ break;
+ case 4:
+ emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]);
+ break;
+ // slower
+ default:
+ args = new Array(len - 1);
+ for (i = 1; i < len; i++)
+ args[i - 1] = arguments[i];
+ emitMany(handler, isFn, this, args);
+ }
+
+ return true;
+};
+
+function _addListener(target, type, listener, prepend) {
+ var m;
+ var events;
+ var existing;
+
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+
+ events = target._events;
+ if (!events) {
+ events = target._events = objectCreate(null);
+ target._eventsCount = 0;
+ } else {
+ // To avoid recursion in the case that type === "newListener"! Before
+ // adding it to the listeners, first emit "newListener".
+ if (events.newListener) {
+ target.emit('newListener', type,
+ listener.listener ? listener.listener : listener);
+
+ // Re-assign `events` because a newListener handler could have caused the
+ // this._events to be assigned to a new object
+ events = target._events;
+ }
+ existing = events[type];
+ }
+
+ if (!existing) {
+ // Optimize the case of one listener. Don't need the extra array object.
+ existing = events[type] = listener;
+ ++target._eventsCount;
+ } else {
+ if (typeof existing === 'function') {
+ // Adding the second element, need to change to array.
+ existing = events[type] =
+ prepend ? [listener, existing] : [existing, listener];
+ } else {
+ // If we've already got an array, just append.
+ if (prepend) {
+ existing.unshift(listener);
+ } else {
+ existing.push(listener);
+ }
+ }
+
+ // Check for listener leak
+ if (!existing.warned) {
+ m = $getMaxListeners(target);
+ if (m && m > 0 && existing.length > m) {
+ existing.warned = true;
+ var w = new Error('Possible EventEmitter memory leak detected. ' +
+ existing.length + ' "' + String(type) + '" listeners ' +
+ 'added. Use emitter.setMaxListeners() to ' +
+ 'increase limit.');
+ w.name = 'MaxListenersExceededWarning';
+ w.emitter = target;
+ w.type = type;
+ w.count = existing.length;
+ if (typeof console === 'object' && console.warn) {
+ console.warn('%s: %s', w.name, w.message);
+ }
+ }
+ }
+ }
+
+ return target;
+}
+
+EventEmitter.prototype.addListener = function addListener(type, listener) {
+ return _addListener(this, type, listener, false);
+};
+
+EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+EventEmitter.prototype.prependListener =
+ function prependListener(type, listener) {
+ return _addListener(this, type, listener, true);
+ };
+
+function onceWrapper() {
+ if (!this.fired) {
+ this.target.removeListener(this.type, this.wrapFn);
+ this.fired = true;
+ switch (arguments.length) {
+ case 0:
+ return this.listener.call(this.target);
+ case 1:
+ return this.listener.call(this.target, arguments[0]);
+ case 2:
+ return this.listener.call(this.target, arguments[0], arguments[1]);
+ case 3:
+ return this.listener.call(this.target, arguments[0], arguments[1],
+ arguments[2]);
+ default:
+ var args = new Array(arguments.length);
+ for (var i = 0; i < args.length; ++i)
+ args[i] = arguments[i];
+ this.listener.apply(this.target, args);
+ }
+ }
+}
+
+function _onceWrap(target, type, listener) {
+ var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
+ var wrapped = bind.call(onceWrapper, state);
+ wrapped.listener = listener;
+ state.wrapFn = wrapped;
+ return wrapped;
+}
+
+EventEmitter.prototype.once = function once(type, listener) {
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+ this.on(type, _onceWrap(this, type, listener));
+ return this;
+};
+
+EventEmitter.prototype.prependOnceListener =
+ function prependOnceListener(type, listener) {
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+ this.prependListener(type, _onceWrap(this, type, listener));
+ return this;
+ };
+
+// Emits a 'removeListener' event if and only if the listener was removed.
+EventEmitter.prototype.removeListener =
+ function removeListener(type, listener) {
+ var list, events, position, i, originalListener;
+
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+
+ events = this._events;
+ if (!events)
+ return this;
+
+ list = events[type];
+ if (!list)
+ return this;
+
+ if (list === listener || list.listener === listener) {
+ if (--this._eventsCount === 0)
+ this._events = objectCreate(null);
+ else {
+ delete events[type];
+ if (events.removeListener)
+ this.emit('removeListener', type, list.listener || listener);
+ }
+ } else if (typeof list !== 'function') {
+ position = -1;
+
+ for (i = list.length - 1; i >= 0; i--) {
+ if (list[i] === listener || list[i].listener === listener) {
+ originalListener = list[i].listener;
+ position = i;
+ break;
+ }
+ }
+
+ if (position < 0)
+ return this;
+
+ if (position === 0)
+ list.shift();
+ else
+ spliceOne(list, position);
+
+ if (list.length === 1)
+ events[type] = list[0];
+
+ if (events.removeListener)
+ this.emit('removeListener', type, originalListener || listener);
+ }
+
+ return this;
+ };
+
+EventEmitter.prototype.removeAllListeners =
+ function removeAllListeners(type) {
+ var listeners, events, i;
+
+ events = this._events;
+ if (!events)
+ return this;
+
+ // not listening for removeListener, no need to emit
+ if (!events.removeListener) {
+ if (arguments.length === 0) {
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ } else if (events[type]) {
+ if (--this._eventsCount === 0)
+ this._events = objectCreate(null);
+ else
+ delete events[type];
+ }
+ return this;
+ }
+
+ // emit removeListener for all listeners on all events
+ if (arguments.length === 0) {
+ var keys = objectKeys(events);
+ var key;
+ for (i = 0; i < keys.length; ++i) {
+ key = keys[i];
+ if (key === 'removeListener') continue;
+ this.removeAllListeners(key);
+ }
+ this.removeAllListeners('removeListener');
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ return this;
+ }
+
+ listeners = events[type];
+
+ if (typeof listeners === 'function') {
+ this.removeListener(type, listeners);
+ } else if (listeners) {
+ // LIFO order
+ for (i = listeners.length - 1; i >= 0; i--) {
+ this.removeListener(type, listeners[i]);
+ }
+ }
+
+ return this;
+ };
+
+function _listeners(target, type, unwrap) {
+ var events = target._events;
+
+ if (!events)
+ return [];
+
+ var evlistener = events[type];
+ if (!evlistener)
+ return [];
+
+ if (typeof evlistener === 'function')
+ return unwrap ? [evlistener.listener || evlistener] : [evlistener];
+
+ return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
+}
+
+EventEmitter.prototype.listeners = function listeners(type) {
+ return _listeners(this, type, true);
+};
+
+EventEmitter.prototype.rawListeners = function rawListeners(type) {
+ return _listeners(this, type, false);
+};
+
+EventEmitter.listenerCount = function(emitter, type) {
+ if (typeof emitter.listenerCount === 'function') {
+ return emitter.listenerCount(type);
+ } else {
+ return listenerCount.call(emitter, type);
+ }
+};
+
+EventEmitter.prototype.listenerCount = listenerCount;
+function listenerCount(type) {
+ var events = this._events;
+
+ if (events) {
+ var evlistener = events[type];
+
+ if (typeof evlistener === 'function') {
+ return 1;
+ } else if (evlistener) {
+ return evlistener.length;
+ }
+ }
+
+ return 0;
+}
+
+EventEmitter.prototype.eventNames = function eventNames() {
+ return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];
+};
+
+// About 1.5x faster than the two-arg version of Array#splice().
+function spliceOne(list, index) {
+ for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
+ list[i] = list[k];
+ list.pop();
+}
+
+function arrayClone(arr, n) {
+ var copy = new Array(n);
+ for (var i = 0; i < n; ++i)
+ copy[i] = arr[i];
+ return copy;
+}
+
+function unwrapListeners(arr) {
+ var ret = new Array(arr.length);
+ for (var i = 0; i < ret.length; ++i) {
+ ret[i] = arr[i].listener || arr[i];
+ }
+ return ret;
+}
+
+function objectCreatePolyfill(proto) {
+ var F = function() {};
+ F.prototype = proto;
+ return new F;
+}
+function objectKeysPolyfill(obj) {
+ var keys = [];
+ for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) {
+ keys.push(k);
+ }
+ return k;
+}
+function functionBindPolyfill(context) {
+ var fn = this;
+ return function () {
+ return fn.apply(context, arguments);
+ };
+}
+
+},{}],3:[function(_dereq_,module,exports){
+(function (global){
+'use strict';
+var Mutation = global.MutationObserver || global.WebKitMutationObserver;
+
+var scheduleDrain;
+
+{
+ if (Mutation) {
+ var called = 0;
+ var observer = new Mutation(nextTick);
+ var element = global.document.createTextNode('');
+ observer.observe(element, {
+ characterData: true
+ });
+ scheduleDrain = function () {
+ element.data = (called = ++called % 2);
+ };
+ } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
+ var channel = new global.MessageChannel();
+ channel.port1.onmessage = nextTick;
+ scheduleDrain = function () {
+ channel.port2.postMessage(0);
+ };
+ } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
+ scheduleDrain = function () {
+
+ // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
+ // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
+ var scriptEl = global.document.createElement('script');
+ scriptEl.onreadystatechange = function () {
+ nextTick();
+
+ scriptEl.onreadystatechange = null;
+ scriptEl.parentNode.removeChild(scriptEl);
+ scriptEl = null;
+ };
+ global.document.documentElement.appendChild(scriptEl);
+ };
+ } else {
+ scheduleDrain = function () {
+ setTimeout(nextTick, 0);
+ };
+ }
+}
+
+var draining;
+var queue = [];
+//named nextTick for less confusing stack traces
+function nextTick() {
+ draining = true;
+ var i, oldQueue;
+ var len = queue.length;
+ while (len) {
+ oldQueue = queue;
+ queue = [];
+ i = -1;
+ while (++i < len) {
+ oldQueue[i]();
+ }
+ len = queue.length;
+ }
+ draining = false;
+}
+
+module.exports = immediate;
+function immediate(task) {
+ if (queue.push(task) === 1 && !draining) {
+ scheduleDrain();
+ }
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],4:[function(_dereq_,module,exports){
+if (typeof Object.create === 'function') {
+ // implementation from standard node.js 'util' module
+ module.exports = function inherits(ctor, superCtor) {
+ ctor.super_ = superCtor
+ ctor.prototype = Object.create(superCtor.prototype, {
+ constructor: {
+ value: ctor,
+ enumerable: false,
+ writable: true,
+ configurable: true
+ }
+ });
+ };
+} else {
+ // old school shim for old browsers
+ module.exports = function inherits(ctor, superCtor) {
+ ctor.super_ = superCtor
+ var TempCtor = function () {}
+ TempCtor.prototype = superCtor.prototype
+ ctor.prototype = new TempCtor()
+ ctor.prototype.constructor = ctor
+ }
+}
+
+},{}],5:[function(_dereq_,module,exports){
+// shim for using process in browser
+var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things. But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals. It's inside a
+// function because try/catches deoptimize in certain engines.
+
+var cachedSetTimeout;
+var cachedClearTimeout;
+
+function defaultSetTimout() {
+ throw new Error('setTimeout has not been defined');
+}
+function defaultClearTimeout () {
+ throw new Error('clearTimeout has not been defined');
+}
+(function () {
+ try {
+ if (typeof setTimeout === 'function') {
+ cachedSetTimeout = setTimeout;
+ } else {
+ cachedSetTimeout = defaultSetTimout;
+ }
+ } catch (e) {
+ cachedSetTimeout = defaultSetTimout;
+ }
+ try {
+ if (typeof clearTimeout === 'function') {
+ cachedClearTimeout = clearTimeout;
+ } else {
+ cachedClearTimeout = defaultClearTimeout;
+ }
+ } catch (e) {
+ cachedClearTimeout = defaultClearTimeout;
+ }
+} ())
+function runTimeout(fun) {
+ if (cachedSetTimeout === setTimeout) {
+ //normal enviroments in sane situations
+ return setTimeout(fun, 0);
+ }
+ // if setTimeout wasn't available but was latter defined
+ if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+ cachedSetTimeout = setTimeout;
+ return setTimeout(fun, 0);
+ }
+ try {
+ // when when somebody has screwed with setTimeout but no I.E. maddness
+ return cachedSetTimeout(fun, 0);
+ } catch(e){
+ try {
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+ return cachedSetTimeout.call(null, fun, 0);
+ } catch(e){
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
+ return cachedSetTimeout.call(this, fun, 0);
+ }
+ }
+
+
+}
+function runClearTimeout(marker) {
+ if (cachedClearTimeout === clearTimeout) {
+ //normal enviroments in sane situations
+ return clearTimeout(marker);
+ }
+ // if clearTimeout wasn't available but was latter defined
+ if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+ cachedClearTimeout = clearTimeout;
+ return clearTimeout(marker);
+ }
+ try {
+ // when when somebody has screwed with setTimeout but no I.E. maddness
+ return cachedClearTimeout(marker);
+ } catch (e){
+ try {
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+ return cachedClearTimeout.call(null, marker);
+ } catch (e){
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
+ // Some versions of I.E. have different rules for clearTimeout vs setTimeout
+ return cachedClearTimeout.call(this, marker);
+ }
+ }
+
+
+
+}
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+ if (!draining || !currentQueue) {
+ return;
+ }
+ draining = false;
+ if (currentQueue.length) {
+ queue = currentQueue.concat(queue);
+ } else {
+ queueIndex = -1;
+ }
+ if (queue.length) {
+ drainQueue();
+ }
+}
+
+function drainQueue() {
+ if (draining) {
+ return;
+ }
+ var timeout = runTimeout(cleanUpNextTick);
+ draining = true;
+
+ var len = queue.length;
+ while(len) {
+ currentQueue = queue;
+ queue = [];
+ while (++queueIndex < len) {
+ if (currentQueue) {
+ currentQueue[queueIndex].run();
+ }
+ }
+ queueIndex = -1;
+ len = queue.length;
+ }
+ currentQueue = null;
+ draining = false;
+ runClearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+ var args = new Array(arguments.length - 1);
+ if (arguments.length > 1) {
+ for (var i = 1; i < arguments.length; i++) {
+ args[i - 1] = arguments[i];
+ }
+ }
+ queue.push(new Item(fun, args));
+ if (queue.length === 1 && !draining) {
+ runTimeout(drainQueue);
+ }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+ this.fun = fun;
+ this.array = array;
+}
+Item.prototype.run = function () {
+ this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+process.prependListener = noop;
+process.prependOnceListener = noop;
+
+process.listeners = function (name) { return [] }
+
+process.binding = function (name) {
+ throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+ throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],6:[function(_dereq_,module,exports){
+(function (factory) {
+ if (typeof exports === 'object') {
+ // Node/CommonJS
+ module.exports = factory();
+ } else if (typeof define === 'function' && define.amd) {
+ // AMD
+ define(factory);
+ } else {
+ // Browser globals (with support for web workers)
+ var glob;
+
+ try {
+ glob = window;
+ } catch (e) {
+ glob = self;
+ }
+
+ glob.SparkMD5 = factory();
+ }
+}(function (undefined) {
+
+ 'use strict';
+
+ /*
+ * Fastest md5 implementation around (JKM md5).
+ * Credits: Joseph Myers
+ *
+ * @see http://www.myersdaily.org/joseph/javascript/md5-text.html
+ * @see http://jsperf.com/md5-shootout/7
+ */
+
+ /* this function is much faster,
+ so if possible we use it. Some IEs
+ are the only ones I know of that
+ need the idiotic second function,
+ generated by an if clause. */
+ var add32 = function (a, b) {
+ return (a + b) & 0xFFFFFFFF;
+ },
+ hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
+
+
+ function cmn(q, a, b, x, s, t) {
+ a = add32(add32(a, q), add32(x, t));
+ return add32((a << s) | (a >>> (32 - s)), b);
+ }
+
+ function md5cycle(x, k) {
+ var a = x[0],
+ b = x[1],
+ c = x[2],
+ d = x[3];
+
+ a += (b & c | ~b & d) + k[0] - 680876936 | 0;
+ a = (a << 7 | a >>> 25) + b | 0;
+ d += (a & b | ~a & c) + k[1] - 389564586 | 0;
+ d = (d << 12 | d >>> 20) + a | 0;
+ c += (d & a | ~d & b) + k[2] + 606105819 | 0;
+ c = (c << 17 | c >>> 15) + d | 0;
+ b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
+ b = (b << 22 | b >>> 10) + c | 0;
+ a += (b & c | ~b & d) + k[4] - 176418897 | 0;
+ a = (a << 7 | a >>> 25) + b | 0;
+ d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
+ d = (d << 12 | d >>> 20) + a | 0;
+ c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
+ c = (c << 17 | c >>> 15) + d | 0;
+ b += (c & d | ~c & a) + k[7] - 45705983 | 0;
+ b = (b << 22 | b >>> 10) + c | 0;
+ a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
+ a = (a << 7 | a >>> 25) + b | 0;
+ d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
+ d = (d << 12 | d >>> 20) + a | 0;
+ c += (d & a | ~d & b) + k[10] - 42063 | 0;
+ c = (c << 17 | c >>> 15) + d | 0;
+ b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
+ b = (b << 22 | b >>> 10) + c | 0;
+ a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
+ a = (a << 7 | a >>> 25) + b | 0;
+ d += (a & b | ~a & c) + k[13] - 40341101 | 0;
+ d = (d << 12 | d >>> 20) + a | 0;
+ c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
+ c = (c << 17 | c >>> 15) + d | 0;
+ b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
+ b = (b << 22 | b >>> 10) + c | 0;
+
+ a += (b & d | c & ~d) + k[1] - 165796510 | 0;
+ a = (a << 5 | a >>> 27) + b | 0;
+ d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
+ d = (d << 9 | d >>> 23) + a | 0;
+ c += (d & b | a & ~b) + k[11] + 643717713 | 0;
+ c = (c << 14 | c >>> 18) + d | 0;
+ b += (c & a | d & ~a) + k[0] - 373897302 | 0;
+ b = (b << 20 | b >>> 12) + c | 0;
+ a += (b & d | c & ~d) + k[5] - 701558691 | 0;
+ a = (a << 5 | a >>> 27) + b | 0;
+ d += (a & c | b & ~c) + k[10] + 38016083 | 0;
+ d = (d << 9 | d >>> 23) + a | 0;
+ c += (d & b | a & ~b) + k[15] - 660478335 | 0;
+ c = (c << 14 | c >>> 18) + d | 0;
+ b += (c & a | d & ~a) + k[4] - 405537848 | 0;
+ b = (b << 20 | b >>> 12) + c | 0;
+ a += (b & d | c & ~d) + k[9] + 568446438 | 0;
+ a = (a << 5 | a >>> 27) + b | 0;
+ d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
+ d = (d << 9 | d >>> 23) + a | 0;
+ c += (d & b | a & ~b) + k[3] - 187363961 | 0;
+ c = (c << 14 | c >>> 18) + d | 0;
+ b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
+ b = (b << 20 | b >>> 12) + c | 0;
+ a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
+ a = (a << 5 | a >>> 27) + b | 0;
+ d += (a & c | b & ~c) + k[2] - 51403784 | 0;
+ d = (d << 9 | d >>> 23) + a | 0;
+ c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
+ c = (c << 14 | c >>> 18) + d | 0;
+ b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
+ b = (b << 20 | b >>> 12) + c | 0;
+
+ a += (b ^ c ^ d) + k[5] - 378558 | 0;
+ a = (a << 4 | a >>> 28) + b | 0;
+ d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
+ d = (d << 11 | d >>> 21) + a | 0;
+ c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
+ c = (c << 16 | c >>> 16) + d | 0;
+ b += (c ^ d ^ a) + k[14] - 35309556 | 0;
+ b = (b << 23 | b >>> 9) + c | 0;
+ a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
+ a = (a << 4 | a >>> 28) + b | 0;
+ d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
+ d = (d << 11 | d >>> 21) + a | 0;
+ c += (d ^ a ^ b) + k[7] - 155497632 | 0;
+ c = (c << 16 | c >>> 16) + d | 0;
+ b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
+ b = (b << 23 | b >>> 9) + c | 0;
+ a += (b ^ c ^ d) + k[13] + 681279174 | 0;
+ a = (a << 4 | a >>> 28) + b | 0;
+ d += (a ^ b ^ c) + k[0] - 358537222 | 0;
+ d = (d << 11 | d >>> 21) + a | 0;
+ c += (d ^ a ^ b) + k[3] - 722521979 | 0;
+ c = (c << 16 | c >>> 16) + d | 0;
+ b += (c ^ d ^ a) + k[6] + 76029189 | 0;
+ b = (b << 23 | b >>> 9) + c | 0;
+ a += (b ^ c ^ d) + k[9] - 640364487 | 0;
+ a = (a << 4 | a >>> 28) + b | 0;
+ d += (a ^ b ^ c) + k[12] - 421815835 | 0;
+ d = (d << 11 | d >>> 21) + a | 0;
+ c += (d ^ a ^ b) + k[15] + 530742520 | 0;
+ c = (c << 16 | c >>> 16) + d | 0;
+ b += (c ^ d ^ a) + k[2] - 995338651 | 0;
+ b = (b << 23 | b >>> 9) + c | 0;
+
+ a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
+ a = (a << 6 | a >>> 26) + b | 0;
+ d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
+ d = (d << 10 | d >>> 22) + a | 0;
+ c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
+ c = (c << 15 | c >>> 17) + d | 0;
+ b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
+ b = (b << 21 |b >>> 11) + c | 0;
+ a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
+ a = (a << 6 | a >>> 26) + b | 0;
+ d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
+ d = (d << 10 | d >>> 22) + a | 0;
+ c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
+ c = (c << 15 | c >>> 17) + d | 0;
+ b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
+ b = (b << 21 |b >>> 11) + c | 0;
+ a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
+ a = (a << 6 | a >>> 26) + b | 0;
+ d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
+ d = (d << 10 | d >>> 22) + a | 0;
+ c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
+ c = (c << 15 | c >>> 17) + d | 0;
+ b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
+ b = (b << 21 |b >>> 11) + c | 0;
+ a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
+ a = (a << 6 | a >>> 26) + b | 0;
+ d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
+ d = (d << 10 | d >>> 22) + a | 0;
+ c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
+ c = (c << 15 | c >>> 17) + d | 0;
+ b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
+ b = (b << 21 | b >>> 11) + c | 0;
+
+ x[0] = a + x[0] | 0;
+ x[1] = b + x[1] | 0;
+ x[2] = c + x[2] | 0;
+ x[3] = d + x[3] | 0;
+ }
+
+ function md5blk(s) {
+ var md5blks = [],
+ i; /* Andy King said do it this way. */
+
+ for (i = 0; i < 64; i += 4) {
+ md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
+ }
+ return md5blks;
+ }
+
+ function md5blk_array(a) {
+ var md5blks = [],
+ i; /* Andy King said do it this way. */
+
+ for (i = 0; i < 64; i += 4) {
+ md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
+ }
+ return md5blks;
+ }
+
+ function md51(s) {
+ var n = s.length,
+ state = [1732584193, -271733879, -1732584194, 271733878],
+ i,
+ length,
+ tail,
+ tmp,
+ lo,
+ hi;
+
+ for (i = 64; i <= n; i += 64) {
+ md5cycle(state, md5blk(s.substring(i - 64, i)));
+ }
+ s = s.substring(i - 64);
+ length = s.length;
+ tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+ for (i = 0; i < length; i += 1) {
+ tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
+ }
+ tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+ if (i > 55) {
+ md5cycle(state, tail);
+ for (i = 0; i < 16; i += 1) {
+ tail[i] = 0;
+ }
+ }
+
+ // Beware that the final length might not fit in 32 bits so we take care of that
+ tmp = n * 8;
+ tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+ lo = parseInt(tmp[2], 16);
+ hi = parseInt(tmp[1], 16) || 0;
+
+ tail[14] = lo;
+ tail[15] = hi;
+
+ md5cycle(state, tail);
+ return state;
+ }
+
+ function md51_array(a) {
+ var n = a.length,
+ state = [1732584193, -271733879, -1732584194, 271733878],
+ i,
+ length,
+ tail,
+ tmp,
+ lo,
+ hi;
+
+ for (i = 64; i <= n; i += 64) {
+ md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
+ }
+
+ // Not sure if it is a bug, however IE10 will always produce a sub array of length 1
+ // containing the last element of the parent array if the sub array specified starts
+ // beyond the length of the parent array - weird.
+ // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
+ a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0);
+
+ length = a.length;
+ tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+ for (i = 0; i < length; i += 1) {
+ tail[i >> 2] |= a[i] << ((i % 4) << 3);
+ }
+
+ tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+ if (i > 55) {
+ md5cycle(state, tail);
+ for (i = 0; i < 16; i += 1) {
+ tail[i] = 0;
+ }
+ }
+
+ // Beware that the final length might not fit in 32 bits so we take care of that
+ tmp = n * 8;
+ tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+ lo = parseInt(tmp[2], 16);
+ hi = parseInt(tmp[1], 16) || 0;
+
+ tail[14] = lo;
+ tail[15] = hi;
+
+ md5cycle(state, tail);
+
+ return state;
+ }
+
+ function rhex(n) {
+ var s = '',
+ j;
+ for (j = 0; j < 4; j += 1) {
+ s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
+ }
+ return s;
+ }
+
+ function hex(x) {
+ var i;
+ for (i = 0; i < x.length; i += 1) {
+ x[i] = rhex(x[i]);
+ }
+ return x.join('');
+ }
+
+ // In some cases the fast add32 function cannot be used..
+ if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') {
+ add32 = function (x, y) {
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF),
+ msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+ };
+ }
+
+ // ---------------------------------------------------
+
+ /**
+ * ArrayBuffer slice polyfill.
+ *
+ * @see https://github.com/ttaubert/node-arraybuffer-slice
+ */
+
+ if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
+ (function () {
+ function clamp(val, length) {
+ val = (val | 0) || 0;
+
+ if (val < 0) {
+ return Math.max(val + length, 0);
+ }
+
+ return Math.min(val, length);
+ }
+
+ ArrayBuffer.prototype.slice = function (from, to) {
+ var length = this.byteLength,
+ begin = clamp(from, length),
+ end = length,
+ num,
+ target,
+ targetArray,
+ sourceArray;
+
+ if (to !== undefined) {
+ end = clamp(to, length);
+ }
+
+ if (begin > end) {
+ return new ArrayBuffer(0);
+ }
+
+ num = end - begin;
+ target = new ArrayBuffer(num);
+ targetArray = new Uint8Array(target);
+
+ sourceArray = new Uint8Array(this, begin, num);
+ targetArray.set(sourceArray);
+
+ return target;
+ };
+ })();
+ }
+
+ // ---------------------------------------------------
+
+ /**
+ * Helpers.
+ */
+
+ function toUtf8(str) {
+ if (/[\u0080-\uFFFF]/.test(str)) {
+ str = unescape(encodeURIComponent(str));
+ }
+
+ return str;
+ }
+
+ function utf8Str2ArrayBuffer(str, returnUInt8Array) {
+ var length = str.length,
+ buff = new ArrayBuffer(length),
+ arr = new Uint8Array(buff),
+ i;
+
+ for (i = 0; i < length; i += 1) {
+ arr[i] = str.charCodeAt(i);
+ }
+
+ return returnUInt8Array ? arr : buff;
+ }
+
+ function arrayBuffer2Utf8Str(buff) {
+ return String.fromCharCode.apply(null, new Uint8Array(buff));
+ }
+
+ function concatenateArrayBuffers(first, second, returnUInt8Array) {
+ var result = new Uint8Array(first.byteLength + second.byteLength);
+
+ result.set(new Uint8Array(first));
+ result.set(new Uint8Array(second), first.byteLength);
+
+ return returnUInt8Array ? result : result.buffer;
+ }
+
+ function hexToBinaryString(hex) {
+ var bytes = [],
+ length = hex.length,
+ x;
+
+ for (x = 0; x < length - 1; x += 2) {
+ bytes.push(parseInt(hex.substr(x, 2), 16));
+ }
+
+ return String.fromCharCode.apply(String, bytes);
+ }
+
+ // ---------------------------------------------------
+
+ /**
+ * SparkMD5 OOP implementation.
+ *
+ * Use this class to perform an incremental md5, otherwise use the
+ * static methods instead.
+ */
+
+ function SparkMD5() {
+ // call reset to init the instance
+ this.reset();
+ }
+
+ /**
+ * Appends a string.
+ * A conversion will be applied if an utf8 string is detected.
+ *
+ * @param {String} str The string to be appended
+ *
+ * @return {SparkMD5} The instance itself
+ */
+ SparkMD5.prototype.append = function (str) {
+ // Converts the string to utf8 bytes if necessary
+ // Then append as binary
+ this.appendBinary(toUtf8(str));
+
+ return this;
+ };
+
+ /**
+ * Appends a binary string.
+ *
+ * @param {String} contents The binary string to be appended
+ *
+ * @return {SparkMD5} The instance itself
+ */
+ SparkMD5.prototype.appendBinary = function (contents) {
+ this._buff += contents;
+ this._length += contents.length;
+
+ var length = this._buff.length,
+ i;
+
+ for (i = 64; i <= length; i += 64) {
+ md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
+ }
+
+ this._buff = this._buff.substring(i - 64);
+
+ return this;
+ };
+
+ /**
+ * Finishes the incremental computation, reseting the internal state and
+ * returning the result.
+ *
+ * @param {Boolean} raw True to get the raw string, false to get the hex string
+ *
+ * @return {String} The result
+ */
+ SparkMD5.prototype.end = function (raw) {
+ var buff = this._buff,
+ length = buff.length,
+ i,
+ tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ ret;
+
+ for (i = 0; i < length; i += 1) {
+ tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3);
+ }
+
+ this._finish(tail, length);
+ ret = hex(this._hash);
+
+ if (raw) {
+ ret = hexToBinaryString(ret);
+ }
+
+ this.reset();
+
+ return ret;
+ };
+
+ /**
+ * Resets the internal state of the computation.
+ *
+ * @return {SparkMD5} The instance itself
+ */
+ SparkMD5.prototype.reset = function () {
+ this._buff = '';
+ this._length = 0;
+ this._hash = [1732584193, -271733879, -1732584194, 271733878];
+
+ return this;
+ };
+
+ /**
+ * Gets the internal state of the computation.
+ *
+ * @return {Object} The state
+ */
+ SparkMD5.prototype.getState = function () {
+ return {
+ buff: this._buff,
+ length: this._length,
+ hash: this._hash
+ };
+ };
+
+ /**
+ * Gets the internal state of the computation.
+ *
+ * @param {Object} state The state
+ *
+ * @return {SparkMD5} The instance itself
+ */
+ SparkMD5.prototype.setState = function (state) {
+ this._buff = state.buff;
+ this._length = state.length;
+ this._hash = state.hash;
+
+ return this;
+ };
+
+ /**
+ * Releases memory used by the incremental buffer and other additional
+ * resources. If you plan to use the instance again, use reset instead.
+ */
+ SparkMD5.prototype.destroy = function () {
+ delete this._hash;
+ delete this._buff;
+ delete this._length;
+ };
+
+ /**
+ * Finish the final calculation based on the tail.
+ *
+ * @param {Array} tail The tail (will be modified)
+ * @param {Number} length The length of the remaining buffer
+ */
+ SparkMD5.prototype._finish = function (tail, length) {
+ var i = length,
+ tmp,
+ lo,
+ hi;
+
+ tail[i >> 2] |= 0x80 << ((i % 4) << 3);
+ if (i > 55) {
+ md5cycle(this._hash, tail);
+ for (i = 0; i < 16; i += 1) {
+ tail[i] = 0;
+ }
+ }
+
+ // Do the final computation based on the tail and length
+ // Beware that the final length may not fit in 32 bits so we take care of that
+ tmp = this._length * 8;
+ tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+ lo = parseInt(tmp[2], 16);
+ hi = parseInt(tmp[1], 16) || 0;
+
+ tail[14] = lo;
+ tail[15] = hi;
+ md5cycle(this._hash, tail);
+ };
+
+ /**
+ * Performs the md5 hash on a string.
+ * A conversion will be applied if utf8 string is detected.
+ *
+ * @param {String} str The string
+ * @param {Boolean} raw True to get the raw string, false to get the hex string
+ *
+ * @return {String} The result
+ */
+ SparkMD5.hash = function (str, raw) {
+ // Converts the string to utf8 bytes if necessary
+ // Then compute it using the binary function
+ return SparkMD5.hashBinary(toUtf8(str), raw);
+ };
+
+ /**
+ * Performs the md5 hash on a binary string.
+ *
+ * @param {String} content The binary string
+ * @param {Boolean} raw True to get the raw string, false to get the hex string
+ *
+ * @return {String} The result
+ */
+ SparkMD5.hashBinary = function (content, raw) {
+ var hash = md51(content),
+ ret = hex(hash);
+
+ return raw ? hexToBinaryString(ret) : ret;
+ };
+
+ // ---------------------------------------------------
+
+ /**
+ * SparkMD5 OOP implementation for array buffers.
+ *
+ * Use this class to perform an incremental md5 ONLY for array buffers.
+ */
+ SparkMD5.ArrayBuffer = function () {
+ // call reset to init the instance
+ this.reset();
+ };
+
+ /**
+ * Appends an array buffer.
+ *
+ * @param {ArrayBuffer} arr The array to be appended
+ *
+ * @return {SparkMD5.ArrayBuffer} The instance itself
+ */
+ SparkMD5.ArrayBuffer.prototype.append = function (arr) {
+ var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),
+ length = buff.length,
+ i;
+
+ this._length += arr.byteLength;
+
+ for (i = 64; i <= length; i += 64) {
+ md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
+ }
+
+ this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
+
+ return this;
+ };
+
+ /**
+ * Finishes the incremental computation, reseting the internal state and
+ * returning the result.
+ *
+ * @param {Boolean} raw True to get the raw string, false to get the hex string
+ *
+ * @return {String} The result
+ */
+ SparkMD5.ArrayBuffer.prototype.end = function (raw) {
+ var buff = this._buff,
+ length = buff.length,
+ tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ i,
+ ret;
+
+ for (i = 0; i < length; i += 1) {
+ tail[i >> 2] |= buff[i] << ((i % 4) << 3);
+ }
+
+ this._finish(tail, length);
+ ret = hex(this._hash);
+
+ if (raw) {
+ ret = hexToBinaryString(ret);
+ }
+
+ this.reset();
+
+ return ret;
+ };
+
+ /**
+ * Resets the internal state of the computation.
+ *
+ * @return {SparkMD5.ArrayBuffer} The instance itself
+ */
+ SparkMD5.ArrayBuffer.prototype.reset = function () {
+ this._buff = new Uint8Array(0);
+ this._length = 0;
+ this._hash = [1732584193, -271733879, -1732584194, 271733878];
+
+ return this;
+ };
+
+ /**
+ * Gets the internal state of the computation.
+ *
+ * @return {Object} The state
+ */
+ SparkMD5.ArrayBuffer.prototype.getState = function () {
+ var state = SparkMD5.prototype.getState.call(this);
+
+ // Convert buffer to a string
+ state.buff = arrayBuffer2Utf8Str(state.buff);
+
+ return state;
+ };
+
+ /**
+ * Gets the internal state of the computation.
+ *
+ * @param {Object} state The state
+ *
+ * @return {SparkMD5.ArrayBuffer} The instance itself
+ */
+ SparkMD5.ArrayBuffer.prototype.setState = function (state) {
+ // Convert string to buffer
+ state.buff = utf8Str2ArrayBuffer(state.buff, true);
+
+ return SparkMD5.prototype.setState.call(this, state);
+ };
+
+ SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
+
+ SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
+
+ /**
+ * Performs the md5 hash on an array buffer.
+ *
+ * @param {ArrayBuffer} arr The array buffer
+ * @param {Boolean} raw True to get the raw string, false to get the hex one
+ *
+ * @return {String} The result
+ */
+ SparkMD5.ArrayBuffer.hash = function (arr, raw) {
+ var hash = md51_array(new Uint8Array(arr)),
+ ret = hex(hash);
+
+ return raw ? hexToBinaryString(ret) : ret;
+ };
+
+ return SparkMD5;
+}));
+
+},{}],7:[function(_dereq_,module,exports){
+var v1 = _dereq_(10);
+var v4 = _dereq_(11);
+
+var uuid = v4;
+uuid.v1 = v1;
+uuid.v4 = v4;
+
+module.exports = uuid;
+
+},{"10":10,"11":11}],8:[function(_dereq_,module,exports){
+/**
+ * Convert array of 16 byte values to UUID string format of the form:
+ * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+ */
+var byteToHex = [];
+for (var i = 0; i < 256; ++i) {
+ byteToHex[i] = (i + 0x100).toString(16).substr(1);
+}
+
+function bytesToUuid(buf, offset) {
+ var i = offset || 0;
+ var bth = byteToHex;
+ return bth[buf[i++]] + bth[buf[i++]] +
+ bth[buf[i++]] + bth[buf[i++]] + '-' +
+ bth[buf[i++]] + bth[buf[i++]] + '-' +
+ bth[buf[i++]] + bth[buf[i++]] + '-' +
+ bth[buf[i++]] + bth[buf[i++]] + '-' +
+ bth[buf[i++]] + bth[buf[i++]] +
+ bth[buf[i++]] + bth[buf[i++]] +
+ bth[buf[i++]] + bth[buf[i++]];
+}
+
+module.exports = bytesToUuid;
+
+},{}],9:[function(_dereq_,module,exports){
+// Unique ID creation requires a high quality random # generator. In the
+// browser this is a little complicated due to unknown quality of Math.random()
+// and inconsistent support for the `crypto` API. We do the best we can via
+// feature-detection
+
+// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation.
+var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues.bind(crypto)) ||
+ (typeof(msCrypto) != 'undefined' && msCrypto.getRandomValues.bind(msCrypto));
+if (getRandomValues) {
+ // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
+ var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef
+
+ module.exports = function whatwgRNG() {
+ getRandomValues(rnds8);
+ return rnds8;
+ };
+} else {
+ // Math.random()-based (RNG)
+ //
+ // If all else fails, use Math.random(). It's fast, but is of unspecified
+ // quality.
+ var rnds = new Array(16);
+
+ module.exports = function mathRNG() {
+ for (var i = 0, r; i < 16; i++) {
+ if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
+ rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
+ }
+
+ return rnds;
+ };
+}
+
+},{}],10:[function(_dereq_,module,exports){
+var rng = _dereq_(9);
+var bytesToUuid = _dereq_(8);
+
+// **`v1()` - Generate time-based UUID**
+//
+// Inspired by https://github.com/LiosK/UUID.js
+// and http://docs.python.org/library/uuid.html
+
+var _nodeId;
+var _clockseq;
+
+// Previous uuid creation time
+var _lastMSecs = 0;
+var _lastNSecs = 0;
+
+// See https://github.com/broofa/node-uuid for API details
+function v1(options, buf, offset) {
+ var i = buf && offset || 0;
+ var b = buf || [];
+
+ options = options || {};
+ var node = options.node || _nodeId;
+ var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;
+
+ // node and clockseq need to be initialized to random values if they're not
+ // specified. We do this lazily to minimize issues related to insufficient
+ // system entropy. See #189
+ if (node == null || clockseq == null) {
+ var seedBytes = rng();
+ if (node == null) {
+ // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
+ node = _nodeId = [
+ seedBytes[0] | 0x01,
+ seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]
+ ];
+ }
+ if (clockseq == null) {
+ // Per 4.2.2, randomize (14 bit) clockseq
+ clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
+ }
+ }
+
+ // UUID timestamps are 100 nano-second units since the Gregorian epoch,
+ // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so
+ // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
+ // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
+ var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();
+
+ // Per 4.2.1.2, use count of uuid's generated during the current clock
+ // cycle to simulate higher resolution clock
+ var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;
+
+ // Time since last uuid creation (in msecs)
+ var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;
+
+ // Per 4.2.1.2, Bump clockseq on clock regression
+ if (dt < 0 && options.clockseq === undefined) {
+ clockseq = clockseq + 1 & 0x3fff;
+ }
+
+ // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
+ // time interval
+ if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
+ nsecs = 0;
+ }
+
+ // Per 4.2.1.2 Throw error if too many uuids are requested
+ if (nsecs >= 10000) {
+ throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
+ }
+
+ _lastMSecs = msecs;
+ _lastNSecs = nsecs;
+ _clockseq = clockseq;
+
+ // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
+ msecs += 12219292800000;
+
+ // `time_low`
+ var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
+ b[i++] = tl >>> 24 & 0xff;
+ b[i++] = tl >>> 16 & 0xff;
+ b[i++] = tl >>> 8 & 0xff;
+ b[i++] = tl & 0xff;
+
+ // `time_mid`
+ var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
+ b[i++] = tmh >>> 8 & 0xff;
+ b[i++] = tmh & 0xff;
+
+ // `time_high_and_version`
+ b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
+ b[i++] = tmh >>> 16 & 0xff;
+
+ // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
+ b[i++] = clockseq >>> 8 | 0x80;
+
+ // `clock_seq_low`
+ b[i++] = clockseq & 0xff;
+
+ // `node`
+ for (var n = 0; n < 6; ++n) {
+ b[i + n] = node[n];
+ }
+
+ return buf ? buf : bytesToUuid(b);
+}
+
+module.exports = v1;
+
+},{"8":8,"9":9}],11:[function(_dereq_,module,exports){
+var rng = _dereq_(9);
+var bytesToUuid = _dereq_(8);
+
+function v4(options, buf, offset) {
+ var i = buf && offset || 0;
+
+ if (typeof(options) == 'string') {
+ buf = options === 'binary' ? new Array(16) : null;
+ options = null;
+ }
+ options = options || {};
+
+ var rnds = options.random || (options.rng || rng)();
+
+ // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
+ rnds[6] = (rnds[6] & 0x0f) | 0x40;
+ rnds[8] = (rnds[8] & 0x3f) | 0x80;
+
+ // Copy bytes to buffer, if provided
+ if (buf) {
+ for (var ii = 0; ii < 16; ++ii) {
+ buf[i + ii] = rnds[ii];
+ }
+ }
+
+ return buf || bytesToUuid(rnds);
+}
+
+module.exports = v4;
+
+},{"8":8,"9":9}],12:[function(_dereq_,module,exports){
+'use strict';
+
+/**
+ * Stringify/parse functions that don't operate
+ * recursively, so they avoid call stack exceeded
+ * errors.
+ */
+exports.stringify = function stringify(input) {
+ var queue = [];
+ queue.push({obj: input});
+
+ var res = '';
+ var next, obj, prefix, val, i, arrayPrefix, keys, k, key, value, objPrefix;
+ while ((next = queue.pop())) {
+ obj = next.obj;
+ prefix = next.prefix || '';
+ val = next.val || '';
+ res += prefix;
+ if (val) {
+ res += val;
+ } else if (typeof obj !== 'object') {
+ res += typeof obj === 'undefined' ? null : JSON.stringify(obj);
+ } else if (obj === null) {
+ res += 'null';
+ } else if (Array.isArray(obj)) {
+ queue.push({val: ']'});
+ for (i = obj.length - 1; i >= 0; i--) {
+ arrayPrefix = i === 0 ? '' : ',';
+ queue.push({obj: obj[i], prefix: arrayPrefix});
+ }
+ queue.push({val: '['});
+ } else { // object
+ keys = [];
+ for (k in obj) {
+ if (obj.hasOwnProperty(k)) {
+ keys.push(k);
+ }
+ }
+ queue.push({val: '}'});
+ for (i = keys.length - 1; i >= 0; i--) {
+ key = keys[i];
+ value = obj[key];
+ objPrefix = (i > 0 ? ',' : '');
+ objPrefix += JSON.stringify(key) + ':';
+ queue.push({obj: value, prefix: objPrefix});
+ }
+ queue.push({val: '{'});
+ }
+ }
+ return res;
+};
+
+// Convenience function for the parse function.
+// This pop function is basically copied from
+// pouchCollate.parseIndexableString
+function pop(obj, stack, metaStack) {
+ var lastMetaElement = metaStack[metaStack.length - 1];
+ if (obj === lastMetaElement.element) {
+ // popping a meta-element, e.g. an object whose value is another object
+ metaStack.pop();
+ lastMetaElement = metaStack[metaStack.length - 1];
+ }
+ var element = lastMetaElement.element;
+ var lastElementIndex = lastMetaElement.index;
+ if (Array.isArray(element)) {
+ element.push(obj);
+ } else if (lastElementIndex === stack.length - 2) { // obj with key+value
+ var key = stack.pop();
+ element[key] = obj;
+ } else {
+ stack.push(obj); // obj with key only
+ }
+}
+
+exports.parse = function (str) {
+ var stack = [];
+ var metaStack = []; // stack for arrays and objects
+ var i = 0;
+ var collationIndex,parsedNum,numChar;
+ var parsedString,lastCh,numConsecutiveSlashes,ch;
+ var arrayElement, objElement;
+ while (true) {
+ collationIndex = str[i++];
+ if (collationIndex === '}' ||
+ collationIndex === ']' ||
+ typeof collationIndex === 'undefined') {
+ if (stack.length === 1) {
+ return stack.pop();
+ } else {
+ pop(stack.pop(), stack, metaStack);
+ continue;
+ }
+ }
+ switch (collationIndex) {
+ case ' ':
+ case '\t':
+ case '\n':
+ case ':':
+ case ',':
+ break;
+ case 'n':
+ i += 3; // 'ull'
+ pop(null, stack, metaStack);
+ break;
+ case 't':
+ i += 3; // 'rue'
+ pop(true, stack, metaStack);
+ break;
+ case 'f':
+ i += 4; // 'alse'
+ pop(false, stack, metaStack);
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ parsedNum = '';
+ i--;
+ while (true) {
+ numChar = str[i++];
+ if (/[\d\.\-e\+]/.test(numChar)) {
+ parsedNum += numChar;
+ } else {
+ i--;
+ break;
+ }
+ }
+ pop(parseFloat(parsedNum), stack, metaStack);
+ break;
+ case '"':
+ parsedString = '';
+ lastCh = void 0;
+ numConsecutiveSlashes = 0;
+ while (true) {
+ ch = str[i++];
+ if (ch !== '"' || (lastCh === '\\' &&
+ numConsecutiveSlashes % 2 === 1)) {
+ parsedString += ch;
+ lastCh = ch;
+ if (lastCh === '\\') {
+ numConsecutiveSlashes++;
+ } else {
+ numConsecutiveSlashes = 0;
+ }
+ } else {
+ break;
+ }
+ }
+ pop(JSON.parse('"' + parsedString + '"'), stack, metaStack);
+ break;
+ case '[':
+ arrayElement = { element: [], index: stack.length };
+ stack.push(arrayElement.element);
+ metaStack.push(arrayElement);
+ break;
+ case '{':
+ objElement = { element: {}, index: stack.length };
+ stack.push(objElement.element);
+ metaStack.push(objElement);
+ break;
+ default:
+ throw new Error(
+ 'unexpectedly reached end of input: ' + collationIndex);
+ }
+ }
+};
+
+},{}],13:[function(_dereq_,module,exports){
+(function (process,global){
+'use strict';
+
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+var immediate = _interopDefault(_dereq_(3));
+var uuidV4 = _interopDefault(_dereq_(7));
+var Md5 = _interopDefault(_dereq_(6));
+var vuvuzela = _interopDefault(_dereq_(12));
+var getArguments = _interopDefault(_dereq_(1));
+var inherits = _interopDefault(_dereq_(4));
+var events = _dereq_(2);
+
+function mangle(key) {
+ return '$' + key;
+}
+function unmangle(key) {
+ return key.substring(1);
+}
+function Map$1() {
+ this._store = {};
+}
+Map$1.prototype.get = function (key) {
+ var mangled = mangle(key);
+ return this._store[mangled];
+};
+Map$1.prototype.set = function (key, value) {
+ var mangled = mangle(key);
+ this._store[mangled] = value;
+ return true;
+};
+Map$1.prototype.has = function (key) {
+ var mangled = mangle(key);
+ return mangled in this._store;
+};
+Map$1.prototype["delete"] = function (key) {
+ var mangled = mangle(key);
+ var res = mangled in this._store;
+ delete this._store[mangled];
+ return res;
+};
+Map$1.prototype.forEach = function (cb) {
+ var keys = Object.keys(this._store);
+ for (var i = 0, len = keys.length; i < len; i++) {
+ var key = keys[i];
+ var value = this._store[key];
+ key = unmangle(key);
+ cb(value, key);
+ }
+};
+Object.defineProperty(Map$1.prototype, 'size', {
+ get: function () {
+ return Object.keys(this._store).length;
+ }
+});
+
+function Set$1(array) {
+ this._store = new Map$1();
+
+ // init with an array
+ if (array && Array.isArray(array)) {
+ for (var i = 0, len = array.length; i < len; i++) {
+ this.add(array[i]);
+ }
+ }
+}
+Set$1.prototype.add = function (key) {
+ return this._store.set(key, true);
+};
+Set$1.prototype.has = function (key) {
+ return this._store.has(key);
+};
+Set$1.prototype.forEach = function (cb) {
+ this._store.forEach(function (value, key) {
+ cb(key);
+ });
+};
+Object.defineProperty(Set$1.prototype, 'size', {
+ get: function () {
+ return this._store.size;
+ }
+});
+
+/* global Map,Set,Symbol */
+// Based on https://kangax.github.io/compat-table/es6/ we can sniff out
+// incomplete Map/Set implementations which would otherwise cause our tests to fail.
+// Notably they fail in IE11 and iOS 8.4, which this prevents.
+function supportsMapAndSet() {
+ if (typeof Symbol === 'undefined' || typeof Map === 'undefined' || typeof Set === 'undefined') {
+ return false;
+ }
+ var prop = Object.getOwnPropertyDescriptor(Map, Symbol.species);
+ return prop && 'get' in prop && Map[Symbol.species] === Map;
+}
+
+// based on https://github.com/montagejs/collections
+
+var ExportedSet;
+var ExportedMap;
+
+{
+ if (supportsMapAndSet()) { // prefer built-in Map/Set
+ ExportedSet = Set;
+ ExportedMap = Map;
+ } else { // fall back to our polyfill
+ ExportedSet = Set$1;
+ ExportedMap = Map$1;
+ }
+}
+
+function isBinaryObject(object) {
+ return (typeof ArrayBuffer !== 'undefined' && object instanceof ArrayBuffer) ||
+ (typeof Blob !== 'undefined' && object instanceof Blob);
+}
+
+function cloneArrayBuffer(buff) {
+ if (typeof buff.slice === 'function') {
+ return buff.slice(0);
+ }
+ // IE10-11 slice() polyfill
+ var target = new ArrayBuffer(buff.byteLength);
+ var targetArray = new Uint8Array(target);
+ var sourceArray = new Uint8Array(buff);
+ targetArray.set(sourceArray);
+ return target;
+}
+
+function cloneBinaryObject(object) {
+ if (object instanceof ArrayBuffer) {
+ return cloneArrayBuffer(object);
+ }
+ var size = object.size;
+ var type = object.type;
+ // Blob
+ if (typeof object.slice === 'function') {
+ return object.slice(0, size, type);
+ }
+ // PhantomJS slice() replacement
+ return object.webkitSlice(0, size, type);
+}
+
+// most of this is borrowed from lodash.isPlainObject:
+// https://github.com/fis-components/lodash.isplainobject/
+// blob/29c358140a74f252aeb08c9eb28bef86f2217d4a/index.js
+
+var funcToString = Function.prototype.toString;
+var objectCtorString = funcToString.call(Object);
+
+function isPlainObject(value) {
+ var proto = Object.getPrototypeOf(value);
+ /* istanbul ignore if */
+ if (proto === null) { // not sure when this happens, but I guess it can
+ return true;
+ }
+ var Ctor = proto.constructor;
+ return (typeof Ctor == 'function' &&
+ Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
+}
+
+function clone(object) {
+ var newObject;
+ var i;
+ var len;
+
+ if (!object || typeof object !== 'object') {
+ return object;
+ }
+
+ if (Array.isArray(object)) {
+ newObject = [];
+ for (i = 0, len = object.length; i < len; i++) {
+ newObject[i] = clone(object[i]);
+ }
+ return newObject;
+ }
+
+ // special case: to avoid inconsistencies between IndexedDB
+ // and other backends, we automatically stringify Dates
+ if (object instanceof Date) {
+ return object.toISOString();
+ }
+
+ if (isBinaryObject(object)) {
+ return cloneBinaryObject(object);
+ }
+
+ if (!isPlainObject(object)) {
+ return object; // don't clone objects like Workers
+ }
+
+ newObject = {};
+ for (i in object) {
+ /* istanbul ignore else */
+ if (Object.prototype.hasOwnProperty.call(object, i)) {
+ var value = clone(object[i]);
+ if (typeof value !== 'undefined') {
+ newObject[i] = value;
+ }
+ }
+ }
+ return newObject;
+}
+
+function once(fun) {
+ var called = false;
+ return getArguments(function (args) {
+ /* istanbul ignore if */
+ if (called) {
+ // this is a smoke test and should never actually happen
+ throw new Error('once called more than once');
+ } else {
+ called = true;
+ fun.apply(this, args);
+ }
+ });
+}
+
+function toPromise(func) {
+ //create the function we will be returning
+ return getArguments(function (args) {
+ // Clone arguments
+ args = clone(args);
+ var self = this;
+ // if the last argument is a function, assume its a callback
+ var usedCB = (typeof args[args.length - 1] === 'function') ? args.pop() : false;
+ var promise = new Promise(function (fulfill, reject) {
+ var resp;
+ try {
+ var callback = once(function (err, mesg) {
+ if (err) {
+ reject(err);
+ } else {
+ fulfill(mesg);
+ }
+ });
+ // create a callback for this invocation
+ // apply the function in the orig context
+ args.push(callback);
+ resp = func.apply(self, args);
+ if (resp && typeof resp.then === 'function') {
+ fulfill(resp);
+ }
+ } catch (e) {
+ reject(e);
+ }
+ });
+ // if there is a callback, call it back
+ if (usedCB) {
+ promise.then(function (result) {
+ usedCB(null, result);
+ }, usedCB);
+ }
+ return promise;
+ });
+}
+
+function logApiCall(self, name, args) {
+ /* istanbul ignore if */
+ if (self.constructor.listeners('debug').length) {
+ var logArgs = ['api', self.name, name];
+ for (var i = 0; i < args.length - 1; i++) {
+ logArgs.push(args[i]);
+ }
+ self.constructor.emit('debug', logArgs);
+
+ // override the callback itself to log the response
+ var origCallback = args[args.length - 1];
+ args[args.length - 1] = function (err, res) {
+ var responseArgs = ['api', self.name, name];
+ responseArgs = responseArgs.concat(
+ err ? ['error', err] : ['success', res]
+ );
+ self.constructor.emit('debug', responseArgs);
+ origCallback(err, res);
+ };
+ }
+}
+
+function adapterFun(name, callback) {
+ return toPromise(getArguments(function (args) {
+ if (this._closed) {
+ return Promise.reject(new Error('database is closed'));
+ }
+ if (this._destroyed) {
+ return Promise.reject(new Error('database is destroyed'));
+ }
+ var self = this;
+ logApiCall(self, name, args);
+ if (!this.taskqueue.isReady) {
+ return new Promise(function (fulfill, reject) {
+ self.taskqueue.addTask(function (failed) {
+ if (failed) {
+ reject(failed);
+ } else {
+ fulfill(self[name].apply(self, args));
+ }
+ });
+ });
+ }
+ return callback.apply(this, args);
+ }));
+}
+
+// like underscore/lodash _.pick()
+function pick(obj, arr) {
+ var res = {};
+ for (var i = 0, len = arr.length; i < len; i++) {
+ var prop = arr[i];
+ if (prop in obj) {
+ res[prop] = obj[prop];
+ }
+ }
+ return res;
+}
+
+// Most browsers throttle concurrent requests at 6, so it's silly
+// to shim _bulk_get by trying to launch potentially hundreds of requests
+// and then letting the majority time out. We can handle this ourselves.
+var MAX_NUM_CONCURRENT_REQUESTS = 6;
+
+function identityFunction(x) {
+ return x;
+}
+
+function formatResultForOpenRevsGet(result) {
+ return [{
+ ok: result
+ }];
+}
+
+// shim for P/CouchDB adapters that don't directly implement _bulk_get
+function bulkGet(db, opts, callback) {
+ var requests = opts.docs;
+
+ // consolidate into one request per doc if possible
+ var requestsById = new ExportedMap();
+ requests.forEach(function (request) {
+ if (requestsById.has(request.id)) {
+ requestsById.get(request.id).push(request);
+ } else {
+ requestsById.set(request.id, [request]);
+ }
+ });
+
+ var numDocs = requestsById.size;
+ var numDone = 0;
+ var perDocResults = new Array(numDocs);
+
+ function collapseResultsAndFinish() {
+ var results = [];
+ perDocResults.forEach(function (res) {
+ res.docs.forEach(function (info) {
+ results.push({
+ id: res.id,
+ docs: [info]
+ });
+ });
+ });
+ callback(null, {results: results});
+ }
+
+ function checkDone() {
+ if (++numDone === numDocs) {
+ collapseResultsAndFinish();
+ }
+ }
+
+ function gotResult(docIndex, id, docs) {
+ perDocResults[docIndex] = {id: id, docs: docs};
+ checkDone();
+ }
+
+ var allRequests = [];
+ requestsById.forEach(function (value, key) {
+ allRequests.push(key);
+ });
+
+ var i = 0;
+
+ function nextBatch() {
+
+ if (i >= allRequests.length) {
+ return;
+ }
+
+ var upTo = Math.min(i + MAX_NUM_CONCURRENT_REQUESTS, allRequests.length);
+ var batch = allRequests.slice(i, upTo);
+ processBatch(batch, i);
+ i += batch.length;
+ }
+
+ function processBatch(batch, offset) {
+ batch.forEach(function (docId, j) {
+ var docIdx = offset + j;
+ var docRequests = requestsById.get(docId);
+
+ // just use the first request as the "template"
+ // TODO: The _bulk_get API allows for more subtle use cases than this,
+ // but for now it is unlikely that there will be a mix of different
+ // "atts_since" or "attachments" in the same request, since it's just
+ // replicate.js that is using this for the moment.
+ // Also, atts_since is aspirational, since we don't support it yet.
+ var docOpts = pick(docRequests[0], ['atts_since', 'attachments']);
+ docOpts.open_revs = docRequests.map(function (request) {
+ // rev is optional, open_revs disallowed
+ return request.rev;
+ });
+
+ // remove falsey / undefined revisions
+ docOpts.open_revs = docOpts.open_revs.filter(identityFunction);
+
+ var formatResult = identityFunction;
+
+ if (docOpts.open_revs.length === 0) {
+ delete docOpts.open_revs;
+
+ // when fetching only the "winning" leaf,
+ // transform the result so it looks like an open_revs
+ // request
+ formatResult = formatResultForOpenRevsGet;
+ }
+
+ // globally-supplied options
+ ['revs', 'attachments', 'binary', 'ajax', 'latest'].forEach(function (param) {
+ if (param in opts) {
+ docOpts[param] = opts[param];
+ }
+ });
+ db.get(docId, docOpts, function (err, res) {
+ var result;
+ /* istanbul ignore if */
+ if (err) {
+ result = [{error: err}];
+ } else {
+ result = formatResult(res);
+ }
+ gotResult(docIdx, docId, result);
+ nextBatch();
+ });
+ });
+ }
+
+ nextBatch();
+
+}
+
+var hasLocal;
+
+try {
+ localStorage.setItem('_pouch_check_localstorage', 1);
+ hasLocal = !!localStorage.getItem('_pouch_check_localstorage');
+} catch (e) {
+ hasLocal = false;
+}
+
+function hasLocalStorage() {
+ return hasLocal;
+}
+
+// Custom nextTick() shim for browsers. In node, this will just be process.nextTick(). We
+
+inherits(Changes, events.EventEmitter);
+
+/* istanbul ignore next */
+function attachBrowserEvents(self) {
+ if (hasLocalStorage()) {
+ addEventListener("storage", function (e) {
+ self.emit(e.key);
+ });
+ }
+}
+
+function Changes() {
+ events.EventEmitter.call(this);
+ this._listeners = {};
+
+ attachBrowserEvents(this);
+}
+Changes.prototype.addListener = function (dbName, id, db, opts) {
+ /* istanbul ignore if */
+ if (this._listeners[id]) {
+ return;
+ }
+ var self = this;
+ var inprogress = false;
+ function eventFunction() {
+ /* istanbul ignore if */
+ if (!self._listeners[id]) {
+ return;
+ }
+ if (inprogress) {
+ inprogress = 'waiting';
+ return;
+ }
+ inprogress = true;
+ var changesOpts = pick(opts, [
+ 'style', 'include_docs', 'attachments', 'conflicts', 'filter',
+ 'doc_ids', 'view', 'since', 'query_params', 'binary', 'return_docs'
+ ]);
+
+ /* istanbul ignore next */
+ function onError() {
+ inprogress = false;
+ }
+
+ db.changes(changesOpts).on('change', function (c) {
+ if (c.seq > opts.since && !opts.cancelled) {
+ opts.since = c.seq;
+ opts.onChange(c);
+ }
+ }).on('complete', function () {
+ if (inprogress === 'waiting') {
+ immediate(eventFunction);
+ }
+ inprogress = false;
+ }).on('error', onError);
+ }
+ this._listeners[id] = eventFunction;
+ this.on(dbName, eventFunction);
+};
+
+Changes.prototype.removeListener = function (dbName, id) {
+ /* istanbul ignore if */
+ if (!(id in this._listeners)) {
+ return;
+ }
+ events.EventEmitter.prototype.removeListener.call(this, dbName,
+ this._listeners[id]);
+ delete this._listeners[id];
+};
+
+
+/* istanbul ignore next */
+Changes.prototype.notifyLocalWindows = function (dbName) {
+ //do a useless change on a storage thing
+ //in order to get other windows's listeners to activate
+ if (hasLocalStorage()) {
+ localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
+ }
+};
+
+Changes.prototype.notify = function (dbName) {
+ this.emit(dbName);
+ this.notifyLocalWindows(dbName);
+};
+
+function guardedConsole(method) {
+ /* istanbul ignore else */
+ if (typeof console !== 'undefined' && typeof console[method] === 'function') {
+ var args = Array.prototype.slice.call(arguments, 1);
+ console[method].apply(console, args);
+ }
+}
+
+function randomNumber(min, max) {
+ var maxTimeout = 600000; // Hard-coded default of 10 minutes
+ min = parseInt(min, 10) || 0;
+ max = parseInt(max, 10);
+ if (max !== max || max <= min) {
+ max = (min || 1) << 1; //doubling
+ } else {
+ max = max + 1;
+ }
+ // In order to not exceed maxTimeout, pick a random value between half of maxTimeout and maxTimeout
+ if (max > maxTimeout) {
+ min = maxTimeout >> 1; // divide by two
+ max = maxTimeout;
+ }
+ var ratio = Math.random();
+ var range = max - min;
+
+ return ~~(range * ratio + min); // ~~ coerces to an int, but fast.
+}
+
+function defaultBackOff(min) {
+ var max = 0;
+ if (!min) {
+ max = 2000;
+ }
+ return randomNumber(min, max);
+}
+
+// designed to give info to browser users, who are disturbed
+// when they see http errors in the console
+function explainError(status, str) {
+ guardedConsole('info', 'The above ' + status + ' is totally normal. ' + str);
+}
+
+var assign;
+{
+ if (typeof Object.assign === 'function') {
+ assign = Object.assign;
+ } else {
+ // lite Object.assign polyfill based on
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
+ assign = function (target) {
+ var to = Object(target);
+
+ for (var index = 1; index < arguments.length; index++) {
+ var nextSource = arguments[index];
+
+ if (nextSource != null) { // Skip over if undefined or null
+ for (var nextKey in nextSource) {
+ // Avoid bugs when hasOwnProperty is shadowed
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
+ to[nextKey] = nextSource[nextKey];
+ }
+ }
+ }
+ }
+ return to;
+ };
+ }
+}
+
+var $inject_Object_assign = assign;
+
+inherits(PouchError, Error);
+
+function PouchError(status, error, reason) {
+ Error.call(this, reason);
+ this.status = status;
+ this.name = error;
+ this.message = reason;
+ this.error = true;
+}
+
+PouchError.prototype.toString = function () {
+ return JSON.stringify({
+ status: this.status,
+ name: this.name,
+ message: this.message,
+ reason: this.reason
+ });
+};
+
+var UNAUTHORIZED = new PouchError(401, 'unauthorized', "Name or password is incorrect.");
+var MISSING_BULK_DOCS = new PouchError(400, 'bad_request', "Missing JSON list of 'docs'");
+var MISSING_DOC = new PouchError(404, 'not_found', 'missing');
+var REV_CONFLICT = new PouchError(409, 'conflict', 'Document update conflict');
+var INVALID_ID = new PouchError(400, 'bad_request', '_id field must contain a string');
+var MISSING_ID = new PouchError(412, 'missing_id', '_id is required for puts');
+var RESERVED_ID = new PouchError(400, 'bad_request', 'Only reserved document ids may start with underscore.');
+var NOT_OPEN = new PouchError(412, 'precondition_failed', 'Database not open');
+var UNKNOWN_ERROR = new PouchError(500, 'unknown_error', 'Database encountered an unknown error');
+var BAD_ARG = new PouchError(500, 'badarg', 'Some query argument is invalid');
+var INVALID_REQUEST = new PouchError(400, 'invalid_request', 'Request was invalid');
+var QUERY_PARSE_ERROR = new PouchError(400, 'query_parse_error', 'Some query parameter is invalid');
+var DOC_VALIDATION = new PouchError(500, 'doc_validation', 'Bad special document member');
+var BAD_REQUEST = new PouchError(400, 'bad_request', 'Something wrong with the request');
+var NOT_AN_OBJECT = new PouchError(400, 'bad_request', 'Document must be a JSON object');
+var DB_MISSING = new PouchError(404, 'not_found', 'Database not found');
+var IDB_ERROR = new PouchError(500, 'indexed_db_went_bad', 'unknown');
+var WSQ_ERROR = new PouchError(500, 'web_sql_went_bad', 'unknown');
+var LDB_ERROR = new PouchError(500, 'levelDB_went_went_bad', 'unknown');
+var FORBIDDEN = new PouchError(403, 'forbidden', 'Forbidden by design doc validate_doc_update function');
+var INVALID_REV = new PouchError(400, 'bad_request', 'Invalid rev format');
+var FILE_EXISTS = new PouchError(412, 'file_exists', 'The database could not be created, the file already exists.');
+var MISSING_STUB = new PouchError(412, 'missing_stub', 'A pre-existing attachment stub wasn\'t found');
+var INVALID_URL = new PouchError(413, 'invalid_url', 'Provided URL is invalid');
+
+function createError(error, reason) {
+ function CustomPouchError(reason) {
+ // inherit error properties from our parent error manually
+ // so as to allow proper JSON parsing.
+ /* jshint ignore:start */
+ for (var p in error) {
+ if (typeof error[p] !== 'function') {
+ this[p] = error[p];
+ }
+ }
+ /* jshint ignore:end */
+ if (reason !== undefined) {
+ this.reason = reason;
+ }
+ }
+ CustomPouchError.prototype = PouchError.prototype;
+ return new CustomPouchError(reason);
+}
+
+function generateErrorFromResponse(err) {
+
+ if (typeof err !== 'object') {
+ var data = err;
+ err = UNKNOWN_ERROR;
+ err.data = data;
+ }
+
+ if ('error' in err && err.error === 'conflict') {
+ err.name = 'conflict';
+ err.status = 409;
+ }
+
+ if (!('name' in err)) {
+ err.name = err.error || 'unknown';
+ }
+
+ if (!('status' in err)) {
+ err.status = 500;
+ }
+
+ if (!('message' in err)) {
+ err.message = err.message || err.reason;
+ }
+
+ return err;
+}
+
+function tryFilter(filter, doc, req) {
+ try {
+ return !filter(doc, req);
+ } catch (err) {
+ var msg = 'Filter function threw: ' + err.toString();
+ return createError(BAD_REQUEST, msg);
+ }
+}
+
+function filterChange(opts) {
+ var req = {};
+ var hasFilter = opts.filter && typeof opts.filter === 'function';
+ req.query = opts.query_params;
+
+ return function filter(change) {
+ if (!change.doc) {
+ // CSG sends events on the changes feed that don't have documents,
+ // this hack makes a whole lot of existing code robust.
+ change.doc = {};
+ }
+
+ var filterReturn = hasFilter && tryFilter(opts.filter, change.doc, req);
+
+ if (typeof filterReturn === 'object') {
+ return filterReturn;
+ }
+
+ if (filterReturn) {
+ return false;
+ }
+
+ if (!opts.include_docs) {
+ delete change.doc;
+ } else if (!opts.attachments) {
+ for (var att in change.doc._attachments) {
+ /* istanbul ignore else */
+ if (change.doc._attachments.hasOwnProperty(att)) {
+ change.doc._attachments[att].stub = true;
+ }
+ }
+ }
+ return true;
+ };
+}
+
+function flatten(arrs) {
+ var res = [];
+ for (var i = 0, len = arrs.length; i < len; i++) {
+ res = res.concat(arrs[i]);
+ }
+ return res;
+}
+
+// shim for Function.prototype.name,
+
+// Determine id an ID is valid
+// - invalid IDs begin with an underescore that does not begin '_design' or
+// '_local'
+// - any other string value is a valid id
+// Returns the specific error object for each case
+function invalidIdError(id) {
+ var err;
+ if (!id) {
+ err = createError(MISSING_ID);
+ } else if (typeof id !== 'string') {
+ err = createError(INVALID_ID);
+ } else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
+ err = createError(RESERVED_ID);
+ }
+ if (err) {
+ throw err;
+ }
+}
+
+// Checks if a PouchDB object is "remote" or not. This is
+
+function isRemote(db) {
+ if (typeof db._remote === 'boolean') {
+ return db._remote;
+ }
+ /* istanbul ignore next */
+ if (typeof db.type === 'function') {
+ guardedConsole('warn',
+ 'db.type() is deprecated and will be removed in ' +
+ 'a future version of PouchDB');
+ return db.type() === 'http';
+ }
+ /* istanbul ignore next */
+ return false;
+}
+
+function listenerCount(ee, type) {
+ return 'listenerCount' in ee ? ee.listenerCount(type) :
+ events.EventEmitter.listenerCount(ee, type);
+}
+
+function parseDesignDocFunctionName(s) {
+ if (!s) {
+ return null;
+ }
+ var parts = s.split('/');
+ if (parts.length === 2) {
+ return parts;
+ }
+ if (parts.length === 1) {
+ return [s, s];
+ }
+ return null;
+}
+
+function normalizeDesignDocFunctionName(s) {
+ var normalized = parseDesignDocFunctionName(s);
+ return normalized ? normalized.join('/') : null;
+}
+
+// originally parseUri 1.2.2, now patched by us
+// (c) Steven Levithan <stevenlevithan.com>
+// MIT License
+var keys = ["source", "protocol", "authority", "userInfo", "user", "password",
+ "host", "port", "relative", "path", "directory", "file", "query", "anchor"];
+var qName ="queryKey";
+var qParser = /(?:^|&)([^&=]*)=?([^&]*)/g;
+
+// use the "loose" parser
+/* eslint maxlen: 0, no-useless-escape: 0 */
+var parser = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
+
+function parseUri(str) {
+ var m = parser.exec(str);
+ var uri = {};
+ var i = 14;
+
+ while (i--) {
+ var key = keys[i];
+ var value = m[i] || "";
+ var encoded = ['user', 'password'].indexOf(key) !== -1;
+ uri[key] = encoded ? decodeURIComponent(value) : value;
+ }
+
+ uri[qName] = {};
+ uri[keys[12]].replace(qParser, function ($0, $1, $2) {
+ if ($1) {
+ uri[qName][$1] = $2;
+ }
+ });
+
+ return uri;
+}
+
+// Based on https://github.com/alexdavid/scope-eval v0.0.3
+// (source: https://unpkg.com/scope-eval@0.0.3/scope_eval.js)
+// This is basically just a wrapper around new Function()
+
+function scopeEval(source, scope) {
+ var keys = [];
+ var values = [];
+ for (var key in scope) {
+ if (scope.hasOwnProperty(key)) {
+ keys.push(key);
+ values.push(scope[key]);
+ }
+ }
+ keys.push(source);
+ return Function.apply(null, keys).apply(null, values);
+}
+
+// this is essentially the "update sugar" function from daleharvey/pouchdb#1388
+// the diffFun tells us what delta to apply to the doc. it either returns
+// the doc, or false if it doesn't need to do an update after all
+function upsert(db, docId, diffFun) {
+ return new Promise(function (fulfill, reject) {
+ db.get(docId, function (err, doc) {
+ if (err) {
+ /* istanbul ignore next */
+ if (err.status !== 404) {
+ return reject(err);
+ }
+ doc = {};
+ }
+
+ // the user might change the _rev, so save it for posterity
+ var docRev = doc._rev;
+ var newDoc = diffFun(doc);
+
+ if (!newDoc) {
+ // if the diffFun returns falsy, we short-circuit as
+ // an optimization
+ return fulfill({updated: false, rev: docRev});
+ }
+
+ // users aren't allowed to modify these values,
+ // so reset them here
+ newDoc._id = docId;
+ newDoc._rev = docRev;
+ fulfill(tryAndPut(db, newDoc, diffFun));
+ });
+ });
+}
+
+function tryAndPut(db, doc, diffFun) {
+ return db.put(doc).then(function (res) {
+ return {
+ updated: true,
+ rev: res.rev
+ };
+ }, function (err) {
+ /* istanbul ignore next */
+ if (err.status !== 409) {
+ throw err;
+ }
+ return upsert(db, doc._id, diffFun);
+ });
+}
+
+var thisAtob = function (str) {
+ return atob(str);
+};
+
+var thisBtoa = function (str) {
+ return btoa(str);
+};
+
+// Abstracts constructing a Blob object, so it also works in older
+// browsers that don't support the native Blob constructor (e.g.
+// old QtWebKit versions, Android < 4.4).
+function createBlob(parts, properties) {
+ /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
+ parts = parts || [];
+ properties = properties || {};
+ try {
+ return new Blob(parts, properties);
+ } catch (e) {
+ if (e.name !== "TypeError") {
+ throw e;
+ }
+ var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder :
+ typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder :
+ typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder :
+ WebKitBlobBuilder;
+ var builder = new Builder();
+ for (var i = 0; i < parts.length; i += 1) {
+ builder.append(parts[i]);
+ }
+ return builder.getBlob(properties.type);
+ }
+}
+
+// From http://stackoverflow.com/questions/14967647/ (continues on next line)
+// encode-decode-image-with-base64-breaks-image (2013-04-21)
+function binaryStringToArrayBuffer(bin) {
+ var length = bin.length;
+ var buf = new ArrayBuffer(length);
+ var arr = new Uint8Array(buf);
+ for (var i = 0; i < length; i++) {
+ arr[i] = bin.charCodeAt(i);
+ }
+ return buf;
+}
+
+function binStringToBluffer(binString, type) {
+ return createBlob([binaryStringToArrayBuffer(binString)], {type: type});
+}
+
+function b64ToBluffer(b64, type) {
+ return binStringToBluffer(thisAtob(b64), type);
+}
+
+//Can't find original post, but this is close
+//http://stackoverflow.com/questions/6965107/ (continues on next line)
+//converting-between-strings-and-arraybuffers
+function arrayBufferToBinaryString(buffer) {
+ var binary = '';
+ var bytes = new Uint8Array(buffer);
+ var length = bytes.byteLength;
+ for (var i = 0; i < length; i++) {
+ binary += String.fromCharCode(bytes[i]);
+ }
+ return binary;
+}
+
+// shim for browsers that don't support it
+function readAsBinaryString(blob, callback) {
+ var reader = new FileReader();
+ var hasBinaryString = typeof reader.readAsBinaryString === 'function';
+ reader.onloadend = function (e) {
+ var result = e.target.result || '';
+ if (hasBinaryString) {
+ return callback(result);
+ }
+ callback(arrayBufferToBinaryString(result));
+ };
+ if (hasBinaryString) {
+ reader.readAsBinaryString(blob);
+ } else {
+ reader.readAsArrayBuffer(blob);
+ }
+}
+
+function blobToBinaryString(blobOrBuffer, callback) {
+ readAsBinaryString(blobOrBuffer, function (bin) {
+ callback(bin);
+ });
+}
+
+function blobToBase64(blobOrBuffer, callback) {
+ blobToBinaryString(blobOrBuffer, function (base64) {
+ callback(thisBtoa(base64));
+ });
+}
+
+// simplified API. universal browser support is assumed
+function readAsArrayBuffer(blob, callback) {
+ var reader = new FileReader();
+ reader.onloadend = function (e) {
+ var result = e.target.result || new ArrayBuffer(0);
+ callback(result);
+ };
+ reader.readAsArrayBuffer(blob);
+}
+
+// this is not used in the browser
+
+var setImmediateShim = global.setImmediate || global.setTimeout;
+var MD5_CHUNK_SIZE = 32768;
+
+function rawToBase64(raw) {
+ return thisBtoa(raw);
+}
+
+function sliceBlob(blob, start, end) {
+ if (blob.webkitSlice) {
+ return blob.webkitSlice(start, end);
+ }
+ return blob.slice(start, end);
+}
+
+function appendBlob(buffer, blob, start, end, callback) {
+ if (start > 0 || end < blob.size) {
+ // only slice blob if we really need to
+ blob = sliceBlob(blob, start, end);
+ }
+ readAsArrayBuffer(blob, function (arrayBuffer) {
+ buffer.append(arrayBuffer);
+ callback();
+ });
+}
+
+function appendString(buffer, string, start, end, callback) {
+ if (start > 0 || end < string.length) {
+ // only create a substring if we really need to
+ string = string.substring(start, end);
+ }
+ buffer.appendBinary(string);
+ callback();
+}
+
+function binaryMd5(data, callback) {
+ var inputIsString = typeof data === 'string';
+ var len = inputIsString ? data.length : data.size;
+ var chunkSize = Math.min(MD5_CHUNK_SIZE, len);
+ var chunks = Math.ceil(len / chunkSize);
+ var currentChunk = 0;
+ var buffer = inputIsString ? new Md5() : new Md5.ArrayBuffer();
+
+ var append = inputIsString ? appendString : appendBlob;
+
+ function next() {
+ setImmediateShim(loadNextChunk);
+ }
+
+ function done() {
+ var raw = buffer.end(true);
+ var base64 = rawToBase64(raw);
+ callback(base64);
+ buffer.destroy();
+ }
+
+ function loadNextChunk() {
+ var start = currentChunk * chunkSize;
+ var end = start + chunkSize;
+ currentChunk++;
+ if (currentChunk < chunks) {
+ append(buffer, data, start, end, next);
+ } else {
+ append(buffer, data, start, end, done);
+ }
+ }
+ loadNextChunk();
+}
+
+function stringMd5(string) {
+ return Md5.hash(string);
+}
+
+function rev(doc, deterministic_revs) {
+ var clonedDoc = clone(doc);
+ if (!deterministic_revs) {
+ return uuidV4.v4().replace(/-/g, '').toLowerCase();
+ }
+
+ delete clonedDoc._rev_tree;
+ return stringMd5(JSON.stringify(clonedDoc));
+}
+
+var uuid = uuidV4.v4;
+
+// We fetch all leafs of the revision tree, and sort them based on tree length
+// and whether they were deleted, undeleted documents with the longest revision
+// tree (most edits) win
+// The final sort algorithm is slightly documented in a sidebar here:
+// http://guide.couchdb.org/draft/conflicts.html
+function winningRev(metadata) {
+ var winningId;
+ var winningPos;
+ var winningDeleted;
+ var toVisit = metadata.rev_tree.slice();
+ var node;
+ while ((node = toVisit.pop())) {
+ var tree = node.ids;
+ var branches = tree[2];
+ var pos = node.pos;
+ if (branches.length) { // non-leaf
+ for (var i = 0, len = branches.length; i < len; i++) {
+ toVisit.push({pos: pos + 1, ids: branches[i]});
+ }
+ continue;
+ }
+ var deleted = !!tree[1].deleted;
+ var id = tree[0];
+ // sort by deleted, then pos, then id
+ if (!winningId || (winningDeleted !== deleted ? winningDeleted :
+ winningPos !== pos ? winningPos < pos : winningId < id)) {
+ winningId = id;
+ winningPos = pos;
+ winningDeleted = deleted;
+ }
+ }
+
+ return winningPos + '-' + winningId;
+}
+
+// Pretty much all below can be combined into a higher order function to
+// traverse revisions
+// The return value from the callback will be passed as context to all
+// children of that node
+function traverseRevTree(revs, callback) {
+ var toVisit = revs.slice();
+
+ var node;
+ while ((node = toVisit.pop())) {
+ var pos = node.pos;
+ var tree = node.ids;
+ var branches = tree[2];
+ var newCtx =
+ callback(branches.length === 0, pos, tree[0], node.ctx, tree[1]);
+ for (var i = 0, len = branches.length; i < len; i++) {
+ toVisit.push({pos: pos + 1, ids: branches[i], ctx: newCtx});
+ }
+ }
+}
+
+function sortByPos(a, b) {
+ return a.pos - b.pos;
+}
+
+function collectLeaves(revs) {
+ var leaves = [];
+ traverseRevTree(revs, function (isLeaf, pos, id, acc, opts) {
+ if (isLeaf) {
+ leaves.push({rev: pos + "-" + id, pos: pos, opts: opts});
+ }
+ });
+ leaves.sort(sortByPos).reverse();
+ for (var i = 0, len = leaves.length; i < len; i++) {
+ delete leaves[i].pos;
+ }
+ return leaves;
+}
+
+// returns revs of all conflicts that is leaves such that
+// 1. are not deleted and
+// 2. are different than winning revision
+function collectConflicts(metadata) {
+ var win = winningRev(metadata);
+ var leaves = collectLeaves(metadata.rev_tree);
+ var conflicts = [];
+ for (var i = 0, len = leaves.length; i < len; i++) {
+ var leaf = leaves[i];
+ if (leaf.rev !== win && !leaf.opts.deleted) {
+ conflicts.push(leaf.rev);
+ }
+ }
+ return conflicts;
+}
+
+// compact a tree by marking its non-leafs as missing,
+// and return a list of revs to delete
+function compactTree(metadata) {
+ var revs = [];
+ traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+ revHash, ctx, opts) {
+ if (opts.status === 'available' && !isLeaf) {
+ revs.push(pos + '-' + revHash);
+ opts.status = 'missing';
+ }
+ });
+ return revs;
+}
+
+// build up a list of all the paths to the leafs in this revision tree
+function rootToLeaf(revs) {
+ var paths = [];
+ var toVisit = revs.slice();
+ var node;
+ while ((node = toVisit.pop())) {
+ var pos = node.pos;
+ var tree = node.ids;
+ var id = tree[0];
+ var opts = tree[1];
+ var branches = tree[2];
+ var isLeaf = branches.length === 0;
+
+ var history = node.history ? node.history.slice() : [];
+ history.push({id: id, opts: opts});
+ if (isLeaf) {
+ paths.push({pos: (pos + 1 - history.length), ids: history});
+ }
+ for (var i = 0, len = branches.length; i < len; i++) {
+ toVisit.push({pos: pos + 1, ids: branches[i], history: history});
+ }
+ }
+ return paths.reverse();
+}
+
+// for a better overview of what this is doing, read:
+
+function sortByPos$1(a, b) {
+ return a.pos - b.pos;
+}
+
+// classic binary search
+function binarySearch(arr, item, comparator) {
+ var low = 0;
+ var high = arr.length;
+ var mid;
+ while (low < high) {
+ mid = (low + high) >>> 1;
+ if (comparator(arr[mid], item) < 0) {
+ low = mid + 1;
+ } else {
+ high = mid;
+ }
+ }
+ return low;
+}
+
+// assuming the arr is sorted, insert the item in the proper place
+function insertSorted(arr, item, comparator) {
+ var idx = binarySearch(arr, item, comparator);
+ arr.splice(idx, 0, item);
+}
+
+// Turn a path as a flat array into a tree with a single branch.
+// If any should be stemmed from the beginning of the array, that's passed
+// in as the second argument
+function pathToTree(path, numStemmed) {
+ var root;
+ var leaf;
+ for (var i = numStemmed, len = path.length; i < len; i++) {
+ var node = path[i];
+ var currentLeaf = [node.id, node.opts, []];
+ if (leaf) {
+ leaf[2].push(currentLeaf);
+ leaf = currentLeaf;
+ } else {
+ root = leaf = currentLeaf;
+ }
+ }
+ return root;
+}
+
+// compare the IDs of two trees
+function compareTree(a, b) {
+ return a[0] < b[0] ? -1 : 1;
+}
+
+// Merge two trees together
+// The roots of tree1 and tree2 must be the same revision
+function mergeTree(in_tree1, in_tree2) {
+ var queue = [{tree1: in_tree1, tree2: in_tree2}];
+ var conflicts = false;
+ while (queue.length > 0) {
+ var item = queue.pop();
+ var tree1 = item.tree1;
+ var tree2 = item.tree2;
+
+ if (tree1[1].status || tree2[1].status) {
+ tree1[1].status =
+ (tree1[1].status === 'available' ||
+ tree2[1].status === 'available') ? 'available' : 'missing';
+ }
+
+ for (var i = 0; i < tree2[2].length; i++) {
+ if (!tree1[2][0]) {
+ conflicts = 'new_leaf';
+ tree1[2][0] = tree2[2][i];
+ continue;
+ }
+
+ var merged = false;
+ for (var j = 0; j < tree1[2].length; j++) {
+ if (tree1[2][j][0] === tree2[2][i][0]) {
+ queue.push({tree1: tree1[2][j], tree2: tree2[2][i]});
+ merged = true;
+ }
+ }
+ if (!merged) {
+ conflicts = 'new_branch';
+ insertSorted(tree1[2], tree2[2][i], compareTree);
+ }
+ }
+ }
+ return {conflicts: conflicts, tree: in_tree1};
+}
+
+function doMerge(tree, path, dontExpand) {
+ var restree = [];
+ var conflicts = false;
+ var merged = false;
+ var res;
+
+ if (!tree.length) {
+ return {tree: [path], conflicts: 'new_leaf'};
+ }
+
+ for (var i = 0, len = tree.length; i < len; i++) {
+ var branch = tree[i];
+ if (branch.pos === path.pos && branch.ids[0] === path.ids[0]) {
+ // Paths start at the same position and have the same root, so they need
+ // merged
+ res = mergeTree(branch.ids, path.ids);
+ restree.push({pos: branch.pos, ids: res.tree});
+ conflicts = conflicts || res.conflicts;
+ merged = true;
+ } else if (dontExpand !== true) {
+ // The paths start at a different position, take the earliest path and
+ // traverse up until it as at the same point from root as the path we
+ // want to merge. If the keys match we return the longer path with the
+ // other merged After stemming we dont want to expand the trees
+
+ var t1 = branch.pos < path.pos ? branch : path;
+ var t2 = branch.pos < path.pos ? path : branch;
+ var diff = t2.pos - t1.pos;
+
+ var candidateParents = [];
+
+ var trees = [];
+ trees.push({ids: t1.ids, diff: diff, parent: null, parentIdx: null});
+ while (trees.length > 0) {
+ var item = trees.pop();
+ if (item.diff === 0) {
+ if (item.ids[0] === t2.ids[0]) {
+ candidateParents.push(item);
+ }
+ continue;
+ }
+ var elements = item.ids[2];
+ for (var j = 0, elementsLen = elements.length; j < elementsLen; j++) {
+ trees.push({
+ ids: elements[j],
+ diff: item.diff - 1,
+ parent: item.ids,
+ parentIdx: j
+ });
+ }
+ }
+
+ var el = candidateParents[0];
+
+ if (!el) {
+ restree.push(branch);
+ } else {
+ res = mergeTree(el.ids, t2.ids);
+ el.parent[2][el.parentIdx] = res.tree;
+ restree.push({pos: t1.pos, ids: t1.ids});
+ conflicts = conflicts || res.conflicts;
+ merged = true;
+ }
+ } else {
+ restree.push(branch);
+ }
+ }
+
+ // We didnt find
+ if (!merged) {
+ restree.push(path);
+ }
+
+ restree.sort(sortByPos$1);
+
+ return {
+ tree: restree,
+ conflicts: conflicts || 'internal_node'
+ };
+}
+
+// To ensure we dont grow the revision tree infinitely, we stem old revisions
+function stem(tree, depth) {
+ // First we break out the tree into a complete list of root to leaf paths
+ var paths = rootToLeaf(tree);
+ var stemmedRevs;
+
+ var result;
+ for (var i = 0, len = paths.length; i < len; i++) {
+ // Then for each path, we cut off the start of the path based on the
+ // `depth` to stem to, and generate a new set of flat trees
+ var path = paths[i];
+ var stemmed = path.ids;
+ var node;
+ if (stemmed.length > depth) {
+ // only do the stemming work if we actually need to stem
+ if (!stemmedRevs) {
+ stemmedRevs = {}; // avoid allocating this object unnecessarily
+ }
+ var numStemmed = stemmed.length - depth;
+ node = {
+ pos: path.pos + numStemmed,
+ ids: pathToTree(stemmed, numStemmed)
+ };
+
+ for (var s = 0; s < numStemmed; s++) {
+ var rev = (path.pos + s) + '-' + stemmed[s].id;
+ stemmedRevs[rev] = true;
+ }
+ } else { // no need to actually stem
+ node = {
+ pos: path.pos,
+ ids: pathToTree(stemmed, 0)
+ };
+ }
+
+ // Then we remerge all those flat trees together, ensuring that we dont
+ // connect trees that would go beyond the depth limit
+ if (result) {
+ result = doMerge(result, node, true).tree;
+ } else {
+ result = [node];
+ }
+ }
+
+ // this is memory-heavy per Chrome profiler, avoid unless we actually stemmed
+ if (stemmedRevs) {
+ traverseRevTree(result, function (isLeaf, pos, revHash) {
+ // some revisions may have been removed in a branch but not in another
+ delete stemmedRevs[pos + '-' + revHash];
+ });
+ }
+
+ return {
+ tree: result,
+ revs: stemmedRevs ? Object.keys(stemmedRevs) : []
+ };
+}
+
+function merge(tree, path, depth) {
+ var newTree = doMerge(tree, path);
+ var stemmed = stem(newTree.tree, depth);
+ return {
+ tree: stemmed.tree,
+ stemmedRevs: stemmed.revs,
+ conflicts: newTree.conflicts
+ };
+}
+
+// return true if a rev exists in the rev tree, false otherwise
+function revExists(revs, rev) {
+ var toVisit = revs.slice();
+ var splitRev = rev.split('-');
+ var targetPos = parseInt(splitRev[0], 10);
+ var targetId = splitRev[1];
+
+ var node;
+ while ((node = toVisit.pop())) {
+ if (node.pos === targetPos && node.ids[0] === targetId) {
+ return true;
+ }
+ var branches = node.ids[2];
+ for (var i = 0, len = branches.length; i < len; i++) {
+ toVisit.push({pos: node.pos + 1, ids: branches[i]});
+ }
+ }
+ return false;
+}
+
+function getTrees(node) {
+ return node.ids;
+}
+
+// check if a specific revision of a doc has been deleted
+// - metadata: the metadata object from the doc store
+// - rev: (optional) the revision to check. defaults to winning revision
+function isDeleted(metadata, rev) {
+ if (!rev) {
+ rev = winningRev(metadata);
+ }
+ var id = rev.substring(rev.indexOf('-') + 1);
+ var toVisit = metadata.rev_tree.map(getTrees);
+
+ var tree;
+ while ((tree = toVisit.pop())) {
+ if (tree[0] === id) {
+ return !!tree[1].deleted;
+ }
+ toVisit = toVisit.concat(tree[2]);
+ }
+}
+
+function isLocalId(id) {
+ return (/^_local/).test(id);
+}
+
+// returns the current leaf node for a given revision
+function latest(rev, metadata) {
+ var toVisit = metadata.rev_tree.slice();
+ var node;
+ while ((node = toVisit.pop())) {
+ var pos = node.pos;
+ var tree = node.ids;
+ var id = tree[0];
+ var opts = tree[1];
+ var branches = tree[2];
+ var isLeaf = branches.length === 0;
+
+ var history = node.history ? node.history.slice() : [];
+ history.push({id: id, pos: pos, opts: opts});
+
+ if (isLeaf) {
+ for (var i = 0, len = history.length; i < len; i++) {
+ var historyNode = history[i];
+ var historyRev = historyNode.pos + '-' + historyNode.id;
+
+ if (historyRev === rev) {
+ // return the rev of this leaf
+ return pos + '-' + id;
+ }
+ }
+ }
+
+ for (var j = 0, l = branches.length; j < l; j++) {
+ toVisit.push({pos: pos + 1, ids: branches[j], history: history});
+ }
+ }
+
+ /* istanbul ignore next */
+ throw new Error('Unable to resolve latest revision for id ' + metadata.id + ', rev ' + rev);
+}
+
+inherits(Changes$1, events.EventEmitter);
+
+function tryCatchInChangeListener(self, change, pending, lastSeq) {
+ // isolate try/catches to avoid V8 deoptimizations
+ try {
+ self.emit('change', change, pending, lastSeq);
+ } catch (e) {
+ guardedConsole('error', 'Error in .on("change", function):', e);
+ }
+}
+
+function Changes$1(db, opts, callback) {
+ events.EventEmitter.call(this);
+ var self = this;
+ this.db = db;
+ opts = opts ? clone(opts) : {};
+ var complete = opts.complete = once(function (err, resp) {
+ if (err) {
+ if (listenerCount(self, 'error') > 0) {
+ self.emit('error', err);
+ }
+ } else {
+ self.emit('complete', resp);
+ }
+ self.removeAllListeners();
+ db.removeListener('destroyed', onDestroy);
+ });
+ if (callback) {
+ self.on('complete', function (resp) {
+ callback(null, resp);
+ });
+ self.on('error', callback);
+ }
+ function onDestroy() {
+ self.cancel();
+ }
+ db.once('destroyed', onDestroy);
+
+ opts.onChange = function (change, pending, lastSeq) {
+ /* istanbul ignore if */
+ if (self.isCancelled) {
+ return;
+ }
+ tryCatchInChangeListener(self, change, pending, lastSeq);
+ };
+
+ var promise = new Promise(function (fulfill, reject) {
+ opts.complete = function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ fulfill(res);
+ }
+ };
+ });
+ self.once('cancel', function () {
+ db.removeListener('destroyed', onDestroy);
+ opts.complete(null, {status: 'cancelled'});
+ });
+ this.then = promise.then.bind(promise);
+ this['catch'] = promise['catch'].bind(promise);
+ this.then(function (result) {
+ complete(null, result);
+ }, complete);
+
+
+
+ if (!db.taskqueue.isReady) {
+ db.taskqueue.addTask(function (failed) {
+ if (failed) {
+ opts.complete(failed);
+ } else if (self.isCancelled) {
+ self.emit('cancel');
+ } else {
+ self.validateChanges(opts);
+ }
+ });
+ } else {
+ self.validateChanges(opts);
+ }
+}
+Changes$1.prototype.cancel = function () {
+ this.isCancelled = true;
+ if (this.db.taskqueue.isReady) {
+ this.emit('cancel');
+ }
+};
+function processChange(doc, metadata, opts) {
+ var changeList = [{rev: doc._rev}];
+ if (opts.style === 'all_docs') {
+ changeList = collectLeaves(metadata.rev_tree)
+ .map(function (x) { return {rev: x.rev}; });
+ }
+ var change = {
+ id: metadata.id,
+ changes: changeList,
+ doc: doc
+ };
+
+ if (isDeleted(metadata, doc._rev)) {
+ change.deleted = true;
+ }
+ if (opts.conflicts) {
+ change.doc._conflicts = collectConflicts(metadata);
+ if (!change.doc._conflicts.length) {
+ delete change.doc._conflicts;
+ }
+ }
+ return change;
+}
+
+Changes$1.prototype.validateChanges = function (opts) {
+ var callback = opts.complete;
+ var self = this;
+
+ /* istanbul ignore else */
+ if (PouchDB._changesFilterPlugin) {
+ PouchDB._changesFilterPlugin.validate(opts, function (err) {
+ if (err) {
+ return callback(err);
+ }
+ self.doChanges(opts);
+ });
+ } else {
+ self.doChanges(opts);
+ }
+};
+
+Changes$1.prototype.doChanges = function (opts) {
+ var self = this;
+ var callback = opts.complete;
+
+ opts = clone(opts);
+ if ('live' in opts && !('continuous' in opts)) {
+ opts.continuous = opts.live;
+ }
+ opts.processChange = processChange;
+
+ if (opts.since === 'latest') {
+ opts.since = 'now';
+ }
+ if (!opts.since) {
+ opts.since = 0;
+ }
+ if (opts.since === 'now') {
+ this.db.info().then(function (info) {
+ /* istanbul ignore if */
+ if (self.isCancelled) {
+ callback(null, {status: 'cancelled'});
+ return;
+ }
+ opts.since = info.update_seq;
+ self.doChanges(opts);
+ }, callback);
+ return;
+ }
+
+ /* istanbul ignore else */
+ if (PouchDB._changesFilterPlugin) {
+ PouchDB._changesFilterPlugin.normalize(opts);
+ if (PouchDB._changesFilterPlugin.shouldFilter(this, opts)) {
+ return PouchDB._changesFilterPlugin.filter(this, opts);
+ }
+ } else {
+ ['doc_ids', 'filter', 'selector', 'view'].forEach(function (key) {
+ if (key in opts) {
+ guardedConsole('warn',
+ 'The "' + key + '" option was passed in to changes/replicate, ' +
+ 'but pouchdb-changes-filter plugin is not installed, so it ' +
+ 'was ignored. Please install the plugin to enable filtering.'
+ );
+ }
+ });
+ }
+
+ if (!('descending' in opts)) {
+ opts.descending = false;
+ }
+
+ // 0 and 1 should return 1 document
+ opts.limit = opts.limit === 0 ? 1 : opts.limit;
+ opts.complete = callback;
+ var newPromise = this.db._changes(opts);
+ /* istanbul ignore else */
+ if (newPromise && typeof newPromise.cancel === 'function') {
+ var cancel = self.cancel;
+ self.cancel = getArguments(function (args) {
+ newPromise.cancel();
+ cancel.apply(this, args);
+ });
+ }
+};
+
+/*
+ * A generic pouch adapter
+ */
+
+function compare(left, right) {
+ return left < right ? -1 : left > right ? 1 : 0;
+}
+
+// Wrapper for functions that call the bulkdocs api with a single doc,
+// if the first result is an error, return an error
+function yankError(callback, docId) {
+ return function (err, results) {
+ if (err || (results[0] && results[0].error)) {
+ err = err || results[0];
+ err.docId = docId;
+ callback(err);
+ } else {
+ callback(null, results.length ? results[0] : results);
+ }
+ };
+}
+
+// clean docs given to us by the user
+function cleanDocs(docs) {
+ for (var i = 0; i < docs.length; i++) {
+ var doc = docs[i];
+ if (doc._deleted) {
+ delete doc._attachments; // ignore atts for deleted docs
+ } else if (doc._attachments) {
+ // filter out extraneous keys from _attachments
+ var atts = Object.keys(doc._attachments);
+ for (var j = 0; j < atts.length; j++) {
+ var att = atts[j];
+ doc._attachments[att] = pick(doc._attachments[att],
+ ['data', 'digest', 'content_type', 'length', 'revpos', 'stub']);
+ }
+ }
+ }
+}
+
+// compare two docs, first by _id then by _rev
+function compareByIdThenRev(a, b) {
+ var idCompare = compare(a._id, b._id);
+ if (idCompare !== 0) {
+ return idCompare;
+ }
+ var aStart = a._revisions ? a._revisions.start : 0;
+ var bStart = b._revisions ? b._revisions.start : 0;
+ return compare(aStart, bStart);
+}
+
+// for every node in a revision tree computes its distance from the closest
+// leaf
+function computeHeight(revs) {
+ var height = {};
+ var edges = [];
+ traverseRevTree(revs, function (isLeaf, pos, id, prnt) {
+ var rev$$1 = pos + "-" + id;
+ if (isLeaf) {
+ height[rev$$1] = 0;
+ }
+ if (prnt !== undefined) {
+ edges.push({from: prnt, to: rev$$1});
+ }
+ return rev$$1;
+ });
+
+ edges.reverse();
+ edges.forEach(function (edge) {
+ if (height[edge.from] === undefined) {
+ height[edge.from] = 1 + height[edge.to];
+ } else {
+ height[edge.from] = Math.min(height[edge.from], 1 + height[edge.to]);
+ }
+ });
+ return height;
+}
+
+function allDocsKeysParse(opts) {
+ var keys = ('limit' in opts) ?
+ opts.keys.slice(opts.skip, opts.limit + opts.skip) :
+ (opts.skip > 0) ? opts.keys.slice(opts.skip) : opts.keys;
+ opts.keys = keys;
+ opts.skip = 0;
+ delete opts.limit;
+ if (opts.descending) {
+ keys.reverse();
+ opts.descending = false;
+ }
+}
+
+// all compaction is done in a queue, to avoid attaching
+// too many listeners at once
+function doNextCompaction(self) {
+ var task = self._compactionQueue[0];
+ var opts = task.opts;
+ var callback = task.callback;
+ self.get('_local/compaction')["catch"](function () {
+ return false;
+ }).then(function (doc) {
+ if (doc && doc.last_seq) {
+ opts.last_seq = doc.last_seq;
+ }
+ self._compact(opts, function (err, res) {
+ /* istanbul ignore if */
+ if (err) {
+ callback(err);
+ } else {
+ callback(null, res);
+ }
+ immediate(function () {
+ self._compactionQueue.shift();
+ if (self._compactionQueue.length) {
+ doNextCompaction(self);
+ }
+ });
+ });
+ });
+}
+
+function attachmentNameError(name) {
+ if (name.charAt(0) === '_') {
+ return name + ' is not a valid attachment name, attachment ' +
+ 'names cannot start with \'_\'';
+ }
+ return false;
+}
+
+inherits(AbstractPouchDB, events.EventEmitter);
+
+function AbstractPouchDB() {
+ events.EventEmitter.call(this);
+
+ // re-bind prototyped methods
+ for (var p in AbstractPouchDB.prototype) {
+ if (typeof this[p] === 'function') {
+ this[p] = this[p].bind(this);
+ }
+ }
+}
+
+AbstractPouchDB.prototype.post =
+ adapterFun('post', function (doc, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ if (typeof doc !== 'object' || Array.isArray(doc)) {
+ return callback(createError(NOT_AN_OBJECT));
+ }
+ this.bulkDocs({docs: [doc]}, opts, yankError(callback, doc._id));
+});
+
+AbstractPouchDB.prototype.put = adapterFun('put', function (doc, opts, cb) {
+ if (typeof opts === 'function') {
+ cb = opts;
+ opts = {};
+ }
+ if (typeof doc !== 'object' || Array.isArray(doc)) {
+ return cb(createError(NOT_AN_OBJECT));
+ }
+ invalidIdError(doc._id);
+ if (isLocalId(doc._id) && typeof this._putLocal === 'function') {
+ if (doc._deleted) {
+ return this._removeLocal(doc, cb);
+ } else {
+ return this._putLocal(doc, cb);
+ }
+ }
+ var self = this;
+ if (opts.force && doc._rev) {
+ transformForceOptionToNewEditsOption();
+ putDoc(function (err) {
+ var result = err ? null : {ok: true, id: doc._id, rev: doc._rev};
+ cb(err, result);
+ });
+ } else {
+ putDoc(cb);
+ }
+
+ function transformForceOptionToNewEditsOption() {
+ var parts = doc._rev.split('-');
+ var oldRevId = parts[1];
+ var oldRevNum = parseInt(parts[0], 10);
+
+ var newRevNum = oldRevNum + 1;
+ var newRevId = rev();
+
+ doc._revisions = {
+ start: newRevNum,
+ ids: [newRevId, oldRevId]
+ };
+ doc._rev = newRevNum + '-' + newRevId;
+ opts.new_edits = false;
+ }
+ function putDoc(next) {
+ if (typeof self._put === 'function' && opts.new_edits !== false) {
+ self._put(doc, opts, next);
+ } else {
+ self.bulkDocs({docs: [doc]}, opts, yankError(next, doc._id));
+ }
+ }
+});
+
+AbstractPouchDB.prototype.putAttachment =
+ adapterFun('putAttachment', function (docId, attachmentId, rev$$1,
+ blob, type) {
+ var api = this;
+ if (typeof type === 'function') {
+ type = blob;
+ blob = rev$$1;
+ rev$$1 = null;
+ }
+ // Lets fix in https://github.com/pouchdb/pouchdb/issues/3267
+ /* istanbul ignore if */
+ if (typeof type === 'undefined') {
+ type = blob;
+ blob = rev$$1;
+ rev$$1 = null;
+ }
+ if (!type) {
+ guardedConsole('warn', 'Attachment', attachmentId, 'on document', docId, 'is missing content_type');
+ }
+
+ function createAttachment(doc) {
+ var prevrevpos = '_rev' in doc ? parseInt(doc._rev, 10) : 0;
+ doc._attachments = doc._attachments || {};
+ doc._attachments[attachmentId] = {
+ content_type: type,
+ data: blob,
+ revpos: ++prevrevpos
+ };
+ return api.put(doc);
+ }
+
+ return api.get(docId).then(function (doc) {
+ if (doc._rev !== rev$$1) {
+ throw createError(REV_CONFLICT);
+ }
+
+ return createAttachment(doc);
+ }, function (err) {
+ // create new doc
+ /* istanbul ignore else */
+ if (err.reason === MISSING_DOC.message) {
+ return createAttachment({_id: docId});
+ } else {
+ throw err;
+ }
+ });
+});
+
+AbstractPouchDB.prototype.removeAttachment =
+ adapterFun('removeAttachment', function (docId, attachmentId, rev$$1,
+ callback) {
+ var self = this;
+ self.get(docId, function (err, obj) {
+ /* istanbul ignore if */
+ if (err) {
+ callback(err);
+ return;
+ }
+ if (obj._rev !== rev$$1) {
+ callback(createError(REV_CONFLICT));
+ return;
+ }
+ /* istanbul ignore if */
+ if (!obj._attachments) {
+ return callback();
+ }
+ delete obj._attachments[attachmentId];
+ if (Object.keys(obj._attachments).length === 0) {
+ delete obj._attachments;
+ }
+ self.put(obj, callback);
+ });
+});
+
+AbstractPouchDB.prototype.remove =
+ adapterFun('remove', function (docOrId, optsOrRev, opts, callback) {
+ var doc;
+ if (typeof optsOrRev === 'string') {
+ // id, rev, opts, callback style
+ doc = {
+ _id: docOrId,
+ _rev: optsOrRev
+ };
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ } else {
+ // doc, opts, callback style
+ doc = docOrId;
+ if (typeof optsOrRev === 'function') {
+ callback = optsOrRev;
+ opts = {};
+ } else {
+ callback = opts;
+ opts = optsOrRev;
+ }
+ }
+ opts = opts || {};
+ opts.was_delete = true;
+ var newDoc = {_id: doc._id, _rev: (doc._rev || opts.rev)};
+ newDoc._deleted = true;
+ if (isLocalId(newDoc._id) && typeof this._removeLocal === 'function') {
+ return this._removeLocal(doc, callback);
+ }
+ this.bulkDocs({docs: [newDoc]}, opts, yankError(callback, newDoc._id));
+});
+
+AbstractPouchDB.prototype.revsDiff =
+ adapterFun('revsDiff', function (req, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ var ids = Object.keys(req);
+
+ if (!ids.length) {
+ return callback(null, {});
+ }
+
+ var count = 0;
+ var missing = new ExportedMap();
+
+ function addToMissing(id, revId) {
+ if (!missing.has(id)) {
+ missing.set(id, {missing: []});
+ }
+ missing.get(id).missing.push(revId);
+ }
+
+ function processDoc(id, rev_tree) {
+ // Is this fast enough? Maybe we should switch to a set simulated by a map
+ var missingForId = req[id].slice(0);
+ traverseRevTree(rev_tree, function (isLeaf, pos, revHash, ctx,
+ opts) {
+ var rev$$1 = pos + '-' + revHash;
+ var idx = missingForId.indexOf(rev$$1);
+ if (idx === -1) {
+ return;
+ }
+
+ missingForId.splice(idx, 1);
+ /* istanbul ignore if */
+ if (opts.status !== 'available') {
+ addToMissing(id, rev$$1);
+ }
+ });
+
+ // Traversing the tree is synchronous, so now `missingForId` contains
+ // revisions that were not found in the tree
+ missingForId.forEach(function (rev$$1) {
+ addToMissing(id, rev$$1);
+ });
+ }
+
+ ids.map(function (id) {
+ this._getRevisionTree(id, function (err, rev_tree) {
+ if (err && err.status === 404 && err.message === 'missing') {
+ missing.set(id, {missing: req[id]});
+ } else if (err) {
+ /* istanbul ignore next */
+ return callback(err);
+ } else {
+ processDoc(id, rev_tree);
+ }
+
+ if (++count === ids.length) {
+ // convert LazyMap to object
+ var missingObj = {};
+ missing.forEach(function (value, key) {
+ missingObj[key] = value;
+ });
+ return callback(null, missingObj);
+ }
+ });
+ }, this);
+});
+
+// _bulk_get API for faster replication, as described in
+// https://github.com/apache/couchdb-chttpd/pull/33
+// At the "abstract" level, it will just run multiple get()s in
+// parallel, because this isn't much of a performance cost
+// for local databases (except the cost of multiple transactions, which is
+// small). The http adapter overrides this in order
+// to do a more efficient single HTTP request.
+AbstractPouchDB.prototype.bulkGet =
+ adapterFun('bulkGet', function (opts, callback) {
+ bulkGet(this, opts, callback);
+});
+
+// compact one document and fire callback
+// by compacting we mean removing all revisions which
+// are further from the leaf in revision tree than max_height
+AbstractPouchDB.prototype.compactDocument =
+ adapterFun('compactDocument', function (docId, maxHeight, callback) {
+ var self = this;
+ this._getRevisionTree(docId, function (err, revTree) {
+ /* istanbul ignore if */
+ if (err) {
+ return callback(err);
+ }
+ var height = computeHeight(revTree);
+ var candidates = [];
+ var revs = [];
+ Object.keys(height).forEach(function (rev$$1) {
+ if (height[rev$$1] > maxHeight) {
+ candidates.push(rev$$1);
+ }
+ });
+
+ traverseRevTree(revTree, function (isLeaf, pos, revHash, ctx, opts) {
+ var rev$$1 = pos + '-' + revHash;
+ if (opts.status === 'available' && candidates.indexOf(rev$$1) !== -1) {
+ revs.push(rev$$1);
+ }
+ });
+ self._doCompaction(docId, revs, callback);
+ });
+});
+
+// compact the whole database using single document
+// compaction
+AbstractPouchDB.prototype.compact =
+ adapterFun('compact', function (opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+
+ var self = this;
+ opts = opts || {};
+
+ self._compactionQueue = self._compactionQueue || [];
+ self._compactionQueue.push({opts: opts, callback: callback});
+ if (self._compactionQueue.length === 1) {
+ doNextCompaction(self);
+ }
+});
+AbstractPouchDB.prototype._compact = function (opts, callback) {
+ var self = this;
+ var changesOpts = {
+ return_docs: false,
+ last_seq: opts.last_seq || 0
+ };
+ var promises = [];
+
+ function onChange(row) {
+ promises.push(self.compactDocument(row.id, 0));
+ }
+ function onComplete(resp) {
+ var lastSeq = resp.last_seq;
+ Promise.all(promises).then(function () {
+ return upsert(self, '_local/compaction', function deltaFunc(doc) {
+ if (!doc.last_seq || doc.last_seq < lastSeq) {
+ doc.last_seq = lastSeq;
+ return doc;
+ }
+ return false; // somebody else got here first, don't update
+ });
+ }).then(function () {
+ callback(null, {ok: true});
+ })["catch"](callback);
+ }
+ self.changes(changesOpts)
+ .on('change', onChange)
+ .on('complete', onComplete)
+ .on('error', callback);
+};
+
+/* Begin api wrappers. Specific functionality to storage belongs in the
+ _[method] */
+AbstractPouchDB.prototype.get = adapterFun('get', function (id, opts, cb) {
+ if (typeof opts === 'function') {
+ cb = opts;
+ opts = {};
+ }
+ if (typeof id !== 'string') {
+ return cb(createError(INVALID_ID));
+ }
+ if (isLocalId(id) && typeof this._getLocal === 'function') {
+ return this._getLocal(id, cb);
+ }
+ var leaves = [], self = this;
+
+ function finishOpenRevs() {
+ var result = [];
+ var count = leaves.length;
+ /* istanbul ignore if */
+ if (!count) {
+ return cb(null, result);
+ }
+
+ // order with open_revs is unspecified
+ leaves.forEach(function (leaf) {
+ self.get(id, {
+ rev: leaf,
+ revs: opts.revs,
+ latest: opts.latest,
+ attachments: opts.attachments,
+ binary: opts.binary
+ }, function (err, doc) {
+ if (!err) {
+ // using latest=true can produce duplicates
+ var existing;
+ for (var i = 0, l = result.length; i < l; i++) {
+ if (result[i].ok && result[i].ok._rev === doc._rev) {
+ existing = true;
+ break;
+ }
+ }
+ if (!existing) {
+ result.push({ok: doc});
+ }
+ } else {
+ result.push({missing: leaf});
+ }
+ count--;
+ if (!count) {
+ cb(null, result);
+ }
+ });
+ });
+ }
+
+ if (opts.open_revs) {
+ if (opts.open_revs === "all") {
+ this._getRevisionTree(id, function (err, rev_tree) {
+ /* istanbul ignore if */
+ if (err) {
+ return cb(err);
+ }
+ leaves = collectLeaves(rev_tree).map(function (leaf) {
+ return leaf.rev;
+ });
+ finishOpenRevs();
+ });
+ } else {
+ if (Array.isArray(opts.open_revs)) {
+ leaves = opts.open_revs;
+ for (var i = 0; i < leaves.length; i++) {
+ var l = leaves[i];
+ // looks like it's the only thing couchdb checks
+ if (!(typeof (l) === "string" && /^\d+-/.test(l))) {
+ return cb(createError(INVALID_REV));
+ }
+ }
+ finishOpenRevs();
+ } else {
+ return cb(createError(UNKNOWN_ERROR, 'function_clause'));
+ }
+ }
+ return; // open_revs does not like other options
+ }
+
+ return this._get(id, opts, function (err, result) {
+ if (err) {
+ err.docId = id;
+ return cb(err);
+ }
+
+ var doc = result.doc;
+ var metadata = result.metadata;
+ var ctx = result.ctx;
+
+ if (opts.conflicts) {
+ var conflicts = collectConflicts(metadata);
+ if (conflicts.length) {
+ doc._conflicts = conflicts;
+ }
+ }
+
+ if (isDeleted(metadata, doc._rev)) {
+ doc._deleted = true;
+ }
+
+ if (opts.revs || opts.revs_info) {
+ var splittedRev = doc._rev.split('-');
+ var revNo = parseInt(splittedRev[0], 10);
+ var revHash = splittedRev[1];
+
+ var paths = rootToLeaf(metadata.rev_tree);
+ var path = null;
+
+ for (var i = 0; i < paths.length; i++) {
+ var currentPath = paths[i];
+ var hashIndex = currentPath.ids.map(function (x) { return x.id; })
+ .indexOf(revHash);
+ var hashFoundAtRevPos = hashIndex === (revNo - 1);
+
+ if (hashFoundAtRevPos || (!path && hashIndex !== -1)) {
+ path = currentPath;
+ }
+ }
+
+ /* istanbul ignore if */
+ if (!path) {
+ err = new Error('invalid rev tree');
+ err.docId = id;
+ return cb(err);
+ }
+
+ var indexOfRev = path.ids.map(function (x) { return x.id; })
+ .indexOf(doc._rev.split('-')[1]) + 1;
+ var howMany = path.ids.length - indexOfRev;
+ path.ids.splice(indexOfRev, howMany);
+ path.ids.reverse();
+
+ if (opts.revs) {
+ doc._revisions = {
+ start: (path.pos + path.ids.length) - 1,
+ ids: path.ids.map(function (rev$$1) {
+ return rev$$1.id;
+ })
+ };
+ }
+ if (opts.revs_info) {
+ var pos = path.pos + path.ids.length;
+ doc._revs_info = path.ids.map(function (rev$$1) {
+ pos--;
+ return {
+ rev: pos + '-' + rev$$1.id,
+ status: rev$$1.opts.status
+ };
+ });
+ }
+ }
+
+ if (opts.attachments && doc._attachments) {
+ var attachments = doc._attachments;
+ var count = Object.keys(attachments).length;
+ if (count === 0) {
+ return cb(null, doc);
+ }
+ Object.keys(attachments).forEach(function (key) {
+ this._getAttachment(doc._id, key, attachments[key], {
+ // Previously the revision handling was done in adapter.js
+ // getAttachment, however since idb-next doesnt we need to
+ // pass the rev through
+ rev: doc._rev,
+ binary: opts.binary,
+ ctx: ctx
+ }, function (err, data) {
+ var att = doc._attachments[key];
+ att.data = data;
+ delete att.stub;
+ delete att.length;
+ if (!--count) {
+ cb(null, doc);
+ }
+ });
+ }, self);
+ } else {
+ if (doc._attachments) {
+ for (var key in doc._attachments) {
+ /* istanbul ignore else */
+ if (doc._attachments.hasOwnProperty(key)) {
+ doc._attachments[key].stub = true;
+ }
+ }
+ }
+ cb(null, doc);
+ }
+ });
+});
+
+// TODO: I dont like this, it forces an extra read for every
+// attachment read and enforces a confusing api between
+// adapter.js and the adapter implementation
+AbstractPouchDB.prototype.getAttachment =
+ adapterFun('getAttachment', function (docId, attachmentId, opts, callback) {
+ var self = this;
+ if (opts instanceof Function) {
+ callback = opts;
+ opts = {};
+ }
+ this._get(docId, opts, function (err, res) {
+ if (err) {
+ return callback(err);
+ }
+ if (res.doc._attachments && res.doc._attachments[attachmentId]) {
+ opts.ctx = res.ctx;
+ opts.binary = true;
+ self._getAttachment(docId, attachmentId,
+ res.doc._attachments[attachmentId], opts, callback);
+ } else {
+ return callback(createError(MISSING_DOC));
+ }
+ });
+});
+
+AbstractPouchDB.prototype.allDocs =
+ adapterFun('allDocs', function (opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ opts.skip = typeof opts.skip !== 'undefined' ? opts.skip : 0;
+ if (opts.start_key) {
+ opts.startkey = opts.start_key;
+ }
+ if (opts.end_key) {
+ opts.endkey = opts.end_key;
+ }
+ if ('keys' in opts) {
+ if (!Array.isArray(opts.keys)) {
+ return callback(new TypeError('options.keys must be an array'));
+ }
+ var incompatibleOpt =
+ ['startkey', 'endkey', 'key'].filter(function (incompatibleOpt) {
+ return incompatibleOpt in opts;
+ })[0];
+ if (incompatibleOpt) {
+ callback(createError(QUERY_PARSE_ERROR,
+ 'Query parameter `' + incompatibleOpt +
+ '` is not compatible with multi-get'
+ ));
+ return;
+ }
+ if (!isRemote(this)) {
+ allDocsKeysParse(opts);
+ if (opts.keys.length === 0) {
+ return this._allDocs({limit: 0}, callback);
+ }
+ }
+ }
+
+ return this._allDocs(opts, callback);
+});
+
+AbstractPouchDB.prototype.changes = function (opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+
+ opts = opts || {};
+
+ // By default set return_docs to false if the caller has opts.live = true,
+ // this will prevent us from collecting the set of changes indefinitely
+ // resulting in growing memory
+ opts.return_docs = ('return_docs' in opts) ? opts.return_docs : !opts.live;
+
+ return new Changes$1(this, opts, callback);
+};
+
+AbstractPouchDB.prototype.close = adapterFun('close', function (callback) {
+ this._closed = true;
+ this.emit('closed');
+ return this._close(callback);
+});
+
+AbstractPouchDB.prototype.info = adapterFun('info', function (callback) {
+ var self = this;
+ this._info(function (err, info) {
+ if (err) {
+ return callback(err);
+ }
+ // assume we know better than the adapter, unless it informs us
+ info.db_name = info.db_name || self.name;
+ info.auto_compaction = !!(self.auto_compaction && !isRemote(self));
+ info.adapter = self.adapter;
+ callback(null, info);
+ });
+});
+
+AbstractPouchDB.prototype.id = adapterFun('id', function (callback) {
+ return this._id(callback);
+});
+
+/* istanbul ignore next */
+AbstractPouchDB.prototype.type = function () {
+ return (typeof this._type === 'function') ? this._type() : this.adapter;
+};
+
+AbstractPouchDB.prototype.bulkDocs =
+ adapterFun('bulkDocs', function (req, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+
+ opts = opts || {};
+
+ if (Array.isArray(req)) {
+ req = {
+ docs: req
+ };
+ }
+
+ if (!req || !req.docs || !Array.isArray(req.docs)) {
+ return callback(createError(MISSING_BULK_DOCS));
+ }
+
+ for (var i = 0; i < req.docs.length; ++i) {
+ if (typeof req.docs[i] !== 'object' || Array.isArray(req.docs[i])) {
+ return callback(createError(NOT_AN_OBJECT));
+ }
+ }
+
+ var attachmentError;
+ req.docs.forEach(function (doc) {
+ if (doc._attachments) {
+ Object.keys(doc._attachments).forEach(function (name) {
+ attachmentError = attachmentError || attachmentNameError(name);
+ if (!doc._attachments[name].content_type) {
+ guardedConsole('warn', 'Attachment', name, 'on document', doc._id, 'is missing content_type');
+ }
+ });
+ }
+ });
+
+ if (attachmentError) {
+ return callback(createError(BAD_REQUEST, attachmentError));
+ }
+
+ if (!('new_edits' in opts)) {
+ if ('new_edits' in req) {
+ opts.new_edits = req.new_edits;
+ } else {
+ opts.new_edits = true;
+ }
+ }
+
+ var adapter = this;
+ if (!opts.new_edits && !isRemote(adapter)) {
+ // ensure revisions of the same doc are sorted, so that
+ // the local adapter processes them correctly (#2935)
+ req.docs.sort(compareByIdThenRev);
+ }
+
+ cleanDocs(req.docs);
+
+ // in the case of conflicts, we want to return the _ids to the user
+ // however, the underlying adapter may destroy the docs array, so
+ // create a copy here
+ var ids = req.docs.map(function (doc) {
+ return doc._id;
+ });
+
+ return this._bulkDocs(req, opts, function (err, res) {
+ if (err) {
+ return callback(err);
+ }
+ if (!opts.new_edits) {
+ // this is what couch does when new_edits is false
+ res = res.filter(function (x) {
+ return x.error;
+ });
+ }
+ // add ids for error/conflict responses (not required for CouchDB)
+ if (!isRemote(adapter)) {
+ for (var i = 0, l = res.length; i < l; i++) {
+ res[i].id = res[i].id || ids[i];
+ }
+ }
+
+ callback(null, res);
+ });
+});
+
+AbstractPouchDB.prototype.registerDependentDatabase =
+ adapterFun('registerDependentDatabase', function (dependentDb,
+ callback) {
+ var depDB = new this.constructor(dependentDb, this.__opts);
+
+ function diffFun(doc) {
+ doc.dependentDbs = doc.dependentDbs || {};
+ if (doc.dependentDbs[dependentDb]) {
+ return false; // no update required
+ }
+ doc.dependentDbs[dependentDb] = true;
+ return doc;
+ }
+ upsert(this, '_local/_pouch_dependentDbs', diffFun)
+ .then(function () {
+ callback(null, {db: depDB});
+ })["catch"](callback);
+});
+
+AbstractPouchDB.prototype.destroy =
+ adapterFun('destroy', function (opts, callback) {
+
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+
+ var self = this;
+ var usePrefix = 'use_prefix' in self ? self.use_prefix : true;
+
+ function destroyDb() {
+ // call destroy method of the particular adaptor
+ self._destroy(opts, function (err, resp) {
+ if (err) {
+ return callback(err);
+ }
+ self._destroyed = true;
+ self.emit('destroyed');
+ callback(null, resp || { 'ok': true });
+ });
+ }
+
+ if (isRemote(self)) {
+ // no need to check for dependent DBs if it's a remote DB
+ return destroyDb();
+ }
+
+ self.get('_local/_pouch_dependentDbs', function (err, localDoc) {
+ if (err) {
+ /* istanbul ignore if */
+ if (err.status !== 404) {
+ return callback(err);
+ } else { // no dependencies
+ return destroyDb();
+ }
+ }
+ var dependentDbs = localDoc.dependentDbs;
+ var PouchDB = self.constructor;
+ var deletedMap = Object.keys(dependentDbs).map(function (name) {
+ // use_prefix is only false in the browser
+ /* istanbul ignore next */
+ var trueName = usePrefix ?
+ name.replace(new RegExp('^' + PouchDB.prefix), '') : name;
+ return new PouchDB(trueName, self.__opts).destroy();
+ });
+ Promise.all(deletedMap).then(destroyDb, callback);
+ });
+});
+
+function TaskQueue() {
+ this.isReady = false;
+ this.failed = false;
+ this.queue = [];
+}
+
+TaskQueue.prototype.execute = function () {
+ var fun;
+ if (this.failed) {
+ while ((fun = this.queue.shift())) {
+ fun(this.failed);
+ }
+ } else {
+ while ((fun = this.queue.shift())) {
+ fun();
+ }
+ }
+};
+
+TaskQueue.prototype.fail = function (err) {
+ this.failed = err;
+ this.execute();
+};
+
+TaskQueue.prototype.ready = function (db) {
+ this.isReady = true;
+ this.db = db;
+ this.execute();
+};
+
+TaskQueue.prototype.addTask = function (fun) {
+ this.queue.push(fun);
+ if (this.failed) {
+ this.execute();
+ }
+};
+
+function parseAdapter(name, opts) {
+ var match = name.match(/([a-z-]*):\/\/(.*)/);
+ if (match) {
+ // the http adapter expects the fully qualified name
+ return {
+ name: /https?/.test(match[1]) ? match[1] + '://' + match[2] : match[2],
+ adapter: match[1]
+ };
+ }
+
+ var adapters = PouchDB.adapters;
+ var preferredAdapters = PouchDB.preferredAdapters;
+ var prefix = PouchDB.prefix;
+ var adapterName = opts.adapter;
+
+ if (!adapterName) { // automatically determine adapter
+ for (var i = 0; i < preferredAdapters.length; ++i) {
+ adapterName = preferredAdapters[i];
+ // check for browsers that have been upgraded from websql-only to websql+idb
+ /* istanbul ignore if */
+ if (adapterName === 'idb' && 'websql' in adapters &&
+ hasLocalStorage() && localStorage['_pouch__websqldb_' + prefix + name]) {
+ // log it, because this can be confusing during development
+ guardedConsole('log', 'PouchDB is downgrading "' + name + '" to WebSQL to' +
+ ' avoid data loss, because it was already opened with WebSQL.');
+ continue; // keep using websql to avoid user data loss
+ }
+ break;
+ }
+ }
+
+ var adapter = adapters[adapterName];
+
+ // if adapter is invalid, then an error will be thrown later
+ var usePrefix = (adapter && 'use_prefix' in adapter) ?
+ adapter.use_prefix : true;
+
+ return {
+ name: usePrefix ? (prefix + name) : name,
+ adapter: adapterName
+ };
+}
+
+// OK, so here's the deal. Consider this code:
+// var db1 = new PouchDB('foo');
+// var db2 = new PouchDB('foo');
+// db1.destroy();
+// ^ these two both need to emit 'destroyed' events,
+// as well as the PouchDB constructor itself.
+// So we have one db object (whichever one got destroy() called on it)
+// responsible for emitting the initial event, which then gets emitted
+// by the constructor, which then broadcasts it to any other dbs
+// that may have been created with the same name.
+function prepareForDestruction(self) {
+
+ function onDestroyed(from_constructor) {
+ self.removeListener('closed', onClosed);
+ if (!from_constructor) {
+ self.constructor.emit('destroyed', self.name);
+ }
+ }
+
+ function onClosed() {
+ self.removeListener('destroyed', onDestroyed);
+ self.constructor.emit('unref', self);
+ }
+
+ self.once('destroyed', onDestroyed);
+ self.once('closed', onClosed);
+ self.constructor.emit('ref', self);
+}
+
+inherits(PouchDB, AbstractPouchDB);
+function PouchDB(name, opts) {
+ // In Node our test suite only tests this for PouchAlt unfortunately
+ /* istanbul ignore if */
+ if (!(this instanceof PouchDB)) {
+ return new PouchDB(name, opts);
+ }
+
+ var self = this;
+ opts = opts || {};
+
+ if (name && typeof name === 'object') {
+ opts = name;
+ name = opts.name;
+ delete opts.name;
+ }
+
+ if (opts.deterministic_revs === undefined) {
+ opts.deterministic_revs = true;
+ }
+
+ this.__opts = opts = clone(opts);
+
+ self.auto_compaction = opts.auto_compaction;
+ self.prefix = PouchDB.prefix;
+
+ if (typeof name !== 'string') {
+ throw new Error('Missing/invalid DB name');
+ }
+
+ var prefixedName = (opts.prefix || '') + name;
+ var backend = parseAdapter(prefixedName, opts);
+
+ opts.name = backend.name;
+ opts.adapter = opts.adapter || backend.adapter;
+
+ self.name = name;
+ self._adapter = opts.adapter;
+ PouchDB.emit('debug', ['adapter', 'Picked adapter: ', opts.adapter]);
+
+ if (!PouchDB.adapters[opts.adapter] ||
+ !PouchDB.adapters[opts.adapter].valid()) {
+ throw new Error('Invalid Adapter: ' + opts.adapter);
+ }
+
+ AbstractPouchDB.call(self);
+ self.taskqueue = new TaskQueue();
+
+ self.adapter = opts.adapter;
+
+ PouchDB.adapters[opts.adapter].call(self, opts, function (err) {
+ if (err) {
+ return self.taskqueue.fail(err);
+ }
+ prepareForDestruction(self);
+
+ self.emit('created', self);
+ PouchDB.emit('created', self.name);
+ self.taskqueue.ready(self);
+ });
+
+}
+
+// AbortController was introduced quite a while after fetch and
+// isnt required for PouchDB to function so polyfill if needed
+var a = (typeof AbortController !== 'undefined')
+ ? AbortController
+ : function () { return {abort: function () {}}; };
+
+var f$1 = fetch;
+var h = Headers;
+
+PouchDB.adapters = {};
+PouchDB.preferredAdapters = [];
+
+PouchDB.prefix = '_pouch_';
+
+var eventEmitter = new events.EventEmitter();
+
+function setUpEventEmitter(Pouch) {
+ Object.keys(events.EventEmitter.prototype).forEach(function (key) {
+ if (typeof events.EventEmitter.prototype[key] === 'function') {
+ Pouch[key] = eventEmitter[key].bind(eventEmitter);
+ }
+ });
+
+ // these are created in constructor.js, and allow us to notify each DB with
+ // the same name that it was destroyed, via the constructor object
+ var destructListeners = Pouch._destructionListeners = new ExportedMap();
+
+ Pouch.on('ref', function onConstructorRef(db) {
+ if (!destructListeners.has(db.name)) {
+ destructListeners.set(db.name, []);
+ }
+ destructListeners.get(db.name).push(db);
+ });
+
+ Pouch.on('unref', function onConstructorUnref(db) {
+ if (!destructListeners.has(db.name)) {
+ return;
+ }
+ var dbList = destructListeners.get(db.name);
+ var pos = dbList.indexOf(db);
+ if (pos < 0) {
+ /* istanbul ignore next */
+ return;
+ }
+ dbList.splice(pos, 1);
+ if (dbList.length > 1) {
+ /* istanbul ignore next */
+ destructListeners.set(db.name, dbList);
+ } else {
+ destructListeners["delete"](db.name);
+ }
+ });
+
+ Pouch.on('destroyed', function onConstructorDestroyed(name) {
+ if (!destructListeners.has(name)) {
+ return;
+ }
+ var dbList = destructListeners.get(name);
+ destructListeners["delete"](name);
+ dbList.forEach(function (db) {
+ db.emit('destroyed',true);
+ });
+ });
+}
+
+setUpEventEmitter(PouchDB);
+
+PouchDB.adapter = function (id, obj, addToPreferredAdapters) {
+ /* istanbul ignore else */
+ if (obj.valid()) {
+ PouchDB.adapters[id] = obj;
+ if (addToPreferredAdapters) {
+ PouchDB.preferredAdapters.push(id);
+ }
+ }
+};
+
+PouchDB.plugin = function (obj) {
+ if (typeof obj === 'function') { // function style for plugins
+ obj(PouchDB);
+ } else if (typeof obj !== 'object' || Object.keys(obj).length === 0) {
+ throw new Error('Invalid plugin: got "' + obj + '", expected an object or a function');
+ } else {
+ Object.keys(obj).forEach(function (id) { // object style for plugins
+ PouchDB.prototype[id] = obj[id];
+ });
+ }
+ if (this.__defaults) {
+ PouchDB.__defaults = $inject_Object_assign({}, this.__defaults);
+ }
+ return PouchDB;
+};
+
+PouchDB.defaults = function (defaultOpts) {
+ function PouchAlt(name, opts) {
+ if (!(this instanceof PouchAlt)) {
+ return new PouchAlt(name, opts);
+ }
+
+ opts = opts || {};
+
+ if (name && typeof name === 'object') {
+ opts = name;
+ name = opts.name;
+ delete opts.name;
+ }
+
+ opts = $inject_Object_assign({}, PouchAlt.__defaults, opts);
+ PouchDB.call(this, name, opts);
+ }
+
+ inherits(PouchAlt, PouchDB);
+
+ PouchAlt.preferredAdapters = PouchDB.preferredAdapters.slice();
+ Object.keys(PouchDB).forEach(function (key) {
+ if (!(key in PouchAlt)) {
+ PouchAlt[key] = PouchDB[key];
+ }
+ });
+
+ // make default options transitive
+ // https://github.com/pouchdb/pouchdb/issues/5922
+ PouchAlt.__defaults = $inject_Object_assign({}, this.__defaults, defaultOpts);
+
+ return PouchAlt;
+};
+
+PouchDB.fetch = function (url, opts) {
+ return f$1(url, opts);
+};
+
+// managed automatically by set-version.js
+var version = "7.1.1";
+
+// this would just be "return doc[field]", but fields
+// can be "deep" due to dot notation
+function getFieldFromDoc(doc, parsedField) {
+ var value = doc;
+ for (var i = 0, len = parsedField.length; i < len; i++) {
+ var key = parsedField[i];
+ value = value[key];
+ if (!value) {
+ break;
+ }
+ }
+ return value;
+}
+
+function compare$1(left, right) {
+ return left < right ? -1 : left > right ? 1 : 0;
+}
+
+// Converts a string in dot notation to an array of its components, with backslash escaping
+function parseField(fieldName) {
+ // fields may be deep (e.g. "foo.bar.baz"), so parse
+ var fields = [];
+ var current = '';
+ for (var i = 0, len = fieldName.length; i < len; i++) {
+ var ch = fieldName[i];
+ if (ch === '.') {
+ if (i > 0 && fieldName[i - 1] === '\\') { // escaped delimiter
+ current = current.substring(0, current.length - 1) + '.';
+ } else { // not escaped, so delimiter
+ fields.push(current);
+ current = '';
+ }
+ } else { // normal character
+ current += ch;
+ }
+ }
+ fields.push(current);
+ return fields;
+}
+
+var combinationFields = ['$or', '$nor', '$not'];
+function isCombinationalField(field) {
+ return combinationFields.indexOf(field) > -1;
+}
+
+function getKey(obj) {
+ return Object.keys(obj)[0];
+}
+
+function getValue(obj) {
+ return obj[getKey(obj)];
+}
+
+
+// flatten an array of selectors joined by an $and operator
+function mergeAndedSelectors(selectors) {
+
+ // sort to ensure that e.g. if the user specified
+ // $and: [{$gt: 'a'}, {$gt: 'b'}], then it's collapsed into
+ // just {$gt: 'b'}
+ var res = {};
+
+ selectors.forEach(function (selector) {
+ Object.keys(selector).forEach(function (field) {
+ var matcher = selector[field];
+ if (typeof matcher !== 'object') {
+ matcher = {$eq: matcher};
+ }
+
+ if (isCombinationalField(field)) {
+ if (matcher instanceof Array) {
+ res[field] = matcher.map(function (m) {
+ return mergeAndedSelectors([m]);
+ });
+ } else {
+ res[field] = mergeAndedSelectors([matcher]);
+ }
+ } else {
+ var fieldMatchers = res[field] = res[field] || {};
+ Object.keys(matcher).forEach(function (operator) {
+ var value = matcher[operator];
+
+ if (operator === '$gt' || operator === '$gte') {
+ return mergeGtGte(operator, value, fieldMatchers);
+ } else if (operator === '$lt' || operator === '$lte') {
+ return mergeLtLte(operator, value, fieldMatchers);
+ } else if (operator === '$ne') {
+ return mergeNe(value, fieldMatchers);
+ } else if (operator === '$eq') {
+ return mergeEq(value, fieldMatchers);
+ }
+ fieldMatchers[operator] = value;
+ });
+ }
+ });
+ });
+
+ return res;
+}
+
+
+
+// collapse logically equivalent gt/gte values
+function mergeGtGte(operator, value, fieldMatchers) {
+ if (typeof fieldMatchers.$eq !== 'undefined') {
+ return; // do nothing
+ }
+ if (typeof fieldMatchers.$gte !== 'undefined') {
+ if (operator === '$gte') {
+ if (value > fieldMatchers.$gte) { // more specificity
+ fieldMatchers.$gte = value;
+ }
+ } else { // operator === '$gt'
+ if (value >= fieldMatchers.$gte) { // more specificity
+ delete fieldMatchers.$gte;
+ fieldMatchers.$gt = value;
+ }
+ }
+ } else if (typeof fieldMatchers.$gt !== 'undefined') {
+ if (operator === '$gte') {
+ if (value > fieldMatchers.$gt) { // more specificity
+ delete fieldMatchers.$gt;
+ fieldMatchers.$gte = value;
+ }
+ } else { // operator === '$gt'
+ if (value > fieldMatchers.$gt) { // more specificity
+ fieldMatchers.$gt = value;
+ }
+ }
+ } else {
+ fieldMatchers[operator] = value;
+ }
+}
+
+// collapse logically equivalent lt/lte values
+function mergeLtLte(operator, value, fieldMatchers) {
+ if (typeof fieldMatchers.$eq !== 'undefined') {
+ return; // do nothing
+ }
+ if (typeof fieldMatchers.$lte !== 'undefined') {
+ if (operator === '$lte') {
+ if (value < fieldMatchers.$lte) { // more specificity
+ fieldMatchers.$lte = value;
+ }
+ } else { // operator === '$gt'
+ if (value <= fieldMatchers.$lte) { // more specificity
+ delete fieldMatchers.$lte;
+ fieldMatchers.$lt = value;
+ }
+ }
+ } else if (typeof fieldMatchers.$lt !== 'undefined') {
+ if (operator === '$lte') {
+ if (value < fieldMatchers.$lt) { // more specificity
+ delete fieldMatchers.$lt;
+ fieldMatchers.$lte = value;
+ }
+ } else { // operator === '$gt'
+ if (value < fieldMatchers.$lt) { // more specificity
+ fieldMatchers.$lt = value;
+ }
+ }
+ } else {
+ fieldMatchers[operator] = value;
+ }
+}
+
+// combine $ne values into one array
+function mergeNe(value, fieldMatchers) {
+ if ('$ne' in fieldMatchers) {
+ // there are many things this could "not" be
+ fieldMatchers.$ne.push(value);
+ } else { // doesn't exist yet
+ fieldMatchers.$ne = [value];
+ }
+}
+
+// add $eq into the mix
+function mergeEq(value, fieldMatchers) {
+ // these all have less specificity than the $eq
+ // TODO: check for user errors here
+ delete fieldMatchers.$gt;
+ delete fieldMatchers.$gte;
+ delete fieldMatchers.$lt;
+ delete fieldMatchers.$lte;
+ delete fieldMatchers.$ne;
+ fieldMatchers.$eq = value;
+}
+
+//#7458: execute function mergeAndedSelectors on nested $and
+function mergeAndedSelectorsNested(obj) {
+ for (var prop in obj) {
+ if (Array.isArray(obj)) {
+ for (var i in obj) {
+ if (obj[i]['$and']) {
+ obj[i] = mergeAndedSelectors(obj[i]['$and']);
+ }
+ }
+ }
+ var value = obj[prop];
+ if (typeof value === 'object') {
+ mergeAndedSelectorsNested(value); // <- recursive call
+ }
+ }
+ return obj;
+}
+
+//#7458: determine id $and is present in selector (at any level)
+function isAndInSelector(obj, isAnd) {
+ for (var prop in obj) {
+ if (prop === '$and') {
+ isAnd = true;
+ }
+ var value = obj[prop];
+ if (typeof value === 'object') {
+ isAnd = isAndInSelector(value, isAnd); // <- recursive call
+ }
+ }
+ return isAnd;
+}
+
+//
+// normalize the selector
+//
+function massageSelector(input) {
+ var result = clone(input);
+ var wasAnded = false;
+ //#7458: if $and is present in selector (at any level) merge nested $and
+ if (isAndInSelector(result, false)) {
+ result = mergeAndedSelectorsNested(result);
+ if ('$and' in result) {
+ result = mergeAndedSelectors(result['$and']);
+ }
+ wasAnded = true;
+ }
+
+ ['$or', '$nor'].forEach(function (orOrNor) {
+ if (orOrNor in result) {
+ // message each individual selector
+ // e.g. {foo: 'bar'} becomes {foo: {$eq: 'bar'}}
+ result[orOrNor].forEach(function (subSelector) {
+ var fields = Object.keys(subSelector);
+ for (var i = 0; i < fields.length; i++) {
+ var field = fields[i];
+ var matcher = subSelector[field];
+ if (typeof matcher !== 'object' || matcher === null) {
+ subSelector[field] = {$eq: matcher};
+ }
+ }
+ });
+ }
+ });
+
+ if ('$not' in result) {
+ //This feels a little like forcing, but it will work for now,
+ //I would like to come back to this and make the merging of selectors a little more generic
+ result['$not'] = mergeAndedSelectors([result['$not']]);
+ }
+
+ var fields = Object.keys(result);
+
+ for (var i = 0; i < fields.length; i++) {
+ var field = fields[i];
+ var matcher = result[field];
+
+ if (typeof matcher !== 'object' || matcher === null) {
+ matcher = {$eq: matcher};
+ } else if ('$ne' in matcher && !wasAnded) {
+ // I put these in an array, since there may be more than one
+ // but in the "mergeAnded" operation, I already take care of that
+ matcher.$ne = [matcher.$ne];
+ }
+ result[field] = matcher;
+ }
+
+ return result;
+}
+
+function pad(str, padWith, upToLength) {
+ var padding = '';
+ var targetLength = upToLength - str.length;
+ /* istanbul ignore next */
+ while (padding.length < targetLength) {
+ padding += padWith;
+ }
+ return padding;
+}
+
+function padLeft(str, padWith, upToLength) {
+ var padding = pad(str, padWith, upToLength);
+ return padding + str;
+}
+
+var MIN_MAGNITUDE = -324; // verified by -Number.MIN_VALUE
+var MAGNITUDE_DIGITS = 3; // ditto
+var SEP = ''; // set to '_' for easier debugging
+
+function collate(a, b) {
+
+ if (a === b) {
+ return 0;
+ }
+
+ a = normalizeKey(a);
+ b = normalizeKey(b);
+
+ var ai = collationIndex(a);
+ var bi = collationIndex(b);
+ if ((ai - bi) !== 0) {
+ return ai - bi;
+ }
+ switch (typeof a) {
+ case 'number':
+ return a - b;
+ case 'boolean':
+ return a < b ? -1 : 1;
+ case 'string':
+ return stringCollate(a, b);
+ }
+ return Array.isArray(a) ? arrayCollate(a, b) : objectCollate(a, b);
+}
+
+// couch considers null/NaN/Infinity/-Infinity === undefined,
+// for the purposes of mapreduce indexes. also, dates get stringified.
+function normalizeKey(key) {
+ switch (typeof key) {
+ case 'undefined':
+ return null;
+ case 'number':
+ if (key === Infinity || key === -Infinity || isNaN(key)) {
+ return null;
+ }
+ return key;
+ case 'object':
+ var origKey = key;
+ if (Array.isArray(key)) {
+ var len = key.length;
+ key = new Array(len);
+ for (var i = 0; i < len; i++) {
+ key[i] = normalizeKey(origKey[i]);
+ }
+ /* istanbul ignore next */
+ } else if (key instanceof Date) {
+ return key.toJSON();
+ } else if (key !== null) { // generic object
+ key = {};
+ for (var k in origKey) {
+ if (origKey.hasOwnProperty(k)) {
+ var val = origKey[k];
+ if (typeof val !== 'undefined') {
+ key[k] = normalizeKey(val);
+ }
+ }
+ }
+ }
+ }
+ return key;
+}
+
+function indexify(key) {
+ if (key !== null) {
+ switch (typeof key) {
+ case 'boolean':
+ return key ? 1 : 0;
+ case 'number':
+ return numToIndexableString(key);
+ case 'string':
+ // We've to be sure that key does not contain \u0000
+ // Do order-preserving replacements:
+ // 0 -> 1, 1
+ // 1 -> 1, 2
+ // 2 -> 2, 2
+ /* eslint-disable no-control-regex */
+ return key
+ .replace(/\u0002/g, '\u0002\u0002')
+ .replace(/\u0001/g, '\u0001\u0002')
+ .replace(/\u0000/g, '\u0001\u0001');
+ /* eslint-enable no-control-regex */
+ case 'object':
+ var isArray = Array.isArray(key);
+ var arr = isArray ? key : Object.keys(key);
+ var i = -1;
+ var len = arr.length;
+ var result = '';
+ if (isArray) {
+ while (++i < len) {
+ result += toIndexableString(arr[i]);
+ }
+ } else {
+ while (++i < len) {
+ var objKey = arr[i];
+ result += toIndexableString(objKey) +
+ toIndexableString(key[objKey]);
+ }
+ }
+ return result;
+ }
+ }
+ return '';
+}
+
+// convert the given key to a string that would be appropriate
+// for lexical sorting, e.g. within a database, where the
+// sorting is the same given by the collate() function.
+function toIndexableString(key) {
+ var zero = '\u0000';
+ key = normalizeKey(key);
+ return collationIndex(key) + SEP + indexify(key) + zero;
+}
+
+function parseNumber(str, i) {
+ var originalIdx = i;
+ var num;
+ var zero = str[i] === '1';
+ if (zero) {
+ num = 0;
+ i++;
+ } else {
+ var neg = str[i] === '0';
+ i++;
+ var numAsString = '';
+ var magAsString = str.substring(i, i + MAGNITUDE_DIGITS);
+ var magnitude = parseInt(magAsString, 10) + MIN_MAGNITUDE;
+ /* istanbul ignore next */
+ if (neg) {
+ magnitude = -magnitude;
+ }
+ i += MAGNITUDE_DIGITS;
+ while (true) {
+ var ch = str[i];
+ if (ch === '\u0000') {
+ break;
+ } else {
+ numAsString += ch;
+ }
+ i++;
+ }
+ numAsString = numAsString.split('.');
+ if (numAsString.length === 1) {
+ num = parseInt(numAsString, 10);
+ } else {
+ /* istanbul ignore next */
+ num = parseFloat(numAsString[0] + '.' + numAsString[1]);
+ }
+ /* istanbul ignore next */
+ if (neg) {
+ num = num - 10;
+ }
+ /* istanbul ignore next */
+ if (magnitude !== 0) {
+ // parseFloat is more reliable than pow due to rounding errors
+ // e.g. Number.MAX_VALUE would return Infinity if we did
+ // num * Math.pow(10, magnitude);
+ num = parseFloat(num + 'e' + magnitude);
+ }
+ }
+ return {num: num, length : i - originalIdx};
+}
+
+// move up the stack while parsing
+// this function moved outside of parseIndexableString for performance
+function pop(stack, metaStack) {
+ var obj = stack.pop();
+
+ if (metaStack.length) {
+ var lastMetaElement = metaStack[metaStack.length - 1];
+ if (obj === lastMetaElement.element) {
+ // popping a meta-element, e.g. an object whose value is another object
+ metaStack.pop();
+ lastMetaElement = metaStack[metaStack.length - 1];
+ }
+ var element = lastMetaElement.element;
+ var lastElementIndex = lastMetaElement.index;
+ if (Array.isArray(element)) {
+ element.push(obj);
+ } else if (lastElementIndex === stack.length - 2) { // obj with key+value
+ var key = stack.pop();
+ element[key] = obj;
+ } else {
+ stack.push(obj); // obj with key only
+ }
+ }
+}
+
+function parseIndexableString(str) {
+ var stack = [];
+ var metaStack = []; // stack for arrays and objects
+ var i = 0;
+
+ /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
+ while (true) {
+ var collationIndex = str[i++];
+ if (collationIndex === '\u0000') {
+ if (stack.length === 1) {
+ return stack.pop();
+ } else {
+ pop(stack, metaStack);
+ continue;
+ }
+ }
+ switch (collationIndex) {
+ case '1':
+ stack.push(null);
+ break;
+ case '2':
+ stack.push(str[i] === '1');
+ i++;
+ break;
+ case '3':
+ var parsedNum = parseNumber(str, i);
+ stack.push(parsedNum.num);
+ i += parsedNum.length;
+ break;
+ case '4':
+ var parsedStr = '';
+ /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
+ while (true) {
+ var ch = str[i];
+ if (ch === '\u0000') {
+ break;
+ }
+ parsedStr += ch;
+ i++;
+ }
+ // perform the reverse of the order-preserving replacement
+ // algorithm (see above)
+ /* eslint-disable no-control-regex */
+ parsedStr = parsedStr.replace(/\u0001\u0001/g, '\u0000')
+ .replace(/\u0001\u0002/g, '\u0001')
+ .replace(/\u0002\u0002/g, '\u0002');
+ /* eslint-enable no-control-regex */
+ stack.push(parsedStr);
+ break;
+ case '5':
+ var arrayElement = { element: [], index: stack.length };
+ stack.push(arrayElement.element);
+ metaStack.push(arrayElement);
+ break;
+ case '6':
+ var objElement = { element: {}, index: stack.length };
+ stack.push(objElement.element);
+ metaStack.push(objElement);
+ break;
+ /* istanbul ignore next */
+ default:
+ throw new Error(
+ 'bad collationIndex or unexpectedly reached end of input: ' +
+ collationIndex);
+ }
+ }
+}
+
+function arrayCollate(a, b) {
+ var len = Math.min(a.length, b.length);
+ for (var i = 0; i < len; i++) {
+ var sort = collate(a[i], b[i]);
+ if (sort !== 0) {
+ return sort;
+ }
+ }
+ return (a.length === b.length) ? 0 :
+ (a.length > b.length) ? 1 : -1;
+}
+function stringCollate(a, b) {
+ // See: https://github.com/daleharvey/pouchdb/issues/40
+ // This is incompatible with the CouchDB implementation, but its the
+ // best we can do for now
+ return (a === b) ? 0 : ((a > b) ? 1 : -1);
+}
+function objectCollate(a, b) {
+ var ak = Object.keys(a), bk = Object.keys(b);
+ var len = Math.min(ak.length, bk.length);
+ for (var i = 0; i < len; i++) {
+ // First sort the keys
+ var sort = collate(ak[i], bk[i]);
+ if (sort !== 0) {
+ return sort;
+ }
+ // if the keys are equal sort the values
+ sort = collate(a[ak[i]], b[bk[i]]);
+ if (sort !== 0) {
+ return sort;
+ }
+
+ }
+ return (ak.length === bk.length) ? 0 :
+ (ak.length > bk.length) ? 1 : -1;
+}
+// The collation is defined by erlangs ordered terms
+// the atoms null, true, false come first, then numbers, strings,
+// arrays, then objects
+// null/undefined/NaN/Infinity/-Infinity are all considered null
+function collationIndex(x) {
+ var id = ['boolean', 'number', 'string', 'object'];
+ var idx = id.indexOf(typeof x);
+ //false if -1 otherwise true, but fast!!!!1
+ if (~idx) {
+ if (x === null) {
+ return 1;
+ }
+ if (Array.isArray(x)) {
+ return 5;
+ }
+ return idx < 3 ? (idx + 2) : (idx + 3);
+ }
+ /* istanbul ignore next */
+ if (Array.isArray(x)) {
+ return 5;
+ }
+}
+
+// conversion:
+// x yyy zz...zz
+// x = 0 for negative, 1 for 0, 2 for positive
+// y = exponent (for negative numbers negated) moved so that it's >= 0
+// z = mantisse
+function numToIndexableString(num) {
+
+ if (num === 0) {
+ return '1';
+ }
+
+ // convert number to exponential format for easier and
+ // more succinct string sorting
+ var expFormat = num.toExponential().split(/e\+?/);
+ var magnitude = parseInt(expFormat[1], 10);
+
+ var neg = num < 0;
+
+ var result = neg ? '0' : '2';
+
+ // first sort by magnitude
+ // it's easier if all magnitudes are positive
+ var magForComparison = ((neg ? -magnitude : magnitude) - MIN_MAGNITUDE);
+ var magString = padLeft((magForComparison).toString(), '0', MAGNITUDE_DIGITS);
+
+ result += SEP + magString;
+
+ // then sort by the factor
+ var factor = Math.abs(parseFloat(expFormat[0])); // [1..10)
+ /* istanbul ignore next */
+ if (neg) { // for negative reverse ordering
+ factor = 10 - factor;
+ }
+
+ var factorStr = factor.toFixed(20);
+
+ // strip zeros from the end
+ factorStr = factorStr.replace(/\.?0+$/, '');
+
+ result += SEP + factorStr;
+
+ return result;
+}
+
+// create a comparator based on the sort object
+function createFieldSorter(sort) {
+
+ function getFieldValuesAsArray(doc) {
+ return sort.map(function (sorting) {
+ var fieldName = getKey(sorting);
+ var parsedField = parseField(fieldName);
+ var docFieldValue = getFieldFromDoc(doc, parsedField);
+ return docFieldValue;
+ });
+ }
+
+ return function (aRow, bRow) {
+ var aFieldValues = getFieldValuesAsArray(aRow.doc);
+ var bFieldValues = getFieldValuesAsArray(bRow.doc);
+ var collation = collate(aFieldValues, bFieldValues);
+ if (collation !== 0) {
+ return collation;
+ }
+ // this is what mango seems to do
+ return compare$1(aRow.doc._id, bRow.doc._id);
+ };
+}
+
+function filterInMemoryFields(rows, requestDef, inMemoryFields) {
+ rows = rows.filter(function (row) {
+ return rowFilter(row.doc, requestDef.selector, inMemoryFields);
+ });
+
+ if (requestDef.sort) {
+ // in-memory sort
+ var fieldSorter = createFieldSorter(requestDef.sort);
+ rows = rows.sort(fieldSorter);
+ if (typeof requestDef.sort[0] !== 'string' &&
+ getValue(requestDef.sort[0]) === 'desc') {
+ rows = rows.reverse();
+ }
+ }
+
+ if ('limit' in requestDef || 'skip' in requestDef) {
+ // have to do the limit in-memory
+ var skip = requestDef.skip || 0;
+ var limit = ('limit' in requestDef ? requestDef.limit : rows.length) + skip;
+ rows = rows.slice(skip, limit);
+ }
+ return rows;
+}
+
+function rowFilter(doc, selector, inMemoryFields) {
+ return inMemoryFields.every(function (field) {
+ var matcher = selector[field];
+ var parsedField = parseField(field);
+ var docFieldValue = getFieldFromDoc(doc, parsedField);
+ if (isCombinationalField(field)) {
+ return matchCominationalSelector(field, matcher, doc);
+ }
+
+ return matchSelector(matcher, doc, parsedField, docFieldValue);
+ });
+}
+
+function matchSelector(matcher, doc, parsedField, docFieldValue) {
+ if (!matcher) {
+ // no filtering necessary; this field is just needed for sorting
+ return true;
+ }
+
+ // is matcher an object, if so continue recursion
+ if (typeof matcher === 'object') {
+ return Object.keys(matcher).every(function (userOperator) {
+ var userValue = matcher[userOperator];
+ return match(userOperator, doc, userValue, parsedField, docFieldValue);
+ });
+ }
+
+ // no more depth, No need to recurse further
+ return matcher === docFieldValue;
+}
+
+function matchCominationalSelector(field, matcher, doc) {
+
+ if (field === '$or') {
+ return matcher.some(function (orMatchers) {
+ return rowFilter(doc, orMatchers, Object.keys(orMatchers));
+ });
+ }
+
+ if (field === '$not') {
+ return !rowFilter(doc, matcher, Object.keys(matcher));
+ }
+
+ //`$nor`
+ return !matcher.find(function (orMatchers) {
+ return rowFilter(doc, orMatchers, Object.keys(orMatchers));
+ });
+
+}
+
+function match(userOperator, doc, userValue, parsedField, docFieldValue) {
+ if (!matchers[userOperator]) {
+ throw new Error('unknown operator "' + userOperator +
+ '" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, ' +
+ '$nin, $size, $mod, $regex, $elemMatch, $type, $allMatch or $all');
+ }
+ return matchers[userOperator](doc, userValue, parsedField, docFieldValue);
+}
+
+function fieldExists(docFieldValue) {
+ return typeof docFieldValue !== 'undefined' && docFieldValue !== null;
+}
+
+function fieldIsNotUndefined(docFieldValue) {
+ return typeof docFieldValue !== 'undefined';
+}
+
+function modField(docFieldValue, userValue) {
+ var divisor = userValue[0];
+ var mod = userValue[1];
+ if (divisor === 0) {
+ throw new Error('Bad divisor, cannot divide by zero');
+ }
+
+ if (parseInt(divisor, 10) !== divisor ) {
+ throw new Error('Divisor is not an integer');
+ }
+
+ if (parseInt(mod, 10) !== mod ) {
+ throw new Error('Modulus is not an integer');
+ }
+
+ if (parseInt(docFieldValue, 10) !== docFieldValue) {
+ return false;
+ }
+
+ return docFieldValue % divisor === mod;
+}
+
+function arrayContainsValue(docFieldValue, userValue) {
+ return userValue.some(function (val) {
+ if (docFieldValue instanceof Array) {
+ return docFieldValue.indexOf(val) > -1;
+ }
+
+ return docFieldValue === val;
+ });
+}
+
+function arrayContainsAllValues(docFieldValue, userValue) {
+ return userValue.every(function (val) {
+ return docFieldValue.indexOf(val) > -1;
+ });
+}
+
+function arraySize(docFieldValue, userValue) {
+ return docFieldValue.length === userValue;
+}
+
+function regexMatch(docFieldValue, userValue) {
+ var re = new RegExp(userValue);
+
+ return re.test(docFieldValue);
+}
+
+function typeMatch(docFieldValue, userValue) {
+
+ switch (userValue) {
+ case 'null':
+ return docFieldValue === null;
+ case 'boolean':
+ return typeof (docFieldValue) === 'boolean';
+ case 'number':
+ return typeof (docFieldValue) === 'number';
+ case 'string':
+ return typeof (docFieldValue) === 'string';
+ case 'array':
+ return docFieldValue instanceof Array;
+ case 'object':
+ return ({}).toString.call(docFieldValue) === '[object Object]';
+ }
+
+ throw new Error(userValue + ' not supported as a type.' +
+ 'Please use one of object, string, array, number, boolean or null.');
+
+}
+
+var matchers = {
+
+ '$elemMatch': function (doc, userValue, parsedField, docFieldValue) {
+ if (!Array.isArray(docFieldValue)) {
+ return false;
+ }
+
+ if (docFieldValue.length === 0) {
+ return false;
+ }
+
+ if (typeof docFieldValue[0] === 'object') {
+ return docFieldValue.some(function (val) {
+ return rowFilter(val, userValue, Object.keys(userValue));
+ });
+ }
+
+ return docFieldValue.some(function (val) {
+ return matchSelector(userValue, doc, parsedField, val);
+ });
+ },
+
+ '$allMatch': function (doc, userValue, parsedField, docFieldValue) {
+ if (!Array.isArray(docFieldValue)) {
+ return false;
+ }
+
+ /* istanbul ignore next */
+ if (docFieldValue.length === 0) {
+ return false;
+ }
+
+ if (typeof docFieldValue[0] === 'object') {
+ return docFieldValue.every(function (val) {
+ return rowFilter(val, userValue, Object.keys(userValue));
+ });
+ }
+
+ return docFieldValue.every(function (val) {
+ return matchSelector(userValue, doc, parsedField, val);
+ });
+ },
+
+ '$eq': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) === 0;
+ },
+
+ '$gte': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) >= 0;
+ },
+
+ '$gt': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) > 0;
+ },
+
+ '$lte': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) <= 0;
+ },
+
+ '$lt': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldIsNotUndefined(docFieldValue) && collate(docFieldValue, userValue) < 0;
+ },
+
+ '$exists': function (doc, userValue, parsedField, docFieldValue) {
+ //a field that is null is still considered to exist
+ if (userValue) {
+ return fieldIsNotUndefined(docFieldValue);
+ }
+
+ return !fieldIsNotUndefined(docFieldValue);
+ },
+
+ '$mod': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldExists(docFieldValue) && modField(docFieldValue, userValue);
+ },
+
+ '$ne': function (doc, userValue, parsedField, docFieldValue) {
+ return userValue.every(function (neValue) {
+ return collate(docFieldValue, neValue) !== 0;
+ });
+ },
+ '$in': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldExists(docFieldValue) && arrayContainsValue(docFieldValue, userValue);
+ },
+
+ '$nin': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldExists(docFieldValue) && !arrayContainsValue(docFieldValue, userValue);
+ },
+
+ '$size': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldExists(docFieldValue) && arraySize(docFieldValue, userValue);
+ },
+
+ '$all': function (doc, userValue, parsedField, docFieldValue) {
+ return Array.isArray(docFieldValue) && arrayContainsAllValues(docFieldValue, userValue);
+ },
+
+ '$regex': function (doc, userValue, parsedField, docFieldValue) {
+ return fieldExists(docFieldValue) && regexMatch(docFieldValue, userValue);
+ },
+
+ '$type': function (doc, userValue, parsedField, docFieldValue) {
+ return typeMatch(docFieldValue, userValue);
+ }
+};
+
+// return true if the given doc matches the supplied selector
+function matchesSelector(doc, selector) {
+ /* istanbul ignore if */
+ if (typeof selector !== 'object') {
+ // match the CouchDB error message
+ throw new Error('Selector error: expected a JSON object');
+ }
+
+ selector = massageSelector(selector);
+ var row = {
+ 'doc': doc
+ };
+
+ var rowsMatched = filterInMemoryFields([row], { 'selector': selector }, Object.keys(selector));
+ return rowsMatched && rowsMatched.length === 1;
+}
+
+function evalFilter(input) {
+ return scopeEval('"use strict";\nreturn ' + input + ';', {});
+}
+
+function evalView(input) {
+ var code = [
+ 'return function(doc) {',
+ ' "use strict";',
+ ' var emitted = false;',
+ ' var emit = function (a, b) {',
+ ' emitted = true;',
+ ' };',
+ ' var view = ' + input + ';',
+ ' view(doc);',
+ ' if (emitted) {',
+ ' return true;',
+ ' }',
+ '};'
+ ].join('\n');
+
+ return scopeEval(code, {});
+}
+
+function validate(opts, callback) {
+ if (opts.selector) {
+ if (opts.filter && opts.filter !== '_selector') {
+ var filterName = typeof opts.filter === 'string' ?
+ opts.filter : 'function';
+ return callback(new Error('selector invalid for filter "' + filterName + '"'));
+ }
+ }
+ callback();
+}
+
+function normalize(opts) {
+ if (opts.view && !opts.filter) {
+ opts.filter = '_view';
+ }
+
+ if (opts.selector && !opts.filter) {
+ opts.filter = '_selector';
+ }
+
+ if (opts.filter && typeof opts.filter === 'string') {
+ if (opts.filter === '_view') {
+ opts.view = normalizeDesignDocFunctionName(opts.view);
+ } else {
+ opts.filter = normalizeDesignDocFunctionName(opts.filter);
+ }
+ }
+}
+
+function shouldFilter(changesHandler, opts) {
+ return opts.filter && typeof opts.filter === 'string' &&
+ !opts.doc_ids && !isRemote(changesHandler.db);
+}
+
+function filter(changesHandler, opts) {
+ var callback = opts.complete;
+ if (opts.filter === '_view') {
+ if (!opts.view || typeof opts.view !== 'string') {
+ var err = createError(BAD_REQUEST,
+ '`view` filter parameter not found or invalid.');
+ return callback(err);
+ }
+ // fetch a view from a design doc, make it behave like a filter
+ var viewName = parseDesignDocFunctionName(opts.view);
+ changesHandler.db.get('_design/' + viewName[0], function (err, ddoc) {
+ /* istanbul ignore if */
+ if (changesHandler.isCancelled) {
+ return callback(null, {status: 'cancelled'});
+ }
+ /* istanbul ignore next */
+ if (err) {
+ return callback(generateErrorFromResponse(err));
+ }
+ var mapFun = ddoc && ddoc.views && ddoc.views[viewName[1]] &&
+ ddoc.views[viewName[1]].map;
+ if (!mapFun) {
+ return callback(createError(MISSING_DOC,
+ (ddoc.views ? 'missing json key: ' + viewName[1] :
+ 'missing json key: views')));
+ }
+ opts.filter = evalView(mapFun);
+ changesHandler.doChanges(opts);
+ });
+ } else if (opts.selector) {
+ opts.filter = function (doc) {
+ return matchesSelector(doc, opts.selector);
+ };
+ changesHandler.doChanges(opts);
+ } else {
+ // fetch a filter from a design doc
+ var filterName = parseDesignDocFunctionName(opts.filter);
+ changesHandler.db.get('_design/' + filterName[0], function (err, ddoc) {
+ /* istanbul ignore if */
+ if (changesHandler.isCancelled) {
+ return callback(null, {status: 'cancelled'});
+ }
+ /* istanbul ignore next */
+ if (err) {
+ return callback(generateErrorFromResponse(err));
+ }
+ var filterFun = ddoc && ddoc.filters && ddoc.filters[filterName[1]];
+ if (!filterFun) {
+ return callback(createError(MISSING_DOC,
+ ((ddoc && ddoc.filters) ? 'missing json key: ' + filterName[1]
+ : 'missing json key: filters')));
+ }
+ opts.filter = evalFilter(filterFun);
+ changesHandler.doChanges(opts);
+ });
+ }
+}
+
+function applyChangesFilterPlugin(PouchDB) {
+ PouchDB._changesFilterPlugin = {
+ validate: validate,
+ normalize: normalize,
+ shouldFilter: shouldFilter,
+ filter: filter
+ };
+}
+
+// TODO: remove from pouchdb-core (breaking)
+PouchDB.plugin(applyChangesFilterPlugin);
+
+PouchDB.version = version;
+
+function toObject(array) {
+ return array.reduce(function (obj, item) {
+ obj[item] = true;
+ return obj;
+ }, {});
+}
+// List of top level reserved words for doc
+var reservedWords = toObject([
+ '_id',
+ '_rev',
+ '_attachments',
+ '_deleted',
+ '_revisions',
+ '_revs_info',
+ '_conflicts',
+ '_deleted_conflicts',
+ '_local_seq',
+ '_rev_tree',
+ //replication documents
+ '_replication_id',
+ '_replication_state',
+ '_replication_state_time',
+ '_replication_state_reason',
+ '_replication_stats',
+ // Specific to Couchbase Sync Gateway
+ '_removed'
+]);
+
+// List of reserved words that should end up the document
+var dataWords = toObject([
+ '_attachments',
+ //replication documents
+ '_replication_id',
+ '_replication_state',
+ '_replication_state_time',
+ '_replication_state_reason',
+ '_replication_stats'
+]);
+
+function parseRevisionInfo(rev$$1) {
+ if (!/^\d+-./.test(rev$$1)) {
+ return createError(INVALID_REV);
+ }
+ var idx = rev$$1.indexOf('-');
+ var left = rev$$1.substring(0, idx);
+ var right = rev$$1.substring(idx + 1);
+ return {
+ prefix: parseInt(left, 10),
+ id: right
+ };
+}
+
+function makeRevTreeFromRevisions(revisions, opts) {
+ var pos = revisions.start - revisions.ids.length + 1;
+
+ var revisionIds = revisions.ids;
+ var ids = [revisionIds[0], opts, []];
+
+ for (var i = 1, len = revisionIds.length; i < len; i++) {
+ ids = [revisionIds[i], {status: 'missing'}, [ids]];
+ }
+
+ return [{
+ pos: pos,
+ ids: ids
+ }];
+}
+
+// Preprocess documents, parse their revisions, assign an id and a
+// revision for new writes that are missing them, etc
+function parseDoc(doc, newEdits, dbOpts) {
+ if (!dbOpts) {
+ dbOpts = {
+ deterministic_revs: true
+ };
+ }
+
+ var nRevNum;
+ var newRevId;
+ var revInfo;
+ var opts = {status: 'available'};
+ if (doc._deleted) {
+ opts.deleted = true;
+ }
+
+ if (newEdits) {
+ if (!doc._id) {
+ doc._id = uuid();
+ }
+ newRevId = rev(doc, dbOpts.deterministic_revs);
+ if (doc._rev) {
+ revInfo = parseRevisionInfo(doc._rev);
+ if (revInfo.error) {
+ return revInfo;
+ }
+ doc._rev_tree = [{
+ pos: revInfo.prefix,
+ ids: [revInfo.id, {status: 'missing'}, [[newRevId, opts, []]]]
+ }];
+ nRevNum = revInfo.prefix + 1;
+ } else {
+ doc._rev_tree = [{
+ pos: 1,
+ ids : [newRevId, opts, []]
+ }];
+ nRevNum = 1;
+ }
+ } else {
+ if (doc._revisions) {
+ doc._rev_tree = makeRevTreeFromRevisions(doc._revisions, opts);
+ nRevNum = doc._revisions.start;
+ newRevId = doc._revisions.ids[0];
+ }
+ if (!doc._rev_tree) {
+ revInfo = parseRevisionInfo(doc._rev);
+ if (revInfo.error) {
+ return revInfo;
+ }
+ nRevNum = revInfo.prefix;
+ newRevId = revInfo.id;
+ doc._rev_tree = [{
+ pos: nRevNum,
+ ids: [newRevId, opts, []]
+ }];
+ }
+ }
+
+ invalidIdError(doc._id);
+
+ doc._rev = nRevNum + '-' + newRevId;
+
+ var result = {metadata : {}, data : {}};
+ for (var key in doc) {
+ /* istanbul ignore else */
+ if (Object.prototype.hasOwnProperty.call(doc, key)) {
+ var specialKey = key[0] === '_';
+ if (specialKey && !reservedWords[key]) {
+ var error = createError(DOC_VALIDATION, key);
+ error.message = DOC_VALIDATION.message + ': ' + key;
+ throw error;
+ } else if (specialKey && !dataWords[key]) {
+ result.metadata[key.slice(1)] = doc[key];
+ } else {
+ result.data[key] = doc[key];
+ }
+ }
+ }
+ return result;
+}
+
+function parseBase64(data) {
+ try {
+ return thisAtob(data);
+ } catch (e) {
+ var err = createError(BAD_ARG,
+ 'Attachment is not a valid base64 string');
+ return {error: err};
+ }
+}
+
+function preprocessString(att, blobType, callback) {
+ var asBinary = parseBase64(att.data);
+ if (asBinary.error) {
+ return callback(asBinary.error);
+ }
+
+ att.length = asBinary.length;
+ if (blobType === 'blob') {
+ att.data = binStringToBluffer(asBinary, att.content_type);
+ } else if (blobType === 'base64') {
+ att.data = thisBtoa(asBinary);
+ } else { // binary
+ att.data = asBinary;
+ }
+ binaryMd5(asBinary, function (result) {
+ att.digest = 'md5-' + result;
+ callback();
+ });
+}
+
+function preprocessBlob(att, blobType, callback) {
+ binaryMd5(att.data, function (md5) {
+ att.digest = 'md5-' + md5;
+ // size is for blobs (browser), length is for buffers (node)
+ att.length = att.data.size || att.data.length || 0;
+ if (blobType === 'binary') {
+ blobToBinaryString(att.data, function (binString) {
+ att.data = binString;
+ callback();
+ });
+ } else if (blobType === 'base64') {
+ blobToBase64(att.data, function (b64) {
+ att.data = b64;
+ callback();
+ });
+ } else {
+ callback();
+ }
+ });
+}
+
+function preprocessAttachment(att, blobType, callback) {
+ if (att.stub) {
+ return callback();
+ }
+ if (typeof att.data === 'string') { // input is a base64 string
+ preprocessString(att, blobType, callback);
+ } else { // input is a blob
+ preprocessBlob(att, blobType, callback);
+ }
+}
+
+function preprocessAttachments(docInfos, blobType, callback) {
+
+ if (!docInfos.length) {
+ return callback();
+ }
+
+ var docv = 0;
+ var overallErr;
+
+ docInfos.forEach(function (docInfo) {
+ var attachments = docInfo.data && docInfo.data._attachments ?
+ Object.keys(docInfo.data._attachments) : [];
+ var recv = 0;
+
+ if (!attachments.length) {
+ return done();
+ }
+
+ function processedAttachment(err) {
+ overallErr = err;
+ recv++;
+ if (recv === attachments.length) {
+ done();
+ }
+ }
+
+ for (var key in docInfo.data._attachments) {
+ if (docInfo.data._attachments.hasOwnProperty(key)) {
+ preprocessAttachment(docInfo.data._attachments[key],
+ blobType, processedAttachment);
+ }
+ }
+ });
+
+ function done() {
+ docv++;
+ if (docInfos.length === docv) {
+ if (overallErr) {
+ callback(overallErr);
+ } else {
+ callback();
+ }
+ }
+ }
+}
+
+function updateDoc(revLimit, prev, docInfo, results,
+ i, cb, writeDoc, newEdits) {
+
+ if (revExists(prev.rev_tree, docInfo.metadata.rev) && !newEdits) {
+ results[i] = docInfo;
+ return cb();
+ }
+
+ // sometimes this is pre-calculated. historically not always
+ var previousWinningRev = prev.winningRev || winningRev(prev);
+ var previouslyDeleted = 'deleted' in prev ? prev.deleted :
+ isDeleted(prev, previousWinningRev);
+ var deleted = 'deleted' in docInfo.metadata ? docInfo.metadata.deleted :
+ isDeleted(docInfo.metadata);
+ var isRoot = /^1-/.test(docInfo.metadata.rev);
+
+ if (previouslyDeleted && !deleted && newEdits && isRoot) {
+ var newDoc = docInfo.data;
+ newDoc._rev = previousWinningRev;
+ newDoc._id = docInfo.metadata.id;
+ docInfo = parseDoc(newDoc, newEdits);
+ }
+
+ var merged = merge(prev.rev_tree, docInfo.metadata.rev_tree[0], revLimit);
+
+ var inConflict = newEdits && ((
+ (previouslyDeleted && deleted && merged.conflicts !== 'new_leaf') ||
+ (!previouslyDeleted && merged.conflicts !== 'new_leaf') ||
+ (previouslyDeleted && !deleted && merged.conflicts === 'new_branch')));
+
+ if (inConflict) {
+ var err = createError(REV_CONFLICT);
+ results[i] = err;
+ return cb();
+ }
+
+ var newRev = docInfo.metadata.rev;
+ docInfo.metadata.rev_tree = merged.tree;
+ docInfo.stemmedRevs = merged.stemmedRevs || [];
+ /* istanbul ignore else */
+ if (prev.rev_map) {
+ docInfo.metadata.rev_map = prev.rev_map; // used only by leveldb
+ }
+
+ // recalculate
+ var winningRev$$1 = winningRev(docInfo.metadata);
+ var winningRevIsDeleted = isDeleted(docInfo.metadata, winningRev$$1);
+
+ // calculate the total number of documents that were added/removed,
+ // from the perspective of total_rows/doc_count
+ var delta = (previouslyDeleted === winningRevIsDeleted) ? 0 :
+ previouslyDeleted < winningRevIsDeleted ? -1 : 1;
+
+ var newRevIsDeleted;
+ if (newRev === winningRev$$1) {
+ // if the new rev is the same as the winning rev, we can reuse that value
+ newRevIsDeleted = winningRevIsDeleted;
+ } else {
+ // if they're not the same, then we need to recalculate
+ newRevIsDeleted = isDeleted(docInfo.metadata, newRev);
+ }
+
+ writeDoc(docInfo, winningRev$$1, winningRevIsDeleted, newRevIsDeleted,
+ true, delta, i, cb);
+}
+
+function rootIsMissing(docInfo) {
+ return docInfo.metadata.rev_tree[0].ids[1].status === 'missing';
+}
+
+function processDocs(revLimit, docInfos, api, fetchedDocs, tx, results,
+ writeDoc, opts, overallCallback) {
+
+ // Default to 1000 locally
+ revLimit = revLimit || 1000;
+
+ function insertDoc(docInfo, resultsIdx, callback) {
+ // Cant insert new deleted documents
+ var winningRev$$1 = winningRev(docInfo.metadata);
+ var deleted = isDeleted(docInfo.metadata, winningRev$$1);
+ if ('was_delete' in opts && deleted) {
+ results[resultsIdx] = createError(MISSING_DOC, 'deleted');
+ return callback();
+ }
+
+ // 4712 - detect whether a new document was inserted with a _rev
+ var inConflict = newEdits && rootIsMissing(docInfo);
+
+ if (inConflict) {
+ var err = createError(REV_CONFLICT);
+ results[resultsIdx] = err;
+ return callback();
+ }
+
+ var delta = deleted ? 0 : 1;
+
+ writeDoc(docInfo, winningRev$$1, deleted, deleted, false,
+ delta, resultsIdx, callback);
+ }
+
+ var newEdits = opts.new_edits;
+ var idsToDocs = new ExportedMap();
+
+ var docsDone = 0;
+ var docsToDo = docInfos.length;
+
+ function checkAllDocsDone() {
+ if (++docsDone === docsToDo && overallCallback) {
+ overallCallback();
+ }
+ }
+
+ docInfos.forEach(function (currentDoc, resultsIdx) {
+
+ if (currentDoc._id && isLocalId(currentDoc._id)) {
+ var fun = currentDoc._deleted ? '_removeLocal' : '_putLocal';
+ api[fun](currentDoc, {ctx: tx}, function (err, res) {
+ results[resultsIdx] = err || res;
+ checkAllDocsDone();
+ });
+ return;
+ }
+
+ var id = currentDoc.metadata.id;
+ if (idsToDocs.has(id)) {
+ docsToDo--; // duplicate
+ idsToDocs.get(id).push([currentDoc, resultsIdx]);
+ } else {
+ idsToDocs.set(id, [[currentDoc, resultsIdx]]);
+ }
+ });
+
+ // in the case of new_edits, the user can provide multiple docs
+ // with the same id. these need to be processed sequentially
+ idsToDocs.forEach(function (docs, id) {
+ var numDone = 0;
+
+ function docWritten() {
+ if (++numDone < docs.length) {
+ nextDoc();
+ } else {
+ checkAllDocsDone();
+ }
+ }
+ function nextDoc() {
+ var value = docs[numDone];
+ var currentDoc = value[0];
+ var resultsIdx = value[1];
+
+ if (fetchedDocs.has(id)) {
+ updateDoc(revLimit, fetchedDocs.get(id), currentDoc, results,
+ resultsIdx, docWritten, writeDoc, newEdits);
+ } else {
+ // Ensure stemming applies to new writes as well
+ var merged = merge([], currentDoc.metadata.rev_tree[0], revLimit);
+ currentDoc.metadata.rev_tree = merged.tree;
+ currentDoc.stemmedRevs = merged.stemmedRevs || [];
+ insertDoc(currentDoc, resultsIdx, docWritten);
+ }
+ }
+ nextDoc();
+ });
+}
+
+// IndexedDB requires a versioned database structure, so we use the
+// version here to manage migrations.
+var ADAPTER_VERSION = 5;
+
+// The object stores created for each database
+// DOC_STORE stores the document meta data, its revision history and state
+// Keyed by document id
+var DOC_STORE = 'document-store';
+// BY_SEQ_STORE stores a particular version of a document, keyed by its
+// sequence id
+var BY_SEQ_STORE = 'by-sequence';
+// Where we store attachments
+var ATTACH_STORE = 'attach-store';
+// Where we store many-to-many relations
+// between attachment digests and seqs
+var ATTACH_AND_SEQ_STORE = 'attach-seq-store';
+
+// Where we store database-wide meta data in a single record
+// keyed by id: META_STORE
+var META_STORE = 'meta-store';
+// Where we store local documents
+var LOCAL_STORE = 'local-store';
+// Where we detect blob support
+var DETECT_BLOB_SUPPORT_STORE = 'detect-blob-support';
+
+function safeJsonParse(str) {
+ // This try/catch guards against stack overflow errors.
+ // JSON.parse() is faster than vuvuzela.parse() but vuvuzela
+ // cannot overflow.
+ try {
+ return JSON.parse(str);
+ } catch (e) {
+ /* istanbul ignore next */
+ return vuvuzela.parse(str);
+ }
+}
+
+function safeJsonStringify(json) {
+ try {
+ return JSON.stringify(json);
+ } catch (e) {
+ /* istanbul ignore next */
+ return vuvuzela.stringify(json);
+ }
+}
+
+function idbError(callback) {
+ return function (evt) {
+ var message = 'unknown_error';
+ if (evt.target && evt.target.error) {
+ message = evt.target.error.name || evt.target.error.message;
+ }
+ callback(createError(IDB_ERROR, message, evt.type));
+ };
+}
+
+// Unfortunately, the metadata has to be stringified
+// when it is put into the database, because otherwise
+// IndexedDB can throw errors for deeply-nested objects.
+// Originally we just used JSON.parse/JSON.stringify; now
+// we use this custom vuvuzela library that avoids recursion.
+// If we could do it all over again, we'd probably use a
+// format for the revision trees other than JSON.
+function encodeMetadata(metadata, winningRev, deleted) {
+ return {
+ data: safeJsonStringify(metadata),
+ winningRev: winningRev,
+ deletedOrLocal: deleted ? '1' : '0',
+ seq: metadata.seq, // highest seq for this doc
+ id: metadata.id
+ };
+}
+
+function decodeMetadata(storedObject) {
+ if (!storedObject) {
+ return null;
+ }
+ var metadata = safeJsonParse(storedObject.data);
+ metadata.winningRev = storedObject.winningRev;
+ metadata.deleted = storedObject.deletedOrLocal === '1';
+ metadata.seq = storedObject.seq;
+ return metadata;
+}
+
+// read the doc back out from the database. we don't store the
+// _id or _rev because we already have _doc_id_rev.
+function decodeDoc(doc) {
+ if (!doc) {
+ return doc;
+ }
+ var idx = doc._doc_id_rev.lastIndexOf(':');
+ doc._id = doc._doc_id_rev.substring(0, idx - 1);
+ doc._rev = doc._doc_id_rev.substring(idx + 1);
+ delete doc._doc_id_rev;
+ return doc;
+}
+
+// Read a blob from the database, encoding as necessary
+// and translating from base64 if the IDB doesn't support
+// native Blobs
+function readBlobData(body, type, asBlob, callback) {
+ if (asBlob) {
+ if (!body) {
+ callback(createBlob([''], {type: type}));
+ } else if (typeof body !== 'string') { // we have blob support
+ callback(body);
+ } else { // no blob support
+ callback(b64ToBluffer(body, type));
+ }
+ } else { // as base64 string
+ if (!body) {
+ callback('');
+ } else if (typeof body !== 'string') { // we have blob support
+ readAsBinaryString(body, function (binary) {
+ callback(thisBtoa(binary));
+ });
+ } else { // no blob support
+ callback(body);
+ }
+ }
+}
+
+function fetchAttachmentsIfNecessary(doc, opts, txn, cb) {
+ var attachments = Object.keys(doc._attachments || {});
+ if (!attachments.length) {
+ return cb && cb();
+ }
+ var numDone = 0;
+
+ function checkDone() {
+ if (++numDone === attachments.length && cb) {
+ cb();
+ }
+ }
+
+ function fetchAttachment(doc, att) {
+ var attObj = doc._attachments[att];
+ var digest = attObj.digest;
+ var req = txn.objectStore(ATTACH_STORE).get(digest);
+ req.onsuccess = function (e) {
+ attObj.body = e.target.result.body;
+ checkDone();
+ };
+ }
+
+ attachments.forEach(function (att) {
+ if (opts.attachments && opts.include_docs) {
+ fetchAttachment(doc, att);
+ } else {
+ doc._attachments[att].stub = true;
+ checkDone();
+ }
+ });
+}
+
+// IDB-specific postprocessing necessary because
+// we don't know whether we stored a true Blob or
+// a base64-encoded string, and if it's a Blob it
+// needs to be read outside of the transaction context
+function postProcessAttachments(results, asBlob) {
+ return Promise.all(results.map(function (row) {
+ if (row.doc && row.doc._attachments) {
+ var attNames = Object.keys(row.doc._attachments);
+ return Promise.all(attNames.map(function (att) {
+ var attObj = row.doc._attachments[att];
+ if (!('body' in attObj)) { // already processed
+ return;
+ }
+ var body = attObj.body;
+ var type = attObj.content_type;
+ return new Promise(function (resolve) {
+ readBlobData(body, type, asBlob, function (data) {
+ row.doc._attachments[att] = $inject_Object_assign(
+ pick(attObj, ['digest', 'content_type']),
+ {data: data}
+ );
+ resolve();
+ });
+ });
+ }));
+ }
+ }));
+}
+
+function compactRevs(revs, docId, txn) {
+
+ var possiblyOrphanedDigests = [];
+ var seqStore = txn.objectStore(BY_SEQ_STORE);
+ var attStore = txn.objectStore(ATTACH_STORE);
+ var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
+ var count = revs.length;
+
+ function checkDone() {
+ count--;
+ if (!count) { // done processing all revs
+ deleteOrphanedAttachments();
+ }
+ }
+
+ function deleteOrphanedAttachments() {
+ if (!possiblyOrphanedDigests.length) {
+ return;
+ }
+ possiblyOrphanedDigests.forEach(function (digest) {
+ var countReq = attAndSeqStore.index('digestSeq').count(
+ IDBKeyRange.bound(
+ digest + '::', digest + '::\uffff', false, false));
+ countReq.onsuccess = function (e) {
+ var count = e.target.result;
+ if (!count) {
+ // orphaned
+ attStore["delete"](digest);
+ }
+ };
+ });
+ }
+
+ revs.forEach(function (rev$$1) {
+ var index = seqStore.index('_doc_id_rev');
+ var key = docId + "::" + rev$$1;
+ index.getKey(key).onsuccess = function (e) {
+ var seq = e.target.result;
+ if (typeof seq !== 'number') {
+ return checkDone();
+ }
+ seqStore["delete"](seq);
+
+ var cursor = attAndSeqStore.index('seq')
+ .openCursor(IDBKeyRange.only(seq));
+
+ cursor.onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ var digest = cursor.value.digestSeq.split('::')[0];
+ possiblyOrphanedDigests.push(digest);
+ attAndSeqStore["delete"](cursor.primaryKey);
+ cursor["continue"]();
+ } else { // done
+ checkDone();
+ }
+ };
+ };
+ });
+}
+
+function openTransactionSafely(idb, stores, mode) {
+ try {
+ return {
+ txn: idb.transaction(stores, mode)
+ };
+ } catch (err) {
+ return {
+ error: err
+ };
+ }
+}
+
+var changesHandler = new Changes();
+
+function idbBulkDocs(dbOpts, req, opts, api, idb, callback) {
+ var docInfos = req.docs;
+ var txn;
+ var docStore;
+ var bySeqStore;
+ var attachStore;
+ var attachAndSeqStore;
+ var metaStore;
+ var docInfoError;
+ var metaDoc;
+
+ for (var i = 0, len = docInfos.length; i < len; i++) {
+ var doc = docInfos[i];
+ if (doc._id && isLocalId(doc._id)) {
+ continue;
+ }
+ doc = docInfos[i] = parseDoc(doc, opts.new_edits, dbOpts);
+ if (doc.error && !docInfoError) {
+ docInfoError = doc;
+ }
+ }
+
+ if (docInfoError) {
+ return callback(docInfoError);
+ }
+
+ var allDocsProcessed = false;
+ var docCountDelta = 0;
+ var results = new Array(docInfos.length);
+ var fetchedDocs = new ExportedMap();
+ var preconditionErrored = false;
+ var blobType = api._meta.blobSupport ? 'blob' : 'base64';
+
+ preprocessAttachments(docInfos, blobType, function (err) {
+ if (err) {
+ return callback(err);
+ }
+ startTransaction();
+ });
+
+ function startTransaction() {
+
+ var stores = [
+ DOC_STORE, BY_SEQ_STORE,
+ ATTACH_STORE,
+ LOCAL_STORE, ATTACH_AND_SEQ_STORE,
+ META_STORE
+ ];
+ var txnResult = openTransactionSafely(idb, stores, 'readwrite');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ txn = txnResult.txn;
+ txn.onabort = idbError(callback);
+ txn.ontimeout = idbError(callback);
+ txn.oncomplete = complete;
+ docStore = txn.objectStore(DOC_STORE);
+ bySeqStore = txn.objectStore(BY_SEQ_STORE);
+ attachStore = txn.objectStore(ATTACH_STORE);
+ attachAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
+ metaStore = txn.objectStore(META_STORE);
+
+ metaStore.get(META_STORE).onsuccess = function (e) {
+ metaDoc = e.target.result;
+ updateDocCountIfReady();
+ };
+
+ verifyAttachments(function (err) {
+ if (err) {
+ preconditionErrored = true;
+ return callback(err);
+ }
+ fetchExistingDocs();
+ });
+ }
+
+ function onAllDocsProcessed() {
+ allDocsProcessed = true;
+ updateDocCountIfReady();
+ }
+
+ function idbProcessDocs() {
+ processDocs(dbOpts.revs_limit, docInfos, api, fetchedDocs,
+ txn, results, writeDoc, opts, onAllDocsProcessed);
+ }
+
+ function updateDocCountIfReady() {
+ if (!metaDoc || !allDocsProcessed) {
+ return;
+ }
+ // caching the docCount saves a lot of time in allDocs() and
+ // info(), which is why we go to all the trouble of doing this
+ metaDoc.docCount += docCountDelta;
+ metaStore.put(metaDoc);
+ }
+
+ function fetchExistingDocs() {
+
+ if (!docInfos.length) {
+ return;
+ }
+
+ var numFetched = 0;
+
+ function checkDone() {
+ if (++numFetched === docInfos.length) {
+ idbProcessDocs();
+ }
+ }
+
+ function readMetadata(event) {
+ var metadata = decodeMetadata(event.target.result);
+
+ if (metadata) {
+ fetchedDocs.set(metadata.id, metadata);
+ }
+ checkDone();
+ }
+
+ for (var i = 0, len = docInfos.length; i < len; i++) {
+ var docInfo = docInfos[i];
+ if (docInfo._id && isLocalId(docInfo._id)) {
+ checkDone(); // skip local docs
+ continue;
+ }
+ var req = docStore.get(docInfo.metadata.id);
+ req.onsuccess = readMetadata;
+ }
+ }
+
+ function complete() {
+ if (preconditionErrored) {
+ return;
+ }
+
+ changesHandler.notify(api._meta.name);
+ callback(null, results);
+ }
+
+ function verifyAttachment(digest, callback) {
+
+ var req = attachStore.get(digest);
+ req.onsuccess = function (e) {
+ if (!e.target.result) {
+ var err = createError(MISSING_STUB,
+ 'unknown stub attachment with digest ' +
+ digest);
+ err.status = 412;
+ callback(err);
+ } else {
+ callback();
+ }
+ };
+ }
+
+ function verifyAttachments(finish) {
+
+
+ var digests = [];
+ docInfos.forEach(function (docInfo) {
+ if (docInfo.data && docInfo.data._attachments) {
+ Object.keys(docInfo.data._attachments).forEach(function (filename) {
+ var att = docInfo.data._attachments[filename];
+ if (att.stub) {
+ digests.push(att.digest);
+ }
+ });
+ }
+ });
+ if (!digests.length) {
+ return finish();
+ }
+ var numDone = 0;
+ var err;
+
+ function checkDone() {
+ if (++numDone === digests.length) {
+ finish(err);
+ }
+ }
+ digests.forEach(function (digest) {
+ verifyAttachment(digest, function (attErr) {
+ if (attErr && !err) {
+ err = attErr;
+ }
+ checkDone();
+ });
+ });
+ }
+
+ function writeDoc(docInfo, winningRev$$1, winningRevIsDeleted, newRevIsDeleted,
+ isUpdate, delta, resultsIdx, callback) {
+
+ docInfo.metadata.winningRev = winningRev$$1;
+ docInfo.metadata.deleted = winningRevIsDeleted;
+
+ var doc = docInfo.data;
+ doc._id = docInfo.metadata.id;
+ doc._rev = docInfo.metadata.rev;
+
+ if (newRevIsDeleted) {
+ doc._deleted = true;
+ }
+
+ var hasAttachments = doc._attachments &&
+ Object.keys(doc._attachments).length;
+ if (hasAttachments) {
+ return writeAttachments(docInfo, winningRev$$1, winningRevIsDeleted,
+ isUpdate, resultsIdx, callback);
+ }
+
+ docCountDelta += delta;
+ updateDocCountIfReady();
+
+ finishDoc(docInfo, winningRev$$1, winningRevIsDeleted,
+ isUpdate, resultsIdx, callback);
+ }
+
+ function finishDoc(docInfo, winningRev$$1, winningRevIsDeleted,
+ isUpdate, resultsIdx, callback) {
+
+ var doc = docInfo.data;
+ var metadata = docInfo.metadata;
+
+ doc._doc_id_rev = metadata.id + '::' + metadata.rev;
+ delete doc._id;
+ delete doc._rev;
+
+ function afterPutDoc(e) {
+ var revsToDelete = docInfo.stemmedRevs || [];
+
+ if (isUpdate && api.auto_compaction) {
+ revsToDelete = revsToDelete.concat(compactTree(docInfo.metadata));
+ }
+
+ if (revsToDelete && revsToDelete.length) {
+ compactRevs(revsToDelete, docInfo.metadata.id, txn);
+ }
+
+ metadata.seq = e.target.result;
+ // Current _rev is calculated from _rev_tree on read
+ // delete metadata.rev;
+ var metadataToStore = encodeMetadata(metadata, winningRev$$1,
+ winningRevIsDeleted);
+ var metaDataReq = docStore.put(metadataToStore);
+ metaDataReq.onsuccess = afterPutMetadata;
+ }
+
+ function afterPutDocError(e) {
+ // ConstraintError, need to update, not put (see #1638 for details)
+ e.preventDefault(); // avoid transaction abort
+ e.stopPropagation(); // avoid transaction onerror
+ var index = bySeqStore.index('_doc_id_rev');
+ var getKeyReq = index.getKey(doc._doc_id_rev);
+ getKeyReq.onsuccess = function (e) {
+ var putReq = bySeqStore.put(doc, e.target.result);
+ putReq.onsuccess = afterPutDoc;
+ };
+ }
+
+ function afterPutMetadata() {
+ results[resultsIdx] = {
+ ok: true,
+ id: metadata.id,
+ rev: metadata.rev
+ };
+ fetchedDocs.set(docInfo.metadata.id, docInfo.metadata);
+ insertAttachmentMappings(docInfo, metadata.seq, callback);
+ }
+
+ var putReq = bySeqStore.put(doc);
+
+ putReq.onsuccess = afterPutDoc;
+ putReq.onerror = afterPutDocError;
+ }
+
+ function writeAttachments(docInfo, winningRev$$1, winningRevIsDeleted,
+ isUpdate, resultsIdx, callback) {
+
+
+ var doc = docInfo.data;
+
+ var numDone = 0;
+ var attachments = Object.keys(doc._attachments);
+
+ function collectResults() {
+ if (numDone === attachments.length) {
+ finishDoc(docInfo, winningRev$$1, winningRevIsDeleted,
+ isUpdate, resultsIdx, callback);
+ }
+ }
+
+ function attachmentSaved() {
+ numDone++;
+ collectResults();
+ }
+
+ attachments.forEach(function (key) {
+ var att = docInfo.data._attachments[key];
+ if (!att.stub) {
+ var data = att.data;
+ delete att.data;
+ att.revpos = parseInt(winningRev$$1, 10);
+ var digest = att.digest;
+ saveAttachment(digest, data, attachmentSaved);
+ } else {
+ numDone++;
+ collectResults();
+ }
+ });
+ }
+
+ // map seqs to attachment digests, which
+ // we will need later during compaction
+ function insertAttachmentMappings(docInfo, seq, callback) {
+
+ var attsAdded = 0;
+ var attsToAdd = Object.keys(docInfo.data._attachments || {});
+
+ if (!attsToAdd.length) {
+ return callback();
+ }
+
+ function checkDone() {
+ if (++attsAdded === attsToAdd.length) {
+ callback();
+ }
+ }
+
+ function add(att) {
+ var digest = docInfo.data._attachments[att].digest;
+ var req = attachAndSeqStore.put({
+ seq: seq,
+ digestSeq: digest + '::' + seq
+ });
+
+ req.onsuccess = checkDone;
+ req.onerror = function (e) {
+ // this callback is for a constaint error, which we ignore
+ // because this docid/rev has already been associated with
+ // the digest (e.g. when new_edits == false)
+ e.preventDefault(); // avoid transaction abort
+ e.stopPropagation(); // avoid transaction onerror
+ checkDone();
+ };
+ }
+ for (var i = 0; i < attsToAdd.length; i++) {
+ add(attsToAdd[i]); // do in parallel
+ }
+ }
+
+ function saveAttachment(digest, data, callback) {
+
+
+ var getKeyReq = attachStore.count(digest);
+ getKeyReq.onsuccess = function (e) {
+ var count = e.target.result;
+ if (count) {
+ return callback(); // already exists
+ }
+ var newAtt = {
+ digest: digest,
+ body: data
+ };
+ var putReq = attachStore.put(newAtt);
+ putReq.onsuccess = callback;
+ };
+ }
+}
+
+// Abstraction over IDBCursor and getAll()/getAllKeys() that allows us to batch our operations
+// while falling back to a normal IDBCursor operation on browsers that don't support getAll() or
+// getAllKeys(). This allows for a much faster implementation than just straight-up cursors, because
+// we're not processing each document one-at-a-time.
+function runBatchedCursor(objectStore, keyRange, descending, batchSize, onBatch) {
+
+ if (batchSize === -1) {
+ batchSize = 1000;
+ }
+
+ // Bail out of getAll()/getAllKeys() in the following cases:
+ // 1) either method is unsupported - we need both
+ // 2) batchSize is 1 (might as well use IDBCursor)
+ // 3) descending – no real way to do this via getAll()/getAllKeys()
+
+ var useGetAll = typeof objectStore.getAll === 'function' &&
+ typeof objectStore.getAllKeys === 'function' &&
+ batchSize > 1 && !descending;
+
+ var keysBatch;
+ var valuesBatch;
+ var pseudoCursor;
+
+ function onGetAll(e) {
+ valuesBatch = e.target.result;
+ if (keysBatch) {
+ onBatch(keysBatch, valuesBatch, pseudoCursor);
+ }
+ }
+
+ function onGetAllKeys(e) {
+ keysBatch = e.target.result;
+ if (valuesBatch) {
+ onBatch(keysBatch, valuesBatch, pseudoCursor);
+ }
+ }
+
+ function continuePseudoCursor() {
+ if (!keysBatch.length) { // no more results
+ return onBatch();
+ }
+ // fetch next batch, exclusive start
+ var lastKey = keysBatch[keysBatch.length - 1];
+ var newKeyRange;
+ if (keyRange && keyRange.upper) {
+ try {
+ newKeyRange = IDBKeyRange.bound(lastKey, keyRange.upper,
+ true, keyRange.upperOpen);
+ } catch (e) {
+ if (e.name === "DataError" && e.code === 0) {
+ return onBatch(); // we're done, startkey and endkey are equal
+ }
+ }
+ } else {
+ newKeyRange = IDBKeyRange.lowerBound(lastKey, true);
+ }
+ keyRange = newKeyRange;
+ keysBatch = null;
+ valuesBatch = null;
+ objectStore.getAll(keyRange, batchSize).onsuccess = onGetAll;
+ objectStore.getAllKeys(keyRange, batchSize).onsuccess = onGetAllKeys;
+ }
+
+ function onCursor(e) {
+ var cursor = e.target.result;
+ if (!cursor) { // done
+ return onBatch();
+ }
+ // regular IDBCursor acts like a batch where batch size is always 1
+ onBatch([cursor.key], [cursor.value], cursor);
+ }
+
+ if (useGetAll) {
+ pseudoCursor = {"continue": continuePseudoCursor};
+ objectStore.getAll(keyRange, batchSize).onsuccess = onGetAll;
+ objectStore.getAllKeys(keyRange, batchSize).onsuccess = onGetAllKeys;
+ } else if (descending) {
+ objectStore.openCursor(keyRange, 'prev').onsuccess = onCursor;
+ } else {
+ objectStore.openCursor(keyRange).onsuccess = onCursor;
+ }
+}
+
+// simple shim for objectStore.getAll(), falling back to IDBCursor
+function getAll(objectStore, keyRange, onSuccess) {
+ if (typeof objectStore.getAll === 'function') {
+ // use native getAll
+ objectStore.getAll(keyRange).onsuccess = onSuccess;
+ return;
+ }
+ // fall back to cursors
+ var values = [];
+
+ function onCursor(e) {
+ var cursor = e.target.result;
+ if (cursor) {
+ values.push(cursor.value);
+ cursor["continue"]();
+ } else {
+ onSuccess({
+ target: {
+ result: values
+ }
+ });
+ }
+ }
+
+ objectStore.openCursor(keyRange).onsuccess = onCursor;
+}
+
+function allDocsKeys(keys, docStore, onBatch) {
+ // It's not guaranted to be returned in right order
+ var valuesBatch = new Array(keys.length);
+ var count = 0;
+ keys.forEach(function (key, index) {
+ docStore.get(key).onsuccess = function (event) {
+ if (event.target.result) {
+ valuesBatch[index] = event.target.result;
+ } else {
+ valuesBatch[index] = {key: key, error: 'not_found'};
+ }
+ count++;
+ if (count === keys.length) {
+ onBatch(keys, valuesBatch, {});
+ }
+ };
+ });
+}
+
+function createKeyRange(start, end, inclusiveEnd, key, descending) {
+ try {
+ if (start && end) {
+ if (descending) {
+ return IDBKeyRange.bound(end, start, !inclusiveEnd, false);
+ } else {
+ return IDBKeyRange.bound(start, end, false, !inclusiveEnd);
+ }
+ } else if (start) {
+ if (descending) {
+ return IDBKeyRange.upperBound(start);
+ } else {
+ return IDBKeyRange.lowerBound(start);
+ }
+ } else if (end) {
+ if (descending) {
+ return IDBKeyRange.lowerBound(end, !inclusiveEnd);
+ } else {
+ return IDBKeyRange.upperBound(end, !inclusiveEnd);
+ }
+ } else if (key) {
+ return IDBKeyRange.only(key);
+ }
+ } catch (e) {
+ return {error: e};
+ }
+ return null;
+}
+
+function idbAllDocs(opts, idb, callback) {
+ var start = 'startkey' in opts ? opts.startkey : false;
+ var end = 'endkey' in opts ? opts.endkey : false;
+ var key = 'key' in opts ? opts.key : false;
+ var keys = 'keys' in opts ? opts.keys : false;
+ var skip = opts.skip || 0;
+ var limit = typeof opts.limit === 'number' ? opts.limit : -1;
+ var inclusiveEnd = opts.inclusive_end !== false;
+
+ var keyRange ;
+ var keyRangeError;
+ if (!keys) {
+ keyRange = createKeyRange(start, end, inclusiveEnd, key, opts.descending);
+ keyRangeError = keyRange && keyRange.error;
+ if (keyRangeError &&
+ !(keyRangeError.name === "DataError" && keyRangeError.code === 0)) {
+ // DataError with error code 0 indicates start is less than end, so
+ // can just do an empty query. Else need to throw
+ return callback(createError(IDB_ERROR,
+ keyRangeError.name, keyRangeError.message));
+ }
+ }
+
+ var stores = [DOC_STORE, BY_SEQ_STORE, META_STORE];
+
+ if (opts.attachments) {
+ stores.push(ATTACH_STORE);
+ }
+ var txnResult = openTransactionSafely(idb, stores, 'readonly');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ var txn = txnResult.txn;
+ txn.oncomplete = onTxnComplete;
+ txn.onabort = idbError(callback);
+ var docStore = txn.objectStore(DOC_STORE);
+ var seqStore = txn.objectStore(BY_SEQ_STORE);
+ var metaStore = txn.objectStore(META_STORE);
+ var docIdRevIndex = seqStore.index('_doc_id_rev');
+ var results = [];
+ var docCount;
+ var updateSeq;
+
+ metaStore.get(META_STORE).onsuccess = function (e) {
+ docCount = e.target.result.docCount;
+ };
+
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ getMaxUpdateSeq(seqStore, function (e) {
+ if (e.target.result && e.target.result.length > 0) {
+ updateSeq = e.target.result[0];
+ }
+ });
+ }
+
+ function getMaxUpdateSeq(objectStore, onSuccess) {
+ function onCursor(e) {
+ var cursor = e.target.result;
+ var maxKey = undefined;
+ if (cursor && cursor.key) {
+ maxKey = cursor.key;
+ }
+ return onSuccess({
+ target: {
+ result: [maxKey]
+ }
+ });
+ }
+ objectStore.openCursor(null, 'prev').onsuccess = onCursor;
+ }
+
+ // if the user specifies include_docs=true, then we don't
+ // want to block the main cursor while we're fetching the doc
+ function fetchDocAsynchronously(metadata, row, winningRev$$1) {
+ var key = metadata.id + "::" + winningRev$$1;
+ docIdRevIndex.get(key).onsuccess = function onGetDoc(e) {
+ row.doc = decodeDoc(e.target.result) || {};
+ if (opts.conflicts) {
+ var conflicts = collectConflicts(metadata);
+ if (conflicts.length) {
+ row.doc._conflicts = conflicts;
+ }
+ }
+ fetchAttachmentsIfNecessary(row.doc, opts, txn);
+ };
+ }
+
+ function allDocsInner(winningRev$$1, metadata) {
+ var row = {
+ id: metadata.id,
+ key: metadata.id,
+ value: {
+ rev: winningRev$$1
+ }
+ };
+ var deleted = metadata.deleted;
+ if (deleted) {
+ if (keys) {
+ results.push(row);
+ // deleted docs are okay with "keys" requests
+ row.value.deleted = true;
+ row.doc = null;
+ }
+ } else if (skip-- <= 0) {
+ results.push(row);
+ if (opts.include_docs) {
+ fetchDocAsynchronously(metadata, row, winningRev$$1);
+ }
+ }
+ }
+
+ function processBatch(batchValues) {
+ for (var i = 0, len = batchValues.length; i < len; i++) {
+ if (results.length === limit) {
+ break;
+ }
+ var batchValue = batchValues[i];
+ if (batchValue.error && keys) {
+ // key was not found with "keys" requests
+ results.push(batchValue);
+ continue;
+ }
+ var metadata = decodeMetadata(batchValue);
+ var winningRev$$1 = metadata.winningRev;
+ allDocsInner(winningRev$$1, metadata);
+ }
+ }
+
+ function onBatch(batchKeys, batchValues, cursor) {
+ if (!cursor) {
+ return;
+ }
+ processBatch(batchValues);
+ if (results.length < limit) {
+ cursor["continue"]();
+ }
+ }
+
+ function onGetAll(e) {
+ var values = e.target.result;
+ if (opts.descending) {
+ values = values.reverse();
+ }
+ processBatch(values);
+ }
+
+ function onResultsReady() {
+ var returnVal = {
+ total_rows: docCount,
+ offset: opts.skip,
+ rows: results
+ };
+
+ /* istanbul ignore if */
+ if (opts.update_seq && updateSeq !== undefined) {
+ returnVal.update_seq = updateSeq;
+ }
+ callback(null, returnVal);
+ }
+
+ function onTxnComplete() {
+ if (opts.attachments) {
+ postProcessAttachments(results, opts.binary).then(onResultsReady);
+ } else {
+ onResultsReady();
+ }
+ }
+
+ // don't bother doing any requests if start > end or limit === 0
+ if (keyRangeError || limit === 0) {
+ return;
+ }
+ if (keys) {
+ return allDocsKeys(opts.keys, docStore, onBatch);
+ }
+ if (limit === -1) { // just fetch everything
+ return getAll(docStore, keyRange, onGetAll);
+ }
+ // else do a cursor
+ // choose a batch size based on the skip, since we'll need to skip that many
+ runBatchedCursor(docStore, keyRange, opts.descending, limit + skip, onBatch);
+}
+
+//
+// Blobs are not supported in all versions of IndexedDB, notably
+// Chrome <37 and Android <5. In those versions, storing a blob will throw.
+//
+// Various other blob bugs exist in Chrome v37-42 (inclusive).
+// Detecting them is expensive and confusing to users, and Chrome 37-42
+// is at very low usage worldwide, so we do a hacky userAgent check instead.
+//
+// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120
+// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916
+// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836
+//
+function checkBlobSupport(txn) {
+ return new Promise(function (resolve) {
+ var blob$$1 = createBlob(['']);
+ var req = txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob$$1, 'key');
+
+ req.onsuccess = function () {
+ var matchedChrome = navigator.userAgent.match(/Chrome\/(\d+)/);
+ var matchedEdge = navigator.userAgent.match(/Edge\//);
+ // MS Edge pretends to be Chrome 42:
+ // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx
+ resolve(matchedEdge || !matchedChrome ||
+ parseInt(matchedChrome[1], 10) >= 43);
+ };
+
+ req.onerror = txn.onabort = function (e) {
+ // If the transaction aborts now its due to not being able to
+ // write to the database, likely due to the disk being full
+ e.preventDefault();
+ e.stopPropagation();
+ resolve(false);
+ };
+ })["catch"](function () {
+ return false; // error, so assume unsupported
+ });
+}
+
+function countDocs(txn, cb) {
+ var index = txn.objectStore(DOC_STORE).index('deletedOrLocal');
+ index.count(IDBKeyRange.only('0')).onsuccess = function (e) {
+ cb(e.target.result);
+ };
+}
+
+// This task queue ensures that IDB open calls are done in their own tick
+
+var running = false;
+var queue = [];
+
+function tryCode(fun, err, res, PouchDB) {
+ try {
+ fun(err, res);
+ } catch (err) {
+ // Shouldn't happen, but in some odd cases
+ // IndexedDB implementations might throw a sync
+ // error, in which case this will at least log it.
+ PouchDB.emit('error', err);
+ }
+}
+
+function applyNext() {
+ if (running || !queue.length) {
+ return;
+ }
+ running = true;
+ queue.shift()();
+}
+
+function enqueueTask(action, callback, PouchDB) {
+ queue.push(function runAction() {
+ action(function runCallback(err, res) {
+ tryCode(callback, err, res, PouchDB);
+ running = false;
+ immediate(function runNext() {
+ applyNext(PouchDB);
+ });
+ });
+ });
+ applyNext();
+}
+
+function changes(opts, api, dbName, idb) {
+ opts = clone(opts);
+
+ if (opts.continuous) {
+ var id = dbName + ':' + uuid();
+ changesHandler.addListener(dbName, id, api, opts);
+ changesHandler.notify(dbName);
+ return {
+ cancel: function () {
+ changesHandler.removeListener(dbName, id);
+ }
+ };
+ }
+
+ var docIds = opts.doc_ids && new ExportedSet(opts.doc_ids);
+
+ opts.since = opts.since || 0;
+ var lastSeq = opts.since;
+
+ var limit = 'limit' in opts ? opts.limit : -1;
+ if (limit === 0) {
+ limit = 1; // per CouchDB _changes spec
+ }
+
+ var results = [];
+ var numResults = 0;
+ var filter = filterChange(opts);
+ var docIdsToMetadata = new ExportedMap();
+
+ var txn;
+ var bySeqStore;
+ var docStore;
+ var docIdRevIndex;
+
+ function onBatch(batchKeys, batchValues, cursor) {
+ if (!cursor || !batchKeys.length) { // done
+ return;
+ }
+
+ var winningDocs = new Array(batchKeys.length);
+ var metadatas = new Array(batchKeys.length);
+
+ function processMetadataAndWinningDoc(metadata, winningDoc) {
+ var change = opts.processChange(winningDoc, metadata, opts);
+ lastSeq = change.seq = metadata.seq;
+
+ var filtered = filter(change);
+ if (typeof filtered === 'object') { // anything but true/false indicates error
+ return Promise.reject(filtered);
+ }
+
+ if (!filtered) {
+ return Promise.resolve();
+ }
+ numResults++;
+ if (opts.return_docs) {
+ results.push(change);
+ }
+ // process the attachment immediately
+ // for the benefit of live listeners
+ if (opts.attachments && opts.include_docs) {
+ return new Promise(function (resolve) {
+ fetchAttachmentsIfNecessary(winningDoc, opts, txn, function () {
+ postProcessAttachments([change], opts.binary).then(function () {
+ resolve(change);
+ });
+ });
+ });
+ } else {
+ return Promise.resolve(change);
+ }
+ }
+
+ function onBatchDone() {
+ var promises = [];
+ for (var i = 0, len = winningDocs.length; i < len; i++) {
+ if (numResults === limit) {
+ break;
+ }
+ var winningDoc = winningDocs[i];
+ if (!winningDoc) {
+ continue;
+ }
+ var metadata = metadatas[i];
+ promises.push(processMetadataAndWinningDoc(metadata, winningDoc));
+ }
+
+ Promise.all(promises).then(function (changes) {
+ for (var i = 0, len = changes.length; i < len; i++) {
+ if (changes[i]) {
+ opts.onChange(changes[i]);
+ }
+ }
+ })["catch"](opts.complete);
+
+ if (numResults !== limit) {
+ cursor["continue"]();
+ }
+ }
+
+ // Fetch all metadatas/winningdocs from this batch in parallel, then process
+ // them all only once all data has been collected. This is done in parallel
+ // because it's faster than doing it one-at-a-time.
+ var numDone = 0;
+ batchValues.forEach(function (value, i) {
+ var doc = decodeDoc(value);
+ var seq = batchKeys[i];
+ fetchWinningDocAndMetadata(doc, seq, function (metadata, winningDoc) {
+ metadatas[i] = metadata;
+ winningDocs[i] = winningDoc;
+ if (++numDone === batchKeys.length) {
+ onBatchDone();
+ }
+ });
+ });
+ }
+
+ function onGetMetadata(doc, seq, metadata, cb) {
+ if (metadata.seq !== seq) {
+ // some other seq is later
+ return cb();
+ }
+
+ if (metadata.winningRev === doc._rev) {
+ // this is the winning doc
+ return cb(metadata, doc);
+ }
+
+ // fetch winning doc in separate request
+ var docIdRev = doc._id + '::' + metadata.winningRev;
+ var req = docIdRevIndex.get(docIdRev);
+ req.onsuccess = function (e) {
+ cb(metadata, decodeDoc(e.target.result));
+ };
+ }
+
+ function fetchWinningDocAndMetadata(doc, seq, cb) {
+ if (docIds && !docIds.has(doc._id)) {
+ return cb();
+ }
+
+ var metadata = docIdsToMetadata.get(doc._id);
+ if (metadata) { // cached
+ return onGetMetadata(doc, seq, metadata, cb);
+ }
+ // metadata not cached, have to go fetch it
+ docStore.get(doc._id).onsuccess = function (e) {
+ metadata = decodeMetadata(e.target.result);
+ docIdsToMetadata.set(doc._id, metadata);
+ onGetMetadata(doc, seq, metadata, cb);
+ };
+ }
+
+ function finish() {
+ opts.complete(null, {
+ results: results,
+ last_seq: lastSeq
+ });
+ }
+
+ function onTxnComplete() {
+ if (!opts.continuous && opts.attachments) {
+ // cannot guarantee that postProcessing was already done,
+ // so do it again
+ postProcessAttachments(results).then(finish);
+ } else {
+ finish();
+ }
+ }
+
+ var objectStores = [DOC_STORE, BY_SEQ_STORE];
+ if (opts.attachments) {
+ objectStores.push(ATTACH_STORE);
+ }
+ var txnResult = openTransactionSafely(idb, objectStores, 'readonly');
+ if (txnResult.error) {
+ return opts.complete(txnResult.error);
+ }
+ txn = txnResult.txn;
+ txn.onabort = idbError(opts.complete);
+ txn.oncomplete = onTxnComplete;
+
+ bySeqStore = txn.objectStore(BY_SEQ_STORE);
+ docStore = txn.objectStore(DOC_STORE);
+ docIdRevIndex = bySeqStore.index('_doc_id_rev');
+
+ var keyRange = (opts.since && !opts.descending) ?
+ IDBKeyRange.lowerBound(opts.since, true) : null;
+
+ runBatchedCursor(bySeqStore, keyRange, opts.descending, limit, onBatch);
+}
+
+var cachedDBs = new ExportedMap();
+var blobSupportPromise;
+var openReqList = new ExportedMap();
+
+function IdbPouch(opts, callback) {
+ var api = this;
+
+ enqueueTask(function (thisCallback) {
+ init(api, opts, thisCallback);
+ }, callback, api.constructor);
+}
+
+function init(api, opts, callback) {
+
+ var dbName = opts.name;
+
+ var idb = null;
+ api._meta = null;
+
+ // called when creating a fresh new database
+ function createSchema(db) {
+ var docStore = db.createObjectStore(DOC_STORE, {keyPath : 'id'});
+ db.createObjectStore(BY_SEQ_STORE, {autoIncrement: true})
+ .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
+ db.createObjectStore(ATTACH_STORE, {keyPath: 'digest'});
+ db.createObjectStore(META_STORE, {keyPath: 'id', autoIncrement: false});
+ db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);
+
+ // added in v2
+ docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false});
+
+ // added in v3
+ db.createObjectStore(LOCAL_STORE, {keyPath: '_id'});
+
+ // added in v4
+ var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE,
+ {autoIncrement: true});
+ attAndSeqStore.createIndex('seq', 'seq');
+ attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true});
+ }
+
+ // migration to version 2
+ // unfortunately "deletedOrLocal" is a misnomer now that we no longer
+ // store local docs in the main doc-store, but whaddyagonnado
+ function addDeletedOrLocalIndex(txn, callback) {
+ var docStore = txn.objectStore(DOC_STORE);
+ docStore.createIndex('deletedOrLocal', 'deletedOrLocal', {unique : false});
+
+ docStore.openCursor().onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ var metadata = cursor.value;
+ var deleted = isDeleted(metadata);
+ metadata.deletedOrLocal = deleted ? "1" : "0";
+ docStore.put(metadata);
+ cursor["continue"]();
+ } else {
+ callback();
+ }
+ };
+ }
+
+ // migration to version 3 (part 1)
+ function createLocalStoreSchema(db) {
+ db.createObjectStore(LOCAL_STORE, {keyPath: '_id'})
+ .createIndex('_doc_id_rev', '_doc_id_rev', {unique: true});
+ }
+
+ // migration to version 3 (part 2)
+ function migrateLocalStore(txn, cb) {
+ var localStore = txn.objectStore(LOCAL_STORE);
+ var docStore = txn.objectStore(DOC_STORE);
+ var seqStore = txn.objectStore(BY_SEQ_STORE);
+
+ var cursor = docStore.openCursor();
+ cursor.onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ var metadata = cursor.value;
+ var docId = metadata.id;
+ var local = isLocalId(docId);
+ var rev$$1 = winningRev(metadata);
+ if (local) {
+ var docIdRev = docId + "::" + rev$$1;
+ // remove all seq entries
+ // associated with this docId
+ var start = docId + "::";
+ var end = docId + "::~";
+ var index = seqStore.index('_doc_id_rev');
+ var range = IDBKeyRange.bound(start, end, false, false);
+ var seqCursor = index.openCursor(range);
+ seqCursor.onsuccess = function (e) {
+ seqCursor = e.target.result;
+ if (!seqCursor) {
+ // done
+ docStore["delete"](cursor.primaryKey);
+ cursor["continue"]();
+ } else {
+ var data = seqCursor.value;
+ if (data._doc_id_rev === docIdRev) {
+ localStore.put(data);
+ }
+ seqStore["delete"](seqCursor.primaryKey);
+ seqCursor["continue"]();
+ }
+ };
+ } else {
+ cursor["continue"]();
+ }
+ } else if (cb) {
+ cb();
+ }
+ };
+ }
+
+ // migration to version 4 (part 1)
+ function addAttachAndSeqStore(db) {
+ var attAndSeqStore = db.createObjectStore(ATTACH_AND_SEQ_STORE,
+ {autoIncrement: true});
+ attAndSeqStore.createIndex('seq', 'seq');
+ attAndSeqStore.createIndex('digestSeq', 'digestSeq', {unique: true});
+ }
+
+ // migration to version 4 (part 2)
+ function migrateAttsAndSeqs(txn, callback) {
+ var seqStore = txn.objectStore(BY_SEQ_STORE);
+ var attStore = txn.objectStore(ATTACH_STORE);
+ var attAndSeqStore = txn.objectStore(ATTACH_AND_SEQ_STORE);
+
+ // need to actually populate the table. this is the expensive part,
+ // so as an optimization, check first that this database even
+ // contains attachments
+ var req = attStore.count();
+ req.onsuccess = function (e) {
+ var count = e.target.result;
+ if (!count) {
+ return callback(); // done
+ }
+
+ seqStore.openCursor().onsuccess = function (e) {
+ var cursor = e.target.result;
+ if (!cursor) {
+ return callback(); // done
+ }
+ var doc = cursor.value;
+ var seq = cursor.primaryKey;
+ var atts = Object.keys(doc._attachments || {});
+ var digestMap = {};
+ for (var j = 0; j < atts.length; j++) {
+ var att = doc._attachments[atts[j]];
+ digestMap[att.digest] = true; // uniq digests, just in case
+ }
+ var digests = Object.keys(digestMap);
+ for (j = 0; j < digests.length; j++) {
+ var digest = digests[j];
+ attAndSeqStore.put({
+ seq: seq,
+ digestSeq: digest + '::' + seq
+ });
+ }
+ cursor["continue"]();
+ };
+ };
+ }
+
+ // migration to version 5
+ // Instead of relying on on-the-fly migration of metadata,
+ // this brings the doc-store to its modern form:
+ // - metadata.winningrev
+ // - metadata.seq
+ // - stringify the metadata when storing it
+ function migrateMetadata(txn) {
+
+ function decodeMetadataCompat(storedObject) {
+ if (!storedObject.data) {
+ // old format, when we didn't store it stringified
+ storedObject.deleted = storedObject.deletedOrLocal === '1';
+ return storedObject;
+ }
+ return decodeMetadata(storedObject);
+ }
+
+ // ensure that every metadata has a winningRev and seq,
+ // which was previously created on-the-fly but better to migrate
+ var bySeqStore = txn.objectStore(BY_SEQ_STORE);
+ var docStore = txn.objectStore(DOC_STORE);
+ var cursor = docStore.openCursor();
+ cursor.onsuccess = function (e) {
+ var cursor = e.target.result;
+ if (!cursor) {
+ return; // done
+ }
+ var metadata = decodeMetadataCompat(cursor.value);
+
+ metadata.winningRev = metadata.winningRev ||
+ winningRev(metadata);
+
+ function fetchMetadataSeq() {
+ // metadata.seq was added post-3.2.0, so if it's missing,
+ // we need to fetch it manually
+ var start = metadata.id + '::';
+ var end = metadata.id + '::\uffff';
+ var req = bySeqStore.index('_doc_id_rev').openCursor(
+ IDBKeyRange.bound(start, end));
+
+ var metadataSeq = 0;
+ req.onsuccess = function (e) {
+ var cursor = e.target.result;
+ if (!cursor) {
+ metadata.seq = metadataSeq;
+ return onGetMetadataSeq();
+ }
+ var seq = cursor.primaryKey;
+ if (seq > metadataSeq) {
+ metadataSeq = seq;
+ }
+ cursor["continue"]();
+ };
+ }
+
+ function onGetMetadataSeq() {
+ var metadataToStore = encodeMetadata(metadata,
+ metadata.winningRev, metadata.deleted);
+
+ var req = docStore.put(metadataToStore);
+ req.onsuccess = function () {
+ cursor["continue"]();
+ };
+ }
+
+ if (metadata.seq) {
+ return onGetMetadataSeq();
+ }
+
+ fetchMetadataSeq();
+ };
+
+ }
+
+ api._remote = false;
+ api.type = function () {
+ return 'idb';
+ };
+
+ api._id = toPromise(function (callback) {
+ callback(null, api._meta.instanceId);
+ });
+
+ api._bulkDocs = function idb_bulkDocs(req, reqOpts, callback) {
+ idbBulkDocs(opts, req, reqOpts, api, idb, callback);
+ };
+
+ // First we look up the metadata in the ids database, then we fetch the
+ // current revision(s) from the by sequence store
+ api._get = function idb_get(id, opts, callback) {
+ var doc;
+ var metadata;
+ var err;
+ var txn = opts.ctx;
+ if (!txn) {
+ var txnResult = openTransactionSafely(idb,
+ [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ txn = txnResult.txn;
+ }
+
+ function finish() {
+ callback(err, {doc: doc, metadata: metadata, ctx: txn});
+ }
+
+ txn.objectStore(DOC_STORE).get(id).onsuccess = function (e) {
+ metadata = decodeMetadata(e.target.result);
+ // we can determine the result here if:
+ // 1. there is no such document
+ // 2. the document is deleted and we don't ask about specific rev
+ // When we ask with opts.rev we expect the answer to be either
+ // doc (possibly with _deleted=true) or missing error
+ if (!metadata) {
+ err = createError(MISSING_DOC, 'missing');
+ return finish();
+ }
+
+ var rev$$1;
+ if (!opts.rev) {
+ rev$$1 = metadata.winningRev;
+ var deleted = isDeleted(metadata);
+ if (deleted) {
+ err = createError(MISSING_DOC, "deleted");
+ return finish();
+ }
+ } else {
+ rev$$1 = opts.latest ? latest(opts.rev, metadata) : opts.rev;
+ }
+
+ var objectStore = txn.objectStore(BY_SEQ_STORE);
+ var key = metadata.id + '::' + rev$$1;
+
+ objectStore.index('_doc_id_rev').get(key).onsuccess = function (e) {
+ doc = e.target.result;
+ if (doc) {
+ doc = decodeDoc(doc);
+ }
+ if (!doc) {
+ err = createError(MISSING_DOC, 'missing');
+ return finish();
+ }
+ finish();
+ };
+ };
+ };
+
+ api._getAttachment = function (docId, attachId, attachment, opts, callback) {
+ var txn;
+ if (opts.ctx) {
+ txn = opts.ctx;
+ } else {
+ var txnResult = openTransactionSafely(idb,
+ [DOC_STORE, BY_SEQ_STORE, ATTACH_STORE], 'readonly');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ txn = txnResult.txn;
+ }
+ var digest = attachment.digest;
+ var type = attachment.content_type;
+
+ txn.objectStore(ATTACH_STORE).get(digest).onsuccess = function (e) {
+ var body = e.target.result.body;
+ readBlobData(body, type, opts.binary, function (blobData) {
+ callback(null, blobData);
+ });
+ };
+ };
+
+ api._info = function idb_info(callback) {
+ var updateSeq;
+ var docCount;
+
+ var txnResult = openTransactionSafely(idb, [META_STORE, BY_SEQ_STORE], 'readonly');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ var txn = txnResult.txn;
+ txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) {
+ docCount = e.target.result.docCount;
+ };
+ txn.objectStore(BY_SEQ_STORE).openCursor(null, 'prev').onsuccess = function (e) {
+ var cursor = e.target.result;
+ updateSeq = cursor ? cursor.key : 0;
+ };
+
+ txn.oncomplete = function () {
+ callback(null, {
+ doc_count: docCount,
+ update_seq: updateSeq,
+ // for debugging
+ idb_attachment_format: (api._meta.blobSupport ? 'binary' : 'base64')
+ });
+ };
+ };
+
+ api._allDocs = function idb_allDocs(opts, callback) {
+ idbAllDocs(opts, idb, callback);
+ };
+
+ api._changes = function idbChanges(opts) {
+ return changes(opts, api, dbName, idb);
+ };
+
+ api._close = function (callback) {
+ // https://developer.mozilla.org/en-US/docs/IndexedDB/IDBDatabase#close
+ // "Returns immediately and closes the connection in a separate thread..."
+ idb.close();
+ cachedDBs["delete"](dbName);
+ callback();
+ };
+
+ api._getRevisionTree = function (docId, callback) {
+ var txnResult = openTransactionSafely(idb, [DOC_STORE], 'readonly');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ var txn = txnResult.txn;
+ var req = txn.objectStore(DOC_STORE).get(docId);
+ req.onsuccess = function (event) {
+ var doc = decodeMetadata(event.target.result);
+ if (!doc) {
+ callback(createError(MISSING_DOC));
+ } else {
+ callback(null, doc.rev_tree);
+ }
+ };
+ };
+
+ // This function removes revisions of document docId
+ // which are listed in revs and sets this document
+ // revision to to rev_tree
+ api._doCompaction = function (docId, revs, callback) {
+ var stores = [
+ DOC_STORE,
+ BY_SEQ_STORE,
+ ATTACH_STORE,
+ ATTACH_AND_SEQ_STORE
+ ];
+ var txnResult = openTransactionSafely(idb, stores, 'readwrite');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ var txn = txnResult.txn;
+
+ var docStore = txn.objectStore(DOC_STORE);
+
+ docStore.get(docId).onsuccess = function (event) {
+ var metadata = decodeMetadata(event.target.result);
+ traverseRevTree(metadata.rev_tree, function (isLeaf, pos,
+ revHash, ctx, opts) {
+ var rev$$1 = pos + '-' + revHash;
+ if (revs.indexOf(rev$$1) !== -1) {
+ opts.status = 'missing';
+ }
+ });
+ compactRevs(revs, docId, txn);
+ var winningRev$$1 = metadata.winningRev;
+ var deleted = metadata.deleted;
+ txn.objectStore(DOC_STORE).put(
+ encodeMetadata(metadata, winningRev$$1, deleted));
+ };
+ txn.onabort = idbError(callback);
+ txn.oncomplete = function () {
+ callback();
+ };
+ };
+
+
+ api._getLocal = function (id, callback) {
+ var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readonly');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ var tx = txnResult.txn;
+ var req = tx.objectStore(LOCAL_STORE).get(id);
+
+ req.onerror = idbError(callback);
+ req.onsuccess = function (e) {
+ var doc = e.target.result;
+ if (!doc) {
+ callback(createError(MISSING_DOC));
+ } else {
+ delete doc['_doc_id_rev']; // for backwards compat
+ callback(null, doc);
+ }
+ };
+ };
+
+ api._putLocal = function (doc, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ delete doc._revisions; // ignore this, trust the rev
+ var oldRev = doc._rev;
+ var id = doc._id;
+ if (!oldRev) {
+ doc._rev = '0-1';
+ } else {
+ doc._rev = '0-' + (parseInt(oldRev.split('-')[1], 10) + 1);
+ }
+
+ var tx = opts.ctx;
+ var ret;
+ if (!tx) {
+ var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ tx = txnResult.txn;
+ tx.onerror = idbError(callback);
+ tx.oncomplete = function () {
+ if (ret) {
+ callback(null, ret);
+ }
+ };
+ }
+
+ var oStore = tx.objectStore(LOCAL_STORE);
+ var req;
+ if (oldRev) {
+ req = oStore.get(id);
+ req.onsuccess = function (e) {
+ var oldDoc = e.target.result;
+ if (!oldDoc || oldDoc._rev !== oldRev) {
+ callback(createError(REV_CONFLICT));
+ } else { // update
+ var req = oStore.put(doc);
+ req.onsuccess = function () {
+ ret = {ok: true, id: doc._id, rev: doc._rev};
+ if (opts.ctx) { // return immediately
+ callback(null, ret);
+ }
+ };
+ }
+ };
+ } else { // new doc
+ req = oStore.add(doc);
+ req.onerror = function (e) {
+ // constraint error, already exists
+ callback(createError(REV_CONFLICT));
+ e.preventDefault(); // avoid transaction abort
+ e.stopPropagation(); // avoid transaction onerror
+ };
+ req.onsuccess = function () {
+ ret = {ok: true, id: doc._id, rev: doc._rev};
+ if (opts.ctx) { // return immediately
+ callback(null, ret);
+ }
+ };
+ }
+ };
+
+ api._removeLocal = function (doc, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ var tx = opts.ctx;
+ if (!tx) {
+ var txnResult = openTransactionSafely(idb, [LOCAL_STORE], 'readwrite');
+ if (txnResult.error) {
+ return callback(txnResult.error);
+ }
+ tx = txnResult.txn;
+ tx.oncomplete = function () {
+ if (ret) {
+ callback(null, ret);
+ }
+ };
+ }
+ var ret;
+ var id = doc._id;
+ var oStore = tx.objectStore(LOCAL_STORE);
+ var req = oStore.get(id);
+
+ req.onerror = idbError(callback);
+ req.onsuccess = function (e) {
+ var oldDoc = e.target.result;
+ if (!oldDoc || oldDoc._rev !== doc._rev) {
+ callback(createError(MISSING_DOC));
+ } else {
+ oStore["delete"](id);
+ ret = {ok: true, id: id, rev: '0-0'};
+ if (opts.ctx) { // return immediately
+ callback(null, ret);
+ }
+ }
+ };
+ };
+
+ api._destroy = function (opts, callback) {
+ changesHandler.removeAllListeners(dbName);
+
+ //Close open request for "dbName" database to fix ie delay.
+ var openReq = openReqList.get(dbName);
+ if (openReq && openReq.result) {
+ openReq.result.close();
+ cachedDBs["delete"](dbName);
+ }
+ var req = indexedDB.deleteDatabase(dbName);
+
+ req.onsuccess = function () {
+ //Remove open request from the list.
+ openReqList["delete"](dbName);
+ if (hasLocalStorage() && (dbName in localStorage)) {
+ delete localStorage[dbName];
+ }
+ callback(null, { 'ok': true });
+ };
+
+ req.onerror = idbError(callback);
+ };
+
+ var cached = cachedDBs.get(dbName);
+
+ if (cached) {
+ idb = cached.idb;
+ api._meta = cached.global;
+ return immediate(function () {
+ callback(null, api);
+ });
+ }
+
+ var req = indexedDB.open(dbName, ADAPTER_VERSION);
+ openReqList.set(dbName, req);
+
+ req.onupgradeneeded = function (e) {
+ var db = e.target.result;
+ if (e.oldVersion < 1) {
+ return createSchema(db); // new db, initial schema
+ }
+ // do migrations
+
+ var txn = e.currentTarget.transaction;
+ // these migrations have to be done in this function, before
+ // control is returned to the event loop, because IndexedDB
+
+ if (e.oldVersion < 3) {
+ createLocalStoreSchema(db); // v2 -> v3
+ }
+ if (e.oldVersion < 4) {
+ addAttachAndSeqStore(db); // v3 -> v4
+ }
+
+ var migrations = [
+ addDeletedOrLocalIndex, // v1 -> v2
+ migrateLocalStore, // v2 -> v3
+ migrateAttsAndSeqs, // v3 -> v4
+ migrateMetadata // v4 -> v5
+ ];
+
+ var i = e.oldVersion;
+
+ function next() {
+ var migration = migrations[i - 1];
+ i++;
+ if (migration) {
+ migration(txn, next);
+ }
+ }
+
+ next();
+ };
+
+ req.onsuccess = function (e) {
+
+ idb = e.target.result;
+
+ idb.onversionchange = function () {
+ idb.close();
+ cachedDBs["delete"](dbName);
+ };
+
+ idb.onabort = function (e) {
+ guardedConsole('error', 'Database has a global failure', e.target.error);
+ idb.close();
+ cachedDBs["delete"](dbName);
+ };
+
+ // Do a few setup operations (in parallel as much as possible):
+ // 1. Fetch meta doc
+ // 2. Check blob support
+ // 3. Calculate docCount
+ // 4. Generate an instanceId if necessary
+ // 5. Store docCount and instanceId on meta doc
+
+ var txn = idb.transaction([
+ META_STORE,
+ DETECT_BLOB_SUPPORT_STORE,
+ DOC_STORE
+ ], 'readwrite');
+
+ var storedMetaDoc = false;
+ var metaDoc;
+ var docCount;
+ var blobSupport;
+ var instanceId;
+
+ function completeSetup() {
+ if (typeof blobSupport === 'undefined' || !storedMetaDoc) {
+ return;
+ }
+ api._meta = {
+ name: dbName,
+ instanceId: instanceId,
+ blobSupport: blobSupport
+ };
+
+ cachedDBs.set(dbName, {
+ idb: idb,
+ global: api._meta
+ });
+ callback(null, api);
+ }
+
+ function storeMetaDocIfReady() {
+ if (typeof docCount === 'undefined' || typeof metaDoc === 'undefined') {
+ return;
+ }
+ var instanceKey = dbName + '_id';
+ if (instanceKey in metaDoc) {
+ instanceId = metaDoc[instanceKey];
+ } else {
+ metaDoc[instanceKey] = instanceId = uuid();
+ }
+ metaDoc.docCount = docCount;
+ txn.objectStore(META_STORE).put(metaDoc);
+ }
+
+ //
+ // fetch or generate the instanceId
+ //
+ txn.objectStore(META_STORE).get(META_STORE).onsuccess = function (e) {
+ metaDoc = e.target.result || { id: META_STORE };
+ storeMetaDocIfReady();
+ };
+
+ //
+ // countDocs
+ //
+ countDocs(txn, function (count) {
+ docCount = count;
+ storeMetaDocIfReady();
+ });
+
+ //
+ // check blob support
+ //
+ if (!blobSupportPromise) {
+ // make sure blob support is only checked once
+ blobSupportPromise = checkBlobSupport(txn);
+ }
+
+ blobSupportPromise.then(function (val) {
+ blobSupport = val;
+ completeSetup();
+ });
+
+ // only when the metadata put transaction has completed,
+ // consider the setup done
+ txn.oncomplete = function () {
+ storedMetaDoc = true;
+ completeSetup();
+ };
+ txn.onabort = idbError(callback);
+ };
+
+ req.onerror = function () {
+ var msg = 'Failed to open indexedDB, are you in private browsing mode?';
+ guardedConsole('error', msg);
+ callback(createError(IDB_ERROR, msg));
+ };
+}
+
+IdbPouch.valid = function () {
+ // Following #7085 buggy idb versions (typically Safari < 10.1) are
+ // considered valid.
+
+ // On Firefox SecurityError is thrown while referencing indexedDB if cookies
+ // are not allowed. `typeof indexedDB` also triggers the error.
+ try {
+ // some outdated implementations of IDB that appear on Samsung
+ // and HTC Android devices <4.4 are missing IDBKeyRange
+ return typeof indexedDB !== 'undefined' && typeof IDBKeyRange !== 'undefined';
+ } catch (e) {
+ return false;
+ }
+};
+
+function IDBPouch (PouchDB) {
+ PouchDB.adapter('idb', IdbPouch, true);
+}
+
+// dead simple promise pool, inspired by https://github.com/timdp/es6-promise-pool
+// but much smaller in code size. limits the number of concurrent promises that are executed
+
+
+function pool(promiseFactories, limit) {
+ return new Promise(function (resolve, reject) {
+ var running = 0;
+ var current = 0;
+ var done = 0;
+ var len = promiseFactories.length;
+ var err;
+
+ function runNext() {
+ running++;
+ promiseFactories[current++]().then(onSuccess, onError);
+ }
+
+ function doNext() {
+ if (++done === len) {
+ /* istanbul ignore if */
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ } else {
+ runNextBatch();
+ }
+ }
+
+ function onSuccess() {
+ running--;
+ doNext();
+ }
+
+ /* istanbul ignore next */
+ function onError(thisErr) {
+ running--;
+ err = err || thisErr;
+ doNext();
+ }
+
+ function runNextBatch() {
+ while (running < limit && current < len) {
+ runNext();
+ }
+ }
+
+ runNextBatch();
+ });
+}
+
+var CHANGES_BATCH_SIZE = 25;
+var MAX_SIMULTANEOUS_REVS = 50;
+var CHANGES_TIMEOUT_BUFFER = 5000;
+var DEFAULT_HEARTBEAT = 10000;
+
+var supportsBulkGetMap = {};
+
+function readAttachmentsAsBlobOrBuffer(row) {
+ var doc = row.doc || row.ok;
+ var atts = doc && doc._attachments;
+ if (!atts) {
+ return;
+ }
+ Object.keys(atts).forEach(function (filename) {
+ var att = atts[filename];
+ att.data = b64ToBluffer(att.data, att.content_type);
+ });
+}
+
+function encodeDocId(id) {
+ if (/^_design/.test(id)) {
+ return '_design/' + encodeURIComponent(id.slice(8));
+ }
+ if (/^_local/.test(id)) {
+ return '_local/' + encodeURIComponent(id.slice(7));
+ }
+ return encodeURIComponent(id);
+}
+
+function preprocessAttachments$1(doc) {
+ if (!doc._attachments || !Object.keys(doc._attachments)) {
+ return Promise.resolve();
+ }
+
+ return Promise.all(Object.keys(doc._attachments).map(function (key) {
+ var attachment = doc._attachments[key];
+ if (attachment.data && typeof attachment.data !== 'string') {
+ return new Promise(function (resolve) {
+ blobToBase64(attachment.data, resolve);
+ }).then(function (b64) {
+ attachment.data = b64;
+ });
+ }
+ }));
+}
+
+function hasUrlPrefix(opts) {
+ if (!opts.prefix) {
+ return false;
+ }
+ var protocol = parseUri(opts.prefix).protocol;
+ return protocol === 'http' || protocol === 'https';
+}
+
+// Get all the information you possibly can about the URI given by name and
+// return it as a suitable object.
+function getHost(name, opts) {
+ // encode db name if opts.prefix is a url (#5574)
+ if (hasUrlPrefix(opts)) {
+ var dbName = opts.name.substr(opts.prefix.length);
+ // Ensure prefix has a trailing slash
+ var prefix = opts.prefix.replace(/\/?$/, '/');
+ name = prefix + encodeURIComponent(dbName);
+ }
+
+ var uri = parseUri(name);
+ if (uri.user || uri.password) {
+ uri.auth = {username: uri.user, password: uri.password};
+ }
+
+ // Split the path part of the URI into parts using '/' as the delimiter
+ // after removing any leading '/' and any trailing '/'
+ var parts = uri.path.replace(/(^\/|\/$)/g, '').split('/');
+
+ uri.db = parts.pop();
+ // Prevent double encoding of URI component
+ if (uri.db.indexOf('%') === -1) {
+ uri.db = encodeURIComponent(uri.db);
+ }
+
+ uri.path = parts.join('/');
+
+ return uri;
+}
+
+// Generate a URL with the host data given by opts and the given path
+function genDBUrl(opts, path) {
+ return genUrl(opts, opts.db + '/' + path);
+}
+
+// Generate a URL with the host data given by opts and the given path
+function genUrl(opts, path) {
+ // If the host already has a path, then we need to have a path delimiter
+ // Otherwise, the path delimiter is the empty string
+ var pathDel = !opts.path ? '' : '/';
+
+ // If the host already has a path, then we need to have a path delimiter
+ // Otherwise, the path delimiter is the empty string
+ return opts.protocol + '://' + opts.host +
+ (opts.port ? (':' + opts.port) : '') +
+ '/' + opts.path + pathDel + path;
+}
+
+function paramsToStr(params) {
+ return '?' + Object.keys(params).map(function (k) {
+ return k + '=' + encodeURIComponent(params[k]);
+ }).join('&');
+}
+
+function shouldCacheBust(opts) {
+ var ua = (typeof navigator !== 'undefined' && navigator.userAgent) ?
+ navigator.userAgent.toLowerCase() : '';
+ var isIE = ua.indexOf('msie') !== -1;
+ var isTrident = ua.indexOf('trident') !== -1;
+ var isEdge = ua.indexOf('edge') !== -1;
+ var isGET = !('method' in opts) || opts.method === 'GET';
+ return (isIE || isTrident || isEdge) && isGET;
+}
+
+// Implements the PouchDB API for dealing with CouchDB instances over HTTP
+function HttpPouch(opts, callback) {
+
+ // The functions that will be publicly available for HttpPouch
+ var api = this;
+
+ var host = getHost(opts.name, opts);
+ var dbUrl = genDBUrl(host, '');
+
+ opts = clone(opts);
+
+ var ourFetch = function (url, options) {
+
+ options = options || {};
+ options.headers = options.headers || new h();
+
+ options.credentials = 'include';
+
+ if (opts.auth || host.auth) {
+ var nAuth = opts.auth || host.auth;
+ var str = nAuth.username + ':' + nAuth.password;
+ var token = thisBtoa(unescape(encodeURIComponent(str)));
+ options.headers.set('Authorization', 'Basic ' + token);
+ }
+
+ var headers = opts.headers || {};
+ Object.keys(headers).forEach(function (key) {
+ options.headers.append(key, headers[key]);
+ });
+
+ /* istanbul ignore if */
+ if (shouldCacheBust(options)) {
+ url += (url.indexOf('?') === -1 ? '?' : '&') + '_nonce=' + Date.now();
+ }
+
+ var fetchFun = opts.fetch || f$1;
+ return fetchFun(url, options);
+ };
+
+ function adapterFun$$1(name, fun) {
+ return adapterFun(name, getArguments(function (args) {
+ setup().then(function () {
+ return fun.apply(this, args);
+ })["catch"](function (e) {
+ var callback = args.pop();
+ callback(e);
+ });
+ })).bind(api);
+ }
+
+ function fetchJSON(url, options, callback) {
+
+ var result = {};
+
+ options = options || {};
+ options.headers = options.headers || new h();
+
+ if (!options.headers.get('Content-Type')) {
+ options.headers.set('Content-Type', 'application/json');
+ }
+ if (!options.headers.get('Accept')) {
+ options.headers.set('Accept', 'application/json');
+ }
+
+ return ourFetch(url, options).then(function (response) {
+ result.ok = response.ok;
+ result.status = response.status;
+ return response.json();
+ }).then(function (json) {
+ result.data = json;
+ if (!result.ok) {
+ result.data.status = result.status;
+ var err = generateErrorFromResponse(result.data);
+ if (callback) {
+ return callback(err);
+ } else {
+ throw err;
+ }
+ }
+
+ if (Array.isArray(result.data)) {
+ result.data = result.data.map(function (v) {
+ if (v.error || v.missing) {
+ return generateErrorFromResponse(v);
+ } else {
+ return v;
+ }
+ });
+ }
+
+ if (callback) {
+ callback(null, result.data);
+ } else {
+ return result;
+ }
+ });
+ }
+
+ var setupPromise;
+
+ function setup() {
+ if (opts.skip_setup) {
+ return Promise.resolve();
+ }
+
+ // If there is a setup in process or previous successful setup
+ // done then we will use that
+ // If previous setups have been rejected we will try again
+ if (setupPromise) {
+ return setupPromise;
+ }
+
+ setupPromise = fetchJSON(dbUrl)["catch"](function (err) {
+ if (err && err.status && err.status === 404) {
+ // Doesnt exist, create it
+ explainError(404, 'PouchDB is just detecting if the remote exists.');
+ return fetchJSON(dbUrl, {method: 'PUT'});
+ } else {
+ return Promise.reject(err);
+ }
+ })["catch"](function (err) {
+ // If we try to create a database that already exists, skipped in
+ // istanbul since its catching a race condition.
+ /* istanbul ignore if */
+ if (err && err.status && err.status === 412) {
+ return true;
+ }
+ return Promise.reject(err);
+ });
+
+ setupPromise["catch"](function () {
+ setupPromise = null;
+ });
+
+ return setupPromise;
+ }
+
+ immediate(function () {
+ callback(null, api);
+ });
+
+ api._remote = true;
+
+ /* istanbul ignore next */
+ api.type = function () {
+ return 'http';
+ };
+
+ api.id = adapterFun$$1('id', function (callback) {
+ ourFetch(genUrl(host, '')).then(function (response) {
+ return response.json();
+ })["catch"](function () {
+ return {};
+ }).then(function (result) {
+ // Bad response or missing `uuid` should not prevent ID generation.
+ var uuid$$1 = (result && result.uuid) ?
+ (result.uuid + host.db) : genDBUrl(host, '');
+ callback(null, uuid$$1);
+ });
+ });
+
+ // Sends a POST request to the host calling the couchdb _compact function
+ // version: The version of CouchDB it is running
+ api.compact = adapterFun$$1('compact', function (opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ opts = clone(opts);
+
+ fetchJSON(genDBUrl(host, '_compact'), {method: 'POST'}).then(function () {
+ function ping() {
+ api.info(function (err, res) {
+ // CouchDB may send a "compact_running:true" if it's
+ // already compacting. PouchDB Server doesn't.
+ /* istanbul ignore else */
+ if (res && !res.compact_running) {
+ callback(null, {ok: true});
+ } else {
+ setTimeout(ping, opts.interval || 200);
+ }
+ });
+ }
+ // Ping the http if it's finished compaction
+ ping();
+ });
+ });
+
+ api.bulkGet = adapterFun('bulkGet', function (opts, callback) {
+ var self = this;
+
+ function doBulkGet(cb) {
+ var params = {};
+ if (opts.revs) {
+ params.revs = true;
+ }
+ if (opts.attachments) {
+ /* istanbul ignore next */
+ params.attachments = true;
+ }
+ if (opts.latest) {
+ params.latest = true;
+ }
+ fetchJSON(genDBUrl(host, '_bulk_get' + paramsToStr(params)), {
+ method: 'POST',
+ body: JSON.stringify({ docs: opts.docs})
+ }).then(function (result) {
+ if (opts.attachments && opts.binary) {
+ result.data.results.forEach(function (res) {
+ res.docs.forEach(readAttachmentsAsBlobOrBuffer);
+ });
+ }
+ cb(null, result.data);
+ })["catch"](cb);
+ }
+
+ /* istanbul ignore next */
+ function doBulkGetShim() {
+ // avoid "url too long error" by splitting up into multiple requests
+ var batchSize = MAX_SIMULTANEOUS_REVS;
+ var numBatches = Math.ceil(opts.docs.length / batchSize);
+ var numDone = 0;
+ var results = new Array(numBatches);
+
+ function onResult(batchNum) {
+ return function (err, res) {
+ // err is impossible because shim returns a list of errs in that case
+ results[batchNum] = res.results;
+ if (++numDone === numBatches) {
+ callback(null, {results: flatten(results)});
+ }
+ };
+ }
+
+ for (var i = 0; i < numBatches; i++) {
+ var subOpts = pick(opts, ['revs', 'attachments', 'binary', 'latest']);
+ subOpts.docs = opts.docs.slice(i * batchSize,
+ Math.min(opts.docs.length, (i + 1) * batchSize));
+ bulkGet(self, subOpts, onResult(i));
+ }
+ }
+
+ // mark the whole database as either supporting or not supporting _bulk_get
+ var dbUrl = genUrl(host, '');
+ var supportsBulkGet = supportsBulkGetMap[dbUrl];
+
+ /* istanbul ignore next */
+ if (typeof supportsBulkGet !== 'boolean') {
+ // check if this database supports _bulk_get
+ doBulkGet(function (err, res) {
+ if (err) {
+ supportsBulkGetMap[dbUrl] = false;
+ explainError(
+ err.status,
+ 'PouchDB is just detecting if the remote ' +
+ 'supports the _bulk_get API.'
+ );
+ doBulkGetShim();
+ } else {
+ supportsBulkGetMap[dbUrl] = true;
+ callback(null, res);
+ }
+ });
+ } else if (supportsBulkGet) {
+ doBulkGet(callback);
+ } else {
+ doBulkGetShim();
+ }
+ });
+
+ // Calls GET on the host, which gets back a JSON string containing
+ // couchdb: A welcome string
+ // version: The version of CouchDB it is running
+ api._info = function (callback) {
+ setup().then(function () {
+ return ourFetch(genDBUrl(host, ''));
+ }).then(function (response) {
+ return response.json();
+ }).then(function (info) {
+ info.host = genDBUrl(host, '');
+ callback(null, info);
+ })["catch"](callback);
+ };
+
+ api.fetch = function (path, options) {
+ return setup().then(function () {
+ var url = path.substring(0, 1) === '/' ?
+ genUrl(host, path.substring(1)) :
+ genDBUrl(host, path);
+ return ourFetch(url, options);
+ });
+ };
+
+ // Get the document with the given id from the database given by host.
+ // The id could be solely the _id in the database, or it may be a
+ // _design/ID or _local/ID path
+ api.get = adapterFun$$1('get', function (id, opts, callback) {
+ // If no options were given, set the callback to the second parameter
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ opts = clone(opts);
+
+ // List of parameters to add to the GET request
+ var params = {};
+
+ if (opts.revs) {
+ params.revs = true;
+ }
+
+ if (opts.revs_info) {
+ params.revs_info = true;
+ }
+
+ if (opts.latest) {
+ params.latest = true;
+ }
+
+ if (opts.open_revs) {
+ if (opts.open_revs !== "all") {
+ opts.open_revs = JSON.stringify(opts.open_revs);
+ }
+ params.open_revs = opts.open_revs;
+ }
+
+ if (opts.rev) {
+ params.rev = opts.rev;
+ }
+
+ if (opts.conflicts) {
+ params.conflicts = opts.conflicts;
+ }
+
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ params.update_seq = opts.update_seq;
+ }
+
+ id = encodeDocId(id);
+
+ function fetchAttachments(doc) {
+ var atts = doc._attachments;
+ var filenames = atts && Object.keys(atts);
+ if (!atts || !filenames.length) {
+ return;
+ }
+ // we fetch these manually in separate XHRs, because
+ // Sync Gateway would normally send it back as multipart/mixed,
+ // which we cannot parse. Also, this is more efficient than
+ // receiving attachments as base64-encoded strings.
+ function fetchData(filename) {
+ var att = atts[filename];
+ var path = encodeDocId(doc._id) + '/' + encodeAttachmentId(filename) +
+ '?rev=' + doc._rev;
+ return ourFetch(genDBUrl(host, path)).then(function (response) {
+ if (typeof process !== 'undefined' && !process.browser) {
+ return response.buffer();
+ } else {
+ /* istanbul ignore next */
+ return response.blob();
+ }
+ }).then(function (blob) {
+ if (opts.binary) {
+ // TODO: Can we remove this?
+ if (typeof process !== 'undefined' && !process.browser) {
+ blob.type = att.content_type;
+ }
+ return blob;
+ }
+ return new Promise(function (resolve) {
+ blobToBase64(blob, resolve);
+ });
+ }).then(function (data) {
+ delete att.stub;
+ delete att.length;
+ att.data = data;
+ });
+ }
+
+ var promiseFactories = filenames.map(function (filename) {
+ return function () {
+ return fetchData(filename);
+ };
+ });
+
+ // This limits the number of parallel xhr requests to 5 any time
+ // to avoid issues with maximum browser request limits
+ return pool(promiseFactories, 5);
+ }
+
+ function fetchAllAttachments(docOrDocs) {
+ if (Array.isArray(docOrDocs)) {
+ return Promise.all(docOrDocs.map(function (doc) {
+ if (doc.ok) {
+ return fetchAttachments(doc.ok);
+ }
+ }));
+ }
+ return fetchAttachments(docOrDocs);
+ }
+
+ var url = genDBUrl(host, id + paramsToStr(params));
+ fetchJSON(url).then(function (res) {
+ return Promise.resolve().then(function () {
+ if (opts.attachments) {
+ return fetchAllAttachments(res.data);
+ }
+ }).then(function () {
+ callback(null, res.data);
+ });
+ })["catch"](function (e) {
+ e.docId = id;
+ callback(e);
+ });
+ });
+
+
+ // Delete the document given by doc from the database given by host.
+ api.remove = adapterFun$$1('remove', function (docOrId, optsOrRev, opts, cb) {
+ var doc;
+ if (typeof optsOrRev === 'string') {
+ // id, rev, opts, callback style
+ doc = {
+ _id: docOrId,
+ _rev: optsOrRev
+ };
+ if (typeof opts === 'function') {
+ cb = opts;
+ opts = {};
+ }
+ } else {
+ // doc, opts, callback style
+ doc = docOrId;
+ if (typeof optsOrRev === 'function') {
+ cb = optsOrRev;
+ opts = {};
+ } else {
+ cb = opts;
+ opts = optsOrRev;
+ }
+ }
+
+ var rev$$1 = (doc._rev || opts.rev);
+ var url = genDBUrl(host, encodeDocId(doc._id)) + '?rev=' + rev$$1;
+
+ fetchJSON(url, {method: 'DELETE'}, cb)["catch"](cb);
+ });
+
+ function encodeAttachmentId(attachmentId) {
+ return attachmentId.split("/").map(encodeURIComponent).join("/");
+ }
+
+ // Get the attachment
+ api.getAttachment = adapterFun$$1('getAttachment', function (docId, attachmentId,
+ opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ var params = opts.rev ? ('?rev=' + opts.rev) : '';
+ var url = genDBUrl(host, encodeDocId(docId)) + '/' +
+ encodeAttachmentId(attachmentId) + params;
+ var contentType;
+ ourFetch(url, {method: 'GET'}).then(function (response) {
+ contentType = response.headers.get('content-type');
+ if (!response.ok) {
+ throw response;
+ } else {
+ if (typeof process !== 'undefined' && !process.browser) {
+ return response.buffer();
+ } else {
+ /* istanbul ignore next */
+ return response.blob();
+ }
+ }
+ }).then(function (blob) {
+ // TODO: also remove
+ if (typeof process !== 'undefined' && !process.browser) {
+ blob.type = contentType;
+ }
+ callback(null, blob);
+ })["catch"](function (err) {
+ callback(err);
+ });
+ });
+
+ // Remove the attachment given by the id and rev
+ api.removeAttachment = adapterFun$$1('removeAttachment', function (docId,
+ attachmentId,
+ rev$$1,
+ callback) {
+ var url = genDBUrl(host, encodeDocId(docId) + '/' +
+ encodeAttachmentId(attachmentId)) + '?rev=' + rev$$1;
+ fetchJSON(url, {method: 'DELETE'}, callback)["catch"](callback);
+ });
+
+ // Add the attachment given by blob and its contentType property
+ // to the document with the given id, the revision given by rev, and
+ // add it to the database given by host.
+ api.putAttachment = adapterFun$$1('putAttachment', function (docId, attachmentId,
+ rev$$1, blob,
+ type, callback) {
+ if (typeof type === 'function') {
+ callback = type;
+ type = blob;
+ blob = rev$$1;
+ rev$$1 = null;
+ }
+ var id = encodeDocId(docId) + '/' + encodeAttachmentId(attachmentId);
+ var url = genDBUrl(host, id);
+ if (rev$$1) {
+ url += '?rev=' + rev$$1;
+ }
+
+ if (typeof blob === 'string') {
+ // input is assumed to be a base64 string
+ var binary;
+ try {
+ binary = thisAtob(blob);
+ } catch (err) {
+ return callback(createError(BAD_ARG,
+ 'Attachment is not a valid base64 string'));
+ }
+ blob = binary ? binStringToBluffer(binary, type) : '';
+ }
+
+ // Add the attachment
+ fetchJSON(url, {
+ headers: new h({'Content-Type': type}),
+ method: 'PUT',
+ body: blob
+ }, callback)["catch"](callback);
+ });
+
+ // Update/create multiple documents given by req in the database
+ // given by host.
+ api._bulkDocs = function (req, opts, callback) {
+ // If new_edits=false then it prevents the database from creating
+ // new revision numbers for the documents. Instead it just uses
+ // the old ones. This is used in database replication.
+ req.new_edits = opts.new_edits;
+
+ setup().then(function () {
+ return Promise.all(req.docs.map(preprocessAttachments$1));
+ }).then(function () {
+ // Update/create the documents
+ return fetchJSON(genDBUrl(host, '_bulk_docs'), {
+ method: 'POST',
+ body: JSON.stringify(req)
+ }, callback);
+ })["catch"](callback);
+ };
+
+
+ // Update/create document
+ api._put = function (doc, opts, callback) {
+ setup().then(function () {
+ return preprocessAttachments$1(doc);
+ }).then(function () {
+ return fetchJSON(genDBUrl(host, encodeDocId(doc._id)), {
+ method: 'PUT',
+ body: JSON.stringify(doc)
+ });
+ }).then(function (result) {
+ callback(null, result.data);
+ })["catch"](function (err) {
+ err.docId = doc && doc._id;
+ callback(err);
+ });
+ };
+
+
+ // Get a listing of the documents in the database given
+ // by host and ordered by increasing id.
+ api.allDocs = adapterFun$$1('allDocs', function (opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ opts = clone(opts);
+
+ // List of parameters to add to the GET request
+ var params = {};
+ var body;
+ var method = 'GET';
+
+ if (opts.conflicts) {
+ params.conflicts = true;
+ }
+
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ params.update_seq = true;
+ }
+
+ if (opts.descending) {
+ params.descending = true;
+ }
+
+ if (opts.include_docs) {
+ params.include_docs = true;
+ }
+
+ // added in CouchDB 1.6.0
+ if (opts.attachments) {
+ params.attachments = true;
+ }
+
+ if (opts.key) {
+ params.key = JSON.stringify(opts.key);
+ }
+
+ if (opts.start_key) {
+ opts.startkey = opts.start_key;
+ }
+
+ if (opts.startkey) {
+ params.startkey = JSON.stringify(opts.startkey);
+ }
+
+ if (opts.end_key) {
+ opts.endkey = opts.end_key;
+ }
+
+ if (opts.endkey) {
+ params.endkey = JSON.stringify(opts.endkey);
+ }
+
+ if (typeof opts.inclusive_end !== 'undefined') {
+ params.inclusive_end = !!opts.inclusive_end;
+ }
+
+ if (typeof opts.limit !== 'undefined') {
+ params.limit = opts.limit;
+ }
+
+ if (typeof opts.skip !== 'undefined') {
+ params.skip = opts.skip;
+ }
+
+ var paramStr = paramsToStr(params);
+
+ if (typeof opts.keys !== 'undefined') {
+ method = 'POST';
+ body = {keys: opts.keys};
+ }
+
+ fetchJSON(genDBUrl(host, '_all_docs' + paramStr), {
+ method: method,
+ body: JSON.stringify(body)
+ }).then(function (result) {
+ if (opts.include_docs && opts.attachments && opts.binary) {
+ result.data.rows.forEach(readAttachmentsAsBlobOrBuffer);
+ }
+ callback(null, result.data);
+ })["catch"](callback);
+ });
+
+ // Get a list of changes made to documents in the database given by host.
+ // TODO According to the README, there should be two other methods here,
+ // api.changes.addListener and api.changes.removeListener.
+ api._changes = function (opts) {
+
+ // We internally page the results of a changes request, this means
+ // if there is a large set of changes to be returned we can start
+ // processing them quicker instead of waiting on the entire
+ // set of changes to return and attempting to process them at once
+ var batchSize = 'batch_size' in opts ? opts.batch_size : CHANGES_BATCH_SIZE;
+
+ opts = clone(opts);
+
+ if (opts.continuous && !('heartbeat' in opts)) {
+ opts.heartbeat = DEFAULT_HEARTBEAT;
+ }
+
+ var requestTimeout = ('timeout' in opts) ? opts.timeout : 30 * 1000;
+
+ // ensure CHANGES_TIMEOUT_BUFFER applies
+ if ('timeout' in opts && opts.timeout &&
+ (requestTimeout - opts.timeout) < CHANGES_TIMEOUT_BUFFER) {
+ requestTimeout = opts.timeout + CHANGES_TIMEOUT_BUFFER;
+ }
+
+ /* istanbul ignore if */
+ if ('heartbeat' in opts && opts.heartbeat &&
+ (requestTimeout - opts.heartbeat) < CHANGES_TIMEOUT_BUFFER) {
+ requestTimeout = opts.heartbeat + CHANGES_TIMEOUT_BUFFER;
+ }
+
+ var params = {};
+ if ('timeout' in opts && opts.timeout) {
+ params.timeout = opts.timeout;
+ }
+
+ var limit = (typeof opts.limit !== 'undefined') ? opts.limit : false;
+ var leftToFetch = limit;
+
+ if (opts.style) {
+ params.style = opts.style;
+ }
+
+ if (opts.include_docs || opts.filter && typeof opts.filter === 'function') {
+ params.include_docs = true;
+ }
+
+ if (opts.attachments) {
+ params.attachments = true;
+ }
+
+ if (opts.continuous) {
+ params.feed = 'longpoll';
+ }
+
+ if (opts.seq_interval) {
+ params.seq_interval = opts.seq_interval;
+ }
+
+ if (opts.conflicts) {
+ params.conflicts = true;
+ }
+
+ if (opts.descending) {
+ params.descending = true;
+ }
+
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ params.update_seq = true;
+ }
+
+ if ('heartbeat' in opts) {
+ // If the heartbeat value is false, it disables the default heartbeat
+ if (opts.heartbeat) {
+ params.heartbeat = opts.heartbeat;
+ }
+ }
+
+ if (opts.filter && typeof opts.filter === 'string') {
+ params.filter = opts.filter;
+ }
+
+ if (opts.view && typeof opts.view === 'string') {
+ params.filter = '_view';
+ params.view = opts.view;
+ }
+
+ // If opts.query_params exists, pass it through to the changes request.
+ // These parameters may be used by the filter on the source database.
+ if (opts.query_params && typeof opts.query_params === 'object') {
+ for (var param_name in opts.query_params) {
+ /* istanbul ignore else */
+ if (opts.query_params.hasOwnProperty(param_name)) {
+ params[param_name] = opts.query_params[param_name];
+ }
+ }
+ }
+
+ var method = 'GET';
+ var body;
+
+ if (opts.doc_ids) {
+ // set this automagically for the user; it's annoying that couchdb
+ // requires both a "filter" and a "doc_ids" param.
+ params.filter = '_doc_ids';
+ method = 'POST';
+ body = {doc_ids: opts.doc_ids };
+ }
+ /* istanbul ignore next */
+ else if (opts.selector) {
+ // set this automagically for the user, similar to above
+ params.filter = '_selector';
+ method = 'POST';
+ body = {selector: opts.selector };
+ }
+
+ var controller = new a();
+ var lastFetchedSeq;
+
+ // Get all the changes starting wtih the one immediately after the
+ // sequence number given by since.
+ var fetchData = function (since, callback) {
+ if (opts.aborted) {
+ return;
+ }
+ params.since = since;
+ // "since" can be any kind of json object in Cloudant/CouchDB 2.x
+ /* istanbul ignore next */
+ if (typeof params.since === "object") {
+ params.since = JSON.stringify(params.since);
+ }
+
+ if (opts.descending) {
+ if (limit) {
+ params.limit = leftToFetch;
+ }
+ } else {
+ params.limit = (!limit || leftToFetch > batchSize) ?
+ batchSize : leftToFetch;
+ }
+
+ // Set the options for the ajax call
+ var url = genDBUrl(host, '_changes' + paramsToStr(params));
+ var fetchOpts = {
+ signal: controller.signal,
+ method: method,
+ body: JSON.stringify(body)
+ };
+ lastFetchedSeq = since;
+
+ /* istanbul ignore if */
+ if (opts.aborted) {
+ return;
+ }
+
+ // Get the changes
+ setup().then(function () {
+ return fetchJSON(url, fetchOpts, callback);
+ })["catch"](callback);
+ };
+
+ // If opts.since exists, get all the changes from the sequence
+ // number given by opts.since. Otherwise, get all the changes
+ // from the sequence number 0.
+ var results = {results: []};
+
+ var fetched = function (err, res) {
+ if (opts.aborted) {
+ return;
+ }
+ var raw_results_length = 0;
+ // If the result of the ajax call (res) contains changes (res.results)
+ if (res && res.results) {
+ raw_results_length = res.results.length;
+ results.last_seq = res.last_seq;
+ var pending = null;
+ var lastSeq = null;
+ // Attach 'pending' property if server supports it (CouchDB 2.0+)
+ /* istanbul ignore if */
+ if (typeof res.pending === 'number') {
+ pending = res.pending;
+ }
+ if (typeof results.last_seq === 'string' || typeof results.last_seq === 'number') {
+ lastSeq = results.last_seq;
+ }
+ // For each change
+ var req = {};
+ req.query = opts.query_params;
+ res.results = res.results.filter(function (c) {
+ leftToFetch--;
+ var ret = filterChange(opts)(c);
+ if (ret) {
+ if (opts.include_docs && opts.attachments && opts.binary) {
+ readAttachmentsAsBlobOrBuffer(c);
+ }
+ if (opts.return_docs) {
+ results.results.push(c);
+ }
+ opts.onChange(c, pending, lastSeq);
+ }
+ return ret;
+ });
+ } else if (err) {
+ // In case of an error, stop listening for changes and call
+ // opts.complete
+ opts.aborted = true;
+ opts.complete(err);
+ return;
+ }
+
+ // The changes feed may have timed out with no results
+ // if so reuse last update sequence
+ if (res && res.last_seq) {
+ lastFetchedSeq = res.last_seq;
+ }
+
+ var finished = (limit && leftToFetch <= 0) ||
+ (res && raw_results_length < batchSize) ||
+ (opts.descending);
+
+ if ((opts.continuous && !(limit && leftToFetch <= 0)) || !finished) {
+ // Queue a call to fetch again with the newest sequence number
+ immediate(function () { fetchData(lastFetchedSeq, fetched); });
+ } else {
+ // We're done, call the callback
+ opts.complete(null, results);
+ }
+ };
+
+ fetchData(opts.since || 0, fetched);
+
+ // Return a method to cancel this method from processing any more
+ return {
+ cancel: function () {
+ opts.aborted = true;
+ controller.abort();
+ }
+ };
+ };
+
+ // Given a set of document/revision IDs (given by req), tets the subset of
+ // those that do NOT correspond to revisions stored in the database.
+ // See http://wiki.apache.org/couchdb/HttpPostRevsDiff
+ api.revsDiff = adapterFun$$1('revsDiff', function (req, opts, callback) {
+ // If no options were given, set the callback to be the second parameter
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+
+ // Get the missing document/revision IDs
+ fetchJSON(genDBUrl(host, '_revs_diff'), {
+ method: 'POST',
+ body: JSON.stringify(req)
+ }, callback)["catch"](callback);
+ });
+
+ api._close = function (callback) {
+ callback();
+ };
+
+ api._destroy = function (options, callback) {
+ fetchJSON(genDBUrl(host, ''), {method: 'DELETE'}).then(function (json) {
+ callback(null, json);
+ })["catch"](function (err) {
+ /* istanbul ignore if */
+ if (err.status === 404) {
+ callback(null, {ok: true});
+ } else {
+ callback(err);
+ }
+ });
+ };
+}
+
+// HttpPouch is a valid adapter.
+HttpPouch.valid = function () {
+ return true;
+};
+
+function HttpPouch$1 (PouchDB) {
+ PouchDB.adapter('http', HttpPouch, false);
+ PouchDB.adapter('https', HttpPouch, false);
+}
+
+function QueryParseError(message) {
+ this.status = 400;
+ this.name = 'query_parse_error';
+ this.message = message;
+ this.error = true;
+ try {
+ Error.captureStackTrace(this, QueryParseError);
+ } catch (e) {}
+}
+
+inherits(QueryParseError, Error);
+
+function NotFoundError(message) {
+ this.status = 404;
+ this.name = 'not_found';
+ this.message = message;
+ this.error = true;
+ try {
+ Error.captureStackTrace(this, NotFoundError);
+ } catch (e) {}
+}
+
+inherits(NotFoundError, Error);
+
+function BuiltInError(message) {
+ this.status = 500;
+ this.name = 'invalid_value';
+ this.message = message;
+ this.error = true;
+ try {
+ Error.captureStackTrace(this, BuiltInError);
+ } catch (e) {}
+}
+
+inherits(BuiltInError, Error);
+
+function promisedCallback(promise, callback) {
+ if (callback) {
+ promise.then(function (res) {
+ immediate(function () {
+ callback(null, res);
+ });
+ }, function (reason) {
+ immediate(function () {
+ callback(reason);
+ });
+ });
+ }
+ return promise;
+}
+
+function callbackify(fun) {
+ return getArguments(function (args) {
+ var cb = args.pop();
+ var promise = fun.apply(this, args);
+ if (typeof cb === 'function') {
+ promisedCallback(promise, cb);
+ }
+ return promise;
+ });
+}
+
+// Promise finally util similar to Q.finally
+function fin(promise, finalPromiseFactory) {
+ return promise.then(function (res) {
+ return finalPromiseFactory().then(function () {
+ return res;
+ });
+ }, function (reason) {
+ return finalPromiseFactory().then(function () {
+ throw reason;
+ });
+ });
+}
+
+function sequentialize(queue, promiseFactory) {
+ return function () {
+ var args = arguments;
+ var that = this;
+ return queue.add(function () {
+ return promiseFactory.apply(that, args);
+ });
+ };
+}
+
+// uniq an array of strings, order not guaranteed
+// similar to underscore/lodash _.uniq
+function uniq(arr) {
+ var theSet = new ExportedSet(arr);
+ var result = new Array(theSet.size);
+ var index = -1;
+ theSet.forEach(function (value) {
+ result[++index] = value;
+ });
+ return result;
+}
+
+function mapToKeysArray(map) {
+ var result = new Array(map.size);
+ var index = -1;
+ map.forEach(function (value, key) {
+ result[++index] = key;
+ });
+ return result;
+}
+
+function createBuiltInError(name) {
+ var message = 'builtin ' + name +
+ ' function requires map values to be numbers' +
+ ' or number arrays';
+ return new BuiltInError(message);
+}
+
+function sum(values) {
+ var result = 0;
+ for (var i = 0, len = values.length; i < len; i++) {
+ var num = values[i];
+ if (typeof num !== 'number') {
+ if (Array.isArray(num)) {
+ // lists of numbers are also allowed, sum them separately
+ result = typeof result === 'number' ? [result] : result;
+ for (var j = 0, jLen = num.length; j < jLen; j++) {
+ var jNum = num[j];
+ if (typeof jNum !== 'number') {
+ throw createBuiltInError('_sum');
+ } else if (typeof result[j] === 'undefined') {
+ result.push(jNum);
+ } else {
+ result[j] += jNum;
+ }
+ }
+ } else { // not array/number
+ throw createBuiltInError('_sum');
+ }
+ } else if (typeof result === 'number') {
+ result += num;
+ } else { // add number to array
+ result[0] += num;
+ }
+ }
+ return result;
+}
+
+var log = guardedConsole.bind(null, 'log');
+var isArray = Array.isArray;
+var toJSON = JSON.parse;
+
+function evalFunctionWithEval(func, emit) {
+ return scopeEval(
+ "return (" + func.replace(/;\s*$/, "") + ");",
+ {
+ emit: emit,
+ sum: sum,
+ log: log,
+ isArray: isArray,
+ toJSON: toJSON
+ }
+ );
+}
+
+/*
+ * Simple task queue to sequentialize actions. Assumes
+ * callbacks will eventually fire (once).
+ */
+
+
+function TaskQueue$1() {
+ this.promise = new Promise(function (fulfill) {fulfill(); });
+}
+TaskQueue$1.prototype.add = function (promiseFactory) {
+ this.promise = this.promise["catch"](function () {
+ // just recover
+ }).then(function () {
+ return promiseFactory();
+ });
+ return this.promise;
+};
+TaskQueue$1.prototype.finish = function () {
+ return this.promise;
+};
+
+function stringify(input) {
+ if (!input) {
+ return 'undefined'; // backwards compat for empty reduce
+ }
+ // for backwards compat with mapreduce, functions/strings are stringified
+ // as-is. everything else is JSON-stringified.
+ switch (typeof input) {
+ case 'function':
+ // e.g. a mapreduce map
+ return input.toString();
+ case 'string':
+ // e.g. a mapreduce built-in _reduce function
+ return input.toString();
+ default:
+ // e.g. a JSON object in the case of mango queries
+ return JSON.stringify(input);
+ }
+}
+
+/* create a string signature for a view so we can cache it and uniq it */
+function createViewSignature(mapFun, reduceFun) {
+ // the "undefined" part is for backwards compatibility
+ return stringify(mapFun) + stringify(reduceFun) + 'undefined';
+}
+
+function createView(sourceDB, viewName, mapFun, reduceFun, temporary, localDocName) {
+ var viewSignature = createViewSignature(mapFun, reduceFun);
+
+ var cachedViews;
+ if (!temporary) {
+ // cache this to ensure we don't try to update the same view twice
+ cachedViews = sourceDB._cachedViews = sourceDB._cachedViews || {};
+ if (cachedViews[viewSignature]) {
+ return cachedViews[viewSignature];
+ }
+ }
+
+ var promiseForView = sourceDB.info().then(function (info) {
+
+ var depDbName = info.db_name + '-mrview-' +
+ (temporary ? 'temp' : stringMd5(viewSignature));
+
+ // save the view name in the source db so it can be cleaned up if necessary
+ // (e.g. when the _design doc is deleted, remove all associated view data)
+ function diffFunction(doc) {
+ doc.views = doc.views || {};
+ var fullViewName = viewName;
+ if (fullViewName.indexOf('/') === -1) {
+ fullViewName = viewName + '/' + viewName;
+ }
+ var depDbs = doc.views[fullViewName] = doc.views[fullViewName] || {};
+ /* istanbul ignore if */
+ if (depDbs[depDbName]) {
+ return; // no update necessary
+ }
+ depDbs[depDbName] = true;
+ return doc;
+ }
+ return upsert(sourceDB, '_local/' + localDocName, diffFunction).then(function () {
+ return sourceDB.registerDependentDatabase(depDbName).then(function (res) {
+ var db = res.db;
+ db.auto_compaction = true;
+ var view = {
+ name: depDbName,
+ db: db,
+ sourceDB: sourceDB,
+ adapter: sourceDB.adapter,
+ mapFun: mapFun,
+ reduceFun: reduceFun
+ };
+ return view.db.get('_local/lastSeq')["catch"](function (err) {
+ /* istanbul ignore if */
+ if (err.status !== 404) {
+ throw err;
+ }
+ }).then(function (lastSeqDoc) {
+ view.seq = lastSeqDoc ? lastSeqDoc.seq : 0;
+ if (cachedViews) {
+ view.db.once('destroyed', function () {
+ delete cachedViews[viewSignature];
+ });
+ }
+ return view;
+ });
+ });
+ });
+ });
+
+ if (cachedViews) {
+ cachedViews[viewSignature] = promiseForView;
+ }
+ return promiseForView;
+}
+
+var persistentQueues = {};
+var tempViewQueue = new TaskQueue$1();
+var CHANGES_BATCH_SIZE$1 = 50;
+
+function parseViewName(name) {
+ // can be either 'ddocname/viewname' or just 'viewname'
+ // (where the ddoc name is the same)
+ return name.indexOf('/') === -1 ? [name, name] : name.split('/');
+}
+
+function isGenOne(changes) {
+ // only return true if the current change is 1-
+ // and there are no other leafs
+ return changes.length === 1 && /^1-/.test(changes[0].rev);
+}
+
+function emitError(db, e) {
+ try {
+ db.emit('error', e);
+ } catch (err) {
+ guardedConsole('error',
+ 'The user\'s map/reduce function threw an uncaught error.\n' +
+ 'You can debug this error by doing:\n' +
+ 'myDatabase.on(\'error\', function (err) { debugger; });\n' +
+ 'Please double-check your map/reduce function.');
+ guardedConsole('error', e);
+ }
+}
+
+/**
+ * Returns an "abstract" mapreduce object of the form:
+ *
+ * {
+ * query: queryFun,
+ * viewCleanup: viewCleanupFun
+ * }
+ *
+ * Arguments are:
+ *
+ * localDoc: string
+ * This is for the local doc that gets saved in order to track the
+ * "dependent" DBs and clean them up for viewCleanup. It should be
+ * unique, so that indexer plugins don't collide with each other.
+ * mapper: function (mapFunDef, emit)
+ * Returns a map function based on the mapFunDef, which in the case of
+ * normal map/reduce is just the de-stringified function, but may be
+ * something else, such as an object in the case of pouchdb-find.
+ * reducer: function (reduceFunDef)
+ * Ditto, but for reducing. Modules don't have to support reducing
+ * (e.g. pouchdb-find).
+ * ddocValidator: function (ddoc, viewName)
+ * Throws an error if the ddoc or viewName is not valid.
+ * This could be a way to communicate to the user that the configuration for the
+ * indexer is invalid.
+ */
+function createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator) {
+
+ function tryMap(db, fun, doc) {
+ // emit an event if there was an error thrown by a map function.
+ // putting try/catches in a single function also avoids deoptimizations.
+ try {
+ fun(doc);
+ } catch (e) {
+ emitError(db, e);
+ }
+ }
+
+ function tryReduce(db, fun, keys, values, rereduce) {
+ // same as above, but returning the result or an error. there are two separate
+ // functions to avoid extra memory allocations since the tryCode() case is used
+ // for custom map functions (common) vs this function, which is only used for
+ // custom reduce functions (rare)
+ try {
+ return {output : fun(keys, values, rereduce)};
+ } catch (e) {
+ emitError(db, e);
+ return {error: e};
+ }
+ }
+
+ function sortByKeyThenValue(x, y) {
+ var keyCompare = collate(x.key, y.key);
+ return keyCompare !== 0 ? keyCompare : collate(x.value, y.value);
+ }
+
+ function sliceResults(results, limit, skip) {
+ skip = skip || 0;
+ if (typeof limit === 'number') {
+ return results.slice(skip, limit + skip);
+ } else if (skip > 0) {
+ return results.slice(skip);
+ }
+ return results;
+ }
+
+ function rowToDocId(row) {
+ var val = row.value;
+ // Users can explicitly specify a joined doc _id, or it
+ // defaults to the doc _id that emitted the key/value.
+ var docId = (val && typeof val === 'object' && val._id) || row.id;
+ return docId;
+ }
+
+ function readAttachmentsAsBlobOrBuffer(res) {
+ res.rows.forEach(function (row) {
+ var atts = row.doc && row.doc._attachments;
+ if (!atts) {
+ return;
+ }
+ Object.keys(atts).forEach(function (filename) {
+ var att = atts[filename];
+ atts[filename].data = b64ToBluffer(att.data, att.content_type);
+ });
+ });
+ }
+
+ function postprocessAttachments(opts) {
+ return function (res) {
+ if (opts.include_docs && opts.attachments && opts.binary) {
+ readAttachmentsAsBlobOrBuffer(res);
+ }
+ return res;
+ };
+ }
+
+ function addHttpParam(paramName, opts, params, asJson) {
+ // add an http param from opts to params, optionally json-encoded
+ var val = opts[paramName];
+ if (typeof val !== 'undefined') {
+ if (asJson) {
+ val = encodeURIComponent(JSON.stringify(val));
+ }
+ params.push(paramName + '=' + val);
+ }
+ }
+
+ function coerceInteger(integerCandidate) {
+ if (typeof integerCandidate !== 'undefined') {
+ var asNumber = Number(integerCandidate);
+ // prevents e.g. '1foo' or '1.1' being coerced to 1
+ if (!isNaN(asNumber) && asNumber === parseInt(integerCandidate, 10)) {
+ return asNumber;
+ } else {
+ return integerCandidate;
+ }
+ }
+ }
+
+ function coerceOptions(opts) {
+ opts.group_level = coerceInteger(opts.group_level);
+ opts.limit = coerceInteger(opts.limit);
+ opts.skip = coerceInteger(opts.skip);
+ return opts;
+ }
+
+ function checkPositiveInteger(number) {
+ if (number) {
+ if (typeof number !== 'number') {
+ return new QueryParseError('Invalid value for integer: "' +
+ number + '"');
+ }
+ if (number < 0) {
+ return new QueryParseError('Invalid value for positive integer: ' +
+ '"' + number + '"');
+ }
+ }
+ }
+
+ function checkQueryParseError(options, fun) {
+ var startkeyName = options.descending ? 'endkey' : 'startkey';
+ var endkeyName = options.descending ? 'startkey' : 'endkey';
+
+ if (typeof options[startkeyName] !== 'undefined' &&
+ typeof options[endkeyName] !== 'undefined' &&
+ collate(options[startkeyName], options[endkeyName]) > 0) {
+ throw new QueryParseError('No rows can match your key range, ' +
+ 'reverse your start_key and end_key or set {descending : true}');
+ } else if (fun.reduce && options.reduce !== false) {
+ if (options.include_docs) {
+ throw new QueryParseError('{include_docs:true} is invalid for reduce');
+ } else if (options.keys && options.keys.length > 1 &&
+ !options.group && !options.group_level) {
+ throw new QueryParseError('Multi-key fetches for reduce views must use ' +
+ '{group: true}');
+ }
+ }
+ ['group_level', 'limit', 'skip'].forEach(function (optionName) {
+ var error = checkPositiveInteger(options[optionName]);
+ if (error) {
+ throw error;
+ }
+ });
+ }
+
+ function httpQuery(db, fun, opts) {
+ // List of parameters to add to the PUT request
+ var params = [];
+ var body;
+ var method = 'GET';
+ var ok, status;
+
+ // If opts.reduce exists and is defined, then add it to the list
+ // of parameters.
+ // If reduce=false then the results are that of only the map function
+ // not the final result of map and reduce.
+ addHttpParam('reduce', opts, params);
+ addHttpParam('include_docs', opts, params);
+ addHttpParam('attachments', opts, params);
+ addHttpParam('limit', opts, params);
+ addHttpParam('descending', opts, params);
+ addHttpParam('group', opts, params);
+ addHttpParam('group_level', opts, params);
+ addHttpParam('skip', opts, params);
+ addHttpParam('stale', opts, params);
+ addHttpParam('conflicts', opts, params);
+ addHttpParam('startkey', opts, params, true);
+ addHttpParam('start_key', opts, params, true);
+ addHttpParam('endkey', opts, params, true);
+ addHttpParam('end_key', opts, params, true);
+ addHttpParam('inclusive_end', opts, params);
+ addHttpParam('key', opts, params, true);
+ addHttpParam('update_seq', opts, params);
+
+ // Format the list of parameters into a valid URI query string
+ params = params.join('&');
+ params = params === '' ? '' : '?' + params;
+
+ // If keys are supplied, issue a POST to circumvent GET query string limits
+ // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
+ if (typeof opts.keys !== 'undefined') {
+ var MAX_URL_LENGTH = 2000;
+ // according to http://stackoverflow.com/a/417184/680742,
+ // the de facto URL length limit is 2000 characters
+
+ var keysAsString =
+ 'keys=' + encodeURIComponent(JSON.stringify(opts.keys));
+ if (keysAsString.length + params.length + 1 <= MAX_URL_LENGTH) {
+ // If the keys are short enough, do a GET. we do this to work around
+ // Safari not understanding 304s on POSTs (see pouchdb/pouchdb#1239)
+ params += (params[0] === '?' ? '&' : '?') + keysAsString;
+ } else {
+ method = 'POST';
+ if (typeof fun === 'string') {
+ body = {keys: opts.keys};
+ } else { // fun is {map : mapfun}, so append to this
+ fun.keys = opts.keys;
+ }
+ }
+ }
+
+ // We are referencing a query defined in the design doc
+ if (typeof fun === 'string') {
+ var parts = parseViewName(fun);
+ return db.fetch('_design/' + parts[0] + '/_view/' + parts[1] + params, {
+ headers: new h({'Content-Type': 'application/json'}),
+ method: method,
+ body: JSON.stringify(body)
+ }).then(function (response) {
+ ok = response.ok;
+ status = response.status;
+ return response.json();
+ }).then(function (result) {
+ if (!ok) {
+ result.status = status;
+ throw generateErrorFromResponse(result);
+ }
+ // fail the entire request if the result contains an error
+ result.rows.forEach(function (row) {
+ /* istanbul ignore if */
+ if (row.value && row.value.error && row.value.error === "builtin_reduce_error") {
+ throw new Error(row.reason);
+ }
+ });
+ return result;
+ }).then(postprocessAttachments(opts));
+ }
+
+ // We are using a temporary view, terrible for performance, good for testing
+ body = body || {};
+ Object.keys(fun).forEach(function (key) {
+ if (Array.isArray(fun[key])) {
+ body[key] = fun[key];
+ } else {
+ body[key] = fun[key].toString();
+ }
+ });
+
+ return db.fetch('_temp_view' + params, {
+ headers: new h({'Content-Type': 'application/json'}),
+ method: 'POST',
+ body: JSON.stringify(body)
+ }).then(function (response) {
+ ok = response.ok;
+ status = response.status;
+ return response.json();
+ }).then(function (result) {
+ if (!ok) {
+ result.status = status;
+ throw generateErrorFromResponse(result);
+ }
+ return result;
+ }).then(postprocessAttachments(opts));
+ }
+
+ // custom adapters can define their own api._query
+ // and override the default behavior
+ /* istanbul ignore next */
+ function customQuery(db, fun, opts) {
+ return new Promise(function (resolve, reject) {
+ db._query(fun, opts, function (err, res) {
+ if (err) {
+ return reject(err);
+ }
+ resolve(res);
+ });
+ });
+ }
+
+ // custom adapters can define their own api._viewCleanup
+ // and override the default behavior
+ /* istanbul ignore next */
+ function customViewCleanup(db) {
+ return new Promise(function (resolve, reject) {
+ db._viewCleanup(function (err, res) {
+ if (err) {
+ return reject(err);
+ }
+ resolve(res);
+ });
+ });
+ }
+
+ function defaultsTo(value) {
+ return function (reason) {
+ /* istanbul ignore else */
+ if (reason.status === 404) {
+ return value;
+ } else {
+ throw reason;
+ }
+ };
+ }
+
+ // returns a promise for a list of docs to update, based on the input docId.
+ // the order doesn't matter, because post-3.2.0, bulkDocs
+ // is an atomic operation in all three adapters.
+ function getDocsToPersist(docId, view, docIdsToChangesAndEmits) {
+ var metaDocId = '_local/doc_' + docId;
+ var defaultMetaDoc = {_id: metaDocId, keys: []};
+ var docData = docIdsToChangesAndEmits.get(docId);
+ var indexableKeysToKeyValues = docData[0];
+ var changes = docData[1];
+
+ function getMetaDoc() {
+ if (isGenOne(changes)) {
+ // generation 1, so we can safely assume initial state
+ // for performance reasons (avoids unnecessary GETs)
+ return Promise.resolve(defaultMetaDoc);
+ }
+ return view.db.get(metaDocId)["catch"](defaultsTo(defaultMetaDoc));
+ }
+
+ function getKeyValueDocs(metaDoc) {
+ if (!metaDoc.keys.length) {
+ // no keys, no need for a lookup
+ return Promise.resolve({rows: []});
+ }
+ return view.db.allDocs({
+ keys: metaDoc.keys,
+ include_docs: true
+ });
+ }
+
+ function processKeyValueDocs(metaDoc, kvDocsRes) {
+ var kvDocs = [];
+ var oldKeys = new ExportedSet();
+
+ for (var i = 0, len = kvDocsRes.rows.length; i < len; i++) {
+ var row = kvDocsRes.rows[i];
+ var doc = row.doc;
+ if (!doc) { // deleted
+ continue;
+ }
+ kvDocs.push(doc);
+ oldKeys.add(doc._id);
+ doc._deleted = !indexableKeysToKeyValues.has(doc._id);
+ if (!doc._deleted) {
+ var keyValue = indexableKeysToKeyValues.get(doc._id);
+ if ('value' in keyValue) {
+ doc.value = keyValue.value;
+ }
+ }
+ }
+ var newKeys = mapToKeysArray(indexableKeysToKeyValues);
+ newKeys.forEach(function (key) {
+ if (!oldKeys.has(key)) {
+ // new doc
+ var kvDoc = {
+ _id: key
+ };
+ var keyValue = indexableKeysToKeyValues.get(key);
+ if ('value' in keyValue) {
+ kvDoc.value = keyValue.value;
+ }
+ kvDocs.push(kvDoc);
+ }
+ });
+ metaDoc.keys = uniq(newKeys.concat(metaDoc.keys));
+ kvDocs.push(metaDoc);
+
+ return kvDocs;
+ }
+
+ return getMetaDoc().then(function (metaDoc) {
+ return getKeyValueDocs(metaDoc).then(function (kvDocsRes) {
+ return processKeyValueDocs(metaDoc, kvDocsRes);
+ });
+ });
+ }
+
+ // updates all emitted key/value docs and metaDocs in the mrview database
+ // for the given batch of documents from the source database
+ function saveKeyValues(view, docIdsToChangesAndEmits, seq) {
+ var seqDocId = '_local/lastSeq';
+ return view.db.get(seqDocId)[
+ "catch"](defaultsTo({_id: seqDocId, seq: 0}))
+ .then(function (lastSeqDoc) {
+ var docIds = mapToKeysArray(docIdsToChangesAndEmits);
+ return Promise.all(docIds.map(function (docId) {
+ return getDocsToPersist(docId, view, docIdsToChangesAndEmits);
+ })).then(function (listOfDocsToPersist) {
+ var docsToPersist = flatten(listOfDocsToPersist);
+ lastSeqDoc.seq = seq;
+ docsToPersist.push(lastSeqDoc);
+ // write all docs in a single operation, update the seq once
+ return view.db.bulkDocs({docs : docsToPersist});
+ });
+ });
+ }
+
+ function getQueue(view) {
+ var viewName = typeof view === 'string' ? view : view.name;
+ var queue = persistentQueues[viewName];
+ if (!queue) {
+ queue = persistentQueues[viewName] = new TaskQueue$1();
+ }
+ return queue;
+ }
+
+ function updateView(view) {
+ return sequentialize(getQueue(view), function () {
+ return updateViewInQueue(view);
+ })();
+ }
+
+ function updateViewInQueue(view) {
+ // bind the emit function once
+ var mapResults;
+ var doc;
+
+ function emit(key, value) {
+ var output = {id: doc._id, key: normalizeKey(key)};
+ // Don't explicitly store the value unless it's defined and non-null.
+ // This saves on storage space, because often people don't use it.
+ if (typeof value !== 'undefined' && value !== null) {
+ output.value = normalizeKey(value);
+ }
+ mapResults.push(output);
+ }
+
+ var mapFun = mapper(view.mapFun, emit);
+
+ var currentSeq = view.seq || 0;
+
+ function processChange(docIdsToChangesAndEmits, seq) {
+ return function () {
+ return saveKeyValues(view, docIdsToChangesAndEmits, seq);
+ };
+ }
+
+ var queue = new TaskQueue$1();
+
+ function processNextBatch() {
+ return view.sourceDB.changes({
+ return_docs: true,
+ conflicts: true,
+ include_docs: true,
+ style: 'all_docs',
+ since: currentSeq,
+ limit: CHANGES_BATCH_SIZE$1
+ }).then(processBatch);
+ }
+
+ function processBatch(response) {
+ var results = response.results;
+ if (!results.length) {
+ return;
+ }
+ var docIdsToChangesAndEmits = createDocIdsToChangesAndEmits(results);
+ queue.add(processChange(docIdsToChangesAndEmits, currentSeq));
+ if (results.length < CHANGES_BATCH_SIZE$1) {
+ return;
+ }
+ return processNextBatch();
+ }
+
+ function createDocIdsToChangesAndEmits(results) {
+ var docIdsToChangesAndEmits = new ExportedMap();
+ for (var i = 0, len = results.length; i < len; i++) {
+ var change = results[i];
+ if (change.doc._id[0] !== '_') {
+ mapResults = [];
+ doc = change.doc;
+
+ if (!doc._deleted) {
+ tryMap(view.sourceDB, mapFun, doc);
+ }
+ mapResults.sort(sortByKeyThenValue);
+
+ var indexableKeysToKeyValues = createIndexableKeysToKeyValues(mapResults);
+ docIdsToChangesAndEmits.set(change.doc._id, [
+ indexableKeysToKeyValues,
+ change.changes
+ ]);
+ }
+ currentSeq = change.seq;
+ }
+ return docIdsToChangesAndEmits;
+ }
+
+ function createIndexableKeysToKeyValues(mapResults) {
+ var indexableKeysToKeyValues = new ExportedMap();
+ var lastKey;
+ for (var i = 0, len = mapResults.length; i < len; i++) {
+ var emittedKeyValue = mapResults[i];
+ var complexKey = [emittedKeyValue.key, emittedKeyValue.id];
+ if (i > 0 && collate(emittedKeyValue.key, lastKey) === 0) {
+ complexKey.push(i); // dup key+id, so make it unique
+ }
+ indexableKeysToKeyValues.set(toIndexableString(complexKey), emittedKeyValue);
+ lastKey = emittedKeyValue.key;
+ }
+ return indexableKeysToKeyValues;
+ }
+
+ return processNextBatch().then(function () {
+ return queue.finish();
+ }).then(function () {
+ view.seq = currentSeq;
+ });
+ }
+
+ function reduceView(view, results, options) {
+ if (options.group_level === 0) {
+ delete options.group_level;
+ }
+
+ var shouldGroup = options.group || options.group_level;
+
+ var reduceFun = reducer(view.reduceFun);
+
+ var groups = [];
+ var lvl = isNaN(options.group_level) ? Number.POSITIVE_INFINITY :
+ options.group_level;
+ results.forEach(function (e) {
+ var last = groups[groups.length - 1];
+ var groupKey = shouldGroup ? e.key : null;
+
+ // only set group_level for array keys
+ if (shouldGroup && Array.isArray(groupKey)) {
+ groupKey = groupKey.slice(0, lvl);
+ }
+
+ if (last && collate(last.groupKey, groupKey) === 0) {
+ last.keys.push([e.key, e.id]);
+ last.values.push(e.value);
+ return;
+ }
+ groups.push({
+ keys: [[e.key, e.id]],
+ values: [e.value],
+ groupKey: groupKey
+ });
+ });
+ results = [];
+ for (var i = 0, len = groups.length; i < len; i++) {
+ var e = groups[i];
+ var reduceTry = tryReduce(view.sourceDB, reduceFun, e.keys, e.values, false);
+ if (reduceTry.error && reduceTry.error instanceof BuiltInError) {
+ // CouchDB returns an error if a built-in errors out
+ throw reduceTry.error;
+ }
+ results.push({
+ // CouchDB just sets the value to null if a non-built-in errors out
+ value: reduceTry.error ? null : reduceTry.output,
+ key: e.groupKey
+ });
+ }
+ // no total_rows/offset when reducing
+ return {rows: sliceResults(results, options.limit, options.skip)};
+ }
+
+ function queryView(view, opts) {
+ return sequentialize(getQueue(view), function () {
+ return queryViewInQueue(view, opts);
+ })();
+ }
+
+ function queryViewInQueue(view, opts) {
+ var totalRows;
+ var shouldReduce = view.reduceFun && opts.reduce !== false;
+ var skip = opts.skip || 0;
+ if (typeof opts.keys !== 'undefined' && !opts.keys.length) {
+ // equivalent query
+ opts.limit = 0;
+ delete opts.keys;
+ }
+
+ function fetchFromView(viewOpts) {
+ viewOpts.include_docs = true;
+ return view.db.allDocs(viewOpts).then(function (res) {
+ totalRows = res.total_rows;
+ return res.rows.map(function (result) {
+
+ // implicit migration - in older versions of PouchDB,
+ // we explicitly stored the doc as {id: ..., key: ..., value: ...}
+ // this is tested in a migration test
+ /* istanbul ignore next */
+ if ('value' in result.doc && typeof result.doc.value === 'object' &&
+ result.doc.value !== null) {
+ var keys = Object.keys(result.doc.value).sort();
+ // this detection method is not perfect, but it's unlikely the user
+ // emitted a value which was an object with these 3 exact keys
+ var expectedKeys = ['id', 'key', 'value'];
+ if (!(keys < expectedKeys || keys > expectedKeys)) {
+ return result.doc.value;
+ }
+ }
+
+ var parsedKeyAndDocId = parseIndexableString(result.doc._id);
+ return {
+ key: parsedKeyAndDocId[0],
+ id: parsedKeyAndDocId[1],
+ value: ('value' in result.doc ? result.doc.value : null)
+ };
+ });
+ });
+ }
+
+ function onMapResultsReady(rows) {
+ var finalResults;
+ if (shouldReduce) {
+ finalResults = reduceView(view, rows, opts);
+ } else {
+ finalResults = {
+ total_rows: totalRows,
+ offset: skip,
+ rows: rows
+ };
+ }
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ finalResults.update_seq = view.seq;
+ }
+ if (opts.include_docs) {
+ var docIds = uniq(rows.map(rowToDocId));
+
+ return view.sourceDB.allDocs({
+ keys: docIds,
+ include_docs: true,
+ conflicts: opts.conflicts,
+ attachments: opts.attachments,
+ binary: opts.binary
+ }).then(function (allDocsRes) {
+ var docIdsToDocs = new ExportedMap();
+ allDocsRes.rows.forEach(function (row) {
+ docIdsToDocs.set(row.id, row.doc);
+ });
+ rows.forEach(function (row) {
+ var docId = rowToDocId(row);
+ var doc = docIdsToDocs.get(docId);
+ if (doc) {
+ row.doc = doc;
+ }
+ });
+ return finalResults;
+ });
+ } else {
+ return finalResults;
+ }
+ }
+
+ if (typeof opts.keys !== 'undefined') {
+ var keys = opts.keys;
+ var fetchPromises = keys.map(function (key) {
+ var viewOpts = {
+ startkey : toIndexableString([key]),
+ endkey : toIndexableString([key, {}])
+ };
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ viewOpts.update_seq = true;
+ }
+ return fetchFromView(viewOpts);
+ });
+ return Promise.all(fetchPromises).then(flatten).then(onMapResultsReady);
+ } else { // normal query, no 'keys'
+ var viewOpts = {
+ descending : opts.descending
+ };
+ /* istanbul ignore if */
+ if (opts.update_seq) {
+ viewOpts.update_seq = true;
+ }
+ var startkey;
+ var endkey;
+ if ('start_key' in opts) {
+ startkey = opts.start_key;
+ }
+ if ('startkey' in opts) {
+ startkey = opts.startkey;
+ }
+ if ('end_key' in opts) {
+ endkey = opts.end_key;
+ }
+ if ('endkey' in opts) {
+ endkey = opts.endkey;
+ }
+ if (typeof startkey !== 'undefined') {
+ viewOpts.startkey = opts.descending ?
+ toIndexableString([startkey, {}]) :
+ toIndexableString([startkey]);
+ }
+ if (typeof endkey !== 'undefined') {
+ var inclusiveEnd = opts.inclusive_end !== false;
+ if (opts.descending) {
+ inclusiveEnd = !inclusiveEnd;
+ }
+
+ viewOpts.endkey = toIndexableString(
+ inclusiveEnd ? [endkey, {}] : [endkey]);
+ }
+ if (typeof opts.key !== 'undefined') {
+ var keyStart = toIndexableString([opts.key]);
+ var keyEnd = toIndexableString([opts.key, {}]);
+ if (viewOpts.descending) {
+ viewOpts.endkey = keyStart;
+ viewOpts.startkey = keyEnd;
+ } else {
+ viewOpts.startkey = keyStart;
+ viewOpts.endkey = keyEnd;
+ }
+ }
+ if (!shouldReduce) {
+ if (typeof opts.limit === 'number') {
+ viewOpts.limit = opts.limit;
+ }
+ viewOpts.skip = skip;
+ }
+ return fetchFromView(viewOpts).then(onMapResultsReady);
+ }
+ }
+
+ function httpViewCleanup(db) {
+ return db.fetch('_view_cleanup', {
+ headers: new h({'Content-Type': 'application/json'}),
+ method: 'POST'
+ }).then(function (response) {
+ return response.json();
+ });
+ }
+
+ function localViewCleanup(db) {
+ return db.get('_local/' + localDocName).then(function (metaDoc) {
+ var docsToViews = new ExportedMap();
+ Object.keys(metaDoc.views).forEach(function (fullViewName) {
+ var parts = parseViewName(fullViewName);
+ var designDocName = '_design/' + parts[0];
+ var viewName = parts[1];
+ var views = docsToViews.get(designDocName);
+ if (!views) {
+ views = new ExportedSet();
+ docsToViews.set(designDocName, views);
+ }
+ views.add(viewName);
+ });
+ var opts = {
+ keys : mapToKeysArray(docsToViews),
+ include_docs : true
+ };
+ return db.allDocs(opts).then(function (res) {
+ var viewsToStatus = {};
+ res.rows.forEach(function (row) {
+ var ddocName = row.key.substring(8); // cuts off '_design/'
+ docsToViews.get(row.key).forEach(function (viewName) {
+ var fullViewName = ddocName + '/' + viewName;
+ /* istanbul ignore if */
+ if (!metaDoc.views[fullViewName]) {
+ // new format, without slashes, to support PouchDB 2.2.0
+ // migration test in pouchdb's browser.migration.js verifies this
+ fullViewName = viewName;
+ }
+ var viewDBNames = Object.keys(metaDoc.views[fullViewName]);
+ // design doc deleted, or view function nonexistent
+ var statusIsGood = row.doc && row.doc.views &&
+ row.doc.views[viewName];
+ viewDBNames.forEach(function (viewDBName) {
+ viewsToStatus[viewDBName] =
+ viewsToStatus[viewDBName] || statusIsGood;
+ });
+ });
+ });
+ var dbsToDelete = Object.keys(viewsToStatus).filter(
+ function (viewDBName) { return !viewsToStatus[viewDBName]; });
+ var destroyPromises = dbsToDelete.map(function (viewDBName) {
+ return sequentialize(getQueue(viewDBName), function () {
+ return new db.constructor(viewDBName, db.__opts).destroy();
+ })();
+ });
+ return Promise.all(destroyPromises).then(function () {
+ return {ok: true};
+ });
+ });
+ }, defaultsTo({ok: true}));
+ }
+
+ function queryPromised(db, fun, opts) {
+ /* istanbul ignore next */
+ if (typeof db._query === 'function') {
+ return customQuery(db, fun, opts);
+ }
+ if (isRemote(db)) {
+ return httpQuery(db, fun, opts);
+ }
+
+ if (typeof fun !== 'string') {
+ // temp_view
+ checkQueryParseError(opts, fun);
+
+ tempViewQueue.add(function () {
+ var createViewPromise = createView(
+ /* sourceDB */ db,
+ /* viewName */ 'temp_view/temp_view',
+ /* mapFun */ fun.map,
+ /* reduceFun */ fun.reduce,
+ /* temporary */ true,
+ /* localDocName */ localDocName);
+ return createViewPromise.then(function (view) {
+ return fin(updateView(view).then(function () {
+ return queryView(view, opts);
+ }), function () {
+ return view.db.destroy();
+ });
+ });
+ });
+ return tempViewQueue.finish();
+ } else {
+ // persistent view
+ var fullViewName = fun;
+ var parts = parseViewName(fullViewName);
+ var designDocName = parts[0];
+ var viewName = parts[1];
+ return db.get('_design/' + designDocName).then(function (doc) {
+ var fun = doc.views && doc.views[viewName];
+
+ if (!fun) {
+ // basic validator; it's assumed that every subclass would want this
+ throw new NotFoundError('ddoc ' + doc._id + ' has no view named ' +
+ viewName);
+ }
+
+ ddocValidator(doc, viewName);
+ checkQueryParseError(opts, fun);
+
+ var createViewPromise = createView(
+ /* sourceDB */ db,
+ /* viewName */ fullViewName,
+ /* mapFun */ fun.map,
+ /* reduceFun */ fun.reduce,
+ /* temporary */ false,
+ /* localDocName */ localDocName);
+ return createViewPromise.then(function (view) {
+ if (opts.stale === 'ok' || opts.stale === 'update_after') {
+ if (opts.stale === 'update_after') {
+ immediate(function () {
+ updateView(view);
+ });
+ }
+ return queryView(view, opts);
+ } else { // stale not ok
+ return updateView(view).then(function () {
+ return queryView(view, opts);
+ });
+ }
+ });
+ });
+ }
+ }
+
+ function abstractQuery(fun, opts, callback) {
+ var db = this;
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ opts = opts ? coerceOptions(opts) : {};
+
+ if (typeof fun === 'function') {
+ fun = {map : fun};
+ }
+
+ var promise = Promise.resolve().then(function () {
+ return queryPromised(db, fun, opts);
+ });
+ promisedCallback(promise, callback);
+ return promise;
+ }
+
+ var abstractViewCleanup = callbackify(function () {
+ var db = this;
+ /* istanbul ignore next */
+ if (typeof db._viewCleanup === 'function') {
+ return customViewCleanup(db);
+ }
+ if (isRemote(db)) {
+ return httpViewCleanup(db);
+ }
+ return localViewCleanup(db);
+ });
+
+ return {
+ query: abstractQuery,
+ viewCleanup: abstractViewCleanup
+ };
+}
+
+var builtInReduce = {
+ _sum: function (keys, values) {
+ return sum(values);
+ },
+
+ _count: function (keys, values) {
+ return values.length;
+ },
+
+ _stats: function (keys, values) {
+ // no need to implement rereduce=true, because Pouch
+ // will never call it
+ function sumsqr(values) {
+ var _sumsqr = 0;
+ for (var i = 0, len = values.length; i < len; i++) {
+ var num = values[i];
+ _sumsqr += (num * num);
+ }
+ return _sumsqr;
+ }
+ return {
+ sum : sum(values),
+ min : Math.min.apply(null, values),
+ max : Math.max.apply(null, values),
+ count : values.length,
+ sumsqr : sumsqr(values)
+ };
+ }
+};
+
+function getBuiltIn(reduceFunString) {
+ if (/^_sum/.test(reduceFunString)) {
+ return builtInReduce._sum;
+ } else if (/^_count/.test(reduceFunString)) {
+ return builtInReduce._count;
+ } else if (/^_stats/.test(reduceFunString)) {
+ return builtInReduce._stats;
+ } else if (/^_/.test(reduceFunString)) {
+ throw new Error(reduceFunString + ' is not a supported reduce function.');
+ }
+}
+
+function mapper(mapFun, emit) {
+ // for temp_views one can use emit(doc, emit), see #38
+ if (typeof mapFun === "function" && mapFun.length === 2) {
+ var origMap = mapFun;
+ return function (doc) {
+ return origMap(doc, emit);
+ };
+ } else {
+ return evalFunctionWithEval(mapFun.toString(), emit);
+ }
+}
+
+function reducer(reduceFun) {
+ var reduceFunString = reduceFun.toString();
+ var builtIn = getBuiltIn(reduceFunString);
+ if (builtIn) {
+ return builtIn;
+ } else {
+ return evalFunctionWithEval(reduceFunString);
+ }
+}
+
+function ddocValidator(ddoc, viewName) {
+ var fun = ddoc.views && ddoc.views[viewName];
+ if (typeof fun.map !== 'string') {
+ throw new NotFoundError('ddoc ' + ddoc._id + ' has no string view named ' +
+ viewName + ', instead found object of type: ' + typeof fun.map);
+ }
+}
+
+var localDocName = 'mrviews';
+var abstract = createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator);
+
+function query(fun, opts, callback) {
+ return abstract.query.call(this, fun, opts, callback);
+}
+
+function viewCleanup(callback) {
+ return abstract.viewCleanup.call(this, callback);
+}
+
+var mapreduce = {
+ query: query,
+ viewCleanup: viewCleanup
+};
+
+function isGenOne$1(rev$$1) {
+ return /^1-/.test(rev$$1);
+}
+
+function fileHasChanged(localDoc, remoteDoc, filename) {
+ return !localDoc._attachments ||
+ !localDoc._attachments[filename] ||
+ localDoc._attachments[filename].digest !== remoteDoc._attachments[filename].digest;
+}
+
+function getDocAttachments(db, doc) {
+ var filenames = Object.keys(doc._attachments);
+ return Promise.all(filenames.map(function (filename) {
+ return db.getAttachment(doc._id, filename, {rev: doc._rev});
+ }));
+}
+
+function getDocAttachmentsFromTargetOrSource(target, src, doc) {
+ var doCheckForLocalAttachments = isRemote(src) && !isRemote(target);
+ var filenames = Object.keys(doc._attachments);
+
+ if (!doCheckForLocalAttachments) {
+ return getDocAttachments(src, doc);
+ }
+
+ return target.get(doc._id).then(function (localDoc) {
+ return Promise.all(filenames.map(function (filename) {
+ if (fileHasChanged(localDoc, doc, filename)) {
+ return src.getAttachment(doc._id, filename);
+ }
+
+ return target.getAttachment(localDoc._id, filename);
+ }));
+ })["catch"](function (error) {
+ /* istanbul ignore if */
+ if (error.status !== 404) {
+ throw error;
+ }
+
+ return getDocAttachments(src, doc);
+ });
+}
+
+function createBulkGetOpts(diffs) {
+ var requests = [];
+ Object.keys(diffs).forEach(function (id) {
+ var missingRevs = diffs[id].missing;
+ missingRevs.forEach(function (missingRev) {
+ requests.push({
+ id: id,
+ rev: missingRev
+ });
+ });
+ });
+
+ return {
+ docs: requests,
+ revs: true,
+ latest: true
+ };
+}
+
+//
+// Fetch all the documents from the src as described in the "diffs",
+// which is a mapping of docs IDs to revisions. If the state ever
+// changes to "cancelled", then the returned promise will be rejected.
+// Else it will be resolved with a list of fetched documents.
+//
+function getDocs(src, target, diffs, state) {
+ diffs = clone(diffs); // we do not need to modify this
+
+ var resultDocs = [],
+ ok = true;
+
+ function getAllDocs() {
+
+ var bulkGetOpts = createBulkGetOpts(diffs);
+
+ if (!bulkGetOpts.docs.length) { // optimization: skip empty requests
+ return;
+ }
+
+ return src.bulkGet(bulkGetOpts).then(function (bulkGetResponse) {
+ /* istanbul ignore if */
+ if (state.cancelled) {
+ throw new Error('cancelled');
+ }
+ return Promise.all(bulkGetResponse.results.map(function (bulkGetInfo) {
+ return Promise.all(bulkGetInfo.docs.map(function (doc) {
+ var remoteDoc = doc.ok;
+
+ if (doc.error) {
+ // when AUTO_COMPACTION is set, docs can be returned which look
+ // like this: {"missing":"1-7c3ac256b693c462af8442f992b83696"}
+ ok = false;
+ }
+
+ if (!remoteDoc || !remoteDoc._attachments) {
+ return remoteDoc;
+ }
+
+ return getDocAttachmentsFromTargetOrSource(target, src, remoteDoc)
+ .then(function (attachments) {
+ var filenames = Object.keys(remoteDoc._attachments);
+ attachments
+ .forEach(function (attachment, i) {
+ var att = remoteDoc._attachments[filenames[i]];
+ delete att.stub;
+ delete att.length;
+ att.data = attachment;
+ });
+
+ return remoteDoc;
+ });
+ }));
+ }))
+
+ .then(function (results) {
+ resultDocs = resultDocs.concat(flatten(results).filter(Boolean));
+ });
+ });
+ }
+
+ function hasAttachments(doc) {
+ return doc._attachments && Object.keys(doc._attachments).length > 0;
+ }
+
+ function hasConflicts(doc) {
+ return doc._conflicts && doc._conflicts.length > 0;
+ }
+
+ function fetchRevisionOneDocs(ids) {
+ // Optimization: fetch gen-1 docs and attachments in
+ // a single request using _all_docs
+ return src.allDocs({
+ keys: ids,
+ include_docs: true,
+ conflicts: true
+ }).then(function (res) {
+ if (state.cancelled) {
+ throw new Error('cancelled');
+ }
+ res.rows.forEach(function (row) {
+ if (row.deleted || !row.doc || !isGenOne$1(row.value.rev) ||
+ hasAttachments(row.doc) || hasConflicts(row.doc)) {
+ // if any of these conditions apply, we need to fetch using get()
+ return;
+ }
+
+ // strip _conflicts array to appease CSG (#5793)
+ /* istanbul ignore if */
+ if (row.doc._conflicts) {
+ delete row.doc._conflicts;
+ }
+
+ // the doc we got back from allDocs() is sufficient
+ resultDocs.push(row.doc);
+ delete diffs[row.id];
+ });
+ });
+ }
+
+ function getRevisionOneDocs() {
+ // filter out the generation 1 docs and get them
+ // leaving the non-generation one docs to be got otherwise
+ var ids = Object.keys(diffs).filter(function (id) {
+ var missing = diffs[id].missing;
+ return missing.length === 1 && isGenOne$1(missing[0]);
+ });
+ if (ids.length > 0) {
+ return fetchRevisionOneDocs(ids);
+ }
+ }
+
+ function returnResult() {
+ return { ok:ok, docs:resultDocs };
+ }
+
+ return Promise.resolve()
+ .then(getRevisionOneDocs)
+ .then(getAllDocs)
+ .then(returnResult);
+}
+
+var CHECKPOINT_VERSION = 1;
+var REPLICATOR = "pouchdb";
+// This is an arbitrary number to limit the
+// amount of replication history we save in the checkpoint.
+// If we save too much, the checkpoing docs will become very big,
+// if we save fewer, we'll run a greater risk of having to
+// read all the changes from 0 when checkpoint PUTs fail
+// CouchDB 2.0 has a more involved history pruning,
+// but let's go for the simple version for now.
+var CHECKPOINT_HISTORY_SIZE = 5;
+var LOWEST_SEQ = 0;
+
+function updateCheckpoint(db, id, checkpoint, session, returnValue) {
+ return db.get(id)["catch"](function (err) {
+ if (err.status === 404) {
+ if (db.adapter === 'http' || db.adapter === 'https') {
+ explainError(
+ 404, 'PouchDB is just checking if a remote checkpoint exists.'
+ );
+ }
+ return {
+ session_id: session,
+ _id: id,
+ history: [],
+ replicator: REPLICATOR,
+ version: CHECKPOINT_VERSION
+ };
+ }
+ throw err;
+ }).then(function (doc) {
+ if (returnValue.cancelled) {
+ return;
+ }
+
+ // if the checkpoint has not changed, do not update
+ if (doc.last_seq === checkpoint) {
+ return;
+ }
+
+ // Filter out current entry for this replication
+ doc.history = (doc.history || []).filter(function (item) {
+ return item.session_id !== session;
+ });
+
+ // Add the latest checkpoint to history
+ doc.history.unshift({
+ last_seq: checkpoint,
+ session_id: session
+ });
+
+ // Just take the last pieces in history, to
+ // avoid really big checkpoint docs.
+ // see comment on history size above
+ doc.history = doc.history.slice(0, CHECKPOINT_HISTORY_SIZE);
+
+ doc.version = CHECKPOINT_VERSION;
+ doc.replicator = REPLICATOR;
+
+ doc.session_id = session;
+ doc.last_seq = checkpoint;
+
+ return db.put(doc)["catch"](function (err) {
+ if (err.status === 409) {
+ // retry; someone is trying to write a checkpoint simultaneously
+ return updateCheckpoint(db, id, checkpoint, session, returnValue);
+ }
+ throw err;
+ });
+ });
+}
+
+function Checkpointer(src, target, id, returnValue, opts) {
+ this.src = src;
+ this.target = target;
+ this.id = id;
+ this.returnValue = returnValue;
+ this.opts = opts || {};
+}
+
+Checkpointer.prototype.writeCheckpoint = function (checkpoint, session) {
+ var self = this;
+ return this.updateTarget(checkpoint, session).then(function () {
+ return self.updateSource(checkpoint, session);
+ });
+};
+
+Checkpointer.prototype.updateTarget = function (checkpoint, session) {
+ if (this.opts.writeTargetCheckpoint) {
+ return updateCheckpoint(this.target, this.id, checkpoint,
+ session, this.returnValue);
+ } else {
+ return Promise.resolve(true);
+ }
+};
+
+Checkpointer.prototype.updateSource = function (checkpoint, session) {
+ if (this.opts.writeSourceCheckpoint) {
+ var self = this;
+ return updateCheckpoint(this.src, this.id, checkpoint,
+ session, this.returnValue)[
+ "catch"](function (err) {
+ if (isForbiddenError(err)) {
+ self.opts.writeSourceCheckpoint = false;
+ return true;
+ }
+ throw err;
+ });
+ } else {
+ return Promise.resolve(true);
+ }
+};
+
+var comparisons = {
+ "undefined": function (targetDoc, sourceDoc) {
+ // This is the previous comparison function
+ if (collate(targetDoc.last_seq, sourceDoc.last_seq) === 0) {
+ return sourceDoc.last_seq;
+ }
+ /* istanbul ignore next */
+ return 0;
+ },
+ "1": function (targetDoc, sourceDoc) {
+ // This is the comparison function ported from CouchDB
+ return compareReplicationLogs(sourceDoc, targetDoc).last_seq;
+ }
+};
+
+Checkpointer.prototype.getCheckpoint = function () {
+ var self = this;
+
+ if (self.opts && self.opts.writeSourceCheckpoint && !self.opts.writeTargetCheckpoint) {
+ return self.src.get(self.id).then(function (sourceDoc) {
+ return sourceDoc.last_seq || LOWEST_SEQ;
+ })["catch"](function (err) {
+ /* istanbul ignore if */
+ if (err.status !== 404) {
+ throw err;
+ }
+ return LOWEST_SEQ;
+ });
+ }
+
+ return self.target.get(self.id).then(function (targetDoc) {
+ if (self.opts && self.opts.writeTargetCheckpoint && !self.opts.writeSourceCheckpoint) {
+ return targetDoc.last_seq || LOWEST_SEQ;
+ }
+
+ return self.src.get(self.id).then(function (sourceDoc) {
+ // Since we can't migrate an old version doc to a new one
+ // (no session id), we just go with the lowest seq in this case
+ /* istanbul ignore if */
+ if (targetDoc.version !== sourceDoc.version) {
+ return LOWEST_SEQ;
+ }
+
+ var version;
+ if (targetDoc.version) {
+ version = targetDoc.version.toString();
+ } else {
+ version = "undefined";
+ }
+
+ if (version in comparisons) {
+ return comparisons[version](targetDoc, sourceDoc);
+ }
+ /* istanbul ignore next */
+ return LOWEST_SEQ;
+ }, function (err) {
+ if (err.status === 404 && targetDoc.last_seq) {
+ return self.src.put({
+ _id: self.id,
+ last_seq: LOWEST_SEQ
+ }).then(function () {
+ return LOWEST_SEQ;
+ }, function (err) {
+ if (isForbiddenError(err)) {
+ self.opts.writeSourceCheckpoint = false;
+ return targetDoc.last_seq;
+ }
+ /* istanbul ignore next */
+ return LOWEST_SEQ;
+ });
+ }
+ throw err;
+ });
+ })["catch"](function (err) {
+ if (err.status !== 404) {
+ throw err;
+ }
+ return LOWEST_SEQ;
+ });
+};
+// This checkpoint comparison is ported from CouchDBs source
+// they come from here:
+// https://github.com/apache/couchdb-couch-replicator/blob/master/src/couch_replicator.erl#L863-L906
+
+function compareReplicationLogs(srcDoc, tgtDoc) {
+ if (srcDoc.session_id === tgtDoc.session_id) {
+ return {
+ last_seq: srcDoc.last_seq,
+ history: srcDoc.history
+ };
+ }
+
+ return compareReplicationHistory(srcDoc.history, tgtDoc.history);
+}
+
+function compareReplicationHistory(sourceHistory, targetHistory) {
+ // the erlang loop via function arguments is not so easy to repeat in JS
+ // therefore, doing this as recursion
+ var S = sourceHistory[0];
+ var sourceRest = sourceHistory.slice(1);
+ var T = targetHistory[0];
+ var targetRest = targetHistory.slice(1);
+
+ if (!S || targetHistory.length === 0) {
+ return {
+ last_seq: LOWEST_SEQ,
+ history: []
+ };
+ }
+
+ var sourceId = S.session_id;
+ /* istanbul ignore if */
+ if (hasSessionId(sourceId, targetHistory)) {
+ return {
+ last_seq: S.last_seq,
+ history: sourceHistory
+ };
+ }
+
+ var targetId = T.session_id;
+ if (hasSessionId(targetId, sourceRest)) {
+ return {
+ last_seq: T.last_seq,
+ history: targetRest
+ };
+ }
+
+ return compareReplicationHistory(sourceRest, targetRest);
+}
+
+function hasSessionId(sessionId, history) {
+ var props = history[0];
+ var rest = history.slice(1);
+
+ if (!sessionId || history.length === 0) {
+ return false;
+ }
+
+ if (sessionId === props.session_id) {
+ return true;
+ }
+
+ return hasSessionId(sessionId, rest);
+}
+
+function isForbiddenError(err) {
+ return typeof err.status === 'number' && Math.floor(err.status / 100) === 4;
+}
+
+var STARTING_BACK_OFF = 0;
+
+function backOff(opts, returnValue, error, callback) {
+ if (opts.retry === false) {
+ returnValue.emit('error', error);
+ returnValue.removeAllListeners();
+ return;
+ }
+ /* istanbul ignore if */
+ if (typeof opts.back_off_function !== 'function') {
+ opts.back_off_function = defaultBackOff;
+ }
+ returnValue.emit('requestError', error);
+ if (returnValue.state === 'active' || returnValue.state === 'pending') {
+ returnValue.emit('paused', error);
+ returnValue.state = 'stopped';
+ var backOffSet = function backoffTimeSet() {
+ opts.current_back_off = STARTING_BACK_OFF;
+ };
+ var removeBackOffSetter = function removeBackOffTimeSet() {
+ returnValue.removeListener('active', backOffSet);
+ };
+ returnValue.once('paused', removeBackOffSetter);
+ returnValue.once('active', backOffSet);
+ }
+
+ opts.current_back_off = opts.current_back_off || STARTING_BACK_OFF;
+ opts.current_back_off = opts.back_off_function(opts.current_back_off);
+ setTimeout(callback, opts.current_back_off);
+}
+
+function sortObjectPropertiesByKey(queryParams) {
+ return Object.keys(queryParams).sort(collate).reduce(function (result, key) {
+ result[key] = queryParams[key];
+ return result;
+ }, {});
+}
+
+// Generate a unique id particular to this replication.
+// Not guaranteed to align perfectly with CouchDB's rep ids.
+function generateReplicationId(src, target, opts) {
+ var docIds = opts.doc_ids ? opts.doc_ids.sort(collate) : '';
+ var filterFun = opts.filter ? opts.filter.toString() : '';
+ var queryParams = '';
+ var filterViewName = '';
+ var selector = '';
+
+ // possibility for checkpoints to be lost here as behaviour of
+ // JSON.stringify is not stable (see #6226)
+ /* istanbul ignore if */
+ if (opts.selector) {
+ selector = JSON.stringify(opts.selector);
+ }
+
+ if (opts.filter && opts.query_params) {
+ queryParams = JSON.stringify(sortObjectPropertiesByKey(opts.query_params));
+ }
+
+ if (opts.filter && opts.filter === '_view') {
+ filterViewName = opts.view.toString();
+ }
+
+ return Promise.all([src.id(), target.id()]).then(function (res) {
+ var queryData = res[0] + res[1] + filterFun + filterViewName +
+ queryParams + docIds + selector;
+ return new Promise(function (resolve) {
+ binaryMd5(queryData, resolve);
+ });
+ }).then(function (md5sum) {
+ // can't use straight-up md5 alphabet, because
+ // the char '/' is interpreted as being for attachments,
+ // and + is also not url-safe
+ md5sum = md5sum.replace(/\//g, '.').replace(/\+/g, '_');
+ return '_local/' + md5sum;
+ });
+}
+
+function replicate(src, target, opts, returnValue, result) {
+ var batches = []; // list of batches to be processed
+ var currentBatch; // the batch currently being processed
+ var pendingBatch = {
+ seq: 0,
+ changes: [],
+ docs: []
+ }; // next batch, not yet ready to be processed
+ var writingCheckpoint = false; // true while checkpoint is being written
+ var changesCompleted = false; // true when all changes received
+ var replicationCompleted = false; // true when replication has completed
+ var last_seq = 0;
+ var continuous = opts.continuous || opts.live || false;
+ var batch_size = opts.batch_size || 100;
+ var batches_limit = opts.batches_limit || 10;
+ var changesPending = false; // true while src.changes is running
+ var doc_ids = opts.doc_ids;
+ var selector = opts.selector;
+ var repId;
+ var checkpointer;
+ var changedDocs = [];
+ // Like couchdb, every replication gets a unique session id
+ var session = uuid();
+
+ result = result || {
+ ok: true,
+ start_time: new Date().toISOString(),
+ docs_read: 0,
+ docs_written: 0,
+ doc_write_failures: 0,
+ errors: []
+ };
+
+ var changesOpts = {};
+ returnValue.ready(src, target);
+
+ function initCheckpointer() {
+ if (checkpointer) {
+ return Promise.resolve();
+ }
+ return generateReplicationId(src, target, opts).then(function (res) {
+ repId = res;
+
+ var checkpointOpts = {};
+ if (opts.checkpoint === false) {
+ checkpointOpts = { writeSourceCheckpoint: false, writeTargetCheckpoint: false };
+ } else if (opts.checkpoint === 'source') {
+ checkpointOpts = { writeSourceCheckpoint: true, writeTargetCheckpoint: false };
+ } else if (opts.checkpoint === 'target') {
+ checkpointOpts = { writeSourceCheckpoint: false, writeTargetCheckpoint: true };
+ } else {
+ checkpointOpts = { writeSourceCheckpoint: true, writeTargetCheckpoint: true };
+ }
+
+ checkpointer = new Checkpointer(src, target, repId, returnValue, checkpointOpts);
+ });
+ }
+
+ function writeDocs() {
+ changedDocs = [];
+
+ if (currentBatch.docs.length === 0) {
+ return;
+ }
+ var docs = currentBatch.docs;
+ var bulkOpts = {timeout: opts.timeout};
+ return target.bulkDocs({docs: docs, new_edits: false}, bulkOpts).then(function (res) {
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ completeReplication();
+ throw new Error('cancelled');
+ }
+
+ // `res` doesn't include full documents (which live in `docs`), so we create a map of
+ // (id -> error), and check for errors while iterating over `docs`
+ var errorsById = Object.create(null);
+ res.forEach(function (res) {
+ if (res.error) {
+ errorsById[res.id] = res;
+ }
+ });
+
+ var errorsNo = Object.keys(errorsById).length;
+ result.doc_write_failures += errorsNo;
+ result.docs_written += docs.length - errorsNo;
+
+ docs.forEach(function (doc) {
+ var error = errorsById[doc._id];
+ if (error) {
+ result.errors.push(error);
+ // Normalize error name. i.e. 'Unauthorized' -> 'unauthorized' (eg Sync Gateway)
+ var errorName = (error.name || '').toLowerCase();
+ if (errorName === 'unauthorized' || errorName === 'forbidden') {
+ returnValue.emit('denied', clone(error));
+ } else {
+ throw error;
+ }
+ } else {
+ changedDocs.push(doc);
+ }
+ });
+
+ }, function (err) {
+ result.doc_write_failures += docs.length;
+ throw err;
+ });
+ }
+
+ function finishBatch() {
+ if (currentBatch.error) {
+ throw new Error('There was a problem getting docs.');
+ }
+ result.last_seq = last_seq = currentBatch.seq;
+ var outResult = clone(result);
+ if (changedDocs.length) {
+ outResult.docs = changedDocs;
+ // Attach 'pending' property if server supports it (CouchDB 2.0+)
+ /* istanbul ignore if */
+ if (typeof currentBatch.pending === 'number') {
+ outResult.pending = currentBatch.pending;
+ delete currentBatch.pending;
+ }
+ returnValue.emit('change', outResult);
+ }
+ writingCheckpoint = true;
+ return checkpointer.writeCheckpoint(currentBatch.seq,
+ session).then(function () {
+ writingCheckpoint = false;
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ completeReplication();
+ throw new Error('cancelled');
+ }
+ currentBatch = undefined;
+ getChanges();
+ })["catch"](function (err) {
+ onCheckpointError(err);
+ throw err;
+ });
+ }
+
+ function getDiffs() {
+ var diff = {};
+ currentBatch.changes.forEach(function (change) {
+ // Couchbase Sync Gateway emits these, but we can ignore them
+ /* istanbul ignore if */
+ if (change.id === "_user/") {
+ return;
+ }
+ diff[change.id] = change.changes.map(function (x) {
+ return x.rev;
+ });
+ });
+ return target.revsDiff(diff).then(function (diffs) {
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ completeReplication();
+ throw new Error('cancelled');
+ }
+ // currentBatch.diffs elements are deleted as the documents are written
+ currentBatch.diffs = diffs;
+ });
+ }
+
+ function getBatchDocs() {
+ return getDocs(src, target, currentBatch.diffs, returnValue).then(function (got) {
+ currentBatch.error = !got.ok;
+ got.docs.forEach(function (doc) {
+ delete currentBatch.diffs[doc._id];
+ result.docs_read++;
+ currentBatch.docs.push(doc);
+ });
+ });
+ }
+
+ function startNextBatch() {
+ if (returnValue.cancelled || currentBatch) {
+ return;
+ }
+ if (batches.length === 0) {
+ processPendingBatch(true);
+ return;
+ }
+ currentBatch = batches.shift();
+ getDiffs()
+ .then(getBatchDocs)
+ .then(writeDocs)
+ .then(finishBatch)
+ .then(startNextBatch)[
+ "catch"](function (err) {
+ abortReplication('batch processing terminated with error', err);
+ });
+ }
+
+
+ function processPendingBatch(immediate$$1) {
+ if (pendingBatch.changes.length === 0) {
+ if (batches.length === 0 && !currentBatch) {
+ if ((continuous && changesOpts.live) || changesCompleted) {
+ returnValue.state = 'pending';
+ returnValue.emit('paused');
+ }
+ if (changesCompleted) {
+ completeReplication();
+ }
+ }
+ return;
+ }
+ if (
+ immediate$$1 ||
+ changesCompleted ||
+ pendingBatch.changes.length >= batch_size
+ ) {
+ batches.push(pendingBatch);
+ pendingBatch = {
+ seq: 0,
+ changes: [],
+ docs: []
+ };
+ if (returnValue.state === 'pending' || returnValue.state === 'stopped') {
+ returnValue.state = 'active';
+ returnValue.emit('active');
+ }
+ startNextBatch();
+ }
+ }
+
+
+ function abortReplication(reason, err) {
+ if (replicationCompleted) {
+ return;
+ }
+ if (!err.message) {
+ err.message = reason;
+ }
+ result.ok = false;
+ result.status = 'aborting';
+ batches = [];
+ pendingBatch = {
+ seq: 0,
+ changes: [],
+ docs: []
+ };
+ completeReplication(err);
+ }
+
+
+ function completeReplication(fatalError) {
+ if (replicationCompleted) {
+ return;
+ }
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ result.status = 'cancelled';
+ if (writingCheckpoint) {
+ return;
+ }
+ }
+ result.status = result.status || 'complete';
+ result.end_time = new Date().toISOString();
+ result.last_seq = last_seq;
+ replicationCompleted = true;
+
+ if (fatalError) {
+ // need to extend the error because Firefox considers ".result" read-only
+ fatalError = createError(fatalError);
+ fatalError.result = result;
+
+ // Normalize error name. i.e. 'Unauthorized' -> 'unauthorized' (eg Sync Gateway)
+ var errorName = (fatalError.name || '').toLowerCase();
+ if (errorName === 'unauthorized' || errorName === 'forbidden') {
+ returnValue.emit('error', fatalError);
+ returnValue.removeAllListeners();
+ } else {
+ backOff(opts, returnValue, fatalError, function () {
+ replicate(src, target, opts, returnValue);
+ });
+ }
+ } else {
+ returnValue.emit('complete', result);
+ returnValue.removeAllListeners();
+ }
+ }
+
+
+ function onChange(change, pending, lastSeq) {
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ return completeReplication();
+ }
+ // Attach 'pending' property if server supports it (CouchDB 2.0+)
+ /* istanbul ignore if */
+ if (typeof pending === 'number') {
+ pendingBatch.pending = pending;
+ }
+
+ var filter = filterChange(opts)(change);
+ if (!filter) {
+ return;
+ }
+ pendingBatch.seq = change.seq || lastSeq;
+ pendingBatch.changes.push(change);
+ immediate(function () {
+ processPendingBatch(batches.length === 0 && changesOpts.live);
+ });
+ }
+
+
+ function onChangesComplete(changes) {
+ changesPending = false;
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ return completeReplication();
+ }
+
+ // if no results were returned then we're done,
+ // else fetch more
+ if (changes.results.length > 0) {
+ changesOpts.since = changes.results[changes.results.length - 1].seq;
+ getChanges();
+ processPendingBatch(true);
+ } else {
+
+ var complete = function () {
+ if (continuous) {
+ changesOpts.live = true;
+ getChanges();
+ } else {
+ changesCompleted = true;
+ }
+ processPendingBatch(true);
+ };
+
+ // update the checkpoint so we start from the right seq next time
+ if (!currentBatch && changes.results.length === 0) {
+ writingCheckpoint = true;
+ checkpointer.writeCheckpoint(changes.last_seq,
+ session).then(function () {
+ writingCheckpoint = false;
+ result.last_seq = last_seq = changes.last_seq;
+ complete();
+ })[
+ "catch"](onCheckpointError);
+ } else {
+ complete();
+ }
+ }
+ }
+
+
+ function onChangesError(err) {
+ changesPending = false;
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ return completeReplication();
+ }
+ abortReplication('changes rejected', err);
+ }
+
+
+ function getChanges() {
+ if (!(
+ !changesPending &&
+ !changesCompleted &&
+ batches.length < batches_limit
+ )) {
+ return;
+ }
+ changesPending = true;
+ function abortChanges() {
+ changes.cancel();
+ }
+ function removeListener() {
+ returnValue.removeListener('cancel', abortChanges);
+ }
+
+ if (returnValue._changes) { // remove old changes() and listeners
+ returnValue.removeListener('cancel', returnValue._abortChanges);
+ returnValue._changes.cancel();
+ }
+ returnValue.once('cancel', abortChanges);
+
+ var changes = src.changes(changesOpts)
+ .on('change', onChange);
+ changes.then(removeListener, removeListener);
+ changes.then(onChangesComplete)[
+ "catch"](onChangesError);
+
+ if (opts.retry) {
+ // save for later so we can cancel if necessary
+ returnValue._changes = changes;
+ returnValue._abortChanges = abortChanges;
+ }
+ }
+
+
+ function startChanges() {
+ initCheckpointer().then(function () {
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ completeReplication();
+ return;
+ }
+ return checkpointer.getCheckpoint().then(function (checkpoint) {
+ last_seq = checkpoint;
+ changesOpts = {
+ since: last_seq,
+ limit: batch_size,
+ batch_size: batch_size,
+ style: 'all_docs',
+ doc_ids: doc_ids,
+ selector: selector,
+ return_docs: true // required so we know when we're done
+ };
+ if (opts.filter) {
+ if (typeof opts.filter !== 'string') {
+ // required for the client-side filter in onChange
+ changesOpts.include_docs = true;
+ } else { // ddoc filter
+ changesOpts.filter = opts.filter;
+ }
+ }
+ if ('heartbeat' in opts) {
+ changesOpts.heartbeat = opts.heartbeat;
+ }
+ if ('timeout' in opts) {
+ changesOpts.timeout = opts.timeout;
+ }
+ if (opts.query_params) {
+ changesOpts.query_params = opts.query_params;
+ }
+ if (opts.view) {
+ changesOpts.view = opts.view;
+ }
+ getChanges();
+ });
+ })["catch"](function (err) {
+ abortReplication('getCheckpoint rejected with ', err);
+ });
+ }
+
+ /* istanbul ignore next */
+ function onCheckpointError(err) {
+ writingCheckpoint = false;
+ abortReplication('writeCheckpoint completed with error', err);
+ }
+
+ /* istanbul ignore if */
+ if (returnValue.cancelled) { // cancelled immediately
+ completeReplication();
+ return;
+ }
+
+ if (!returnValue._addedListeners) {
+ returnValue.once('cancel', completeReplication);
+
+ if (typeof opts.complete === 'function') {
+ returnValue.once('error', opts.complete);
+ returnValue.once('complete', function (result) {
+ opts.complete(null, result);
+ });
+ }
+ returnValue._addedListeners = true;
+ }
+
+ if (typeof opts.since === 'undefined') {
+ startChanges();
+ } else {
+ initCheckpointer().then(function () {
+ writingCheckpoint = true;
+ return checkpointer.writeCheckpoint(opts.since, session);
+ }).then(function () {
+ writingCheckpoint = false;
+ /* istanbul ignore if */
+ if (returnValue.cancelled) {
+ completeReplication();
+ return;
+ }
+ last_seq = opts.since;
+ startChanges();
+ })["catch"](onCheckpointError);
+ }
+}
+
+// We create a basic promise so the caller can cancel the replication possibly
+// before we have actually started listening to changes etc
+inherits(Replication, events.EventEmitter);
+function Replication() {
+ events.EventEmitter.call(this);
+ this.cancelled = false;
+ this.state = 'pending';
+ var self = this;
+ var promise = new Promise(function (fulfill, reject) {
+ self.once('complete', fulfill);
+ self.once('error', reject);
+ });
+ self.then = function (resolve, reject) {
+ return promise.then(resolve, reject);
+ };
+ self["catch"] = function (reject) {
+ return promise["catch"](reject);
+ };
+ // As we allow error handling via "error" event as well,
+ // put a stub in here so that rejecting never throws UnhandledError.
+ self["catch"](function () {});
+}
+
+Replication.prototype.cancel = function () {
+ this.cancelled = true;
+ this.state = 'cancelled';
+ this.emit('cancel');
+};
+
+Replication.prototype.ready = function (src, target) {
+ var self = this;
+ if (self._readyCalled) {
+ return;
+ }
+ self._readyCalled = true;
+
+ function onDestroy() {
+ self.cancel();
+ }
+ src.once('destroyed', onDestroy);
+ target.once('destroyed', onDestroy);
+ function cleanup() {
+ src.removeListener('destroyed', onDestroy);
+ target.removeListener('destroyed', onDestroy);
+ }
+ self.once('complete', cleanup);
+};
+
+function toPouch(db, opts) {
+ var PouchConstructor = opts.PouchConstructor;
+ if (typeof db === 'string') {
+ return new PouchConstructor(db, opts);
+ } else {
+ return db;
+ }
+}
+
+function replicateWrapper(src, target, opts, callback) {
+
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ if (typeof opts === 'undefined') {
+ opts = {};
+ }
+
+ if (opts.doc_ids && !Array.isArray(opts.doc_ids)) {
+ throw createError(BAD_REQUEST,
+ "`doc_ids` filter parameter is not a list.");
+ }
+
+ opts.complete = callback;
+ opts = clone(opts);
+ opts.continuous = opts.continuous || opts.live;
+ opts.retry = ('retry' in opts) ? opts.retry : false;
+ /*jshint validthis:true */
+ opts.PouchConstructor = opts.PouchConstructor || this;
+ var replicateRet = new Replication(opts);
+ var srcPouch = toPouch(src, opts);
+ var targetPouch = toPouch(target, opts);
+ replicate(srcPouch, targetPouch, opts, replicateRet);
+ return replicateRet;
+}
+
+inherits(Sync, events.EventEmitter);
+function sync(src, target, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ if (typeof opts === 'undefined') {
+ opts = {};
+ }
+ opts = clone(opts);
+ /*jshint validthis:true */
+ opts.PouchConstructor = opts.PouchConstructor || this;
+ src = toPouch(src, opts);
+ target = toPouch(target, opts);
+ return new Sync(src, target, opts, callback);
+}
+
+function Sync(src, target, opts, callback) {
+ var self = this;
+ this.canceled = false;
+
+ var optsPush = opts.push ? $inject_Object_assign({}, opts, opts.push) : opts;
+ var optsPull = opts.pull ? $inject_Object_assign({}, opts, opts.pull) : opts;
+
+ this.push = replicateWrapper(src, target, optsPush);
+ this.pull = replicateWrapper(target, src, optsPull);
+
+ this.pushPaused = true;
+ this.pullPaused = true;
+
+ function pullChange(change) {
+ self.emit('change', {
+ direction: 'pull',
+ change: change
+ });
+ }
+ function pushChange(change) {
+ self.emit('change', {
+ direction: 'push',
+ change: change
+ });
+ }
+ function pushDenied(doc) {
+ self.emit('denied', {
+ direction: 'push',
+ doc: doc
+ });
+ }
+ function pullDenied(doc) {
+ self.emit('denied', {
+ direction: 'pull',
+ doc: doc
+ });
+ }
+ function pushPaused() {
+ self.pushPaused = true;
+ /* istanbul ignore if */
+ if (self.pullPaused) {
+ self.emit('paused');
+ }
+ }
+ function pullPaused() {
+ self.pullPaused = true;
+ /* istanbul ignore if */
+ if (self.pushPaused) {
+ self.emit('paused');
+ }
+ }
+ function pushActive() {
+ self.pushPaused = false;
+ /* istanbul ignore if */
+ if (self.pullPaused) {
+ self.emit('active', {
+ direction: 'push'
+ });
+ }
+ }
+ function pullActive() {
+ self.pullPaused = false;
+ /* istanbul ignore if */
+ if (self.pushPaused) {
+ self.emit('active', {
+ direction: 'pull'
+ });
+ }
+ }
+
+ var removed = {};
+
+ function removeAll(type) { // type is 'push' or 'pull'
+ return function (event, func) {
+ var isChange = event === 'change' &&
+ (func === pullChange || func === pushChange);
+ var isDenied = event === 'denied' &&
+ (func === pullDenied || func === pushDenied);
+ var isPaused = event === 'paused' &&
+ (func === pullPaused || func === pushPaused);
+ var isActive = event === 'active' &&
+ (func === pullActive || func === pushActive);
+
+ if (isChange || isDenied || isPaused || isActive) {
+ if (!(event in removed)) {
+ removed[event] = {};
+ }
+ removed[event][type] = true;
+ if (Object.keys(removed[event]).length === 2) {
+ // both push and pull have asked to be removed
+ self.removeAllListeners(event);
+ }
+ }
+ };
+ }
+
+ if (opts.live) {
+ this.push.on('complete', self.pull.cancel.bind(self.pull));
+ this.pull.on('complete', self.push.cancel.bind(self.push));
+ }
+
+ function addOneListener(ee, event, listener) {
+ if (ee.listeners(event).indexOf(listener) == -1) {
+ ee.on(event, listener);
+ }
+ }
+
+ this.on('newListener', function (event) {
+ if (event === 'change') {
+ addOneListener(self.pull, 'change', pullChange);
+ addOneListener(self.push, 'change', pushChange);
+ } else if (event === 'denied') {
+ addOneListener(self.pull, 'denied', pullDenied);
+ addOneListener(self.push, 'denied', pushDenied);
+ } else if (event === 'active') {
+ addOneListener(self.pull, 'active', pullActive);
+ addOneListener(self.push, 'active', pushActive);
+ } else if (event === 'paused') {
+ addOneListener(self.pull, 'paused', pullPaused);
+ addOneListener(self.push, 'paused', pushPaused);
+ }
+ });
+
+ this.on('removeListener', function (event) {
+ if (event === 'change') {
+ self.pull.removeListener('change', pullChange);
+ self.push.removeListener('change', pushChange);
+ } else if (event === 'denied') {
+ self.pull.removeListener('denied', pullDenied);
+ self.push.removeListener('denied', pushDenied);
+ } else if (event === 'active') {
+ self.pull.removeListener('active', pullActive);
+ self.push.removeListener('active', pushActive);
+ } else if (event === 'paused') {
+ self.pull.removeListener('paused', pullPaused);
+ self.push.removeListener('paused', pushPaused);
+ }
+ });
+
+ this.pull.on('removeListener', removeAll('pull'));
+ this.push.on('removeListener', removeAll('push'));
+
+ var promise = Promise.all([
+ this.push,
+ this.pull
+ ]).then(function (resp) {
+ var out = {
+ push: resp[0],
+ pull: resp[1]
+ };
+ self.emit('complete', out);
+ if (callback) {
+ callback(null, out);
+ }
+ self.removeAllListeners();
+ return out;
+ }, function (err) {
+ self.cancel();
+ if (callback) {
+ // if there's a callback, then the callback can receive
+ // the error event
+ callback(err);
+ } else {
+ // if there's no callback, then we're safe to emit an error
+ // event, which would otherwise throw an unhandled error
+ // due to 'error' being a special event in EventEmitters
+ self.emit('error', err);
+ }
+ self.removeAllListeners();
+ if (callback) {
+ // no sense throwing if we're already emitting an 'error' event
+ throw err;
+ }
+ });
+
+ this.then = function (success, err) {
+ return promise.then(success, err);
+ };
+
+ this["catch"] = function (err) {
+ return promise["catch"](err);
+ };
+}
+
+Sync.prototype.cancel = function () {
+ if (!this.canceled) {
+ this.canceled = true;
+ this.push.cancel();
+ this.pull.cancel();
+ }
+};
+
+function replication(PouchDB) {
+ PouchDB.replicate = replicateWrapper;
+ PouchDB.sync = sync;
+
+ Object.defineProperty(PouchDB.prototype, 'replicate', {
+ get: function () {
+ var self = this;
+ if (typeof this.replicateMethods === 'undefined') {
+ this.replicateMethods = {
+ from: function (other, opts, callback) {
+ return self.constructor.replicate(other, self, opts, callback);
+ },
+ to: function (other, opts, callback) {
+ return self.constructor.replicate(self, other, opts, callback);
+ }
+ };
+ }
+ return this.replicateMethods;
+ }
+ });
+
+ PouchDB.prototype.sync = function (dbName, opts, callback) {
+ return this.constructor.sync(this, dbName, opts, callback);
+ };
+}
+
+PouchDB.plugin(IDBPouch)
+ .plugin(HttpPouch$1)
+ .plugin(mapreduce)
+ .plugin(replication);
+
+// Pull from src because pouchdb-node/pouchdb-browser themselves
+
+module.exports = PouchDB;
+
+}).call(this,_dereq_(5),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"1":1,"12":12,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7}]},{},[13])(13)
+});
diff --git a/src/lib/toaster.js b/src/lib/toaster.js
new file mode 100644
index 0000000..565957e
--- /dev/null
+++ b/src/lib/toaster.js
@@ -0,0 +1,146 @@
+// License: https://github.com/ivarlovlie/bootstrap-v5-toaster/blob/master/LICENSE
+/** Class representing a Bootstrap 5 Toaster. */
+class Toaster {
+ constructor(options) {
+ if (!options) {
+ options = {
+ hideAfter: 3500,
+ position: "top-right",
+ };
+ }
+ this.root = document.createElement("div");
+ this.root.id = "toaster-container";
+ switch (options.position) {
+ case "top-right":
+ this.root.style =
+ "display: flex; align-items: end; flex-direction: column; position: absolute; top: 0; right: 0; padding: 15px;";
+ break;
+ case "top-left":
+ this.root.style = "position: absolute; top: 0; padding: 15px;";
+ break;
+ case "bottom-right":
+ this.root.style =
+ "display: flex; align-items: end; flex-direction: column; position: absolute; bottom: 0; right: 0; padding: 15px;";
+ break;
+ case "bottom-left":
+ this.root.style = "position: absolute; bottom: 0; padding: 15px;";
+ break;
+ default:
+ // top-right
+ this.root.style =
+ "display: flex; align-items: end; flex-direction: column; position: absolute; top: 0; right: 0; padding: 15px;";
+ break;
+ }
+ document.body.appendChild(this.root);
+ this.defaultTimeout = options.hideAfter ? options.hideAfter : 3500;
+ this.toastTypes = {
+ error: "error",
+ success: "success",
+ info: "info",
+ };
+ }
+ display(title, message, autohide, type) {
+ if (!title || typeof title !== "string" || typeof message !== "string") {
+ throw new Error("Toaster: title &| message is empty or not a string");
+ }
+ let toast = document.createElement("div");
+ toast.className = "toast";
+ toast.role = "alert";
+ toast.id = Math.random().toString(36).substring(2) + Date.now().toString(36);
+ let toastHeader = document.createElement("div");
+ toastHeader.className = "toast-header";
+ let toastTypeIndicator = document.createElement("div");
+ switch (type) {
+ case this.toastTypes.error:
+ toastTypeIndicator.className = "toast-type-indicator rounded mr-2 bg-danger";
+ toast.style =
+ "width: max-content; min-width: 300px; border-color: var(--bs-danger);";
+ break;
+ case this.toastTypes.success:
+ toastTypeIndicator.className = "toast-type-indicator rounded mr-2 bg-success";
+ toast.style =
+ "width: max-content; min-width: 300px; border-color: var(--bs-success);";
+ break;
+ case this.toastTypes.info:
+ toastTypeIndicator.className = "toast-type-indicator rounded mr-2 bg-info";
+ toast.style = "width: max-content; min-width: 300px; border-color: var(--bs-info);";
+ break;
+ }
+ toastTypeIndicator.style = "width: 18px; height: 18px;";
+ toastHeader.appendChild(toastTypeIndicator);
+ let toastTitle = document.createElement("strong");
+ toastTitle.className = "mr-auto text-truncate";
+ toastTitle.innerText = title;
+ toastHeader.appendChild(toastTitle);
+ let toastCloseButton = document.createElement("button");
+ toastCloseButton.className = "ml-2 mb-1 close";
+ toastCloseButton.dataset.dismiss = "toast";
+ toastCloseButton.onclick = () => {
+ setTimeout(() => {
+ toast.parentNode.removeChild(toast);
+ }, parseInt(1000));
+ };
+ if (!autohide) {
+ let toastCloseButtonIcon = document.createElement("img");
+ // icon license: https://github.com/twbs/icons/blob/master/LICENSE.md
+ toastCloseButtonIcon.src =
+ 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="1em" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M14 1H2a1 1 0 00-1 1v12a1 1 0 001 1h12a1 1 0 001-1V2a1 1 0 00-1-1zM2 0a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V2a2 2 0 00-2-2H2z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M11.854 4.146a.5.5 0 010 .708l-7 7a.5.5 0 01-.708-.708l7-7a.5.5 0 01.708 0z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M4.146 4.146a.5.5 0 000 .708l7 7a.5.5 0 00.708-.708l-7-7a.5.5 0 00-.708 0z" clip-rule="evenodd"/></svg>';
+ toastCloseButtonIcon.alt = "x";
+ toastCloseButtonIcon.dataset.ariaHidden = "true";
+ toastCloseButton.appendChild(toastCloseButtonIcon);
+ toastHeader.appendChild(toastCloseButton);
+ }
+ toast.appendChild(toastHeader);
+ if (message) {
+ let toastBody = document.createElement("div");
+ toastBody.className = "toast-body";
+ toastBody.style = "word-wrap: break-word;";
+ toastBody.innerText = message;
+ toast.appendChild(toastBody);
+ }
+ this.root.appendChild(toast);
+ let delay = 0;
+ if (typeof autohide === "number" && autohide !== 0) {
+ delay = autohide;
+ autohide = true;
+ } else if (autohide) {
+ delay = this.defaultTimeout;
+ }
+ new bootstrap.Toast(document.getElementById(toast.id), {
+ animation: true,
+ autohide,
+ delay,
+ }).show();
+ if (delay)
+ setTimeout(() => {
+ toast.parentNode.removeChild(toast);
+ }, parseInt(delay + 1000));
+ }
+ /**
+ * Display an toast indicating an error.
+ * @param {string} title Title of the toast
+ * @param {string} message Message of the toast
+ * @param {boolean} autohide Autohide toast
+ */
+ error(title, message = "", autohide = true) {
+ this.display(title, message, autohide, this.toastTypes.error);
+ }
+ /**
+ * Display an toast indicating an successfull operation.
+ * @param {string} title Title of the toast
+ * @param {string} message Message of the toast
+ * @param {boolean} autohide Autohide toast
+ */
+ success(title, message = "", autohide = true) {
+ this.display(title, message, autohide, this.toastTypes.success);
+ }
+ /**
+ * Display an informational toast.
+ * @param {string} title Title of the toast
+ * @param {string} message Message of the toast
+ * @param {boolean} autohide Autohide toast
+ */
+ info(title, message = "", autohide = true) {
+ this.display(title, message, autohide, this.toastTypes.info);
+ }
+}