Page MenuHomec4science

No OneTemporary

File Metadata

Created
Sun, Nov 24, 16:54
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/desuto-couchdb/docker-entrypoint.sh b/desuto-couchdb/docker-entrypoint.sh
index ae06393..63d5019 100755
--- a/desuto-couchdb/docker-entrypoint.sh
+++ b/desuto-couchdb/docker-entrypoint.sh
@@ -1,98 +1,99 @@
#!/bin/bash
# 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
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
set -m
if [ "$1" = '/opt/couchdb/bin/couchdb' ]; then
# we need to set the permissions here because docker mounts volumes as root
chown -R couchdb:couchdb /opt/couchdb
chmod -R 0770 /opt/couchdb/data
chmod 664 /opt/couchdb/etc/*.ini
chmod 664 /opt/couchdb/etc/local.d/*.ini
chmod 775 /opt/couchdb/etc/*.d
if [ ! -z "$NODENAME" ] && ! grep "couchdb@" /opt/couchdb/etc/vm.args; then
echo "-name couchdb@$NODENAME" >> /opt/couchdb/etc/vm.args
fi
if [ "$COUCHDB_USER" ] && [ "$COUCHDB_PASSWORD" ]; then
# Create admin
printf "[admins]\n%s = %s\n" "$COUCHDB_USER" "$COUCHDB_PASSWORD" > /opt/couchdb/etc/local.d/docker.ini
chown couchdb:couchdb /opt/couchdb/etc/local.d/docker.ini
fi
# if we don't find an [admins] section followed by a non-comment, display a warning
if ! grep -Pzoqr '\[admins\]\n[^;]\w+' /opt/couchdb/etc/local.d/*.ini; then
# The - option suppresses leading tabs but *not* spaces. :)
cat >&2 <<-'EOWARN'
****************************************************
WARNING: CouchDB is running in Admin Party mode.
This will allow anyone with access to the
CouchDB port to access your database. In
Docker's default configuration, this is
effectively any other container on the same
system.
Use "-e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password"
to set it in "docker run".
****************************************************
EOWARN
fi
#exec gosu couchdb "$@"
# Run CouchdB in background
gosu couchdb "$@" &
# Wait for the server to be up
sleep 10
# Variables (set your own)
user=$COUCHDB_USER
pass=$COUCHDB_PASSWORD
host=$COUCHDB_HOST
port=$COUCHDB_PORT
protocol=$COUCHDB_PROTOCOL
dbname=$COUCHDB_DB_NAME
echo "Base URL for configuring the DB : $protocol://$user:$pass"'@'"$host:$port/"
####################
### Configure DB ###
####################
# Set timeout of cookies to 10h
curl -H "Content-Type: application/json" -X PUT -d '36000' "$protocol://$user:$pass"'@'"$host:$port/$dbname"
# Create system DBs
curl -X PUT "$protocol://$user:$pass"'@'"$host:$port/_users"
curl -X PUT "$protocol://$user:$pass"'@'"$host:$port/_replicator"
curl -X PUT "$protocol://$user:$pass"'@'"$host:$port/_global_changes"
# Create DB
curl -X PUT "$protocol://$user:$pass"'@'"$host:$port/$dbname"
# Setup DB security roles
curl -H "Content-Type: application/json" -X PUT -d '{"admins":{"names":["admin"],"roles":["admins"]},"members":{"names":[],"roles":["users","pathologists"]}}' "$protocol://$user:$pass"'@'"$host:$port/$dbname/_security"
# Setup users in DB
- curl -H "Content-Type: application/json" -X PUT "$protocol://$user:$pass"'@'"$host:$port/_users/org.couchdb.user:user" --data-binary '{"_id": "org.couchdb.user:user","name": "user","roles": ["users", "regions"],"type": "user","password": "userpass"}'
- curl -H "Content-Type: application/json" -X PUT "$protocol://$user:$pass"'@'"$host:$port/_users/org.couchdb.user:pathologist1" --data-binary '{"_id": "org.couchdb.user:pathologist1","name": "pathologist1","roles": ["users", "pathologists", "regions"],"type": "user","password": "pathologistpass"}'
- curl -H "Content-Type: application/json" -X PUT "$protocol://$user:$pass"'@'"$host:$port/_users/org.couchdb.user:pathologist2" --data-binary '{"_id": "org.couchdb.user:pathologist2","name": "pathologist2","roles": ["users", "pathologists", "regions"],"type": "user","password": "pathologistpass"}'
+ curl -H "Content-Type: application/json" -X PUT "$protocol://$user:$pass"'@'"$host:$port/_users/org.couchdb.user:user" --data-binary '{"_id": "org.couchdb.user:user","name": "user","roles": ["users"],"type": "user","password": "userpass"}'
+ curl -H "Content-Type: application/json" -X PUT "$protocol://$user:$pass"'@'"$host:$port/_users/org.couchdb.user:pathologist1" --data-binary '{"_id": "org.couchdb.user:pathologist1","name": "pathologist1","roles": ["users", "pathologists"],"type": "user","password": "pathologistpass"}'
+ curl -H "Content-Type: application/json" -X PUT "$protocol://$user:$pass"'@'"$host:$port/_users/org.couchdb.user:pathologist2" --data-binary '{"_id": "org.couchdb.user:pathologist2","name": "pathologist2","roles": ["users", "pathologists"],"type": "user","password": "pathologistpass"}'
+ curl -H "Content-Type: application/json" -X PUT "$protocol://$user:$pass"'@'"$host:$port/_users/org.couchdb.user:annotationadmin" --data-binary '{"_id": "org.couchdb.user:annotationadmin","name": "annotationadmin","roles": ["users", "pathologists", "annotationadmins"],"type": "user","password": "annotationpassw"}'
# Bring CouchDB to foreground
fg
fi
exec "$@"
diff --git a/desuto-viewer/Desuto-webviewer/public/img/download.png b/desuto-viewer/Desuto-webviewer/public/img/download.png
new file mode 100644
index 0000000..af69a07
Binary files /dev/null and b/desuto-viewer/Desuto-webviewer/public/img/download.png differ
diff --git a/desuto-viewer/Desuto-webviewer/public/img/svg_edit_icons-fa.svg b/desuto-viewer/Desuto-webviewer/public/img/svg_edit_icons-fa.svg
index 09a105d..ab1cdc6 100644
--- a/desuto-viewer/Desuto-webviewer/public/img/svg_edit_icons-fa.svg
+++ b/desuto-viewer/Desuto-webviewer/public/img/svg_edit_icons-fa.svg
@@ -1,1040 +1,1046 @@
<svg xmlns="http://www.w3.org/2000/svg">
<!-- All images created with SVG-edit - http://svg-edit.googlecode.com/ -->
<g id="logo">
<svg viewBox="0 0 478 472" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="svg_5" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#ffffe0" stop-opacity="1"/>
<stop offset="1" stop-color="#edc39c" stop-opacity="1"/>
</linearGradient>
<linearGradient id="svg_10" x1="0.57031" y1="0.78125" x2="0.28906" y2="0.41406">
<stop offset="0" stop-color="#ff7f00" stop-opacity="1"/>
<stop offset="1" stop-color="#ffff00"/>
</linearGradient>
<linearGradient id="svg_18" x1="0.37891" y1="0.35938" x2="1" y2="1">
<stop offset="0" stop-color="#e0e0e0" stop-opacity="1"/>
<stop offset="1" stop-color="#666666" stop-opacity="1"/>
</linearGradient>
</defs>
<g>
<path d="m68.82031,270.04688l-22,-33l17,-35l34,2l25,15l7,-35l28,-16l25,12l100,102l21,23l-15,35l-36,9l20,49l-31,24l-49,-17l-1,31l-33,21l-31,-19l-13,-35l-30,21l-30,-9l-5,-35l16,-31l-32,-6l-15,-19l3,-36l47,-18z" id="svg_19" fill="#ffffff"/>
<path fill="#1a171a" fill-rule="nonzero" id="path2902" d="m158.96452,155.03685c-25.02071,0 -45.37077,20.35121 -45.37077,45.3775c0,0.72217 0.01794,1.4399 0.0471,2.15645c-0.49339,-0.53604 -0.99355,-1.06085 -1.50603,-1.58452c-8.56077,-8.55519 -19.95982,-13.28413 -32.07432,-13.28413c-12.12122,0 -23.52027,4.72334 -32.08778,13.29646c-17.69347,17.69464 -17.69347,46.4619 0,64.17445c0.51809,0.51697 1.0485,1.0126 1.59015,1.50601c-0.72891,-0.03586 -1.45782,-0.04822 -2.19234,-0.04822c-25.02071,0 -45.37189,20.35117 -45.37189,45.37747c0,25.01398 20.35119,45.36517 45.37189,45.36517c0.72891,0 1.45221,-0.01236 2.1744,-0.04828c-0.5293,0.48221 -1.05412,0.98801 -1.56547,1.49368c-17.70021,17.68906 -17.70021,46.48654 -0.00628,64.18677c8.57872,8.56747 19.96655,13.2785 32.08778,13.2785c12.1145,0 23.5012,-4.71103 32.07433,-13.2785c0.51247,-0.51694 1.01823,-1.04849 1.50603,-1.57895c-0.02915,0.71213 -0.04709,1.44669 -0.04709,2.15759c0,25.01511 20.35007,45.37747 45.37077,45.37747c25.01398,0 45.37079,-20.3624 45.37079,-45.37747c0,-0.7222 -0.01689,-1.44553 -0.05266,-2.18112c0.48105,0.52933 0.97562,1.04849 1.48697,1.56662c8.57982,8.57977 19.97775,13.2908 32.1057,13.2908c12.11003,0 23.51358,-4.71103 32.0687,-13.2785c17.68906,-17.70013 17.68906,-46.48538 0,-64.17441c-0.50577,-0.4946 -1.01141,-1.00034 -1.54306,-1.48248c0.69983,0.03592 1.42316,0.04828 2.16992,0.04828c25.01514,0 45.35284,-20.35123 45.35284,-45.36517c0,-25.02631 -20.33774,-45.37747 -45.35284,-45.37747c-0.74683,0 -1.47009,0.01236 -2.19345,0.04822c0.53152,-0.49341 1.06082,-0.98904 1.59128,-1.50601c8.55521,-8.55521 13.2785,-19.94186 13.2785,-32.07545c0,-12.12793 -4.72336,-23.52028 -13.30319,-32.0934c-8.55515,-8.56076 -19.95866,-13.2841 -32.0687,-13.2841c-12.12122,0 -23.52025,4.72334 -32.08777,13.2841c-0.51137,0.5181 -1.01822,1.04851 -1.5049,1.57895c0.03586,-0.72331 0.05266,-1.43991 0.05266,-2.16881c0,-25.02629 -20.35681,-45.3775 -45.37079,-45.3775m0,20.71901c13.61607,0 24.65851,11.03122 24.65851,24.65849c0,6.62749 -2.651,12.62137 -6.9101,17.04979l0,51.67419l36.53975,-36.53523c0.12001,-6.14418 2.48277,-12.24686 7.18146,-16.94667c4.81305,-4.81305 11.12094,-7.22409 17.44116,-7.22409c6.30228,0 12.61577,2.41104 17.43552,7.22409c9.62166,9.63287 9.62166,25.24948 0,34.87669c-4.69977,4.68634 -10.80803,7.04915 -16.95334,7.18147l-36.5341,36.53305l51.66742,0c4.42841,-4.25351 10.42905,-6.90451 17.08008,-6.90451c13.59137,0 24.62933,11.03799 24.62933,24.66525c0,13.61606 -11.03796,24.66519 -24.62933,24.66519c-6.65106,0 -12.65167,-2.66333 -17.08008,-6.91681l-51.64836,0l36.50273,36.50946c6.16995,0.14465 12.26587,2.50522 16.96568,7.20618c9.6216,9.61487 9.6216,25.23151 0,34.85757c-4.80856,4.81979 -11.13327,7.22974 -17.43556,7.22974c-6.32019,0 -12.63371,-2.40991 -17.44786,-7.22974c-4.68074,-4.68744 -7.04802,-10.79572 -7.17473,-16.94098l-36.53975,-36.53415l0,51.66742c4.25908,4.44635 6.9101,10.43466 6.9101,17.0621c0,13.62729 -11.04243,24.66415 -24.65851,24.66415c-13.62166,0 -24.65848,-11.0369 -24.65848,-24.66415c0,-6.62744 2.64539,-12.61575 6.90335,-17.0621l0,-51.66742l-36.53864,36.54648c-0.12672,6.14413 -2.48838,12.26477 -7.18147,16.94098c-4.81416,4.81873 -11.12206,7.22974 -17.42882,7.22974c-6.31461,0 -12.6225,-2.41101 -17.43555,-7.22974c-9.63284,-9.62833 -9.63284,-25.24277 0,-34.8699c4.68073,-4.67627 10.79012,-7.05026 16.94101,-7.18262l36.533,-36.53302l-51.66632,0c-4.44075,4.25348 -10.42902,6.91681 -17.06211,6.91681c-13.61606,0 -24.65288,-11.04913 -24.65288,-24.66519c0,-13.62726 11.03682,-24.66525 24.65288,-24.66525c6.63309,0 12.62136,2.651 17.06211,6.90451l51.68537,0l-36.55208,-36.54538c-6.14527,-0.12 -12.25354,-2.49403 -16.94775,-7.19377c-9.62611,-9.61493 -9.62611,-25.23715 0,-34.86441c4.81419,-4.81305 11.12769,-7.22406 17.44228,-7.22406c6.30676,0 12.61465,2.41101 17.42883,7.22406c4.69978,4.69307 7.06034,10.80246 7.18144,16.94777l36.5386,36.53299l0,-51.66074c-4.25795,-4.42841 -6.90334,-10.42229 -6.90334,-17.04979c0,-13.62726 11.03682,-24.65848 24.65848,-24.65848"/>
<path d="m188.82031,210.04688l16,-47l155,-148l107,100l-158,156.99999l-44,12l-76,-74z" id="svg_6" fill="url(#svg_10)" stroke="none"/>
<path d="m335.57031,40.29688c-11.5,39.75 55.5,115.25 109.25,98.75l21,-20.99999l-103,-101l-27.25,23.25z" id="svg_11" fill="url(#svg_18)" stroke="none"/>
<rect x="272.80404" y="20.76382" width="42.35197" height="232.66835" id="svg_13" fill="#ffffff" stroke="none" transform="rotate(45.9094, 293.98, 137.1)" opacity="0.4"/>
<rect x="282.80404" y="22.76382" width="14" height="232.66835" fill="#ffffff" stroke="none" transform="rotate(45.9094, 289.805, 139.1)" opacity="0.4" id="svg_14"/>
<ellipse cx="415.13312" cy="64.38066" id="svg_12" fill="#ea7598" stroke="none" rx="67.79251" ry="34.82026" transform="rotate(39.4735, 415.133, 64.379)"/>
<path d="m212.07031,166.04688c-8.5,47 36.25,103.75 99.25,96.75l-152.5,53.25l53.25,-150z" id="svg_4" fill="url(#svg_5)" stroke="none"/>
<path d="m181.32031,242.54688c0.5,20.5 26.75,45 46.75,48.5l-66.25,20l19.5,-68.5z" id="svg_3" fill="#27382f" stroke="none"/>
</g>
<g>
<path d="m152.82031,317.04688l51,-152l157,-153c40,-12.00001 118,48 105,105l-157,152.99999l-156,47z" id="svg_1" fill="none" stroke="#800000" stroke-width="17"/>
</g>
</svg>
</g>
<g id="select">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path stroke="#ffffff" stroke-width="0" fill="#000000" id="svg_13" d="m7.38168,2.46948l0.07502,17.03258l3.30083,-2.62617l2.62566,5.62751l4.20105,-2.62617l-3.30082,-4.80214l4.57614,-0.37517l-11.47787,-12.23044z"/>
</svg>
</g>
<g id="select_node">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle stroke="#0000ff" fill="#00ffff" id="svg_44" r="3.87891" cy="5.3" cx="8.7" stroke-width="1.5"/>
<path d="m9.18161,5.6695l0.07763,15.16198l3.41588,-2.33775l2.71718,5.00947l4.34748,-2.33775l-3.41587,-4.27474l4.73565,-0.33397l-11.87794,-10.88723z" id="svg_13" fill="#000000" stroke="#ffffff"/>
</svg>
</g>
<g id="square">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<defs>
<linearGradient id="svg_2" x1="0.36328" y1="0.10156" x2="1" y2="1">
<stop offset="0" stop-color="#ffffff" stop-opacity="1"/>
<stop offset="1" stop-color="#3b7e9b" stop-opacity="1"/>
</linearGradient>
</defs>
<rect x="1.5" y="1.5" width="20" height="20" id="svg_1" fill="url(#svg_2)" stroke="#000000"/>
</svg>
</g>
<g id="rect">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient y2="1" x2="1" y1="0.10156" x1="0.36328" id="svg_2">
<stop stop-opacity="1" stop-color="#ffffff" offset="0"/>
<stop stop-opacity="1" stop-color="#ffffff" offset="1"/>
</linearGradient>
</defs>
<rect transform="matrix(1, 0, 0, 1, 0, 0)" stroke="#000000" fill="url(#svg_2)" id="svg_1" height="12" width="20" y="5.5" x="1.5"/>
</svg>
</g>
<g id="fh_rect">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
<defs>
<linearGradient y2="1" x2="1" y1="0.10156" x1="0.36328" id="svg_2">
<stop stop-opacity="1" stop-color="#ffffff" offset="0"/>
<stop stop-opacity="1" stop-color="#3b7e9b" offset="1"/>
</linearGradient>
<linearGradient y2="0.3945" x2="0.6132" y1="0.1093" x1="0.3046" id="svg_9">
<stop stop-opacity="1" stop-color="#f9d225" offset="0"/>
<stop stop-opacity="1" stop-color="#bf5f00" offset="1"/>
</linearGradient>
</defs>
<rect stroke="#000000" stroke-width="2" fill="url(#svg_2)" id="svg_1" height="50" width="50" y="0.75" x="1.25"/>
<path stroke-width="2" stroke="#000000" fill="url(#svg_9)" id="svg_2" d="m31.5,0l-8.75,20.25l0.75,24l16.5,-16.5l6,-12.5"/>
<path stroke-width="2" stroke="#000000" fill="#fce0a9" id="svg_10" d="m39.5,28.5c-2,-9.25 -10.25,-11.75 -17,-7.4375l0.4843,24.4414z"/>
<path id="svg_11" stroke-width="2" stroke="#000000" fill="#000000" d="m26.9318,41.1745c-0.4491,-2.3511 -2.3021,-2.9866 -3.8181,-1.8905l0.1087,6.2126z"/>
</svg>
</g>
<g id="circle">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54 54">
<defs>
<linearGradient y2="1.0" x2="1.0" y1="0.1875" x1="0.171875" id="svg_4">
<stop stop-opacity="1" stop-color="#ffffff" offset="0.0"/>
<stop stop-opacity="1" stop-color="#ff6666" offset="1.0"/>
</linearGradient>
</defs>
<g>
<circle stroke-opacity="1" fill-opacity="1" stroke-width="2" stroke="#000000" fill="url(#svg_4)" id="svg_1" r="23" cy="27" cx="27"/>
</g>
</svg>
</g>
<g id="ellipse">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54 54">
<defs>
<linearGradient y2="1.0" x2="1.0" y1="0.1875" x1="0.171875" id="svg_4">
<stop stop-opacity="1" stop-color="#ffffff" offset="0.0"/>
<stop stop-opacity="1" stop-color="#ffffff" offset="1.0"/>
</linearGradient>
</defs>
<g>
<ellipse stroke-opacity="1" fill-opacity="1" stroke-width="2" stroke="#000000" fill="url(#svg_4)" id="svg_1" rx="23" ry="15" cy="27" cx="27"/>
</g>
</svg>
</g>
<g id="fh_ellipse">
<svg viewBox="0 0 52 52" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="svg_9" x1="0.3046" y1="0.1093" x2="0.6132" y2="0.3945">
<stop offset="0" stop-color="#f9d225" stop-opacity="1"/>
<stop offset="1" stop-color="#bf5f00" stop-opacity="1"/>
</linearGradient>
<linearGradient id="svg_4" x1="0.17188" y1="0.1875" x2="1" y2="1">
<stop offset="0" stop-color="#ffffff" stop-opacity="1"/>
<stop offset="1" stop-color="#ff6666" stop-opacity="1"/>
</linearGradient>
</defs>
<ellipse stroke-width="2" stroke="#000000" fill="url(#svg_4)" id="svg_1" rx="23" ry="12" cy="37" cx="27"/>
<path d="m31.5,0l-8.75,20.25l0.75,24l16.5,-16.5l6,-12.5" id="svg_2" fill="url(#svg_9)" stroke="#000000" stroke-width="2"/>
<path d="m39.5,28.5c-2,-9.25 -10.25,-11.75 -17,-7.4375l0.4843,24.4414z" id="svg_10" fill="#fce0a9" stroke="#000000" stroke-width="2"/>
<path d="m26.9318,41.1745c-0.4491,-2.3511 -2.3021,-2.9866 -3.8181,-1.8905l0.1087,6.2126z" fill="#000000" stroke="#000000" stroke-width="2" id="svg_11"/>
</svg>
</g>
<g id="pencil">
<!--<svg viewBox="0 0 48 52" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="svg_9" x1="0.3046" y1="0.1093" x2="0.6132" y2="0.3945">
<stop offset="0.0" stop-color="#f9d225" stop-opacity="1"/>
<stop offset="1.0" stop-color="#bf5f00" stop-opacity="1"/>
</linearGradient>
</defs>
<path d="M31.5,0 l-8.75,20.25 l0.75,24 l16.5,-16.5 l6,-12.5" id="svg_2" fill="url(#svg_9)" stroke="#000000" stroke-width="2" fill-opacity="1" stroke-opacity="1"/>
<path d="M39.5,28.5 c-2,-9.25 -10.25,-11.75 -17,-7.4375 l0.4843,24.4414z" id="svg_10" fill="#fce0a9" stroke="#000000" stroke-width="2" fill-opacity="1" stroke-opacity="1"/>
<path d="M26.9318,41.1745 c-0.4491,-2.3511 -2.3021,-2.9866 -3.8181,-1.8905 l0.1087,6.2126z" fill="#000000" stroke="#000000" stroke-width="2" fill-opacity="1" stroke-opacity="1" id="svg_11"/>
<path d="M2.3132,4.6197 c12.4998,-1.6891 10.4729,7.0945 0,21.6215 c22.9729,-4.0539 12.1620,5.4053 12.1620,13.1756 c-0.3377,4.0539 8.7836,21.9594 26.0135,-1.3513" id="svg_12" fill="none" stroke="#000000" stroke-width="2" fill-opacity="1" stroke-opacity="1"/>
</svg>-->
<svg width="24" height="24" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path d="M491 1536l91-91-235-235-91 91v107h128v128h107zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17zm-54-192l416 416-832 832h-416v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91z"/>
</svg>
</g>
+<g id="point">
+ <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <circle cx="12" cy="12" r="6"></circle>
+ </svg>
+</g>
+
<g id="pen">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!--<defs>
<linearGradient id="svg_16" x1="0.46484" y1="0.15625" x2="0.9375" y2="0.39453">
<stop offset="0" stop-color="#ffffff" stop-opacity="1"/>
<stop offset="1" stop-color="#ffffff" stop-opacity="1"/>
</linearGradient>
<linearGradient id="svg_19" x1="0.18359" y1="0.26172" x2="0.77734" y2="0.56641">
<stop offset="0" stop-color="#ffffff" stop-opacity="1"/>
<stop offset="1" stop-color="#ffffff" stop-opacity="1"/>
</linearGradient>
</defs>-->
<line x1="1" y1="1" x2="23" y2="23" id="svg_5" stroke="#000000" fill="none"/>
<!--<path d="m14.05272,13.68732l-1.46451,7.52632l4.03769,-6.32571" id="svg_6" fill="#a0a0a0" stroke="#000000"/>
<path d="m13.61215,10.26563c-0.38567,1.05257 -0.60723,2.40261 -0.50403,3.125l4.33468,1.81452c0.46153,-0.30769 1.6129,-1.71371 1.6129,-2.52016" id="svg_7" fill="url(#svg_19)" stroke="#000000"/>
<path d="m16.61335,1.00028l-3.67325,8.60247l7.10285,3.47318l3.17783,-7.20549" id="svg_8" fill="url(#svg_16)" stroke="#000000"/>
<line id="svg_1" y2="0.7" x2="0.8" y1="0.1" x1="0.1" stroke="#000000" fill="none"/>-->
</svg>
</g>
<g id="text">
<svg viewBox="0 0 158 128" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<text x="58" y="120" id="svg_1" fill="#000000" stroke="none" font-size="120pt" font-family="sans-serif" text-anchor="middle" fill-opacity="1" stroke-opacity="1" font-weight="bold">A</text>
<line x1="136" y1="7" x2="136" y2="121" id="svg_2" stroke="#000000" fill="none" fill-opacity="1" stroke-opacity="1" stroke-width="5"/>
<line x1="120" y1="4" x2="152" y2="4" id="svg_3" stroke="#000000" stroke-width="5" fill="none" fill-opacity="1" stroke-opacity="1"/>
<line x1="120" y1="124" x2="152" y2="124" stroke="#000000" stroke-width="5" fill="none" fill-opacity="1" stroke-opacity="1" id="svg_4"/>
</svg>
</g>
<g id="path">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 124 124" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient y2="1" x2="1" y1="0.28125" x1="0.33594" id="svg_4">
<stop stop-opacity="1" stop-color="#ffffff" offset="0"/>
<stop stop-opacity="1" stop-color="#ffffff" offset="1"/>
</linearGradient>
</defs>
<path stroke-dasharray="null" stroke-width="4" stroke="#000000" fill="url(#svg_4)" id="svg_1" d="m6,103l55,-87c85,33.64 -26,37.12 55,87l-110,0z"/>
<line id="svg_2" y2="178" x2="280" y1="124" x1="175" stroke-width="5" stroke="#000000" fill="none"/>
</svg>
</g>
<g id="add_subpath">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 124 124" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="svg_4" x1="0.33594" y1="0.28125" x2="1" y2="1">
<stop offset="0" stop-color="#ffffff" stop-opacity="1"/>
<stop offset="1" stop-color="#33a533" stop-opacity="1"/>
</linearGradient>
</defs>
<g>
<path d="m6,103l55,-87c85,33.64 -26,37.12 55,87l-110,0z" id="svg_1" fill="url(#svg_4)" stroke="#000000" stroke-width="4" stroke-dasharray="null"/>
<g id="svg_7">
<circle stroke-dasharray="null" stroke-width="5" stroke="#000000" fill="#ffffff" id="svg_6" r="22.63281" cy="88.5" cx="45.5"/>
<line stroke-dasharray="null" stroke-width="7" stroke="#000000" id="svg_2" y2="104.03768" x2="45.5" y1="72.96232" x1="45.5"/>
<line stroke-dasharray="null" stroke-width="7" stroke="#000000" id="svg_3" y2="88.5" x2="61.03768" y1="88.5" x1="29.96232"/>
</g>
</g>
</svg>
</g>
<g id="close_path">
<svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<path stroke="#000" stroke-width="15" fill="#ffc8c8" d="m121.5,40l-84,106l27,115l166,2l29,-111"/>
<line x1="240" y1="136" x2="169.5" y2="74" stroke="#A00" stroke-width="25" fill="none"/>
<path stroke="none" fill ="#A00" d="m158,65l31,74l-3,-50l51,-3z"/>
<g stroke-width="15" stroke="#00f" fill="#0ff">
<circle r="30" cy="41" cx="123"/>
<circle r="30" cy="146" cx="40"/>
<circle r="30" cy="260" cx="69"/>
<circle r="30" cy="260" cx="228"/>
<circle r="30" cy="148" cx="260"/>
</g>
</g>
</svg>
</g>
<g id="open_path">
<svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<path stroke="#000" stroke-width="15" fill="#ffc8c8" d="m123.5,38l-84,106l27,115l166,2l29,-111"/>
<line x1="276.5" y1="153" x2="108.5" y2="24" stroke="#000" stroke-width="10" fill="none"/>
<g stroke-width="15" stroke="#00f" fill="#0ff">
<circle r="30" cy="41" cx="123"/>
<circle r="30" cy="146" cx="40"/>
<circle r="30" cy="260" cx="69"/>
<circle r="30" cy="260" cx="228"/>
<circle r="30" cy="148" cx="260"/>
</g>
<g stroke="#A00" stroke-width="15" fill="none">
<line x1="168" y1="24" x2="210" y2="150"/>
<line x1="210" y1="24" x2="168" y2="150"/>
</g>
</g>
</svg>
</g>
<g id="image">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<defs>
<linearGradient y2="1" x2="1" y1="0" x1="1" id="svg_25">
<stop stop-opacity="1" stop-color="#10284c" offset="0"/>
<stop stop-opacity="1" stop-color="#5374ad" offset="1"/>
</linearGradient>
<linearGradient y2="0.75781" x2="0.99609" y1="0" x1="1" id="svg_23">
<stop stop-opacity="1" stop-color="#162e84" offset="0"/>
<stop stop-opacity="1" stop-color="#97c4ef" offset="1"/>
</linearGradient>
</defs>
<rect x="1" y="3.83333" width="22" height="17" id="svg_18" fill="#202020" stroke="none"/>
<rect stroke-width="1.2" stroke="#ffffff" fill="#232947" id="svg_15" height="14" width="19" y="5.33333" x="2.5"/>
<rect fill="url(#svg_23)" id="svg_20" height="7.02244" width="15.96424" y="6.7266" x="4"/>
<rect fill="url(#svg_25)" id="svg_24" height="4.02393" width="15.96303" y="13.77454" x="4"/>
<circle fill="#ffffad" id="svg_26" r="1.83333" cy="9.82002" cx="7.13254"/>
<path d="m14.5696,13.77458l0.70243,-4.85313l-3.12899,4.85313l2.42656,0z" id="svg_14" fill="#404040" stroke="none"/>
<path d="m15.27203,8.98531c2.74584,0.06386 2.42657,4.21456 -0.63857,4.85313c0.70243,-1.27714 1.66028,-3.63985 0.63857,-4.85313z" id="svg_17" fill="#404040" stroke="none"/>
</svg>
</g>
<g id="zoom">
<svg viewBox="0 0 150 150" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="svg_30" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#d3d3d3" stop-opacity="1"/>
<stop offset="1" stop-color="#424242" stop-opacity="1"/>
</linearGradient>
</defs>
<path d="m107.14774,101.03477l-0.64774,43.96523c5.00857,4.72089 14.00811,5.27188 19,0l-0.31667,-44.16l-9.61514,-19.84l-8.42046,20.03477z" id="svg_29" fill="url(#svg_30)" stroke="#202020" stroke-width="2" transform="rotate(-45, 116, 114)"/>
<circle cx="58" cy="58" r="51" id="svg_22" fill="#c0c0c0" stroke="#202020" stroke-width="5"/>
<circle cx="58" cy="58" r="43" id="svg_27" fill="#aaccff" stroke="none"/>
<path d="m15.68604,61.46511c38.13954,17.67442 48.13954,15.34883 85.11628,-0.46511c1.39536,18.60465 -19.30231,41.86047 -42.7907,40.93023c-21.6279,-0.93023 -42.7907,-21.86046 -42.32558,-40.46511z" id="svg_28" fill="#8cbaff" stroke="none"/>
</svg>
</g>
<g id="arrow_right">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 50">
<path stroke="#000000" fill="#000000" d="m0,0l0,50l25,-25l-25,-25z"/>
</svg>
</g>
<g id="arrow_right_big">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 50">
<path stroke="#000000" fill="#000000" d="m0,0l0,50l25,-25l-25,-25z"/>
</svg>
</g>
<g id="arrow_down">
<svg viewBox="0 0 50 40" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path transform="rotate(90, 26, 13)" d="m14,-12l0,50l25,-25l-25,-25z" fill="#000000" stroke="#000000"/>
</svg>
</g>
<g id="fill">
<svg width="32" height="33" xmlns="http://www.w3.org/2000/svg">
<g id="svg_5">
<path id="svg_4" d="m17.49167,10.97621c6.9875,-0.325 12.1875,2.70833 12.13333,7.36667l-0.325,10.075c-0.75833,4.0625 -2.275,3.0875 -3.03333,0.10833l0.21667,-9.64166c-0.43333,-0.975 -1.08333,-1.625 -1.95,-1.51667" stroke-linejoin="round" stroke="#606060" fill="#c0c0c0"/>
<path id="svg_1" d="m2.00055,17.1309l10.72445,-10.72445l12.67445,12.13279l-3.52056,0.05389l-9.15389,9.26223l-10.72445,-10.72445z" stroke-linejoin="round" stroke="#000000" fill="#c0c0c0"/>
<path id="svg_3" d="m14.35,13.57621c-0.1625,-3.95417 0.86667,-11.7 -1.84167,-11.59167c-2.70833,0.10833 -2.6,2.05833 -2.16667,6.93333" stroke-linejoin="round" stroke="#000000" fill="none"/>
<circle id="svg_2" r="1.60938" cy="15.20121" cx="14.45833" stroke-linejoin="round" stroke="#000000" fill="none"/>
</g>
</svg>
</g>
<g id="stroke">
<svg width="50" height="50" xmlns="http://www.w3.org/2000/svg">
<rect fill="none" stroke="#707070" stroke-width="10" x="8.625" y="8.625" width="32.75" height="32.75" id="svg_1"/>
</svg>
</g>
<g id="opacity">
<svg width="50" height="50" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient y2="0.1" x2="0.9" y1="0.9" x1="0.1" id="svg_7">
<stop stop-color="#000000" offset="0"/>
<stop stop-opacity="0" stop-color="#000000" offset="1"/>
</linearGradient>
</defs>
<rect id="svg_4" height="50" width="50" y="0" x="0" fill="#ffffff"/>
<rect id="svg_1" height="25" width="25" y="0" x="0" fill="#a0a0a0"/>
<rect id="svg_2" height="25" width="25" y="25" x="25" fill="#a0a0a0"/>
<rect id="svg_3" height="50" width="50" y="0" x="0" stroke-width="2" stroke="url(#svg_7)" fill="url(#svg_7)"/>
</svg>
</g>
<g id="new_image">
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="2.42792" y="1.6692" width="18" height="21" id="svg_55" fill="#eaeaea" stroke="#606060"/>
<circle stroke="none" fill="url(#svg_9)" id="svg_65" r="6.300781" cy="7.529969" cx="17.761984"/>
<defs>
<radialGradient id="svg_9" cx="0.5" cy="0.5" r="0.5">
<stop offset="0.1" stop-color="#ffe500" stop-opacity="1"/>
<stop offset="1" stop-color="#ffff00" stop-opacity="0"/>
</radialGradient>
</defs>
</svg>
</g>
<g id="save">
<!--<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<defs>
<linearGradient y2="0" x2="1" y1="0" x1="0" id="svg_41">
<stop stop-opacity="1" stop-color="#727272" offset="0"/>
<stop stop-opacity="1" stop-color="#d6d6d6" offset="1"/>
</linearGradient>
<linearGradient y2="0.875" x2="0.21484" y1="0.00391" x1="0.04297" id="svg_46">
<stop stop-opacity="1" stop-color="#81bbf4" offset="0"/>
<stop stop-opacity="1" stop-color="#376eb7" offset="1"/>
</linearGradient>
</defs>
<path stroke="#202020" fill="#e0e0e0" id="svg_21" d="m1.51669,22.3458l21.13245,-0.10111l0,-6.06673l-2.62892,-9.80789l-16.27907,0.10111l-2.32558,9.20121l0.10111,6.67341z"/>
<rect stroke="#efefef" fill="url(#svg_41)" id="svg_32" height="4.75108" width="19.21031" y="16.58227" x="2.42667"/>
<path stroke="#ffffff" fill="#c0c0c0" id="svg_42" d="m4.55005,11.12235l0.70779,-2.83114l13.04348,0l0.70779,3.13448c-0.70779,2.52781 -4.04479,3.84227 -7.17897,3.84227c-2.72977,0 -6.37007,-1.41557 -7.28008,-4.1456z"/>
<path stroke="#285582" fill="url(#svg_46)" id="svg_45" d="m7.14286,9.74903l5.21236,5.79151l5.50193,-5.88803l-2.50965,-0.09653l0,-2.79923c0,-2.3166 -2.3166,-5.59846 -6.56371,-5.59846c-4.05405,0 -6.27413,3.37838 -6.56371,6.75676c0.48263,-1.5444 2.7027,-4.53668 4.44015,-4.44015c2.12355,-0.09653 2.79923,1.64093 2.79923,3.37838l0.09653,2.79923l-2.41313,0.09653z"/>
</svg>-->
<svg width="24" height="24" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path d="M512 1536h768v-384h-768v384zm896 0h128v-896q0-14-10-38.5t-20-34.5l-281-281q-10-10-34-20t-39-10v416q0 40-28 68t-68 28h-576q-40 0-68-28t-28-68v-416h-128v1280h128v-416q0-40 28-68t68-28h832q40 0 68 28t28 68v416zm-384-928v-320q0-13-9.5-22.5t-22.5-9.5h-192q-13 0-22.5 9.5t-9.5 22.5v320q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5-9.5t9.5-22.5zm640 32v928q0 40-28 68t-68 28h-1344q-40 0-68-28t-28-68v-1344q0-40 28-68t68-28h928q40 0 88 20t76 48l280 280q28 28 48 76t20 88z"/>
</svg>
</g>
<g id="export">
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="svg_5" x1="0.77734" y1="0.51172" x2="0.09375" y2="0.53516">
<stop offset="0" stop-color="#81bbf4"/>
<stop offset="1" stop-color="#376eb7"/>
</linearGradient>
</defs>
<g>
<rect x="7.22599" y="1.3603" width="15.76465" height="21.51735" id="svg_55" fill="#eaeaea" stroke="#606060"/>
<circle fill="#31abed" stroke-width="0.5" cx="17.4206" cy="11.1278" r="4.69727" id="svg_3"/>
<path fill="#ffcc00" stroke-width="0.5" d="m9.67673,20.24302l7.38701,-6.80778l2.91746,6.71323" id="svg_4"/>
<rect fill="#ff5555" stroke-width="0.5" x="9.5385" y="2.94914" width="5.74652" height="5.74652" id="svg_2"/>
<path d="m6.13727,17.94236l5.77328,-4.91041l-5.86949,-5.1832l-0.09622,2.36426l-4.64805,-0.06751l-0.04665,5.54694l4.79093,-0.02342l0.09623,2.27334z" id="svg_45" fill="url(#svg_5)" stroke="#285582"/>
</g>
</svg>
</g>
<g id="open">
<svg viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient y2="0.91406" x2="0.65234" y1="0.14063" x1="0.42578" id="svg_76">
<stop stop-opacity="1" stop-color="#81bbf4" offset="0"/>
<stop stop-opacity="1" stop-color="#376eb7" offset="1"/>
</linearGradient>
</defs>
<rect x="1.65" y="3.75" width="9.8" height="16.72712" id="svg_98" fill="#c0c0c0" stroke="#606060"/>
<rect stroke="none" fill="#a0a0a0" id="svg_88" height="14.17459" width="6.39585" y="4.9758" x="2.89542"/>
<path d="m18.62576,4.54365l0,6.91443l-9.9395,0l-0.08643,-10.11236l6.828,0l3.19792,3.19793z" id="svg_99" fill="#e0e0e0" stroke="#404040"/>
<path d="m2.95,20.53644l1.65,-12.03644l16.2,0l-1.5,12l-16.35,0.03643z" id="svg_97" fill="url(#svg_76)" stroke="#285582"/>
<line fill="none" stroke="#606060" id="svg_89" y2="4.28436" x2="13.95851" y1="4.28436" x1="10.32844"/>
<line fill="none" stroke="#606060" id="svg_91" y2="6.53155" x2="14.82282" y1="6.53155" x1="10.32844"/>
<path stroke="none" fill="#ffffff" id="svg_100" d="m15.25895,1.95069l-0.00401,2.85225l2.89558,0.00004l-2.89157,-2.85229z"/>
</svg>
</g>
<g id="import">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient y2="0.875" x2="0.21484" y1="0.00391" x1="0.04297" id="svg_46_import">
<stop stop-opacity="1" stop-color="#81f4bb" offset="0"/>
<stop stop-opacity="1" stop-color="#37b76e" offset="1"/>
</linearGradient>
</defs>
<rect x="2.42792" y="1.6692" width="18" height="21" id="svg_55" fill="#eaeaea" stroke="#606060"/>
<path stroke="#285582" fill="url(#svg_46_import)" id="svg_45" d="m7.14286,12.74903l5.21236,5.79151l5.50193,-5.88803l-2.50965,-0.09653l0,-2.79923c0,-2.3166 -2.3166,-5.59846 -6.56371,-5.59846c-4.05405,0 -6.27413,3.37838 -6.56371,6.75676c0.48263,-1.5444 2.7027,-4.53668 4.44015,-4.44015c2.12355,-0.09653 2.79923,1.64093 2.79923,3.37838l0.09653,2.79923l-2.41313,0.09653z"/>
</svg>
</g>
<g id="docprops">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<defs>
<linearGradient y2="1" x2="1" y1="0.5" x1="1" id="svg_53">
<stop stop-opacity="1" stop-color="#606060" offset="0"/>
<stop stop-opacity="0" stop-color="#5e5e5e" offset="1"/>
</linearGradient>
</defs>
<rect stroke="#606060" fill="#eaeaea" id="svg_55" height="21" width="18" y="1.6692" x="2.42792"/>
<line fill="none" stroke="#a0a0a0" id="svg_56" y2="4.37757" x2="14.89023" y1="4.37757" x1="6.696"/>
<line fill="none" stroke="#a0a0a0" id="svg_57" y2="7.10804" x2="12.92026" y1="7.10804" x1="6.6948"/>
<line fill="none" stroke="#a0a0a0" id="svg_58" y2="9.84241" x2="15.64716" y1="9.84241" x1="6.6942"/>
<line fill="none" stroke="#a0a0a0" id="svg_59" y2="12.36585" x2="13.21805" y1="12.36585" x1="6.69691"/>
<line fill="none" stroke="#a0a0a0" id="svg_60" y2="15.06507" x2="14.43591" y1="15.06507" x1="6.69691"/>
<line fill="none" stroke="#a0a0a0" id="svg_61" y2="17.84241" x2="13.36979" y1="17.84241" x1="6.69691"/>
<g id="svg_54">
<path transform="rotate(-45, 12.5448, 11.7085)" stroke="none" fill="#606060" id="svg_31" d="m11.24329,8.73944l0,2.79974l2.53499,0.07777l0,-2.95528c1.78134,0.07777 2.26093,1.39987 2.12391,2.95528c-0.06851,1.63318 -1.30175,3.49967 -3.49418,3.26636c-2.19242,-0.31108 -2.87755,-1.39987 -3.15161,-2.72197c-0.27406,-1.39987 0.41108,-3.34413 1.98689,-3.4219z"/>
<rect opacity="0.95" transform="rotate(-45, 16.2485, 15.1732)" stroke="none" fill="url(#svg_53)" id="svg_50" height="4.85445" width="2.57974" y="12.746" x="15.04047"/>
</g>
</svg>
</g>
<g id="source">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 55 52">
<text xml:space="preserve" text-anchor="middle" font-family="monospace" font-size="24" stroke="none" fill="#019191" id="svg_40" y="15" x="28.23" font-weight="bold">s</text>
<text xml:space="preserve" text-anchor="middle" font-family="monospace" font-size="24" stroke="none" fill="#019191" id="svg_47" y="30" x="28.23" font-weight="bold">v</text>
<text xml:space="preserve" text-anchor="middle" font-family="monospace" font-size="24" stroke="none" fill="#019191" id="svg_48" y="44" x="28.23" font-weight="bold">g</text>
<line stroke-width="3" fill="none" stroke="#aa0000" id="svg_51" y2="43" x2="16" y1="25" x1="5"/>
<line id="svg_62" stroke-width="3" fill="none" stroke="#aa0000" y2="8" x2="16" y1="26" x1="5"/>
<line id="svg_63" stroke-width="3" fill="none" stroke="#aa0000" y2="43" x2="39" y1="25" x1="50"/>
<line id="svg_64" stroke-width="3" fill="none" stroke="#aa0000" y2="8" x2="39" y1="26" x1="51"/>
</svg>
</g>
<g id="wireframe">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<circle stroke="#000000" fill="none" id="svg_49" r="8" cy="9.5" cx="9.5"/>
<rect stroke="#000000" fill="none" id="svg_52" height="14" width="14" y="8.5" x="8.5"/>
</svg>
</g>
<g id="undo">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="svg_66" x1="0.04297" y1="0.00391" x2="0.21484" y2="0.875">
<stop offset="0" stop-color="#f7f963" stop-opacity="1"/>
<stop offset="1" stop-color="#d3c310" stop-opacity="1"/>
</linearGradient>
</defs>
<path transform="rotate(-90, 10.3017, 11.5526)" d="m6.70188,10.72562l6.55493,-7.13388l6.65817,7.24912l-3.79441,0.03193l0,2.72259c-0.04257,2.74017 -2.76516,5.83068 -7.81235,6.02135c-5.18575,0 -7.1226,-3.75464 -7.49302,-7.41944c0.61736,1.6754 3.14913,3.78397 5.3716,3.67918c2.71635,0.1048 4.41501,-0.61714 4.41501,-2.50184l0,-2.64901l-3.89995,0z" id="svg_45" fill="url(#svg_66)" stroke="#b7a800"/>
</svg>
</g>
<g id="redo">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient y2="1" x2="1" y1="0" x1="1" id="svg_71">
<stop stop-opacity="1" stop-color="#98fc46" offset="0"/>
<stop stop-opacity="1" stop-color="#56aa25" offset="1"/>
</linearGradient>
</defs>
<path transform="rotate(-90, 12.7299, 11.5526)" d="m9.11294,12.43144l6.54089,6.84566l6.6439,-6.95624l-3.78628,-0.03064l0,-2.61259c-0.04248,-2.62946 -2.75924,-5.5951 -7.79561,-5.77807c-5.17464,0 -7.10734,3.60294 -7.47697,7.11967c0.61604,-1.60771 3.14238,-3.63109 5.36009,-3.53053c2.71053,-0.10056 4.40555,0.59221 4.40555,2.40076l0,2.54198l-3.89159,0z" id="svg_45" fill="url(#svg_71)" stroke="#44aa00"/>
</svg>
</g>
<g id="clone">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">
<defs>
<linearGradient y2="1" x2="1" y1="0" x1="0" id="svg_36">
<stop stop-opacity="1" stop-color="#f9f3de" offset="0"/>
<stop stop-opacity="1" stop-color="#ccbd8f" offset="1"/>
</linearGradient>
<linearGradient y2="0.80078" x2="0.42578" y1="0" x1="0" id="svg_69">
<stop stop-opacity="1" stop-color="#f9f3de" offset="0"/>
<stop stop-opacity="1" stop-color="#af995b" offset="1"/>
</linearGradient>
</defs>
<path stroke="#8f5902" fill="url(#svg_69)" id="svg_34" d="m2.11676,16.32061l-0.13787,-5.05515l1.93015,-2.02206l10.11029,0l2.02206,2.29779l0,4.77941l-13.92463,0z"/>
<rect x="7.85379" y="6.30027" width="2.2932" height="4.3407" id="svg_38" fill="url(#svg_36)" stroke="#8f5902" rx="1" ry="1"/>
<circle stroke="#8f5902" fill="url(#svg_36)" id="svg_35" r="2.96392" cy="4.48149" cx="9.11757"/>
<line x1="2.44838" y1="12.03512" x2="15.5524" y2="12.03512" id="svg_39" stroke="#f9f3de" fill="none"/>
<path d="m6.72427,12.55859l4.74203,0l-2.30831,2.07258l-2.43372,-2.07258z" id="svg_43" fill="#000000" stroke="none"/>
</svg>
</g>
<g id="delete">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<rect ry="3" rx="3" stroke="#800000" fill="#aa0000" id="svg_37" height="20.29514" width="21.17486" y="1.70304" x="1.42011"/>
<rect ry="3" rx="3" stroke="#ff5555" fill="#aa0000" id="svg_67" height="18.63022" width="19.61118" y="2.53597" x="2.20258"/>
<line stroke-width="2" fill="none" stroke="#ffffff" id="svg_68" y2="16.85127" x2="17.00646" y1="6.85127" x1="7.00646"/>
<line stroke-width="2" id="svg_70" fill="none" stroke="#ffffff" y2="16.85127" x2="7.00646" y1="6.85127" x1="17.00646"/>
</svg>
</g>
<g id="go_up">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">
<defs>
<linearGradient y2="0" x2="0.7" y1="0" x1="0" id="svg_74">
<stop stop-opacity="1" stop-color="#afe853" offset="0"/>
<stop stop-opacity="1" stop-color="#52a310" offset="1"/>
</linearGradient>
</defs>
<path stroke="#008000" fill="url(#svg_74)" id="svg_33" d="m5.38492,16.77043l7.07692,0l0,-5.23077l4.15385,0l-7.69231,-10.15385l-7.69231,10.15385l4.15385,0l0,5.23077z"/>
</svg>
</g>
<g id="go_down">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">
<defs>
<linearGradient y2="0" x2="0.7" y1="0" x1="0" id="svg_75">
<stop stop-opacity="1" stop-color="#afe853" offset="0"/>
<stop stop-opacity="1" stop-color="#52a310" offset="1"/>
</linearGradient>
</defs>
<path stroke="#008000" fill="url(#svg_75)" id="svg_33" d="m5.3015,1.69202l6.93483,0l0,5.07323l4.07045,0l-7.53786,9.84803l-7.53786,-9.84803l4.07045,0l0,-5.07323z"/>
</svg>
</g>
<g id="context_menu">
<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg">
<path stroke-width="0" id="svg_11" d="m4.5,46.5l52,0l-26,38l-26,-38z" stroke="#000" fill="#000"/>
<g id="svg_16">
<line stroke-width="10" id="svg_12" y2="27.5" x2="117.5" y1="27.5" x1="59.5" stroke="#000" fill="#000"/>
<line id="svg_13" stroke-width="10" y2="51.5" x2="117.5" y1="51.5" x1="59.5" stroke="#000" fill="#000"/>
<line id="svg_14" stroke-width="10" y2="73.5" x2="117.5" y1="73.5" x1="59.5" stroke="#000" fill="#000"/>
<line id="svg_15" stroke-width="10" y2="97.5" x2="117.5" y1="97.5" x1="59.5" stroke="#000" fill="#000"/>
</g>
</svg>
</g>
<g id="move_bottom">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23">
<defs>
<linearGradient y2="0" x2="1" y1="0" x1="0" id="svg_80">
<stop stop-opacity="1" stop-color="#bc7f05" offset="0"/>
<stop stop-opacity="1" stop-color="#fcfc9f" offset="1"/>
</linearGradient>
</defs>
<line stroke-width="2" fill="none" stroke="#000000" id="svg_72" y2="2.5" x2="22" y1="2.5" x1="10.5"/>
<line id="svg_73" stroke-width="2" fill="none" stroke="#000000" y2="6.5" x2="21.99844" y1="6.5" x1="10.49844"/>
<line id="svg_74" stroke-width="2" fill="none" stroke="#000000" y2="10.5" x2="21.99922" y1="10.5" x1="10.49922"/>
<line id="svg_75" stroke-width="2" fill="none" stroke="#000000" y2="14.5" x2="21.99922" y1="14.5" x1="10.49922"/>
<rect stroke="#000000" fill="url(#svg_80)" id="svg_77" height="2.2" width="20" y="17.65" x="1.65"/>
<path stroke="none" fill="#000000" id="svg_81" d="m4.25,1.55l2.35,0l0,11.05l2,0l-3.175,3.45l-3.175,-3.45l2,0l0,-11.05z"/>
</svg>
</g>
<g id="move_top">
<svg viewBox="0 0 23 23" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="svg_86" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#9fdcf4" stop-opacity="1"/>
<stop offset="1" stop-color="#617e96" stop-opacity="1"/>
</linearGradient>
</defs>
<line x1="1.3" y1="8.19922" x2="12.8" y2="8.19922" id="svg_72" stroke="#000000" fill="none" stroke-width="2"/>
<line x1="1.29844" y1="12.19922" x2="12.79844" y2="12.19922" stroke="#000000" fill="none" stroke-width="2" id="svg_73"/>
<line x1="1.29922" y1="16.19922" x2="12.79922" y2="16.19922" stroke="#000000" fill="none" stroke-width="2" id="svg_74"/>
<line x1="1.29922" y1="20.19922" x2="12.79922" y2="20.19922" stroke="#000000" fill="none" stroke-width="2" id="svg_75"/>
<rect x="1.55" y="1.85" width="20" height="3.2" id="svg_77" fill="url(#svg_86)" stroke="#000000"/>
<path d="m16.83475,21.14603l2.33207,0l0,-11.04578l1.98474,0l-3.15077,-3.44869l-3.15077,3.44869l1.98474,0l0,11.04578z" id="svg_81" fill="#000000" stroke="none"/>
</svg>
</g>
<g id="to_path">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient y2="0.46875" x2="0.42969" y1="0.10156" x1="0.10547" id="svg_105">
<stop stop-color="#ff0000" offset="0"/>
<stop stop-opacity="0" stop-color="#ff0000" offset="1"/>
</linearGradient>
</defs>
<g>
<circle cx="21" cy="21.3125" r="18.44531" id="svg_120" fill="url(#svg_105)" stroke="#000000"/>
<path fill="none" stroke="#000000" d="m2.875,21.3125c-0.375,-9.25 7.75,-18.875 17.75,-18" id="svg_115"/>
<line x1="25.375" y1="3.0625" x2="8.5" y2="3.0625" id="svg_116" stroke="#808080" fill="none"/>
<line x1="2.625" y1="24.75" x2="2.625" y2="9.8125" id="svg_117" stroke="#808080" fill="none"/>
<circle cx="8.5" cy="2.9375" r="1.95313" fill="#00ffff" stroke="#0000ff" stroke-width="0.5" id="svg_118"/>
<circle cx="2.625" cy="9.8125" r="1.95313" fill="#00ffff" stroke="#0000ff" stroke-width="0.5" id="svg_119"/>
<circle cx="20.875" cy="3.1875" r="2.5" id="svg_112" fill="#00ffff" stroke="#0000ff"/>
<circle cx="2.875" cy="21.0625" r="2.5" fill="#00ffff" stroke="#0000ff" id="svg_114"/>
</g>
</svg>
</g>
<g id="link_controls">
<svg viewBox="0 0 24 24" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
<path stroke-width="2" id="svg_102" d="m9.875,23c-2,-4.25 -1.6875,-7.375 1.6875,-10.5c3.375,-3.125 7.5625,-2.75 11.0625,2" stroke="#8dd35f" fill="none"/>
<line fill="none" stroke="#606060" id="svg_109" y2="4" x2="19" y1="19" x1="4"/>
<circle stroke="#0000ff" fill="#00ffff" id="svg_111" r="2.17578" cy="11.5" cx="11.5"/>
<circle stroke-width="0.5" id="svg_121" stroke="#0000ff" fill="#00ffff" r="2.26172" cy="4" cx="19"/>
<circle id="svg_123" stroke-width="0.5" stroke="#0000ff" fill="#00ffff" r="2.26172" cy="19" cx="4"/>
</svg>
</g>
<g id="reorient">
<svg viewBox="0 0 24 24" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient y2="1" x2="1" y1="1" x1="0" id="svg_113">
<stop stop-opacity="0" stop-color="#0000ff" offset="0"/>
<stop stop-opacity="1" stop-color="#507ece" offset="1"/>
</linearGradient>
</defs>
<rect stroke-dasharray="2,2" stroke="#0000ff" fill="none" id="svg_108" height="19.125" width="18.625" y="2.625" x="2.875"/>
<rect transform="rotate(45, 12.2344, 12.1719)" stroke="#000000" fill="url(#svg_113)" id="svg_107" height="6.125" width="16" y="9.10848" x="4.23267"/>
</svg>
</g>
<g id="group_elements">
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="svg_90" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#ccddff" stop-opacity="1"/>
<stop offset="1" stop-color="#789fed" stop-opacity="1"/>
</linearGradient>
<linearGradient id="svg_92" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#70a1e5" stop-opacity="1"/>
<stop offset="1" stop-color="#4b6baf" stop-opacity="1"/>
</linearGradient>
</defs>
<rect x="13.5" y="0.5" width="2" height="2" fill="#a0a0a0" stroke="#555555" id="svg_79"/>
<rect x="13.5" y="13.5" width="2" height="2" fill="#a0a0a0" stroke="#555555" id="svg_82"/>
<rect x="0.5" y="13.5" width="2" height="2" fill="#a0a0a0" stroke="#555555" id="svg_83"/>
<rect x="2.5" y="2.5" width="8" height="7" fill="#a0a0a0" stroke="#555555" id="svg_85"/>
<rect x="2.5" y="2.5" width="8" height="7" fill="url(#svg_90)" stroke="url(#svg_92)" id="svg_87"/>
<rect x="5.5" y="6.5" width="8" height="7" id="svg_84" fill="#7399d6" stroke="url(#svg_92)"/>
<rect x="0.5" y="0.5" width="2" height="2" id="svg_78" fill="#a0a0a0" stroke="#555555"/>
</svg>
</g>
<g id="ungroup">
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="svg_90" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#ccddff" stop-opacity="1"/>
<stop offset="1" stop-color="#789fed" stop-opacity="1"/>
</linearGradient>
<linearGradient id="svg_92" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#70a1e5" stop-opacity="1"/>
<stop offset="1" stop-color="#4b6baf" stop-opacity="1"/>
</linearGradient>
</defs>
<rect x="2.5" y="2.5" width="8" height="7" fill="url(#svg_90)" stroke="url(#svg_92)" id="svg_87"/>
<rect x="5.5" y="6.5" width="8" height="7" id="svg_84" fill="#7399d6" stroke="url(#svg_92)"/>
<rect x="9.5" y="1.5" width="2" height="2" fill="#a0a0a0" stroke="#555555" id="svg_79"/>
<rect x="1.5" y="8.5" width="2" height="2" fill="#a0a0a0" stroke="#555555" id="svg_83"/>
<rect x="1.5" y="1.5" width="2" height="2" id="svg_78" fill="#a0a0a0" stroke="#555555"/>
<rect id="svg_93" x="12.5" y="5.5" width="2" height="2" fill="#a0a0a0" stroke="#555555"/>
<rect id="svg_94" x="12.5" y="12.5" width="2" height="2" fill="#a0a0a0" stroke="#555555"/>
<rect id="svg_95" x="4.5" y="12.5" width="2" height="2" fill="#a0a0a0" stroke="#555555"/>
<rect id="svg_96" x="4.5" y="5.5" width="2" height="2" fill="#a0a0a0" stroke="#555555"/>
</svg>
</g>
<g id="unlink_use">
<svg width="222" height="222" xmlns="http://www.w3.org/2000/svg">
<path id="svg_1" d="m93.75,118.44922c-4.5,13.58447 -14.66553,11.5 -28.25,11.5l-34,0c-13.58447,0 -24.5,-7.16553 -24.5,-21.5c0,-14.33447 10.91553,-20.5 24.5,-20.5l34,0c13.58447,0 19.75,-2.33447 26.5,10.75" stroke-width="13" stroke="#3f3f3f" fill="none"/>
<g id="svg_11">
<line id="svg_4" y2="65.94563" x2="83.07683" y1="28.27895" x1="45.41017" stroke-linecap="round" stroke-width="8" stroke="#007fff" fill="none"/>
<line id="svg_5" y2="15.01293" x2="109.41467" y1="65.94638" x1="109.41467" stroke-linecap="round" stroke-width="8" stroke="#007fff" fill="none"/>
<line id="svg_6" y2="29.31928" x2="177.58937" y1="65.94638" x1="140.96227" stroke-linecap="round" stroke-width="8" stroke="#007fff" fill="none"/>
</g>
<g id="svg_12" transform="rotate(-180, 108, 172.111)">
<line y2="190.94563" x2="79.57683" y1="153.27895" x1="41.91017" stroke-linecap="round" stroke-width="8" stroke="#007fff" fill="none" id="svg_13"/>
<line y2="140.01293" x2="105.91467" y1="190.94638" x1="105.91467" stroke-linecap="round" stroke-width="8" stroke="#007fff" fill="none" id="svg_14"/>
<line y2="154.31928" x2="174.08937" y1="190.94638" x1="137.46227" stroke-linecap="round" stroke-width="8" stroke="#007fff" fill="none" id="svg_15"/>
</g>
<path transform="rotate(-180, 172.125, 108.926)" id="svg_2" d="m215.5,118.44901c-4.5,13.58499 -14.6655,11.5 -28.25,11.5l-34,0c-13.5845,0 -24.5,-7.16501 -24.5,-21.5c0,-14.3343 10.9155,-20.4998 24.5,-20.4998l34,0c13.5845,0 19.75,-2.3345 26.5,10.75" stroke-width="13" stroke="#3f3f3f" fill="none"/>
</svg>
</g>
<g id="width">
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<path id="svg_6" d="m19,42.5l-7.5,7.5l7.5,7.5l0,-15zm0,7.5l62,0l0,-7.5l7.5,7.5l-7.5,7.5l0,-7.5" stroke-width="8" stroke="#000000" fill="#000000"/>
</svg>
</g>
<g id="height">
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<path transform="rotate(90, 50, 50)" fill="#000000" stroke="#000000" stroke-width="8" d="m19,42.5l-7.5,7.5l7.5,7.5l0,-15zm0,7.5l62,0l0,-7.5l7.5,7.5l-7.5,7.5l0,-7.5" id="svg_6"/>
</svg>
</g>
<g id="c_radius">
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg">
<rect stroke="#404040" fill="none" stroke-width="0.5" x="2.37501" y="2.4375" width="43.9375" height="43.9375" id="svg_1" rx="13" ry="13"/>
<path fill="none" stroke="#000000" d="m2.43674,15.88952l13.73722,0l0.08978,-13.46483m0.08978,14.08493" id="svg_3"/>
<line fill="none" stroke="#000000" x1="16.35107" y1="15.88934" x2="5.20504" y2="5.20504" id="svg_4" stroke-dasharray="2,2"/>
</svg>
</g>
<g id="angle">
<svg width="50" height="50" xmlns="http://www.w3.org/2000/svg">
<path stroke-width="2" stroke-dasharray="1,3" id="svg_6" d="m32.78778,41.03469c-0.40379,-8.68145 -4.50873,-16.79003 -12.11365,-20.5932" stroke="#000000" fill="none"/>
<path id="svg_7" d="m29.20348,7.67055l-24.20348,34.47921l41.16472,0" stroke-width="3" stroke="#404040" fill="none"/>
</svg>
</g>
<g id="blur">
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<defs>
<filter id="svg_4_blur" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="25"/>
</filter>
</defs>
<circle fill="#000000" stroke="#000000" stroke-width="5" stroke-dasharray="null" cx="150" cy="150" r="91.80151" id="svg_4" filter="url(#svg_4_blur)"/>
</svg>
</g>
<g id="fontsize">
<svg width="50" height="50" xmlns="http://www.w3.org/2000/svg">
<text fill="#606060" stroke="none" x="14.451" y="41.4587" id="svg_2" font-size="26" font-family="serif" text-anchor="middle">T</text>
<text fill="#000000" stroke="none" x="28.853" y="41.8685" font-size="52" font-family="serif" text-anchor="middle" xml:space="preserve" id="svg_3">T</text>
</svg>
</g>
<g id="align">
<svg width="22" height="22" xmlns="http://www.w3.org/2000/svg">
<rect stroke="#606060" fill="#c0c0c0" id="svg_4" height="7" width="12" y="7.5" x="4.5"/>
<rect stroke="#c15909" fill="#ef9a23" id="svg_2" height="40" width="2" y="-10" x="9.5"/>
<rect stroke="#ffffff" fill="none" id="svg_5" height="5" width="10" y="8.5" x="5.5"/>
</svg>
</g>
<g id="align_left">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
<rect stroke="#606060" fill="#ffffff" id="svg_4" height="7" width="12" y="2.5" x="2.5"/>
<rect stroke="none" fill="#c0c0c0" id="svg_5" height="4" width="11" y="4" x="2"/>
<rect id="svg_6" stroke="#606060" fill="#ffffff" height="7" width="18" y="12.5" x="2.5"/>
<rect id="svg_7" stroke="none" fill="#c0c0c0" height="4" width="17" y="14" x="2"/>
<rect stroke="#c15909" fill="#ef9a23" id="svg_2" height="40" width="2" y="-10" x="1.5"/>
</svg>
</g>
<g id="align_center">
<svg viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="1.5" y="12.5" width="18" height="7" fill="#c0c0c0" stroke="#606060" id="svg_6"/>
<rect x="4.5" y="2.5" width="12" height="7" id="svg_4" fill="#c0c0c0" stroke="#606060"/>
<rect x="9.5" y="-10" width="2" height="40" id="svg_2" fill="#ef9a23" stroke="#c15909"/>
<rect x="2.5" y="13.5" width="16" height="5" fill="none" stroke="#ffffff" id="svg_7"/>
<rect x="5.5" y="3.5" width="10" height="5" id="svg_5" fill="none" stroke="#ffffff"/>
</svg>
</g>
<g id="align_right">
<svg viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="7.5" y="2.5" width="12" height="7" id="svg_4" fill="#ffffff" stroke="#606060"/>
<rect x="9" y="4" width="11" height="4" id="svg_5" fill="#c0c0c0" stroke="none"/>
<rect x="1.5" y="12.5" width="18" height="7" fill="#ffffff" stroke="#606060" id="svg_6"/>
<rect x="3" y="14" width="17" height="4" fill="#c0c0c0" stroke="none" id="svg_7"/>
<rect x="18.5" y="-10" width="2" height="40" id="svg_2" fill="#ef9a23" stroke="#c15909"/>
</svg>
</g>
<g id="align_top">
<svg viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="rotate(90, 11, 11)" id="svg_1">
<rect x="2.5" y="3.5" width="12" height="7" id="svg_4" fill="#ffffff" stroke="#606060"/>
<rect x="2" y="5" width="11" height="4" id="svg_5" fill="#c0c0c0" stroke="none"/>
<rect x="2.5" y="13.5" width="18" height="7" fill="#ffffff" stroke="#606060" id="svg_6"/>
<rect x="2" y="15" width="17" height="4" fill="#c0c0c0" stroke="none" id="svg_7"/>
<rect x="1.5" y="-9" width="2" height="40" id="svg_2" fill="#ef9a23" stroke="#c15909"/>
</g>
</svg>
</g>
<g id="align_middle">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
<g transform="rotate(90, 12, 11.5)" id="svg_1">
<rect id="svg_6" stroke="#606060" fill="#c0c0c0" height="7" width="18" y="14" x="3"/>
<rect stroke="#606060" fill="#c0c0c0" id="svg_4" height="7" width="12" y="4" x="6"/>
<rect stroke="#c15909" fill="#ef9a23" id="svg_2" height="40" width="2" y="-8.5" x="11"/>
<rect id="svg_7" stroke="#ffffff" fill="none" height="5" width="16" y="15" x="4"/>
<rect stroke="#ffffff" fill="none" id="svg_5" height="5" width="10" y="5" x="7"/>
</g>
</svg>
</g>
<g id="align_bottom">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
<g transform="rotate(90, 11, 11)" id="svg_1">
<rect stroke="#606060" fill="#ffffff" id="svg_4" height="7" width="12" y="2.5" x="7.5"/>
<rect stroke="none" fill="#c0c0c0" id="svg_5" height="4" width="11" y="4" x="9"/>
<rect id="svg_6" stroke="#606060" fill="#ffffff" height="7" width="18" y="12.5" x="1.5"/>
<rect id="svg_7" stroke="none" fill="#c0c0c0" height="4" width="17" y="14" x="3"/>
<rect stroke="#c15909" fill="#ef9a23" id="svg_2" height="40" width="2" y="-10" x="18.5"/>
</g>
</svg>
</g>
<g id="linecap_butt">
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:se="http://svg-edit.googlecode.com" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<defs>
<linearGradient id="svg_8" x1="0.8" y1="1" x2="0.2" y2="1">
<stop offset="0" stop-color="#000000" stop-opacity="1"/>
<stop offset="1" stop-color="#000000" stop-opacity="0"/>
</linearGradient>
</defs>
<g>
<rect fill="url(#svg_8)" stroke="#a0a0a0" stroke-width="2" x="-15.20196" y="43.5974" width="94.8373" height="50.3728" id="svg_3" transform="rotate(-45, 32.2148, 68.7832)"/>
<path id="svg_1" d="m6.63133,95.07755l59.17514,-59.17514" stroke-width="3" stroke="#00ffff" fill="none"/>
<path id="svg_2" d="m51.62893,36.10742l13.05662,-13.05662l13.05661,13.05662l-13.05661,13.05662l-13.05662,-13.05662z" stroke="none" fill="#00ffff"/>
</g>
</svg>
</g>
<g id="linecap_square">
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:se="http://svg-edit.googlecode.com" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<defs>
<linearGradient id="svg_8" x1="0.8" y1="1" x2="0.2" y2="1">
<stop offset="0" stop-color="#000000" stop-opacity="1"/>
<stop offset="1" stop-color="#000000" stop-opacity="0"/>
</linearGradient>
</defs>
<g>
<rect fill="url(#svg_8)" stroke="none" x="-18.51568" y="35.5974" width="117.46469" height="50.3728" id="svg_3" transform="rotate(-45, 40.2168, 60.7832)"/>
<path id="svg_1" d="m6.63133,95.07755l59.17514,-59.17514" stroke-width="3" stroke="#00ffff" fill="none"/>
<path id="svg_2" d="m51.62893,36.10742l13.05662,-13.05662l13.05661,13.05662l-13.05661,13.05662l-13.05662,-13.05662z" stroke="none" fill="#00ffff"/>
</g>
</svg>
</g>
<g id="linecap_round">
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:se="http://svg-edit.googlecode.com">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<defs>
<linearGradient y2="1" x2="0.2" y1="1" x1="0.8" id="svg_8">
<stop stop-opacity="1" stop-color="#000000" offset="0"/>
<stop stop-opacity="0" stop-color="#000000" offset="1"/>
</linearGradient>
</defs>
<g>
<path transform="rotate(-45, 41.5117, 59.4648)" id="svg_3" d="m-19.0679,34.2946l94.8359,0c36.499,-1.4142 33.67101,48.9569 0,50.3711l-94.8359,0l0,-50.3711z" stroke-width="2" stroke="#a0a0a0" fill="url(#svg_8)"/>
<path id="svg_1" d="m6.63133,95.07755l59.17515,-59.17515" stroke-width="3" stroke="#00ffff" fill="none"/>
<path id="svg_2" d="m51.62893,36.10742l13.05662,-13.05662l13.05661,13.05662l-13.05661,13.05662l-13.05662,-13.05662z" stroke="none" fill="#00ffff"/>
</g>
</svg>
</g>
<g id="linejoin_miter">
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:se="http://svg-edit.googlecode.com">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<defs>
<linearGradient y2="1" x2="0.2" y1="1" x1="0.8" id="svg_8">
<stop stop-opacity="1" stop-color="#000000" offset="0"/>
<stop stop-opacity="0" stop-color="#000000" offset="1"/>
</linearGradient>
</defs>
<g>
<path fill="none" stroke="url(#svg_8)" stroke-width="49" d="m-15,-35l75,85l-75,75" id="svg_6"/>
<path transform="rotate(90, 57.8925, 50.2519)" fill="#00ffff" stroke="none" d="m44.83592,50.25187l13.05661,-13.05663l13.05661,13.05663l-13.05661,13.05662l-13.05661,-13.05662z" id="svg_2"/>
<path id="svg_4" d="m-15,-35l75,85l-75,75" stroke-width="3" stroke="#00ffff" fill="none"/>
</g>
</svg>
</g>
<g id="linejoin_bevel">
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:se="http://svg-edit.googlecode.com">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<defs>
<linearGradient y2="1" x2="0.2" y1="1" x1="0.8" id="svg_8">
<stop stop-opacity="1" stop-color="#000000" offset="0"/>
<stop stop-opacity="0" stop-color="#000000" offset="1"/>
</linearGradient>
</defs>
<g>
<path stroke-linejoin="bevel" fill="none" stroke="url(#svg_8)" stroke-width="49" d="m-15,-35l75,85l-75,75" id="svg_6"/>
<path transform="rotate(90, 57.8925, 50.2519)" fill="#00ffff" stroke="none" d="m44.83592,50.25187l13.05661,-13.05663l13.05661,13.05663l-13.05661,13.05662l-13.05661,-13.05662z" id="svg_2"/>
<path id="svg_4" d="m-15,-35l75,85l-75,75" stroke-width="3" stroke="#00ffff" fill="none"/>
</g>
</svg>
</g>
<g id="linejoin_round">
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:se="http://svg-edit.googlecode.com">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<defs>
<linearGradient y2="1" x2="0.2" y1="1" x1="0.8" id="svg_8">
<stop stop-opacity="1" stop-color="#000000" offset="0"/>
<stop stop-opacity="0" stop-color="#000000" offset="1"/>
</linearGradient>
</defs>
<g>
<path stroke-linejoin="round" fill="none" stroke="url(#svg_8)" stroke-width="49" d="m-15,-35l75,85l-75,75" id="svg_6"/>
<path transform="rotate(90, 57.8925, 50.2519)" fill="#00ffff" stroke="none" d="m44.83592,50.25187l13.05661,-13.05663l13.05661,13.05663l-13.05661,13.05662l-13.05661,-13.05662z" id="svg_2"/>
<path id="svg_4" d="m-15,-35l75,85l-75,75" stroke-width="3" stroke="#00ffff" fill="none"/>
</g>
</svg>
</g>
<g id="eye">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17 17">
<defs>
<linearGradient y2="0.79688" x2="0.5625" y1="0.19141" x1="0.42969" id="svg_91">
<stop stop-opacity="1" stop-color="#d3a16b" offset="0"/>
<stop stop-opacity="1" stop-color="#a37c53" offset="1"/>
</linearGradient>
</defs>
<path stroke="none" fill="url(#svg_91)" id="svg_9" d="m0.12852,8.18338c3.59931,-7.71208 13.19749,-7.36932 16.75236,0.08569c-3.02165,7.5407 -13.59741,7.66924 -16.75236,-0.08569z"/>
<path id="svg_76" stroke="none" fill="#ffffff" d="m0.33033,8.2557c3.5173,-4.97159 12.89675,-4.75063 16.37062,0.05524c-2.95279,4.86111 -13.28756,4.94397 -16.37062,-0.05524z"/>
<circle stroke="none" fill="#4f92c1" id="svg_88" r="3.08008" cy="7.71116" cx="8.45861"/>
<circle stroke="none" fill="#000000" id="svg_89" r="1.27539" cy="7.6539" cx="8.43159"/>
</svg>
</g>
<g id="no_color">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<line fill="none" stroke="#d40000" id="svg_90" y2="24" x2="24" y1="0" x1="0"/>
<line id="svg_92" fill="none" stroke="#d40000" y2="24" x2="0" y1="0" x1="24"/>
</svg>
</g>
<g id="ok">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<defs>
<linearGradient y2="0.65625" x2="0.94141" y1="0.43359" x1="0.42969" id="svg_106">
<stop stop-opacity="1" stop-color="#38ff45" offset="0"/>
<stop stop-opacity="1" stop-color="#127c0c" offset="1"/>
</linearGradient>
</defs>
<path transform="rotate(45, 12, 10)" stroke="#005500" fill="url(#svg_106)" id="svg_101" d="m7.9,15.9l4.9,-0.05l0,-13.75l3.8,0l0,17.6l-8.7,0l0,-3.8z"/>
</svg>
</g>
<g id="cancel">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<defs>
<linearGradient y2="0.65625" x2="0.94141" y1="0.43359" x1="0.42969" id="svg_9">
<stop stop-opacity="1" stop-color="#ff3838" offset="0"/>
<stop stop-opacity="1" stop-color="#7a0c0c" offset="1"/>
</linearGradient>
</defs>
<path stroke="#550000" fill="url(#svg_9)" id="svg_101" d="m2.10526,10.52632l7.36842,0l0,-7.36842l3.68421,0l0,7.36842l7.36842,0l0,3.68421l-7.36842,0l0,7.36842l-3.68421,0l0,-7.36842l-7.36842,0l0,-3.68421z" transform="rotate(45, 11.3, 12.3)"/>
</svg>
</g>
<g id="warning">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<defs>
<linearGradient y2="0.98047" x2="0.57813" y1="0.44922" x1="0.56641" id="svg_110">
<stop stop-opacity="1" stop-color="#ffff00" offset="0"/>
<stop stop-opacity="1" stop-color="#9e9e00" offset="1"/>
</linearGradient>
</defs>
<path d="m1.42857,21.55559l10.71429,-19.36489l10.71429,19.20352l-21.42857,0.16137z" id="svg_44" fill="url(#svg_110)" stroke="#916d1f" stroke-width="2"/>
<path stroke="none" fill="#000000" id="svg_103" d="m11.98371,14.68571c-0.57143,-3.82857 -1.82857,-6.4 0.11429,-6.4c2.11429,0 0.74286,2.57143 0.11429,6.4l-0.22857,0z"/>
<circle stroke="none" fill="#000000" id="svg_104" r="1.17578" cy="17.37143" cx="12.14308"/>
</svg>
</g>
<g id="node_delete">
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
<path stroke-width="2" id="svg_102" d="m4.1953,19.42128c15.49391,-15.53349 -0.21065,0.1581 15.61084,-15.57944" stroke="#8dd35f" fill="none"/>
<circle stroke-width="0.5" id="svg_121" stroke="#0000ff" fill="#00ffff" r="2.26172" cy="4" cx="19.75"/>
<circle id="svg_123" stroke-width="0.5" stroke="#0000ff" fill="#00ffff" r="2.26172" cy="19.40299" cx="4.0653"/>
<circle id="svg_7" stroke-width="0.5" stroke="#0000ff" fill="#00ffff" r="2.26172" cy="11.625" cx="11.9375"/>
<g transform="rotate(-45.291072845458984 9.81157112121582,9.244086265563965) " id="svg_6">
<line stroke-linecap="round" id="svg_4" y2="9.45264" x2="15.14996" y1="9.3943" x1="4.47318" stroke-dasharray="null" stroke-width="2" stroke="#ff0000" fill="none"/>
<line stroke-linecap="round" id="svg_5" y2="14.46579" x2="9.66571" y1="4.02238" x1="9.7824" stroke-dasharray="null" stroke-width="2" stroke="#ff0000" fill="none"/>
</g>
</svg>
</g>
<g id="node_clone">
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
<path stroke-width="2" id="svg_102" d="m4.1953,19.42128c15.49391,-15.53349 -0.21065,0.1581 15.61084,-15.57944" stroke="#8dd35f" fill="none"/>
<circle stroke-width="0.5" id="svg_121" stroke="#0000ff" fill="#00ffff" r="2.26172" cy="4" cx="19.75"/>
<circle id="svg_123" stroke-width="0.5" stroke="#0000ff" fill="#00ffff" r="2.26172" cy="19.40299" cx="4.0653"/>
<circle id="svg_7" stroke-width="0.5" stroke="#0000ff" fill="#00ffff" r="2.26172" cy="11.625" cx="11.9375"/>
<line stroke-linecap="round" id="svg_5" y2="14.46579" x2="9.66571" y1="4.02238" x1="9.7824" stroke-dasharray="null" stroke-width="2" stroke="#0000ff" fill="#0000ff"/>
<line stroke-linecap="round" id="svg_4" y2="9.45264" x2="15.14996" y1="9.3943" x1="4.47318" stroke-dasharray="null" stroke-width="2" stroke="#0000ff" fill="#0000ff"/>
</svg>
</g>
<g id="globe_link">
<svg width="66" height="66" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="svg_8" spreadMethod="pad" cx="0.5" cy="0.32513">
<stop stop-color="#7791ef" stop-opacity="0.99219" offset="0"/>
<stop stop-color="#3c3cfc" offset="1"/>
</radialGradient>
<linearGradient id="svg_10" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#333333" stop-opacity="0.99609"/>
<stop offset="1" stop-opacity="0.99609" stop-color="#666666"/>
</linearGradient>
</defs>
<g>
<g opacity="0.8" id="svg_5">
<circle id="svg_1" r="27.90625" cy="33" cx="33" stroke-width="0" stroke="#AAAAAA" fill="url(#svg_8)"/>
<g id="svg_7">
<path d="m38.2478,36.06121c-0.43732,0 -0.87463,0 -1.31195,0c-0.43731,0 -0.87463,0 -2.6239,0c-0.87463,0 -1.74926,0 -2.18658,0c-0.43732,0 -2.19828,0.33684 -2.6239,0.43732c-0.95172,0.22467 -1.27098,0.48253 -1.74927,0.87463c-1.21939,0.99965 -1.44004,1.00272 -1.74926,1.31195c-0.30923,0.30923 -0.21265,0.79756 -0.43732,1.74926c-0.10048,0.42562 0.16736,0.90792 0,1.31195c-0.23668,0.57138 -0.43732,0.87463 -0.43732,1.74926c0,0.43732 0.12809,0.56541 0.43732,0.87463c0.30923,0.30923 0.12809,0.56541 0.43732,0.87463c0.30923,0.30923 1.32364,0.77415 1.74926,0.87463c0.95171,0.22467 0.69349,0.69349 1.31195,1.31195c0.30923,0.30923 0.90791,-0.16736 1.31195,0c0.57138,0.23668 0.56541,0.56541 0.87463,0.87463c0.30923,0.30923 0.56541,0.12809 0.87463,0.43732c0.61846,0.61846 -0.10048,1.32365 0,1.74926c0.22467,0.95171 0.43732,1.31195 0.43732,2.6239c0,0.87463 0,2.18658 0,3.06121c0,0.43732 0,1.31195 0,2.6239c0,0.43732 0.12809,1.00272 0.43732,1.31195c0.30922,0.30923 1.31195,0 1.74926,0c0.87463,0 1.31195,0 1.74927,0c0.43731,0 0.6065,-0.40129 1.74926,-0.87464c0.40403,-0.16736 0.74057,-0.20064 1.31195,-0.43732c0.40403,-0.16736 0.63795,-0.74057 0.87463,-1.31195c0.16736,-0.40403 0.15712,-2.20917 0.43732,-3.93585c0.22151,-1.36505 0.43732,-2.18658 0.43732,-2.6239c0,-0.43732 -0.12928,-0.88101 0,-2.18658c0.21973,-2.21904 0.43732,-3.49853 0.43732,-3.93585c0,-0.43732 0,-0.87463 0,-1.74927c0,-1.31195 0.16736,-1.78254 0,-2.18658c-0.23668,-0.57138 -1.00272,-0.56541 -1.31195,-0.87463c-0.30923,-0.30922 -0.43732,-0.43731 -1.74926,-1.74926l0,-0.87463l-0.43732,0l0,-0.43732" id="svg_2" stroke="#007f00" fill="#44b544" stroke-width="0"/>
<path d="m5.66773,37.0452c1.12973,-0.3645 0.87463,-0.2187 1.74927,-0.656c0.87463,-0.4373 1.34081,-0.8211 2.18658,-1.3119c1.36372,-0.7915 1.44002,-1.4401 1.74922,-1.7493c0.3093,-0.3092 0.1281,-0.5654 0.4374,-0.8746c0.6184,-0.6185 0.8746,-0.4374 1.7492,-1.312c0.8747,-0.8746 1.0027,-1.0027 1.312,-1.3119c0.6184,-0.6185 0.1281,-1.0028 0.4373,-1.312c0.3092,-0.3092 0,-0.8746 0,-1.3119c0,-0.4374 0,-1.312 0,-1.7493c0,-0.4373 0.2009,-1.7727 0,-2.6239c-0.2247,-0.9517 -0.1281,-1.4401 -0.4373,-1.7493c-0.3093,-0.3092 -0.7073,-1.3452 -0.8746,-1.7492c-0.2367,-0.5714 -0.8747,-0.8747 -0.8747,-1.312c0,-0.4373 -0.4373,-0.4373 -0.4373,-0.8746l0,-0.4374l-1.2026,-0.8746c-3.7901,5.8674 -6.81486,11.6253 -5.79446,21.2099l-0.00001,0z" id="svg_3" stroke="#007f00" fill="#44b544" stroke-width="0"/>
<path d="m52.2419,13.1021c-0.4373,0.4373 -1.3495,0.8398 -2.1866,1.0933c-3.0182,0.9138 -3.2212,2.2857 -3.4985,2.6239c-1.4137,1.7245 -2.4979,1.3039 -4.8105,1.7493c-0.4294,0.0827 -0.4373,0.4373 -0.8746,0.4373c-0.4373,0 -0.8746,0 -1.312,0c-0.4373,0 -1.3119,0 -1.7492,0c-0.4373,0 -1.3453,-0.27 -1.7493,-0.4373c-0.5714,-0.2367 -0.5654,-0.5654 -0.8746,-0.8747c-0.3092,-0.3092 -0.5654,-0.1281 -0.8746,-0.4373c-0.3093,-0.3092 -0.8747,0 -1.312,0c-0.4373,0 -0.9079,-0.1673 -1.3119,0c-0.5714,0.2367 -0.3033,1.0753 -0.8747,1.312c-0.404,0.1673 -0.1281,0.5654 -0.4373,0.8746c-0.3092,0.3092 -0.4373,0.4373 -0.4373,0.8746c0,0.4373 0,0.8747 0,1.312c0,0.4373 0.0333,0.7073 0.4373,0.8746c0.5714,0.2367 0.638,0.7406 0.8746,1.312c0.1674,0.404 0.4374,0.4373 0.4374,0.8746c0,0.4373 0,0.8746 0,1.3119c0,0.4374 -0.4374,0.4374 -0.8747,0.8747c-1.3119,1.3119 -1.9499,1.1779 -2.1865,1.7492c-0.1674,0.4041 -1.0753,0.3033 -1.312,0.8747c-0.1674,0.404 0,0.8746 0.4373,0.8746c0.4373,0 0.8746,0.4373 1.312,0.4373c0.4373,0 0.8746,-0.4373 1.3119,-0.4373c0.4373,0 0.5654,-0.1281 0.8746,-0.4373c0.6185,-0.6185 1.312,0 1.7493,0c0.4373,0 0.397,-0.6543 2.1866,-0.8747c0.434,-0.0534 2.8801,-0.2561 3.4985,-0.8746c0.3093,-0.3092 0.8343,-0.6543 2.6239,-0.8746c0.4341,-0.0535 0.8747,0 1.312,0c0.4373,0 0.8746,0.4373 0.8746,0.8746c0,0.4373 0.4373,0.4373 0.4373,0.8746c0,0.4374 0.5654,2.3147 0.8746,2.6239c0.3093,0.3093 0.1281,1.0028 0.4374,1.312c0.3092,0.3092 2.1095,2.8366 3.0612,3.0612c0.4256,0.1005 0.8215,0.2158 2.1866,0.4373c0.4316,0.0701 1.3119,0 1.7492,0c0.4373,0 0.8864,0.1005 1.312,0c0.9517,-0.2246 1.44,-0.5654 1.7492,-0.8746c0.3093,-0.3092 0.8747,-0.4373 1.312,-0.4373c0.4373,0 0.5654,-0.5654 0.8746,-0.8746c0.3092,-0.3093 0.8746,0 1.312,0l1.0933,-0.656c1.1661,-7.7259 -2.4782,-14.1399 -7.6531,-20.5539l0,0z" id="svg_4" stroke="#007f00" fill="#44b544" stroke-width="0"/>
<path id="svg_6" d="m10.0409,48.3061c2.1137,-0.2187 4.6647,-0.2187 6.3411,1.9679c1.1662,1.5306 1.239,3.7172 0.2186,4.5918c-2.4052,-0.8746 -5.0291,-2.6239 -6.5597,-6.5597l0,0z" stroke="#007f00" fill="#44b544" stroke-width="0"/>
</g>
</g>
<rect transform="rotate(45, 16.9336, 16.9375)" ry="9" rx="9" id="svg_9" height="19.32339" width="29.34293" y="7.27574" x="2.26257" stroke-width="5" stroke="url(#svg_10)" fill="none" stroke-linecap="round"/>
<rect id="svg_11" transform="rotate(45, 49.0664, 49.0625)" ry="9" rx="9" height="19.32339" width="29.34293" y="39.40074" x="34.39538" stroke-width="5" stroke="url(#svg_10)" fill="none" stroke-linecap="round"/>
<line id="svg_12" y2="45.75" x2="45.75" y1="20.25" x1="20.25" stroke-linecap="round" stroke-width="5" stroke="url(#svg_10)" fill="none"/>
</g>
</svg>
</g>
<g id="svg_eof"/>
</svg>
diff --git a/desuto-viewer/Desuto-webviewer/public/js/FileSaver.js b/desuto-viewer/Desuto-webviewer/public/js/FileSaver.js
new file mode 100644
index 0000000..da8d6ef
--- /dev/null
+++ b/desuto-viewer/Desuto-webviewer/public/js/FileSaver.js
@@ -0,0 +1,184 @@
+(function (global, factory) {
+ if (typeof define === "function" && define.amd) {
+ define([], factory);
+ } else if (typeof exports !== "undefined") {
+ factory();
+ } else {
+ var mod = {
+ exports: {}
+ };
+ factory();
+ global.FileSaver = mod.exports;
+ }
+})(this, function () {
+ "use strict";
+
+ /*
+ * FileSaver.js
+ * A saveAs() FileSaver implementation.
+ *
+ * By Eli Grey, http://eligrey.com
+ *
+ * License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
+ * source : http://purl.eligrey.com/github/FileSaver.js
+ */
+ // The one and only way of getting global scope in all environments
+ // https://stackoverflow.com/q/3277182/1008999
+ var _global = typeof window === 'object' && window.window === window ? window : typeof self === 'object' && self.self === self ? self : typeof global === 'object' && global.global === global ? global : void 0;
+
+ function bom(blob, opts) {
+ if (typeof opts === 'undefined') opts = {
+ autoBom: false
+ };else if (typeof opts !== 'object') {
+ console.warn('Deprecated: Expected third argument to be a object');
+ opts = {
+ autoBom: !opts
+ };
+ } // prepend BOM for UTF-8 XML and text/* types (including HTML)
+ // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
+
+ if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
+ return new Blob([String.fromCharCode(0xFEFF), blob], {
+ type: blob.type
+ });
+ }
+
+ return blob;
+ }
+
+ function download(url, name, opts) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', url);
+ xhr.responseType = 'blob';
+
+ xhr.onload = function () {
+ saveAs(xhr.response, name, opts);
+ };
+
+ xhr.onerror = function () {
+ console.error('could not download file');
+ };
+
+ xhr.send();
+ }
+
+ function corsEnabled(url) {
+ var xhr = new XMLHttpRequest(); // use sync to avoid popup blocker
+
+ xhr.open('HEAD', url, false);
+
+ try {
+ xhr.send();
+ } catch (e) {}
+
+ return xhr.status >= 200 && xhr.status <= 299;
+ } // `a.click()` doesn't work for all browsers (#465)
+
+
+ function click(node) {
+ try {
+ node.dispatchEvent(new MouseEvent('click'));
+ } catch (e) {
+ var evt = document.createEvent('MouseEvents');
+ evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
+ node.dispatchEvent(evt);
+ }
+ }
+
+ var saveAs = _global.saveAs || ( // probably in some web worker
+ typeof window !== 'object' || window !== _global ? function saveAs() {}
+ /* noop */
+ // Use download attribute first if possible (#193 Lumia mobile)
+ : 'download' in HTMLAnchorElement.prototype ? function saveAs(blob, name, opts) {
+ var URL = _global.URL || _global.webkitURL;
+ var a = document.createElement('a');
+ name = name || blob.name || 'download';
+ a.download = name;
+ a.rel = 'noopener'; // tabnabbing
+ // TODO: detect chrome extensions & packaged apps
+ // a.target = '_blank'
+
+ if (typeof blob === 'string') {
+ // Support regular links
+ a.href = blob;
+
+ if (a.origin !== location.origin) {
+ corsEnabled(a.href) ? download(blob, name, opts) : click(a, a.target = '_blank');
+ } else {
+ click(a);
+ }
+ } else {
+ // Support blobs
+ a.href = URL.createObjectURL(blob);
+ setTimeout(function () {
+ URL.revokeObjectURL(a.href);
+ }, 4E4); // 40s
+
+ setTimeout(function () {
+ click(a);
+ }, 0);
+ }
+ } // Use msSaveOrOpenBlob as a second approach
+ : 'msSaveOrOpenBlob' in navigator ? function saveAs(blob, name, opts) {
+ name = name || blob.name || 'download';
+
+ if (typeof blob === 'string') {
+ if (corsEnabled(blob)) {
+ download(blob, name, opts);
+ } else {
+ var a = document.createElement('a');
+ a.href = blob;
+ a.target = '_blank';
+ setTimeout(function () {
+ click(a);
+ });
+ }
+ } else {
+ navigator.msSaveOrOpenBlob(bom(blob, opts), name);
+ }
+ } // Fallback to using FileReader and a popup
+ : function saveAs(blob, name, opts, popup) {
+ // Open a popup immediately do go around popup blocker
+ // Mostly only available on user interaction and the fileReader is async so...
+ popup = popup || open('', '_blank');
+
+ if (popup) {
+ popup.document.title = popup.document.body.innerText = 'downloading...';
+ }
+
+ if (typeof blob === 'string') return download(blob, name, opts);
+ var force = blob.type === 'application/octet-stream';
+
+ var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari;
+
+ var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
+
+ if ((isChromeIOS || force && isSafari) && typeof FileReader !== 'undefined') {
+ // Safari doesn't allow downloading of blob URLs
+ var reader = new FileReader();
+
+ reader.onloadend = function () {
+ var url = reader.result;
+ url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;');
+ if (popup) popup.location.href = url;else location = url;
+ popup = null; // reverse-tabnabbing #460
+ };
+
+ reader.readAsDataURL(blob);
+ } else {
+ var URL = _global.URL || _global.webkitURL;
+ var url = URL.createObjectURL(blob);
+ if (popup) popup.location = url;else location.href = url;
+ popup = null; // reverse-tabnabbing #460
+
+ setTimeout(function () {
+ URL.revokeObjectURL(url);
+ }, 4E4); // 40s
+ }
+ });
+ _global.saveAs = saveAs.saveAs = saveAs;
+
+ if (typeof module !== 'undefined') {
+ module.exports = saveAs;
+ }
+});
diff --git a/desuto-viewer/Desuto-webviewer/public/js/FileSaver.min.js b/desuto-viewer/Desuto-webviewer/public/js/FileSaver.min.js
new file mode 100644
index 0000000..183d42a
--- /dev/null
+++ b/desuto-viewer/Desuto-webviewer/public/js/FileSaver.min.js
@@ -0,0 +1,3 @@
+(function(a,b){if("function"==typeof define&&define.amd)define([],b);else if("undefined"!=typeof exports)b();else{b(),a.FileSaver={exports:{}}.exports}})(this,function(){"use strict";function b(a,b){return"undefined"==typeof b?b={autoBom:!1}:"object"!=typeof b&&(console.warn("Deprecated: Expected third argument to be a object"),b={autoBom:!b}),b.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a}function c(b,c,d){var e=new XMLHttpRequest;e.open("GET",b),e.responseType="blob",e.onload=function(){a(e.response,c,d)},e.onerror=function(){console.error("could not download file")},e.send()}function d(a){var b=new XMLHttpRequest;b.open("HEAD",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent("click"))}catch(c){var b=document.createEvent("MouseEvents");b.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0,a=f.saveAs||("object"!=typeof window||window!==f?function(){}:"download"in HTMLAnchorElement.prototype?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement("a");g=g||b.name||"download",j.download=g,j.rel="noopener","string"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target="_blank")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:"msSaveOrOpenBlob"in navigator?function(f,g,h){if(g=g||f.name||"download","string"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement("a");i.href=f,i.target="_blank",setTimeout(function(){e(i)})}}:function(a,b,d,e){if(e=e||open("","_blank"),e&&(e.document.title=e.document.body.innerText="downloading..."),"string"==typeof a)return c(a,b,d);var g="application/octet-stream"===a.type,h=/constructor/i.test(f.HTMLElement)||f.safari,i=/CriOS\/[\d]+/.test(navigator.userAgent);if((i||g&&h)&&"undefined"!=typeof FileReader){var j=new FileReader;j.onloadend=function(){var a=j.result;a=i?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),e?e.location.href=a:location=a,e=null},j.readAsDataURL(a)}else{var k=f.URL||f.webkitURL,l=k.createObjectURL(a);e?e.location=l:location.href=l,e=null,setTimeout(function(){k.revokeObjectURL(l)},4E4)}});f.saveAs=a.saveAs=a,"undefined"!=typeof module&&(module.exports=a)});
+
+//# sourceMappingURL=FileSaver.min.js.map
\ No newline at end of file
diff --git a/desuto-viewer/Desuto-webviewer/public/js/app-main.js b/desuto-viewer/Desuto-webviewer/public/js/app-main.js
index 370f902..4eb4f2e 100644
--- a/desuto-viewer/Desuto-webviewer/public/js/app-main.js
+++ b/desuto-viewer/Desuto-webviewer/public/js/app-main.js
@@ -1,684 +1,703 @@
/* jshint undef: false, curly: false, latedef: false */
/* Document ready execution */
/* Global "annotating" mode variable */
var annotating = false;
/* Default variables */
var initialOpacity = 33;
var tooltipOffset = 10;
var refMag = 40;
var oneXZoom;
var pixelsPerMeter = 0.5e6;
/* State variables */
var saving = false;
var aboveShape = false;
/* SVG Editor variables */
var canvas;
var svgEditContainer = "<div id='svg-overlay'>" +
- "<div id='svg_editor'>" +
- "<div id='workarea'>" +
- "<div id='svgcanvas'>" +
- "</div>" +
- "</div>" +
- "</div>" +
- "</div>";
+ "<div id='svg_editor'>" +
+ "<div id='workarea'>" +
+ "<div id='svgcanvas'>" +
+ "</div>" +
+ "</div>" +
+ "</div>" +
+ "</div>";
/* Define OpenSeadragon options */
var options = {
- id: "openseadragon",
- prefixUrl: "img/",
- showNavigator: true,
- zoomInButton: "zoom-in",
- zoomOutButton: "zoom-out",
- homeButton: "home",
- autoHideControls: false,
- minZoomImageRatio: 1,
- maxZoomPixelRatio: 1
+ id: "openseadragon",
+ prefixUrl: "img/",
+ showNavigator: true,
+ zoomInButton: "zoom-in",
+ zoomOutButton: "zoom-out",
+ homeButton: "home",
+ autoHideControls: false,
+ minZoomImageRatio: 1,
+ maxZoomPixelRatio: 1
};
/* Get currently edited image */
var image = getParameterByName("image");
/* If image is null, get default */
if (image === null || image === "")
- image = defaultImage;
+ image = defaultImage;
/* ID for CouchDB */
var id = image + "-" + annotator;
/* Viewer */
var viewer;
/* Viewer imagingHelper */
var imagingHelper;
/* Viewr inputHook */
var inputHook;
/* Feature viewer variables */
var featureViewer;
var featureImagingHelper;
/* Synchronize the 2 OpenSeadragon viewers */
function onImageViewChanged(event) {
- if (typeof featureImagingHelper !== "undefined" && featureImagingHelper !== null)
- featureImagingHelper.setView(event.viewportWidth, event.viewportHeight, event.viewportCenter, true);
+ if (typeof featureImagingHelper !== "undefined" && featureImagingHelper !== null)
+ featureImagingHelper.setView(event.viewportWidth, event.viewportHeight, event.viewportCenter, true);
}
/* Set Image for viewer */
function setImage(image, options) {
- options.tileSources = config.iipDeepZoomBaseURL + config.iipImageDir + image + config.iipSuffix;
+ options.tileSources = config.iipDeepZoomBaseURL + config.iipImageDir + image + config.iipSuffix;
}
/* Set Overlay for viewer */
function setOverlay(image, options) {
- options.tileSources = {
- type: 'image',
- url: '/' + image.replace(config.iipBaseDir, '')
- };
+ options.tileSources = {
+ type: 'image',
+ url: '/' + image.replace(config.iipBaseDir, '')
+ };
}
/* Toggle shorthand method */
function toggle() {
- annotating = !annotating;
- toggleEditor(annotating);
+ annotating = !annotating;
+ toggleEditor(annotating);
}
/* Toggle the editor between annotation and exploration */
function toggleEditor(annotating) {
- if (annotating) {
+ if (annotating) {
- // Highlight the fact that we are in annotating mode
- $("#openseadragon-container").css("border", "1px solid black");
- $("#locks").show();
+ // Highlight the fact that we are in annotating mode
+ $("#openseadragon-container").css("border", "1px solid black");
+ $("#locks").show();
- // Deselect any currently highlighted element
- $("svg g *[id^='svg_']").each(function(index, shape) {
- $(shape).attr("stroke-opacity", "1.0");
- });
- aboveShape = false;
- $("#annotation-tooltip").hide();
+ // Deselect any currently highlighted element
+ $("svg g *[id^='svg_']").each(function (index, shape) {
+ $(shape).attr("stroke-opacity", "1.0");
+ });
+ aboveShape = false;
+ $("#annotation-tooltip").hide();
- // Toggle toolbars
- $("#tools-viewer").hide();
- $("#tools-drawing-container").show();
+ // Toggle toolbars
+ $("#tools-viewer").hide();
+ $("#tools-drawing-container").show();
- $("#toggle-annotation").text("Stop Annotating");
+ $("#toggle-annotation").text("Stop Annotating");
- // Enable context menu
- $('#workarea').enableContextMenu();
+ // Enable context menu
+ $('#workarea').enableContextMenu();
- // Disable mouse navigation & navigator on viewer
- viewer.setMouseNavEnabled(false);
- $("#openseadragon .navigator").css("pointer-events", "none");
+ // Disable mouse navigation & navigator on viewer
+ viewer.setMouseNavEnabled(false);
+ $("#openseadragon .navigator").css("pointer-events", "none");
- // Select freehand tool
- $('#tool_fhpath').trigger('click');
+ // Select freehand tool
+ $('#tool_fhpath').trigger('click');
- } else {
+ } else {
- // Remove border and locks
- $("#openseadragon-container").css("border", "1px solid transparent");
- $("#locks").hide();
+ // Remove border and locks
+ $("#openseadragon-container").css("border", "1px solid transparent");
+ $("#locks").hide();
- // Toggle toolbars
- $("#tools-drawing-container").hide();
- $("#tools-viewer").show();
+ // Toggle toolbars
+ $("#tools-drawing-container").hide();
+ $("#tools-viewer").show();
- $("#toggle-annotation").text("Start Annotating");
+ $("#toggle-annotation").text("Start Annotating");
- // Disable context menu
- $('#workarea').disableContextMenu();
+ // Disable context menu
+ $('#workarea').disableContextMenu();
- // Enable mouse navigation & navigator on viewer
- viewer.setMouseNavEnabled(true);
- $("#openseadragon .navigator").css("pointer-events", "all");
+ // Enable mouse navigation & navigator on viewer
+ viewer.setMouseNavEnabled(true);
+ $("#openseadragon .navigator").css("pointer-events", "all");
- // Stop annotating specific steps
- // Pathologists only
- if (typeof svgEditor !== 'undefined') {
- svgEditor.canvas.clearSelection();
- svgEditor.canvas.pathActions.clear();
- }
+ // Stop annotating specific steps
+ // Pathologists only
+ if (typeof svgEditor !== 'undefined') {
+ svgEditor.canvas.clearSelection();
+ svgEditor.canvas.pathActions.clear();
}
+ }
- if (typeof change !== "undefined" && change)
- annotating = !annotating;
+ if (typeof change !== "undefined" && change)
+ annotating = !annotating;
}
// Synchronize with a remote CouchDB
function sync() {
- var opts = {
- live: true,
- retry: true
- };
-
- // Sync DBs
- db.sync(remoteCouch, opts)
- .on('error', function(err) {
- syncError();
- })
- .on('change', function(info) {
- console.log('pouchdb - changed : ' + JSON.stringify(info.change.docs.map((doc) => doc._id)))
- })
- .on('denied', function(info) {
- console.log('pouchdb - denied : ' + info)
- }).
- on('paused', function(err){
- $("#sync").hide();
- console.log('pouchdb - paused : ' + ((err) ? err : 'ok'))
- }).
- on('active', function(){
- //$("#sync").show();
- console.log('pouchdb - active')
- }).
- on('complete', function(info){
- console.log('pouchdb - complete : ' + info)
- });
-
- // Listen to changes
- db.changes({
- since: 'now',
- live: true,
- include_docs: true
- }).on('change', function(change){
-
- var reload = change.id == id;
-
- // Check if patch preview needs to be reloaded
- var reloadPatch = false
- if(typeof canvas !== 'undefined' && typeof canvas.getSelectedElems() !== 'undefined' && canvas.getSelectedElems().length === 1) {
- var selectedElement = svgEditor.canvas.getSelectedElems()[0];
- var changedElement = null;
-
- if(typeof selectedElement !== "undefined" && selectedElement != null){
- change.doc.annotations.forEach(function(annotation){
- if(selectedElement.id == annotation.attr.id) {
- changedElement = annotation;
- }
- });
-
- if(changedElement !== null){
- if(!compareObjects(changedElement, getJSONforSVG(selectedElement)))
- reloadPatch = true;
- }
- }
-
+ var opts = {
+ live: true,
+ retry: true
+ };
+
+ // Sync DBs
+ db.sync(remoteCouch, opts)
+ .on('error', function (err) {
+ syncError();
+ })
+ .on('change', function (info) {
+ console.log('pouchdb - changed : ' + JSON.stringify(info.change.docs.map((doc) => doc._id)))
+ })
+ .on('denied', function (info) {
+ console.log('pouchdb - denied : ' + info)
+ }).on('paused', function (err) {
+ $("#sync").hide();
+ console.log('pouchdb - paused : ' + ((err) ? err : 'ok'))
+ }).on('active', function () {
+ //$("#sync").show();
+ console.log('pouchdb - active')
+ }).on('complete', function (info) {
+ console.log('pouchdb - complete : ' + info)
+ });
+
+ // Listen to changes
+ db.changes({
+ since: 'now',
+ live: true,
+ include_docs: true
+ }).on('change', function (change) {
+
+ var reload = change.id == id;
+
+ // Check if patch preview needs to be reloaded
+ var reloadPatch = false
+ if (typeof canvas !== 'undefined' && typeof canvas.getSelectedElems() !== 'undefined' && canvas.getSelectedElems().length === 1) {
+ var selectedElement = svgEditor.canvas.getSelectedElems()[0];
+ var changedElement = null;
+
+ if (typeof selectedElement !== "undefined" && selectedElement != null) {
+ change.doc.annotations.forEach(function (annotation) {
+ if (selectedElement.id == annotation.attr.id) {
+ changedElement = annotation;
}
+ });
- if(reload){
- $("#sync").show();
- loadAnnotations(reloadPatch);
- }
+ if (changedElement !== null) {
+ if (!compareObjects(changedElement, getJSONforSVG(selectedElement)))
+ reloadPatch = true;
+ }
}
- );
+
+ }
+
+ if (reload) {
+ $("#sync").show();
+ loadAnnotations(reloadPatch);
+ }
+ }
+ );
}
// There was some form or error syncing to remote
function syncError() {
- console.log('error syncing db');
+ console.log('error syncing db');
}
// Load annotations
function loadAnnotations(reloadPatch) {
- // Remove elements
- //$("#svgcontent g [id]").remove();
-
- if (!saving) {
- // Get image's annotations
- db.get(id).then(function(doc) {
-
- if(doc.annotations){
- // Global method
- var annotations = doc.annotations;
- var annotationIDs = [];
- // Add / Update the SVG element
- $.each(annotations, function(index, annotation) {
-
- // Only load annotations of current user
- if(annotation.attr["histopatho-annotator"] === annotator){
- // Pathologists only
- if(typeof(canvas) !== 'undefined'){
- canvas.addSvgElementFromJson(annotation);
- } else {
- if( $("#svgcontent g #" + annotation.attr.id).length > 0){
- addSvgElementFromJsonSimple(annotation);
- }else{
- $("#svgcontent g").append(addSvgElementFromJsonSimple(annotation));
- }
- }
- }
-
- annotationIDs.push(annotation.attr.id);
-
- // Load annotation text
- if(typeof canvas !== 'undefined' && typeof canvas.getSelectedElems() !== 'undefined' && canvas.getSelectedElems().length === 1){
- var selectedElement = svgEditor.canvas.getSelectedElems()[0];
- if(typeof selectedElement !== 'undefined'
- && selectedElement !== null
- && selectedElement.getAttribute('id') === annotation.attr.id){
-
- $("#annotation").val(annotation.attr["histopatho-annotation"]);
-
- if(typeof reloadPatch !== "undefined" && reloadPatch)
- loadPatchPreview(selectedElement);
- }
- }
- });
-
- // Remove deleted elements
- $("#svgcontent g [id]").each(function(index) {
- var isThere = _.contains(annotationIDs, $(this).attr("id"));
- if (!isThere) {
- $(this).remove();
- }
- });
- // Update selectors
-
- // Pathologists only
- if(typeof(canvas) !== 'undefined' &&
- canvas.selectorManager !== null &&
- canvas.selectorManager.selectors !== null){
- $.each(canvas.selectorManager.selectors, function(index, element) {
- if(element.selectedElement !== null)
- element.resize();
- });
- }
+ // Remove elements
+ //$("#svgcontent g [id]").remove();
+
+ if (!saving) {
+ // Get image's annotations
+ db.get(id).then(function (doc) {
+
+ if (doc.annotations) {
+ // Global method
+ var annotations = doc.annotations;
+ var annotationIDs = [];
+ // Add / Update the SVG element
+ $.each(annotations, function (index, annotation) {
+
+ // Only load annotations of current user
+ if (annotation.attr["histopatho-annotator"] === annotator) {
+ // Pathologists only
+ if (typeof (canvas) !== 'undefined') {
+ canvas.addSvgElementFromJson(annotation);
+ } else {
+ if ($("#svgcontent g #" + annotation.attr.id).length > 0) {
+ addSvgElementFromJsonSimple(annotation);
+ } else {
+ $("#svgcontent g").append(addSvgElementFromJsonSimple(annotation));
+ }
+ }
+ }
+
+ annotationIDs.push(annotation.attr.id);
+
+ // Load annotation text
+ if (typeof canvas !== 'undefined' && typeof canvas.getSelectedElems() !== 'undefined' && canvas.getSelectedElems().length === 1) {
+ var selectedElement = svgEditor.canvas.getSelectedElems()[0];
+ if (typeof selectedElement !== 'undefined'
+ && selectedElement !== null
+ && selectedElement.getAttribute('id') === annotation.attr.id) {
+
+ $("#annotation").val(annotation.attr["histopatho-annotation"]);
+ if (typeof reloadPatch !== "undefined" && reloadPatch)
+ loadPatchPreview(selectedElement);
}
- }).catch(function(err) {
- console.log(err.stack);
+ }
});
- }
- saving = false;
+ // Remove deleted elements
+ $("#svgcontent g [id]").each(function (index) {
+ var isThere = _.contains(annotationIDs, $(this).attr("id"));
+ if (!isThere) {
+ $(this).remove();
+ }
+ });
+ // Update selectors
+
+ // Pathologists only
+ if (typeof (canvas) !== 'undefined' &&
+ canvas.selectorManager !== null &&
+ canvas.selectorManager.selectors !== null) {
+ $.each(canvas.selectorManager.selectors, function (index, element) {
+ if (element.selectedElement !== null)
+ element.resize();
+ });
+ }
+
+ }
+ }).catch(function (err) {
+ console.log(err.stack);
+ });
+ }
+
+ saving = false;
}
// Destroy feature viewer
function destroyFeatureViewer() {
- if (typeof featureViewer !== "undefined" && featureViewer !== null) {
- featureViewer.destroy();
- featureViewer = null;
- }
+ if (typeof featureViewer !== "undefined" && featureViewer !== null) {
+ featureViewer.destroy();
+ featureViewer = null;
+ }
}
// Load feature viewer
function loadFeatureViewer(feature) {
- // Activate correct LI
- $(".feature-link").removeClass("active");
- $(".feature-link[href=#" + feature + "]").addClass("active");
-
- // Did we select "none" ?
- if (feature === "none") {
- destroyFeatureViewer();
- return;
- }
-
- // Feature viewer options
- var featureOptions = {
- id: "openseadragon-features",
- //prefixUrl: "img/",
- showNavigator: false,
- showNavigationControl: false
- };
+ // Activate correct LI
+ $(".feature-link").removeClass("active");
+ $(".feature-link[href=#" + feature + "]").addClass("active");
- // Set image
- featureImageName = config.iipOverlaysDir + getParameterByName('image') + '/' + feature + config.iipFeatureImageExtension;
- setOverlay(featureImageName, featureOptions);
-
- // Destroy existing viewer
+ // Did we select "none" ?
+ if (feature === "none") {
destroyFeatureViewer();
-
- // Create viewer
- featureViewer = new OpenSeadragon(featureOptions);
- featureImagingHelper = featureViewer.activateImagingHelper();
-
- // Raise image changed event on open
- featureViewer.addHandler('open', function() {
- imagingHelper._raiseImageViewChanged();
- updateOpacity($("#feature-opacity").val());
- });
+ return;
+ }
+
+ // Feature viewer options
+ var featureOptions = {
+ id: "openseadragon-features",
+ //prefixUrl: "img/",
+ showNavigator: false,
+ showNavigationControl: false
+ };
+
+ // Set image
+ featureImageName = config.iipOverlaysDir + getParameterByName('image') + '/' + feature + config.iipFeatureImageExtension;
+ setOverlay(featureImageName, featureOptions);
+
+ // Destroy existing viewer
+ destroyFeatureViewer();
+
+ // Create viewer
+ featureViewer = new OpenSeadragon(featureOptions);
+ featureImagingHelper = featureViewer.activateImagingHelper();
+
+ // Raise image changed event on open
+ featureViewer.addHandler('open', function () {
+ imagingHelper._raiseImageViewChanged();
+ updateOpacity($("#feature-opacity").val());
+ });
}
// Update opacity and label
function updateOpacity(opacity) {
- $("#feature-opacity-label").text(opacity + "%");
- $("#openseadragon-features").css("opacity", opacity / 100);
+ $("#feature-opacity-label").text(opacity + "%");
+ $("#openseadragon-features").css("opacity", opacity / 100);
}
// Position tooltip next to cursor
function positionTooltip(x, y) {
- $("#annotation-tooltip").css({
- left: x + tooltipOffset + 'px',
- top: y + tooltipOffset + 'px'
- });
+ $("#annotation-tooltip").css({
+ left: x + tooltipOffset + 'px',
+ top: y + tooltipOffset + 'px'
+ });
}
/* Set the width of the side navigation to 250px */
function openNav(menu) {
- $('#' + menu).css('width', '300px');
+ $('#' + menu).css('width', '300px');
}
/* Set the width of the side navigation to 0 */
function closeNav(menu) {
- $('#' + menu).css('width', '0');
+ $('#' + menu).css('width', '0');
}
// On mouse hover over SVG element, log it to console
-$(document).on("mouseenter", "svg g *", function(event) {
- if (!annotating) {
- $(event.target).attr("stroke-opacity", "0.7");
- aboveShape = true;
+$(document).on("mouseenter", "svg g *", function (event) {
+ if (!annotating) {
+ $(event.target).attr("stroke-opacity", "0.7");
+ aboveShape = true;
- var annotationText = $(event.target).attr("histopatho-annotation");
- var annotatorText = "(" + $(event.target).attr("histopatho-annotator") + ")";
+ var annotationText = $(event.target).attr("histopatho-annotation");
+ var annotatorText = "(" + $(event.target).attr("histopatho-annotator") + ")";
- var textToShow;
+ var textToShow;
- if (annotationText !== null && annotationText !== "") {
- textToShow = annotationText + "<br />" + annotatorText;
- }else{
- textToShow = annotatorText;
- }
+ if (annotationText !== null && annotationText !== "") {
+ textToShow = annotationText + "<br />" + annotatorText;
+ } else {
+ textToShow = annotatorText;
+ }
- $("#annotation-tooltip div").html(textToShow);
- $("#annotation-tooltip").show();
+ $("#annotation-tooltip div").html(textToShow);
+ $("#annotation-tooltip").show();
- positionTooltip(event.pageX, event.pageY);
- }
+ positionTooltip(event.pageX, event.pageY);
+ }
});
// On mouse leave from SVG element
-$(document).on("mouseleave", "svg g *", function(event) {
- if (!annotating) {
- $(event.target).attr("stroke-opacity", "1.0");
- aboveShape = false;
- $("#annotation-tooltip").hide();
- }
+$(document).on("mouseleave", "svg g *", function (event) {
+ if (!annotating) {
+ $(event.target).attr("stroke-opacity", "1.0");
+ aboveShape = false;
+ $("#annotation-tooltip").hide();
+ }
});
// On mouse move inside of and SVG element, show annotation
-$(document).on("mousemove", "svg g *", function(event) {
- if (!annotating && aboveShape) {
- positionTooltip(event.pageX, event.pageY);
- //console.log('positioning at ' + event.pageX + " - " + event.pageY);
- }
+$(document).on("mousemove", "svg g *", function (event) {
+ if (!annotating && aboveShape) {
+ positionTooltip(event.pageX, event.pageY);
+ //console.log('positioning at ' + event.pageX + " - " + event.pageY);
+ }
});
/* Document ready */
-$(function() {
+$(function () {
- var svgNode, overlay;
+ var svgNode, overlay;
- // Current caption
- var currentCaption;
+ // Current caption
+ var currentCaption;
- // Set right image
- setImage(image, options);
+ // Set right image
+ setImage(image, options);
- // Activate viewer
- viewer = new OpenSeadragon(options);
+ // Activate viewer
+ viewer = new OpenSeadragon(options);
- // Enable imaging helper on viewer
- imagingHelper = viewer.activateImagingHelper({
- onImageViewChanged: onImageViewChanged
- });
+ // Enable imaging helper on viewer
+ imagingHelper = viewer.activateImagingHelper({
+ onImageViewChanged: onImageViewChanged
+ });
- // Fancybox
- $("[data-fancybox]").fancybox({
- iframe:{
- scrolling : 'yes'
- }
+ // Fancybox
+ $("[data-fancybox]").fancybox({
+ iframe: {
+ scrolling: 'yes'
+ }
+ });
+
+ // Init Paper.js canvas
+ paper.setup('papercanvas');
+
+ // Activate correct LI
+ $(".image-link").removeClass("active");
+ $(".image-link[href='?image=" + image + "']").addClass("active");
+
+ // Zoom @ 1x button
+ $("#zoom-1x").click(function (event) {
+ viewer.viewport.zoomTo(1 * oneXZoom, null, false);
+ event.preventDefault();
+ });
+
+ // Zoom @ 5x button
+ $("#zoom-5x").click(function (event) {
+ viewer.viewport.zoomTo(5 * oneXZoom, null, false);
+ event.preventDefault();
+ });
+
+ // Zoom @ 10x button
+ $("#zoom-10x").click(function (event) {
+ viewer.viewport.zoomTo(10 * oneXZoom, null, false);
+ event.preventDefault();
+ });
+
+ // Zoom @ 20x button
+ $("#zoom-20x").click(function (event) {
+ viewer.viewport.zoomTo(20 * oneXZoom, null, false);
+ event.preventDefault();
+ });
+
+ // Zoom @ 40x button
+ $("#zoom-40x").click(function (event) {
+ viewer.viewport.zoomTo(40 * oneXZoom, null, false);
+ event.preventDefault();
+ });
+
+ // Download annotations button
+ $("#download-annotations a").click(async function (event) {
+
+ let annotations = await db.allDocs({
+ startkey: image,
+ endkey: image + '\ufff0',
+ include_docs: true
});
- // Init Paper.js canvas
- paper.setup('papercanvas');
-
- // Activate correct LI
- $(".image-link").removeClass("active");
- $(".image-link[href='?image=" + image + "']").addClass("active");
-
- // Zoom @ 1x button
- $("#zoom-1x").click(function(event) {
- viewer.viewport.zoomTo(1 * oneXZoom, null, false);
- event.preventDefault();
- });
+ let annotationData = {};
- // Zoom @ 5x button
- $("#zoom-5x").click(function(event) {
- viewer.viewport.zoomTo(5 * oneXZoom, null, false);
- event.preventDefault();
- });
+ if (annotations.rows.length > 0) {
+ for(let annotationset of annotations.rows){
+ let userId = annotationset.id.substr(annotationset.id.lastIndexOf('-') + 1);
+ annotationData[userId] = annotationset.doc.annotations;
+ }
+ }
- // Zoom @ 10x button
- $("#zoom-10x").click(function(event) {
- viewer.viewport.zoomTo(10 * oneXZoom, null, false);
- event.preventDefault();
- });
+ let blob = new Blob([JSON.stringify(annotationData, null, 2)], {type: 'text/plain;charset=utf-8'});
+ saveAs(blob, image + '-' + annotator + '.json');
+ });
- // Zoom @ 20x button
- $("#zoom-20x").click(function(event) {
- viewer.viewport.zoomTo(20 * oneXZoom, null, false);
- event.preventDefault();
- });
+ // Drop down menu
+ if ($('select[name="normal"]').length > 0)
+ $('select[name="normal"]').on('change', function () {
+ svgEditor.canvas.setColor('stroke', $('select[name="normal"]').val(), false);
- // Zoom @ 40x button
- $("#zoom-40x").click(function(event) {
- viewer.viewport.zoomTo(40 * oneXZoom, null, false);
- event.preventDefault();
+ var e = document.getElementById("normal");
+ var userAnnotation = e.options[e.selectedIndex].text;
+ $('#annotation').val(userAnnotation);
+ //console.log(userAnnotation);
});
- // Drop down menu
- if($('select[name="normal"]').length > 0)
- $('select[name="normal"]').on('change', function() {
- svgEditor.canvas.setColor('stroke', $('select[name="normal"]').val(), false);
-
- var e = document.getElementById("normal");
- var userAnnotation = e.options[e.selectedIndex].text;
- $('#annotation').val(userAnnotation);
- //console.log(userAnnotation);
- });
-
- // Caption update
- $('#annotation').change(function(event){
+ // Caption update
+ $('#annotation').change(function (event) {
- var annotationAttribute = 'histopatho-annotation';
+ var annotationAttribute = 'histopatho-annotation';
- console.log('new value : ' + $(this).val());
+ console.log('new value : ' + $(this).val());
- var svgElement = svgEditor.canvas.getSelectedElems()[0];
+ var svgElement = svgEditor.canvas.getSelectedElems()[0];
- if($(svgElement).attr(annotationAttribute) !== $(this).val().replace( /\n/g, '<br \\>')){
- $(svgElement).attr(annotationAttribute, $(this).val().replace( /\n/g, '<br \\>'));
- }
+ if ($(svgElement).attr(annotationAttribute) !== $(this).val().replace(/\n/g, '<br \\>')) {
+ $(svgElement).attr(annotationAttribute, $(this).val().replace(/\n/g, '<br \\>'));
+ }
- svgEditor.canvas.runExtensions('elementChanged', {
- elems: [svgElement]
- });
+ svgEditor.canvas.runExtensions('elementChanged', {
+ elems: [svgElement]
});
-
- /*
- // Init color picker
- // Pathologists only
- if($('select[name="colorpicker"]').length > 0)
- $('select[name="colorpicker"]').simplecolorpicker({
- theme: 'fontawesome'
- }).on('change', function() {
- svgEditor.canvas.setColor('stroke', $('select[name="colorpicker"]').val(), false);
- });
- */
-
- // On annotation button click, toggle
- $("#toggle-annotation").click(function(event) {
- toggle();
- $("#annotation-menu button").blur();
+ });
+
+ /*
+ // Init color picker
+ // Pathologists only
+ if($('select[name="colorpicker"]').length > 0)
+ $('select[name="colorpicker"]').simplecolorpicker({
+ theme: 'fontawesome'
+ }).on('change', function() {
+ svgEditor.canvas.setColor('stroke', $('select[name="colorpicker"]').val(), false);
+ });
+ */
+
+ // On annotation button click, toggle
+ $("#toggle-annotation").click(function (event) {
+ toggle();
+ $("#annotation-menu button").blur();
+ });
+
+ // On ESC, toggle annotation mode
+ $(document).bind('keydown', 'esc', function (event) {
+ if (typeof svgEditor !== 'undefined') {
+ toggle();
+ }
+ event.preventDefault();
+ return false;
+ });
+
+ // On feature link click, load feature overlay
+ $(".feature-link").click(function (event) {
+ loadFeatureViewer($(this).attr("href").substr(1));
+ });
+
+ // On feature opacity slide, adjust opacity of feature viewer
+ $("#feature-opacity").on("input", function () {
+ var value = $(this).val();
+ updateOpacity(value);
+ });
+
+ // Initialize the opacity slider
+ $("#feature-opacity").val(initialOpacity);
+ updateOpacity($("#feature-opacity").val());
+
+ // Accordion
+ $("#imagesets").accordion({
+ collapsible: true,
+ heightStyle: 'content'
+ });
+
+ $("#imagesets").on("accordioncreate", function (event, ui) {
+ var i = 0;
+ $("#imagesets h3").each(function (index, element) {
+ if (image.startsWith($(element).text())) {
+ console.log('we are in ' + $(element).text());
+ $("#imagesets").accordion("option", "active", i);
+ }
+ i++;
});
+ });
- // On ESC, toggle annotation mode
- $(document).bind('keydown', 'esc', function(event) {
- if (typeof svgEditor !== 'undefined') {
- toggle();
- }
- event.preventDefault();
- return false;
- });
+ // When viewer is opened
+ viewer.addHandler('open', function () {
- // On feature link click, load feature overlay
- $(".feature-link").click(function(event) {
- loadFeatureViewer($(this).attr("href").substr(1));
- });
+ // Zoom on selected portion (if given)
+ if (getParameterByName("x") !== "" && getParameterByName("y") !== "" && getParameterByName("size") !== "") {
- // On feature opacity slide, adjust opacity of feature viewer
- $("#feature-opacity").on("input", function() {
- var value = $(this).val();
- updateOpacity(value);
- });
+ var x = parseInt(getParameterByName("x"));
+ var y = parseInt(getParameterByName("y"));
+ var size = parseInt(getParameterByName("size"));
- // Initialize the opacity slider
- $("#feature-opacity").val(initialOpacity);
- updateOpacity($("#feature-opacity").val());
+ var upperLeft = new OpenSeadragon.Point(x, y);
+ var viewerPoint = viewer.viewport.imageToViewportCoordinates(upperLeft);
+ var viewerSize = viewer.viewport.imageToViewportCoordinates(new OpenSeadragon.Point(size, size));
- // Accordion
- $("#imagesets").accordion({
- collapsible: true,
- heightStyle: 'content'
- });
+ // TODO - Fix once x & y are in the correct order!
+ viewer.viewport.fitBoundsWithConstraints(new OpenSeadragon.Rect(viewerPoint.y, viewerPoint.x, viewerSize.x, viewerSize.y), false);
+ }
- $("#imagesets").on("accordioncreate", function (event, ui) {
- var i = 0;
- $("#imagesets h3").each(function(index, element){
- if(image.startsWith($(element).text())){
- console.log('we are in ' + $(element).text());
- $("#imagesets").accordion("option", "active", i);
- }
- i++;
- });
+ // Check when image is fully loaded
+ viewer.world.getItemAt(0).addHandler('fully-loaded-change', function (event) {
+ console.log('fully loaded : ' + event.fullyLoaded);
+ if (remoteCouch) {
+ setTimeout(function () {
+ sync();
+ }, 1000);
+ }
+ viewer.world.getItemAt(0).removeAllHandlers('fully-loaded-change');
});
- // When viewer is opened
- viewer.addHandler('open', function() {
-
- // Zoom on selected portion (if given)
- if(getParameterByName("x") !== "" && getParameterByName("y") !== "" && getParameterByName("size") !== ""){
-
- var x = parseInt(getParameterByName("x"));
- var y = parseInt(getParameterByName("y"));
- var size = parseInt(getParameterByName("size"));
-
- var upperLeft = new OpenSeadragon.Point(x, y);
- var viewerPoint = viewer.viewport.imageToViewportCoordinates(upperLeft);
- var viewerSize = viewer.viewport.imageToViewportCoordinates(new OpenSeadragon.Point(size, size));
-
- // TODO - Fix once x & y are in the correct order!
- viewer.viewport.fitBoundsWithConstraints(new OpenSeadragon.Rect(viewerPoint.y, viewerPoint.x, viewerSize.x, viewerSize.y), false);
- }
-
- // Check when image is fully loaded
- viewer.world.getItemAt(0).addHandler('fully-loaded-change', function(event){
- console.log('fully loaded : ' + event.fullyLoaded);
- if (remoteCouch) {
- setTimeout(function(){
- sync();
- }, 1000);
- }
- viewer.world.getItemAt(0).removeAllHandlers('fully-loaded-change');
- });
-
- // Calculate the reference zoom for the magnification buttons (10x, 20x, 40x, ...)
- // Get slide magnification (objective-power)
- var originalImageName = count(image, '\\.') === 2 ? image.substr(0, image.lastIndexOf('.')) : image;
+ // Calculate the reference zoom for the magnification buttons (10x, 20x, 40x, ...)
+ // Get slide magnification (objective-power)
+ var originalImageName = count(image, '\\.') === 2 ? image.substr(0, image.lastIndexOf('.')) : image;
- $.get(config.slideMagURL + config.iipUploadedDir + encodeURIComponent(originalImageName), function (data) {
- if(data && data !== "None"){
- var magnification = parseInt(data);
- refMag = magnification;
- oneXZoom = calculateReferenceZoom(viewer.viewport, viewer.world, magnification);
+ $.get(config.slideMagURL + config.iipUploadedDir + encodeURIComponent(originalImageName), function (data) {
+ if (data && data !== "None") {
+ var magnification = parseInt(data);
+ refMag = magnification;
+ oneXZoom = calculateReferenceZoom(viewer.viewport, viewer.world, magnification);
+
+ // Hide unused buttons
+ if (magnification < 40)
+ $("#zoom-40x").hide();
+
+ if (magnification < 20)
+ $("#zoom-20x").hide();
+
+ if (magnification < 10)
+ $("#zoom-10x").hide();
+
+ if (magnification < 5)
+ $("#zoom-5x").hide();
+ } else {
+ oneXZoom = calculateReferenceZoom(viewer.viewport, viewer.world, refMag, false);
+ console.log("failed getting magnification level");
+ }
+ }, 'text').fail(function (e) {
+ oneXZoom = calculateReferenceZoom(viewer.viewport, viewer.world, refMag, false);
+ console.log("failed getting magnification level");
+ });
- // Hide unused buttons
- if(magnification < 40)
- $("#zoom-40x").hide();
+ // Initialize editor (if available)
+ // Pathologists only
+ if (typeof svgEditor !== 'undefined') {
- if(magnification < 20)
- $("#zoom-20x").hide();
+ // Append SVG overlay element to SVG canvas element
+ $("#openseadragon > .openseadragon-container > .openseadragon-canvas").append(svgEditContainer);
- if(magnification < 10)
- $("#zoom-10x").hide();
+ // Initialize the SVG editor
+ svgEditor.init();
+ canvas = svgEditor.canvas;
- if(magnification < 5)
- $("#zoom-5x").hide();
- }else{
- oneXZoom = calculateReferenceZoom(viewer.viewport, viewer.world, refMag, false);
- console.log("failed getting magnification level");
- }
- }, 'text').fail(function(e){
- oneXZoom = calculateReferenceZoom(viewer.viewport, viewer.world, refMag, false);
- console.log("failed getting magnification level");
- });
+ // Add SVG overlay to OSD (based on SVG-edit element)
+ overlay = viewer.svgOverlay(document.getElementById("svgroot"));
- // Initialize editor (if available)
- // Pathologists only
- if (typeof svgEditor !== 'undefined') {
+ // Trigger color dropdown "change"
+ $('select[name="normal"]').trigger('change');
+ } else {
+ overlay = viewer.svgOverlay();
+ }
- // Append SVG overlay element to SVG canvas element
- $("#openseadragon > .openseadragon-container > .openseadragon-canvas").append(svgEditContainer);
+ svgNode = overlay.node();
- // Initialize the SVG editor
- svgEditor.init();
- canvas = svgEditor.canvas;
+ // If there is a remote CouchDB instance, start syncing
+ loadAnnotations();
- // Add SVG overlay to OSD (based on SVG-edit element)
- overlay = viewer.svgOverlay(document.getElementById("svgroot"));
+ // Put editor in correct mode
+ toggleEditor(annotating);
- // Trigger color dropdown "change"
- $('select[name="normal"]').trigger('change');
- } else {
- overlay = viewer.svgOverlay();
- }
+ // If feature is not null, load the second viewer
+ if (location.hash) {
+ loadFeatureViewer(location.hash.substr(1));
+ }
+ });
- svgNode = overlay.node();
+ // Get slide scale (pixels per meter)
+ var originalImageName = count(image, '\\.') === 2 ? image.substr(0, image.lastIndexOf('.')) : image;
- // If there is a remote CouchDB instance, start syncing
- loadAnnotations();
+ $.get(config.slidePxMURL + config.iipUploadedDir + encodeURIComponent(originalImageName), function (data) {
- // Put editor in correct mode
- toggleEditor(annotating);
+ if (data !== null && data !== "None")
+ pixelsPerMeter = parseFloat(data);
- // If feature is not null, load the second viewer
- if (location.hash) {
- loadFeatureViewer(location.hash.substr(1));
- }
+ // Add scale bar to OSD
+ viewer.scalebar({
+ pixelsPerMeter: pixelsPerMeter
});
- // Get slide scale (pixels per meter)
- var originalImageName = count(image, '\\.') === 2 ? image.substr(0, image.lastIndexOf('.')) : image;
-
- $.get(config.slidePxMURL + config.iipUploadedDir + encodeURIComponent(originalImageName), function(data){
-
- if(data !== null && data !== "None")
- pixelsPerMeter = parseFloat(data);
-
- // Add scale bar to OSD
- viewer.scalebar({
- pixelsPerMeter: pixelsPerMeter
- });
-
- viewer.scalebar();
+ viewer.scalebar();
- }, 'text').fail(function(){
- console.log("failed to get pixels per meter")
- });
+ }, 'text').fail(function () {
+ console.log("failed to get pixels per meter")
+ });
});
function count(s1, letter) {
- return ( s1.match( RegExp(letter,'g') ) || [] ).length;
+ return (s1.match(RegExp(letter, 'g')) || []).length;
}
diff --git a/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb-6.2.0.min.js b/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb-6.2.0.min.js
deleted file mode 100644
index 7afbcf0..0000000
--- a/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb-6.2.0.min.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// PouchDB 6.2.0
-//
-// (c) 2012-2017 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(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.PouchDB=e()}}(function(){var e;return function e(t,n,r){function o(s,a){if(!n[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var f=n[s]={exports:{}};t[s][0].call(f.exports,function(e){var n=t[s][1][e];return o(n||e)},f,f.exports,e,t,n,r)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s<r.length;s++)o(r[s]);return o}({1:[function(e,t,n){"use strict";function r(e){return function(){var t=arguments.length;if(t){for(var n=[],r=-1;++r<t;)n[r]=arguments[r];return e.call(this,n)}return e.call(this,[])}}t.exports=r},{}],2:[function(e,t,n){(function(r){function o(){return!("undefined"==typeof window||!window||void 0===window.process||"renderer"!==window.process.type)||("undefined"!=typeof document&&document&&"WebkitAppearance"in document.documentElement.style||"undefined"!=typeof window&&window&&window.console&&(console.firebug||console.exception&&console.table)||"undefined"!=typeof navigator&&navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))}function i(e){var t=this.useColors;if(e[0]=(t?"%c":"")+this.namespace+(t?" %c":" ")+e[0]+(t?"%c ":" ")+"+"+n.humanize(this.diff),t){var r="color: "+this.color;e.splice(1,0,r,"color: inherit");var o=0,i=0;e[0].replace(/%[a-zA-Z%]/g,function(e){"%%"!==e&&(o++,"%c"===e&&(i=o))}),e.splice(i,0,r)}}function s(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function a(e){try{null==e?n.storage.removeItem("debug"):n.storage.debug=e}catch(e){}}function u(){try{return n.storage.debug}catch(e){}if(void 0!==r&&"env"in r)return r.env.DEBUG}n=t.exports=e(3),n.log=s,n.formatArgs=i,n.save=a,n.load=u,n.useColors=o,n.storage="undefined"!=typeof chrome&&void 0!==chrome.storage?chrome.storage.local:function(){try{return window.localStorage}catch(e){}}(),n.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],n.formatters.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}},n.enable(u())}).call(this,e(9))},{3:3,9:9}],3:[function(e,t,n){function r(e){var t,r=0;for(t in e)r=(r<<5)-r+e.charCodeAt(t),r|=0;return n.colors[Math.abs(r)%n.colors.length]}function o(e){function t(){if(t.enabled){var e=t,r=+new Date,o=r-(c||r);e.diff=o,e.prev=c,e.curr=r,c=r;for(var i=new Array(arguments.length),s=0;s<i.length;s++)i[s]=arguments[s];i[0]=n.coerce(i[0]),"string"!=typeof i[0]&&i.unshift("%O");var a=0;i[0]=i[0].replace(/%([a-zA-Z%])/g,function(t,r){if("%%"===t)return t;a++;var o=n.formatters[r];if("function"==typeof o){var s=i[a];t=o.call(e,s),i.splice(a,1),a--}return t}),n.formatArgs.call(e,i);(t.log||n.log||console.log.bind(console)).apply(e,i)}}return t.namespace=e,t.enabled=n.enabled(e),t.useColors=n.useColors(),t.color=r(e),"function"==typeof n.init&&n.init(t),t}function i(e){n.save(e),n.names=[],n.skips=[];for(var t=(e||"").split(/[\s,]+/),r=t.length,o=0;o<r;o++)t[o]&&(e=t[o].replace(/\*/g,".*?"),"-"===e[0]?n.skips.push(new RegExp("^"+e.substr(1)+"$")):n.names.push(new RegExp("^"+e+"$")))}function s(){n.enable("")}function a(e){var t,r;for(t=0,r=n.skips.length;t<r;t++)if(n.skips[t].test(e))return!1;for(t=0,r=n.names.length;t<r;t++)if(n.names[t].test(e))return!0;return!1}function u(e){return e instanceof Error?e.stack||e.message:e}n=t.exports=o.debug=o.default=o,n.coerce=u,n.disable=s,n.enable=i,n.enabled=a,n.humanize=e(8),n.names=[],n.skips=[],n.formatters={};var c},{8:8}],4:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function o(e){return"function"==typeof e}function i(e){return"number"==typeof e}function s(e){return"object"==typeof e&&null!==e}function a(e){return void 0===e}t.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!i(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,i,u,c;if(this._events||(this._events={}),"error"===e&&(!this._events.error||s(this._events.error)&&!this._events.error.length)){if((t=arguments[1])instanceof Error)throw t;var f=new Error('Uncaught, unspecified "error" event. ('+t+")");throw f.context=t,f}if(n=this._events[e],a(n))return!1;if(o(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:i=Array.prototype.slice.call(arguments,1),n.apply(this,i)}else if(s(n))for(i=Array.prototype.slice.call(arguments,1),c=n.slice(),r=c.length,u=0;u<r;u++)c[u].apply(this,i);return!0},r.prototype.addListener=function(e,t){var n;if(!o(t))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,o(t.listener)?t.listener:t),this._events[e]?s(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,s(this._events[e])&&!this._events[e].warned&&(n=a(this._maxListeners)?r.defaultMaxListeners:this._maxListeners)&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}if(!o(t))throw TypeError("listener must be a function");var r=!1;return n.listener=t,this.on(e,n),this},r.prototype.removeListener=function(e,t){var n,r,i,a;if(!o(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],i=n.length,r=-1,n===t||o(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(s(n)){for(a=i;a-- >0;)if(n[a]===t||n[a].listener&&n[a].listener===t){r=a;break}if(r<0)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],o(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){return this._events&&this._events[e]?o(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(o(t))return 1;if(t)return t.length}return 0},r.listenerCount=function(e,t){return e.listenerCount(t)}},{}],5:[function(e,t,n){(function(e){"use strict";function n(){f=!0;for(var e,t,n=l.length;n;){for(t=l,l=[],e=-1;++e<n;)t[e]();n=l.length}f=!1}function r(e){1!==l.push(e)||f||o()}var o,i=e.MutationObserver||e.WebKitMutationObserver;if(i){var s=0,a=new i(n),u=e.document.createTextNode("");a.observe(u,{characterData:!0}),o=function(){u.data=s=++s%2}}else if(e.setImmediate||void 0===e.MessageChannel)o="document"in e&&"onreadystatechange"in e.document.createElement("script")?function(){var t=e.document.createElement("script");t.onreadystatechange=function(){n(),t.onreadystatechange=null,t.parentNode.removeChild(t),t=null},e.document.documentElement.appendChild(t)}:function(){setTimeout(n,0)};else{var c=new e.MessageChannel;c.port1.onmessage=n,o=function(){c.port2.postMessage(0)}}var f,l=[];t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],6:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],7:[function(e,t,n){"use strict";function r(){}function o(e){if("function"!=typeof e)throw new TypeError("resolver must be a function");this.state=_,this.queue=[],this.outcome=void 0,e!==r&&u(this,e)}function i(e,t,n){this.promise=e,"function"==typeof t&&(this.onFulfilled=t,this.callFulfilled=this.otherCallFulfilled),"function"==typeof n&&(this.onRejected=n,this.callRejected=this.otherCallRejected)}function s(e,t,n){p(function(){var r;try{r=t(n)}catch(t){return v.reject(e,t)}r===e?v.reject(e,new TypeError("Cannot resolve promise with itself")):v.resolve(e,r)})}function a(e){var t=e&&e.then;if(e&&("object"==typeof e||"function"==typeof e)&&"function"==typeof t)return function(){t.apply(e,arguments)}}function u(e,t){function n(t){i||(i=!0,v.reject(e,t))}function r(t){i||(i=!0,v.resolve(e,t))}function o(){t(r,n)}var i=!1,s=c(o);"error"===s.status&&n(s.value)}function c(e,t){var n={};try{n.value=e(t),n.status="success"}catch(e){n.status="error",n.value=e}return n}function f(e){return e instanceof this?e:v.resolve(new this(r),e)}function l(e){var t=new this(r);return v.reject(t,e)}function d(e){var t=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var n=e.length,o=!1;if(!n)return this.resolve([]);for(var i=new Array(n),s=0,a=-1,u=new this(r);++a<n;)!function(e,r){function a(e){i[r]=e,++s!==n||o||(o=!0,v.resolve(u,i))}t.resolve(e).then(a,function(e){o||(o=!0,v.reject(u,e))})}(e[a],a);return u}function h(e){var t=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var n=e.length,o=!1;if(!n)return this.resolve([]);for(var i=-1,s=new this(r);++i<n;)!function(e){t.resolve(e).then(function(e){o||(o=!0,v.resolve(s,e))},function(e){o||(o=!0,v.reject(s,e))})}(e[i]);return s}var p=e(5),v={},g=["REJECTED"],y=["FULFILLED"],_=["PENDING"];t.exports=o,o.prototype.catch=function(e){return this.then(null,e)},o.prototype.then=function(e,t){if("function"!=typeof e&&this.state===y||"function"!=typeof t&&this.state===g)return this;var n=new this.constructor(r);if(this.state!==_){s(n,this.state===y?e:t,this.outcome)}else this.queue.push(new i(n,e,t));return n},i.prototype.callFulfilled=function(e){v.resolve(this.promise,e)},i.prototype.otherCallFulfilled=function(e){s(this.promise,this.onFulfilled,e)},i.prototype.callRejected=function(e){v.reject(this.promise,e)},i.prototype.otherCallRejected=function(e){s(this.promise,this.onRejected,e)},v.resolve=function(e,t){var n=c(a,t);if("error"===n.status)return v.reject(e,n.value);var r=n.value;if(r)u(e,r);else{e.state=y,e.outcome=t;for(var o=-1,i=e.queue.length;++o<i;)e.queue[o].callFulfilled(t)}return e},v.reject=function(e,t){e.state=g,e.outcome=t;for(var n=-1,r=e.queue.length;++n<r;)e.queue[n].callRejected(t);return e},o.resolve=f,o.reject=l,o.all=d,o.race=h},{5:5}],8:[function(e,t,n){function r(e){if(e=String(e),!(e.length>1e4)){var t=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(e);if(t){var n=parseFloat(t[1]);switch((t[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return n*l;case"days":case"day":case"d":return n*f;case"hours":case"hour":case"hrs":case"hr":case"h":return n*c;case"minutes":case"minute":case"mins":case"min":case"m":return n*u;case"seconds":case"second":case"secs":case"sec":case"s":return n*a;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n;default:return}}}}function o(e){return e>=f?Math.round(e/f)+"d":e>=c?Math.round(e/c)+"h":e>=u?Math.round(e/u)+"m":e>=a?Math.round(e/a)+"s":e+"ms"}function i(e){return s(e,f,"day")||s(e,c,"hour")||s(e,u,"minute")||s(e,a,"second")||e+" ms"}function s(e,t,n){if(!(e<t))return e<1.5*t?Math.floor(e/t)+" "+n:Math.ceil(e/t)+" "+n+"s"}var a=1e3,u=60*a,c=60*u,f=24*c,l=365.25*f;t.exports=function(e,t){t=t||{};var n=typeof e;if("string"===n&&e.length>0)return r(e);if("number"===n&&isNaN(e)===!1)return t.long?i(e):o(e);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))}},{}],9:[function(e,t,n){function r(){throw new Error("setTimeout has not been defined")}function o(){throw new Error("clearTimeout has not been defined")}function i(e){if(l===setTimeout)return setTimeout(e,0);if((l===r||!l)&&setTimeout)return l=setTimeout,setTimeout(e,0);try{return l(e,0)}catch(t){try{return l.call(null,e,0)}catch(t){return l.call(this,e,0)}}}function s(e){if(d===clearTimeout)return clearTimeout(e);if((d===o||!d)&&clearTimeout)return d=clearTimeout,clearTimeout(e);try{return d(e)}catch(t){try{return d.call(null,e)}catch(t){return d.call(this,e)}}}function a(){g&&p&&(g=!1,p.length?v=p.concat(v):y=-1,v.length&&u())}function u(){if(!g){var e=i(a);g=!0;for(var t=v.length;t;){for(p=v,v=[];++y<t;)p&&p[y].run();y=-1,t=v.length}p=null,g=!1,s(e)}}function c(e,t){this.fun=e,this.array=t}function f(){}var l,d,h=t.exports={};!function(){try{l="function"==typeof setTimeout?setTimeout:r}catch(e){l=r}try{d="function"==typeof clearTimeout?clearTimeout:o}catch(e){d=o}}();var p,v=[],g=!1,y=-1;h.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];v.push(new c(e,t)),1!==v.length||g||i(u)},c.prototype.run=function(){this.fun.apply(null,this.array)},h.title="browser",h.browser=!0,h.env={},h.argv=[],h.version="",h.versions={},h.on=f,h.addListener=f,h.once=f,h.off=f,h.removeListener=f,h.removeAllListeners=f,h.emit=f,h.binding=function(e){throw new Error("process.binding is not supported")},h.cwd=function(){return"/"},h.chdir=function(e){throw new Error("process.chdir is not supported")},h.umask=function(){return 0}},{}],10:[function(t,n,r){!function(t){if("object"==typeof r)n.exports=t();else if("function"==typeof e&&e.amd)e(t);else{var o;try{o=window}catch(e){o=self}o.SparkMD5=t()}}(function(e){"use strict";function t(e,t){var n=e[0],r=e[1],o=e[2],i=e[3];n+=(r&o|~r&i)+t[0]-680876936|0,n=(n<<7|n>>>25)+r|0,i+=(n&r|~n&o)+t[1]-389564586|0,i=(i<<12|i>>>20)+n|0,o+=(i&n|~i&r)+t[2]+606105819|0,o=(o<<17|o>>>15)+i|0,r+=(o&i|~o&n)+t[3]-1044525330|0,r=(r<<22|r>>>10)+o|0,n+=(r&o|~r&i)+t[4]-176418897|0,n=(n<<7|n>>>25)+r|0,i+=(n&r|~n&o)+t[5]+1200080426|0,i=(i<<12|i>>>20)+n|0,o+=(i&n|~i&r)+t[6]-1473231341|0,o=(o<<17|o>>>15)+i|0,r+=(o&i|~o&n)+t[7]-45705983|0,r=(r<<22|r>>>10)+o|0,n+=(r&o|~r&i)+t[8]+1770035416|0,n=(n<<7|n>>>25)+r|0,i+=(n&r|~n&o)+t[9]-1958414417|0,i=(i<<12|i>>>20)+n|0,o+=(i&n|~i&r)+t[10]-42063|0,o=(o<<17|o>>>15)+i|0,r+=(o&i|~o&n)+t[11]-1990404162|0,r=(r<<22|r>>>10)+o|0,n+=(r&o|~r&i)+t[12]+1804603682|0,n=(n<<7|n>>>25)+r|0,i+=(n&r|~n&o)+t[13]-40341101|0,i=(i<<12|i>>>20)+n|0,o+=(i&n|~i&r)+t[14]-1502002290|0,o=(o<<17|o>>>15)+i|0,r+=(o&i|~o&n)+t[15]+1236535329|0,r=(r<<22|r>>>10)+o|0,n+=(r&i|o&~i)+t[1]-165796510|0,n=(n<<5|n>>>27)+r|0,i+=(n&o|r&~o)+t[6]-1069501632|0,i=(i<<9|i>>>23)+n|0,o+=(i&r|n&~r)+t[11]+643717713|0,o=(o<<14|o>>>18)+i|0,r+=(o&n|i&~n)+t[0]-373897302|0,r=(r<<20|r>>>12)+o|0,n+=(r&i|o&~i)+t[5]-701558691|0,n=(n<<5|n>>>27)+r|0,i+=(n&o|r&~o)+t[10]+38016083|0,i=(i<<9|i>>>23)+n|0,o+=(i&r|n&~r)+t[15]-660478335|0,o=(o<<14|o>>>18)+i|0,r+=(o&n|i&~n)+t[4]-405537848|0,r=(r<<20|r>>>12)+o|0,n+=(r&i|o&~i)+t[9]+568446438|0,n=(n<<5|n>>>27)+r|0,i+=(n&o|r&~o)+t[14]-1019803690|0,i=(i<<9|i>>>23)+n|0,o+=(i&r|n&~r)+t[3]-187363961|0,o=(o<<14|o>>>18)+i|0,r+=(o&n|i&~n)+t[8]+1163531501|0,r=(r<<20|r>>>12)+o|0,n+=(r&i|o&~i)+t[13]-1444681467|0,n=(n<<5|n>>>27)+r|0,i+=(n&o|r&~o)+t[2]-51403784|0,i=(i<<9|i>>>23)+n|0,o+=(i&r|n&~r)+t[7]+1735328473|0,o=(o<<14|o>>>18)+i|0,r+=(o&n|i&~n)+t[12]-1926607734|0,r=(r<<20|r>>>12)+o|0,n+=(r^o^i)+t[5]-378558|0,n=(n<<4|n>>>28)+r|0,i+=(n^r^o)+t[8]-2022574463|0,i=(i<<11|i>>>21)+n|0,o+=(i^n^r)+t[11]+1839030562|0,o=(o<<16|o>>>16)+i|0,r+=(o^i^n)+t[14]-35309556|0,r=(r<<23|r>>>9)+o|0,n+=(r^o^i)+t[1]-1530992060|0,n=(n<<4|n>>>28)+r|0,i+=(n^r^o)+t[4]+1272893353|0,i=(i<<11|i>>>21)+n|0,o+=(i^n^r)+t[7]-155497632|0,o=(o<<16|o>>>16)+i|0,r+=(o^i^n)+t[10]-1094730640|0,r=(r<<23|r>>>9)+o|0,n+=(r^o^i)+t[13]+681279174|0,n=(n<<4|n>>>28)+r|0,i+=(n^r^o)+t[0]-358537222|0,i=(i<<11|i>>>21)+n|0,o+=(i^n^r)+t[3]-722521979|0,o=(o<<16|o>>>16)+i|0,r+=(o^i^n)+t[6]+76029189|0,r=(r<<23|r>>>9)+o|0,n+=(r^o^i)+t[9]-640364487|0,n=(n<<4|n>>>28)+r|0,i+=(n^r^o)+t[12]-421815835|0,i=(i<<11|i>>>21)+n|0,o+=(i^n^r)+t[15]+530742520|0,o=(o<<16|o>>>16)+i|0,r+=(o^i^n)+t[2]-995338651|0,r=(r<<23|r>>>9)+o|0,n+=(o^(r|~i))+t[0]-198630844|0,n=(n<<6|n>>>26)+r|0,i+=(r^(n|~o))+t[7]+1126891415|0,i=(i<<10|i>>>22)+n|0,o+=(n^(i|~r))+t[14]-1416354905|0,o=(o<<15|o>>>17)+i|0,r+=(i^(o|~n))+t[5]-57434055|0,r=(r<<21|r>>>11)+o|0,n+=(o^(r|~i))+t[12]+1700485571|0,n=(n<<6|n>>>26)+r|0,i+=(r^(n|~o))+t[3]-1894986606|0,i=(i<<10|i>>>22)+n|0,o+=(n^(i|~r))+t[10]-1051523|0,o=(o<<15|o>>>17)+i|0,r+=(i^(o|~n))+t[1]-2054922799|0,r=(r<<21|r>>>11)+o|0,n+=(o^(r|~i))+t[8]+1873313359|0,n=(n<<6|n>>>26)+r|0,i+=(r^(n|~o))+t[15]-30611744|0,i=(i<<10|i>>>22)+n|0,o+=(n^(i|~r))+t[6]-1560198380|0,o=(o<<15|o>>>17)+i|0,r+=(i^(o|~n))+t[13]+1309151649|0,r=(r<<21|r>>>11)+o|0,n+=(o^(r|~i))+t[4]-145523070|0,n=(n<<6|n>>>26)+r|0,i+=(r^(n|~o))+t[11]-1120210379|0,i=(i<<10|i>>>22)+n|0,o+=(n^(i|~r))+t[2]+718787259|0,o=(o<<15|o>>>17)+i|0,r+=(i^(o|~n))+t[9]-343485551|0,r=(r<<21|r>>>11)+o|0,e[0]=n+e[0]|0,e[1]=r+e[1]|0,e[2]=o+e[2]|0,e[3]=i+e[3]|0}function n(e){var t,n=[];for(t=0;t<64;t+=4)n[t>>2]=e.charCodeAt(t)+(e.charCodeAt(t+1)<<8)+(e.charCodeAt(t+2)<<16)+(e.charCodeAt(t+3)<<24);return n}function r(e){var t,n=[];for(t=0;t<64;t+=4)n[t>>2]=e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24);return n}function o(e){var r,o,i,s,a,u,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(r=64;r<=c;r+=64)t(f,n(e.substring(r-64,r)));for(e=e.substring(r-64),o=e.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],r=0;r<o;r+=1)i[r>>2]|=e.charCodeAt(r)<<(r%4<<3);if(i[r>>2]|=128<<(r%4<<3),r>55)for(t(f,i),r=0;r<16;r+=1)i[r]=0;return s=8*c,s=s.toString(16).match(/(.*?)(.{0,8})$/),a=parseInt(s[2],16),u=parseInt(s[1],16)||0,i[14]=a,i[15]=u,t(f,i),f}function i(e){var n,o,i,s,a,u,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(n=64;n<=c;n+=64)t(f,r(e.subarray(n-64,n)));for(e=n-64<c?e.subarray(n-64):new Uint8Array(0),o=e.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],n=0;n<o;n+=1)i[n>>2]|=e[n]<<(n%4<<3);if(i[n>>2]|=128<<(n%4<<3),n>55)for(t(f,i),n=0;n<16;n+=1)i[n]=0;return s=8*c,s=s.toString(16).match(/(.*?)(.{0,8})$/),a=parseInt(s[2],16),u=parseInt(s[1],16)||0,i[14]=a,i[15]=u,t(f,i),f}function s(e){var t,n="";for(t=0;t<4;t+=1)n+=p[e>>8*t+4&15]+p[e>>8*t&15];return n}function a(e){var t;for(t=0;t<e.length;t+=1)e[t]=s(e[t]);return e.join("")}function u(e){return/[\u0080-\uFFFF]/.test(e)&&(e=unescape(encodeURIComponent(e))),e}function c(e,t){var n,r=e.length,o=new ArrayBuffer(r),i=new Uint8Array(o);for(n=0;n<r;n+=1)i[n]=e.charCodeAt(n);return t?i:o}function f(e){return String.fromCharCode.apply(null,new Uint8Array(e))}function l(e,t,n){var r=new Uint8Array(e.byteLength+t.byteLength);return r.set(new Uint8Array(e)),r.set(new Uint8Array(t),e.byteLength),n?r:r.buffer}function d(e){var t,n=[],r=e.length;for(t=0;t<r-1;t+=2)n.push(parseInt(e.substr(t,2),16));return String.fromCharCode.apply(String,n)}function h(){this.reset()}var p=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];return"5d41402abc4b2a76b9719d911017c592"!==a(o("hello"))&&function(e,t){var n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n},"undefined"==typeof ArrayBuffer||ArrayBuffer.prototype.slice||function(){function t(e,t){return e=0|e||0,e<0?Math.max(e+t,0):Math.min(e,t)}ArrayBuffer.prototype.slice=function(n,r){var o,i,s,a,u=this.byteLength,c=t(n,u),f=u;return r!==e&&(f=t(r,u)),c>f?new ArrayBuffer(0):(o=f-c,i=new ArrayBuffer(o),s=new Uint8Array(i),a=new Uint8Array(this,c,o),s.set(a),i)}}(),h.prototype.append=function(e){return this.appendBinary(u(e)),this},h.prototype.appendBinary=function(e){this._buff+=e,this._length+=e.length;var r,o=this._buff.length;for(r=64;r<=o;r+=64)t(this._hash,n(this._buff.substring(r-64,r)));return this._buff=this._buff.substring(r-64),this},h.prototype.end=function(e){var t,n,r=this._buff,o=r.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;t<o;t+=1)i[t>>2]|=r.charCodeAt(t)<<(t%4<<3);return this._finish(i,o),n=a(this._hash),e&&(n=d(n)),this.reset(),n},h.prototype.reset=function(){return this._buff="",this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},h.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash}},h.prototype.setState=function(e){return this._buff=e.buff,this._length=e.length,this._hash=e.hash,this},h.prototype.destroy=function(){delete this._hash,delete this._buff,delete this._length},h.prototype._finish=function(e,n){var r,o,i,s=n;if(e[s>>2]|=128<<(s%4<<3),s>55)for(t(this._hash,e),s=0;s<16;s+=1)e[s]=0;r=8*this._length,r=r.toString(16).match(/(.*?)(.{0,8})$/),o=parseInt(r[2],16),i=parseInt(r[1],16)||0,e[14]=o,e[15]=i,t(this._hash,e)},h.hash=function(e,t){return h.hashBinary(u(e),t)},h.hashBinary=function(e,t){var n=o(e),r=a(n);return t?d(r):r},h.ArrayBuffer=function(){this.reset()},h.ArrayBuffer.prototype.append=function(e){var n,o=l(this._buff.buffer,e,!0),i=o.length;for(this._length+=e.byteLength,n=64;n<=i;n+=64)t(this._hash,r(o.subarray(n-64,n)));return this._buff=n-64<i?new Uint8Array(o.buffer.slice(n-64)):new Uint8Array(0),this},h.ArrayBuffer.prototype.end=function(e){var t,n,r=this._buff,o=r.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;t<o;t+=1)i[t>>2]|=r[t]<<(t%4<<3);return this._finish(i,o),n=a(this._hash),e&&(n=d(n)),this.reset(),n},h.ArrayBuffer.prototype.reset=function(){return this._buff=new Uint8Array(0),this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},h.ArrayBuffer.prototype.getState=function(){var e=h.prototype.getState.call(this);return e.buff=f(e.buff),e},h.ArrayBuffer.prototype.setState=function(e){return e.buff=c(e.buff,!0),h.prototype.setState.call(this,e)},h.ArrayBuffer.prototype.destroy=h.prototype.destroy,h.ArrayBuffer.prototype._finish=h.prototype._finish,h.ArrayBuffer.hash=function(e,t){var n=i(new Uint8Array(e)),r=a(n);return t?d(r):r},h})},{}],11:[function(e,t,n){"use strict";function r(e,t,n){var r=n[n.length-1];e===r.element&&(n.pop(),r=n[n.length-1]);var o=r.element,i=r.index;if(Array.isArray(o))o.push(e);else if(i===t.length-2){var s=t.pop();o[s]=e}else t.push(e)}n.stringify=function(e){var t=[];t.push({obj:e});for(var n,r,o,i,s,a,u,c,f,l,d,h="";n=t.pop();)if(r=n.obj,o=n.prefix||"",i=n.val||"",h+=o,i)h+=i;else if("object"!=typeof r)h+=void 0===r?null:JSON.stringify(r);else if(null===r)h+="null";else if(Array.isArray(r)){for(t.push({val:"]"}),s=r.length-1;s>=0;s--)a=0===s?"":",",t.push({obj:r[s],prefix:a});t.push({val:"["})}else{u=[];for(c in r)r.hasOwnProperty(c)&&u.push(c);for(t.push({val:"}"}),s=u.length-1;s>=0;s--)f=u[s],l=r[f],d=s>0?",":"",d+=JSON.stringify(f)+":",t.push({obj:l,prefix:d});t.push({val:"{"})}return h},n.parse=function(e){for(var t,n,o,i,s,a,u,c,f,l=[],d=[],h=0;;)if("}"!==(t=e[h++])&&"]"!==t&&void 0!==t)switch(t){case" ":case"\t":case"\n":case":":case",":break;case"n":h+=3,r(null,l,d);break;case"t":h+=3,r(!0,l,d);break;case"f":h+=4,r(!1,l,d);break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":case"-":for(n="",h--;;){if(o=e[h++],!/[\d\.\-e\+]/.test(o)){h--;break}n+=o}r(parseFloat(n),l,d);break;case'"':for(i="",s=void 0,a=0;;){if('"'===(u=e[h++])&&("\\"!==s||a%2!=1))break;i+=u,s=u,"\\"===s?a++:a=0}r(JSON.parse('"'+i+'"'),l,d);break;case"[":c={element:[],index:l.length},l.push(c.element),d.push(c);break;case"{":f={element:{},index:l.length},l.push(f.element),d.push(f);break;default:throw new Error("unexpectedly reached end of input: "+t)}else{if(1===l.length)return l.pop();r(l.pop(),l,d)}}},{}],12:[function(e,t,n){(function(n){"use strict";function r(e){return e&&"object"==typeof e&&"default"in e?e.default:e}function o(e){return"undefined"!=typeof ArrayBuffer&&e instanceof ArrayBuffer||"undefined"!=typeof Blob&&e instanceof Blob}function i(e){if("function"==typeof e.slice)return e.slice(0);var t=new ArrayBuffer(e.byteLength),n=new Uint8Array(t),r=new Uint8Array(e);return n.set(r),t}function s(e){if(e instanceof ArrayBuffer)return i(e);var t=e.size,n=e.type;return"function"==typeof e.slice?e.slice(0,t,n):e.webkitSlice(0,t,n)}function a(e){var t=Object.getPrototypeOf(e);if(null===t)return!0;var n=t.constructor;return"function"==typeof n&&n instanceof n&&go.call(n)==yo}function u(e){var t,n,r;if(!e||"object"!=typeof e)return e;if(Array.isArray(e)){for(t=[],n=0,r=e.length;n<r;n++)t[n]=u(e[n]);return t}if(e instanceof Date)return e.toISOString();if(o(e))return s(e);if(!a(e))return e;t={};for(n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var i=u(e[n]);void 0!==i&&(t[n]=i)}return t}function c(e){var t=!1;return ao(function(n){if(t)throw new Error("once called more than once");t=!0,e.apply(this,n)})}function f(e){return ao(function(t){t=u(t);var n=this,r="function"==typeof t[t.length-1]&&t.pop(),o=new vo(function(r,o){var i;try{var s=c(function(e,t){e?o(e):r(t)});t.push(s),i=e.apply(n,t),i&&"function"==typeof i.then&&r(i)}catch(e){o(e)}});return r&&o.then(function(e){r(null,e)},r),o})}function l(e,t,n){if(e.constructor.listeners("debug").length){for(var r=["api",e.name,t],o=0;o<n.length-1;o++)r.push(n[o]);e.constructor.emit("debug",r);var i=n[n.length-1];n[n.length-1]=function(n,r){var o=["api",e.name,t];o=o.concat(n?["error",n]:["success",r]),e.constructor.emit("debug",o),i(n,r)}}}function d(e,t){return f(ao(function(n){if(this._closed)return vo.reject(new Error("database is closed"));if(this._destroyed)return vo.reject(new Error("database is destroyed"));var r=this;return l(r,e,n),this.taskqueue.isReady?t.apply(this,n):new vo(function(t,o){r.taskqueue.addTask(function(i){i?o(i):t(r[e].apply(r,n))})})}))}function h(e){return"$"+e}function p(e){return e.substring(1)}function v(){this._store={}}function g(e){if(this._store=new v,e&&Array.isArray(e))for(var t=0,n=e.length;t<n;t++)this.add(e[t])}function y(e,t){for(var n={},r=0,o=t.length;r<o;r++){var i=t[r];i in e&&(n[i]=e[i])}return n}function _(e){return e}function m(e){return[{ok:e}]}function b(e,t,n){function r(){var e=[];d.forEach(function(t){t.docs.forEach(function(n){e.push({id:t.id,docs:[n]})})}),n(null,{results:e})}function o(){++l===f&&r()}function i(e,t,n){d[e]={id:t,docs:n},o()}function s(){if(!(p>=h.length)){var e=Math.min(p+wo,h.length),t=h.slice(p,e);a(t,p),p+=t.length}}function a(n,r){n.forEach(function(n,o){var a=r+o,u=c.get(n),f=y(u[0],["atts_since","attachments"]);f.open_revs=u.map(function(e){return e.rev}),f.open_revs=f.open_revs.filter(_);var l=_;0===f.open_revs.length&&(delete f.open_revs,l=m),["revs","attachments","binary","ajax","latest"].forEach(function(e){e in t&&(f[e]=t[e])}),e.get(n,f,function(e,t){var r;r=e?[{error:e}]:l(t),i(a,n,r),s()})})}var u=t.docs,c=new mo;u.forEach(function(e){c.has(e.id)?c.get(e.id).push(e):c.set(e.id,[e])});var f=c.size,l=0,d=new Array(f),h=[];c.forEach(function(e,t){h.push(t)});var p=0;s()}function w(){return"undefined"!=typeof chrome&&void 0!==chrome.storage&&void 0!==chrome.storage.local}function E(){return bo}function S(e){w()?chrome.storage.onChanged.addListener(function(t){null!=t.db_name&&e.emit(t.dbName.newValue)}):E()&&("undefined"!=typeof addEventListener?addEventListener("storage",function(t){e.emit(t.key)}):window.attachEvent("storage",function(t){e.emit(t.key)}))}function k(){uo.EventEmitter.call(this),this._listeners={},S(this)}function q(e){if("undefined"!==console&&e in console){var t=Array.prototype.slice.call(arguments,1);console[e].apply(console,t)}}function A(e,t){return e=parseInt(e,10)||0,t=parseInt(t,10),t!==t||t<=e?t=(e||1)<<1:t+=1,t>6e5&&(e=3e5,t=6e5),~~((t-e)*Math.random()+e)}function x(e){var t=0;return e||(t=2e3),A(e,t)}function O(e,t){q("info","The above "+e+" is totally normal. "+t)}function T(e,t,n){Error.call(this,n),this.status=e,this.name=t,this.message=n,this.error=!0}function j(e,t){function n(t){for(var n in e)"function"!=typeof e[n]&&(this[n]=e[n]);void 0!==t&&(this.reason=t)}return n.prototype=T.prototype,new n(t)}function C(e){if("object"!=typeof e){var t=e;e=jo,e.data=t}return"error"in e&&"conflict"===e.error&&(e.name="conflict",e.status=409),"name"in e||(e.name=e.error||"unknown"),"status"in e||(e.status=500),"message"in e||(e.message=e.message||e.reason),e}function L(e,t,n){try{return!e(t,n)}catch(e){var r="Filter function threw: "+e.toString();return j(Do,r)}}function I(e){var t={},n=e.filter&&"function"==typeof e.filter;return t.query=e.query_params,function(r){r.doc||(r.doc={});var o=n&&L(e.filter,r.doc,t);if("object"==typeof o)return o;if(o)return!1;if(e.include_docs){if(!e.attachments)for(var i in r.doc._attachments)r.doc._attachments.hasOwnProperty(i)&&(r.doc._attachments[i].stub=!0)}else delete r.doc;return!0}}function D(e){for(var t=[],n=0,r=e.length;n<r;n++)t=t.concat(e[n]);return t}function R(){}function N(e){var t;if(e?"string"!=typeof e?t=j(xo):/^_/.test(e)&&!/^_(design|local)/.test(e)&&(t=j(To)):t=j(Oo),t)throw t}function B(e){return"boolean"==typeof e._remote?e._remote:"function"==typeof e.type&&(q("warn","db.type() is deprecated and will be removed in a future version of PouchDB"),"http"===e.type())}function $(e,t){return"listenerCount"in e?e.listenerCount(t):uo.EventEmitter.listenerCount(e,t)}function F(e){if(!e)return null;var t=e.split("/");return 2===t.length?t:1===t.length?[e,e]:null}function M(e){var t=F(e);return t?t.join("/"):null}function P(e){for(var t=Ho.exec(e),n={},r=14;r--;){var o=Po[r],i=t[r]||"",s=["user","password"].indexOf(o)!==-1;n[o]=s?decodeURIComponent(i):i}return n[Uo]={},n[Po[12]].replace(Jo,function(e,t,r){t&&(n[Uo][t]=r)}),n}function U(e,t){var n=[],r=[];for(var o in t)t.hasOwnProperty(o)&&(n.push(o),r.push(t[o]));return n.push(e),Function.apply(null,n).apply(null,r)}function J(e,t,n){return new vo(function(r,o){e.get(t,function(i,s){if(i){if(404!==i.status)return o(i);s={}}var a=s._rev,u=n(s);if(!u)return r({updated:!1,rev:a});u._id=t,u._rev=a,r(H(e,u,n))})})}function H(e,t,n){return e.put(t).then(function(e){return{updated:!0,rev:e.rev}},function(r){if(409!==r.status)throw r;return J(e,t._id,n)})}function W(e){return 0|Math.random()*e}function z(e,t){t=t||Wo.length;var n="",r=-1;if(e){for(;++r<e;)n+=Wo[W(t)];return n}for(;++r<36;)switch(r){case 8:case 13:case 18:case 23:n+="-";break;case 19:n+=Wo[3&W(16)|8];break;default:n+=Wo[W(16)]}return n}function K(e){for(var t,n,r,o,i=e.rev_tree.slice();o=i.pop();){var s=o.ids,a=s[2],u=o.pos;if(a.length)for(var c=0,f=a.length;c<f;c++)i.push({pos:u+1,ids:a[c]});else{var l=!!s[1].deleted,d=s[0];t&&!(r!==l?r:n!==u?n<u:t<d)||(t=d,n=u,r=l)}}return n+"-"+t}function X(e,t){for(var n,r=e.slice();n=r.pop();)for(var o=n.pos,i=n.ids,s=i[2],a=t(0===s.length,o,i[0],n.ctx,i[1]),u=0,c=s.length;u<c;u++)r.push({pos:o+1,ids:s[u],ctx:a})}function G(e,t){return e.pos-t.pos}function V(e){var t=[];X(e,function(e,n,r,o,i){e&&t.push({rev:n+"-"+r,pos:n,opts:i})}),t.sort(G).reverse();for(var n=0,r=t.length;n<r;n++)delete t[n].pos;return t}function Q(e){for(var t=K(e),n=V(e.rev_tree),r=[],o=0,i=n.length;o<i;o++){var s=n[o];s.rev===t||s.opts.deleted||r.push(s.rev)}return r}
-function Y(e){var t=[];return X(e.rev_tree,function(e,n,r,o,i){"available"!==i.status||e||(t.push(n+"-"+r),i.status="missing")}),t}function Z(e){for(var t,n=[],r=e.slice();t=r.pop();){var o=t.pos,i=t.ids,s=i[0],a=i[1],u=i[2],c=0===u.length,f=t.history?t.history.slice():[];f.push({id:s,opts:a}),c&&n.push({pos:o+1-f.length,ids:f});for(var l=0,d=u.length;l<d;l++)r.push({pos:o+1,ids:u[l],history:f})}return n.reverse()}function ee(e,t){return e.pos-t.pos}function te(e,t,n){for(var r,o=0,i=e.length;o<i;)r=o+i>>>1,n(e[r],t)<0?o=r+1:i=r;return o}function ne(e,t,n){var r=te(e,t,n);e.splice(r,0,t)}function re(e,t){for(var n,r,o=t,i=e.length;o<i;o++){var s=e[o],a=[s.id,s.opts,[]];r?(r[2].push(a),r=a):n=r=a}return n}function oe(e,t){return e[0]<t[0]?-1:1}function ie(e,t){for(var n=[{tree1:e,tree2:t}],r=!1;n.length>0;){var o=n.pop(),i=o.tree1,s=o.tree2;(i[1].status||s[1].status)&&(i[1].status="available"===i[1].status||"available"===s[1].status?"available":"missing");for(var a=0;a<s[2].length;a++)if(i[2][0]){for(var u=!1,c=0;c<i[2].length;c++)i[2][c][0]===s[2][a][0]&&(n.push({tree1:i[2][c],tree2:s[2][a]}),u=!0);u||(r="new_branch",ne(i[2],s[2][a],oe))}else r="new_leaf",i[2][0]=s[2][a]}return{conflicts:r,tree:e}}function se(e,t,n){var r,o=[],i=!1,s=!1;if(!e.length)return{tree:[t],conflicts:"new_leaf"};for(var a=0,u=e.length;a<u;a++){var c=e[a];if(c.pos===t.pos&&c.ids[0]===t.ids[0])r=ie(c.ids,t.ids),o.push({pos:c.pos,ids:r.tree}),i=i||r.conflicts,s=!0;else if(n!==!0){var f=c.pos<t.pos?c:t,l=c.pos<t.pos?t:c,d=l.pos-f.pos,h=[],p=[];for(p.push({ids:f.ids,diff:d,parent:null,parentIdx:null});p.length>0;){var v=p.pop();if(0!==v.diff)for(var g=v.ids[2],y=0,_=g.length;y<_;y++)p.push({ids:g[y],diff:v.diff-1,parent:v.ids,parentIdx:y});else v.ids[0]===l.ids[0]&&h.push(v)}var m=h[0];m?(r=ie(m.ids,l.ids),m.parent[2][m.parentIdx]=r.tree,o.push({pos:f.pos,ids:f.ids}),i=i||r.conflicts,s=!0):o.push(c)}else o.push(c)}return s||o.push(t),o.sort(ee),{tree:o,conflicts:i||"internal_node"}}function ae(e,t){for(var n,r,o=Z(e),i=0,s=o.length;i<s;i++){var a,u=o[i],c=u.ids;if(c.length>t){n||(n={});var f=c.length-t;a={pos:u.pos+f,ids:re(c,f)};for(var l=0;l<f;l++){var d=u.pos+l+"-"+c[l].id;n[d]=!0}}else a={pos:u.pos,ids:re(c,0)};r=r?se(r,a,!0).tree:[a]}return n&&X(r,function(e,t,r){delete n[t+"-"+r]}),{tree:r,revs:n?Object.keys(n):[]}}function ue(e,t,n){var r=se(e,t),o=ae(r.tree,n);return{tree:o.tree,stemmedRevs:o.revs,conflicts:r.conflicts}}function ce(e,t){for(var n,r=e.slice(),o=t.split("-"),i=parseInt(o[0],10),s=o[1];n=r.pop();){if(n.pos===i&&n.ids[0]===s)return!0;for(var a=n.ids[2],u=0,c=a.length;u<c;u++)r.push({pos:n.pos+1,ids:a[u]})}return!1}function fe(e){return e.ids}function le(e,t){t||(t=K(e));for(var n,r=t.substring(t.indexOf("-")+1),o=e.rev_tree.map(fe);n=o.pop();){if(n[0]===r)return!!n[1].deleted;o=o.concat(n[2])}}function de(e){return/^_local/.test(e)}function he(e,t){for(var n,r=t.rev_tree.slice();n=r.pop();){var o=n.pos,i=n.ids,s=i[0],a=i[1],u=i[2],c=0===u.length,f=n.history?n.history.slice():[];if(f.push({id:s,pos:o,opts:a}),c)for(var l=0,d=f.length;l<d;l++){var h=f[l],p=h.pos+"-"+h.id;if(p===e)return o+"-"+s}for(var v=0,g=u.length;v<g;v++)r.push({pos:o+1,ids:u[v],history:f})}throw new Error("Unable to resolve latest revision for id "+t.id+", rev "+e)}function pe(e,t){try{e.emit("change",t)}catch(e){q("error",'Error in .on("change", function):',e)}}function ve(e,t,n){function r(){o.cancel()}uo.EventEmitter.call(this);var o=this;this.db=e,t=t?u(t):{};var i=t.complete=c(function(t,n){t?$(o,"error")>0&&o.emit("error",t):o.emit("complete",n),o.removeAllListeners(),e.removeListener("destroyed",r)});n&&(o.on("complete",function(e){n(null,e)}),o.on("error",n)),e.once("destroyed",r),t.onChange=function(e){o.isCancelled||pe(o,e)};var s=new vo(function(e,n){t.complete=function(t,r){t?n(t):e(r)}});o.once("cancel",function(){e.removeListener("destroyed",r),t.complete(null,{status:"cancelled"})}),this.then=s.then.bind(s),this.catch=s.catch.bind(s),this.then(function(e){i(null,e)},i),e.taskqueue.isReady?o.validateChanges(t):e.taskqueue.addTask(function(e){e?t.complete(e):o.isCancelled?o.emit("cancel"):o.validateChanges(t)})}function ge(e,t,n){var r=[{rev:e._rev}];"all_docs"===n.style&&(r=V(t.rev_tree).map(function(e){return{rev:e.rev}}));var o={id:t.id,changes:r,doc:e};return le(t,e._rev)&&(o.deleted=!0),n.conflicts&&(o.doc._conflicts=Q(t),o.doc._conflicts.length||delete o.doc._conflicts),o}function ye(e,t){return e<t?-1:e>t?1:0}function _e(e){return function(t,n){t||n[0]&&n[0].error?e(t||n[0]):e(null,n.length?n[0]:n)}}function me(e){for(var t=0;t<e.length;t++){var n=e[t];if(n._deleted)delete n._attachments;else if(n._attachments)for(var r=Object.keys(n._attachments),o=0;o<r.length;o++){var i=r[o];n._attachments[i]=y(n._attachments[i],["data","digest","content_type","length","revpos","stub"])}}}function be(e,t){var n=ye(e._id,t._id);return 0!==n?n:ye(e._revisions?e._revisions.start:0,t._revisions?t._revisions.start:0)}function we(e){var t={},n=[];return X(e,function(e,r,o,i){var s=r+"-"+o;return e&&(t[s]=0),void 0!==i&&n.push({from:i,to:s}),s}),n.reverse(),n.forEach(function(e){void 0===t[e.from]?t[e.from]=1+t[e.to]:t[e.from]=Math.min(t[e.from],1+t[e.to])}),t}function Ee(e,t,n){var r="limit"in t?t.keys.slice(t.skip,t.limit+t.skip):t.skip>0?t.keys.slice(t.skip):t.keys;if(t.descending&&r.reverse(),!r.length)return e._allDocs({limit:0},n);var o={offset:t.skip};return vo.all(r.map(function(n){var r=So({key:n,deleted:"ok"},t);return["limit","skip","keys"].forEach(function(e){delete r[e]}),new vo(function(t,i){e._allDocs(r,function(e,r){if(e)return i(e);o.total_rows=r.total_rows,t(r.rows[0]||{key:n,error:"not_found"})})})})).then(function(e){return o.rows=e,o})}function Se(e){var t=e._compactionQueue[0],n=t.opts,r=t.callback;e.get("_local/compaction").catch(function(){return!1}).then(function(t){t&&t.last_seq&&(n.last_seq=t.last_seq),e._compact(n,function(t,n){t?r(t):r(null,n),fo(function(){e._compactionQueue.shift(),e._compactionQueue.length&&Se(e)})})})}function ke(e){return"_"===e.charAt(0)&&e+" is not a valid attachment name, attachment names cannot start with '_'"}function qe(){uo.EventEmitter.call(this)}function Ae(){this.isReady=!1,this.failed=!1,this.queue=[]}function xe(e,t){var n=e.match(/([a-z\-]*):\/\/(.*)/);if(n)return{name:/https?/.test(n[1])?n[1]+"://"+n[2]:n[2],adapter:n[1]};var r=Te.adapters,o=Te.preferredAdapters,i=Te.prefix,s=t.adapter;if(!s)for(var a=0;a<o.length;++a){s=o[a];{if(!("idb"===s&&"websql"in r&&E()&&localStorage["_pouch__websqldb_"+i+e]))break;q("log",'PouchDB is downgrading "'+e+'" to WebSQL to avoid data loss, because it was already opened with WebSQL.')}}var u=r[s];return{name:u&&"use_prefix"in u&&!u.use_prefix?e:i+e,adapter:s}}function Oe(e){function t(){e.removeListener("closed",r),e.constructor.emit("destroyed",e.name)}function n(){e.removeListener("destroyed",t),e.removeListener("closed",r),e.emit("destroyed")}function r(){e.removeListener("destroyed",t),o.delete(e.name)}var o=e.constructor._destructionListeners;e.once("destroyed",t),e.once("closed",r),o.has(e.name)||o.set(e.name,[]),o.get(e.name).push(n)}function Te(e,t){if(!(this instanceof Te))return new Te(e,t);var n=this;if(t=t||{},e&&"object"==typeof e&&(t=e,e=t.name,delete t.name),this.__opts=t=u(t),n.auto_compaction=t.auto_compaction,n.prefix=Te.prefix,"string"!=typeof e)throw new Error("Missing/invalid DB name");var r=(t.prefix||"")+e,o=xe(r,t);if(t.name=o.name,t.adapter=t.adapter||o.adapter,n.name=e,n._adapter=t.adapter,Te.emit("debug",["adapter","Picked adapter: ",t.adapter]),!Te.adapters[t.adapter]||!Te.adapters[t.adapter].valid())throw new Error("Invalid Adapter: "+t.adapter);qe.call(n),n.taskqueue=new Ae,n.adapter=t.adapter,Te.adapters[t.adapter].call(n,t,function(e){if(e)return n.taskqueue.fail(e);Oe(n),n.emit("created",n),Te.emit("created",n.name),n.taskqueue.ready(n)})}function je(e){e.debug=lo;var t={};e.on("debug",function(e){var n=e[0],r=e.slice(1);t[n]||(t[n]=lo("pouchdb:"+n)),t[n].apply(null,r)})}function Ce(e,t){for(var n=e,r=0,o=t.length;r<o;r++){if(!(n=n[t[r]]))break}return n}function Le(e,t){return e<t?-1:e>t?1:0}function Ie(e){for(var t=[],n="",r=0,o=e.length;r<o;r++){var i=e[r];"."===i?r>0&&"\\"===e[r-1]?n=n.substring(0,n.length-1)+".":(t.push(n),n=""):n+=i}return t.push(n),t}function De(e){return Ko.indexOf(e)>-1}function Re(e){return Object.keys(e)[0]}function Ne(e){return e[Re(e)]}function Be(e){var t={};return e.forEach(function(e){Object.keys(e).forEach(function(n){var r=e[n];if("object"!=typeof r&&(r={$eq:r}),De(n))r instanceof Array?t[n]=r.map(function(e){return Be([e])}):t[n]=Be([r]);else{var o=t[n]=t[n]||{};Object.keys(r).forEach(function(e){var t=r[e];return"$gt"===e||"$gte"===e?$e(e,t,o):"$lt"===e||"$lte"===e?Fe(e,t,o):"$ne"===e?Me(t,o):"$eq"===e?Pe(t,o):void(o[e]=t)})}})}),t}function $e(e,t,n){void 0===n.$eq&&(void 0!==n.$gte?"$gte"===e?t>n.$gte&&(n.$gte=t):t>=n.$gte&&(delete n.$gte,n.$gt=t):void 0!==n.$gt?"$gte"===e?t>n.$gt&&(delete n.$gt,n.$gte=t):t>n.$gt&&(n.$gt=t):n[e]=t)}function Fe(e,t,n){void 0===n.$eq&&(void 0!==n.$lte?"$lte"===e?t<n.$lte&&(n.$lte=t):t<=n.$lte&&(delete n.$lte,n.$lt=t):void 0!==n.$lt?"$lte"===e?t<n.$lt&&(delete n.$lt,n.$lte=t):t<n.$lt&&(n.$lt=t):n[e]=t)}function Me(e,t){"$ne"in t?t.$ne.push(e):t.$ne=[e]}function Pe(e,t){delete t.$gt,delete t.$gte,delete t.$lt,delete t.$lte,delete t.$ne,t.$eq=e}function Ue(e){var t=u(e),n=!1;"$and"in t&&(t=Be(t.$and),n=!0),["$or","$nor"].forEach(function(e){e in t&&t[e].forEach(function(e){for(var t=Object.keys(e),n=0;n<t.length;n++){var r=t[n],o=e[r];"object"==typeof o&&null!==o||(e[r]={$eq:o})}})}),"$not"in t&&(t.$not=Be([t.$not]));for(var r=Object.keys(t),o=0;o<r.length;o++){var i=r[o],s=t[i];"object"!=typeof s||null===s?s={$eq:s}:"$ne"in s&&!n&&(s.$ne=[s.$ne]),t[i]=s}return t}function Je(e,t,n){for(var r="",o=n-e.length;r.length<o;)r+=t;return r}function He(e,t,n){return Je(e,t,n)+e}function We(e,t){if(e===t)return 0;e=ze(e),t=ze(t);var n=tt(e),r=tt(t);if(n-r!=0)return n-r;switch(typeof e){case"number":return e-t;case"boolean":return e<t?-1:1;case"string":return Ze(e,t)}return Array.isArray(e)?Ye(e,t):et(e,t)}function ze(e){switch(typeof e){case"undefined":return null;case"number":return 1/0===e||e===-1/0||isNaN(e)?null:e;case"object":var t=e;if(Array.isArray(e)){var n=e.length;e=new Array(n);for(var r=0;r<n;r++)e[r]=ze(t[r])}else{if(e instanceof Date)return e.toJSON();if(null!==e){e={};for(var o in t)if(t.hasOwnProperty(o)){var i=t[o];void 0!==i&&(e[o]=ze(i))}}}}return e}function Ke(e){if(null!==e)switch(typeof e){case"boolean":return e?1:0;case"number":return nt(e);case"string":return e.replace(/\u0002/g,"").replace(/\u0001/g,"").replace(/\u0000/g,"");case"object":var t=Array.isArray(e),n=t?e:Object.keys(e),r=-1,o=n.length,i="";if(t)for(;++r<o;)i+=Xe(n[r]);else for(;++r<o;){var s=n[r];i+=Xe(s)+Xe(e[s])}return i}return""}function Xe(e){return e=ze(e),tt(e)+Vo+Ke(e)+"\0"}function Ge(e,t){var n,r=t;if("1"===e[t])n=0,t++;else{var o="0"===e[t];t++;var i="",s=e.substring(t,t+Go),a=parseInt(s,10)+Xo;for(o&&(a=-a),t+=Go;;){var u=e[t];if("\0"===u)break;i+=u,t++}i=i.split("."),n=1===i.length?parseInt(i,10):parseFloat(i[0]+"."+i[1]),o&&(n-=10),0!==a&&(n=parseFloat(n+"e"+a))}return{num:n,length:t-r}}function Ve(e,t){var n=e.pop();if(t.length){var r=t[t.length-1];n===r.element&&(t.pop(),r=t[t.length-1]);var o=r.element,i=r.index;if(Array.isArray(o))o.push(n);else if(i===e.length-2){var s=e.pop();o[s]=n}else e.push(n)}}function Qe(e){for(var t=[],n=[],r=0;;){var o=e[r++];if("\0"!==o)switch(o){case"1":t.push(null);break;case"2":t.push("1"===e[r]),r++;break;case"3":var i=Ge(e,r);t.push(i.num),r+=i.length;break;case"4":for(var s="";;){var a=e[r];if("\0"===a)break;s+=a,r++}s=s.replace(/\u0001\u0001/g,"\0").replace(/\u0001\u0002/g,"").replace(/\u0002\u0002/g,""),t.push(s);break;case"5":var u={element:[],index:t.length};t.push(u.element),n.push(u);break;case"6":var c={element:{},index:t.length};t.push(c.element),n.push(c);break;default:throw new Error("bad collationIndex or unexpectedly reached end of input: "+o)}else{if(1===t.length)return t.pop();Ve(t,n)}}}function Ye(e,t){for(var n=Math.min(e.length,t.length),r=0;r<n;r++){var o=We(e[r],t[r]);if(0!==o)return o}return e.length===t.length?0:e.length>t.length?1:-1}function Ze(e,t){return e===t?0:e>t?1:-1}function et(e,t){for(var n=Object.keys(e),r=Object.keys(t),o=Math.min(n.length,r.length),i=0;i<o;i++){var s=We(n[i],r[i]);if(0!==s)return s;if(0!==(s=We(e[n[i]],t[r[i]])))return s}return n.length===r.length?0:n.length>r.length?1:-1}function tt(e){var t=["boolean","number","string","object"],n=t.indexOf(typeof e);return~n?null===e?1:Array.isArray(e)?5:n<3?n+2:n+3:Array.isArray(e)?5:void 0}function nt(e){if(0===e)return"1";var t=e.toExponential().split(/e\+?/),n=parseInt(t[1],10),r=e<0,o=r?"0":"2",i=(r?-n:n)-Xo,s=He(i.toString(),"0",Go);o+=Vo+s;var a=Math.abs(parseFloat(t[0]));r&&(a=10-a);var u=a.toFixed(20);return u=u.replace(/\.?0+$/,""),o+=Vo+u}function rt(e){function t(t){return e.map(function(e){var n=Re(e),r=Ie(n);return Ce(t,r)})}return function(e,n){var r=t(e.doc),o=t(n.doc),i=We(r,o);return 0!==i?i:Le(e.doc._id,n.doc._id)}}function ot(e,t,n){if(e=e.filter(function(e){return it(e.doc,t.selector,n)}),t.sort){var r=rt(t.sort);e=e.sort(r),"string"!=typeof t.sort[0]&&"desc"===Ne(t.sort[0])&&(e=e.reverse())}if("limit"in t||"skip"in t){var o=t.skip||0,i=("limit"in t?t.limit:e.length)+o;e=e.slice(o,i)}return e}function it(e,t,n){return n.every(function(n){if(st(e))return!1;var r=t[n],o=Ie(n),i=Ce(e,o);return De(n)?ut(n,r,e):at(r,e,o,i)})}function st(e){return/^_design\//.test(e._id)}function at(e,t,n,r){return!e||Object.keys(e).every(function(o){var i=e[o];return ct(o,t,i,n,r)})}function ut(e,t,n){return"$or"===e?t.some(function(e){return it(n,e,Object.keys(e))}):"$not"===e?!it(n,t,Object.keys(t)):!t.find(function(e){return it(n,e,Object.keys(e))})}function ct(e,t,n,r,o){if(!Qo[e])throw new Error('unknown operator "'+e+'" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, $nin, $size, $mod, $regex, $elemMatch, $type or $all');return Qo[e](t,n,r,o)}function ft(e){return void 0!==e&&null!==e}function lt(e){return void 0!==e}function dt(e,t){var n=t[0],r=t[1];if(0===n)throw new Error("Bad divisor, cannot divide by zero");if(parseInt(n,10)!==n)throw new Error("Divisor is not an integer");if(parseInt(r,10)!==r)throw new Error("Modulus is not an integer");return parseInt(e,10)===e&&e%n===r}function ht(e,t){return t.some(function(t){return e instanceof Array?e.indexOf(t)>-1:e===t})}function pt(e,t){return t.every(function(t){return e.indexOf(t)>-1})}function vt(e,t){return e.length===t}function gt(e,t){return new RegExp(t).test(e)}function yt(e,t){switch(t){case"null":return null===e;case"boolean":return"boolean"==typeof e;case"number":return"number"==typeof e;case"string":return"string"==typeof e;case"array":return e instanceof Array;case"object":return"[object Object]"==={}.toString.call(e)}throw new Error(t+" not supported as a type.Please use one of object, string, array, number, boolean or null.")}function _t(e,t){if("object"!=typeof t)throw"Selector error: expected a JSON object";t=Ue(t);var n={doc:e},r=ot([n],{selector:t},Object.keys(t));return r&&1===r.length}function mt(e){return U('"use strict";\nreturn '+e+";",{})}function bt(e){return U(["return function(doc) {",' "use strict";'," var emitted = false;"," var emit = function (a, b) {"," emitted = true;"," };"," var view = "+e+";"," view(doc);"," if (emitted) {"," return true;"," }","};"].join("\n"),{})}function wt(e,t){if(e.selector&&e.filter&&"_selector"!==e.filter){var n="string"==typeof e.filter?e.filter:"function";return t(new Error('selector invalid for filter "'+n+'"'))}t()}function Et(e){e.view&&!e.filter&&(e.filter="_view"),e.selector&&!e.filter&&(e.filter="_selector"),e.filter&&"string"==typeof e.filter&&("_view"===e.filter?e.view=M(e.view):e.filter=M(e.filter))}function St(e,t){return t.filter&&"string"==typeof t.filter&&!t.doc_ids&&!B(e.db)}function kt(e,t){var n=t.complete;if("_view"===t.filter){if(!t.view||"string"!=typeof t.view){var r=j(Do,"`view` filter parameter not found or invalid.");return n(r)}var o=F(t.view);e.db.get("_design/"+o[0],function(r,i){if(e.isCancelled)return n(null,{status:"cancelled"});if(r)return n(C(r));var s=i&&i.views&&i.views[o[1]]&&i.views[o[1]].map;if(!s)return n(j(qo,i.views?"missing json key: "+o[1]:"missing json key: views"));t.filter=bt(s),e.doChanges(t)})}else if(t.selector)t.filter=function(e){return _t(e,t.selector)},e.doChanges(t);else{var i=F(t.filter);e.db.get("_design/"+i[0],function(r,o){if(e.isCancelled)return n(null,{status:"cancelled"});if(r)return n(C(r));var s=o&&o.filters&&o.filters[i[1]];if(!s)return n(j(qo,o&&o.filters?"missing json key: "+i[1]:"missing json key: filters"));t.filter=mt(s),e.doChanges(t)})}}function qt(e){e._changesFilterPlugin={validate:wt,normalize:Et,shouldFilter:St,filter:kt}}function At(e){return e.reduce(function(e,t){return e[t]=!0,e},{})}function xt(e){if(!/^\d+\-./.test(e))return j($o);var t=e.indexOf("-"),n=e.substring(0,t),r=e.substring(t+1);return{prefix:parseInt(n,10),id:r}}function Ot(e,t){for(var n=e.start-e.ids.length+1,r=e.ids,o=[r[0],t,[]],i=1,s=r.length;i<s;i++)o=[r[i],{status:"missing"},[o]];return[{pos:n,ids:o}]}function Tt(e,t){var n,r,o,i={status:"available"};if(e._deleted&&(i.deleted=!0),t)if(e._id||(e._id=z()),r=z(32,16).toLowerCase(),e._rev){if(o=xt(e._rev),o.error)return o;e._rev_tree=[{pos:o.prefix,ids:[o.id,{status:"missing"},[[r,i,[]]]]}],n=o.prefix+1}else e._rev_tree=[{pos:1,ids:[r,i,[]]}],n=1;else if(e._revisions&&(e._rev_tree=Ot(e._revisions,i),n=e._revisions.start,r=e._revisions.ids[0]),!e._rev_tree){if(o=xt(e._rev),o.error)return o;n=o.prefix,r=o.id,e._rev_tree=[{pos:n,ids:[r,i,[]]}]}N(e._id),e._rev=n+"-"+r;var s={metadata:{},data:{}};for(var a in e)if(Object.prototype.hasOwnProperty.call(e,a)){var u="_"===a[0];if(u&&!Zo[a]){var c=j(Io,a);throw c.message=Io.message+": "+a,c}u&&!ei[a]?s.metadata[a.slice(1)]=e[a]:s.data[a]=e[a]}return s}function jt(e,t){e=e||[],t=t||{};try{return new Blob(e,t)}catch(i){if("TypeError"!==i.name)throw i;for(var n="undefined"!=typeof BlobBuilder?BlobBuilder:"undefined"!=typeof MSBlobBuilder?MSBlobBuilder:"undefined"!=typeof MozBlobBuilder?MozBlobBuilder:WebKitBlobBuilder,r=new n,o=0;o<e.length;o+=1)r.append(e[o]);return r.getBlob(t.type)}}function Ct(e){for(var t=e.length,n=new ArrayBuffer(t),r=new Uint8Array(n),o=0;o<t;o++)r[o]=e.charCodeAt(o);return n}function Lt(e,t){return jt([Ct(e)],{type:t})}function It(e,t){return Lt(ti(e),t)}function Dt(e){for(var t="",n=new Uint8Array(e),r=n.byteLength,o=0;o<r;o++)t+=String.fromCharCode(n[o]);return t}function Rt(e,t){if("undefined"==typeof FileReader)return t(Dt((new FileReaderSync).readAsArrayBuffer(e)));var n=new FileReader,r="function"==typeof n.readAsBinaryString;n.onloadend=function(e){var n=e.target.result||"";if(r)return t(n);t(Dt(n))},r?n.readAsBinaryString(e):n.readAsArrayBuffer(e)}function Nt(e,t){Rt(e,function(e){t(e)})}function Bt(e,t){Nt(e,function(e){t(ni(e))})}function $t(e,t){if("undefined"==typeof FileReader)return t((new FileReaderSync).readAsArrayBuffer(e));var n=new FileReader;n.onloadend=function(e){var n=e.target.result||new ArrayBuffer(0);t(n)},n.readAsArrayBuffer(e)}function Ft(e){return ni(e)}function Mt(e,t,n){return e.webkitSlice?e.webkitSlice(t,n):e.slice(t,n)}function Pt(e,t,n,r,o){(n>0||r<t.size)&&(t=Mt(t,n,r)),$t(t,function(t){e.append(t),o()})}function Ut(e,t,n,r,o){(n>0||r<t.length)&&(t=t.substring(n,r)),e.appendBinary(t),o()}function Jt(e,t){function n(){ri(o)}function r(){var e=f.end(!0),n=Ft(e);t(n),f.destroy()}function o(){var t=c*a,o=t+a;c++,c<u?l(f,e,t,o,n):l(f,e,t,o,r)}var i="string"==typeof e,s=i?e.length:e.size,a=Math.min(oi,s),u=Math.ceil(s/a),c=0,f=i?new ho:new ho.ArrayBuffer,l=i?Ut:Pt;o()}function Ht(e){return ho.hash(e)}function Wt(e){try{return ti(e)}catch(e){var t=j(Co,"Attachment is not a valid base64 string");return{error:t}}}function zt(e,t,n){var r=Wt(e.data);if(r.error)return n(r.error);e.length=r.length,e.data="blob"===t?Lt(r,e.content_type):"base64"===t?ni(r):r,Jt(r,function(t){e.digest="md5-"+t,n()})}function Kt(e,t,n){Jt(e.data,function(r){e.digest="md5-"+r,e.length=e.data.size||e.data.length||0,"binary"===t?Nt(e.data,function(t){e.data=t,n()}):"base64"===t?Bt(e.data,function(t){e.data=t,n()}):n()})}function Xt(e,t,n){if(e.stub)return n();"string"==typeof e.data?zt(e,t,n):Kt(e,t,n)}function Gt(e,t,n){function r(){i++,e.length===i&&(o?n(o):n())}if(!e.length)return n();var o,i=0;e.forEach(function(e){function n(e){o=e,++s===i.length&&r()}var i=e.data&&e.data._attachments?Object.keys(e.data._attachments):[],s=0;if(!i.length)return r();for(var a in e.data._attachments)e.data._attachments.hasOwnProperty(a)&&Xt(e.data._attachments[a],t,n)})}function Vt(e,t,n,r,o,i,s,a){if(ce(t.rev_tree,n.metadata.rev))return r[o]=n,i();var u=t.winningRev||K(t),c="deleted"in t?t.deleted:le(t,u),f="deleted"in n.metadata?n.metadata.deleted:le(n.metadata),l=/^1-/.test(n.metadata.rev);if(c&&!f&&a&&l){var d=n.data;d._rev=u,d._id=n.metadata.id,n=Tt(d,a)}var h=ue(t.rev_tree,n.metadata.rev_tree[0],e);if(a&&(c&&f&&"new_leaf"!==h.conflicts||!c&&"new_leaf"!==h.conflicts||c&&!f&&"new_branch"===h.conflicts)){var p=j(Ao);return r[o]=p,i()}var v=n.metadata.rev;n.metadata.rev_tree=h.tree,n.stemmedRevs=h.stemmedRevs||[],t.rev_map&&(n.metadata.rev_map=t.rev_map);var g,y=K(n.metadata),_=le(n.metadata,y),m=c===_?0:c<_?-1:1;g=v===y?_:le(n.metadata,v),s(n,y,_,g,!0,m,o,i)}function Qt(e){return"missing"===e.metadata.rev_tree[0].ids[1].status}function Yt(e,t,n,r,o,i,s,a,u){function c(e,t,n){var r=K(e.metadata),o=le(e.metadata,r);if("was_delete"in a&&o)return i[t]=j(qo,"deleted"),n();if(l&&Qt(e)){var u=j(Ao);return i[t]=u,n()}s(e,r,o,o,!1,o?0:1,t,n)}function f(){++h===p&&u&&u()}e=e||1e3;var l=a.new_edits,d=new mo,h=0,p=t.length;t.forEach(function(e,t){if(e._id&&de(e._id)){var r=e._deleted?"_removeLocal":"_putLocal";return void n[r](e,{ctx:o},function(e,n){i[t]=e||n,f()})}var s=e.metadata.id;d.has(s)?(p--,d.get(s).push([e,t])):d.set(s,[[e,t]])}),d.forEach(function(t,n){function o(){++u<t.length?a():f()}function a(){var a=t[u],f=a[0],d=a[1];if(r.has(n))Vt(e,r.get(n),f,i,d,o,s,l);else{var h=ue([],f.metadata.rev_tree[0],e);f.metadata.rev_tree=h.tree,f.stemmedRevs=h.stemmedRevs||[],c(f,d,o)}}var u=0;a()})}function Zt(e){try{return JSON.parse(e)}catch(t){return po.parse(e)}}function en(e){try{return JSON.stringify(e)}catch(t){return po.stringify(e)}}function tn(e){return function(t){var n="unknown_error";t.target&&t.target.error&&(n=t.target.error.name||t.target.error.message),e(j(No,n,t.type))}}function nn(e,t,n){return{data:en(e),winningRev:t,deletedOrLocal:n?"1":"0",seq:e.seq,id:e.id}}function rn(e){if(!e)return null;var t=Zt(e.data);return t.winningRev=e.winningRev,t.deleted="1"===e.deletedOrLocal,t.seq=e.seq,t}function on(e){if(!e)return e;var t=e._doc_id_rev.lastIndexOf(":");return e._id=e._doc_id_rev.substring(0,t-1),e._rev=e._doc_id_rev.substring(t+1),delete e._doc_id_rev,e}function sn(e,t,n,r){n?r(e?"string"!=typeof e?e:It(e,t):jt([""],{type:t})):e?"string"!=typeof e?Rt(e,function(e){r(ni(e))}):r(e):r("")}function an(e,t,n,r){function o(){++a===s.length&&r&&r()}function i(e,t){var r=e._attachments[t],i=r.digest;n.objectStore(ui).get(i).onsuccess=function(e){r.body=e.target.result.body,o()}}var s=Object.keys(e._attachments||{});if(!s.length)return r&&r();var a=0;s.forEach(function(n){t.attachments&&t.include_docs?i(e,n):(e._attachments[n].stub=!0,o())})}function un(e,t){return vo.all(e.map(function(e){if(e.doc&&e.doc._attachments){var n=Object.keys(e.doc._attachments);return vo.all(n.map(function(n){var r=e.doc._attachments[n];if("body"in r){var o=r.body,i=r.content_type;return new vo(function(s){sn(o,i,t,function(t){e.doc._attachments[n]=So(y(r,["digest","content_type"]),{data:t}),s()})})}}))}}))}function cn(e,t,n){function r(){--c||o()}function o(){i.length&&i.forEach(function(e){u.index("digestSeq").count(IDBKeyRange.bound(e+"::",e+"::￿",!1,!1)).onsuccess=function(t){t.target.result||a.delete(e)}})}var i=[],s=n.objectStore(ai),a=n.objectStore(ui),u=n.objectStore(ci),c=e.length;e.forEach(function(e){var n=s.index("_doc_id_rev"),o=t+"::"+e;n.getKey(o).onsuccess=function(e){var t=e.target.result;if("number"!=typeof t)return r();s.delete(t),u.index("seq").openCursor(IDBKeyRange.only(t)).onsuccess=function(e){var t=e.target.result;if(t){var n=t.value.digestSeq.split("::")[0];i.push(n),u.delete(t.primaryKey),t.continue()}else r()}}})}function fn(e,t,n){try{return{txn:e.transaction(t,n)}}catch(e){return{error:e}}}function ln(e,t,n,r,o,i){function s(){var e=[si,ai,ui,li,ci,fi],t=fn(o,e,"readwrite");if(t.error)return i(t.error);m=t.txn,m.onabort=tn(i),m.ontimeout=tn(i),m.oncomplete=l,b=m.objectStore(si),w=m.objectStore(ai),E=m.objectStore(ui),S=m.objectStore(ci),k=m.objectStore(fi),k.get(fi).onsuccess=function(e){A=e.target.result,c()},h(function(e){if(e)return N=!0,i(e);f()})}function a(){L=!0,c()}function u(){Yt(e.revs_limit,x,r,R,m,D,p,n,a)}function c(){A&&L&&(A.docCount+=I,k.put(A))}function f(){function e(){++n===x.length&&u()}function t(t){var n=rn(t.target.result);n&&R.set(n.id,n),e()}if(x.length)for(var n=0,r=0,o=x.length;r<o;r++){var i=x[r];if(i._id&&de(i._id))e();else{var s=b.get(i.metadata.id);s.onsuccess=t}}}function l(){N||(hi.notify(r._meta.name),i(null,D))}function d(e,t){E.get(e).onsuccess=function(n){if(n.target.result)t();else{var r=j(Fo,"unknown stub attachment with digest "+e);r.status=412,t(r)}}}function h(e){function t(){++o===n.length&&e(r)}var n=[];if(x.forEach(function(e){e.data&&e.data._attachments&&Object.keys(e.data._attachments).forEach(function(t){var r=e.data._attachments[t];r.stub&&n.push(r.digest)})}),!n.length)return e();var r,o=0;n.forEach(function(e){d(e,function(e){e&&!r&&(r=e),t()})})}function p(e,t,n,r,o,i,s,a){e.metadata.winningRev=t,e.metadata.deleted=n;var u=e.data;if(u._id=e.metadata.id,u._rev=e.metadata.rev,r&&(u._deleted=!0),u._attachments&&Object.keys(u._attachments).length)return g(e,t,n,o,s,a);I+=i,c(),v(e,t,n,o,s,a)}function v(e,t,n,o,i,s){function a(i){var s=e.stemmedRevs||[];o&&r.auto_compaction&&(s=s.concat(Y(e.metadata))),s&&s.length&&cn(s,e.metadata.id,m),l.seq=i.target.result;var a=nn(l,t,n);b.put(a).onsuccess=c}function u(e){e.preventDefault(),e.stopPropagation(),w.index("_doc_id_rev").getKey(f._doc_id_rev).onsuccess=function(e){w.put(f,e.target.result).onsuccess=a}}function c(){D[i]={ok:!0,id:l.id,rev:l.rev},R.set(e.metadata.id,e.metadata),y(e,l.seq,s)}var f=e.data,l=e.metadata;f._doc_id_rev=l.id+"::"+l.rev,delete f._id,delete f._rev;var d=w.put(f);d.onsuccess=a,d.onerror=u}function g(e,t,n,r,o,i){function s(){c===f.length&&v(e,t,n,r,o,i)}function a(){c++,s()}var u=e.data,c=0,f=Object.keys(u._attachments);f.forEach(function(n){var r=e.data._attachments[n];if(r.stub)c++,s();else{var o=r.data;delete r.data,r.revpos=parseInt(t,10);_(r.digest,o,a)}})}function y(e,t,n){function r(){++o===i.length&&n()}var o=0,i=Object.keys(e.data._attachments||{});if(!i.length)return n();for(var s=0;s<i.length;s++)!function(n){var o=e.data._attachments[n].digest,i=S.put({seq:t,digestSeq:o+"::"+t});i.onsuccess=r,i.onerror=function(e){e.preventDefault(),e.stopPropagation(),r()}}(i[s])}function _(e,t,n){E.count(e).onsuccess=function(r){if(r.target.result)return n();var o={digest:e,body:t};E.put(o).onsuccess=n}}for(var m,b,w,E,S,k,q,A,x=t.docs,O=0,T=x.length;O<T;O++){var C=x[O];C._id&&de(C._id)||(C=x[O]=Tt(C,n.new_edits),C.error&&!q&&(q=C))}if(q)return i(q);var L=!1,I=0,D=new Array(x.length),R=new mo,N=!1,B=r._meta.blobSupport?"blob":"base64";Gt(x,B,function(e){if(e)return i(e);s()})}function dn(e,t,n,r,o){function i(e){f=e.target.result,c&&o(c,f,l)}function s(e){c=e.target.result,f&&o(c,f,l)}function a(){if(!c.length)return o();var n,a=c[c.length-1];if(t&&t.upper)try{n=IDBKeyRange.bound(a,t.upper,!0,t.upperOpen)}catch(e){if("DataError"===e.name&&0===e.code)return o()}else n=IDBKeyRange.lowerBound(a,!0);t=n,c=null,f=null,e.getAll(t,r).onsuccess=i,e.getAllKeys(t,r).onsuccess=s}function u(e){var t=e.target.result;if(!t)return o();o([t.key],[t.value],t)}var c,f,l,d="function"==typeof e.getAll&&"function"==typeof e.getAllKeys&&r>1&&!n;d?(l={continue:a},e.getAll(t,r).onsuccess=i,e.getAllKeys(t,r).onsuccess=s):n?e.openCursor(t,"prev").onsuccess=u:e.openCursor(t).onsuccess=u}function hn(e,t,n){function r(e){var t=e.target.result;t?(o.push(t.value),t.continue()):n({target:{result:o}})}if("function"==typeof e.getAll)return void(e.getAll(t).onsuccess=n);var o=[];e.openCursor(t).onsuccess=r}function pn(e,t,n,r,o){try{if(e&&t)return o?IDBKeyRange.bound(t,e,!n,!1):IDBKeyRange.bound(e,t,!1,!n);if(e)return o?IDBKeyRange.upperBound(e):IDBKeyRange.lowerBound(e);if(t)return o?IDBKeyRange.lowerBound(t,!n):IDBKeyRange.upperBound(t,!n);if(r)return IDBKeyRange.only(r)}catch(e){return{error:e}}return null}function vn(e,t,n){function r(t,n,r){var o=t.id+"::"+r;q.get(o).onsuccess=function(r){if(n.doc=on(r.target.result),e.conflicts){var o=Q(t);o.length&&(n.doc._conflicts=o)}an(n.doc,e,b)}}function o(t,n){var o={id:n.id,key:n.id,value:{rev:t}},i=n.deleted;"ok"===e.deleted?(A.push(o),i?(o.value.deleted=!0,o.doc=null):e.include_docs&&r(n,o,t)):!i&&h--<=0&&(A.push(o),e.include_docs&&r(n,o,t))}function i(e){for(var t=0,n=e.length;t<n&&A.length!==p;t++){var r=e[t],i=rn(r);o(i.winningRev,i)}}function s(e,t,n){n&&(i(t),A.length<p&&n.continue())}function a(t){var n=t.target.result;e.descending&&(n=n.reverse()),i(n)}function u(){n(null,{total_rows:w,offset:e.skip,rows:A})}function c(){e.attachments?un(A,e.binary).then(u):u()}var f="startkey"in e&&e.startkey,l="endkey"in e&&e.endkey,d="key"in e&&e.key,h=e.skip||0,p="number"==typeof e.limit?e.limit:-1,v=e.inclusive_end!==!1,g=pn(f,l,v,d,e.descending),y=g&&g.error;if(y&&("DataError"!==y.name||0!==y.code))return n(j(No,y.name,y.message));var _=[si,ai,fi];e.attachments&&_.push(ui);var m=fn(t,_,"readonly");if(m.error)return n(m.error);var b=m.txn;b.oncomplete=c,b.onabort=tn(n);var w,E=b.objectStore(si),S=b.objectStore(ai),k=b.objectStore(fi),q=S.index("_doc_id_rev"),A=[];return k.get(fi).onsuccess=function(e){w=e.target.result.docCount},y||0===p?void 0:p===-1?hn(E,g,a):void dn(E,g,e.descending,p+h,s)}function gn(e){return new vo(function(t){var n=jt([""]);e.objectStore(di).put(n,"key").onsuccess=function(){var e=navigator.userAgent.match(/Chrome\/(\d+)/),n=navigator.userAgent.match(/Edge\//);t(n||!e||parseInt(e[1],10)>=43)},e.onabort=function(e){e.preventDefault(),e.stopPropagation(),t(!1)}}).catch(function(){return!1})}function yn(e,t){e.objectStore(si).index("deletedOrLocal").count(IDBKeyRange.only("0")).onsuccess=function(e){t(e.target.result)}}function _n(e,t,n,r){try{e(t,n)}catch(t){r.emit("error",t)}}function mn(){!pi&&vi.length&&(pi=!0,vi.shift()())}function bn(e,t,n){vi.push(function(){e(function(e,r){_n(t,e,r,n),pi=!1,fo(function(){mn(n)})})}),mn()}function wn(e,t,n,r){function o(t,n,r){function o(t,n){var r=e.processChange(n,t,e);d=r.seq=t.seq;var o=w(r);if("object"==typeof o)return e.complete(o);o&&(b++,p&&m.push(r),e.attachments&&e.include_docs?an(n,e,v,function(){un([r],e.binary).then(function(){e.onChange(r)})}):e.onChange(r))}function i(){for(var e=0,t=a.length;e<t&&b!==h;e++){var n=a[e];if(n){o(u[e],n)}}b!==h&&r.continue()}if(r&&t.length){var a=new Array(t.length),u=new Array(t.length),c=0;n.forEach(function(e,n){s(on(e),t[n],function(e,r){u[n]=e,a[n]=r,++c===t.length&&i()})})}}function i(e,t,n,r){if(n.seq!==t)return r();if(n.winningRev===e._rev)return r(n,e);var o=e._id+"::"+n.winningRev;_.get(o).onsuccess=function(e){r(n,on(e.target.result))}}function s(e,t,n){if(l&&!l.has(e._id))return n();var r=E.get(e._id);if(r)return i(e,t,r,n);y.get(e._id).onsuccess=function(o){r=rn(o.target.result),E.set(e._id,r),i(e,t,r,n)}}function a(){e.complete(null,{results:m,last_seq:d})}function c(){!e.continuous&&e.attachments?un(m).then(a):a()}if(e=u(e),e.continuous){var f=n+":"+z()
-;return hi.addListener(n,f,t,e),hi.notify(n),{cancel:function(){hi.removeListener(n,f)}}}var l=e.doc_ids&&new _o(e.doc_ids);e.since=e.since||0;var d=e.since,h="limit"in e?e.limit:-1;0===h&&(h=1);var p;p="return_docs"in e?e.return_docs:!("returnDocs"in e)||e.returnDocs;var v,g,y,_,m=[],b=0,w=I(e),E=new mo,S=[si,ai];e.attachments&&S.push(ui);var k=fn(r,S,"readonly");if(k.error)return e.complete(k.error);v=k.txn,v.onabort=tn(e.complete),v.oncomplete=c,g=v.objectStore(ai),y=v.objectStore(si),_=g.index("_doc_id_rev"),dn(g,e.since&&!e.descending?IDBKeyRange.lowerBound(e.since,!0):null,e.descending,h,o)}function En(e,t){var n=this;bn(function(t){Sn(n,e,t)},t,n.constructor)}function Sn(e,t,n){function r(e){var t=e.createObjectStore(si,{keyPath:"id"});e.createObjectStore(ai,{autoIncrement:!0}).createIndex("_doc_id_rev","_doc_id_rev",{unique:!0}),e.createObjectStore(ui,{keyPath:"digest"}),e.createObjectStore(fi,{keyPath:"id",autoIncrement:!1}),e.createObjectStore(di),t.createIndex("deletedOrLocal","deletedOrLocal",{unique:!1}),e.createObjectStore(li,{keyPath:"_id"});var n=e.createObjectStore(ci,{autoIncrement:!0});n.createIndex("seq","seq"),n.createIndex("digestSeq","digestSeq",{unique:!0})}function o(e,t){var n=e.objectStore(si);n.createIndex("deletedOrLocal","deletedOrLocal",{unique:!1}),n.openCursor().onsuccess=function(e){var r=e.target.result;if(r){var o=r.value,i=le(o);o.deletedOrLocal=i?"1":"0",n.put(o),r.continue()}else t()}}function i(e){e.createObjectStore(li,{keyPath:"_id"}).createIndex("_doc_id_rev","_doc_id_rev",{unique:!0})}function s(e,t){var n=e.objectStore(li),r=e.objectStore(si),o=e.objectStore(ai);r.openCursor().onsuccess=function(e){var i=e.target.result;if(i){var s=i.value,a=s.id,u=de(a),c=K(s);if(u){var f=a+"::"+c,l=a+"::",d=a+"::~",h=o.index("_doc_id_rev"),p=IDBKeyRange.bound(l,d,!1,!1),v=h.openCursor(p);v.onsuccess=function(e){if(v=e.target.result){var t=v.value;t._doc_id_rev===f&&n.put(t),o.delete(v.primaryKey),v.continue()}else r.delete(i.primaryKey),i.continue()}}else i.continue()}else t&&t()}}function a(e){var t=e.createObjectStore(ci,{autoIncrement:!0});t.createIndex("seq","seq"),t.createIndex("digestSeq","digestSeq",{unique:!0})}function u(e,t){var n=e.objectStore(ai),r=e.objectStore(ui),o=e.objectStore(ci);r.count().onsuccess=function(e){if(!e.target.result)return t();n.openCursor().onsuccess=function(e){var n=e.target.result;if(!n)return t();for(var r=n.value,i=n.primaryKey,s=Object.keys(r._attachments||{}),a={},u=0;u<s.length;u++)a[r._attachments[s[u]].digest]=!0;var c=Object.keys(a);for(u=0;u<c.length;u++){var f=c[u];o.put({seq:i,digestSeq:f+"::"+i})}n.continue()}}}function c(e){function t(e){return e.data?rn(e):(e.deleted="1"===e.deletedOrLocal,e)}var n=e.objectStore(ai),r=e.objectStore(si);r.openCursor().onsuccess=function(e){function o(){var e=nn(s,s.winningRev,s.deleted);r.put(e).onsuccess=function(){i.continue()}}var i=e.target.result;if(i){var s=t(i.value);if(s.winningRev=s.winningRev||K(s),s.seq)return o();!function(){var e=s.id+"::",t=s.id+"::￿",r=n.index("_doc_id_rev").openCursor(IDBKeyRange.bound(e,t)),i=0;r.onsuccess=function(e){var t=e.target.result;if(!t)return s.seq=i,o();var n=t.primaryKey;n>i&&(i=n),t.continue()}}()}}}var l=t.name,d=null;e._meta=null,e._remote=!1,e.type=function(){return"idb"},e._id=f(function(t){t(null,e._meta.instanceId)}),e._bulkDocs=function(n,r,o){ln(t,n,r,e,d,o)},e._get=function(e,t,n){function r(){n(s,{doc:o,metadata:i,ctx:a})}var o,i,s,a=t.ctx;if(!a){var u=fn(d,[si,ai,ui],"readonly");if(u.error)return n(u.error);a=u.txn}a.objectStore(si).get(e).onsuccess=function(e){if(!(i=rn(e.target.result)))return s=j(qo,"missing"),r();var n;if(t.rev)n=t.latest?he(t.rev,i):t.rev;else{n=i.winningRev;if(le(i))return s=j(qo,"deleted"),r()}var u=a.objectStore(ai),c=i.id+"::"+n;u.index("_doc_id_rev").get(c).onsuccess=function(e){if(o=e.target.result,o&&(o=on(o)),!o)return s=j(qo,"missing"),r();r()}}},e._getAttachment=function(e,t,n,r,o){var i;if(r.ctx)i=r.ctx;else{var s=fn(d,[si,ai,ui],"readonly");if(s.error)return o(s.error);i=s.txn}var a=n.digest,u=n.content_type;i.objectStore(ui).get(a).onsuccess=function(e){sn(e.target.result.body,u,r.binary,function(e){o(null,e)})}},e._info=function(t){var n,r,o=fn(d,[fi,ai],"readonly");if(o.error)return t(o.error);var i=o.txn;i.objectStore(fi).get(fi).onsuccess=function(e){r=e.target.result.docCount},i.objectStore(ai).openCursor(null,"prev").onsuccess=function(e){var t=e.target.result;n=t?t.key:0},i.oncomplete=function(){t(null,{doc_count:r,update_seq:n,idb_attachment_format:e._meta.blobSupport?"binary":"base64"})}},e._allDocs=function(e,t){vn(e,d,t)},e._changes=function(t){wn(t,e,l,d)},e._close=function(e){d.close(),gi.delete(l),e()},e._getRevisionTree=function(e,t){var n=fn(d,[si],"readonly");if(n.error)return t(n.error);n.txn.objectStore(si).get(e).onsuccess=function(e){var n=rn(e.target.result);n?t(null,n.rev_tree):t(j(qo))}},e._doCompaction=function(e,t,n){var r=[si,ai,ui,ci],o=fn(d,r,"readwrite");if(o.error)return n(o.error);var i=o.txn;i.objectStore(si).get(e).onsuccess=function(n){var r=rn(n.target.result);X(r.rev_tree,function(e,n,r,o,i){var s=n+"-"+r;t.indexOf(s)!==-1&&(i.status="missing")}),cn(t,e,i);var o=r.winningRev,s=r.deleted;i.objectStore(si).put(nn(r,o,s))},i.onabort=tn(n),i.oncomplete=function(){n()}},e._getLocal=function(e,t){var n=fn(d,[li],"readonly");if(n.error)return t(n.error);var r=n.txn,o=r.objectStore(li).get(e);o.onerror=tn(t),o.onsuccess=function(e){var n=e.target.result;n?(delete n._doc_id_rev,t(null,n)):t(j(qo))}},e._putLocal=function(e,t,n){"function"==typeof t&&(n=t,t={}),delete e._revisions;var r=e._rev,o=e._id;e._rev=r?"0-"+(parseInt(r.split("-")[1],10)+1):"0-1";var i,s=t.ctx;if(!s){var a=fn(d,[li],"readwrite");if(a.error)return n(a.error);s=a.txn,s.onerror=tn(n),s.oncomplete=function(){i&&n(null,i)}}var u,c=s.objectStore(li);r?(u=c.get(o),u.onsuccess=function(o){var s=o.target.result;if(s&&s._rev===r){c.put(e).onsuccess=function(){i={ok:!0,id:e._id,rev:e._rev},t.ctx&&n(null,i)}}else n(j(Ao))}):(u=c.add(e),u.onerror=function(e){n(j(Ao)),e.preventDefault(),e.stopPropagation()},u.onsuccess=function(){i={ok:!0,id:e._id,rev:e._rev},t.ctx&&n(null,i)})},e._removeLocal=function(e,t,n){"function"==typeof t&&(n=t,t={});var r=t.ctx;if(!r){var o=fn(d,[li],"readwrite");if(o.error)return n(o.error);r=o.txn,r.oncomplete=function(){i&&n(null,i)}}var i,s=e._id,a=r.objectStore(li),u=a.get(s);u.onerror=tn(n),u.onsuccess=function(r){var o=r.target.result;o&&o._rev===e._rev?(a.delete(s),i={ok:!0,id:s,rev:"0-0"},t.ctx&&n(null,i)):n(j(qo))}},e._destroy=function(e,t){hi.removeAllListeners(l);var n=yi.get(l);n&&n.result&&(n.result.close(),gi.delete(l));var r=indexedDB.deleteDatabase(l);r.onsuccess=function(){yi.delete(l),E()&&l in localStorage&&delete localStorage[l],t(null,{ok:!0})},r.onerror=tn(t)};var h=gi.get(l);if(h)return d=h.idb,e._meta=h.global,fo(function(){n(null,e)});var p;p=t.storage?kn(l,t.storage):indexedDB.open(l,ii),yi.set(l,p),p.onupgradeneeded=function(e){function t(){var e=l[d-1];d++,e&&e(f,t)}var n=e.target.result;if(e.oldVersion<1)return r(n);var f=e.currentTarget.transaction;e.oldVersion<3&&i(n),e.oldVersion<4&&a(n);var l=[o,s,u,c],d=e.oldVersion;t()},p.onsuccess=function(t){function r(){void 0!==a&&f&&(e._meta={name:l,instanceId:u,blobSupport:a},gi.set(l,{idb:d,global:e._meta}),n(null,e))}function o(){if(void 0!==s&&void 0!==i){var e=l+"_id";e in i?u=i[e]:i[e]=u=z(),i.docCount=s,c.objectStore(fi).put(i)}}d=t.target.result,d.onversionchange=function(){d.close(),gi.delete(l)},d.onabort=function(e){q("error","Database has a global failure",e.target.error),d.close(),gi.delete(l)};var i,s,a,u,c=d.transaction([fi,di,si],"readwrite"),f=!1;c.objectStore(fi).get(fi).onsuccess=function(e){i=e.target.result||{id:fi},o()},yn(c,function(e){s=e,o()}),Yo||(Yo=gn(c)),Yo.then(function(e){a=e,r()}),c.oncomplete=function(){f=!0,r()}},p.onerror=function(){var e="Failed to open indexedDB, are you in private browsing mode?";q("error",e),n(j(No,e))}}function kn(e,t){try{return indexedDB.open(e,{version:ii,storage:t})}catch(t){return indexedDB.open(e,ii)}}function qn(e){return decodeURIComponent(escape(e))}function An(e){return e<65?e-48:e-55}function xn(e,t,n){for(var r="";t<n;)r+=String.fromCharCode(An(e.charCodeAt(t++))<<4|An(e.charCodeAt(t++)));return r}function On(e,t,n){for(var r="";t<n;)r+=String.fromCharCode(An(e.charCodeAt(t+2))<<12|An(e.charCodeAt(t+3))<<8|An(e.charCodeAt(t))<<4|An(e.charCodeAt(t+1))),t+=4;return r}function Tn(e,t){return"UTF-8"===t?qn(xn(e,0,e.length)):On(e,0,e.length)}function jn(e){return"'"+e+"'"}function Cn(e){return e.replace(/\u0002/g,"").replace(/\u0001/g,"").replace(/\u0000/g,"")}function Ln(e){return e.replace(/\u0001\u0001/g,"\0").replace(/\u0001\u0002/g,"").replace(/\u0002\u0002/g,"")}function In(e){return delete e._id,delete e._rev,JSON.stringify(e)}function Dn(e,t,n){return e=JSON.parse(e),e._id=t,e._rev=n,e}function Rn(e){for(var t="(";e--;)t+="?",e&&(t+=",");return t+")"}function Nn(e,t,n,r,o){return"SELECT "+e+" FROM "+("string"==typeof t?t:t.join(" JOIN "))+(n?" ON "+n:"")+(r?" WHERE "+("string"==typeof r?r:r.join(" AND ")):"")+(o?" ORDER BY "+o:"")}function Bn(e,t,n){function r(){++i===e.length&&o()}function o(){if(s.length){var e="SELECT DISTINCT digest AS digest FROM "+qi+" WHERE seq IN "+Rn(s.length);n.executeSql(e,s,function(e,t){for(var n=[],r=0;r<t.rows.length;r++)n.push(t.rows.item(r).digest);if(n.length){var o="DELETE FROM "+qi+" WHERE seq IN ("+s.map(function(){return"?"}).join(",")+")";e.executeSql(o,s,function(e){var t="SELECT digest FROM "+qi+" WHERE digest IN ("+n.map(function(){return"?"}).join(",")+")";e.executeSql(t,n,function(e,t){for(var r=new _o,o=0;o<t.rows.length;o++)r.add(t.rows.item(o).digest);n.forEach(function(t){r.has(t)||(e.executeSql("DELETE FROM "+qi+" WHERE digest=?",[t]),e.executeSql("DELETE FROM "+Ei+" WHERE digest=?",[t]))})})})}})}}if(e.length){var i=0,s=[];e.forEach(function(e){var o="SELECT seq FROM "+wi+" WHERE doc_id=? AND rev=?";n.executeSql(o,[t,e],function(e,t){if(!t.rows.length)return r();var n=t.rows.item(0).seq;s.push(n),e.executeSql("DELETE FROM "+wi+" WHERE seq=?",[n],r)})})}}function $n(e){return function(t){q("error","WebSQL threw an error",t);var n=t&&t.constructor.toString().match(/function ([^\(]+)/),r=n&&n[1]||t.type,o=t.target||t.message;e(j(Bo,o,r))}}function Fn(e){return"size"in e?1e6*e.size:"undefined"!=typeof navigator&&/Android/.test(navigator.userAgent)?5e6:1}function Mn(e,t,n,r,o,i,s){function a(){if(m)return s(m);i.notify(r._name),s(null,b)}function u(e,t){var n="SELECT count(*) as cnt FROM "+Ei+" WHERE digest=?";_.executeSql(n,[e],function(n,r){if(0===r.rows.item(0).cnt){var o=j(Fo,"unknown stub attachment with digest "+e);t(o)}else t()})}function c(e){function t(){++o===n.length&&e(r)}var n=[];if(g.forEach(function(e){e.data&&e.data._attachments&&Object.keys(e.data._attachments).forEach(function(t){var r=e.data._attachments[t];r.stub&&n.push(r.digest)})}),!n.length)return e();var r,o=0;n.forEach(function(e){u(e,function(e){e&&!r&&(r=e),t()})})}function f(e,t,n,o,i,s,a,u){function c(){function t(e,t){function r(){return++o===i.length&&t(),!1}var o=0,i=Object.keys(n._attachments||{});if(!i.length)return t();for(var s=0;s<i.length;s++)!function(t){var o="INSERT INTO "+qi+" (digest, seq) VALUES (?,?)",i=[n._attachments[t].digest,e];_.executeSql(o,i,r,r)}(i[s])}var n=e.data,r=o?1:0,i=n._id,s=n._rev,a=In(n),u="INSERT INTO "+wi+" (doc_id, rev, json, deleted) VALUES (?, ?, ?, ?);",c=[i,s,a,r];_.executeSql(u,c,function(e,n){var r=n.insertId;t(r,function(){d(e,r)})},function(){var e=Nn("seq",wi,null,"doc_id=? AND rev=?");return _.executeSql(e,[i,s],function(e,n){var o=n.rows.item(0).seq,u="UPDATE "+wi+" SET json=?, deleted=? WHERE doc_id=? AND rev=?;",c=[a,r,i,s];e.executeSql(u,c,function(e){t(o,function(){d(e,o)})})}),!1})}function f(e){p||(e?(p=e,u(p)):v===g.length&&c())}function l(e){v++,f(e)}function d(n,o){var s=e.metadata.id,c=e.stemmedRevs||[];i&&r.auto_compaction&&(c=Y(e.metadata).concat(c)),c.length&&Bn(c,s,n),e.metadata.seq=o;var f=e.metadata.rev;delete e.metadata.rev;var l=i?"UPDATE "+bi+" SET json=?, max_seq=?, winningseq=(SELECT seq FROM "+wi+" WHERE doc_id="+bi+".id AND rev=?) WHERE id=?":"INSERT INTO "+bi+" (id, winningseq, max_seq, json) VALUES (?,?,?,?);",d=en(e.metadata),h=i?[d,o,t,s]:[s,o,o,d];n.executeSql(l,h,function(){b[a]={ok:!0,id:e.metadata.id,rev:f},w.set(s,e.metadata),u()})}var p=null,v=0;e.data._id=e.metadata.id,e.data._rev=e.metadata.rev;var g=Object.keys(e.data._attachments||{});o&&(e.data._deleted=!0),g.forEach(function(n){var r=e.data._attachments[n];if(r.stub)v++,f();else{var o=r.data;delete r.data,r.revpos=parseInt(t,10);h(r.digest,o,l)}}),g.length||c()}function l(){Yt(e.revs_limit,g,r,w,_,b,f,n)}function d(e){function t(){++n===g.length&&e()}if(!g.length)return e();var n=0;g.forEach(function(e){if(e._id&&de(e._id))return t();var n=e.metadata.id;_.executeSql("SELECT json FROM "+bi+" WHERE id = ?",[n],function(e,r){if(r.rows.length){var o=Zt(r.rows.item(0).json);w.set(n,o)}t()})})}function h(e,t,n){var r="SELECT digest FROM "+Ei+" WHERE digest=?";_.executeSql(r,[e],function(o,i){if(i.rows.length)return n();r="INSERT INTO "+Ei+" (digest, body, escaped) VALUES (?,?,1)",o.executeSql(r,[e,Cn(t)],function(){n()},function(){return n(),!1})})}var p=n.new_edits,v=t.docs,g=v.map(function(e){return e._id&&de(e._id)?e:Tt(e,p)}),y=g.filter(function(e){return e.error});if(y.length)return s(y[0]);var _,m,b=new Array(g.length),w=new mo;Gt(g,"binary",function(e){if(e)return s(e);o.transaction(function(e){_=e,c(function(e){e?m=e:d(l)})},$n(s),a)})}function Pn(e){return e.websql(e.name,e.version,e.description,e.size)}function Un(e){try{return{db:Pn(e)}}catch(e){return{error:e}}}function Jn(e){var t=Ai.get(e.name);return t||(t=Un(e),Ai.set(e.name,t)),t}function Hn(e,t,n,r,o){function i(){++u===a.length&&o&&o()}function s(e,o){var s=e._attachments[o],a={binary:t.binary,ctx:r};n._getAttachment(e._id,o,s,a,function(t,n){e._attachments[o]=So(y(s,["digest","content_type"]),{data:n}),i()})}var a=Object.keys(e._attachments||{});if(!a.length)return o&&o();var u=0;a.forEach(function(n){t.attachments&&t.include_docs?s(e,n):(e._attachments[n].stub=!0,i())})}function Wn(e,t){function n(){E()&&(window.localStorage["_pouch__websqldb_"+m._name]=!0),t(null,m)}function r(e,t){e.executeSql(Ci),e.executeSql("ALTER TABLE "+wi+" ADD COLUMN deleted TINYINT(1) DEFAULT 0",[],function(){e.executeSql(Ti),e.executeSql("ALTER TABLE "+bi+" ADD COLUMN local TINYINT(1) DEFAULT 0",[],function(){e.executeSql("CREATE INDEX IF NOT EXISTS 'doc-store-local-idx' ON "+bi+" (local, id)");var n="SELECT "+bi+".winningseq AS seq, "+bi+".json AS metadata FROM "+wi+" JOIN "+bi+" ON "+wi+".seq = "+bi+".winningseq";e.executeSql(n,[],function(e,n){for(var r=[],o=[],i=0;i<n.rows.length;i++){var s=n.rows.item(i),a=s.seq,u=JSON.parse(s.metadata);le(u)&&r.push(a),de(u.id)&&o.push(u.id)}e.executeSql("UPDATE "+bi+"SET local = 1 WHERE id IN "+Rn(o.length),o,function(){e.executeSql("UPDATE "+wi+" SET deleted = 1 WHERE seq IN "+Rn(r.length),r,t)})})})})}function o(e,t){var n="CREATE TABLE IF NOT EXISTS "+Si+" (id UNIQUE, rev, json)";e.executeSql(n,[],function(){var n="SELECT "+bi+".id AS id, "+wi+".json AS data FROM "+wi+" JOIN "+bi+" ON "+wi+".seq = "+bi+".winningseq WHERE local = 1";e.executeSql(n,[],function(e,n){function r(){if(!o.length)return t(e);var n=o.shift(),i=JSON.parse(n.data)._rev;e.executeSql("INSERT INTO "+Si+" (id, rev, json) VALUES (?,?,?)",[n.id,i,n.data],function(e){e.executeSql("DELETE FROM "+bi+" WHERE id=?",[n.id],function(e){e.executeSql("DELETE FROM "+wi+" WHERE seq=?",[n.seq],function(){r()})})})}for(var o=[],i=0;i<n.rows.length;i++)o.push(n.rows.item(i));r()})})}function i(e,t){function n(n){function r(){if(!n.length)return t(e);var o=n.shift(),i=Tn(o.hex,_),s=i.lastIndexOf("::"),a=i.substring(0,s),u=i.substring(s+2),c="UPDATE "+wi+" SET doc_id=?, rev=? WHERE doc_id_rev=?";e.executeSql(c,[a,u,i],function(){r()})}r()}var r="ALTER TABLE "+wi+" ADD COLUMN doc_id";e.executeSql(r,[],function(e){var t="ALTER TABLE "+wi+" ADD COLUMN rev";e.executeSql(t,[],function(e){e.executeSql(ji,[],function(e){var t="SELECT hex(doc_id_rev) as hex FROM "+wi;e.executeSql(t,[],function(e,t){for(var r=[],o=0;o<t.rows.length;o++)r.push(t.rows.item(o));n(r)})})})})}function s(e,t){function n(e){var n="SELECT COUNT(*) AS cnt FROM "+Ei;e.executeSql(n,[],function(e,n){function r(){var n=Nn(Ri+", "+bi+".id AS id",[bi,wi],Di,null,bi+".id ");n+=" LIMIT "+i+" OFFSET "+o,o+=i,e.executeSql(n,[],function(e,n){if(!n.rows.length)return t(e);for(var o={},i=0;i<n.rows.length;i++)for(var s=n.rows.item(i),a=Dn(s.data,s.id,s.rev),u=Object.keys(a._attachments||{}),c=0;c<u.length;c++){var f=a._attachments[u[c]];!function(e,t){var n=o[e]=o[e]||[];n.indexOf(t)===-1&&n.push(t)}(f.digest,s.seq)}var l=[];if(Object.keys(o).forEach(function(e){o[e].forEach(function(t){l.push([e,t])})}),!l.length)return r();var d=0;l.forEach(function(t){var n="INSERT INTO "+qi+" (digest, seq) VALUES (?,?)";e.executeSql(n,t,function(){++d===l.length&&r()})})})}if(!n.rows.item(0).cnt)return t(e);var o=0,i=10;r()})}var r="CREATE TABLE IF NOT EXISTS "+qi+" (digest, seq INTEGER)";e.executeSql(r,[],function(e){e.executeSql(Ii,[],function(e){e.executeSql(Li,[],n)})})}function a(e,t){var n="ALTER TABLE "+Ei+" ADD COLUMN escaped TINYINT(1) DEFAULT 0";e.executeSql(n,[],t)}function c(e,t){var n="ALTER TABLE "+bi+" ADD COLUMN max_seq INTEGER";e.executeSql(n,[],function(e){var n="UPDATE "+bi+" SET max_seq=(SELECT MAX(seq) FROM "+wi+" WHERE doc_id=id)";e.executeSql(n,[],function(e){var n="CREATE UNIQUE INDEX IF NOT EXISTS 'doc-max-seq-idx' ON "+bi+" (max_seq)";e.executeSql(n,[],t)})})}function l(e,t){e.executeSql('SELECT HEX("a") AS hex',[],function(e,n){var r=n.rows.item(0).hex;_=2===r.length?"UTF-8":"UTF-16",t()})}function d(){for(;S.length>0;){S.pop()(null,b)}}function h(e,t){if(0===t){var n="CREATE TABLE IF NOT EXISTS "+ki+" (dbid, db_version INTEGER)",u="CREATE TABLE IF NOT EXISTS "+Ei+" (digest UNIQUE, escaped TINYINT(1), body BLOB)",f="CREATE TABLE IF NOT EXISTS "+qi+" (digest, seq INTEGER)",l="CREATE TABLE IF NOT EXISTS "+bi+" (id unique, json, winningseq, max_seq INTEGER UNIQUE)",h="CREATE TABLE IF NOT EXISTS "+wi+" (seq INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, json, deleted TINYINT(1), doc_id, rev)",p="CREATE TABLE IF NOT EXISTS "+Si+" (id UNIQUE, rev, json)";e.executeSql(u),e.executeSql(p),e.executeSql(f,[],function(){e.executeSql(Li),e.executeSql(Ii)}),e.executeSql(l,[],function(){e.executeSql(Ci),e.executeSql(h,[],function(){e.executeSql(Ti),e.executeSql(ji),e.executeSql(n,[],function(){var t="INSERT INTO "+ki+" (db_version, dbid) VALUES (?,?)";b=z();var n=[mi,b];e.executeSql(t,n,function(){d()})})})})}else{var v=function(){t<mi&&e.executeSql("UPDATE "+ki+" SET db_version = "+mi);var n="SELECT dbid FROM "+ki;e.executeSql(n,[],function(e,t){b=t.rows.item(0).dbid,d()})},g=[r,o,i,s,a,c,v],y=t,_=function(e){g[y-1](e,_),y++};_(e)}}function p(e){var t="SELECT sql FROM sqlite_master WHERE tbl_name = "+ki;e.executeSql(t,[],function(e,t){t.rows.length?/db_version/.test(t.rows.item(0).sql)?e.executeSql("SELECT db_version FROM "+ki,[],function(e,t){h(e,t.rows.item(0).db_version)}):e.executeSql("ALTER TABLE "+ki+" ADD COLUMN db_version INTEGER",[],function(){h(e,1)}):h(e,0)})}function v(e,t){var n="SELECT MAX(seq) AS seq FROM "+wi;e.executeSql(n,[],function(e,n){var r=n.rows.item(0).seq||0;t(r)})}function g(e,t){var n=Nn("COUNT("+bi+".id) AS 'num'",[bi,wi],Di,wi+".deleted=0");e.executeSql(n,[],function(e,n){t(n.rows.item(0).num)})}function y(e,t,n,r,o){var i=Nn(Ri,[bi,wi],Di,bi+".id=?"),s=[t];e.executeSql(i,s,function(e,t){if(!t.rows.length){var i=j(qo,"missing");return o(i)}var s=t.rows.item(0),a=Zt(s.metadata);r(he(n,a))})}var _,m=this,b=null,w=Fn(e),S=[];m._name=e.name;var k=So({},e,{version:Oi,description:e.name,size:w}),q=Jn(k);if(q.error)return $n(t)(q.error);var A=q.db;"function"!=typeof A.readTransaction&&(A.readTransaction=A.transaction),function(){A.transaction(function(e){l(e,function(){p(e)})},$n(t),n)}(),m._remote=!1,m.type=function(){return"websql"},m._id=f(function(e){e(null,b)}),m._info=function(e){var t,n;A.readTransaction(function(e){v(e,function(e){t=e}),g(e,function(e){n=e})},$n(e),function(){e(null,{doc_count:n,update_seq:t,websql_encoding:_})})},m._bulkDocs=function(t,n,r){Mn(e,t,n,m,A,xi,r)},m._get=function(e,t,n){function r(e){n(e,{doc:o,metadata:i,ctx:s})}var o,i,s=t.ctx;if(!s)return A.readTransaction(function(r){m._get(e,So({ctx:r},t),n)});var a,u;if(t.rev){if(t.latest)return void y(s,e,t.rev,function(r){t.latest=!1,t.rev=r,m._get(e,t,n)},r);a=Nn(Ri,[bi,wi],bi+".id="+wi+".doc_id",[wi+".doc_id=?",wi+".rev=?"]),u=[e,t.rev]}else a=Nn(Ri,[bi,wi],Di,bi+".id=?"),u=[e];s.executeSql(a,u,function(e,n){if(!n.rows.length){return r(j(qo,"missing"))}var s=n.rows.item(0);if(i=Zt(s.metadata),s.deleted&&!t.rev){return r(j(qo,"deleted"))}o=Dn(s.data,i.id,s.rev),r()})},m._allDocs=function(e,t){var n,r=[],o="startkey"in e&&e.startkey,i="endkey"in e&&e.endkey,s="key"in e&&e.key,a="descending"in e&&e.descending,u="limit"in e?e.limit:-1,c="skip"in e?e.skip:0,f=e.inclusive_end!==!1,l=[],d=[];if(s!==!1)d.push(bi+".id = ?"),l.push(s);else if(o!==!1||i!==!1){if(o!==!1&&(d.push(bi+".id "+(a?"<=":">=")+" ?"),l.push(o)),i!==!1){var h=a?">":"<";f&&(h+="="),d.push(bi+".id "+h+" ?"),l.push(i)}s!==!1&&(d.push(bi+".id = ?"),l.push(s))}"ok"!==e.deleted&&d.push(wi+".deleted = 0"),A.readTransaction(function(t){if(g(t,function(e){n=e}),0!==u){var o=Nn(Ri,[bi,wi],Di,d,bi+".id "+(a?"DESC":"ASC"));o+=" LIMIT "+u+" OFFSET "+c,t.executeSql(o,l,function(t,n){for(var o=0,i=n.rows.length;o<i;o++){var s=n.rows.item(o),a=Zt(s.metadata),u=a.id,c=Dn(s.data,u,s.rev),f=c._rev,l={id:u,key:u,value:{rev:f}};if(e.include_docs){if(l.doc=c,l.doc._rev=f,e.conflicts){var d=Q(a);d.length&&(l.doc._conflicts=d)}Hn(l.doc,e,m,t)}if(s.deleted){if("ok"!==e.deleted)continue;l.value.deleted=!0,l.doc=null}r.push(l)}})}},$n(t),function(){t(null,{total_rows:n,offset:e.skip,rows:r})})},m._changes=function(e){if(e=u(e),e.continuous){var t=m._name+":"+z();return xi.addListener(m._name,t,m,e),xi.notify(m._name),{cancel:function(){xi.removeListener(m._name,t)}}}var n=e.descending;e.since=e.since&&!n?e.since:0;var r="limit"in e?e.limit:-1;0===r&&(r=1);var o;o="return_docs"in e?e.return_docs:!("returnDocs"in e)||e.returnDocs;var i=[],s=0;!function(){var t=bi+".json AS metadata, "+bi+".max_seq AS maxSeq, "+wi+".json AS winningDoc, "+wi+".rev AS winningRev ",a=bi+" JOIN "+wi,u=bi+".id="+wi+".doc_id AND "+bi+".winningseq="+wi+".seq",c=["maxSeq > ?"],f=[e.since];e.doc_ids&&(c.push(bi+".id IN "+Rn(e.doc_ids.length)),f=f.concat(e.doc_ids));var l="maxSeq "+(n?"DESC":"ASC"),d=Nn(t,a,u,c,l),h=I(e);e.view||e.filter||(d+=" LIMIT "+r);var p=e.since||0;A.readTransaction(function(t){t.executeSql(d,f,function(t,n){function a(t){return function(){e.onChange(t)}}for(var u=0,c=n.rows.length;u<c;u++){var f=n.rows.item(u),l=Zt(f.metadata);p=f.maxSeq;var d=Dn(f.winningDoc,l.id,f.winningRev),v=e.processChange(d,l,e);v.seq=f.maxSeq;var g=h(v);if("object"==typeof g)return e.complete(g);if(g&&(s++,o&&i.push(v),e.attachments&&e.include_docs?Hn(d,e,m,t,a(v)):a(v)()),s===r)break}})},$n(e.complete),function(){e.continuous||e.complete(null,{results:i,last_seq:p})})}()},m._close=function(e){e()},m._getAttachment=function(e,t,n,r,o){var i,s=r.ctx,a=n.digest,u=n.content_type,c="SELECT escaped, CASE WHEN escaped = 1 THEN body ELSE HEX(body) END AS body FROM "+Ei+" WHERE digest=?";s.executeSql(c,[a],function(e,t){var n=t.rows.item(0),s=n.escaped?Ln(n.body):Tn(n.body,_);i=r.binary?Lt(s,u):ni(s),o(null,i)})},m._getRevisionTree=function(e,t){A.readTransaction(function(n){var r="SELECT json AS metadata FROM "+bi+" WHERE id = ?";n.executeSql(r,[e],function(e,n){if(n.rows.length){var r=Zt(n.rows.item(0).metadata);t(null,r.rev_tree)}else t(j(qo))})})},m._doCompaction=function(e,t,n){if(!t.length)return n();A.transaction(function(n){var r="SELECT json AS metadata FROM "+bi+" WHERE id = ?";n.executeSql(r,[e],function(n,r){var o=Zt(r.rows.item(0).metadata);X(o.rev_tree,function(e,n,r,o,i){var s=n+"-"+r;t.indexOf(s)!==-1&&(i.status="missing")});var i="UPDATE "+bi+" SET json = ? WHERE id = ?";n.executeSql(i,[en(o),e])}),Bn(t,e,n)},$n(n),function(){n()})},m._getLocal=function(e,t){A.readTransaction(function(n){var r="SELECT json, rev FROM "+Si+" WHERE id=?";n.executeSql(r,[e],function(n,r){if(r.rows.length){var o=r.rows.item(0),i=Dn(o.json,e,o.rev);t(null,i)}else t(j(qo))})})},m._putLocal=function(e,t,n){function r(e){var r,c;i?(r="UPDATE "+Si+" SET rev=?, json=? WHERE id=? AND rev=?",c=[o,u,s,i]):(r="INSERT INTO "+Si+" (id, rev, json) VALUES (?,?,?)",c=[s,o,u]),e.executeSql(r,c,function(e,r){r.rowsAffected?(a={ok:!0,id:s,rev:o},t.ctx&&n(null,a)):n(j(Ao))},function(){return n(j(Ao)),!1})}"function"==typeof t&&(n=t,t={}),delete e._revisions;var o,i=e._rev,s=e._id;o=e._rev=i?"0-"+(parseInt(i.split("-")[1],10)+1):"0-1";var a,u=In(e);t.ctx?r(t.ctx):A.transaction(r,$n(n),function(){a&&n(null,a)})},m._removeLocal=function(e,t,n){function r(r){var i="DELETE FROM "+Si+" WHERE id=? AND rev=?",s=[e._id,e._rev];r.executeSql(i,s,function(r,i){if(!i.rowsAffected)return n(j(qo));o={ok:!0,id:e._id,rev:"0-0"},t.ctx&&n(null,o)})}"function"==typeof t&&(n=t,t={});var o;t.ctx?r(t.ctx):A.transaction(r,$n(n),function(){o&&n(null,o)})},m._destroy=function(e,t){xi.removeAllListeners(m._name),A.transaction(function(e){[bi,wi,Ei,ki,Si,qi].forEach(function(t){e.executeSql("DROP TABLE IF EXISTS "+t,[])})},$n(t),function(){E()&&(delete window.localStorage["_pouch__websqldb_"+m._name],delete window.localStorage[m._name]),t(null,{ok:!0})})}}function zn(){try{return openDatabase("_pouch_validate_websql",1,"",1),!0}catch(e){return!1}}function Kn(){if("undefined"==typeof indexedDB||null===indexedDB||!/iP(hone|od|ad)/.test(navigator.userAgent))return!0;var e=E(),t="_pouch__websqldb_valid_"+navigator.userAgent;if(e&&localStorage[t])return"1"===localStorage[t];var n=zn();return e&&(localStorage[t]=n?"1":"0"),n}function Xn(){return"function"==typeof openDatabase&&Kn()}function Gn(e,t,n,r){return openDatabase(e,t,n,r)}function Vn(e,t){var n=So({websql:Gn},e);Wn.call(this,n,t)}function Qn(){for(var e={},t=new vo(function(t,n){e.resolve=t,e.reject=n}),n=new Array(arguments.length),r=0;r<n.length;r++)n[r]=arguments[r];return e.promise=t,vo.resolve().then(function(){return fetch.apply(null,n)}).then(function(t){e.resolve(t)}).catch(function(t){e.reject(t)}),e}function Yn(e,t){var n,r,o,i=new Headers,s={method:e.method,credentials:"include",headers:i};return e.json&&(i.set("Accept","application/json"),i.set("Content-Type",e.headers["Content-Type"]||"application/json")),e.body&&e.processData&&"string"!=typeof e.body?s.body=JSON.stringify(e.body):s.body="body"in e?e.body:null,Object.keys(e.headers).forEach(function(t){e.headers.hasOwnProperty(t)&&i.set(t,e.headers[t])}),n=Qn(e.url,s),e.timeout>0&&(r=setTimeout(function(){n.reject(new Error("Load timeout for resource: "+e.url))},e.timeout)),n.promise.then(function(t){return o={statusCode:t.status},e.timeout>0&&clearTimeout(r),o.statusCode>=200&&o.statusCode<300?e.binary?t.blob():t.text():t.json()}).then(function(e){o.statusCode>=200&&o.statusCode<300?t(null,o,e):(e.status=o.statusCode,t(e))}).catch(function(e){e||(e=new Error("canceled")),t(e)}),{abort:n.reject}}function Zn(e,t){var n,r,o=!1,i=function(){n.abort(),u()},s=function(){o=!0,n.abort(),u()},a={abort:i},u=function(){clearTimeout(r),a.abort=function(){},n&&(n.onprogress=void 0,n.upload&&(n.upload.onprogress=void 0),n.onreadystatechange=void 0,n=void 0)};n=e.xhr?new e.xhr:new XMLHttpRequest;try{n.open(e.method,e.url)}catch(e){return t(new Error(e.name||"Url is invalid"))}n.withCredentials=!("withCredentials"in e)||e.withCredentials,"GET"===e.method?delete e.headers["Content-Type"]:e.json&&(e.headers.Accept="application/json",e.headers["Content-Type"]=e.headers["Content-Type"]||"application/json",e.body&&e.processData&&"string"!=typeof e.body&&(e.body=JSON.stringify(e.body))),e.binary&&(n.responseType="arraybuffer"),"body"in e||(e.body=null);for(var c in e.headers)e.headers.hasOwnProperty(c)&&n.setRequestHeader(c,e.headers[c]);return e.timeout>0&&(r=setTimeout(s,e.timeout),n.onprogress=function(){clearTimeout(r),4!==n.readyState&&(r=setTimeout(s,e.timeout))},void 0!==n.upload&&(n.upload.onprogress=n.onprogress)),n.onreadystatechange=function(){if(4===n.readyState){var r={statusCode:n.status};if(n.status>=200&&n.status<300){var i;i=e.binary?jt([n.response||""],{type:n.getResponseHeader("Content-Type")}):n.responseText,t(null,r,i)}else{var s={};if(o)s=new Error("ETIMEDOUT"),s.code="ETIMEDOUT";else if("string"==typeof n.response)try{s=JSON.parse(n.response)}catch(e){}s.status=n.status,t(s)}u()}},e.body&&e.body instanceof Blob?$t(e.body,function(e){n.send(e)}):n.send(e.body),a}function er(e,t){return Bi||e.xhr?Zn(e,t):Yn(e,t)}function tr(){return""}function nr(e,t){function n(t,n,r){if(!e.binary&&e.json&&"string"==typeof t)try{t=JSON.parse(t)}catch(e){return r(e)}Array.isArray(t)&&(t=t.map(function(e){return e.error||e.missing?C(e):e})),e.binary&&$i(t,n),r(null,t,n)}return e=u(e),e=So({method:"GET",headers:{},json:!0,processData:!0,timeout:1e4,cache:!1},e),e.json&&(e.binary||(e.headers.Accept="application/json"),e.headers["Content-Type"]=e.headers["Content-Type"]||"application/json"),e.binary&&(e.encoding=null,e.json=!1),e.processData||(e.json=!1),er(e,function(r,o,i){if(r)return t(C(r));var s,a=o.headers&&o.headers["content-type"],u=i||tr();if(!e.binary&&(e.json||!e.processData)&&"object"!=typeof u&&(/json/.test(a)||/^[\s]*\{/.test(u)&&/\}[\s]*$/.test(u)))try{u=JSON.parse(u.toString())}catch(e){}o.statusCode>=200&&o.statusCode<300?n(u,o,t):(s=C(u),s.status=o.statusCode,t(s))})}function rr(e,t){var n=navigator&&navigator.userAgent?navigator.userAgent.toLowerCase():"",r=n.indexOf("safari")!==-1&&n.indexOf("chrome")===-1,o=n.indexOf("msie")!==-1,i=n.indexOf("edge")!==-1,s=r||(o||i)&&"GET"===e.method,a=!("cache"in e)||e.cache;if(!/^blob:/.test(e.url)&&(s||!a)){var u=e.url.indexOf("?")!==-1;e.url+=(u?"&":"?")+"_nonce="+Date.now()}return nr(e,t)}function or(e,t){return new vo(function(n,r){function o(){f++,e[l++]().then(s,a)}function i(){++d===h?c?r(c):n():u()}function s(){f--,i()}function a(e){f--,c=c||e,i()}function u(){for(;f<t&&l<h;)o()}var c,f=0,l=0,d=0,h=e.length;u()})}function ir(e){var t=e.doc&&e.doc._attachments;t&&Object.keys(t).forEach(function(e){var n=t[e];n.data=It(n.data,n.content_type)})}function sr(e){return/^_design/.test(e)?"_design/"+encodeURIComponent(e.slice(8)):/^_local/.test(e)?"_local/"+encodeURIComponent(e.slice(7)):encodeURIComponent(e)}function ar(e){return e._attachments&&Object.keys(e._attachments)?vo.all(Object.keys(e._attachments).map(function(t){var n=e._attachments[t];if(n.data&&"string"!=typeof n.data)return new vo(function(e){Bt(n.data,e)}).then(function(e){n.data=e})})):vo.resolve()}function ur(e){if(!e.prefix)return!1;var t=P(e.prefix).protocol;return"http"===t||"https"===t}function cr(e,t){if(ur(t)){var n=t.name.substr(t.prefix.length);e=t.prefix+encodeURIComponent(n)}var r=P(e);(r.user||r.password)&&(r.auth={username:r.user,password:r.password});var o=r.path.replace(/(^\/|\/$)/g,"").split("/");return r.db=o.pop(),r.db.indexOf("%")===-1&&(r.db=encodeURIComponent(r.db)),r.path=o.join("/"),r}function fr(e,t){return lr(e,e.db+"/"+t)}function lr(e,t){var n=e.path?"/":"";return e.protocol+"://"+e.host+(e.port?":"+e.port:"")+"/"+e.path+n+t}function dr(e){return"?"+Object.keys(e).map(function(t){return t+"="+encodeURIComponent(e[t])}).join("&")}function hr(e,t){function n(e,t,n){var r=e.ajax||{},o=So(u(l),r,t),i=u(l.headers||{});return o.headers=So(i,r.headers,t.headers||{}),a.constructor.listeners("debug").length&&a.constructor.emit("debug",["http",o.method,o.url]),a._ajax(o,n)}function r(e,t){return new vo(function(r,o){n(e,t,function(e,t){if(e)return o(e);r(t)})})}function o(e,t){
-return d(e,ao(function(e){i().then(function(){return t.apply(this,e)}).catch(function(t){e.pop()(t)})}))}function i(){return e.skipSetup||e.skip_setup?vo.resolve():g||(g=r({},{method:"GET",url:f}).catch(function(e){return e&&e.status&&404===e.status?(O(404,"PouchDB is just detecting if the remote exists."),r({},{method:"PUT",url:f})):vo.reject(e)}).catch(function(e){return!(!e||!e.status||412!==e.status)||vo.reject(e)}),g.catch(function(){g=null}),g)}function s(e){return e.split("/").map(encodeURIComponent).join("/")}var a=this,c=cr(e.name,e),f=fr(c,"");e=u(e);var l=e.ajax||{};if(e.auth||c.auth){var h=e.auth||c.auth,p=h.username+":"+h.password,v=ni(unescape(encodeURIComponent(p)));l.headers=l.headers||{},l.headers.Authorization="Basic "+v}a._ajax=rr;var g;fo(function(){t(null,a)}),a._remote=!0,a.type=function(){return"http"},a.id=o("id",function(e){n({},{method:"GET",url:lr(c,"")},function(t,n){var r=n&&n.uuid?n.uuid+c.db:fr(c,"");e(null,r)})}),a.request=o("request",function(e,t){e.url=fr(c,e.url),n({},e,t)}),a.compact=o("compact",function(e,t){"function"==typeof e&&(t=e,e={}),e=u(e),n(e,{url:fr(c,"_compact"),method:"POST"},function(){function n(){a.info(function(r,o){o&&!o.compact_running?t(null,{ok:!0}):setTimeout(n,e.interval||200)})}n()})}),a.bulkGet=d("bulkGet",function(e,t){function r(t){var r={};e.revs&&(r.revs=!0),e.attachments&&(r.attachments=!0),e.latest&&(r.latest=!0),n(e,{url:fr(c,"_bulk_get"+dr(r)),method:"POST",body:{docs:e.docs}},t)}function o(){for(var n=Mi,r=Math.ceil(e.docs.length/n),o=0,s=new Array(r),a=0;a<r;a++){var u=y(e,["revs","attachments","latest"]);u.ajax=l,u.docs=e.docs.slice(a*n,Math.min(e.docs.length,(a+1)*n)),b(i,u,function(e){return function(n,i){s[e]=i.results,++o===r&&t(null,{results:D(s)})}}(a))}}var i=this,s=lr(c,""),a=Pi[s];"boolean"!=typeof a?r(function(e,n){e?(Pi[s]=!1,O(e.status,"PouchDB is just detecting if the remote supports the _bulk_get API."),o()):(Pi[s]=!0,t(null,n))}):a?r(t):o()}),a._info=function(e){i().then(function(){n({},{method:"GET",url:fr(c,"")},function(t,n){if(t)return e(t);n.host=fr(c,""),e(null,n)})}).catch(e)},a.get=o("get",function(e,t,n){function o(e){function n(n){var i=o[n],a=sr(e._id)+"/"+s(n)+"?rev="+e._rev;return r(t,{method:"GET",url:fr(c,a),binary:!0}).then(function(e){return t.binary?e:new vo(function(t){Bt(e,t)})}).then(function(e){delete i.stub,delete i.length,i.data=e})}var o=e._attachments,i=o&&Object.keys(o);if(o&&i.length){return or(i.map(function(e){return function(){return n(e)}}),5)}}function i(e){return Array.isArray(e)?vo.all(e.map(function(e){if(e.ok)return o(e.ok)})):o(e)}"function"==typeof t&&(n=t,t={}),t=u(t);var a={};t.revs&&(a.revs=!0),t.revs_info&&(a.revs_info=!0),t.latest&&(a.latest=!0),t.open_revs&&("all"!==t.open_revs&&(t.open_revs=JSON.stringify(t.open_revs)),a.open_revs=t.open_revs),t.rev&&(a.rev=t.rev),t.conflicts&&(a.conflicts=t.conflicts),e=sr(e);var f={method:"GET",url:fr(c,e+dr(a))};r(t,f).then(function(e){return vo.resolve().then(function(){if(t.attachments)return i(e)}).then(function(){n(null,e)})}).catch(n)}),a.remove=o("remove",function(e,t,r,o){var i;"string"==typeof t?(i={_id:e,_rev:t},"function"==typeof r&&(o=r,r={})):(i=e,"function"==typeof t?(o=t,r={}):(o=r,r=t));var s=i._rev||r.rev;n(r,{method:"DELETE",url:fr(c,sr(i._id))+"?rev="+s},o)}),a.getAttachment=o("getAttachment",function(e,t,r,o){"function"==typeof r&&(o=r,r={});var i=r.rev?"?rev="+r.rev:"";n(r,{method:"GET",url:fr(c,sr(e))+"/"+s(t)+i,binary:!0},o)}),a.removeAttachment=o("removeAttachment",function(e,t,r,o){n({},{method:"DELETE",url:fr(c,sr(e)+"/"+s(t))+"?rev="+r},o)}),a.putAttachment=o("putAttachment",function(e,t,r,o,i,a){"function"==typeof i&&(a=i,i=o,o=r,r=null);var u=sr(e)+"/"+s(t),f=fr(c,u);if(r&&(f+="?rev="+r),"string"==typeof o){var d;try{d=ti(o)}catch(e){return a(j(Co,"Attachment is not a valid base64 string"))}o=d?Lt(d,i):""}n({},{headers:{"Content-Type":i},method:"PUT",url:f,processData:!1,body:o,timeout:l.timeout||6e4},a)}),a._bulkDocs=function(e,t,r){e.new_edits=t.new_edits,i().then(function(){return vo.all(e.docs.map(ar))}).then(function(){n(t,{method:"POST",url:fr(c,"_bulk_docs"),timeout:t.timeout,body:e},function(e,t){if(e)return r(e);t.forEach(function(e){e.ok=!0}),r(null,t)})}).catch(r)},a._put=function(e,t,r){i().then(function(){return ar(e)}).then(function(){n(t,{method:"PUT",url:fr(c,sr(e._id)),body:e},function(e,t){if(e)return r(e);r(null,t)})}).catch(r)},a.allDocs=o("allDocs",function(e,t){"function"==typeof e&&(t=e,e={}),e=u(e);var n,o={},i="GET";e.conflicts&&(o.conflicts=!0),e.descending&&(o.descending=!0),e.include_docs&&(o.include_docs=!0),e.attachments&&(o.attachments=!0),e.key&&(o.key=JSON.stringify(e.key)),e.start_key&&(e.startkey=e.start_key),e.startkey&&(o.startkey=JSON.stringify(e.startkey)),e.end_key&&(e.endkey=e.end_key),e.endkey&&(o.endkey=JSON.stringify(e.endkey)),void 0!==e.inclusive_end&&(o.inclusive_end=!!e.inclusive_end),void 0!==e.limit&&(o.limit=e.limit),void 0!==e.skip&&(o.skip=e.skip);var s=dr(o);void 0!==e.keys&&(i="POST",n={keys:e.keys}),r(e,{method:i,url:fr(c,"_all_docs"+s),body:n}).then(function(n){e.include_docs&&e.attachments&&e.binary&&n.rows.forEach(ir),t(null,n)}).catch(t)}),a._changes=function(e){var t="batch_size"in e?e.batch_size:Fi;e=u(e),e.timeout="timeout"in e?e.timeout:"timeout"in l?l.timeout:3e4;var r,o=e.timeout?{timeout:e.timeout-5e3}:{},s=void 0!==e.limit&&e.limit;r="return_docs"in e?e.return_docs:!("returnDocs"in e)||e.returnDocs;var a=s;if(e.style&&(o.style=e.style),(e.include_docs||e.filter&&"function"==typeof e.filter)&&(o.include_docs=!0),e.attachments&&(o.attachments=!0),e.continuous&&(o.feed="longpoll"),e.conflicts&&(o.conflicts=!0),e.descending&&(o.descending=!0),"heartbeat"in e?e.heartbeat&&(o.heartbeat=e.heartbeat):e.continuous&&(o.heartbeat=1e4),e.filter&&"string"==typeof e.filter&&(o.filter=e.filter),e.view&&"string"==typeof e.view&&(o.filter="_view",o.view=e.view),e.query_params&&"object"==typeof e.query_params)for(var f in e.query_params)e.query_params.hasOwnProperty(f)&&(o[f]=e.query_params[f]);var d,h="GET";e.doc_ids?(o.filter="_doc_ids",h="POST",d={doc_ids:e.doc_ids}):e.selector&&(o.filter="_selector",h="POST",d={selector:e.selector});var p,v,g=function(r,u){if(!e.aborted){o.since=r,"object"==typeof o.since&&(o.since=JSON.stringify(o.since)),e.descending?s&&(o.limit=a):o.limit=!s||a>t?t:a;var f={method:h,url:fr(c,"_changes"+dr(o)),timeout:e.timeout,body:d};v=r,e.aborted||i().then(function(){p=n(e,f,u)}).catch(u)}},y={results:[]},_=function(n,o){if(!e.aborted){var i=0;if(o&&o.results){i=o.results.length,y.last_seq=o.last_seq;({}).query=e.query_params,o.results=o.results.filter(function(t){a--;var n=I(e)(t);return n&&(e.include_docs&&e.attachments&&e.binary&&ir(t),r&&y.results.push(t),e.onChange(t)),n})}else if(n)return e.aborted=!0,void e.complete(n);o&&o.last_seq&&(v=o.last_seq);var u=s&&a<=0||o&&i<t||e.descending;(!e.continuous||s&&a<=0)&&u?e.complete(null,y):fo(function(){g(v,_)})}};return g(e.since||0,_),{cancel:function(){e.aborted=!0,p&&p.abort()}}},a.revsDiff=o("revsDiff",function(e,t,r){"function"==typeof t&&(r=t,t={}),n(t,{method:"POST",url:fr(c,"_revs_diff"),body:e},r)}),a._close=function(e){e()},a._destroy=function(e,t){n(e,{url:fr(c,""),method:"DELETE"},function(e,n){if(e&&e.status&&404!==e.status)return t(e);t(null,n)})}}function pr(e){this.status=400,this.name="query_parse_error",this.message=e,this.error=!0;try{Error.captureStackTrace(this,pr)}catch(e){}}function vr(e){this.status=404,this.name="not_found",this.message=e,this.error=!0;try{Error.captureStackTrace(this,vr)}catch(e){}}function gr(e){this.status=500,this.name="invalid_value",this.message=e,this.error=!0;try{Error.captureStackTrace(this,gr)}catch(e){}}function yr(e,t){return t&&e.then(function(e){fo(function(){t(null,e)})},function(e){fo(function(){t(e)})}),e}function _r(e){return ao(function(t){var n=t.pop(),r=e.apply(this,t);return"function"==typeof n&&yr(r,n),r})}function mr(e,t){return e.then(function(e){return t().then(function(){return e})},function(e){return t().then(function(){throw e})})}function br(e,t){return function(){var n=arguments,r=this;return e.add(function(){return t.apply(r,n)})}}function wr(e){var t=new _o(e),n=new Array(t.size),r=-1;return t.forEach(function(e){n[++r]=e}),n}function Er(e){var t=new Array(e.size),n=-1;return e.forEach(function(e,r){t[++n]=r}),t}function Sr(e){return new gr("builtin "+e+" function requires map values to be numbers or number arrays")}function kr(e){for(var t=0,n=0,r=e.length;n<r;n++){var o=e[n];if("number"!=typeof o){if(!Array.isArray(o))throw Sr("_sum");t="number"==typeof t?[t]:t;for(var i=0,s=o.length;i<s;i++){var a=o[i];if("number"!=typeof a)throw Sr("_sum");void 0===t[i]?t.push(a):t[i]+=a}}else"number"==typeof t?t+=o:t[0]+=o}return t}function qr(e,t){return U("return ("+e.replace(/;\s*$/,"")+");",{emit:t,sum:kr,log:Ji,isArray:Hi,toJSON:Wi})}function Ar(){this.promise=new vo(function(e){e()})}function xr(e){if(!e)return"undefined";switch(typeof e){case"function":case"string":return e.toString();default:return JSON.stringify(e)}}function Or(e,t){return xr(e)+xr(t)+"undefined"}function Tr(e,t,n,r,o,i){var s,a=Or(n,r);if(!o&&(s=e._cachedViews=e._cachedViews||{},s[a]))return s[a];var u=e.info().then(function(u){function c(e){e.views=e.views||{};var n=t;n.indexOf("/")===-1&&(n=t+"/"+t);var r=e.views[n]=e.views[n]||{};if(!r[f])return r[f]=!0,e}var f=u.db_name+"-mrview-"+(o?"temp":Ht(a));return J(e,"_local/"+i,c).then(function(){return e.registerDependentDatabase(f).then(function(t){var o=t.db;o.auto_compaction=!0;var i={name:f,db:o,sourceDB:e,adapter:e.adapter,mapFun:n,reduceFun:r};return i.db.get("_local/lastSeq").catch(function(e){if(404!==e.status)throw e}).then(function(e){return i.seq=e?e.seq:0,s&&i.db.once("destroyed",function(){delete s[a]}),i})})})});return s&&(s[a]=u),u}function jr(e){return e.indexOf("/")===-1?[e,e]:e.split("/")}function Cr(e){return 1===e.length&&/^1-/.test(e[0].rev)}function Lr(e,t){try{e.emit("error",t)}catch(e){q("error","The user's map/reduce function threw an uncaught error.\nYou can debug this error by doing:\nmyDatabase.on('error', function (err) { debugger; });\nPlease double-check your map/reduce function."),q("error",t)}}function Ir(e,t){if("function"==typeof e&&2===e.length){var n=e;return function(e){return n(e,t)}}return qr(e.toString(),t)}function Dr(e){return Gi[e]?Gi[e]:qr(e.toString())}function Rr(e,t){var n=e.views&&e.views[t];if("string"!=typeof n.map)throw new vr("ddoc "+e._id+" has no string view named "+t+", instead found object of type: "+typeof n.map)}function Nr(e,t,n){return Vi.query.call(this,e,t,n)}function Br(e){return Vi.viewCleanup.call(this,e)}function $r(e){return/^1-/.test(e)}function Fr(e,t,n){return!e._attachments||!e._attachments[n]||e._attachments[n].digest!==t._attachments[n].digest}function Mr(e,t){var n=Object.keys(t._attachments);return vo.all(n.map(function(n){return e.getAttachment(t._id,n,{rev:t._rev})}))}function Pr(e,t,n){var r=B(t)&&!B(e),o=Object.keys(n._attachments);return r?e.get(n._id).then(function(r){return vo.all(o.map(function(o){return Fr(r,n,o)?t.getAttachment(n._id,o):e.getAttachment(r._id,o)}))}).catch(function(e){if(404!==e.status)throw e;return Mr(t,n)}):Mr(t,n)}function Ur(e){var t=[];return Object.keys(e).forEach(function(n){e[n].missing.forEach(function(e){t.push({id:n,rev:e})})}),{docs:t,revs:!0,latest:!0}}function Jr(e,t,n,r){function o(){var o=Ur(n);if(o.docs.length)return e.bulkGet(o).then(function(n){if(r.cancelled)throw new Error("cancelled");return vo.all(n.results.map(function(n){return vo.all(n.docs.map(function(n){var r=n.ok;return n.error&&(d=!1),r&&r._attachments?Pr(t,e,r).then(function(e){var t=Object.keys(r._attachments);return e.forEach(function(e,n){var o=r._attachments[t[n]];delete o.stub,delete o.length,o.data=e}),r}):r}))})).then(function(e){l=l.concat(D(e).filter(Boolean))})})}function i(e){return e._attachments&&Object.keys(e._attachments).length>0}function s(e){return e._conflicts&&e._conflicts.length>0}function a(t){return e.allDocs({keys:t,include_docs:!0,conflicts:!0}).then(function(e){if(r.cancelled)throw new Error("cancelled");e.rows.forEach(function(e){e.deleted||!e.doc||!$r(e.value.rev)||i(e.doc)||s(e.doc)||(e.doc._conflicts&&delete e.doc._conflicts,l.push(e.doc),delete n[e.id])})})}function c(){var e=Object.keys(n).filter(function(e){var t=n[e].missing;return 1===t.length&&$r(t[0])});if(e.length>0)return a(e)}function f(){return{ok:d,docs:l}}n=u(n);var l=[],d=!0;return vo.resolve().then(c).then(o).then(f)}function Hr(e,t,n,r,o){return e.get(t).catch(function(n){if(404===n.status)return"http"!==e.adapter&&"https"!==e.adapter||O(404,"PouchDB is just checking if a remote checkpoint exists."),{session_id:r,_id:t,history:[],replicator:Zi,version:Yi};throw n}).then(function(i){if(!o.cancelled&&i.last_seq!==n)return i.history=(i.history||[]).filter(function(e){return e.session_id!==r}),i.history.unshift({last_seq:n,session_id:r}),i.history=i.history.slice(0,es),i.version=Yi,i.replicator=Zi,i.session_id=r,i.last_seq=n,e.put(i).catch(function(i){if(409===i.status)return Hr(e,t,n,r,o);throw i})})}function Wr(e,t,n,r){this.src=e,this.target=t,this.id=n,this.returnValue=r}function zr(e,t){return e.session_id===t.session_id?{last_seq:e.last_seq,history:e.history}:Kr(e.history,t.history)}function Kr(e,t){var n=e[0],r=e.slice(1),o=t[0],i=t.slice(1);return n&&0!==t.length?Xr(n.session_id,t)?{last_seq:n.last_seq,history:e}:Xr(o.session_id,r)?{last_seq:o.last_seq,history:i}:Kr(r,i):{last_seq:ts,history:[]}}function Xr(e,t){var n=t[0],r=t.slice(1);return!(!e||0===t.length)&&(e===n.session_id||Xr(e,r))}function Gr(e){return"number"==typeof e.status&&4===Math.floor(e.status/100)}function Vr(e,t,n,r){if(e.retry===!1)return t.emit("error",n),void t.removeAllListeners();if("function"!=typeof e.back_off_function&&(e.back_off_function=x),t.emit("requestError",n),"active"===t.state||"pending"===t.state){t.emit("paused",n),t.state="stopped";var o=function(){e.current_back_off=rs},i=function(){t.removeListener("active",o)};t.once("paused",i),t.once("active",o)}e.current_back_off=e.current_back_off||rs,e.current_back_off=e.back_off_function(e.current_back_off),setTimeout(r,e.current_back_off)}function Qr(e){return Object.keys(e).sort(We).reduce(function(t,n){return t[n]=e[n],t},{})}function Yr(e,t,n){var r=n.doc_ids?n.doc_ids.sort(We):"",o=n.filter?n.filter.toString():"",i="",s="",a="";return n.selector&&(a=JSON.stringify(n.selector)),n.filter&&n.query_params&&(i=JSON.stringify(Qr(n.query_params))),n.filter&&"_view"===n.filter&&(s=n.view.toString()),vo.all([e.id(),t.id()]).then(function(e){var t=e[0]+e[1]+o+s+i+r+a;return new vo(function(e){Jt(t,e)})}).then(function(e){return"_local/"+(e=e.replace(/\//g,".").replace(/\+/g,"_"))})}function Zr(e,t,n,r,o){function i(){return S?vo.resolve():Yr(e,t,n).then(function(n){E=n,S=new Wr(e,t,E,r)})}function s(){if($=[],0!==w.docs.length){var e=w.docs,i={timeout:n.timeout};return t.bulkDocs({docs:e,new_edits:!1},i).then(function(t){if(r.cancelled)throw p(),new Error("cancelled");var n=Object.create(null);t.forEach(function(e){e.error&&(n[e.id]=e)});var i=Object.keys(n).length;o.doc_write_failures+=i,o.docs_written+=e.length-i,e.forEach(function(e){var t=n[e._id];if(t){if(o.errors.push(t),"unauthorized"!==t.name&&"forbidden"!==t.name)throw t;r.emit("denied",u(t))}else $.push(e)})},function(t){throw o.doc_write_failures+=e.length,t})}}function a(){if(w.error)throw new Error("There was a problem getting docs.");o.last_seq=T=w.seq;var e=u(o);return $.length&&(e.docs=$,r.emit("change",e)),A=!0,S.writeCheckpoint(w.seq,F).then(function(){if(A=!1,r.cancelled)throw p(),new Error("cancelled");w=void 0,_()}).catch(function(e){throw b(e),e})}function c(){var e={};return w.changes.forEach(function(t){"_user/"!==t.id&&(e[t.id]=t.changes.map(function(e){return e.rev}))}),t.revsDiff(e).then(function(e){if(r.cancelled)throw p(),new Error("cancelled");w.diffs=e})}function f(){return Jr(e,t,w.diffs,r).then(function(e){w.error=!e.ok,e.docs.forEach(function(e){delete w.diffs[e._id],o.docs_read++,w.docs.push(e)})})}function l(){if(!r.cancelled&&!w){if(0===k.length)return void d(!0);w=k.shift(),c().then(f).then(s).then(a).then(l).catch(function(e){h("batch processing terminated with error",e)})}}function d(e){if(0===q.changes.length)return void(0!==k.length||w||((C&&M.live||x)&&(r.state="pending",r.emit("paused")),x&&p()));(e||x||q.changes.length>=L)&&(k.push(q),q={seq:0,changes:[],docs:[]},"pending"!==r.state&&"stopped"!==r.state||(r.state="active",r.emit("active")),l())}function h(e,t){O||(t.message||(t.message=e),o.ok=!1,o.status="aborting",k=[],q={seq:0,changes:[],docs:[]},p(t))}function p(i){O||r.cancelled&&(o.status="cancelled",A)||(o.status=o.status||"complete",o.end_time=new Date,o.last_seq=T,O=!0,i?(i=j(i),i.result=o,"unauthorized"===i.name||"forbidden"===i.name?(r.emit("error",i),r.removeAllListeners()):Vr(n,r,i,function(){Zr(e,t,n,r)})):(r.emit("complete",o),r.removeAllListeners()))}function v(e){if(r.cancelled)return p();I(n)(e)&&(q.seq=e.seq,q.changes.push(e),d(0===k.length&&M.live))}function g(e){if(R=!1,r.cancelled)return p();if(e.results.length>0)M.since=e.last_seq,_(),d(!0);else{var t=function(){C?(M.live=!0,_()):x=!0,d(!0)};w||0!==e.results.length?t():(A=!0,S.writeCheckpoint(e.last_seq,F).then(function(){A=!1,o.last_seq=T=e.last_seq,t()}).catch(b))}}function y(e){if(R=!1,r.cancelled)return p();h("changes rejected",e)}function _(){function t(){i.cancel()}function o(){r.removeListener("cancel",t)}if(!R&&!x&&k.length<D){R=!0,r._changes&&(r.removeListener("cancel",r._abortChanges),r._changes.cancel()),r.once("cancel",t);var i=e.changes(M).on("change",v);i.then(o,o),i.then(g).catch(y),n.retry&&(r._changes=i,r._abortChanges=t)}}function m(){i().then(function(){return r.cancelled?void p():S.getCheckpoint().then(function(e){T=e,M={since:T,limit:L,batch_size:L,style:"all_docs",doc_ids:N,selector:B,return_docs:!0},n.filter&&("string"!=typeof n.filter?M.include_docs=!0:M.filter=n.filter),"heartbeat"in n&&(M.heartbeat=n.heartbeat),"timeout"in n&&(M.timeout=n.timeout),n.query_params&&(M.query_params=n.query_params),n.view&&(M.view=n.view),_()})}).catch(function(e){h("getCheckpoint rejected with ",e)})}function b(e){A=!1,h("writeCheckpoint completed with error",e)}var w,E,S,k=[],q={seq:0,changes:[],docs:[]},A=!1,x=!1,O=!1,T=0,C=n.continuous||n.live||!1,L=n.batch_size||100,D=n.batches_limit||10,R=!1,N=n.doc_ids,B=n.selector,$=[],F=z();o=o||{ok:!0,start_time:new Date,docs_read:0,docs_written:0,doc_write_failures:0,errors:[]};var M={};if(r.ready(e,t),r.cancelled)return void p();r._addedListeners||(r.once("cancel",p),"function"==typeof n.complete&&(r.once("error",n.complete),r.once("complete",function(e){n.complete(null,e)})),r._addedListeners=!0),void 0===n.since?m():i().then(function(){return A=!0,S.writeCheckpoint(n.since,F)}).then(function(){if(A=!1,r.cancelled)return void p();T=n.since,m()}).catch(b)}function eo(){uo.EventEmitter.call(this),this.cancelled=!1,this.state="pending";var e=this,t=new vo(function(t,n){e.once("complete",t),e.once("error",n)});e.then=function(e,n){return t.then(e,n)},e.catch=function(e){return t.catch(e)},e.catch(function(){})}function to(e,t){var n=t.PouchConstructor;return"string"==typeof e?new n(e,t):e}function no(e,t,n,r){if("function"==typeof n&&(r=n,n={}),void 0===n&&(n={}),n.doc_ids&&!Array.isArray(n.doc_ids))throw j(Do,"`doc_ids` filter parameter is not a list.");n.complete=r,n=u(n),n.continuous=n.continuous||n.live,n.retry="retry"in n&&n.retry,n.PouchConstructor=n.PouchConstructor||this;var o=new eo(n);return Zr(to(e,n),to(t,n),n,o),o}function ro(e,t,n,r){return"function"==typeof n&&(r=n,n={}),void 0===n&&(n={}),n=u(n),n.PouchConstructor=n.PouchConstructor||this,e=to(e,n),t=to(t,n),new oo(e,t,n,r)}function oo(e,t,n,r){function o(e){p.emit("change",{direction:"pull",change:e})}function i(e){p.emit("change",{direction:"push",change:e})}function s(e){p.emit("denied",{direction:"push",doc:e})}function a(e){p.emit("denied",{direction:"pull",doc:e})}function u(){p.pushPaused=!0,p.pullPaused&&p.emit("paused")}function c(){p.pullPaused=!0,p.pushPaused&&p.emit("paused")}function f(){p.pushPaused=!1,p.pullPaused&&p.emit("active",{direction:"push"})}function l(){p.pullPaused=!1,p.pushPaused&&p.emit("active",{direction:"pull"})}function d(e){return function(t,n){var r="change"===t&&(n===o||n===i),d="denied"===t&&(n===a||n===s),h="paused"===t&&(n===c||n===u),v="active"===t&&(n===l||n===f);(r||d||h||v)&&(t in y||(y[t]={}),y[t][e]=!0,2===Object.keys(y[t]).length&&p.removeAllListeners(t))}}function h(e,t,n){e.listeners(t).indexOf(n)==-1&&e.on(t,n)}var p=this;this.canceled=!1;var v=n.push?So({},n,n.push):n,g=n.pull?So({},n,n.pull):n;this.push=no(e,t,v),this.pull=no(t,e,g),this.pushPaused=!0,this.pullPaused=!0;var y={};n.live&&(this.push.on("complete",p.pull.cancel.bind(p.pull)),this.pull.on("complete",p.push.cancel.bind(p.push))),this.on("newListener",function(e){"change"===e?(h(p.pull,"change",o),h(p.push,"change",i)):"denied"===e?(h(p.pull,"denied",a),h(p.push,"denied",s)):"active"===e?(h(p.pull,"active",l),h(p.push,"active",f)):"paused"===e&&(h(p.pull,"paused",c),h(p.push,"paused",u))}),this.on("removeListener",function(e){"change"===e?(p.pull.removeListener("change",o),p.push.removeListener("change",i)):"denied"===e?(p.pull.removeListener("denied",a),p.push.removeListener("denied",s)):"active"===e?(p.pull.removeListener("active",l),p.push.removeListener("active",f)):"paused"===e&&(p.pull.removeListener("paused",c),p.push.removeListener("paused",u))}),this.pull.on("removeListener",d("pull")),this.push.on("removeListener",d("push"));var _=vo.all([this.push,this.pull]).then(function(e){var t={push:e[0],pull:e[1]};return p.emit("complete",t),r&&r(null,t),p.removeAllListeners(),t},function(e){if(p.cancel(),r?r(e):p.emit("error",e),p.removeAllListeners(),r)throw e});this.then=function(e,t){return _.then(e,t)},this.catch=function(e){return _.catch(e)}}function io(e){e.replicate=no,e.sync=ro,Object.defineProperty(e.prototype,"replicate",{get:function(){var e=this;return{from:function(t,n,r){return e.constructor.replicate(t,e,n,r)},to:function(t,n,r){return e.constructor.replicate(e,t,n,r)}}}}),e.prototype.sync=function(e,t,n){return this.constructor.sync(this,e,t,n)}}var so=r(e(7)),ao=r(e(1)),uo=e(4),co=r(e(6)),fo=r(e(5)),lo=r(e(2)),ho=r(e(10)),po=r(e(11)),vo="function"==typeof Promise?Promise:so,go=Function.prototype.toString,yo=go.call(Object);v.prototype.get=function(e){var t=h(e);return this._store[t]},v.prototype.set=function(e,t){var n=h(e);return this._store[n]=t,!0},v.prototype.has=function(e){return h(e)in this._store},v.prototype.delete=function(e){var t=h(e),n=t in this._store;return delete this._store[t],n},v.prototype.forEach=function(e){for(var t=Object.keys(this._store),n=0,r=t.length;n<r;n++){var o=t[n],i=this._store[o];o=p(o),e(i,o)}},Object.defineProperty(v.prototype,"size",{get:function(){return Object.keys(this._store).length}}),g.prototype.add=function(e){return this._store.set(e,!0)},g.prototype.has=function(e){return this._store.has(e)},g.prototype.forEach=function(e){this._store.forEach(function(t,n){e(n)})},Object.defineProperty(g.prototype,"size",{get:function(){return this._store.size}});var _o,mo;!function(){if("undefined"==typeof Symbol||"undefined"==typeof Map||"undefined"==typeof Set)return!1;var e=Object.getOwnPropertyDescriptor(Map,Symbol.species);return e&&"get"in e&&Map[Symbol.species]===Map}()?(_o=g,mo=v):(_o=Set,mo=Map);var bo,wo=6;if(w())bo=!1;else try{localStorage.setItem("_pouch_check_localstorage",1),bo=!!localStorage.getItem("_pouch_check_localstorage")}catch(e){bo=!1}co(k,uo.EventEmitter),k.prototype.addListener=function(e,t,n,r){function o(){function e(){s=!1}if(i._listeners[t]){if(s)return void(s="waiting");s=!0;var a=y(r,["style","include_docs","attachments","conflicts","filter","doc_ids","view","since","query_params","binary"]);n.changes(a).on("change",function(e){e.seq>r.since&&!r.cancelled&&(r.since=e.seq,r.onChange(e))}).on("complete",function(){"waiting"===s&&fo(o),s=!1}).on("error",e)}}if(!this._listeners[t]){var i=this,s=!1;this._listeners[t]=o,this.on(e,o)}},k.prototype.removeListener=function(e,t){t in this._listeners&&(uo.EventEmitter.prototype.removeListener.call(this,e,this._listeners[t]),delete this._listeners[t])},k.prototype.notifyLocalWindows=function(e){w()?chrome.storage.local.set({dbName:e}):E()&&(localStorage[e]="a"===localStorage[e]?"b":"a")},k.prototype.notify=function(e){this.emit(e),this.notifyLocalWindows(e)};var Eo;Eo="function"==typeof Object.assign?Object.assign:function(e){for(var t=Object(e),n=1;n<arguments.length;n++){var r=arguments[n];if(null!=r)for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(t[o]=r[o])}return t};var So=Eo;co(T,Error),T.prototype.toString=function(){return JSON.stringify({status:this.status,name:this.name,message:this.message,reason:this.reason})};var ko=(new T(401,"unauthorized","Name or password is incorrect."),new T(400,"bad_request","Missing JSON list of 'docs'")),qo=new T(404,"not_found","missing"),Ao=new T(409,"conflict","Document update conflict"),xo=new T(400,"bad_request","_id field must contain a string"),Oo=new T(412,"missing_id","_id is required for puts"),To=new T(400,"bad_request","Only reserved document ids may start with underscore."),jo=(new T(412,"precondition_failed","Database not open"),new T(500,"unknown_error","Database encountered an unknown error")),Co=new T(500,"badarg","Some query argument is invalid"),Lo=(new T(400,"invalid_request","Request was invalid"),new T(400,"query_parse_error","Some query parameter is invalid")),Io=new T(500,"doc_validation","Bad special document member"),Do=new T(400,"bad_request","Something wrong with the request"),Ro=new T(400,"bad_request","Document must be a JSON object"),No=(new T(404,"not_found","Database not found"),new T(500,"indexed_db_went_bad","unknown")),Bo=new T(500,"web_sql_went_bad","unknown"),$o=(new T(500,"levelDB_went_went_bad","unknown"),new T(403,"forbidden","Forbidden by design doc validate_doc_update function"),new T(400,"bad_request","Invalid rev format")),Fo=(new T(412,"file_exists","The database could not be created, the file already exists."),new T(412,"missing_stub","A pre-existing attachment stub wasn't found")),Mo=(new T(413,"invalid_url","Provided URL is invalid"),R.name);var Po=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],Uo="queryKey",Jo=/(?:^|&)([^&=]*)=?([^&]*)/g,Ho=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,Wo="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");co(ve,uo.EventEmitter),ve.prototype.cancel=function(){this.isCancelled=!0,this.db.taskqueue.isReady&&this.emit("cancel")},ve.prototype.validateChanges=function(e){var t=e.complete,n=this;Te._changesFilterPlugin?Te._changesFilterPlugin.validate(e,function(r){if(r)return t(r);n.doChanges(e)}):n.doChanges(e)},ve.prototype.doChanges=function(e){var t=this,n=e.complete;if(e=u(e),"live"in e&&!("continuous"in e)&&(e.continuous=e.live),e.processChange=ge,"latest"===e.since&&(e.since="now"),e.since||(e.since=0),"now"===e.since)return void this.db.info().then(function(r){if(t.isCancelled)return void n(null,{status:"cancelled"});e.since=r.update_seq,t.doChanges(e)},n);if(Te._changesFilterPlugin){if(Te._changesFilterPlugin.normalize(e),Te._changesFilterPlugin.shouldFilter(this,e))return Te._changesFilterPlugin.filter(this,e)}else["doc_ids","filter","selector","view"].forEach(function(t){t in e&&q("warn",'The "'+t+'" 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.')});"descending"in e||(e.descending=!1),e.limit=0===e.limit?1:e.limit,e.complete=n;var r=this.db._changes(e);if(r&&"function"==typeof r.cancel){var o=t.cancel;t.cancel=ao(function(e){r.cancel(),o.apply(this,e)})}},co(qe,uo.EventEmitter),qe.prototype.post=d("post",function(e,t,n){if("function"==typeof t&&(n=t,t={}),"object"!=typeof e||Array.isArray(e))return n(j(Ro));this.bulkDocs({docs:[e]},t,_e(n))}),qe.prototype.put=d("put",function(e,t,n){return"function"==typeof t&&(n=t,t={}),"object"!=typeof e||Array.isArray(e)?n(j(Ro)):(N(e._id),de(e._id)&&"function"==typeof this._putLocal?e._deleted?this._removeLocal(e,n):this._putLocal(e,n):void("function"==typeof this._put&&t.new_edits!==!1?this._put(e,t,n):this.bulkDocs({docs:[e]},t,_e(n))))}),qe.prototype.putAttachment=d("putAttachment",function(e,t,n,r,o){function i(e){var n="_rev"in e?parseInt(e._rev,10):0;return e._attachments=e._attachments||{},e._attachments[t]={content_type:o,data:r,revpos:++n},s.put(e)}var s=this;return"function"==typeof o&&(o=r,r=n,n=null),void 0===o&&(o=r,r=n,n=null),o||q("warn","Attachment",t,"on document",e,"is missing content_type"),s.get(e).then(function(e){if(e._rev!==n)throw j(Ao);return i(e)},function(t){if(t.reason===qo.message)return i({_id:e});throw t})}),qe.prototype.removeAttachment=d("removeAttachment",function(e,t,n,r){var o=this;o.get(e,function(e,i){return e?void r(e):i._rev!==n?void r(j(Ao)):i._attachments?(delete i._attachments[t],0===Object.keys(i._attachments).length&&delete i._attachments,void o.put(i,r)):r()})}),qe.prototype.remove=d("remove",function(e,t,n,r){var o;"string"==typeof t?(o={_id:e,_rev:t},"function"==typeof n&&(r=n,n={})):(o=e,"function"==typeof t?(r=t,n={}):(r=n,n=t)),n=n||{},n.was_delete=!0;var i={_id:o._id,_rev:o._rev||n.rev};if(i._deleted=!0,de(i._id)&&"function"==typeof this._removeLocal)return this._removeLocal(o,r);this.bulkDocs({docs:[i]},n,_e(r))}),qe.prototype.revsDiff=d("revsDiff",function(e,t,n){function r(e,t){a.has(e)||a.set(e,{missing:[]}),a.get(e).missing.push(t)}function o(t,n){var o=e[t].slice(0);X(n,function(e,n,i,s,a){var u=n+"-"+i,c=o.indexOf(u);c!==-1&&(o.splice(c,1),"available"!==a.status&&r(t,u))}),o.forEach(function(e){r(t,e)})}"function"==typeof t&&(n=t,t={});var i=Object.keys(e);if(!i.length)return n(null,{});var s=0,a=new mo;i.map(function(t){this._getRevisionTree(t,function(r,u){if(r&&404===r.status&&"missing"===r.message)a.set(t,{missing:e[t]});else{if(r)return n(r);o(t,u)}if(++s===i.length){var c={};return a.forEach(function(e,t){c[t]=e}),n(null,c)}})},this)}),qe.prototype.bulkGet=d("bulkGet",function(e,t){b(this,e,t)}),qe.prototype.compactDocument=d("compactDocument",function(e,t,n){var r=this;this._getRevisionTree(e,function(o,i){if(o)return n(o);var s=we(i),a=[],u=[];Object.keys(s).forEach(function(e){s[e]>t&&a.push(e)}),X(i,function(e,t,n,r,o){var i=t+"-"+n;"available"===o.status&&a.indexOf(i)!==-1&&u.push(i)}),r._doCompaction(e,u,n)})}),qe.prototype.compact=d("compact",function(e,t){"function"==typeof e&&(t=e,e={});var n=this;e=e||{},n._compactionQueue=n._compactionQueue||[],n._compactionQueue.push({opts:e,callback:t}),1===n._compactionQueue.length&&Se(n)}),qe.prototype._compact=function(e,t){function n(e){s.push(o.compactDocument(e.id,0))}function r(e){var n=e.last_seq;vo.all(s).then(function(){return J(o,"_local/compaction",function(e){return(!e.last_seq||e.last_seq<n)&&(e.last_seq=n,e)})}).then(function(){t(null,{ok:!0})}).catch(t)}var o=this,i={return_docs:!1,last_seq:e.last_seq||0},s=[];o.changes(i).on("change",n).on("complete",r).on("error",t)},qe.prototype.get=d("get",function(e,t,n){function r(){var r=[],s=o.length;if(!s)return n(null,r);o.forEach(function(o){i.get(e,{rev:o,revs:t.revs,latest:t.latest,attachments:t.attachments},function(e,t){if(e)r.push({missing:o});else{for(var i,a=0,u=r.length;a<u;a++)if(r[a].ok&&r[a].ok._rev===t._rev){i=!0;break}i||r.push({ok:t})}--s||n(null,r)})})}if("function"==typeof t&&(n=t,t={}),"string"!=typeof e)return n(j(xo));if(de(e)&&"function"==typeof this._getLocal)return this._getLocal(e,n);var o=[],i=this
-;if(!t.open_revs)return this._get(e,t,function(e,r){if(e)return n(e);var o=r.doc,s=r.metadata,a=r.ctx;if(t.conflicts){var u=Q(s);u.length&&(o._conflicts=u)}if(le(s,o._rev)&&(o._deleted=!0),t.revs||t.revs_info){for(var c=o._rev.split("-"),f=parseInt(c[0],10),l=c[1],d=Z(s.rev_tree),h=null,p=0;p<d.length;p++){var v=d[p],g=v.ids.map(function(e){return e.id}).indexOf(l);(g===f-1||!h&&g!==-1)&&(h=v)}var y=h.ids.map(function(e){return e.id}).indexOf(o._rev.split("-")[1])+1,_=h.ids.length-y;if(h.ids.splice(y,_),h.ids.reverse(),t.revs&&(o._revisions={start:h.pos+h.ids.length-1,ids:h.ids.map(function(e){return e.id})}),t.revs_info){var m=h.pos+h.ids.length;o._revs_info=h.ids.map(function(e){return m--,{rev:m+"-"+e.id,status:e.opts.status}})}}if(t.attachments&&o._attachments){var b=o._attachments,w=Object.keys(b).length;if(0===w)return n(null,o);Object.keys(b).forEach(function(e){this._getAttachment(o._id,e,b[e],{rev:o._rev,binary:t.binary,ctx:a},function(t,r){var i=o._attachments[e];i.data=r,delete i.stub,delete i.length,--w||n(null,o)})},i)}else{if(o._attachments)for(var E in o._attachments)o._attachments.hasOwnProperty(E)&&(o._attachments[E].stub=!0);n(null,o)}});if("all"===t.open_revs)this._getRevisionTree(e,function(e,t){if(e)return n(e);o=V(t).map(function(e){return e.rev}),r()});else{if(!Array.isArray(t.open_revs))return n(j(jo,"function_clause"));o=t.open_revs;for(var s=0;s<o.length;s++){var a=o[s];if("string"!=typeof a||!/^\d+-/.test(a))return n(j($o))}r()}}),qe.prototype.getAttachment=d("getAttachment",function(e,t,n,r){var o=this;n instanceof Function&&(r=n,n={}),this._get(e,n,function(i,s){return i?r(i):s.doc._attachments&&s.doc._attachments[t]?(n.ctx=s.ctx,n.binary=!0,o._getAttachment(e,t,s.doc._attachments[t],n,r),void 0):r(j(qo))})}),qe.prototype.allDocs=d("allDocs",function(e,t){if("function"==typeof e&&(t=e,e={}),e.skip=void 0!==e.skip?e.skip:0,e.start_key&&(e.startkey=e.start_key),e.end_key&&(e.endkey=e.end_key),"keys"in e){if(!Array.isArray(e.keys))return t(new TypeError("options.keys must be an array"));var n=["startkey","endkey","key"].filter(function(t){return t in e})[0];if(n)return void t(j(Lo,"Query parameter `"+n+"` is not compatible with multi-get"));if(!B(this))return Ee(this,e,t)}return this._allDocs(e,t)}),qe.prototype.changes=function(e,t){return"function"==typeof e&&(t=e,e={}),new ve(this,e,t)},qe.prototype.close=d("close",function(e){return this._closed=!0,this.emit("closed"),this._close(e)}),qe.prototype.info=d("info",function(e){var t=this;this._info(function(n,r){if(n)return e(n);r.db_name=r.db_name||t.name,r.auto_compaction=!(!t.auto_compaction||B(t)),r.adapter=t.adapter,e(null,r)})}),qe.prototype.id=d("id",function(e){return this._id(e)}),qe.prototype.type=function(){return"function"==typeof this._type?this._type():this.adapter},qe.prototype.bulkDocs=d("bulkDocs",function(e,t,n){if("function"==typeof t&&(n=t,t={}),t=t||{},Array.isArray(e)&&(e={docs:e}),!e||!e.docs||!Array.isArray(e.docs))return n(j(ko));for(var r=0;r<e.docs.length;++r)if("object"!=typeof e.docs[r]||Array.isArray(e.docs[r]))return n(j(Ro));var o;if(e.docs.forEach(function(e){e._attachments&&Object.keys(e._attachments).forEach(function(t){o=o||ke(t),e._attachments[t].content_type||q("warn","Attachment",t,"on document",e._id,"is missing content_type")})}),o)return n(j(Do,o));"new_edits"in t||(t.new_edits=!("new_edits"in e)||e.new_edits);var i=this;t.new_edits||B(i)||e.docs.sort(be),me(e.docs);var s=e.docs.map(function(e){return e._id});return this._bulkDocs(e,t,function(e,r){if(e)return n(e);if(t.new_edits||(r=r.filter(function(e){return e.error})),!B(i))for(var o=0,a=r.length;o<a;o++)r[o].id=r[o].id||s[o];n(null,r)})}),qe.prototype.registerDependentDatabase=d("registerDependentDatabase",function(e,t){function n(t){return t.dependentDbs=t.dependentDbs||{},!t.dependentDbs[e]&&(t.dependentDbs[e]=!0,t)}var r=new this.constructor(e,this.__opts);J(this,"_local/_pouch_dependentDbs",n).then(function(){t(null,{db:r})}).catch(t)}),qe.prototype.destroy=d("destroy",function(e,t){function n(){r._destroy(e,function(e,n){if(e)return t(e);r._destroyed=!0,r.emit("destroyed"),t(null,n||{ok:!0})})}"function"==typeof e&&(t=e,e={});var r=this,o=!("use_prefix"in r)||r.use_prefix;if(B(r))return n();r.get("_local/_pouch_dependentDbs",function(e,i){if(e)return 404!==e.status?t(e):n();var s=i.dependentDbs,a=r.constructor,u=Object.keys(s).map(function(e){var t=o?e.replace(new RegExp("^"+a.prefix),""):e;return new a(t,r.__opts).destroy()});vo.all(u).then(n,t)})}),Ae.prototype.execute=function(){var e;if(this.failed)for(;e=this.queue.shift();)e(this.failed);else for(;e=this.queue.shift();)e()},Ae.prototype.fail=function(e){this.failed=e,this.execute()},Ae.prototype.ready=function(e){this.isReady=!0,this.db=e,this.execute()},Ae.prototype.addTask=function(e){this.queue.push(e),this.failed&&this.execute()},co(Te,qe),Te.adapters={},Te.preferredAdapters=[],Te.prefix="_pouch_";var zo=new uo.EventEmitter;!function(e){Object.keys(uo.EventEmitter.prototype).forEach(function(t){"function"==typeof uo.EventEmitter.prototype[t]&&(e[t]=zo[t].bind(zo))});var t=e._destructionListeners=new mo;e.on("destroyed",function(e){t.get(e).forEach(function(e){e()}),t.delete(e)})}(Te),Te.adapter=function(e,t,n){t.valid()&&(Te.adapters[e]=t,n&&Te.preferredAdapters.push(e))},Te.plugin=function(e){if("function"==typeof e)e(Te);else{if("object"!=typeof e||0===Object.keys(e).length)throw new Error('Invalid plugin: got "'+e+'", expected an object or a function');Object.keys(e).forEach(function(t){Te.prototype[t]=e[t]})}return this.__defaults&&(Te.__defaults=So({},this.__defaults)),Te},Te.defaults=function(e){function t(e,n){if(!(this instanceof t))return new t(e,n);n=n||{},e&&"object"==typeof e&&(n=e,e=n.name,delete n.name),n=So({},t.__defaults,n),Te.call(this,e,n)}return co(t,Te),t.preferredAdapters=Te.preferredAdapters.slice(),Object.keys(Te).forEach(function(e){e in t||(t[e]=Te[e])}),t.__defaults=So({},this.__defaults,e),t};var Ko=["$or","$nor","$not"],Xo=-324,Go=3,Vo="",Qo={$elemMatch:function(e,t,n,r){return!!Array.isArray(r)&&(0!==r.length&&("object"==typeof r[0]?r.some(function(e){return it(e,t,Object.keys(t))}):r.some(function(r){return at(t,e,n,r)})))},$eq:function(e,t,n,r){return lt(r)&&0===We(r,t)},$gte:function(e,t,n,r){return lt(r)&&We(r,t)>=0},$gt:function(e,t,n,r){return lt(r)&&We(r,t)>0},$lte:function(e,t,n,r){return lt(r)&&We(r,t)<=0},$lt:function(e,t,n,r){return lt(r)&&We(r,t)<0},$exists:function(e,t,n,r){return t?lt(r):!lt(r)},$mod:function(e,t,n,r){return ft(r)&&dt(r,t)},$ne:function(e,t,n,r){return t.every(function(e){return 0!==We(r,e)})},$in:function(e,t,n,r){return ft(r)&&ht(r,t)},$nin:function(e,t,n,r){return ft(r)&&!ht(r,t)},$size:function(e,t,n,r){return ft(r)&&vt(r,t)},$all:function(e,t,n,r){return Array.isArray(r)&&pt(r,t)},$regex:function(e,t,n,r){return ft(r)&&gt(r,t)},$type:function(e,t,n,r){return yt(r,t)}};Te.plugin(je),Te.plugin(qt),Te.version="6.2.0";var Yo,Zo=At(["_id","_rev","_attachments","_deleted","_revisions","_revs_info","_conflicts","_deleted_conflicts","_local_seq","_rev_tree","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats","_removed"]),ei=At(["_attachments","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats"]),ti=function(e){return atob(e)},ni=function(e){return btoa(e)},ri=n.setImmediate||n.setTimeout,oi=32768,ii=5,si="document-store",ai="by-sequence",ui="attach-store",ci="attach-seq-store",fi="meta-store",li="local-store",di="detect-blob-support",hi=new k,pi=!1,vi=[],gi=new mo,yi=new mo;En.valid=function(){return!("undefined"!=typeof openDatabase&&/(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent)&&!/Chrome/.test(navigator.userAgent)&&!/BlackBerry/.test(navigator.platform))&&"undefined"!=typeof indexedDB&&"undefined"!=typeof IDBKeyRange};var _i=function(e){e.adapter("idb",En,!0)},mi=7,bi=jn("document-store"),wi=jn("by-sequence"),Ei=jn("attach-store"),Si=jn("local-store"),ki=jn("metadata-store"),qi=jn("attach-seq-store"),Ai=new mo,xi=new k,Oi=1,Ti="CREATE INDEX IF NOT EXISTS 'by-seq-deleted-idx' ON "+wi+" (seq, deleted)",ji="CREATE UNIQUE INDEX IF NOT EXISTS 'by-seq-doc-id-rev' ON "+wi+" (doc_id, rev)",Ci="CREATE INDEX IF NOT EXISTS 'doc-winningseq-idx' ON "+bi+" (winningseq)",Li="CREATE INDEX IF NOT EXISTS 'attach-seq-seq-idx' ON "+qi+" (seq)",Ii="CREATE UNIQUE INDEX IF NOT EXISTS 'attach-seq-digest-idx' ON "+qi+" (digest, seq)",Di=wi+".seq = "+bi+".winningseq",Ri=wi+".seq AS seq, "+wi+".deleted AS deleted, "+wi+".json AS data, "+wi+".rev AS rev, "+bi+".json AS metadata";Vn.valid=Xn,Vn.use_prefix=!0;var Ni=function(e){e.adapter("websql",Vn,!0)},Bi=function(){try{return new XMLHttpRequest,!0}catch(e){return!1}}(),$i=function(){},Fi=25,Mi=50,Pi={};hr.valid=function(){return!0};var Ui=function(e){e.adapter("http",hr,!1),e.adapter("https",hr,!1)};co(pr,Error),co(vr,Error),co(gr,Error);var Ji=q.bind(null,"log"),Hi=Array.isArray,Wi=JSON.parse;Ar.prototype.add=function(e){return this.promise=this.promise.catch(function(){}).then(function(){return e()}),this.promise},Ar.prototype.finish=function(){return this.promise};var zi={},Ki=new Ar,Xi=50,Gi={_sum:function(e,t){return kr(t)},_count:function(e,t){return t.length},_stats:function(e,t){return{sum:kr(t),min:Math.min.apply(null,t),max:Math.max.apply(null,t),count:t.length,sumsqr:function(e){for(var t=0,n=0,r=e.length;n<r;n++){var o=e[n];t+=o*o}return t}(t)}}},Vi=function(e,t,n,r){function o(e,t,n){try{t(n)}catch(t){Lr(e,t)}}function i(e,t,n,r,o){try{return{output:t(n,r,o)}}catch(t){return Lr(e,t),{error:t}}}function s(e,t){var n=We(e.key,t.key);return 0!==n?n:We(e.value,t.value)}function a(e,t,n){return n=n||0,"number"==typeof t?e.slice(n,t+n):n>0?e.slice(n):e}function u(e){var t=e.value;return t&&"object"==typeof t&&t._id||e.id}function c(e){e.rows.forEach(function(e){var t=e.doc&&e.doc._attachments;t&&Object.keys(t).forEach(function(e){var n=t[e];t[e].data=It(n.data,n.content_type)})})}function f(e){return function(t){return e.include_docs&&e.attachments&&e.binary&&c(t),t}}function l(e,t,n,r){var o=t[e];void 0!==o&&(r&&(o=encodeURIComponent(JSON.stringify(o))),n.push(e+"="+o))}function d(e){if(void 0!==e){var t=Number(e);return isNaN(t)||t!==parseInt(e,10)?e:t}}function h(e){return e.group_level=d(e.group_level),e.limit=d(e.limit),e.skip=d(e.skip),e}function p(e){if(e){if("number"!=typeof e)return new pr('Invalid value for integer: "'+e+'"');if(e<0)return new pr('Invalid value for positive integer: "'+e+'"')}}function v(e,t){var n=e.descending?"endkey":"startkey",r=e.descending?"startkey":"endkey";if(void 0!==e[n]&&void 0!==e[r]&&We(e[n],e[r])>0)throw new pr("No rows can match your key range, reverse your start_key and end_key or set {descending : true}");if(t.reduce&&e.reduce!==!1){if(e.include_docs)throw new pr("{include_docs:true} is invalid for reduce");if(e.keys&&e.keys.length>1&&!e.group&&!e.group_level)throw new pr("Multi-key fetches for reduce views must use {group: true}")}["group_level","limit","skip"].forEach(function(t){var n=p(e[t]);if(n)throw n})}function g(e,t,n){var r,o=[],i="GET";if(l("reduce",n,o),l("include_docs",n,o),l("attachments",n,o),l("limit",n,o),l("descending",n,o),l("group",n,o),l("group_level",n,o),l("skip",n,o),l("stale",n,o),l("conflicts",n,o),l("startkey",n,o,!0),l("start_key",n,o,!0),l("endkey",n,o,!0),l("end_key",n,o,!0),l("inclusive_end",n,o),l("key",n,o,!0),o=o.join("&"),o=""===o?"":"?"+o,void 0!==n.keys){var s="keys="+encodeURIComponent(JSON.stringify(n.keys));s.length+o.length+1<=2e3?o+=("?"===o[0]?"&":"?")+s:(i="POST","string"==typeof t?r={keys:n.keys}:t.keys=n.keys)}if("string"==typeof t){var a=jr(t);return e.request({method:i,url:"_design/"+a[0]+"/_view/"+a[1]+o,body:r}).then(f(n))}return r=r||{},Object.keys(t).forEach(function(e){Array.isArray(t[e])?r[e]=t[e]:r[e]=t[e].toString()}),e.request({method:"POST",url:"_temp_view"+o,body:r}).then(f(n))}function y(e,t,n){return new vo(function(r,o){e._query(t,n,function(e,t){if(e)return o(e);r(t)})})}function _(e){return new vo(function(t,n){e._viewCleanup(function(e,r){if(e)return n(e);t(r)})})}function m(e){return function(t){if(404===t.status)return e;throw t}}function b(e,t,n){function r(e){return e.keys.length?t.db.allDocs({keys:e.keys,include_docs:!0}):vo.resolve({rows:[]})}function o(e,t){for(var n=[],r=new _o,o=0,i=t.rows.length;o<i;o++){var s=t.rows[o],a=s.doc;if(a&&(n.push(a),r.add(a._id),a._deleted=!u.has(a._id),!a._deleted)){var c=u.get(a._id);"value"in c&&(a.value=c.value)}}var f=Er(u);return f.forEach(function(e){if(!r.has(e)){var t={_id:e},o=u.get(e);"value"in o&&(t.value=o.value),n.push(t)}}),e.keys=wr(f.concat(e.keys)),n.push(e),n}var i="_local/doc_"+e,s={_id:i,keys:[]},a=n.get(e),u=a[0],c=a[1];return function(){return Cr(c)?vo.resolve(s):t.db.get(i).catch(m(s))}().then(function(e){return r(e).then(function(t){return o(e,t)})})}function w(e,t,n){return e.db.get("_local/lastSeq").catch(m({_id:"_local/lastSeq",seq:0})).then(function(r){var o=Er(t);return vo.all(o.map(function(n){return b(n,e,t)})).then(function(t){var o=D(t);return r.seq=n,o.push(r),e.db.bulkDocs({docs:o})})})}function E(e){var t="string"==typeof e?e:e.name,n=zi[t];return n||(n=zi[t]=new Ar),n}function S(e){return br(E(e),function(){return k(e)})()}function k(e){function n(e,t){var n={id:l._id,key:ze(e)};void 0!==t&&null!==t&&(n.value=ze(t)),f.push(n)}function r(t,n){return function(){return w(e,t,n)}}function i(){return e.sourceDB.changes({conflicts:!0,include_docs:!0,style:"all_docs",since:h,limit:Xi}).then(a)}function a(e){var t=e.results;if(t.length){var n=u(t);if(p.add(r(n,h)),!(t.length<Xi))return i()}}function u(t){for(var n=new mo,r=0,i=t.length;r<i;r++){var a=t[r];if("_"!==a.doc._id[0]){f=[],l=a.doc,l._deleted||o(e.sourceDB,d,l),f.sort(s);var u=c(f);n.set(a.doc._id,[u,a.changes])}h=a.seq}return n}function c(e){for(var t,n=new mo,r=0,o=e.length;r<o;r++){var i=e[r],s=[i.key,i.id];r>0&&0===We(i.key,t)&&s.push(r),n.set(Xe(s),i),t=i.key}return n}var f,l,d=t(e.mapFun,n),h=e.seq||0,p=new Ar;return i().then(function(){return p.finish()}).then(function(){e.seq=h})}function q(e,t,r){0===r.group_level&&delete r.group_level;var o=r.group||r.group_level,s=n(e.reduceFun),u=[],c=isNaN(r.group_level)?Number.POSITIVE_INFINITY:r.group_level;t.forEach(function(e){var t=u[u.length-1],n=o?e.key:null;if(o&&Array.isArray(n)&&(n=n.slice(0,c)),t&&0===We(t.groupKey,n))return t.keys.push([e.key,e.id]),void t.values.push(e.value);u.push({keys:[[e.key,e.id]],values:[e.value],groupKey:n})}),t=[];for(var f=0,l=u.length;f<l;f++){var d=u[f],h=i(e.sourceDB,s,d.keys,d.values,!1);if(h.error&&h.error instanceof gr)throw h.error;t.push({value:h.error?null:h.output,key:d.groupKey})}return{rows:a(t,r.limit,r.skip)}}function A(e,t){return br(E(e),function(){return x(e,t)})()}function x(e,t){function n(t){return t.include_docs=!0,e.db.allDocs(t).then(function(e){return o=e.total_rows,e.rows.map(function(e){if("value"in e.doc&&"object"==typeof e.doc.value&&null!==e.doc.value){var t=Object.keys(e.doc.value).sort(),n=["id","key","value"];if(!(t<n||t>n))return e.doc.value}var r=Qe(e.doc._id);return{key:r[0],id:r[1],value:"value"in e.doc?e.doc.value:null}})})}function r(n){var r;if(r=i?q(e,n,t):{total_rows:o,offset:s,rows:n},t.include_docs){var a=wr(n.map(u));return e.sourceDB.allDocs({keys:a,include_docs:!0,conflicts:t.conflicts,attachments:t.attachments,binary:t.binary}).then(function(e){var t=new mo;return e.rows.forEach(function(e){t.set(e.id,e.doc)}),n.forEach(function(e){var n=u(e),r=t.get(n);r&&(e.doc=r)}),r})}return r}var o,i=e.reduceFun&&t.reduce!==!1,s=t.skip||0;if(void 0===t.keys||t.keys.length||(t.limit=0,delete t.keys),void 0!==t.keys){var a=t.keys,c=a.map(function(e){return n({startkey:Xe([e]),endkey:Xe([e,{}])})});return vo.all(c).then(D).then(r)}var f,l,d={descending:t.descending};if("start_key"in t&&(f=t.start_key),"startkey"in t&&(f=t.startkey),"end_key"in t&&(l=t.end_key),"endkey"in t&&(l=t.endkey),void 0!==f&&(d.startkey=Xe(t.descending?[f,{}]:[f])),void 0!==l){var h=t.inclusive_end!==!1;t.descending&&(h=!h),d.endkey=Xe(h?[l,{}]:[l])}if(void 0!==t.key){var p=Xe([t.key]),v=Xe([t.key,{}]);d.descending?(d.endkey=p,d.startkey=v):(d.startkey=p,d.endkey=v)}return i||("number"==typeof t.limit&&(d.limit=t.limit),d.skip=s),n(d).then(r)}function O(e){return e.request({method:"POST",url:"_view_cleanup"})}function T(t){return t.get("_local/"+e).then(function(e){var n=new mo;Object.keys(e.views).forEach(function(e){var t=jr(e),r="_design/"+t[0],o=t[1],i=n.get(r);i||(i=new _o,n.set(r,i)),i.add(o)});var r={keys:Er(n),include_docs:!0};return t.allDocs(r).then(function(r){var o={};r.rows.forEach(function(t){var r=t.key.substring(8);n.get(t.key).forEach(function(n){var i=r+"/"+n;e.views[i]||(i=n);var s=Object.keys(e.views[i]),a=t.doc&&t.doc.views&&t.doc.views[n];s.forEach(function(e){o[e]=o[e]||a})})});var i=Object.keys(o).filter(function(e){return!o[e]}),s=i.map(function(e){return br(E(e),function(){return new t.constructor(e,t.__opts).destroy()})()});return vo.all(s).then(function(){return{ok:!0}})})},m({ok:!0}))}function j(t,n,o){if("function"==typeof t._query)return y(t,n,o);if(B(t))return g(t,n,o);if("string"!=typeof n)return v(o,n),Ki.add(function(){return Tr(t,"temp_view/temp_view",n.map,n.reduce,!0,e).then(function(e){return mr(S(e).then(function(){return A(e,o)}),function(){return e.db.destroy()})})}),Ki.finish();var i=n,s=jr(i),a=s[0],u=s[1];return t.get("_design/"+a).then(function(n){var s=n.views&&n.views[u];if(!s)throw new vr("ddoc "+n._id+" has no view named "+u);return r(n,u),v(o,s),Tr(t,i,s.map,s.reduce,!1,e).then(function(e){return"ok"===o.stale||"update_after"===o.stale?("update_after"===o.stale&&fo(function(){S(e)}),A(e,o)):S(e).then(function(){return A(e,o)})})})}function C(e,t,n){var r=this;"function"==typeof t&&(n=t,t={}),t=t?h(t):{},"function"==typeof e&&(e={map:e});var o=vo.resolve().then(function(){return j(r,e,t)});return yr(o,n),o}return{query:C,viewCleanup:_r(function(){var e=this;return"function"==typeof e._viewCleanup?_(e):B(e)?O(e):T(e)})}}("mrviews",Ir,Dr,Rr),Qi={query:Nr,viewCleanup:Br},Yi=1,Zi="pouchdb",es=5,ts=0;Wr.prototype.writeCheckpoint=function(e,t){var n=this;return this.updateTarget(e,t).then(function(){return n.updateSource(e,t)})},Wr.prototype.updateTarget=function(e,t){return Hr(this.target,this.id,e,t,this.returnValue)},Wr.prototype.updateSource=function(e,t){var n=this;return this.readOnlySource?vo.resolve(!0):Hr(this.src,this.id,e,t,this.returnValue).catch(function(e){if(Gr(e))return n.readOnlySource=!0,!0;throw e})};var ns={undefined:function(e,t){return 0===We(e.last_seq,t.last_seq)?t.last_seq:0},1:function(e,t){return zr(t,e).last_seq}};Wr.prototype.getCheckpoint=function(){var e=this;return e.target.get(e.id).then(function(t){return e.readOnlySource?vo.resolve(t.last_seq):e.src.get(e.id).then(function(e){if(t.version!==e.version)return ts;var n;return n=t.version?t.version.toString():"undefined",n in ns?ns[n](t,e):ts},function(n){if(404===n.status&&t.last_seq)return e.src.put({_id:e.id,last_seq:ts}).then(function(){return ts},function(n){return Gr(n)?(e.readOnlySource=!0,t.last_seq):ts});throw n})}).catch(function(e){if(404!==e.status)throw e;return ts})};var rs=0;co(eo,uo.EventEmitter),eo.prototype.cancel=function(){this.cancelled=!0,this.state="cancelled",this.emit("cancel")},eo.prototype.ready=function(e,t){function n(){o.cancel()}function r(){e.removeListener("destroyed",n),t.removeListener("destroyed",n)}var o=this;o._readyCalled||(o._readyCalled=!0,e.once("destroyed",n),t.once("destroyed",n),o.once("complete",r))},co(oo,uo.EventEmitter),oo.prototype.cancel=function(){this.canceled||(this.canceled=!0,this.push.cancel(),this.pull.cancel())},Te.plugin(_i).plugin(Ni).plugin(Ui).plugin(Qi).plugin(io),t.exports=Te}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{1:1,10:10,11:11,2:2,4:4,5:5,6:6,7:7}]},{},[12])(12)});
diff --git a/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb-7.1.1.min.js b/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb-7.1.1.min.js
new file mode 100644
index 0000000..a801b42
--- /dev/null
+++ b/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb-7.1.1.min.js
@@ -0,0 +1,7 @@
+// 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(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).PouchDB=e()}}(function(){return function o(s,a,u){function c(t,e){if(!a[t]){if(!s[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(f)return f(t,!0);var r=new Error("Cannot find module '"+t+"'");throw r.code="MODULE_NOT_FOUND",r}var i=a[t]={exports:{}};s[t][0].call(i.exports,function(e){return c(s[t][1][e]||e)},i,i.exports,o,s,a,u)}return a[t].exports}for(var f="function"==typeof require&&require,e=0;e<u.length;e++)c(u[e]);return c}({1:[function(e,t,n){"use strict";t.exports=function(r){return function(){var e=arguments.length;if(e){for(var t=[],n=-1;++n<e;)t[n]=arguments[n];return r.call(this,t)}return r.call(this,[])}}},{}],2:[function(e,t,n){var u=Object.create||function(e){function t(){}return t.prototype=e,new t},s=Object.keys||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.push(n);return n},o=Function.prototype.bind||function(e){var t=this;return function(){return t.apply(e,arguments)}};function r(){this._events&&Object.prototype.hasOwnProperty.call(this,"_events")||(this._events=u(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0}((t.exports=r).EventEmitter=r).prototype._events=void 0,r.prototype._maxListeners=void 0;var i,a=10;try{var c={};Object.defineProperty&&Object.defineProperty(c,"x",{value:0}),i=0===c.x}catch(e){i=!1}function f(e){return void 0===e._maxListeners?r.defaultMaxListeners:e._maxListeners}function l(e,t,n,r){var i,o,s;if("function"!=typeof n)throw new TypeError('"listener" argument must be a function');if((o=e._events)?(o.newListener&&(e.emit("newListener",t,n.listener?n.listener:n),o=e._events),s=o[t]):(o=e._events=u(null),e._eventsCount=0),s){if("function"==typeof s?s=o[t]=r?[n,s]:[s,n]:r?s.unshift(n):s.push(n),!s.warned&&(i=f(e))&&0<i&&s.length>i){s.warned=!0;var a=new Error("Possible EventEmitter memory leak detected. "+s.length+' "'+String(t)+'" listeners added. Use emitter.setMaxListeners() to increase limit.');a.name="MaxListenersExceededWarning",a.emitter=e,a.type=t,a.count=s.length,"object"==typeof console&&console.warn&&console.warn("%s: %s",a.name,a.message)}}else s=o[t]=n,++e._eventsCount;return e}function d(){if(!this.fired)switch(this.target.removeListener(this.type,this.wrapFn),this.fired=!0,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:for(var e=new Array(arguments.length),t=0;t<e.length;++t)e[t]=arguments[t];this.listener.apply(this.target,e)}}function h(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},i=o.call(d,r);return i.listener=n,r.wrapFn=i}function p(e,t,n){var r=e._events;if(!r)return[];var i=r[t];return i?"function"==typeof i?n?[i.listener||i]:[i]:n?function(e){for(var t=new Array(e.length),n=0;n<t.length;++n)t[n]=e[n].listener||e[n];return t}(i):y(i,i.length):[]}function v(e){var t=this._events;if(t){var n=t[e];if("function"==typeof n)return 1;if(n)return n.length}return 0}function y(e,t){for(var n=new Array(t),r=0;r<t;++r)n[r]=e[r];return n}i?Object.defineProperty(r,"defaultMaxListeners",{enumerable:!0,get:function(){return a},set:function(e){if("number"!=typeof e||e<0||e!=e)throw new TypeError('"defaultMaxListeners" must be a positive number');a=e}}):r.defaultMaxListeners=a,r.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||isNaN(e))throw new TypeError('"n" argument must be a positive number');return this._maxListeners=e,this},r.prototype.getMaxListeners=function(){return f(this)},r.prototype.emit=function(e,t,n,r){var i,o,s,a,u,c,f="error"===e;if(c=this._events)f=f&&null==c.error;else if(!f)return!1;if(f){if(1<arguments.length&&(i=t),i instanceof Error)throw i;var l=new Error('Unhandled "error" event. ('+i+")");throw l.context=i,l}if(!(o=c[e]))return!1;var d="function"==typeof o;switch(s=arguments.length){case 1:!function(e,t,n){if(t)e.call(n);else for(var r=e.length,i=y(e,r),o=0;o<r;++o)i[o].call(n)}(o,d,this);break;case 2:!function(e,t,n,r){if(t)e.call(n,r);else for(var i=e.length,o=y(e,i),s=0;s<i;++s)o[s].call(n,r)}(o,d,this,t);break;case 3:!function(e,t,n,r,i){if(t)e.call(n,r,i);else for(var o=e.length,s=y(e,o),a=0;a<o;++a)s[a].call(n,r,i)}(o,d,this,t,n);break;case 4:!function(e,t,n,r,i,o){if(t)e.call(n,r,i,o);else for(var s=e.length,a=y(e,s),u=0;u<s;++u)a[u].call(n,r,i,o)}(o,d,this,t,n,r);break;default:for(a=new Array(s-1),u=1;u<s;u++)a[u-1]=arguments[u];!function(e,t,n,r){if(t)e.apply(n,r);else for(var i=e.length,o=y(e,i),s=0;s<i;++s)o[s].apply(n,r)}(o,d,this,a)}return!0},r.prototype.on=r.prototype.addListener=function(e,t){return l(this,e,t,!1)},r.prototype.prependListener=function(e,t){return l(this,e,t,!0)},r.prototype.once=function(e,t){if("function"!=typeof t)throw new TypeError('"listener" argument must be a function');return this.on(e,h(this,e,t)),this},r.prototype.prependOnceListener=function(e,t){if("function"!=typeof t)throw new TypeError('"listener" argument must be a function');return this.prependListener(e,h(this,e,t)),this},r.prototype.removeListener=function(e,t){var n,r,i,o,s;if("function"!=typeof t)throw new TypeError('"listener" argument must be a function');if(!(r=this._events))return this;if(!(n=r[e]))return this;if(n===t||n.listener===t)0==--this._eventsCount?this._events=u(null):(delete r[e],r.removeListener&&this.emit("removeListener",e,n.listener||t));else if("function"!=typeof n){for(i=-1,o=n.length-1;0<=o;o--)if(n[o]===t||n[o].listener===t){s=n[o].listener,i=o;break}if(i<0)return this;0===i?n.shift():function(e,t){for(var n=t,r=n+1,i=e.length;r<i;n+=1,r+=1)e[n]=e[r];e.pop()}(n,i),1===n.length&&(r[e]=n[0]),r.removeListener&&this.emit("removeListener",e,s||t)}return this},r.prototype.removeAllListeners=function(e){var t,n,r;if(!(n=this._events))return this;if(!n.removeListener)return 0===arguments.length?(this._events=u(null),this._eventsCount=0):n[e]&&(0==--this._eventsCount?this._events=u(null):delete n[e]),this;if(0===arguments.length){var i,o=s(n);for(r=0;r<o.length;++r)"removeListener"!==(i=o[r])&&this.removeAllListeners(i);return this.removeAllListeners("removeListener"),this._events=u(null),this._eventsCount=0,this}if("function"==typeof(t=n[e]))this.removeListener(e,t);else if(t)for(r=t.length-1;0<=r;r--)this.removeListener(e,t[r]);return this},r.prototype.listeners=function(e){return p(this,e,!0)},r.prototype.rawListeners=function(e){return p(this,e,!1)},r.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):v.call(e,t)},r.prototype.listenerCount=v,r.prototype.eventNames=function(){return 0<this._eventsCount?Reflect.ownKeys(this._events):[]}},{}],3:[function(e,f,t){(function(t){"use strict";var n,r,e=t.MutationObserver||t.WebKitMutationObserver;if(e){var i=0,o=new e(c),s=t.document.createTextNode("");o.observe(s,{characterData:!0}),n=function(){s.data=i=++i%2}}else if(t.setImmediate||void 0===t.MessageChannel)n="document"in t&&"onreadystatechange"in t.document.createElement("script")?function(){var e=t.document.createElement("script");e.onreadystatechange=function(){c(),e.onreadystatechange=null,e.parentNode.removeChild(e),e=null},t.document.documentElement.appendChild(e)}:function(){setTimeout(c,0)};else{var a=new t.MessageChannel;a.port1.onmessage=c,n=function(){a.port2.postMessage(0)}}var u=[];function c(){var e,t;r=!0;for(var n=u.length;n;){for(t=u,u=[],e=-1;++e<n;)t[e]();n=u.length}r=!1}f.exports=function(e){1!==u.push(e)||r||n()}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],4:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;function n(){}n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],5:[function(e,t,n){var r,i,o=t.exports={};function s(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function u(t){if(r===setTimeout)return setTimeout(t,0);if((r===s||!r)&&setTimeout)return r=setTimeout,setTimeout(t,0);try{return r(t,0)}catch(e){try{return r.call(null,t,0)}catch(e){return r.call(this,t,0)}}}!function(){try{r="function"==typeof setTimeout?setTimeout:s}catch(e){r=s}try{i="function"==typeof clearTimeout?clearTimeout:a}catch(e){i=a}}();var c,f=[],l=!1,d=-1;function h(){l&&c&&(l=!1,c.length?f=c.concat(f):d=-1,f.length&&p())}function p(){if(!l){var e=u(h);l=!0;for(var t=f.length;t;){for(c=f,f=[];++d<t;)c&&c[d].run();d=-1,t=f.length}c=null,l=!1,function(t){if(i===clearTimeout)return clearTimeout(t);if((i===a||!i)&&clearTimeout)return i=clearTimeout,clearTimeout(t);try{i(t)}catch(e){try{return i.call(null,t)}catch(e){return i.call(this,t)}}}(e)}}function v(e,t){this.fun=e,this.array=t}function y(){}o.nextTick=function(e){var t=new Array(arguments.length-1);if(1<arguments.length)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];f.push(new v(e,t)),1!==f.length||l||u(p)},v.prototype.run=function(){this.fun.apply(null,this.array)},o.title="browser",o.browser=!0,o.env={},o.argv=[],o.version="",o.versions={},o.on=y,o.addListener=y,o.once=y,o.off=y,o.removeListener=y,o.removeAllListeners=y,o.emit=y,o.prependListener=y,o.prependOnceListener=y,o.listeners=function(e){return[]},o.binding=function(e){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(e){throw new Error("process.chdir is not supported")},o.umask=function(){return 0}},{}],6:[function(e,n,r){!function(e){if("object"==typeof r)n.exports=e();else{var t;try{t=window}catch(e){t=self}t.SparkMD5=e()}}(function(c){"use strict";var r=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];function f(e,t){var n=e[0],r=e[1],i=e[2],o=e[3];r=((r+=((i=((i+=((o=((o+=((n=((n+=(r&i|~r&o)+t[0]-680876936|0)<<7|n>>>25)+r|0)&r|~n&i)+t[1]-389564586|0)<<12|o>>>20)+n|0)&n|~o&r)+t[2]+606105819|0)<<17|i>>>15)+o|0)&o|~i&n)+t[3]-1044525330|0)<<22|r>>>10)+i|0,r=((r+=((i=((i+=((o=((o+=((n=((n+=(r&i|~r&o)+t[4]-176418897|0)<<7|n>>>25)+r|0)&r|~n&i)+t[5]+1200080426|0)<<12|o>>>20)+n|0)&n|~o&r)+t[6]-1473231341|0)<<17|i>>>15)+o|0)&o|~i&n)+t[7]-45705983|0)<<22|r>>>10)+i|0,r=((r+=((i=((i+=((o=((o+=((n=((n+=(r&i|~r&o)+t[8]+1770035416|0)<<7|n>>>25)+r|0)&r|~n&i)+t[9]-1958414417|0)<<12|o>>>20)+n|0)&n|~o&r)+t[10]-42063|0)<<17|i>>>15)+o|0)&o|~i&n)+t[11]-1990404162|0)<<22|r>>>10)+i|0,r=((r+=((i=((i+=((o=((o+=((n=((n+=(r&i|~r&o)+t[12]+1804603682|0)<<7|n>>>25)+r|0)&r|~n&i)+t[13]-40341101|0)<<12|o>>>20)+n|0)&n|~o&r)+t[14]-1502002290|0)<<17|i>>>15)+o|0)&o|~i&n)+t[15]+1236535329|0)<<22|r>>>10)+i|0,r=((r+=((i=((i+=((o=((o+=((n=((n+=(r&o|i&~o)+t[1]-165796510|0)<<5|n>>>27)+r|0)&i|r&~i)+t[6]-1069501632|0)<<9|o>>>23)+n|0)&r|n&~r)+t[11]+643717713|0)<<14|i>>>18)+o|0)&n|o&~n)+t[0]-373897302|0)<<20|r>>>12)+i|0,r=((r+=((i=((i+=((o=((o+=((n=((n+=(r&o|i&~o)+t[5]-701558691|0)<<5|n>>>27)+r|0)&i|r&~i)+t[10]+38016083|0)<<9|o>>>23)+n|0)&r|n&~r)+t[15]-660478335|0)<<14|i>>>18)+o|0)&n|o&~n)+t[4]-405537848|0)<<20|r>>>12)+i|0,r=((r+=((i=((i+=((o=((o+=((n=((n+=(r&o|i&~o)+t[9]+568446438|0)<<5|n>>>27)+r|0)&i|r&~i)+t[14]-1019803690|0)<<9|o>>>23)+n|0)&r|n&~r)+t[3]-187363961|0)<<14|i>>>18)+o|0)&n|o&~n)+t[8]+1163531501|0)<<20|r>>>12)+i|0,r=((r+=((i=((i+=((o=((o+=((n=((n+=(r&o|i&~o)+t[13]-1444681467|0)<<5|n>>>27)+r|0)&i|r&~i)+t[2]-51403784|0)<<9|o>>>23)+n|0)&r|n&~r)+t[7]+1735328473|0)<<14|i>>>18)+o|0)&n|o&~n)+t[12]-1926607734|0)<<20|r>>>12)+i|0,r=((r+=((i=((i+=((o=((o+=((n=((n+=(r^i^o)+t[5]-378558|0)<<4|n>>>28)+r|0)^r^i)+t[8]-2022574463|0)<<11|o>>>21)+n|0)^n^r)+t[11]+1839030562|0)<<16|i>>>16)+o|0)^o^n)+t[14]-35309556|0)<<23|r>>>9)+i|0,r=((r+=((i=((i+=((o=((o+=((n=((n+=(r^i^o)+t[1]-1530992060|0)<<4|n>>>28)+r|0)^r^i)+t[4]+1272893353|0)<<11|o>>>21)+n|0)^n^r)+t[7]-155497632|0)<<16|i>>>16)+o|0)^o^n)+t[10]-1094730640|0)<<23|r>>>9)+i|0,r=((r+=((i=((i+=((o=((o+=((n=((n+=(r^i^o)+t[13]+681279174|0)<<4|n>>>28)+r|0)^r^i)+t[0]-358537222|0)<<11|o>>>21)+n|0)^n^r)+t[3]-722521979|0)<<16|i>>>16)+o|0)^o^n)+t[6]+76029189|0)<<23|r>>>9)+i|0,r=((r+=((i=((i+=((o=((o+=((n=((n+=(r^i^o)+t[9]-640364487|0)<<4|n>>>28)+r|0)^r^i)+t[12]-421815835|0)<<11|o>>>21)+n|0)^n^r)+t[15]+530742520|0)<<16|i>>>16)+o|0)^o^n)+t[2]-995338651|0)<<23|r>>>9)+i|0,r=((r+=((o=((o+=(r^((n=((n+=(i^(r|~o))+t[0]-198630844|0)<<6|n>>>26)+r|0)|~i))+t[7]+1126891415|0)<<10|o>>>22)+n|0)^((i=((i+=(n^(o|~r))+t[14]-1416354905|0)<<15|i>>>17)+o|0)|~n))+t[5]-57434055|0)<<21|r>>>11)+i|0,r=((r+=((o=((o+=(r^((n=((n+=(i^(r|~o))+t[12]+1700485571|0)<<6|n>>>26)+r|0)|~i))+t[3]-1894986606|0)<<10|o>>>22)+n|0)^((i=((i+=(n^(o|~r))+t[10]-1051523|0)<<15|i>>>17)+o|0)|~n))+t[1]-2054922799|0)<<21|r>>>11)+i|0,r=((r+=((o=((o+=(r^((n=((n+=(i^(r|~o))+t[8]+1873313359|0)<<6|n>>>26)+r|0)|~i))+t[15]-30611744|0)<<10|o>>>22)+n|0)^((i=((i+=(n^(o|~r))+t[6]-1560198380|0)<<15|i>>>17)+o|0)|~n))+t[13]+1309151649|0)<<21|r>>>11)+i|0,r=((r+=((o=((o+=(r^((n=((n+=(i^(r|~o))+t[4]-145523070|0)<<6|n>>>26)+r|0)|~i))+t[11]-1120210379|0)<<10|o>>>22)+n|0)^((i=((i+=(n^(o|~r))+t[2]+718787259|0)<<15|i>>>17)+o|0)|~n))+t[9]-343485551|0)<<21|r>>>11)+i|0,e[0]=n+e[0]|0,e[1]=r+e[1]|0,e[2]=i+e[2]|0,e[3]=o+e[3]|0}function l(e){var t,n=[];for(t=0;t<64;t+=4)n[t>>2]=e.charCodeAt(t)+(e.charCodeAt(t+1)<<8)+(e.charCodeAt(t+2)<<16)+(e.charCodeAt(t+3)<<24);return n}function d(e){var t,n=[];for(t=0;t<64;t+=4)n[t>>2]=e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24);return n}function i(e){var t,n,r,i,o,s,a=e.length,u=[1732584193,-271733879,-1732584194,271733878];for(t=64;t<=a;t+=64)f(u,l(e.substring(t-64,t)));for(n=(e=e.substring(t-64)).length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;t<n;t+=1)r[t>>2]|=e.charCodeAt(t)<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),55<t)for(f(u,r),t=0;t<16;t+=1)r[t]=0;return i=(i=8*a).toString(16).match(/(.*?)(.{0,8})$/),o=parseInt(i[2],16),s=parseInt(i[1],16)||0,r[14]=o,r[15]=s,f(u,r),u}function n(e){var t,n="";for(t=0;t<4;t+=1)n+=r[e>>8*t+4&15]+r[e>>8*t&15];return n}function s(e){var t;for(t=0;t<e.length;t+=1)e[t]=n(e[t]);return e.join("")}function h(e,t){return(e=0|e||0)<0?Math.max(e+t,0):Math.min(e,t)}function o(e){return/[\u0080-\uFFFF]/.test(e)&&(e=unescape(encodeURIComponent(e))),e}function a(e){var t,n=[],r=e.length;for(t=0;t<r-1;t+=2)n.push(parseInt(e.substr(t,2),16));return String.fromCharCode.apply(String,n)}function u(){this.reset()}return"5d41402abc4b2a76b9719d911017c592"!==s(i("hello"))&&function(e,t){var n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n},"undefined"==typeof ArrayBuffer||ArrayBuffer.prototype.slice||(ArrayBuffer.prototype.slice=function(e,t){var n,r,i,o,s=this.byteLength,a=h(e,s),u=s;return t!==c&&(u=h(t,s)),u<a?new ArrayBuffer(0):(n=u-a,r=new ArrayBuffer(n),i=new Uint8Array(r),o=new Uint8Array(this,a,n),i.set(o),r)}),u.prototype.append=function(e){return this.appendBinary(o(e)),this},u.prototype.appendBinary=function(e){this._buff+=e,this._length+=e.length;var t,n=this._buff.length;for(t=64;t<=n;t+=64)f(this._hash,l(this._buff.substring(t-64,t)));return this._buff=this._buff.substring(t-64),this},u.prototype.end=function(e){var t,n,r=this._buff,i=r.length,o=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;t<i;t+=1)o[t>>2]|=r.charCodeAt(t)<<(t%4<<3);return this._finish(o,i),n=s(this._hash),e&&(n=a(n)),this.reset(),n},u.prototype.reset=function(){return this._buff="",this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},u.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash}},u.prototype.setState=function(e){return this._buff=e.buff,this._length=e.length,this._hash=e.hash,this},u.prototype.destroy=function(){delete this._hash,delete this._buff,delete this._length},u.prototype._finish=function(e,t){var n,r,i,o=t;if(e[o>>2]|=128<<(o%4<<3),55<o)for(f(this._hash,e),o=0;o<16;o+=1)e[o]=0;n=(n=8*this._length).toString(16).match(/(.*?)(.{0,8})$/),r=parseInt(n[2],16),i=parseInt(n[1],16)||0,e[14]=r,e[15]=i,f(this._hash,e)},u.hash=function(e,t){return u.hashBinary(o(e),t)},u.hashBinary=function(e,t){var n=s(i(e));return t?a(n):n},(u.ArrayBuffer=function(){this.reset()}).prototype.append=function(e){var t,n=function(e,t,n){var r=new Uint8Array(e.byteLength+t.byteLength);return r.set(new Uint8Array(e)),r.set(new Uint8Array(t),e.byteLength),n?r:r.buffer}(this._buff.buffer,e,!0),r=n.length;for(this._length+=e.byteLength,t=64;t<=r;t+=64)f(this._hash,d(n.subarray(t-64,t)));return this._buff=t-64<r?new Uint8Array(n.buffer.slice(t-64)):new Uint8Array(0),this},u.ArrayBuffer.prototype.end=function(e){var t,n,r=this._buff,i=r.length,o=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;t<i;t+=1)o[t>>2]|=r[t]<<(t%4<<3);return this._finish(o,i),n=s(this._hash),e&&(n=a(n)),this.reset(),n},u.ArrayBuffer.prototype.reset=function(){return this._buff=new Uint8Array(0),this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},u.ArrayBuffer.prototype.getState=function(){var e=u.prototype.getState.call(this);return e.buff=function(e){return String.fromCharCode.apply(null,new Uint8Array(e))}(e.buff),e},u.ArrayBuffer.prototype.setState=function(e){return e.buff=function(e,t){var n,r=e.length,i=new ArrayBuffer(r),o=new Uint8Array(i);for(n=0;n<r;n+=1)o[n]=e.charCodeAt(n);return t?o:i}(e.buff,!0),u.prototype.setState.call(this,e)},u.ArrayBuffer.prototype.destroy=u.prototype.destroy,u.ArrayBuffer.prototype._finish=u.prototype._finish,u.ArrayBuffer.hash=function(e,t){var n=s(function(e){var t,n,r,i,o,s,a=e.length,u=[1732584193,-271733879,-1732584194,271733878];for(t=64;t<=a;t+=64)f(u,d(e.subarray(t-64,t)));for(n=(e=t-64<a?e.subarray(t-64):new Uint8Array(0)).length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;t<n;t+=1)r[t>>2]|=e[t]<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),55<t)for(f(u,r),t=0;t<16;t+=1)r[t]=0;return i=(i=8*a).toString(16).match(/(.*?)(.{0,8})$/),o=parseInt(i[2],16),s=parseInt(i[1],16)||0,r[14]=o,r[15]=s,f(u,r),u}(new Uint8Array(e)));return t?a(n):n},u})},{}],7:[function(e,t,n){var r=e(10),i=e(11),o=i;o.v1=r,o.v4=i,t.exports=o},{10:10,11:11}],8:[function(e,t,n){for(var i=[],r=0;r<256;++r)i[r]=(r+256).toString(16).substr(1);t.exports=function(e,t){var n=t||0,r=i;return r[e[n++]]+r[e[n++]]+r[e[n++]]+r[e[n++]]+"-"+r[e[n++]]+r[e[n++]]+"-"+r[e[n++]]+r[e[n++]]+"-"+r[e[n++]]+r[e[n++]]+"-"+r[e[n++]]+r[e[n++]]+r[e[n++]]+r[e[n++]]+r[e[n++]]+r[e[n++]]}},{}],9:[function(e,t,n){var r="undefined"!=typeof crypto&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&msCrypto.getRandomValues.bind(msCrypto);if(r){var i=new Uint8Array(16);t.exports=function(){return r(i),i}}else{var o=new Array(16);t.exports=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),o[t]=e>>>((3&t)<<3)&255;return o}}},{}],10:[function(e,t,n){var p,v,y=e(9),_=e(8),g=0,m=0;t.exports=function(e,t,n){var r=t&&n||0,i=t||[],o=(e=e||{}).node||p,s=void 0!==e.clockseq?e.clockseq:v;if(null==o||null==s){var a=y();null==o&&(o=p=[1|a[0],a[1],a[2],a[3],a[4],a[5]]),null==s&&(s=v=16383&(a[6]<<8|a[7]))}var u=void 0!==e.msecs?e.msecs:(new Date).getTime(),c=void 0!==e.nsecs?e.nsecs:m+1,f=u-g+(c-m)/1e4;if(f<0&&void 0===e.clockseq&&(s=s+1&16383),(f<0||g<u)&&void 0===e.nsecs&&(c=0),1e4<=c)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");g=u,v=s;var l=(1e4*(268435455&(u+=122192928e5))+(m=c))%4294967296;i[r++]=l>>>24&255,i[r++]=l>>>16&255,i[r++]=l>>>8&255,i[r++]=255&l;var d=u/4294967296*1e4&268435455;i[r++]=d>>>8&255,i[r++]=255&d,i[r++]=d>>>24&15|16,i[r++]=d>>>16&255,i[r++]=s>>>8|128,i[r++]=255&s;for(var h=0;h<6;++h)i[r+h]=o[h];return t||_(i)}},{8:8,9:9}],11:[function(e,t,n){var s=e(9),a=e(8);t.exports=function(e,t,n){var r=t&&n||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var i=(e=e||{}).random||(e.rng||s)();if(i[6]=15&i[6]|64,i[8]=63&i[8]|128,t)for(var o=0;o<16;++o)t[r+o]=i[o];return t||a(i)}},{8:8,9:9}],12:[function(e,t,n){"use strict";function h(e,t,n){var r=n[n.length-1];e===r.element&&(n.pop(),r=n[n.length-1]);var i=r.element,o=r.index;if(Array.isArray(i))i.push(e);else if(o===t.length-2){i[t.pop()]=e}else t.push(e)}n.stringify=function(e){var t=[];t.push({obj:e});for(var n,r,i,o,s,a,u,c,f,l,d="";n=t.pop();)if(r=n.obj,d+=n.prefix||"",i=n.val||"")d+=i;else if("object"!=typeof r)d+=void 0===r?null:JSON.stringify(r);else if(null===r)d+="null";else if(Array.isArray(r)){for(t.push({val:"]"}),o=r.length-1;0<=o;o--)s=0===o?"":",",t.push({obj:r[o],prefix:s});t.push({val:"["})}else{for(u in a=[],r)r.hasOwnProperty(u)&&a.push(u);for(t.push({val:"}"}),o=a.length-1;0<=o;o--)f=r[c=a[o]],l=0<o?",":"",l+=JSON.stringify(c)+":",t.push({obj:f,prefix:l});t.push({val:"{"})}return d},n.parse=function(e){for(var t,n,r,i,o,s,a,u,c,f=[],l=[],d=0;;)if("}"!==(t=e[d++])&&"]"!==t&&void 0!==t)switch(t){case" ":case"\t":case"\n":case":":case",":break;case"n":d+=3,h(null,f,l);break;case"t":d+=3,h(!0,f,l);break;case"f":d+=4,h(!1,f,l);break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":case"-":for(n="",d--;;){if(r=e[d++],!/[\d\.\-e\+]/.test(r)){d--;break}n+=r}h(parseFloat(n),f,l);break;case'"':for(i="",o=void 0,s=0;'"'!==(a=e[d++])||"\\"===o&&s%2==1;)i+=a,"\\"===(o=a)?s++:s=0;h(JSON.parse('"'+i+'"'),f,l);break;case"[":u={element:[],index:f.length},f.push(u.element),l.push(u);break;case"{":c={element:{},index:f.length},f.push(c.element),l.push(c);break;default:throw new Error("unexpectedly reached end of input: "+t)}else{if(1===f.length)return f.pop();h(f.pop(),f,l)}}},{}],13:[function(Dr,Ir,e){(function(u,e){"use strict";function t(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var b,x,T=t(Dr(3)),r=t(Dr(7)),d=t(Dr(6)),i=t(Dr(12)),f=t(Dr(1)),o=t(Dr(4)),a=Dr(2);function s(e){return"$"+e}function c(){this._store={}}function n(e){if(this._store=new c,e&&Array.isArray(e))for(var t=0,n=e.length;t<n;t++)this.add(e[t])}function l(e){if(e instanceof ArrayBuffer)return function(e){if("function"==typeof e.slice)return e.slice(0);var t=new ArrayBuffer(e.byteLength),n=new Uint8Array(t),r=new Uint8Array(e);return n.set(r),t}(e);var t=e.size,n=e.type;return"function"==typeof e.slice?e.slice(0,t,n):e.webkitSlice(0,t,n)}c.prototype.get=function(e){var t=s(e);return this._store[t]},c.prototype.set=function(e,t){var n=s(e);return this._store[n]=t,!0},c.prototype.has=function(e){return s(e)in this._store},c.prototype.delete=function(e){var t=s(e),n=t in this._store;return delete this._store[t],n},c.prototype.forEach=function(e){for(var t=Object.keys(this._store),n=0,r=t.length;n<r;n++){var i=t[n];e(this._store[i],i=i.substring(1))}},Object.defineProperty(c.prototype,"size",{get:function(){return Object.keys(this._store).length}}),n.prototype.add=function(e){return this._store.set(e,!0)},n.prototype.has=function(e){return this._store.has(e)},n.prototype.forEach=function(n){this._store.forEach(function(e,t){n(t)})},Object.defineProperty(n.prototype,"size",{get:function(){return this._store.size}}),x=function(){if("undefined"==typeof Symbol||"undefined"==typeof Map||"undefined"==typeof Set)return!1;var e=Object.getOwnPropertyDescriptor(Map,Symbol.species);return e&&"get"in e&&Map[Symbol.species]===Map}()?(b=Set,Map):(b=n,c);var h=Function.prototype.toString,p=h.call(Object);function R(e){var t,n,r;if(!e||"object"!=typeof e)return e;if(Array.isArray(e)){for(t=[],n=0,r=e.length;n<r;n++)t[n]=R(e[n]);return t}if(e instanceof Date)return e.toISOString();if(function(e){return"undefined"!=typeof ArrayBuffer&&e instanceof ArrayBuffer||"undefined"!=typeof Blob&&e instanceof Blob}(e))return l(e);if(!function(e){var t=Object.getPrototypeOf(e);if(null===t)return!0;var n=t.constructor;return"function"==typeof n&&n instanceof n&&h.call(n)==p}(e))return e;for(n in t={},e)if(Object.prototype.hasOwnProperty.call(e,n)){var i=R(e[n]);void 0!==i&&(t[n]=i)}return t}function v(t){var n=!1;return f(function(e){if(n)throw new Error("once called more than once");n=!0,t.apply(this,e)})}function y(s){return f(function(i){i=R(i);var o=this,t="function"==typeof i[i.length-1]&&i.pop(),e=new Promise(function(n,r){var e;try{var t=v(function(e,t){e?r(e):n(t)});i.push(t),(e=s.apply(o,i))&&"function"==typeof e.then&&n(e)}catch(e){r(e)}});return t&&e.then(function(e){t(null,e)},t),e})}function m(o,e){return y(f(function(r){if(this._closed)return Promise.reject(new Error("database is closed"));if(this._destroyed)return Promise.reject(new Error("database is destroyed"));var i=this;return function(r,i,e){if(r.constructor.listeners("debug").length){for(var t=["api",r.name,i],n=0;n<e.length-1;n++)t.push(e[n]);r.constructor.emit("debug",t);var o=e[e.length-1];e[e.length-1]=function(e,t){var n=["api",r.name,i];n=n.concat(e?["error",e]:["success",t]),r.constructor.emit("debug",n),o(e,t)}}}(i,o,r),this.taskqueue.isReady?e.apply(this,r):new Promise(function(t,n){i.taskqueue.addTask(function(e){e?n(e):t(i[o].apply(i,r))})})}))}function w(e,t){for(var n={},r=0,i=t.length;r<i;r++){var o=t[r];o in e&&(n[o]=e[o])}return n}var _,g=6;function k(e){return e}function j(e){return[{ok:e}]}function O(a,u,e){var t=u.docs,c=new x;t.forEach(function(e){c.has(e.id)?c.get(e.id).push(e):c.set(e.id,[e])});var n=c.size,r=0,f=new Array(n);function l(){++r===n&&function(){var n=[];f.forEach(function(t){t.docs.forEach(function(e){n.push({id:t.id,docs:[e]})})}),e(null,{results:n})}()}var i=[];c.forEach(function(e,t){i.push(t)});var o=0;function d(){if(!(o>=i.length)){var e=Math.min(o+g,i.length),t=i.slice(o,e);!function(e,s){e.forEach(function(r,e){var i=s+e,t=c.get(r),n=w(t[0],["atts_since","attachments"]);n.open_revs=t.map(function(e){return e.rev}),n.open_revs=n.open_revs.filter(k);var o=k;0===n.open_revs.length&&(delete n.open_revs,o=j),["revs","attachments","binary","ajax","latest"].forEach(function(e){e in u&&(n[e]=u[e])}),a.get(r,n,function(e,t){var n;n=e?[{error:e}]:o(t),function(e,t,n){f[e]={id:t,docs:n},l()}(i,r,n),d()})})}(t,o),o+=t.length}}d()}try{localStorage.setItem("_pouch_check_localstorage",1),_=!!localStorage.getItem("_pouch_check_localstorage")}catch(e){_=!1}function A(){return _}function q(){a.EventEmitter.call(this),this._listeners={},function(t){A()&&addEventListener("storage",function(e){t.emit(e.key)})}(this)}function E(e){if("undefined"!=typeof console&&"function"==typeof console[e]){var t=Array.prototype.slice.call(arguments,1);console[e].apply(console,t)}}function M(e){var t=0;return e||(t=2e3),function(e,t){return e=parseInt(e,10)||0,(t=parseInt(t,10))!=t||t<=e?t=(e||1)<<1:t+=1,6e5<t&&(e=3e5,t=6e5),~~((t-e)*Math.random()+e)}(e,t)}function S(e,t){E("info","The above "+e+" is totally normal. "+t)}o(q,a.EventEmitter),q.prototype.addListener=function(e,t,n,r){if(!this._listeners[t]){var i=this,o=!1;this._listeners[t]=s,this.on(e,s)}function s(){if(i._listeners[t])if(o)o="waiting";else{o=!0;var e=w(r,["style","include_docs","attachments","conflicts","filter","doc_ids","view","since","query_params","binary","return_docs"]);n.changes(e).on("change",function(e){e.seq>r.since&&!r.cancelled&&(r.since=e.seq,r.onChange(e))}).on("complete",function(){"waiting"===o&&T(s),o=!1}).on("error",function(){o=!1})}}},q.prototype.removeListener=function(e,t){t in this._listeners&&(a.EventEmitter.prototype.removeListener.call(this,e,this._listeners[t]),delete this._listeners[t])},q.prototype.notifyLocalWindows=function(e){A()&&(localStorage[e]="a"===localStorage[e]?"b":"a")},q.prototype.notify=function(e){this.emit(e),this.notifyLocalWindows(e)};var C="function"==typeof Object.assign?Object.assign:function(e){for(var t=Object(e),n=1;n<arguments.length;n++){var r=arguments[n];if(null!=r)for(var i in r)Object.prototype.hasOwnProperty.call(r,i)&&(t[i]=r[i])}return t};function P(e,t,n){Error.call(this,n),this.status=e,this.name=t,this.message=n,this.error=!0}o(P,Error),P.prototype.toString=function(){return JSON.stringify({status:this.status,name:this.name,message:this.message,reason:this.reason})};new P(401,"unauthorized","Name or password is incorrect.");var L=new P(400,"bad_request","Missing JSON list of 'docs'"),$=new P(404,"not_found","missing"),D=new P(409,"conflict","Document update conflict"),I=new P(400,"bad_request","_id field must contain a string"),B=new P(412,"missing_id","_id is required for puts"),N=new P(400,"bad_request","Only reserved document ids may start with underscore."),U=(new P(412,"precondition_failed","Database not open"),new P(500,"unknown_error","Database encountered an unknown error")),F=new P(500,"badarg","Some query argument is invalid"),K=(new P(400,"invalid_request","Request was invalid"),new P(400,"query_parse_error","Some query parameter is invalid")),J=new P(500,"doc_validation","Bad special document member"),z=new P(400,"bad_request","Something wrong with the request"),V=new P(400,"bad_request","Document must be a JSON object"),G=(new P(404,"not_found","Database not found"),new P(500,"indexed_db_went_bad","unknown")),Q=(new P(500,"web_sql_went_bad","unknown"),new P(500,"levelDB_went_went_bad","unknown"),new P(403,"forbidden","Forbidden by design doc validate_doc_update function"),new P(400,"bad_request","Invalid rev format")),W=(new P(412,"file_exists","The database could not be created, the file already exists."),new P(412,"missing_stub","A pre-existing attachment stub wasn't found"));new P(413,"invalid_url","Provided URL is invalid");function Y(n,e){function t(e){for(var t in n)"function"!=typeof n[t]&&(this[t]=n[t]);void 0!==e&&(this.reason=e)}return t.prototype=P.prototype,new t(e)}function H(e){if("object"!=typeof e){var t=e;(e=U).data=t}return"error"in e&&"conflict"===e.error&&(e.name="conflict",e.status=409),"name"in e||(e.name=e.error||"unknown"),"status"in e||(e.status=500),"message"in e||(e.message=e.message||e.reason),e}function X(r){var i={},o=r.filter&&"function"==typeof r.filter;return i.query=r.query_params,function(e){e.doc||(e.doc={});var t=o&&function(e,t,n){try{return!e(t,n)}catch(e){var r="Filter function threw: "+e.toString();return Y(z,r)}}(r.filter,e.doc,i);if("object"==typeof t)return t;if(t)return!1;if(r.include_docs){if(!r.attachments)for(var n in e.doc._attachments)e.doc._attachments.hasOwnProperty(n)&&(e.doc._attachments[n].stub=!0)}else delete e.doc;return!0}}function Z(e){for(var t=[],n=0,r=e.length;n<r;n++)t=t.concat(e[n]);return t}function ee(e){var t;if(e?"string"!=typeof e?t=Y(I):/^_/.test(e)&&!/^_(design|local)/.test(e)&&(t=Y(N)):t=Y(B),t)throw t}function te(e){return"boolean"==typeof e._remote?e._remote:"function"==typeof e.type&&(E("warn","db.type() is deprecated and will be removed in a future version of PouchDB"),"http"===e.type())}function ne(e){if(!e)return null;var t=e.split("/");return 2===t.length?t:1===t.length?[e,e]:null}function re(e){var t=ne(e);return t?t.join("/"):null}var ie=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],oe="queryKey",se=/(?:^|&)([^&=]*)=?([^&]*)/g,ae=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;function ue(e){for(var t=ae.exec(e),r={},n=14;n--;){var i=ie[n],o=t[n]||"",s=-1!==["user","password"].indexOf(i);r[i]=s?decodeURIComponent(o):o}return r[oe]={},r[ie[12]].replace(se,function(e,t,n){t&&(r[oe][t]=n)}),r}function ce(e,t){var n=[],r=[];for(var i in t)t.hasOwnProperty(i)&&(n.push(i),r.push(t[i]));return n.push(e),Function.apply(null,n).apply(null,r)}function fe(s,a,u){return new Promise(function(i,o){s.get(a,function(e,t){if(e){if(404!==e.status)return o(e);t={}}var n=t._rev,r=u(t);if(!r)return i({updated:!1,rev:n});r._id=a,r._rev=n,i(function(t,n,r){return t.put(n).then(function(e){return{updated:!0,rev:e.rev}},function(e){if(409!==e.status)throw e;return fe(t,n._id,r)})}(s,r,u))})})}var le=function(e){return atob(e)},de=function(e){return btoa(e)};function he(t,n){t=t||[],n=n||{};try{return new Blob(t,n)}catch(e){if("TypeError"!==e.name)throw e;for(var r=new("undefined"!=typeof BlobBuilder?BlobBuilder:"undefined"!=typeof MSBlobBuilder?MSBlobBuilder:"undefined"!=typeof MozBlobBuilder?MozBlobBuilder:WebKitBlobBuilder),i=0;i<t.length;i+=1)r.append(t[i]);return r.getBlob(n.type)}}function pe(e,t){return he([function(e){for(var t=e.length,n=new ArrayBuffer(t),r=new Uint8Array(n),i=0;i<t;i++)r[i]=e.charCodeAt(i);return n}(e)],{type:t})}function ve(e,t){return pe(le(e),t)}function ye(e,n){var t=new FileReader,r="function"==typeof t.readAsBinaryString;t.onloadend=function(e){var t=e.target.result||"";if(r)return n(t);n(function(e){for(var t="",n=new Uint8Array(e),r=n.byteLength,i=0;i<r;i++)t+=String.fromCharCode(n[i]);return t}(t))},r?t.readAsBinaryString(e):t.readAsArrayBuffer(e)}function _e(e,t){ye(e,function(e){t(e)})}function ge(e,t){_e(e,function(e){t(de(e))})}var me=e.setImmediate||e.setTimeout,be=32768;function we(t,e,n,r,i){(0<n||r<e.size)&&(e=function(e,t,n){return e.webkitSlice?e.webkitSlice(t,n):e.slice(t,n)}(e,n,r)),function(e,n){var t=new FileReader;t.onloadend=function(e){var t=e.target.result||new ArrayBuffer(0);n(t)},t.readAsArrayBuffer(e)}(e,function(e){t.append(e),i()})}function ke(e,t,n,r,i){(0<n||r<t.length)&&(t=t.substring(n,r)),e.appendBinary(t),i()}function je(n,t){var e="string"==typeof n,r=e?n.length:n.size,i=Math.min(be,r),o=Math.ceil(r/i),s=0,a=e?new d:new d.ArrayBuffer,u=e?ke:we;function c(){me(l)}function f(){var e=function(e){return de(e)}(a.end(!0));t(e),a.destroy()}function l(){var e=s*i,t=e+i;u(a,n,e,t,++s<o?c:f)}l()}function Oe(e){return d.hash(e)}function Ae(e,t){var n=R(e);return t?(delete n._rev_tree,Oe(JSON.stringify(n))):r.v4().replace(/-/g,"").toLowerCase()}var qe=r.v4;function Ee(e){for(var t,n,r,i,o=e.rev_tree.slice();i=o.pop();){var s=i.ids,a=s[2],u=i.pos;if(a.length)for(var c=0,f=a.length;c<f;c++)o.push({pos:u+1,ids:a[c]});else{var l=!!s[1].deleted,d=s[0];t&&!(r!==l?r:n!==u?n<u:t<d)||(t=d,n=u,r=l)}}return n+"-"+t}function Se(e,t){for(var n,r=e.slice();n=r.pop();)for(var i=n.pos,o=n.ids,s=o[2],a=t(0===s.length,i,o[0],n.ctx,o[1]),u=0,c=s.length;u<c;u++)r.push({pos:i+1,ids:s[u],ctx:a})}function xe(e,t){return e.pos-t.pos}function Ce(e){var o=[];Se(e,function(e,t,n,r,i){e&&o.push({rev:t+"-"+n,pos:t,opts:i})}),o.sort(xe).reverse();for(var t=0,n=o.length;t<n;t++)delete o[t].pos;return o}function Pe(e){for(var t=Ee(e),n=Ce(e.rev_tree),r=[],i=0,o=n.length;i<o;i++){var s=n[i];s.rev===t||s.opts.deleted||r.push(s.rev)}return r}function Le(e){for(var t,n=[],r=e.slice();t=r.pop();){var i=t.pos,o=t.ids,s=o[0],a=o[1],u=o[2],c=0===u.length,f=t.history?t.history.slice():[];f.push({id:s,opts:a}),c&&n.push({pos:i+1-f.length,ids:f});for(var l=0,d=u.length;l<d;l++)r.push({pos:i+1,ids:u[l],history:f})}return n.reverse()}function $e(e,t){return e.pos-t.pos}function De(e,t){for(var n,r,i=t,o=e.length;i<o;i++){var s=e[i],a=[s.id,s.opts,[]];r?(r[2].push(a),r=a):n=r=a}return n}function Ie(e,t){return e[0]<t[0]?-1:1}function Be(e,t){for(var n,r,i,o=[{tree1:e,tree2:t}],s=!1;0<o.length;){var a=o.pop(),u=a.tree1,c=a.tree2;(u[1].status||c[1].status)&&(u[1].status="available"===u[1].status||"available"===c[1].status?"available":"missing");for(var f=0;f<c[2].length;f++)if(u[2][0]){for(var l=!1,d=0;d<u[2].length;d++)u[2][d][0]===c[2][f][0]&&(o.push({tree1:u[2][d],tree2:c[2][f]}),l=!0);l||(s="new_branch",n=u[2],r=c[2][f],void 0,i=function(e,t,n){for(var r,i=0,o=e.length;i<o;)n(e[r=i+o>>>1],t)<0?i=1+r:o=r;return i}(n,r,Ie),n.splice(i,0,r))}else s="new_leaf",u[2][0]=c[2][f]}return{conflicts:s,tree:e}}function Te(e,t,n){var r,i=[],o=!1,s=!1;if(!e.length)return{tree:[t],conflicts:"new_leaf"};for(var a=0,u=e.length;a<u;a++){var c=e[a];if(c.pos===t.pos&&c.ids[0]===t.ids[0])r=Be(c.ids,t.ids),i.push({pos:c.pos,ids:r.tree}),o=o||r.conflicts,s=!0;else if(!0!==n){var f=c.pos<t.pos?c:t,l=c.pos<t.pos?t:c,d=l.pos-f.pos,h=[],p=[];for(p.push({ids:f.ids,diff:d,parent:null,parentIdx:null});0<p.length;){var v=p.pop();if(0!==v.diff)for(var y=v.ids[2],_=0,g=y.length;_<g;_++)p.push({ids:y[_],diff:v.diff-1,parent:v.ids,parentIdx:_});else v.ids[0]===l.ids[0]&&h.push(v)}var m=h[0];m?(r=Be(m.ids,l.ids),m.parent[2][m.parentIdx]=r.tree,i.push({pos:f.pos,ids:f.ids}),o=o||r.conflicts,s=!0):i.push(c)}else i.push(c)}return s||i.push(t),i.sort($e),{tree:i,conflicts:o||"internal_node"}}function Re(e,t,n){var r=Te(e,t),i=function(e,t){for(var r,n,i=Le(e),o=0,s=i.length;o<s;o++){var a,u=i[o],c=u.ids;if(c.length>t){r||(r={});var f=c.length-t;a={pos:u.pos+f,ids:De(c,f)};for(var l=0;l<f;l++){var d=u.pos+l+"-"+c[l].id;r[d]=!0}}else a={pos:u.pos,ids:De(c,0)};n=n?Te(n,a,!0).tree:[a]}return r&&Se(n,function(e,t,n){delete r[t+"-"+n]}),{tree:n,revs:r?Object.keys(r):[]}}(r.tree,n);return{tree:i.tree,stemmedRevs:i.revs,conflicts:r.conflicts}}function Me(e){return e.ids}function Ne(e,t){t||(t=Ee(e));for(var n,r=t.substring(t.indexOf("-")+1),i=e.rev_tree.map(Me);n=i.pop();){if(n[0]===r)return!!n[1].deleted;i=i.concat(n[2])}}function Ue(e){return/^_local/.test(e)}function Fe(n,t,r){a.EventEmitter.call(this);var i=this;this.db=n;var o=(t=t?R(t):{}).complete=v(function(e,t){e?0<function(e,t){return"listenerCount"in e?e.listenerCount(t):a.EventEmitter.listenerCount(e,t)}(i,"error")&&i.emit("error",e):i.emit("complete",t),i.removeAllListeners(),n.removeListener("destroyed",s)});function s(){i.cancel()}r&&(i.on("complete",function(e){r(null,e)}),i.on("error",r)),n.once("destroyed",s),t.onChange=function(e,t,n){i.isCancelled||function(e,t,n,r){try{e.emit("change",t,n,r)}catch(e){E("error",'Error in .on("change", function):',e)}}(i,e,t,n)};var e=new Promise(function(n,r){t.complete=function(e,t){e?r(e):n(t)}});i.once("cancel",function(){n.removeListener("destroyed",s),t.complete(null,{status:"cancelled"})}),this.then=e.then.bind(e),this.catch=e.catch.bind(e),this.then(function(e){o(null,e)},o),n.taskqueue.isReady?i.validateChanges(t):n.taskqueue.addTask(function(e){e?t.complete(e):i.isCancelled?i.emit("cancel"):i.validateChanges(t)})}function Ke(e,t,n){var r=[{rev:e._rev}];"all_docs"===n.style&&(r=Ce(t.rev_tree).map(function(e){return{rev:e.rev}}));var i={id:t.id,changes:r,doc:e};return Ne(t,e._rev)&&(i.deleted=!0),n.conflicts&&(i.doc._conflicts=Pe(t),i.doc._conflicts.length||delete i.doc._conflicts),i}function Je(e,t){return e<t?-1:t<e?1:0}function ze(n,r){return function(e,t){e||t[0]&&t[0].error?((e=e||t[0]).docId=r,n(e)):n(null,t.length?t[0]:t)}}function Ve(e,t){var n=Je(e._id,t._id);return 0!==n?n:Je(e._revisions?e._revisions.start:0,t._revisions?t._revisions.start:0)}function Ge(){for(var e in a.EventEmitter.call(this),Ge.prototype)"function"==typeof this[e]&&(this[e]=this[e].bind(this))}function Qe(){this.isReady=!1,this.failed=!1,this.queue=[]}function We(e,t){if(!(this instanceof We))return new We(e,t);var n=this;if(t=t||{},e&&"object"==typeof e&&(e=(t=e).name,delete t.name),void 0===t.deterministic_revs&&(t.deterministic_revs=!0),this.__opts=t=R(t),n.auto_compaction=t.auto_compaction,n.prefix=We.prefix,"string"!=typeof e)throw new Error("Missing/invalid DB name");var r=function(e,t){var n=e.match(/([a-z-]*):\/\/(.*)/);if(n)return{name:/https?/.test(n[1])?n[1]+"://"+n[2]:n[2],adapter:n[1]};var r=We.adapters,i=We.preferredAdapters,o=We.prefix,s=t.adapter;if(!s)for(var a=0;a<i.length&&("idb"===(s=i[a])&&"websql"in r&&A()&&localStorage["_pouch__websqldb_"+o+e]);++a)E("log",'PouchDB is downgrading "'+e+'" to WebSQL to avoid data loss, because it was already opened with WebSQL.');var u=r[s];return{name:!(u&&"use_prefix"in u)||u.use_prefix?o+e:e,adapter:s}}((t.prefix||"")+e,t);if(t.name=r.name,t.adapter=t.adapter||r.adapter,n.name=e,n._adapter=t.adapter,We.emit("debug",["adapter","Picked adapter: ",t.adapter]),!We.adapters[t.adapter]||!We.adapters[t.adapter].valid())throw new Error("Invalid Adapter: "+t.adapter);Ge.call(n),n.taskqueue=new Qe,n.adapter=t.adapter,We.adapters[t.adapter].call(n,t,function(e){if(e)return n.taskqueue.fail(e);!function(t){function e(e){t.removeListener("closed",n),e||t.constructor.emit("destroyed",t.name)}function n(){t.removeListener("destroyed",e),t.constructor.emit("unref",t)}t.once("destroyed",e),t.once("closed",n),t.constructor.emit("ref",t)}(n),n.emit("created",n),We.emit("created",n.name),n.taskqueue.ready(n)})}o(Fe,a.EventEmitter),Fe.prototype.cancel=function(){this.isCancelled=!0,this.db.taskqueue.isReady&&this.emit("cancel")},Fe.prototype.validateChanges=function(t){var n=t.complete,r=this;We._changesFilterPlugin?We._changesFilterPlugin.validate(t,function(e){if(e)return n(e);r.doChanges(t)}):r.doChanges(t)},Fe.prototype.doChanges=function(t){var n=this,r=t.complete;if("live"in(t=R(t))&&!("continuous"in t)&&(t.continuous=t.live),t.processChange=Ke,"latest"===t.since&&(t.since="now"),t.since||(t.since=0),"now"!==t.since){if(We._changesFilterPlugin){if(We._changesFilterPlugin.normalize(t),We._changesFilterPlugin.shouldFilter(this,t))return We._changesFilterPlugin.filter(this,t)}else["doc_ids","filter","selector","view"].forEach(function(e){e in t&&E("warn",'The "'+e+'" 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.')});"descending"in t||(t.descending=!1),t.limit=0===t.limit?1:t.limit,t.complete=r;var i=this.db._changes(t);if(i&&"function"==typeof i.cancel){var o=n.cancel;n.cancel=f(function(e){i.cancel(),o.apply(this,e)})}}else this.db.info().then(function(e){n.isCancelled?r(null,{status:"cancelled"}):(t.since=e.update_seq,n.doChanges(t))},r)},o(Ge,a.EventEmitter),Ge.prototype.post=m("post",function(e,t,n){if("function"==typeof t&&(n=t,t={}),"object"!=typeof e||Array.isArray(e))return n(Y(V));this.bulkDocs({docs:[e]},t,ze(n,e._id))}),Ge.prototype.put=m("put",function(n,t,r){if("function"==typeof t&&(r=t,t={}),"object"!=typeof n||Array.isArray(n))return r(Y(V));if(ee(n._id),Ue(n._id)&&"function"==typeof this._putLocal)return n._deleted?this._removeLocal(n,r):this._putLocal(n,r);var e,i,o,s,a=this;function u(e){"function"==typeof a._put&&!1!==t.new_edits?a._put(n,t,e):a.bulkDocs({docs:[n]},t,ze(e,n._id))}t.force&&n._rev?(e=n._rev.split("-"),i=e[1],o=parseInt(e[0],10)+1,s=Ae(),n._revisions={start:o,ids:[s,i]},n._rev=o+"-"+s,t.new_edits=!1,u(function(e){var t=e?null:{ok:!0,id:n._id,rev:n._rev};r(e,t)})):u(r)}),Ge.prototype.putAttachment=m("putAttachment",function(t,n,r,i,o){var s=this;function a(e){var t="_rev"in e?parseInt(e._rev,10):0;return e._attachments=e._attachments||{},e._attachments[n]={content_type:o,data:i,revpos:++t},s.put(e)}return"function"==typeof o&&(o=i,i=r,r=null),void 0===o&&(o=i,i=r,r=null),o||E("warn","Attachment",n,"on document",t,"is missing content_type"),s.get(t).then(function(e){if(e._rev!==r)throw Y(D);return a(e)},function(e){if(e.reason===$.message)return a({_id:t});throw e})}),Ge.prototype.removeAttachment=m("removeAttachment",function(e,n,r,i){var o=this;o.get(e,function(e,t){if(e)i(e);else if(t._rev===r){if(!t._attachments)return i();delete t._attachments[n],0===Object.keys(t._attachments).length&&delete t._attachments,o.put(t,i)}else i(Y(D))})}),Ge.prototype.remove=m("remove",function(e,t,n,r){var i;"string"==typeof t?(i={_id:e,_rev:t},"function"==typeof n&&(r=n,n={})):(i=e,n="function"==typeof t?(r=t,{}):(r=n,t)),(n=n||{}).was_delete=!0;var o={_id:i._id,_rev:i._rev||n.rev,_deleted:!0};if(Ue(o._id)&&"function"==typeof this._removeLocal)return this._removeLocal(i,r);this.bulkDocs({docs:[o]},n,ze(r,o._id))}),Ge.prototype.revsDiff=m("revsDiff",function(i,e,o){"function"==typeof e&&(o=e,e={});var s=Object.keys(i);if(!s.length)return o(null,{});var a=0,u=new x;function c(e,t){u.has(e)||u.set(e,{missing:[]}),u.get(e).missing.push(t)}s.map(function(r){this._getRevisionTree(r,function(e,t){if(e&&404===e.status&&"missing"===e.message)u.set(r,{missing:i[r]});else{if(e)return o(e);!function(a,e){var u=i[a].slice(0);Se(e,function(e,t,n,r,i){var o=t+"-"+n,s=u.indexOf(o);-1!==s&&(u.splice(s,1),"available"!==i.status&&c(a,o))}),u.forEach(function(e){c(a,e)})}(r,t)}if(++a===s.length){var n={};return u.forEach(function(e,t){n[t]=e}),o(null,n)}})},this)}),Ge.prototype.bulkGet=m("bulkGet",function(e,t){O(this,e,t)}),Ge.prototype.compactDocument=m("compactDocument",function(r,i,o){var u=this;this._getRevisionTree(r,function(e,t){if(e)return o(e);var n=function(e){var o={},s=[];return Se(e,function(e,t,n,r){var i=t+"-"+n;return e&&(o[i]=0),void 0!==r&&s.push({from:r,to:i}),i}),s.reverse(),s.forEach(function(e){void 0===o[e.from]?o[e.from]=1+o[e.to]:o[e.from]=Math.min(o[e.from],1+o[e.to])}),o}(t),s=[],a=[];Object.keys(n).forEach(function(e){n[e]>i&&s.push(e)}),Se(t,function(e,t,n,r,i){var o=t+"-"+n;"available"===i.status&&-1!==s.indexOf(o)&&a.push(o)}),u._doCompaction(r,a,o)})}),Ge.prototype.compact=m("compact",function(e,t){"function"==typeof e&&(t=e,e={});var n=this;e=e||{},n._compactionQueue=n._compactionQueue||[],n._compactionQueue.push({opts:e,callback:t}),1===n._compactionQueue.length&&function n(r){var e=r._compactionQueue[0],t=e.opts,i=e.callback;r.get("_local/compaction").catch(function(){return!1}).then(function(e){e&&e.last_seq&&(t.last_seq=e.last_seq),r._compact(t,function(e,t){e?i(e):i(null,t),T(function(){r._compactionQueue.shift(),r._compactionQueue.length&&n(r)})})})}(n)}),Ge.prototype._compact=function(e,n){var r=this,t={return_docs:!1,last_seq:e.last_seq||0},i=[];r.changes(t).on("change",function(e){i.push(r.compactDocument(e.id,0))}).on("complete",function(e){var t=e.last_seq;Promise.all(i).then(function(){return fe(r,"_local/compaction",function(e){return(!e.last_seq||e.last_seq<t)&&(e.last_seq=t,e)})}).then(function(){n(null,{ok:!0})}).catch(n)}).on("error",n)},Ge.prototype.get=m("get",function(b,w,k){if("function"==typeof w&&(k=w,w={}),"string"!=typeof b)return k(Y(I));if(Ue(b)&&"function"==typeof this._getLocal)return this._getLocal(b,k);var n=[],j=this;function r(){var s=[],a=n.length;if(!a)return k(null,s);n.forEach(function(o){j.get(b,{rev:o,revs:w.revs,latest:w.latest,attachments:w.attachments,binary:w.binary},function(e,t){if(e)s.push({missing:o});else{for(var n,r=0,i=s.length;r<i;r++)if(s[r].ok&&s[r].ok._rev===t._rev){n=!0;break}n||s.push({ok:t})}--a||k(null,s)})})}if(!w.open_revs)return this._get(b,w,function(e,t){if(e)return e.docId=b,k(e);var i=t.doc,n=t.metadata,o=t.ctx;if(w.conflicts){var r=Pe(n);r.length&&(i._conflicts=r)}if(Ne(n,i._rev)&&(i._deleted=!0),w.revs||w.revs_info){for(var s=i._rev.split("-"),a=parseInt(s[0],10),u=s[1],c=Le(n.rev_tree),f=null,l=0;l<c.length;l++){var d=c[l],h=d.ids.map(function(e){return e.id}).indexOf(u);(h===a-1||!f&&-1!==h)&&(f=d)}if(!f)return(e=new Error("invalid rev tree")).docId=b,k(e);var p=f.ids.map(function(e){return e.id}).indexOf(i._rev.split("-")[1])+1,v=f.ids.length-p;if(f.ids.splice(p,v),f.ids.reverse(),w.revs&&(i._revisions={start:f.pos+f.ids.length-1,ids:f.ids.map(function(e){return e.id})}),w.revs_info){var y=f.pos+f.ids.length;i._revs_info=f.ids.map(function(e){return{rev:--y+"-"+e.id,status:e.opts.status}})}}if(w.attachments&&i._attachments){var _=i._attachments,g=Object.keys(_).length;if(0===g)return k(null,i);Object.keys(_).forEach(function(r){this._getAttachment(i._id,r,_[r],{rev:i._rev,binary:w.binary,ctx:o},function(e,t){var n=i._attachments[r];n.data=t,delete n.stub,delete n.length,--g||k(null,i)})},j)}else{if(i._attachments)for(var m in i._attachments)i._attachments.hasOwnProperty(m)&&(i._attachments[m].stub=!0);k(null,i)}});if("all"===w.open_revs)this._getRevisionTree(b,function(e,t){if(e)return k(e);n=Ce(t).map(function(e){return e.rev}),r()});else{if(!Array.isArray(w.open_revs))return k(Y(U,"function_clause"));n=w.open_revs;for(var e=0;e<n.length;e++){var t=n[e];if("string"!=typeof t||!/^\d+-/.test(t))return k(Y(Q))}r()}}),Ge.prototype.getAttachment=m("getAttachment",function(n,r,i,o){var s=this;i instanceof Function&&(o=i,i={}),this._get(n,i,function(e,t){return e?o(e):t.doc._attachments&&t.doc._attachments[r]?(i.ctx=t.ctx,i.binary=!0,void s._getAttachment(n,r,t.doc._attachments[r],i,o)):o(Y($))})}),Ge.prototype.allDocs=m("allDocs",function(t,e){if("function"==typeof t&&(e=t,t={}),t.skip=void 0!==t.skip?t.skip:0,t.start_key&&(t.startkey=t.start_key),t.end_key&&(t.endkey=t.end_key),"keys"in t){if(!Array.isArray(t.keys))return e(new TypeError("options.keys must be an array"));var n=["startkey","endkey","key"].filter(function(e){return e in t})[0];if(n)return void e(Y(K,"Query parameter `"+n+"` is not compatible with multi-get"));if(!te(this)&&(function(e){var t="limit"in e?e.keys.slice(e.skip,e.limit+e.skip):0<e.skip?e.keys.slice(e.skip):e.keys;e.keys=t,e.skip=0,delete e.limit,e.descending&&(t.reverse(),e.descending=!1)}(t),0===t.keys.length))return this._allDocs({limit:0},e)}return this._allDocs(t,e)}),Ge.prototype.changes=function(e,t){return"function"==typeof e&&(t=e,e={}),(e=e||{}).return_docs="return_docs"in e?e.return_docs:!e.live,new Fe(this,e,t)},Ge.prototype.close=m("close",function(e){return this._closed=!0,this.emit("closed"),this._close(e)}),Ge.prototype.info=m("info",function(n){var r=this;this._info(function(e,t){if(e)return n(e);t.db_name=t.db_name||r.name,t.auto_compaction=!(!r.auto_compaction||te(r)),t.adapter=r.adapter,n(null,t)})}),Ge.prototype.id=m("id",function(e){return this._id(e)}),Ge.prototype.type=function(){return"function"==typeof this._type?this._type():this.adapter},Ge.prototype.bulkDocs=m("bulkDocs",function(e,i,o){if("function"==typeof i&&(o=i,i={}),i=i||{},Array.isArray(e)&&(e={docs:e}),!e||!e.docs||!Array.isArray(e.docs))return o(Y(L));for(var t=0;t<e.docs.length;++t)if("object"!=typeof e.docs[t]||Array.isArray(e.docs[t]))return o(Y(V));var n;if(e.docs.forEach(function(t){t._attachments&&Object.keys(t._attachments).forEach(function(e){n=n||function(e){return"_"===e.charAt(0)&&e+" is not a valid attachment name, attachment names cannot start with '_'"}(e),t._attachments[e].content_type||E("warn","Attachment",e,"on document",t._id,"is missing content_type")})}),n)return o(Y(z,n));"new_edits"in i||(i.new_edits=!("new_edits"in e)||e.new_edits);var s=this;i.new_edits||te(s)||e.docs.sort(Ve),function(e){for(var t=0;t<e.length;t++){var n=e[t];if(n._deleted)delete n._attachments;else if(n._attachments)for(var r=Object.keys(n._attachments),i=0;i<r.length;i++){var o=r[i];n._attachments[o]=w(n._attachments[o],["data","digest","content_type","length","revpos","stub"])}}}(e.docs);var a=e.docs.map(function(e){return e._id});return this._bulkDocs(e,i,function(e,t){if(e)return o(e);if(i.new_edits||(t=t.filter(function(e){return e.error})),!te(s))for(var n=0,r=t.length;n<r;n++)t[n].id=t[n].id||a[n];o(null,t)})}),Ge.prototype.registerDependentDatabase=m("registerDependentDatabase",function(t,e){var n=new this.constructor(t,this.__opts);fe(this,"_local/_pouch_dependentDbs",function(e){return e.dependentDbs=e.dependentDbs||{},!e.dependentDbs[t]&&(e.dependentDbs[t]=!0,e)}).then(function(){e(null,{db:n})}).catch(e)}),Ge.prototype.destroy=m("destroy",function(e,o){"function"==typeof e&&(o=e,e={});var s=this,a=!("use_prefix"in s)||s.use_prefix;function u(){s._destroy(e,function(e,t){if(e)return o(e);s._destroyed=!0,s.emit("destroyed"),o(null,t||{ok:!0})})}if(te(s))return u();s.get("_local/_pouch_dependentDbs",function(e,t){if(e)return 404!==e.status?o(e):u();var n=t.dependentDbs,r=s.constructor,i=Object.keys(n).map(function(e){var t=a?e.replace(new RegExp("^"+r.prefix),""):e;return new r(t,s.__opts).destroy()});Promise.all(i).then(u,o)})}),Qe.prototype.execute=function(){var e;if(this.failed)for(;e=this.queue.shift();)e(this.failed);else for(;e=this.queue.shift();)e()},Qe.prototype.fail=function(e){this.failed=e,this.execute()},Qe.prototype.ready=function(e){this.isReady=!0,this.db=e,this.execute()},Qe.prototype.addTask=function(e){this.queue.push(e),this.failed&&this.execute()},o(We,Ge);var Ye="undefined"!=typeof AbortController?AbortController:function(){return{abort:function(){}}},He=fetch,Xe=Headers;We.adapters={},We.preferredAdapters=[],We.prefix="_pouch_";var Ze=new a.EventEmitter;!function(t){Object.keys(a.EventEmitter.prototype).forEach(function(e){"function"==typeof a.EventEmitter.prototype[e]&&(t[e]=Ze[e].bind(Ze))});var r=t._destructionListeners=new x;t.on("ref",function(e){r.has(e.name)||r.set(e.name,[]),r.get(e.name).push(e)}),t.on("unref",function(e){if(r.has(e.name)){var t=r.get(e.name),n=t.indexOf(e);n<0||(t.splice(n,1),1<t.length?r.set(e.name,t):r.delete(e.name))}}),t.on("destroyed",function(e){if(r.has(e)){var t=r.get(e);r.delete(e),t.forEach(function(e){e.emit("destroyed",!0)})}})}(We),We.adapter=function(e,t,n){t.valid()&&(We.adapters[e]=t,n&&We.preferredAdapters.push(e))},We.plugin=function(t){if("function"==typeof t)t(We);else{if("object"!=typeof t||0===Object.keys(t).length)throw new Error('Invalid plugin: got "'+t+'", expected an object or a function');Object.keys(t).forEach(function(e){We.prototype[e]=t[e]})}return this.__defaults&&(We.__defaults=C({},this.__defaults)),We},We.defaults=function(e){function n(e,t){if(!(this instanceof n))return new n(e,t);t=t||{},e&&"object"==typeof e&&(e=(t=e).name,delete t.name),t=C({},n.__defaults,t),We.call(this,e,t)}return o(n,We),n.preferredAdapters=We.preferredAdapters.slice(),Object.keys(We).forEach(function(e){e in n||(n[e]=We[e])}),n.__defaults=C({},this.__defaults,e),n},We.fetch=function(e,t){return He(e,t)};function et(e,t){for(var n=e,r=0,i=t.length;r<i;r++){if(!(n=n[t[r]]))break}return n}function tt(e){for(var t=[],n="",r=0,i=e.length;r<i;r++){var o=e[r];"."===o?n=0<r&&"\\"===e[r-1]?n.substring(0,n.length-1)+".":(t.push(n),""):n+=o}return t.push(n),t}var nt=["$or","$nor","$not"];function rt(e){return-1<nt.indexOf(e)}function it(e){return Object.keys(e)[0]}function ot(e){var i={};return e.forEach(function(t){Object.keys(t).forEach(function(e){var n=t[e];if("object"!=typeof n&&(n={$eq:n}),rt(e))n instanceof Array?i[e]=n.map(function(e){return ot([e])}):i[e]=ot([n]);else{var r=i[e]=i[e]||{};Object.keys(n).forEach(function(e){var t=n[e];return"$gt"===e||"$gte"===e?function(e,t,n){if(void 0!==n.$eq)return;void 0!==n.$gte?"$gte"===e?t>n.$gte&&(n.$gte=t):t>=n.$gte&&(delete n.$gte,n.$gt=t):void 0!==n.$gt?"$gte"===e?t>n.$gt&&(delete n.$gt,n.$gte=t):t>n.$gt&&(n.$gt=t):n[e]=t}(e,t,r):"$lt"===e||"$lte"===e?function(e,t,n){if(void 0!==n.$eq)return;void 0!==n.$lte?"$lte"===e?t<n.$lte&&(n.$lte=t):t<=n.$lte&&(delete n.$lte,n.$lt=t):void 0!==n.$lt?"$lte"===e?t<n.$lt&&(delete n.$lt,n.$lte=t):t<n.$lt&&(n.$lt=t):n[e]=t}(e,t,r):"$ne"===e?function(e,t){"$ne"in t?t.$ne.push(e):t.$ne=[e]}(t,r):"$eq"===e?function(e,t){delete t.$gt,delete t.$gte,delete t.$lt,delete t.$lte,delete t.$ne,t.$eq=e}(t,r):void(r[e]=t)})}})}),i}function st(e){var t=R(e),n=!1;!function e(t,n){for(var r in t){"$and"===r&&(n=!0);var i=t[r];"object"==typeof i&&(n=e(i,n))}return n}(t,!1)||("$and"in(t=function e(t){for(var n in t){if(Array.isArray(t))for(var r in t)t[r].$and&&(t[r]=ot(t[r].$and));var i=t[n];"object"==typeof i&&e(i)}return t}(t))&&(t=ot(t.$and)),n=!0),["$or","$nor"].forEach(function(e){e in t&&t[e].forEach(function(e){for(var t=Object.keys(e),n=0;n<t.length;n++){var r=t[n],i=e[r];"object"==typeof i&&null!==i||(e[r]={$eq:i})}})}),"$not"in t&&(t.$not=ot([t.$not]));for(var r=Object.keys(t),i=0;i<r.length;i++){var o=r[i],s=t[o];"object"!=typeof s||null===s?s={$eq:s}:"$ne"in s&&!n&&(s.$ne=[s.$ne]),t[o]=s}return t}var at=-324,ut=3,ct="";function ft(e,t){if(e===t)return 0;e=lt(e),t=lt(t);var n=yt(e),r=yt(t);if(n-r!=0)return n-r;switch(typeof e){case"number":return e-t;case"boolean":return e<t?-1:1;case"string":return function(e,t){return e===t?0:t<e?1:-1}(e,t)}return Array.isArray(e)?function(e,t){for(var n=Math.min(e.length,t.length),r=0;r<n;r++){var i=ft(e[r],t[r]);if(0!==i)return i}return e.length===t.length?0:e.length>t.length?1:-1}(e,t):function(e,t){for(var n=Object.keys(e),r=Object.keys(t),i=Math.min(n.length,r.length),o=0;o<i;o++){var s=ft(n[o],r[o]);if(0!==s)return s;if(0!==(s=ft(e[n[o]],t[r[o]])))return s}return n.length===r.length?0:n.length>r.length?1:-1}(e,t)}function lt(e){switch(typeof e){case"undefined":return null;case"number":return e===1/0||e===-1/0||isNaN(e)?null:e;case"object":var t=e;if(Array.isArray(e)){var n=e.length;e=new Array(n);for(var r=0;r<n;r++)e[r]=lt(t[r])}else{if(e instanceof Date)return e.toJSON();if(null!==e)for(var i in e={},t)if(t.hasOwnProperty(i)){var o=t[i];void 0!==o&&(e[i]=lt(o))}}}return e}function dt(e){if(null!==e)switch(typeof e){case"boolean":return e?1:0;case"number":return function(e){if(0===e)return"1";var t=e.toExponential().split(/e\+?/),n=parseInt(t[1],10),r=e<0,i=r?"0":"2",o=function(e,t,n){return function(e,t,n){for(var r="",i=n-e.length;r.length<i;)r+=t;return r}(e,t,n)+e}(((r?-n:n)-at).toString(),"0",ut);i+=ct+o;var s=Math.abs(parseFloat(t[0]));r&&(s=10-s);var a=s.toFixed(20);return a=a.replace(/\.?0+$/,""),i+=ct+a}(e);case"string":return e.replace(/\u0002/g,"").replace(/\u0001/g,"").replace(/\u0000/g,"");case"object":var t=Array.isArray(e),n=t?e:Object.keys(e),r=-1,i=n.length,o="";if(t)for(;++r<i;)o+=ht(n[r]);else for(;++r<i;){var s=n[r];o+=ht(s)+ht(e[s])}return o}return""}function ht(e){return yt(e=lt(e))+ct+dt(e)+"\0"}function pt(e,t){var n,r=t;if("1"===e[t])n=0,t++;else{var i="0"===e[t];t++;var o="",s=e.substring(t,t+ut),a=parseInt(s,10)+at;for(i&&(a=-a),t+=ut;;){var u=e[t];if("\0"===u)break;o+=u,t++}n=1===(o=o.split(".")).length?parseInt(o,10):parseFloat(o[0]+"."+o[1]),i&&(n-=10),0!==a&&(n=parseFloat(n+"e"+a))}return{num:n,length:t-r}}function vt(e,t){var n=e.pop();if(t.length){var r=t[t.length-1];n===r.element&&(t.pop(),r=t[t.length-1]);var i=r.element,o=r.index;if(Array.isArray(i))i.push(n);else if(o===e.length-2){i[e.pop()]=n}else e.push(n)}}function yt(e){var t=["boolean","number","string","object"].indexOf(typeof e);return~t?null===e?1:Array.isArray(e)?5:t<3?t+2:t+3:Array.isArray(e)?5:void 0}function _t(e,t,n){if(e=e.filter(function(e){return gt(e.doc,t.selector,n)}),t.sort){var r=function(e){function r(n){return e.map(function(e){var t=tt(it(e));return et(n,t)})}return function(e,t){var n=ft(r(e.doc),r(t.doc));return 0!==n?n:function(e,t){return e<t?-1:t<e?1:0}(e.doc._id,t.doc._id)}}(t.sort);e=e.sort(r),"string"!=typeof t.sort[0]&&"desc"===function(e){return e[it(e)]}(t.sort[0])&&(e=e.reverse())}if("limit"in t||"skip"in t){var i=t.skip||0,o=("limit"in t?t.limit:e.length)+i;e=e.slice(i,o)}return e}function gt(i,o,e){return e.every(function(e){var t=o[e],n=tt(e),r=et(i,n);return rt(e)?function(e,t,n){return"$or"!==e?"$not"!==e?!t.find(function(e){return gt(n,e,Object.keys(e))}):!gt(n,t,Object.keys(t)):t.some(function(e){return gt(n,e,Object.keys(e))})}(e,t,i):mt(t,i,n,r)})}function mt(n,r,i,o){return!n||("object"==typeof n?Object.keys(n).every(function(e){var t=n[e];return function(e,t,n,r,i){if(jt[e])return jt[e](t,n,r,i);throw new Error('unknown operator "'+e+'" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, $nin, $size, $mod, $regex, $elemMatch, $type, $allMatch or $all')}(e,r,t,i,o)}):n===o)}function bt(e){return null!=e}function wt(e){return void 0!==e}function kt(t,e){return e.some(function(e){return t instanceof Array?-1<t.indexOf(e):t===e})}var jt={$elemMatch:function(t,n,r,e){return!!Array.isArray(e)&&(0!==e.length&&("object"==typeof e[0]?e.some(function(e){return gt(e,n,Object.keys(n))}):e.some(function(e){return mt(n,t,r,e)})))},$allMatch:function(t,n,r,e){return!!Array.isArray(e)&&(0!==e.length&&("object"==typeof e[0]?e.every(function(e){return gt(e,n,Object.keys(n))}):e.every(function(e){return mt(n,t,r,e)})))},$eq:function(e,t,n,r){return wt(r)&&0===ft(r,t)},$gte:function(e,t,n,r){return wt(r)&&0<=ft(r,t)},$gt:function(e,t,n,r){return wt(r)&&0<ft(r,t)},$lte:function(e,t,n,r){return wt(r)&&ft(r,t)<=0},$lt:function(e,t,n,r){return wt(r)&&ft(r,t)<0},$exists:function(e,t,n,r){return t?wt(r):!wt(r)},$mod:function(e,t,n,r){return bt(r)&&function(e,t){var n=t[0],r=t[1];if(0===n)throw new Error("Bad divisor, cannot divide by zero");if(parseInt(n,10)!==n)throw new Error("Divisor is not an integer");if(parseInt(r,10)!==r)throw new Error("Modulus is not an integer");return parseInt(e,10)===e&&e%n===r}(r,t)},$ne:function(e,t,n,r){return t.every(function(e){return 0!==ft(r,e)})},$in:function(e,t,n,r){return bt(r)&&kt(r,t)},$nin:function(e,t,n,r){return bt(r)&&!kt(r,t)},$size:function(e,t,n,r){return bt(r)&&function(e,t){return e.length===t}(r,t)},$all:function(e,t,n,r){return Array.isArray(r)&&function(t,e){return e.every(function(e){return-1<t.indexOf(e)})}(r,t)},$regex:function(e,t,n,r){return bt(r)&&function(e,t){return new RegExp(t).test(e)}(r,t)},$type:function(e,t,n,r){return function(e,t){switch(t){case"null":return null===e;case"boolean":return"boolean"==typeof e;case"number":return"number"==typeof e;case"string":return"string"==typeof e;case"array":return e instanceof Array;case"object":return"[object Object]"==={}.toString.call(e)}throw new Error(t+" not supported as a type.Please use one of object, string, array, number, boolean or null.")}(r,t)}};function Ot(e,t){if(e.selector&&e.filter&&"_selector"!==e.filter){var n="string"==typeof e.filter?e.filter:"function";return t(new Error('selector invalid for filter "'+n+'"'))}t()}function At(e){e.view&&!e.filter&&(e.filter="_view"),e.selector&&!e.filter&&(e.filter="_selector"),e.filter&&"string"==typeof e.filter&&("_view"===e.filter?e.view=re(e.view):e.filter=re(e.filter))}function qt(e,t){return t.filter&&"string"==typeof t.filter&&!t.doc_ids&&!te(e.db)}function Et(r,i){var o=i.complete;if("_view"===i.filter){if(!i.view||"string"!=typeof i.view){var e=Y(z,"`view` filter parameter not found or invalid.");return o(e)}var s=ne(i.view);r.db.get("_design/"+s[0],function(e,t){if(r.isCancelled)return o(null,{status:"cancelled"});if(e)return o(H(e));var n=t&&t.views&&t.views[s[1]]&&t.views[s[1]].map;if(!n)return o(Y($,t.views?"missing json key: "+s[1]:"missing json key: views"));i.filter=function(e){return ce(["return function(doc) {",' "use strict";'," var emitted = false;"," var emit = function (a, b) {"," emitted = true;"," };"," var view = "+e+";"," view(doc);"," if (emitted) {"," return true;"," }","};"].join("\n"),{})}(n),r.doChanges(i)})}else if(i.selector)i.filter=function(e){return function(e,t){if("object"!=typeof t)throw new Error("Selector error: expected a JSON object");var n=_t([{doc:e}],{selector:t=st(t)},Object.keys(t));return n&&1===n.length}(e,i.selector)},r.doChanges(i);else{var a=ne(i.filter);r.db.get("_design/"+a[0],function(e,t){if(r.isCancelled)return o(null,{status:"cancelled"});if(e)return o(H(e));var n=t&&t.filters&&t.filters[a[1]];if(!n)return o(Y($,t&&t.filters?"missing json key: "+a[1]:"missing json key: filters"));i.filter=function(e){return ce('"use strict";\nreturn '+e+";",{})}(n),r.doChanges(i)})}}function St(e){return e.reduce(function(e,t){return e[t]=!0,e},{})}We.plugin(function(e){e._changesFilterPlugin={validate:Ot,normalize:At,shouldFilter:qt,filter:Et}}),We.version="7.1.1";var xt=St(["_id","_rev","_attachments","_deleted","_revisions","_revs_info","_conflicts","_deleted_conflicts","_local_seq","_rev_tree","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats","_removed"]),Ct=St(["_attachments","_replication_id","_replication_state","_replication_state_time","_replication_state_reason","_replication_stats"]);function Pt(e){if(!/^\d+-./.test(e))return Y(Q);var t=e.indexOf("-"),n=e.substring(0,t),r=e.substring(t+1);return{prefix:parseInt(n,10),id:r}}function Lt(e,t,n){var r,i,o;n||(n={deterministic_revs:!0});var s={status:"available"};if(e._deleted&&(s.deleted=!0),t)if(e._id||(e._id=qe()),i=Ae(e,n.deterministic_revs),e._rev){if((o=Pt(e._rev)).error)return o;e._rev_tree=[{pos:o.prefix,ids:[o.id,{status:"missing"},[[i,s,[]]]]}],r=o.prefix+1}else e._rev_tree=[{pos:1,ids:[i,s,[]]}],r=1;else if(e._revisions&&(e._rev_tree=function(e,t){for(var n=e.start-e.ids.length+1,r=e.ids,i=[r[0],t,[]],o=1,s=r.length;o<s;o++)i=[r[o],{status:"missing"},[i]];return[{pos:n,ids:i}]}(e._revisions,s),r=e._revisions.start,i=e._revisions.ids[0]),!e._rev_tree){if((o=Pt(e._rev)).error)return o;r=o.prefix,i=o.id,e._rev_tree=[{pos:r,ids:[i,s,[]]}]}ee(e._id),e._rev=r+"-"+i;var a={metadata:{},data:{}};for(var u in e)if(Object.prototype.hasOwnProperty.call(e,u)){var c="_"===u[0];if(c&&!xt[u]){var f=Y(J,u);throw f.message=J.message+": "+u,f}c&&!Ct[u]?a.metadata[u.slice(1)]=e[u]:a.data[u]=e[u]}return a}function $t(t,e,n){var r=function(e){try{return le(e)}catch(e){return{error:Y(F,"Attachment is not a valid base64 string")}}}(t.data);if(r.error)return n(r.error);t.length=r.length,t.data="blob"===e?pe(r,t.content_type):"base64"===e?de(r):r,je(r,function(e){t.digest="md5-"+e,n()})}function Dt(e,t,n){if(e.stub)return n();"string"==typeof e.data?$t(e,t,n):function(t,n,r){je(t.data,function(e){t.digest="md5-"+e,t.length=t.data.size||t.data.length||0,"binary"===n?_e(t.data,function(e){t.data=e,r()}):"base64"===n?ge(t.data,function(e){t.data=e,r()}):r()})}(e,t,n)}function It(e,t,n,r,i,o,s,a){if(function(e,t){for(var n,r=e.slice(),i=t.split("-"),o=parseInt(i[0],10),s=i[1];n=r.pop();){if(n.pos===o&&n.ids[0]===s)return!0;for(var a=n.ids[2],u=0,c=a.length;u<c;u++)r.push({pos:n.pos+1,ids:a[u]})}return!1}(t.rev_tree,n.metadata.rev)&&!a)return r[i]=n,o();var u=t.winningRev||Ee(t),c="deleted"in t?t.deleted:Ne(t,u),f="deleted"in n.metadata?n.metadata.deleted:Ne(n.metadata),l=/^1-/.test(n.metadata.rev);if(c&&!f&&a&&l){var d=n.data;d._rev=u,d._id=n.metadata.id,n=Lt(d,a)}var h=Re(t.rev_tree,n.metadata.rev_tree[0],e);if(a&&(c&&f&&"new_leaf"!==h.conflicts||!c&&"new_leaf"!==h.conflicts||c&&!f&&"new_branch"===h.conflicts)){var p=Y(D);return r[i]=p,o()}var v=n.metadata.rev;n.metadata.rev_tree=h.tree,n.stemmedRevs=h.stemmedRevs||[],t.rev_map&&(n.metadata.rev_map=t.rev_map);var y=Ee(n.metadata),_=Ne(n.metadata,y),g=c===_?0:c<_?-1:1;s(n,y,_,v===y?_:Ne(n.metadata,v),!0,g,i,o)}function Bt(u,e,i,c,o,f,l,d,t){u=u||1e3;var h=d.new_edits,s=new x,n=0,a=e.length;function p(){++n===a&&t&&t()}e.forEach(function(e,n){if(e._id&&Ue(e._id)){var t=e._deleted?"_removeLocal":"_putLocal";i[t](e,{ctx:o},function(e,t){f[n]=e||t,p()})}else{var r=e.metadata.id;s.has(r)?(a--,s.get(r).push([e,n])):s.set(r,[[e,n]])}}),s.forEach(function(i,o){var s=0;function a(){++s<i.length?e():p()}function e(){var e=i[s],t=e[0],n=e[1];if(c.has(o))It(u,c.get(o),t,f,n,a,l,h);else{var r=Re([],t.metadata.rev_tree[0],u);t.metadata.rev_tree=r.tree,t.stemmedRevs=r.stemmedRevs||[],function(e,t,n){var r=Ee(e.metadata),i=Ne(e.metadata,r);if("was_delete"in d&&i)return f[t]=Y($,"deleted"),n();if(h&&function(e){return"missing"===e.metadata.rev_tree[0].ids[1].status}(e)){var o=Y(D);return f[t]=o,n()}l(e,r,i,i,!1,i?0:1,t,n)}(t,n,a)}}e()})}var Tt=5,Rt="document-store",Mt="by-sequence",Nt="attach-store",Ut="attach-seq-store",Ft="meta-store",Kt="local-store",Jt="detect-blob-support";function zt(n){return function(e){var t="unknown_error";e.target&&e.target.error&&(t=e.target.error.name||e.target.error.message),n(Y(G,t,e.type))}}function Vt(e,t,n){return{data:function(t){try{return JSON.stringify(t)}catch(e){return i.stringify(t)}}(e),winningRev:t,deletedOrLocal:n?"1":"0",seq:e.seq,id:e.id}}function Gt(e){if(!e)return null;var t=function(t){try{return JSON.parse(t)}catch(e){return i.parse(t)}}(e.data);return t.winningRev=e.winningRev,t.deleted="1"===e.deletedOrLocal,t.seq=e.seq,t}function Qt(e){if(!e)return e;var t=e._doc_id_rev.lastIndexOf(":");return e._id=e._doc_id_rev.substring(0,t-1),e._rev=e._doc_id_rev.substring(t+1),delete e._doc_id_rev,e}function Wt(e,t,n,r){n?r(e?"string"!=typeof e?e:ve(e,t):he([""],{type:t})):e?"string"!=typeof e?ye(e,function(e){r(de(e))}):r(e):r("")}function Yt(t,n,i,e){var r=Object.keys(t._attachments||{});if(!r.length)return e&&e();var o=0;function s(){++o===r.length&&e&&e()}r.forEach(function(e){n.attachments&&n.include_docs?function(e,t){var n=e._attachments[t],r=n.digest;i.objectStore(Nt).get(r).onsuccess=function(e){n.body=e.target.result.body,s()}}(t,e):(t._attachments[e].stub=!0,s())})}function Ht(e,s){return Promise.all(e.map(function(o){if(o.doc&&o.doc._attachments){var e=Object.keys(o.doc._attachments);return Promise.all(e.map(function(n){var r=o.doc._attachments[n];if("body"in r){var e=r.body,i=r.content_type;return new Promise(function(t){Wt(e,i,s,function(e){o.doc._attachments[n]=C(w(r,["digest","content_type"]),{data:e}),t()})})}}))}}))}function Xt(e,r,t){var i=[],o=t.objectStore(Mt),n=t.objectStore(Nt),s=t.objectStore(Ut),a=e.length;function u(){--a||function(){if(!i.length)return;i.forEach(function(t){s.index("digestSeq").count(IDBKeyRange.bound(t+"::",t+"::￿",!1,!1)).onsuccess=function(e){e.target.result||n.delete(t)}})}()}e.forEach(function(e){var t=o.index("_doc_id_rev"),n=r+"::"+e;t.getKey(n).onsuccess=function(e){var t=e.target.result;if("number"!=typeof t)return u();o.delete(t),s.index("seq").openCursor(IDBKeyRange.only(t)).onsuccess=function(e){var t=e.target.result;if(t){var n=t.value.digestSeq.split("::")[0];i.push(n),s.delete(t.primaryKey),t.continue()}else u()}}})}function Zt(e,t,n){try{return{txn:e.transaction(t,n)}}catch(e){return{error:e}}}var en=new q;function tn(s,e,a,l,t,n){for(var d,h,p,v,y,r,i,o,u=e.docs,c=0,f=u.length;c<f;c++){var _=u[c];_._id&&Ue(_._id)||(_=u[c]=Lt(_,a.new_edits,s)).error&&!i&&(i=_)}if(i)return n(i);var g=!1,m=0,b=new Array(u.length),w=new x,k=!1,j=l._meta.blobSupport?"blob":"base64";function O(){g=!0,A()}function A(){o&&g&&(o.docCount+=m,r.put(o))}function q(){k||(en.notify(l._meta.name),n(null,b))}function E(e,t,n,r,i,o,s,a){e.metadata.winningRev=t,e.metadata.deleted=n;var u=e.data;if(u._id=e.metadata.id,u._rev=e.metadata.rev,r&&(u._deleted=!0),u._attachments&&Object.keys(u._attachments).length)return function(r,i,e,t,n,o){var s=r.data,a=0,u=Object.keys(s._attachments);function c(){a===u.length&&S(r,i,e,t,n,o)}function f(){a++,c()}u.forEach(function(e){var t=r.data._attachments[e];if(t.stub)a++,c();else{var n=t.data;delete t.data,t.revpos=parseInt(i,10),function(n,r,i){v.count(n).onsuccess=function(e){if(e.target.result)return i();var t={digest:n,body:r};v.put(t).onsuccess=i}}(t.digest,n,f)}})}(e,t,n,i,s,a);m+=o,A(),S(e,t,n,i,s,a)}function S(r,i,o,s,e,t){var n=r.data,a=r.metadata;function u(e){var t=r.stemmedRevs||[];s&&l.auto_compaction&&(t=t.concat(function(e){var o=[];return Se(e.rev_tree,function(e,t,n,r,i){"available"!==i.status||e||(o.push(t+"-"+n),i.status="missing")}),o}(r.metadata))),t&&t.length&&Xt(t,r.metadata.id,d),a.seq=e.target.result;var n=Vt(a,i,o);h.put(n).onsuccess=c}function c(){b[e]={ok:!0,id:a.id,rev:a.rev},w.set(r.metadata.id,r.metadata),function(e,t,n){var r=0,i=Object.keys(e.data._attachments||{});if(!i.length)return n();function o(){++r===i.length&&n()}for(var s=0;s<i.length;s++)a=i[s],c=void 0,u=e.data._attachments[a].digest,(c=y.put({seq:t,digestSeq:u+"::"+t})).onsuccess=o,c.onerror=function(e){e.preventDefault(),e.stopPropagation(),o()};var a,u,c}(r,a.seq,t)}n._doc_id_rev=a.id+"::"+a.rev,delete n._id,delete n._rev;var f=p.put(n);f.onsuccess=u,f.onerror=function(e){e.preventDefault(),e.stopPropagation(),p.index("_doc_id_rev").getKey(n._doc_id_rev).onsuccess=function(e){p.put(n,e.target.result).onsuccess=u}}}!function(e,o,t){if(!e.length)return t();var s,n=0;function a(){n++,e.length===n&&(s?t(s):t())}e.forEach(function(e){var t=e.data&&e.data._attachments?Object.keys(e.data._attachments):[],n=0;if(!t.length)return a();function r(e){s=e,++n===t.length&&a()}for(var i in e.data._attachments)e.data._attachments.hasOwnProperty(i)&&Dt(e.data._attachments[i],o,r)})}(u,j,function(e){if(e)return n(e);!function(){var e=Zt(t,[Rt,Mt,Nt,Kt,Ut,Ft],"readwrite");if(e.error)return n(e.error);(d=e.txn).onabort=zt(n),d.ontimeout=zt(n),d.oncomplete=q,h=d.objectStore(Rt),p=d.objectStore(Mt),v=d.objectStore(Nt),y=d.objectStore(Ut),(r=d.objectStore(Ft)).get(Ft).onsuccess=function(e){o=e.target.result,A()},function(t){var r=[];if(u.forEach(function(n){n.data&&n.data._attachments&&Object.keys(n.data._attachments).forEach(function(e){var t=n.data._attachments[e];t.stub&&r.push(t.digest)})}),!r.length)return t();var n,i=0;r.forEach(function(e){!function(n,r){v.get(n).onsuccess=function(e){if(e.target.result)r();else{var t=Y(W,"unknown stub attachment with digest "+n);t.status=412,r(t)}}}(e,function(e){e&&!n&&(n=e),++i===r.length&&t(n)})})}(function(e){if(e)return k=!0,n(e);!function(){if(!u.length)return;var e=0;function n(){++e===u.length&&Bt(s.revs_limit,u,l,w,d,b,E,a,O)}function t(e){var t=Gt(e.target.result);t&&w.set(t.id,t),n()}for(var r=0,i=u.length;r<i;r++){var o=u[r];if(o._id&&Ue(o._id))n();else h.get(o.metadata.id).onsuccess=t}}()})}()})}function nn(n,r,e,i,o){var s,a,t;function u(e){a=e.target.result,s&&o(s,a,t)}function c(e){s=e.target.result,a&&o(s,a,t)}function f(e){var t=e.target.result;if(!t)return o();o([t.key],[t.value],t)}-1===i&&(i=1e3),"function"==typeof n.getAll&&"function"==typeof n.getAllKeys&&1<i&&!e?(t={continue:function(){if(!s.length)return o();var e,t=s[s.length-1];if(r&&r.upper)try{e=IDBKeyRange.bound(t,r.upper,!0,r.upperOpen)}catch(e){if("DataError"===e.name&&0===e.code)return o()}else e=IDBKeyRange.lowerBound(t,!0);r=e,a=s=null,n.getAll(r,i).onsuccess=u,n.getAllKeys(r,i).onsuccess=c}},n.getAll(r,i).onsuccess=u,n.getAllKeys(r,i).onsuccess=c):e?n.openCursor(r,"prev").onsuccess=f:n.openCursor(r).onsuccess=f}function rn(i,e,t){var n,r,o="startkey"in i&&i.startkey,s="endkey"in i&&i.endkey,a="key"in i&&i.key,u="keys"in i&&i.keys,c=i.skip||0,f="number"==typeof i.limit?i.limit:-1,l=!1!==i.inclusive_end;if(!u&&(r=(n=function(e,t,n,r,i){try{if(e&&t)return i?IDBKeyRange.bound(t,e,!n,!1):IDBKeyRange.bound(e,t,!1,!n);if(e)return i?IDBKeyRange.upperBound(e):IDBKeyRange.lowerBound(e);if(t)return i?IDBKeyRange.lowerBound(t,!n):IDBKeyRange.upperBound(t,!n);if(r)return IDBKeyRange.only(r)}catch(e){return{error:e}}return null}(o,s,l,a,i.descending))&&n.error)&&("DataError"!==r.name||0!==r.code))return t(Y(G,r.name,r.message));var d=[Rt,Mt,Ft];i.attachments&&d.push(Nt);var h=Zt(e,d,"readonly");if(h.error)return t(h.error);var p=h.txn;p.oncomplete=function(){i.attachments?Ht(k,i.binary).then(q):q()},p.onabort=zt(t);var v,y,_,g=p.objectStore(Rt),m=p.objectStore(Mt),b=p.objectStore(Ft),w=m.index("_doc_id_rev"),k=[];function j(e,t){var n={id:t.id,key:t.id,value:{rev:e}};t.deleted?u&&(k.push(n),n.value.deleted=!0,n.doc=null):c--<=0&&(k.push(n),i.include_docs&&function(n,r,e){var t=n.id+"::"+e;w.get(t).onsuccess=function(e){if(r.doc=Qt(e.target.result)||{},i.conflicts){var t=Pe(n);t.length&&(r.doc._conflicts=t)}Yt(r.doc,i,p)}}(t,n,e))}function O(e){for(var t=0,n=e.length;t<n&&k.length!==f;t++){var r=e[t];if(r.error&&u)k.push(r);else{var i=Gt(r);j(i.winningRev,i)}}}function A(e,t,n){n&&(O(t),k.length<f&&n.continue())}function q(){var e={total_rows:v,offset:i.skip,rows:k};i.update_seq&&void 0!==y&&(e.update_seq=y),t(null,e)}return b.get(Ft).onsuccess=function(e){v=e.target.result.docCount},i.update_seq&&(_=function(e){e.target.result&&0<e.target.result.length&&(y=e.target.result[0])},m.openCursor(null,"prev").onsuccess=function(e){var t=e.target.result,n=void 0;return t&&t.key&&(n=t.key),_({target:{result:[n]}})}),r||0===f?void 0:u?function(r,e,i){var o=new Array(r.length),s=0;r.forEach(function(t,n){e.get(t).onsuccess=function(e){e.target.result?o[n]=e.target.result:o[n]={key:t,error:"not_found"},++s===r.length&&i(r,o,{})}})}(i.keys,g,A):-1===f?function(e,t,n){if("function"!=typeof e.getAll){var r=[];e.openCursor(t).onsuccess=function(e){var t=e.target.result;t?(r.push(t.value),t.continue()):n({target:{result:r}})}}else e.getAll(t).onsuccess=n}(g,n,function(e){var t=e.target.result;i.descending&&(t=t.reverse()),O(t)}):void nn(g,n,i.descending,f+c,A)}var on=!1,sn=[];function an(){!on&&sn.length&&(on=!0,sn.shift()())}function un(c,e,t,n){if((c=R(c)).continuous){var r=t+":"+qe();return en.addListener(t,r,e,c),en.notify(t),{cancel:function(){en.removeListener(t,r)}}}var f=c.doc_ids&&new b(c.doc_ids);c.since=c.since||0;var l=c.since,d="limit"in c?c.limit:-1;0===d&&(d=1);var h,i,p,o,v=[],y=0,_=X(c),g=new x;function m(e,t,n,r){if(n.seq!==t)return r();if(n.winningRev===e._rev)return r(n,e);var i=e._id+"::"+n.winningRev;o.get(i).onsuccess=function(e){r(n,Qt(e.target.result))}}function s(){c.complete(null,{results:v,last_seq:l})}var a=[Rt,Mt];c.attachments&&a.push(Nt);var u=Zt(n,a,"readonly");if(u.error)return c.complete(u.error);(h=u.txn).onabort=zt(c.complete),h.oncomplete=function(){!c.continuous&&c.attachments?Ht(v).then(s):s()},i=h.objectStore(Mt),p=h.objectStore(Rt),o=i.index("_doc_id_rev"),nn(i,c.since&&!c.descending?IDBKeyRange.lowerBound(c.since,!0):null,c.descending,d,function(r,e,o){if(o&&r.length){var s=new Array(r.length),a=new Array(r.length),i=0;e.forEach(function(e,n){!function(t,n,r){if(f&&!f.has(t._id))return r();var i=g.get(t._id);if(i)return m(t,n,i,r);p.get(t._id).onsuccess=function(e){i=Gt(e.target.result),g.set(t._id,i),m(t,n,i,r)}}(Qt(e),r[n],function(e,t){a[n]=e,s[n]=t,++i===r.length&&function(){for(var e=[],t=0,n=s.length;t<n&&y!==d;t++){var r=s[t];if(r){var i=a[t];e.push(u(i,r))}}Promise.all(e).then(function(e){for(var t=0,n=e.length;t<n;t++)e[t]&&c.onChange(e[t])}).catch(c.complete),y!==d&&o.continue()}()})})}function u(e,t){var n=c.processChange(t,e,c);l=n.seq=e.seq;var r=_(n);return"object"==typeof r?Promise.reject(r):r?(y++,c.return_docs&&v.push(n),c.attachments&&c.include_docs?new Promise(function(e){Yt(t,c,h,function(){Ht([n],c.binary).then(function(){e(n)})})}):Promise.resolve(n)):Promise.resolve()}})}var cn,fn=new x,ln=new x;function dn(t,e){var n=this;!function(e,n,r){sn.push(function(){e(function(e,t){!function(e,t,n,r){try{e(t,n)}catch(t){r.emit("error",t)}}(n,e,t,r),on=!1,T(function(){an()})})}),an()}(function(e){!function(c,r,f){var l=r.name,d=null;function o(e,i){var o=e.objectStore(Rt);o.createIndex("deletedOrLocal","deletedOrLocal",{unique:!1}),o.openCursor().onsuccess=function(e){var t=e.target.result;if(t){var n=t.value,r=Ne(n);n.deletedOrLocal=r?"1":"0",o.put(n),t.continue()}else i()}}function s(e,d){var h=e.objectStore(Kt),p=e.objectStore(Rt),v=e.objectStore(Mt);p.openCursor().onsuccess=function(e){var n=e.target.result;if(n){var t=n.value,r=t.id,i=Ue(r),o=Ee(t);if(i){var s=r+"::"+o,a=r+"::",u=r+"::~",c=v.index("_doc_id_rev"),f=IDBKeyRange.bound(a,u,!1,!1),l=c.openCursor(f);l.onsuccess=function(e){if(l=e.target.result){var t=l.value;t._doc_id_rev===s&&h.put(t),v.delete(l.primaryKey),l.continue()}else p.delete(n.primaryKey),n.continue()}}else n.continue()}else d&&d()}}function a(e,c){var t=e.objectStore(Mt),n=e.objectStore(Nt),f=e.objectStore(Ut);n.count().onsuccess=function(e){if(!e.target.result)return c();t.openCursor().onsuccess=function(e){var t=e.target.result;if(!t)return c();for(var n=t.value,r=t.primaryKey,i=Object.keys(n._attachments||{}),o={},s=0;s<i.length;s++){o[n._attachments[i[s]].digest]=!0}var a=Object.keys(o);for(s=0;s<a.length;s++){var u=a[s];f.put({seq:r,digestSeq:u+"::"+r})}t.continue()}}}function u(e){var u=e.objectStore(Mt),c=e.objectStore(Rt);c.openCursor().onsuccess=function(e){var t=e.target.result;if(t){var n,r,i,o,s=function(e){return e.data?Gt(e):(e.deleted="1"===e.deletedOrLocal,e)}(t.value);if(s.winningRev=s.winningRev||Ee(s),s.seq)return a();n=s.id+"::",r=s.id+"::￿",i=u.index("_doc_id_rev").openCursor(IDBKeyRange.bound(n,r)),o=0,i.onsuccess=function(e){var t=e.target.result;if(!t)return s.seq=o,a();var n=t.primaryKey;o<n&&(o=n),t.continue()}}function a(){var e=Vt(s,s.winningRev,s.deleted);c.put(e).onsuccess=function(){t.continue()}}}}c._meta=null,c._remote=!1,c.type=function(){return"idb"},c._id=y(function(e){e(null,c._meta.instanceId)}),c._bulkDocs=function(e,t,n){tn(r,e,t,c,d,n)},c._get=function(e,i,t){var o,s,a,u=i.ctx;if(!u){var n=Zt(d,[Rt,Mt,Nt],"readonly");if(n.error)return t(n.error);u=n.txn}function c(){t(a,{doc:o,metadata:s,ctx:u})}u.objectStore(Rt).get(e).onsuccess=function(e){if(!(s=Gt(e.target.result)))return a=Y($,"missing"),c();var t;if(i.rev)t=i.latest?function(e,t){for(var n,r=t.rev_tree.slice();n=r.pop();){var i=n.pos,o=n.ids,s=o[0],a=o[1],u=o[2],c=0===u.length,f=n.history?n.history.slice():[];if(f.push({id:s,pos:i,opts:a}),c)for(var l=0,d=f.length;l<d;l++){var h=f[l];if(h.pos+"-"+h.id===e)return i+"-"+s}for(var p=0,v=u.length;p<v;p++)r.push({pos:i+1,ids:u[p],history:f})}throw new Error("Unable to resolve latest revision for id "+t.id+", rev "+e)}(i.rev,s):i.rev;else if(t=s.winningRev,Ne(s))return a=Y($,"deleted"),c();var n=u.objectStore(Mt),r=s.id+"::"+t;n.index("_doc_id_rev").get(r).onsuccess=function(e){if((o=e.target.result)&&(o=Qt(o)),!o)return a=Y($,"missing"),c();c()}}},c._getAttachment=function(e,t,n,r,i){var o;if(r.ctx)o=r.ctx;else{var s=Zt(d,[Rt,Mt,Nt],"readonly");if(s.error)return i(s.error);o=s.txn}var a=n.digest,u=n.content_type;o.objectStore(Nt).get(a).onsuccess=function(e){Wt(e.target.result.body,u,r.binary,function(e){i(null,e)})}},c._info=function(e){var n,t,r=Zt(d,[Ft,Mt],"readonly");if(r.error)return e(r.error);var i=r.txn;i.objectStore(Ft).get(Ft).onsuccess=function(e){t=e.target.result.docCount},i.objectStore(Mt).openCursor(null,"prev").onsuccess=function(e){var t=e.target.result;n=t?t.key:0},i.oncomplete=function(){e(null,{doc_count:t,update_seq:n,idb_attachment_format:c._meta.blobSupport?"binary":"base64"})}},c._allDocs=function(e,t){rn(e,d,t)},c._changes=function(e){return un(e,c,l,d)},c._close=function(e){d.close(),fn.delete(l),e()},c._getRevisionTree=function(e,n){var t=Zt(d,[Rt],"readonly");if(t.error)return n(t.error);t.txn.objectStore(Rt).get(e).onsuccess=function(e){var t=Gt(e.target.result);t?n(null,t.rev_tree):n(Y($))}},c._doCompaction=function(i,s,e){var t=Zt(d,[Rt,Mt,Nt,Ut],"readwrite");if(t.error)return e(t.error);var o=t.txn;o.objectStore(Rt).get(i).onsuccess=function(e){var t=Gt(e.target.result);Se(t.rev_tree,function(e,t,n,r,i){var o=t+"-"+n;-1!==s.indexOf(o)&&(i.status="missing")}),Xt(s,i,o);var n=t.winningRev,r=t.deleted;o.objectStore(Rt).put(Vt(t,n,r))},o.onabort=zt(e),o.oncomplete=function(){e()}},c._getLocal=function(e,n){var t=Zt(d,[Kt],"readonly");if(t.error)return n(t.error);var r=t.txn.objectStore(Kt).get(e);r.onerror=zt(n),r.onsuccess=function(e){var t=e.target.result;t?(delete t._doc_id_rev,n(null,t)):n(Y($))}},c._putLocal=function(n,r,i){"function"==typeof r&&(i=r,r={}),delete n._revisions;var o=n._rev,e=n._id;n._rev=o?"0-"+(parseInt(o.split("-")[1],10)+1):"0-1";var s,t=r.ctx;if(!t){var a=Zt(d,[Kt],"readwrite");if(a.error)return i(a.error);(t=a.txn).onerror=zt(i),t.oncomplete=function(){s&&i(null,s)}}var u,c=t.objectStore(Kt);o?(u=c.get(e)).onsuccess=function(e){var t=e.target.result;t&&t._rev===o?c.put(n).onsuccess=function(){s={ok:!0,id:n._id,rev:n._rev},r.ctx&&i(null,s)}:i(Y(D))}:((u=c.add(n)).onerror=function(e){i(Y(D)),e.preventDefault(),e.stopPropagation()},u.onsuccess=function(){s={ok:!0,id:n._id,rev:n._rev},r.ctx&&i(null,s)})},c._removeLocal=function(n,r,i){"function"==typeof r&&(i=r,r={});var o,e=r.ctx;if(!e){var t=Zt(d,[Kt],"readwrite");if(t.error)return i(t.error);(e=t.txn).oncomplete=function(){o&&i(null,o)}}var s=n._id,a=e.objectStore(Kt),u=a.get(s);u.onerror=zt(i),u.onsuccess=function(e){var t=e.target.result;t&&t._rev===n._rev?(a.delete(s),o={ok:!0,id:s,rev:"0-0"},r.ctx&&i(null,o)):i(Y($))}},c._destroy=function(e,t){en.removeAllListeners(l);var n=ln.get(l);n&&n.result&&(n.result.close(),fn.delete(l));var r=indexedDB.deleteDatabase(l);r.onsuccess=function(){ln.delete(l),A()&&l in localStorage&&delete localStorage[l],t(null,{ok:!0})},r.onerror=zt(t)};var e=fn.get(l);if(e)return d=e.idb,c._meta=e.global,T(function(){f(null,c)});var t=indexedDB.open(l,Tt);ln.set(l,t),t.onupgradeneeded=function(e){var t=e.target.result;if(e.oldVersion<1)return function(e){var t=e.createObjectStore(Rt,{keyPath:"id"});e.createObjectStore(Mt,{autoIncrement:!0}).createIndex("_doc_id_rev","_doc_id_rev",{unique:!0}),e.createObjectStore(Nt,{keyPath:"digest"}),e.createObjectStore(Ft,{keyPath:"id",autoIncrement:!1}),e.createObjectStore(Jt),t.createIndex("deletedOrLocal","deletedOrLocal",{unique:!1}),e.createObjectStore(Kt,{keyPath:"_id"});var n=e.createObjectStore(Ut,{autoIncrement:!0});n.createIndex("seq","seq"),n.createIndex("digestSeq","digestSeq",{unique:!0})}(t);var n=e.currentTarget.transaction;e.oldVersion<3&&function(e){e.createObjectStore(Kt,{keyPath:"_id"}).createIndex("_doc_id_rev","_doc_id_rev",{unique:!0})}(t),e.oldVersion<4&&function(e){var t=e.createObjectStore(Ut,{autoIncrement:!0});t.createIndex("seq","seq"),t.createIndex("digestSeq","digestSeq",{unique:!0})}(t);var r=[o,s,a,u],i=e.oldVersion;!function e(){var t=r[i-1];i++,t&&t(n,e)}()},t.onsuccess=function(e){(d=e.target.result).onversionchange=function(){d.close(),fn.delete(l)},d.onabort=function(e){E("error","Database has a global failure",e.target.error),d.close(),fn.delete(l)};var t,n,r,i,o=d.transaction([Ft,Jt,Rt],"readwrite"),s=!1;function a(){void 0!==r&&s&&(c._meta={name:l,instanceId:i,blobSupport:r},fn.set(l,{idb:d,global:c._meta}),f(null,c))}function u(){if(void 0!==n&&void 0!==t){var e=l+"_id";e in t?i=t[e]:t[e]=i=qe(),t.docCount=n,o.objectStore(Ft).put(t)}}o.objectStore(Ft).get(Ft).onsuccess=function(e){t=e.target.result||{id:Ft},u()},function(e,t){e.objectStore(Rt).index("deletedOrLocal").count(IDBKeyRange.only("0")).onsuccess=function(e){t(e.target.result)}}(o,function(e){n=e,u()}),cn||(cn=function(r){return new Promise(function(n){var e=he([""]),t=r.objectStore(Jt).put(e,"key");t.onsuccess=function(){var e=navigator.userAgent.match(/Chrome\/(\d+)/),t=navigator.userAgent.match(/Edge\//);n(t||!e||43<=parseInt(e[1],10))},t.onerror=r.onabort=function(e){e.preventDefault(),e.stopPropagation(),n(!1)}}).catch(function(){return!1})}(o)),cn.then(function(e){r=e,a()}),o.oncomplete=function(){s=!0,a()},o.onabort=zt(f)},t.onerror=function(){var e="Failed to open indexedDB, are you in private browsing mode?";E("error",e),f(Y(G,e))}}(n,t,e)},e,n.constructor)}dn.valid=function(){try{return"undefined"!=typeof indexedDB&&"undefined"!=typeof IDBKeyRange}catch(e){return!1}};var hn=25,pn=50,vn=5e3,yn=1e4,_n={};function gn(e){var t=e.doc||e.ok,n=t&&t._attachments;n&&Object.keys(n).forEach(function(e){var t=n[e];t.data=ve(t.data,t.content_type)})}function mn(e){return/^_design/.test(e)?"_design/"+encodeURIComponent(e.slice(8)):/^_local/.test(e)?"_local/"+encodeURIComponent(e.slice(7)):encodeURIComponent(e)}function bn(n){return n._attachments&&Object.keys(n._attachments)?Promise.all(Object.keys(n._attachments).map(function(e){var t=n._attachments[e];if(t.data&&"string"!=typeof t.data)return new Promise(function(e){ge(t.data,e)}).then(function(e){t.data=e})})):Promise.resolve()}function wn(e,t){if(function(e){if(!e.prefix)return!1;var t=ue(e.prefix).protocol;return"http"===t||"https"===t}(t)){var n=t.name.substr(t.prefix.length);e=t.prefix.replace(/\/?$/,"/")+encodeURIComponent(n)}var r=ue(e);(r.user||r.password)&&(r.auth={username:r.user,password:r.password});var i=r.path.replace(/(^\/|\/$)/g,"").split("/");return r.db=i.pop(),-1===r.db.indexOf("%")&&(r.db=encodeURIComponent(r.db)),r.path=i.join("/"),r}function kn(e,t){return jn(e,e.db+"/"+t)}function jn(e,t){var n=e.path?"/":"";return e.protocol+"://"+e.host+(e.port?":"+e.port:"")+"/"+e.path+n+t}function On(t){return"?"+Object.keys(t).map(function(e){return e+"="+encodeURIComponent(t[e])}).join("&")}function An(s,e){var t=this,y=wn(s.name,s),n=kn(y,"");s=R(s);var r,a=function(e,t){if((t=t||{}).headers=t.headers||new Xe,t.credentials="include",s.auth||y.auth){var n=s.auth||y.auth,r=n.username+":"+n.password,i=de(unescape(encodeURIComponent(r)));t.headers.set("Authorization","Basic "+i)}var o=s.headers||{};return Object.keys(o).forEach(function(e){t.headers.append(e,o[e])}),function(e){var t="undefined"!=typeof navigator&&navigator.userAgent?navigator.userAgent.toLowerCase():"",n=-1!==t.indexOf("msie"),r=-1!==t.indexOf("trident"),i=-1!==t.indexOf("edge"),o=!("method"in e)||"GET"===e.method;return(n||r||i)&&o}(t)&&(e+=(-1===e.indexOf("?")?"?":"&")+"_nonce="+Date.now()),(s.fetch||He)(e,t)};function i(e,n){return m(e,f(function(t){g().then(function(){return n.apply(this,t)}).catch(function(e){t.pop()(e)})})).bind(t)}function _(e,t,n){var r={};return(t=t||{}).headers=t.headers||new Xe,t.headers.get("Content-Type")||t.headers.set("Content-Type","application/json"),t.headers.get("Accept")||t.headers.set("Accept","application/json"),a(e,t).then(function(e){return r.ok=e.ok,r.status=e.status,e.json()}).then(function(e){if(r.data=e,!r.ok){r.data.status=r.status;var t=H(r.data);if(n)return n(t);throw t}if(Array.isArray(r.data)&&(r.data=r.data.map(function(e){return e.error||e.missing?H(e):e})),!n)return r;n(null,r.data)})}function g(){return s.skip_setup?Promise.resolve():r||((r=_(n).catch(function(e){return e&&e.status&&404===e.status?(S(404,"PouchDB is just detecting if the remote exists."),_(n,{method:"PUT"})):Promise.reject(e)}).catch(function(e){return!(!e||!e.status||412!==e.status)||Promise.reject(e)})).catch(function(){r=null}),r)}function c(e){return e.split("/").map(encodeURIComponent).join("/")}T(function(){e(null,t)}),t._remote=!0,t.type=function(){return"http"},t.id=i("id",function(n){a(jn(y,"")).then(function(e){return e.json()}).catch(function(){return{}}).then(function(e){var t=e&&e.uuid?e.uuid+y.db:kn(y,"");n(null,t)})}),t.compact=i("compact",function(r,i){"function"==typeof r&&(i=r,r={}),r=R(r),_(kn(y,"_compact"),{method:"POST"}).then(function(){!function n(){t.info(function(e,t){t&&!t.compact_running?i(null,{ok:!0}):setTimeout(n,r.interval||200)})}()})}),t.bulkGet=m("bulkGet",function(a,u){var c=this;function e(t){var e={};a.revs&&(e.revs=!0),a.attachments&&(e.attachments=!0),a.latest&&(e.latest=!0),_(kn(y,"_bulk_get"+On(e)),{method:"POST",body:JSON.stringify({docs:a.docs})}).then(function(e){a.attachments&&a.binary&&e.data.results.forEach(function(e){e.docs.forEach(gn)}),t(null,e.data)}).catch(t)}function n(){var e=pn,r=Math.ceil(a.docs.length/e),i=0,o=new Array(r);function t(n){return function(e,t){o[n]=t.results,++i===r&&u(null,{results:Z(o)})}}for(var n=0;n<r;n++){var s=w(a,["revs","attachments","binary","latest"]);s.docs=a.docs.slice(n*e,Math.min(a.docs.length,(n+1)*e)),O(c,s,t(n))}}var r=jn(y,""),t=_n[r];"boolean"!=typeof t?e(function(e,t){e?(_n[r]=!1,S(e.status,"PouchDB is just detecting if the remote supports the _bulk_get API."),n()):(_n[r]=!0,u(null,t))}):t?e(u):n()}),t._info=function(t){g().then(function(){return a(kn(y,""))}).then(function(e){return e.json()}).then(function(e){e.host=kn(y,""),t(null,e)}).catch(t)},t.fetch=function(t,n){return g().then(function(){var e="/"===t.substring(0,1)?jn(y,t.substring(1)):kn(y,t);return a(e,n)})},t.get=i("get",function(t,o,n){"function"==typeof o&&(n=o,o={});var e={};function r(r){var i=r._attachments,e=i&&Object.keys(i);if(i&&e.length)return function(l,d){return new Promise(function(e,t){var n,r=0,i=0,o=0,s=l.length;function a(){++o===s?n?t(n):e():f()}function u(){r--,a()}function c(e){r--,n=n||e,a()}function f(){for(;r<d&&i<s;)r++,l[i++]().then(u,c)}f()})}(e.map(function(e){return function(){return function(e){var n=i[e],t=mn(r._id)+"/"+c(e)+"?rev="+r._rev;return a(kn(y,t)).then(function(e){return void 0===u||u.browser?e.blob():e.buffer()}).then(function(t){return o.binary?(void 0===u||u.browser||(t.type=n.content_type),t):new Promise(function(e){ge(t,e)})}).then(function(e){delete n.stub,delete n.length,n.data=e})}(e)}}),5)}(o=R(o)).revs&&(e.revs=!0),o.revs_info&&(e.revs_info=!0),o.latest&&(e.latest=!0),o.open_revs&&("all"!==o.open_revs&&(o.open_revs=JSON.stringify(o.open_revs)),e.open_revs=o.open_revs),o.rev&&(e.rev=o.rev),o.conflicts&&(e.conflicts=o.conflicts),o.update_seq&&(e.update_seq=o.update_seq),t=mn(t),_(kn(y,t+On(e))).then(function(e){return Promise.resolve().then(function(){if(o.attachments)return function(e){return Array.isArray(e)?Promise.all(e.map(function(e){if(e.ok)return r(e.ok)})):r(e)}(e.data)}).then(function(){n(null,e.data)})}).catch(function(e){e.docId=t,n(e)})}),t.remove=i("remove",function(e,t,n,r){var i;"string"==typeof t?(i={_id:e,_rev:t},"function"==typeof n&&(r=n,n={})):(i=e,n="function"==typeof t?(r=t,{}):(r=n,t));var o=i._rev||n.rev;_(kn(y,mn(i._id))+"?rev="+o,{method:"DELETE"},r).catch(r)}),t.getAttachment=i("getAttachment",function(e,t,n,r){"function"==typeof n&&(r=n,n={});var i,o=n.rev?"?rev="+n.rev:"",s=kn(y,mn(e))+"/"+c(t)+o;a(s,{method:"GET"}).then(function(e){if(i=e.headers.get("content-type"),e.ok)return void 0===u||u.browser?e.blob():e.buffer();throw e}).then(function(e){void 0===u||u.browser||(e.type=i),r(null,e)}).catch(function(e){r(e)})}),t.removeAttachment=i("removeAttachment",function(e,t,n,r){_(kn(y,mn(e)+"/"+c(t))+"?rev="+n,{method:"DELETE"},r).catch(r)}),t.putAttachment=i("putAttachment",function(e,t,n,r,i,o){"function"==typeof i&&(o=i,i=r,r=n,n=null);var s=mn(e)+"/"+c(t),a=kn(y,s);if(n&&(a+="?rev="+n),"string"==typeof r){var u;try{u=le(r)}catch(e){return o(Y(F,"Attachment is not a valid base64 string"))}r=u?pe(u,i):""}_(a,{headers:new Xe({"Content-Type":i}),method:"PUT",body:r},o).catch(o)}),t._bulkDocs=function(e,t,n){e.new_edits=t.new_edits,g().then(function(){return Promise.all(e.docs.map(bn))}).then(function(){return _(kn(y,"_bulk_docs"),{method:"POST",body:JSON.stringify(e)},n)}).catch(n)},t._put=function(t,e,n){g().then(function(){return bn(t)}).then(function(){return _(kn(y,mn(t._id)),{method:"PUT",body:JSON.stringify(t)})}).then(function(e){n(null,e.data)}).catch(function(e){e.docId=t&&t._id,n(e)})},t.allDocs=i("allDocs",function(t,n){"function"==typeof t&&(n=t,t={});var e,r={},i="GET";(t=R(t)).conflicts&&(r.conflicts=!0),t.update_seq&&(r.update_seq=!0),t.descending&&(r.descending=!0),t.include_docs&&(r.include_docs=!0),t.attachments&&(r.attachments=!0),t.key&&(r.key=JSON.stringify(t.key)),t.start_key&&(t.startkey=t.start_key),t.startkey&&(r.startkey=JSON.stringify(t.startkey)),t.end_key&&(t.endkey=t.end_key),t.endkey&&(r.endkey=JSON.stringify(t.endkey)),void 0!==t.inclusive_end&&(r.inclusive_end=!!t.inclusive_end),void 0!==t.limit&&(r.limit=t.limit),void 0!==t.skip&&(r.skip=t.skip);var o=On(r);void 0!==t.keys&&(i="POST",e={keys:t.keys}),_(kn(y,"_all_docs"+o),{method:i,body:JSON.stringify(e)}).then(function(e){t.include_docs&&t.attachments&&t.binary&&e.data.rows.forEach(gn),n(null,e.data)}).catch(n)}),t._changes=function(s){var a="batch_size"in s?s.batch_size:hn;!(s=R(s)).continuous||"heartbeat"in s||(s.heartbeat=yn);var e="timeout"in s?s.timeout:3e4;"timeout"in s&&s.timeout&&e-s.timeout<vn&&(e=s.timeout+vn),"heartbeat"in s&&s.heartbeat&&e-s.heartbeat<vn&&(e=s.heartbeat+vn);var i={};"timeout"in s&&s.timeout&&(i.timeout=s.timeout);var u=void 0!==s.limit&&s.limit,c=u;if(s.style&&(i.style=s.style),(s.include_docs||s.filter&&"function"==typeof s.filter)&&(i.include_docs=!0),s.attachments&&(i.attachments=!0),s.continuous&&(i.feed="longpoll"),s.seq_interval&&(i.seq_interval=s.seq_interval),s.conflicts&&(i.conflicts=!0),s.descending&&(i.descending=!0),s.update_seq&&(i.update_seq=!0),"heartbeat"in s&&s.heartbeat&&(i.heartbeat=s.heartbeat),s.filter&&"string"==typeof s.filter&&(i.filter=s.filter),s.view&&"string"==typeof s.view&&(i.filter="_view",i.view=s.view),s.query_params&&"object"==typeof s.query_params)for(var t in s.query_params)s.query_params.hasOwnProperty(t)&&(i[t]=s.query_params[t]);var o,f="GET";s.doc_ids?(i.filter="_doc_ids",f="POST",o={doc_ids:s.doc_ids}):s.selector&&(i.filter="_selector",f="POST",o={selector:s.selector});function l(e,t){if(!s.aborted){i.since=e,"object"==typeof i.since&&(i.since=JSON.stringify(i.since)),s.descending?u&&(i.limit=c):i.limit=!u||a<c?a:c;var n=kn(y,"_changes"+On(i)),r={signal:h.signal,method:f,body:JSON.stringify(o)};d=e,s.aborted||g().then(function(){return _(n,r,t)}).catch(t)}}var d,h=new Ye,p={results:[]},v=function(e,t){if(!s.aborted){var n=0;if(t&&t.results){n=t.results.length,p.last_seq=t.last_seq;var r=null,i=null;"number"==typeof t.pending&&(r=t.pending),"string"!=typeof p.last_seq&&"number"!=typeof p.last_seq||(i=p.last_seq);s.query_params,t.results=t.results.filter(function(e){c--;var t=X(s)(e);return t&&(s.include_docs&&s.attachments&&s.binary&&gn(e),s.return_docs&&p.results.push(e),s.onChange(e,r,i)),t})}else if(e)return s.aborted=!0,void s.complete(e);t&&t.last_seq&&(d=t.last_seq);var o=u&&c<=0||t&&n<a||s.descending;(!s.continuous||u&&c<=0)&&o?s.complete(null,p):T(function(){l(d,v)})}};return l(s.since||0,v),{cancel:function(){s.aborted=!0,h.abort()}}},t.revsDiff=i("revsDiff",function(e,t,n){"function"==typeof t&&(n=t,t={}),_(kn(y,"_revs_diff"),{method:"POST",body:JSON.stringify(e)},n).catch(n)}),t._close=function(e){e()},t._destroy=function(e,t){_(kn(y,""),{method:"DELETE"}).then(function(e){t(null,e)}).catch(function(e){404===e.status?t(null,{ok:!0}):t(e)})}}function qn(e){this.status=400,this.name="query_parse_error",this.message=e,this.error=!0;try{Error.captureStackTrace(this,qn)}catch(e){}}function En(e){this.status=404,this.name="not_found",this.message=e,this.error=!0;try{Error.captureStackTrace(this,En)}catch(e){}}function Sn(e){this.status=500,this.name="invalid_value",this.message=e,this.error=!0;try{Error.captureStackTrace(this,Sn)}catch(e){}}function xn(e,t){return t&&e.then(function(e){T(function(){t(null,e)})},function(e){T(function(){t(e)})}),e}function Cn(n,r){return function(){var e=arguments,t=this;return n.add(function(){return r.apply(t,e)})}}function Pn(e){var t=new b(e),n=new Array(t.size),r=-1;return t.forEach(function(e){n[++r]=e}),n}function Ln(e){var n=new Array(e.size),r=-1;return e.forEach(function(e,t){n[++r]=t}),n}function $n(e){return new Sn("builtin "+e+" function requires map values to be numbers or number arrays")}function Dn(e){for(var t=0,n=0,r=e.length;n<r;n++){var i=e[n];if("number"!=typeof i){if(!Array.isArray(i))throw $n("_sum");t="number"==typeof t?[t]:t;for(var o=0,s=i.length;o<s;o++){var a=i[o];if("number"!=typeof a)throw $n("_sum");void 0===t[o]?t.push(a):t[o]+=a}}else"number"==typeof t?t+=i:t[0]+=i}return t}An.valid=function(){return!0},o(qn,Error),o(En,Error),o(Sn,Error);var In=E.bind(null,"log"),Bn=Array.isArray,Tn=JSON.parse;function Rn(e,t){return ce("return ("+e.replace(/;\s*$/,"")+");",{emit:t,sum:Dn,log:In,isArray:Bn,toJSON:Tn})}function Mn(){this.promise=new Promise(function(e){e()})}function Nn(e){if(!e)return"undefined";switch(typeof e){case"function":case"string":return e.toString();default:return JSON.stringify(e)}}function Un(i,o,s,a,t,n){var u,c=function(e,t){return Nn(e)+Nn(t)+"undefined"}(s,a);if(!t&&(u=i._cachedViews=i._cachedViews||{})[c])return u[c];var e=i.info().then(function(e){var r=e.db_name+"-mrview-"+(t?"temp":Oe(c));return fe(i,"_local/"+n,function(e){e.views=e.views||{};var t=o;-1===t.indexOf("/")&&(t=o+"/"+o);var n=e.views[t]=e.views[t]||{};if(!n[r])return n[r]=!0,e}).then(function(){return i.registerDependentDatabase(r).then(function(e){var t=e.db;t.auto_compaction=!0;var n={name:r,db:t,sourceDB:i,adapter:i.adapter,mapFun:s,reduceFun:a};return n.db.get("_local/lastSeq").catch(function(e){if(404!==e.status)throw e}).then(function(e){return n.seq=e?e.seq:0,u&&n.db.once("destroyed",function(){delete u[c]}),n})})})});return u&&(u[c]=e),e}Mn.prototype.add=function(e){return this.promise=this.promise.catch(function(){}).then(function(){return e()}),this.promise},Mn.prototype.finish=function(){return this.promise};var Fn={},Kn=new Mn;function Jn(e){return-1===e.indexOf("/")?[e,e]:e.split("/")}function zn(e,t){try{e.emit("error",t)}catch(e){E("error","The user's map/reduce function threw an uncaught error.\nYou can debug this error by doing:\nmyDatabase.on('error', function (err) { debugger; });\nPlease double-check your map/reduce function."),E("error",t)}}var Vn={_sum:function(e,t){return Dn(t)},_count:function(e,t){return t.length},_stats:function(e,t){return{sum:Dn(t),min:Math.min.apply(null,t),max:Math.max.apply(null,t),count:t.length,sumsqr:function(e){for(var t=0,n=0,r=e.length;n<r;n++){var i=e[n];t+=i*i}return t}(t)}}};var Gn,Qn,Wn,Yn,Hn,Xn=(Qn="mrviews",Wn=function(e,t){if("function"!=typeof e||2!==e.length)return Rn(e.toString(),t);var n=e;return function(e){return n(e,t)}},Yn=function(e){var t=e.toString(),n=function(e){if(/^_sum/.test(e))return Vn._sum;if(/^_count/.test(e))return Vn._count;if(/^_stats/.test(e))return Vn._stats;if(/^_/.test(e))throw new Error(e+" is not a supported reduce function.")}(t);return n||Rn(t)},Hn=function(e,t){var n=e.views&&e.views[t];if("string"!=typeof n.map)throw new En("ddoc "+e._id+" has no string view named "+t+", instead found object of type: "+typeof n.map)},{query:function(e,t,n){var r=this;"function"==typeof t&&(n=t,t={}),t=t?function(e){return e.group_level=or(e.group_level),e.limit=or(e.limit),e.skip=or(e.skip),e}(t):{},"function"==typeof e&&(e={map:e});var i=Promise.resolve().then(function(){return dr(r,e,t)});return xn(i,n),i},viewCleanup:(Gn=function(){var e=this;return"function"==typeof e._viewCleanup?function(e){return new Promise(function(n,r){e._viewCleanup(function(e,t){if(e)return r(e);n(t)})})}(e):te(e)?function(e){return e.fetch("_view_cleanup",{headers:new Xe({"Content-Type":"application/json"}),method:"POST"}).then(function(e){return e.json()})}(e):function(n){return n.get("_local/"+Qn).then(function(a){var u=new x;Object.keys(a.views).forEach(function(e){var t=Jn(e),n="_design/"+t[0],r=t[1],i=u.get(n);i||(i=new b,u.set(n,i)),i.add(r)});var e={keys:Ln(u),include_docs:!0};return n.allDocs(e).then(function(e){var s={};e.rows.forEach(function(i){var o=i.key.substring(8);u.get(i.key).forEach(function(e){var t=o+"/"+e;a.views[t]||(t=e);var n=Object.keys(a.views[t]),r=i.doc&&i.doc.views&&i.doc.views[e];n.forEach(function(e){s[e]=s[e]||r})})});var t=Object.keys(s).filter(function(e){return!s[e]}).map(function(e){return Cn(cr(e),function(){return new n.constructor(e,n.__opts).destroy()})()});return Promise.all(t).then(function(){return{ok:!0}})})},ar({ok:!0}))}(e)},f(function(e){var t=e.pop(),n=Gn.apply(this,e);return"function"==typeof t&&xn(n,t),n}))});function Zn(t,e,n){try{e(n)}catch(e){zn(t,e)}}function er(t,e,n,r,i){try{return{output:e(n,r,i)}}catch(e){return zn(t,e),{error:e}}}function tr(e,t){var n=ft(e.key,t.key);return 0!==n?n:ft(e.value,t.value)}function nr(e){var t=e.value;return t&&"object"==typeof t&&t._id||e.id}function rr(t){return function(e){return t.include_docs&&t.attachments&&t.binary&&function(e){e.rows.forEach(function(e){var n=e.doc&&e.doc._attachments;n&&Object.keys(n).forEach(function(e){var t=n[e];n[e].data=ve(t.data,t.content_type)})})}(e),e}}function ir(e,t,n,r){var i=t[e];void 0!==i&&(r&&(i=encodeURIComponent(JSON.stringify(i))),n.push(e+"="+i))}function or(e){if(void 0!==e){var t=Number(e);return isNaN(t)||t!==parseInt(e,10)?e:t}}function sr(n,e){var t=n.descending?"endkey":"startkey",r=n.descending?"startkey":"endkey";if(void 0!==n[t]&&void 0!==n[r]&&0<ft(n[t],n[r]))throw new qn("No rows can match your key range, reverse your start_key and end_key or set {descending : true}");if(e.reduce&&!1!==n.reduce){if(n.include_docs)throw new qn("{include_docs:true} is invalid for reduce");if(n.keys&&1<n.keys.length&&!n.group&&!n.group_level)throw new qn("Multi-key fetches for reduce views must use {group: true}")}["group_level","limit","skip"].forEach(function(e){var t=function(e){if(e){if("number"!=typeof e)return new qn('Invalid value for integer: "'+e+'"');if(e<0)return new qn('Invalid value for positive integer: "'+e+'"')}}(n[e]);if(t)throw t})}function ar(t){return function(e){if(404===e.status)return t;throw e}}function ur(e,n,t){var r="_local/doc_"+e,i={_id:r,keys:[]},o=t.get(e),c=o[0];return(function(e){return 1===e.length&&/^1-/.test(e[0].rev)}(o[1])?Promise.resolve(i):n.db.get(r).catch(ar(i))).then(function(t){return function(e){return e.keys.length?n.db.allDocs({keys:e.keys,include_docs:!0}):Promise.resolve({rows:[]})}(t).then(function(e){return function(e,t){for(var r=[],i=new b,n=0,o=t.rows.length;n<o;n++){var s=t.rows[n].doc;if(s&&(r.push(s),i.add(s._id),s._deleted=!c.has(s._id),!s._deleted)){var a=c.get(s._id);"value"in a&&(s.value=a.value)}}var u=Ln(c);return u.forEach(function(e){if(!i.has(e)){var t={_id:e},n=c.get(e);"value"in n&&(t.value=n.value),r.push(t)}}),e.keys=Pn(u.concat(e.keys)),r.push(e),r}(t,e)})})}function cr(e){var t="string"==typeof e?e:e.name,n=Fn[t];return n||(n=Fn[t]=new Mn),n}function fr(e){return Cn(cr(e),function(){return function(s){var a,u;var c=Wn(s.mapFun,function(e,t){var n={id:u._id,key:lt(e)};null!=t&&(n.value=lt(t)),a.push(n)}),f=s.seq||0;function r(e,t){return function(){return function(r,t,i){var e="_local/lastSeq";return r.db.get(e).catch(ar({_id:e,seq:0})).then(function(n){var e=Ln(t);return Promise.all(e.map(function(e){return ur(e,r,t)})).then(function(e){var t=Z(e);return n.seq=i,t.push(n),r.db.bulkDocs({docs:t})})})}(s,e,t)}}var i=new Mn;function o(){return s.sourceDB.changes({return_docs:!0,conflicts:!0,include_docs:!0,style:"all_docs",since:f,limit:50}).then(e)}function e(e){var t=e.results;if(t.length){var n=function(e){for(var t=new x,n=0,r=e.length;n<r;n++){var i=e[n];if("_"!==i.doc._id[0]){a=[],(u=i.doc)._deleted||Zn(s.sourceDB,c,u),a.sort(tr);var o=l(a);t.set(i.doc._id,[o,i.changes])}f=i.seq}return t}(t);if(i.add(r(n,f)),!(t.length<50))return o()}}function l(e){for(var t,n=new x,r=0,i=e.length;r<i;r++){var o=e[r],s=[o.key,o.id];0<r&&0===ft(o.key,t)&&s.push(r),n.set(ht(s),o),t=o.key}return n}return o().then(function(){return i.finish()}).then(function(){s.seq=f})}(e)})()}function lr(e,t){return Cn(cr(e),function(){return function(r,i){var o,s=r.reduceFun&&!1!==i.reduce,a=i.skip||0;void 0===i.keys||i.keys.length||(i.limit=0,delete i.keys);function n(e){return e.include_docs=!0,r.db.allDocs(e).then(function(e){return o=e.total_rows,e.rows.map(function(e){if("value"in e.doc&&"object"==typeof e.doc.value&&null!==e.doc.value){var t=Object.keys(e.doc.value).sort(),n=["id","key","value"];if(!(t<n||n<t))return e.doc.value}var r=function(e){for(var t=[],n=[],r=0;;){var i=e[r++];if("\0"!==i)switch(i){case"1":t.push(null);break;case"2":t.push("1"===e[r]),r++;break;case"3":var o=pt(e,r);t.push(o.num),r+=o.length;break;case"4":for(var s="";;){var a=e[r];if("\0"===a)break;s+=a,r++}s=s.replace(/\u0001\u0001/g,"\0").replace(/\u0001\u0002/g,"").replace(/\u0002\u0002/g,""),t.push(s);break;case"5":var u={element:[],index:t.length};t.push(u.element),n.push(u);break;case"6":var c={element:{},index:t.length};t.push(c.element),n.push(c);break;default:throw new Error("bad collationIndex or unexpectedly reached end of input: "+i)}else{if(1===t.length)return t.pop();vt(t,n)}}}(e.doc._id);return{key:r[0],id:r[1],value:"value"in e.doc?e.doc.value:null}})})}function e(t){var n;if(n=s?function(e,t,n){0===n.group_level&&delete n.group_level;var r=n.group||n.group_level,i=Yn(e.reduceFun),o=[],s=isNaN(n.group_level)?Number.POSITIVE_INFINITY:n.group_level;t.forEach(function(e){var t=o[o.length-1],n=r?e.key:null;if(r&&Array.isArray(n)&&(n=n.slice(0,s)),t&&0===ft(t.groupKey,n))return t.keys.push([e.key,e.id]),void t.values.push(e.value);o.push({keys:[[e.key,e.id]],values:[e.value],groupKey:n})}),t=[];for(var a=0,u=o.length;a<u;a++){var c=o[a],f=er(e.sourceDB,i,c.keys,c.values,!1);if(f.error&&f.error instanceof Sn)throw f.error;t.push({value:f.error?null:f.output,key:c.groupKey})}return{rows:function(e,t,n){return n=n||0,"number"==typeof t?e.slice(n,t+n):0<n?e.slice(n):e}(t,n.limit,n.skip)}}(r,t,i):{total_rows:o,offset:a,rows:t},i.update_seq&&(n.update_seq=r.seq),i.include_docs){var e=Pn(t.map(nr));return r.sourceDB.allDocs({keys:e,include_docs:!0,conflicts:i.conflicts,attachments:i.attachments,binary:i.binary}).then(function(e){var r=new x;return e.rows.forEach(function(e){r.set(e.id,e.doc)}),t.forEach(function(e){var t=nr(e),n=r.get(t);n&&(e.doc=n)}),n})}return n}{if(void 0!==i.keys){var t=i.keys.map(function(e){var t={startkey:ht([e]),endkey:ht([e,{}])};return i.update_seq&&(t.update_seq=!0),n(t)});return Promise.all(t).then(Z).then(e)}var u,c,f={descending:i.descending};if(i.update_seq&&(f.update_seq=!0),"start_key"in i&&(u=i.start_key),"startkey"in i&&(u=i.startkey),"end_key"in i&&(c=i.end_key),"endkey"in i&&(c=i.endkey),void 0!==u&&(f.startkey=i.descending?ht([u,{}]):ht([u])),void 0!==c){var l=!1!==i.inclusive_end;i.descending&&(l=!l),f.endkey=ht(l?[c,{}]:[c])}if(void 0!==i.key){var d=ht([i.key]),h=ht([i.key,{}]);f.descending?(f.endkey=d,f.startkey=h):(f.startkey=d,f.endkey=h)}return s||("number"==typeof i.limit&&(f.limit=i.limit),f.skip=a),n(f).then(e)}}(e,t)})()}function dr(n,e,r){if("function"==typeof n._query)return function(e,t,i){return new Promise(function(n,r){e._query(t,i,function(e,t){if(e)return r(e);n(t)})})}(n,e,r);if(te(n))return function(e,t,n){var r,i,o,s=[],a="GET";if(ir("reduce",n,s),ir("include_docs",n,s),ir("attachments",n,s),ir("limit",n,s),ir("descending",n,s),ir("group",n,s),ir("group_level",n,s),ir("skip",n,s),ir("stale",n,s),ir("conflicts",n,s),ir("startkey",n,s,!0),ir("start_key",n,s,!0),ir("endkey",n,s,!0),ir("end_key",n,s,!0),ir("inclusive_end",n,s),ir("key",n,s,!0),ir("update_seq",n,s),s=""===(s=s.join("&"))?"":"?"+s,void 0!==n.keys){var u="keys="+encodeURIComponent(JSON.stringify(n.keys));u.length+s.length+1<=2e3?s+=("?"===s[0]?"&":"?")+u:(a="POST","string"==typeof t?r={keys:n.keys}:t.keys=n.keys)}if("string"!=typeof t)return r=r||{},Object.keys(t).forEach(function(e){Array.isArray(t[e])?r[e]=t[e]:r[e]=t[e].toString()}),e.fetch("_temp_view"+s,{headers:new Xe({"Content-Type":"application/json"}),method:"POST",body:JSON.stringify(r)}).then(function(e){return i=e.ok,o=e.status,e.json()}).then(function(e){if(!i)throw e.status=o,H(e);return e}).then(rr(n));var c=Jn(t);return e.fetch("_design/"+c[0]+"/_view/"+c[1]+s,{headers:new Xe({"Content-Type":"application/json"}),method:a,body:JSON.stringify(r)}).then(function(e){return i=e.ok,o=e.status,e.json()}).then(function(e){if(!i)throw e.status=o,H(e);return e.rows.forEach(function(e){if(e.value&&e.value.error&&"builtin_reduce_error"===e.value.error)throw new Error(e.reason)}),e}).then(rr(n))}(n,e,r);if("string"!=typeof e)return sr(r,e),Kn.add(function(){return Un(n,"temp_view/temp_view",e.map,e.reduce,!0,Qn).then(function(e){return function(e,t){return e.then(function(e){return t().then(function(){return e})},function(e){return t().then(function(){throw e})})}(fr(e).then(function(){return lr(e,r)}),function(){return e.db.destroy()})})}),Kn.finish();var i=e,t=Jn(i),o=t[0],s=t[1];return n.get("_design/"+o).then(function(e){var t=e.views&&e.views[s];if(!t)throw new En("ddoc "+e._id+" has no view named "+s);return Hn(e,s),sr(r,t),Un(n,i,t.map,t.reduce,!1,Qn).then(function(e){return"ok"===r.stale||"update_after"===r.stale?("update_after"===r.stale&&T(function(){fr(e)}),lr(e,r)):fr(e).then(function(){return lr(e,r)})})})}var hr={query:function(e,t,n){return Xn.query.call(this,e,t,n)},viewCleanup:function(e){return Xn.viewCleanup.call(this,e)}};function pr(e){return/^1-/.test(e)}function vr(t,n){var e=Object.keys(n._attachments);return Promise.all(e.map(function(e){return t.getAttachment(n._id,e,{rev:n._rev})}))}function yr(t,n,r,i){r=R(r);var o=[],s=!0;function a(e){return t.allDocs({keys:e,include_docs:!0,conflicts:!0}).then(function(e){if(i.cancelled)throw new Error("cancelled");e.rows.forEach(function(e){e.deleted||!e.doc||!pr(e.value.rev)||function(e){return e._attachments&&0<Object.keys(e._attachments).length}(e.doc)||function(e){return e._conflicts&&0<e._conflicts.length}(e.doc)||(e.doc._conflicts&&delete e.doc._conflicts,o.push(e.doc),delete r[e.id])})})}return Promise.resolve().then(function(){var e=Object.keys(r).filter(function(e){var t=r[e].missing;return 1===t.length&&pr(t[0])});if(0<e.length)return a(e)}).then(function(){var e=function(e){var n=[];return Object.keys(e).forEach(function(t){e[t].missing.forEach(function(e){n.push({id:t,rev:e})})}),{docs:n,revs:!0,latest:!0}}(r);if(e.docs.length)return t.bulkGet(e).then(function(e){if(i.cancelled)throw new Error("cancelled");return Promise.all(e.results.map(function(e){return Promise.all(e.docs.map(function(e){var i=e.ok;return e.error&&(s=!1),i&&i._attachments?function(n,r,i){var e=te(r)&&!te(n),o=Object.keys(i._attachments);return e?n.get(i._id).then(function(t){return Promise.all(o.map(function(e){return function(e,t,n){return!e._attachments||!e._attachments[n]||e._attachments[n].digest!==t._attachments[n].digest}(t,i,e)?r.getAttachment(i._id,e):n.getAttachment(t._id,e)}))}).catch(function(e){if(404!==e.status)throw e;return vr(r,i)}):vr(r,i)}(n,t,i).then(function(e){var r=Object.keys(i._attachments);return e.forEach(function(e,t){var n=i._attachments[r[t]];delete n.stub,delete n.length,n.data=e}),i}):i}))})).then(function(e){o=o.concat(Z(e).filter(Boolean))})})}).then(function(){return{ok:s,docs:o}})}var _r=1,gr="pouchdb",mr=5,br=0;function wr(t,n,r,i,o){return t.get(n).catch(function(e){if(404===e.status)return"http"!==t.adapter&&"https"!==t.adapter||S(404,"PouchDB is just checking if a remote checkpoint exists."),{session_id:i,_id:n,history:[],replicator:gr,version:_r};throw e}).then(function(e){if(!o.cancelled&&e.last_seq!==r)return e.history=(e.history||[]).filter(function(e){return e.session_id!==i}),e.history.unshift({last_seq:r,session_id:i}),e.history=e.history.slice(0,mr),e.version=_r,e.replicator=gr,e.session_id=i,e.last_seq=r,t.put(e).catch(function(e){if(409===e.status)return wr(t,n,r,i,o);throw e})})}function kr(e,t,n,r,i){this.src=e,this.target=t,this.id=n,this.returnValue=r,this.opts=i||{}}kr.prototype.writeCheckpoint=function(e,t){var n=this;return this.updateTarget(e,t).then(function(){return n.updateSource(e,t)})},kr.prototype.updateTarget=function(e,t){return this.opts.writeTargetCheckpoint?wr(this.target,this.id,e,t,this.returnValue):Promise.resolve(!0)},kr.prototype.updateSource=function(e,t){if(this.opts.writeSourceCheckpoint){var n=this;return wr(this.src,this.id,e,t,this.returnValue).catch(function(e){if(Ar(e))return!(n.opts.writeSourceCheckpoint=!1);throw e})}return Promise.resolve(!0)};var jr={undefined:function(e,t){return 0===ft(e.last_seq,t.last_seq)?t.last_seq:0},1:function(e,t){return function(e,t){return e.session_id!==t.session_id?function e(t,n){var r=t[0];var i=t.slice(1);var o=n[0];var s=n.slice(1);if(!r||0===n.length)return{last_seq:br,history:[]};var a=r.session_id;if(Or(a,n))return{last_seq:r.last_seq,history:t};var u=o.session_id;if(Or(u,i))return{last_seq:o.last_seq,history:s};return e(i,s)}(e.history,t.history):{last_seq:e.last_seq,history:e.history}}(t,e).last_seq}};function Or(e,t){var n=t[0],r=t.slice(1);return!(!e||0===t.length)&&(e===n.session_id||Or(e,r))}function Ar(e){return"number"==typeof e.status&&4===Math.floor(e.status/100)}kr.prototype.getCheckpoint=function(){var t=this;return t.opts&&t.opts.writeSourceCheckpoint&&!t.opts.writeTargetCheckpoint?t.src.get(t.id).then(function(e){return e.last_seq||br}).catch(function(e){if(404!==e.status)throw e;return br}):t.target.get(t.id).then(function(n){return t.opts&&t.opts.writeTargetCheckpoint&&!t.opts.writeSourceCheckpoint?n.last_seq||br:t.src.get(t.id).then(function(e){return n.version!==e.version?br:(t=n.version?n.version.toString():"undefined")in jr?jr[t](n,e):br;var t},function(e){if(404===e.status&&n.last_seq)return t.src.put({_id:t.id,last_seq:br}).then(function(){return br},function(e){return Ar(e)?(t.opts.writeSourceCheckpoint=!1,n.last_seq):br});throw e})}).catch(function(e){if(404!==e.status)throw e;return br})};var qr=0;function Er(e,t,n){var r=n.doc_ids?n.doc_ids.sort(ft):"",i=n.filter?n.filter.toString():"",o="",s="",a="";return n.selector&&(a=JSON.stringify(n.selector)),n.filter&&n.query_params&&(o=JSON.stringify(function(n){return Object.keys(n).sort(ft).reduce(function(e,t){return e[t]=n[t],e},{})}(n.query_params))),n.filter&&"_view"===n.filter&&(s=n.view.toString()),Promise.all([e.id(),t.id()]).then(function(e){var t=e[0]+e[1]+i+s+o+r+a;return new Promise(function(e){je(t,e)})}).then(function(e){return"_local/"+(e=e.replace(/\//g,".").replace(/\+/g,"_"))})}function Sr(r,i,o,s,a){var u,n,c,f=[],l={seq:0,changes:[],docs:[]},d=!1,h=!1,p=!1,v=0,y=o.continuous||o.live||!1,t=o.batch_size||100,_=o.batches_limit||10,g=!1,m=o.doc_ids,b=o.selector,w=[],k=qe();a=a||{ok:!0,start_time:(new Date).toISOString(),docs_read:0,docs_written:0,doc_write_failures:0,errors:[]};var j={};function e(){return c?Promise.resolve():Er(r,i,o).then(function(e){n=e;var t={};t=!1===o.checkpoint?{writeSourceCheckpoint:!1,writeTargetCheckpoint:!1}:"source"===o.checkpoint?{writeSourceCheckpoint:!0,writeTargetCheckpoint:!1}:"target"===o.checkpoint?{writeSourceCheckpoint:!1,writeTargetCheckpoint:!0}:{writeSourceCheckpoint:!0,writeTargetCheckpoint:!0},c=new kr(r,i,n,s,t)})}function O(){if(w=[],0!==u.docs.length){var n=u.docs,e={timeout:o.timeout};return i.bulkDocs({docs:n,new_edits:!1},e).then(function(e){if(s.cancelled)throw C(),new Error("cancelled");var r=Object.create(null);e.forEach(function(e){e.error&&(r[e.id]=e)});var t=Object.keys(r).length;a.doc_write_failures+=t,a.docs_written+=n.length-t,n.forEach(function(e){var t=r[e._id];if(t){a.errors.push(t);var n=(t.name||"").toLowerCase();if("unauthorized"!==n&&"forbidden"!==n)throw t;s.emit("denied",R(t))}else w.push(e)})},function(e){throw a.doc_write_failures+=n.length,e})}}function A(){if(u.error)throw new Error("There was a problem getting docs.");a.last_seq=v=u.seq;var e=R(a);return w.length&&(e.docs=w,"number"==typeof u.pending&&(e.pending=u.pending,delete u.pending),s.emit("change",e)),d=!0,c.writeCheckpoint(u.seq,k).then(function(){if(d=!1,s.cancelled)throw C(),new Error("cancelled");u=void 0,D()}).catch(function(e){throw B(e),e})}function q(){return yr(r,i,u.diffs,s).then(function(e){u.error=!e.ok,e.docs.forEach(function(e){delete u.diffs[e._id],a.docs_read++,u.docs.push(e)})})}function E(){s.cancelled||u||(0!==f.length?(u=f.shift(),function(){var t={};return u.changes.forEach(function(e){"_user/"!==e.id&&(t[e.id]=e.changes.map(function(e){return e.rev}))}),i.revsDiff(t).then(function(e){if(s.cancelled)throw C(),new Error("cancelled");u.diffs=e})}().then(q).then(O).then(A).then(E).catch(function(e){x("batch processing terminated with error",e)})):S(!0))}function S(e){0!==l.changes.length?(e||h||l.changes.length>=t)&&(f.push(l),l={seq:0,changes:[],docs:[]},"pending"!==s.state&&"stopped"!==s.state||(s.state="active",s.emit("active")),E()):0!==f.length||u||((y&&j.live||h)&&(s.state="pending",s.emit("paused")),h&&C())}function x(e,t){p||(t.message||(t.message=e),a.ok=!1,a.status="aborting",f=[],l={seq:0,changes:[],docs:[]},C(t))}function C(e){if(!(p||s.cancelled&&(a.status="cancelled",d)))if(a.status=a.status||"complete",a.end_time=(new Date).toISOString(),a.last_seq=v,p=!0,e){(e=Y(e)).result=a;var t=(e.name||"").toLowerCase();"unauthorized"===t||"forbidden"===t?(s.emit("error",e),s.removeAllListeners()):function(e,t,n,r){if(!1===e.retry)return t.emit("error",n),t.removeAllListeners();if("function"!=typeof e.back_off_function&&(e.back_off_function=M),t.emit("requestError",n),"active"===t.state||"pending"===t.state){t.emit("paused",n),t.state="stopped";var i=function(){e.current_back_off=qr};t.once("paused",function(){t.removeListener("active",i)}),t.once("active",i)}e.current_back_off=e.current_back_off||qr,e.current_back_off=e.back_off_function(e.current_back_off),setTimeout(r,e.current_back_off)}(o,s,e,function(){Sr(r,i,o,s)})}else s.emit("complete",a),s.removeAllListeners()}function P(e,t,n){if(s.cancelled)return C();"number"==typeof t&&(l.pending=t),X(o)(e)&&(l.seq=e.seq||n,l.changes.push(e),T(function(){S(0===f.length&&j.live)}))}function L(e){if(g=!1,s.cancelled)return C();if(0<e.results.length)j.since=e.results[e.results.length-1].seq,D(),S(!0);else{var t=function(){y?(j.live=!0,D()):h=!0,S(!0)};u||0!==e.results.length?t():(d=!0,c.writeCheckpoint(e.last_seq,k).then(function(){d=!1,a.last_seq=v=e.last_seq,t()}).catch(B))}}function $(e){if(g=!1,s.cancelled)return C();x("changes rejected",e)}function D(){if(!g&&!h&&f.length<_){g=!0,s._changes&&(s.removeListener("cancel",s._abortChanges),s._changes.cancel()),s.once("cancel",t);var e=r.changes(j).on("change",P);e.then(n,n),e.then(L).catch($),o.retry&&(s._changes=e,s._abortChanges=t)}function t(){e.cancel()}function n(){s.removeListener("cancel",t)}}function I(){e().then(function(){if(!s.cancelled)return c.getCheckpoint().then(function(e){j={since:v=e,limit:t,batch_size:t,style:"all_docs",doc_ids:m,selector:b,return_docs:!0},o.filter&&("string"!=typeof o.filter?j.include_docs=!0:j.filter=o.filter),"heartbeat"in o&&(j.heartbeat=o.heartbeat),"timeout"in o&&(j.timeout=o.timeout),o.query_params&&(j.query_params=o.query_params),o.view&&(j.view=o.view),D()});C()}).catch(function(e){x("getCheckpoint rejected with ",e)})}function B(e){d=!1,x("writeCheckpoint completed with error",e)}s.ready(r,i),s.cancelled?C():(s._addedListeners||(s.once("cancel",C),"function"==typeof o.complete&&(s.once("error",o.complete),s.once("complete",function(e){o.complete(null,e)})),s._addedListeners=!0),void 0===o.since?I():e().then(function(){return d=!0,c.writeCheckpoint(o.since,k)}).then(function(){d=!1,s.cancelled?C():(v=o.since,I())}).catch(B))}function xr(){a.EventEmitter.call(this),this.cancelled=!1,this.state="pending";var n=this,r=new Promise(function(e,t){n.once("complete",e),n.once("error",t)});n.then=function(e,t){return r.then(e,t)},n.catch=function(e){return r.catch(e)},n.catch(function(){})}function Cr(e,t){var n=t.PouchConstructor;return"string"==typeof e?new n(e,t):e}function Pr(e,t,n,r){if("function"==typeof n&&(r=n,n={}),void 0===n&&(n={}),n.doc_ids&&!Array.isArray(n.doc_ids))throw Y(z,"`doc_ids` filter parameter is not a list.");n.complete=r,(n=R(n)).continuous=n.continuous||n.live,n.retry="retry"in n&&n.retry,n.PouchConstructor=n.PouchConstructor||this;var i=new xr(n);return Sr(Cr(e,n),Cr(t,n),n,i),i}function Lr(e,t,n,r){return"function"==typeof n&&(r=n,n={}),void 0===n&&(n={}),(n=R(n)).PouchConstructor=n.PouchConstructor||this,new $r(e=Cr(e,n),t=Cr(t,n),n,r)}function $r(e,t,n,r){var i=this;this.canceled=!1;var o=n.push?C({},n,n.push):n,s=n.pull?C({},n,n.pull):n;function a(e){i.emit("change",{direction:"pull",change:e})}function u(e){i.emit("change",{direction:"push",change:e})}function c(e){i.emit("denied",{direction:"push",doc:e})}function f(e){i.emit("denied",{direction:"pull",doc:e})}function l(){i.pushPaused=!0,i.pullPaused&&i.emit("paused")}function d(){i.pullPaused=!0,i.pushPaused&&i.emit("paused")}function h(){i.pushPaused=!1,i.pullPaused&&i.emit("active",{direction:"push"})}function p(){i.pullPaused=!1,i.pushPaused&&i.emit("active",{direction:"pull"})}this.push=Pr(e,t,o),this.pull=Pr(t,e,s),this.pushPaused=!0,this.pullPaused=!0;var v={};function y(n){return function(e,t){("change"!==e||t!==a&&t!==u)&&("denied"!==e||t!==f&&t!==c)&&("paused"!==e||t!==d&&t!==l)&&("active"!==e||t!==p&&t!==h)||(e in v||(v[e]={}),v[e][n]=!0,2===Object.keys(v[e]).length&&i.removeAllListeners(e))}}function _(e,t,n){-1==e.listeners(t).indexOf(n)&&e.on(t,n)}n.live&&(this.push.on("complete",i.pull.cancel.bind(i.pull)),this.pull.on("complete",i.push.cancel.bind(i.push))),this.on("newListener",function(e){"change"===e?(_(i.pull,"change",a),_(i.push,"change",u)):"denied"===e?(_(i.pull,"denied",f),_(i.push,"denied",c)):"active"===e?(_(i.pull,"active",p),_(i.push,"active",h)):"paused"===e&&(_(i.pull,"paused",d),_(i.push,"paused",l))}),this.on("removeListener",function(e){"change"===e?(i.pull.removeListener("change",a),i.push.removeListener("change",u)):"denied"===e?(i.pull.removeListener("denied",f),i.push.removeListener("denied",c)):"active"===e?(i.pull.removeListener("active",p),i.push.removeListener("active",h)):"paused"===e&&(i.pull.removeListener("paused",d),i.push.removeListener("paused",l))}),this.pull.on("removeListener",y("pull")),this.push.on("removeListener",y("push"));var g=Promise.all([this.push,this.pull]).then(function(e){var t={push:e[0],pull:e[1]};return i.emit("complete",t),r&&r(null,t),i.removeAllListeners(),t},function(e){if(i.cancel(),r?r(e):i.emit("error",e),i.removeAllListeners(),r)throw e});this.then=function(e,t){return g.then(e,t)},this.catch=function(e){return g.catch(e)}}o(xr,a.EventEmitter),xr.prototype.cancel=function(){this.cancelled=!0,this.state="cancelled",this.emit("cancel")},xr.prototype.ready=function(e,t){var n=this;function r(){n.cancel()}n._readyCalled||(n._readyCalled=!0,e.once("destroyed",r),t.once("destroyed",r),n.once("complete",function(){e.removeListener("destroyed",r),t.removeListener("destroyed",r)}))},o($r,a.EventEmitter),$r.prototype.cancel=function(){this.canceled||(this.canceled=!0,this.push.cancel(),this.pull.cancel())},We.plugin(function(e){e.adapter("idb",dn,!0)}).plugin(function(e){e.adapter("http",An,!1),e.adapter("https",An,!1)}).plugin(hr).plugin(function(e){e.replicate=Pr,e.sync=Lr,Object.defineProperty(e.prototype,"replicate",{get:function(){var r=this;return void 0===this.replicateMethods&&(this.replicateMethods={from:function(e,t,n){return r.constructor.replicate(e,r,t,n)},to:function(e,t,n){return r.constructor.replicate(r,e,t,n)}}),this.replicateMethods}}),e.prototype.sync=function(e,t,n){return this.constructor.sync(this,e,t,n)}}),Ir.exports=We}).call(this,Dr(5),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{1:1,12:12,2:2,3:3,4:4,5:5,6:6,7:7}]},{},[13])(13)});
\ No newline at end of file
diff --git a/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb.authentication.js b/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb.authentication.js
index 1c3757c..dd83d28 100644
--- a/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb.authentication.js
+++ b/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb.authentication.js
@@ -1,3939 +1,3824 @@
(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.PouchAuthentication = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-(function (process){
'use strict';
-var Promise = require(13);
-var urlJoin = require(16);
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+var urlJoin = _interopDefault(require(15));
+var urlParse = _interopDefault(require(16));
+var inherits = _interopDefault(require(5));
+var pouchdbBinaryUtils = require(9);
+var ajaxCore = _interopDefault(require(7));
+var pouchdbUtils = require(11);
+var Promise = _interopDefault(require(10));
function getBaseUrl(db) {
+ // Parse database url
+ var url;
if (typeof db.getUrl === 'function') { // pouchdb pre-6.0.0
- return db.getUrl().replace(/\/[^\/]+\/?$/, '');
+ url = urlParse(db.getUrl());
} else { // pouchdb post-6.0.0
- return db.name.replace(/\/[^\/]+\/?$/, '');
+ // Use PouchDB.defaults' prefix, if any
+ var prefix = db.__opts && db.__opts.prefix ? db.__opts.prefix + '/' : '';
+ url = urlParse(prefix + db.name);
}
-}
-exports.getUsersUrl = function (db) {
- return urlJoin(getBaseUrl(db), '/_users');
-};
-exports.getSessionUrl = function (db) {
- return urlJoin(getBaseUrl(db), '/_session');
-};
-exports.once = function (fun) {
- var called = false;
- return exports.getArguments(function (args) {
- if (called) {
- console.trace();
- throw new Error('once called more than once');
- } else {
- called = true;
- fun.apply(this, args);
- }
- });
-};
-exports.getArguments = function (fun) {
- return function () {
- var len = arguments.length;
- var args = new Array(len);
- var i = -1;
- while (++i < len) {
- args[i] = arguments[i];
- }
- return fun.call(this, args);
- };
-};
-exports.toPromise = function (func) {
- //create the function we will be returning
- return exports.getArguments(function (args) {
- var self = this;
- var tempCB = (typeof args[args.length - 1] === 'function') ? args.pop() : false;
- // if the last argument is a function, assume its a callback
- var usedCB;
- if (tempCB) {
- // if it was a callback, create a new callback which calls it,
- // but do so async so we don't trap any errors
- usedCB = function (err, resp) {
- process.nextTick(function () {
- tempCB(err, resp);
- });
- };
- }
- var promise = new Promise(function (fulfill, reject) {
- try {
- var callback = exports.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);
- func.apply(self, args);
- } catch (e) {
- reject(e);
- }
- });
- // if there is a callback, call it back
- if (usedCB) {
- promise.then(function (result) {
- usedCB(null, result);
- }, usedCB);
- }
- promise.cancel = function () {
- return this;
- };
- return promise;
- });
-};
-
-exports.inherits = require(7);
-exports.extend = require(12);
-exports.ajax = require(11);
-exports.clone = function (obj) {
- return exports.extend(true, {}, obj);
-};
-exports.uuid = require(14).uuid;
-exports.Promise = Promise;
-}).call(this,require(15))
-},{"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"7":7}],2:[function(require,module,exports){
-'use strict';
-
-module.exports = argsArray;
+ // Compute parent path for databases not hosted on domain root (see #215)
+ var path = url.pathname;
+ path = path.substr(-1, 1) === '/' ? path.substr(0, -1) : path;
+ var parentPath = path.split('/').slice(0, -1).join('/');
-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, []);
- }
- };
+ return url.origin + parentPath;
}
-},{}],3:[function(require,module,exports){
-
-/**
- * This is the web browser implementation of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = require(4);
-exports.log = log;
-exports.formatArgs = formatArgs;
-exports.save = save;
-exports.load = load;
-exports.useColors = useColors;
-exports.storage = 'undefined' != typeof chrome
- && 'undefined' != typeof chrome.storage
- ? chrome.storage.local
- : localstorage();
-
-/**
- * Colors.
- */
-
-exports.colors = [
- 'lightseagreen',
- 'forestgreen',
- 'goldenrod',
- 'dodgerblue',
- 'darkorchid',
- 'crimson'
-];
-
-/**
- * Currently only WebKit-based Web Inspectors, Firefox >= v31,
- * and the Firebug extension (any Firefox version) are known
- * to support "%c" CSS customizations.
- *
- * TODO: add a `localStorage` variable to explicitly enable/disable colors
- */
-function useColors() {
- // is webkit? http://stackoverflow.com/a/16459606/376773
- return ('WebkitAppearance' in document.documentElement.style) ||
- // is firebug? http://stackoverflow.com/a/398120/376773
- (window.console && (console.firebug || (console.exception && console.table))) ||
- // is firefox >= v31?
- // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
- (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31);
+function getConfigUrl(db, nodeName) {
+ return urlJoin(getBaseUrl(db), (nodeName ? '/_node/' + nodeName : '') + '/_config');
}
-/**
- * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
- */
-
-exports.formatters.j = function(v) {
- return JSON.stringify(v);
-};
+function getUsersUrl(db) {
+ return urlJoin(getBaseUrl(db), '/_users');
+}
+function getSessionUrl(db) {
+ return urlJoin(getBaseUrl(db), '/_session');
+}
-/**
- * Colorize log arguments if enabled.
- *
- * @api public
- */
+function getBasicAuthHeaders(db) {
+ var auth;
-function formatArgs() {
- var args = arguments;
- var useColors = this.useColors;
-
- args[0] = (useColors ? '%c' : '')
- + this.namespace
- + (useColors ? ' %c' : ' ')
- + args[0]
- + (useColors ? '%c ' : ' ')
- + '+' + exports.humanize(this.diff);
-
- if (!useColors) return args;
-
- var c = 'color: ' + this.color;
- args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));
-
- // the final "%c" is somewhat tricky, because there could be other
- // arguments passed either before or after the %c, so we need to
- // figure out the correct index to insert the CSS into
- var index = 0;
- var lastC = 0;
- args[0].replace(/%[a-z%]/g, function(match) {
- if ('%%' === match) return;
- index++;
- if ('%c' === match) {
- // we only are interested in the *last* %c
- // (the user may have provided their own)
- lastC = index;
+ if (db.__opts.auth) {
+ auth = db.__opts.auth;
+ } else {
+ var url = urlParse(db.name);
+ if (url.auth) {
+ auth = url;
}
- });
-
- args.splice(lastC, 0, c);
- return args;
-}
+ }
-/**
- * Invokes `console.log()` when available.
- * No-op when `console.log` is not a "function".
- *
- * @api public
- */
+ if (!auth) {
+ return {};
+ }
-function log() {
- // this hackery is required for IE8/9, where
- // the `console.log` function doesn't have 'apply'
- return 'object' === typeof console
- && console.log
- && Function.prototype.apply.call(console.log, console, arguments);
+ var str = auth.username + ':' + auth.password;
+ var token = pouchdbBinaryUtils.btoa(unescape(encodeURIComponent(str)));
+ return {Authorization: 'Basic ' + token};
}
-/**
- * Save `namespaces`.
- *
- * @param {String} namespaces
- * @api private
- */
-
-function save(namespaces) {
- try {
- if (null == namespaces) {
- exports.storage.removeItem('debug');
- } else {
- exports.storage.debug = namespaces;
+function wrapError(callback) {
+ // provide more helpful error message
+ return function (err, res) {
+ if (err) {
+ if (err.name === 'unknown_error') {
+ err.message = (err.message || '') +
+ ' Unknown error! Did you remember to enable CORS?';
+ }
}
- } catch(e) {}
+ return callback(err, res);
+ };
}
-/**
- * Load `namespaces`.
- *
- * @return {String} returns the previously persisted debug modes
- * @api private
- */
-
-function load() {
- var r;
+function AuthError(message) {
+ this.status = 400;
+ this.name = 'authentication_error';
+ this.message = message;
+ this.error = true;
try {
- r = exports.storage.debug;
- } catch(e) {}
- return r;
+ Error.captureStackTrace(this, AuthError);
+ } catch (e) {}
}
-/**
- * Enable namespaces listed in `localStorage.debug` initially.
- */
-
-exports.enable(load());
-
-/**
- * Localstorage attempts to return the localstorage.
- *
- * This is necessary because safari throws
- * when a user disables cookies/localstorage
- * and you attempt to access it.
- *
- * @return {LocalStorage}
- * @api private
- */
+inherits(AuthError, Error);
-function localstorage(){
- try {
- return window.localStorage;
- } catch (e) {}
-}
+var getMembership = pouchdbUtils.toPromise(function (opts, callback) {
+ var db = this;
+ if (typeof callback === 'undefined') {
+ callback = opts;
+ opts = {};
+ }
-},{"4":4}],4:[function(require,module,exports){
+ var url = getBaseUrl(db) + '/_membership';
+ var ajaxOpts = pouchdbUtils.assign({
+ method: 'GET',
+ url: url,
+ headers: getBasicAuthHeaders(db),
+ }, opts.ajax || {});
+ ajaxCore(ajaxOpts, wrapError(callback));
+});
-/**
- * This is the common logic for both the Node.js and web browser
- * implementations of `debug()`.
- *
- * Expose `debug()` as the module.
- */
+var signUpAdmin = pouchdbUtils.toPromise(function (username, password, opts, callback) {
+ var db = this;
+ if (typeof callback === 'undefined') {
+ callback = typeof opts === 'undefined' ? (typeof password === 'undefined' ?
+ username : password) : opts;
+ opts = {};
+ }
+ if (['http', 'https'].indexOf(db.type()) === -1) {
+ return callback(new AuthError('This plugin only works for the http/https adapter. ' +
+ 'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
+ } else if (!username) {
+ return callback(new AuthError('You must provide a username'));
+ } else if (!password) {
+ return callback(new AuthError('You must provide a password'));
+ }
-exports = module.exports = debug;
-exports.coerce = coerce;
-exports.disable = disable;
-exports.enable = enable;
-exports.enabled = enabled;
-exports.humanize = require(10);
+ db.getMembership(opts, function (error, membership) {
+ var nodeName;
+ if (error) {
+ if (error.error !== 'illegal_database_name') {
+ return callback(error);
+ } else {
+ // Some couchdb-1.x-like server
+ nodeName = undefined;
+ }
+ } else {
+ // Some couchdb-2.x-like server
+ nodeName = membership.all_nodes[0];
+ }
+
+ var configUrl = getConfigUrl(db, nodeName);
+ var url = (opts.configUrl || configUrl) + '/admins/' + encodeURIComponent(username);
+ var ajaxOpts = pouchdbUtils.assign({
+ method: 'PUT',
+ url: url,
+ processData: false,
+ headers: getBasicAuthHeaders(db),
+ body: '"' + password + '"',
+ }, opts.ajax || {});
+ ajaxCore(ajaxOpts, wrapError(callback));
+ });
+});
-/**
- * The currently active debug mode names, and names to skip.
- */
+var deleteAdmin = pouchdbUtils.toPromise(function (username, opts, callback) {
+ var db = this;
+ if (typeof callback === 'undefined') {
+ callback = typeof opts === 'undefined' ? username : opts;
+ opts = {};
+ }
+ if (['http', 'https'].indexOf(db.type()) === -1) {
+ return callback(new AuthError('This plugin only works for the http/https adapter. ' +
+ 'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
+ } else if (!username) {
+ return callback(new AuthError('You must provide a username'));
+ }
-exports.names = [];
-exports.skips = [];
+ db.getMembership(opts, function (error, membership) {
+ var nodeName;
+ if (error) {
+ if (error.error !== 'illegal_database_name') {
+ return callback(error);
+ } else {
+ // Some couchdb-1.x-like server
+ nodeName = undefined;
+ }
+ } else {
+ // Some couchdb-2.x-like server
+ nodeName = membership.all_nodes[0];
+ }
-/**
- * Map of special "%n" handling functions, for the debug "format" argument.
- *
- * Valid key names are a single, lowercased letter, i.e. "n".
- */
+ var configUrl = getConfigUrl(db, nodeName);
+ var url = (opts.configUrl || configUrl) + '/admins/' + encodeURIComponent(username);
+ var ajaxOpts = pouchdbUtils.assign({
+ method: 'DELETE',
+ url: url,
+ processData: false,
+ headers: getBasicAuthHeaders(db),
+ }, opts.ajax || {});
+ ajaxCore(ajaxOpts, wrapError(callback));
+ });
+});
-exports.formatters = {};
+var logIn = pouchdbUtils.toPromise(function (username, password, opts, callback) {
+ var db = this;
+ if (typeof callback === 'undefined') {
+ callback = opts;
+ opts = {};
+ }
+ if (['http', 'https'].indexOf(db.type()) === -1) {
+ return callback(new AuthError('this plugin only works for the http/https adapter'));
+ }
-/**
- * Previously assigned color.
- */
+ if (!username) {
+ return callback(new AuthError('you must provide a username'));
+ } else if (!password) {
+ return callback(new AuthError('you must provide a password'));
+ }
-var prevColor = 0;
+ var ajaxOpts = pouchdbUtils.assign({
+ method: 'POST',
+ url: getSessionUrl(db),
+ headers: pouchdbUtils.assign({'Content-Type': 'application/json'}, getBasicAuthHeaders(db)),
+ body: {name: username, password: password},
+ }, opts.ajax || {});
+ ajaxCore(ajaxOpts, wrapError(callback));
+});
-/**
- * Previous log timestamp.
- */
+var logOut = pouchdbUtils.toPromise(function (opts, callback) {
+ var db = this;
+ if (typeof callback === 'undefined') {
+ callback = opts;
+ opts = {};
+ }
+ var ajaxOpts = pouchdbUtils.assign({
+ method: 'DELETE',
+ url: getSessionUrl(db),
+ headers: getBasicAuthHeaders(db),
+ }, opts.ajax || {});
+ ajaxCore(ajaxOpts, wrapError(callback));
+});
-var prevTime;
+var getSession = pouchdbUtils.toPromise(function (opts, callback) {
+ var db = this;
+ if (typeof callback === 'undefined') {
+ callback = opts;
+ opts = {};
+ }
+ var url = getSessionUrl(db);
-/**
- * Select a color.
- *
- * @return {Number}
- * @api private
- */
+ var ajaxOpts = pouchdbUtils.assign({
+ method: 'GET',
+ url: url,
+ headers: getBasicAuthHeaders(db),
+ }, opts.ajax || {});
+ ajaxCore(ajaxOpts, wrapError(callback));
+});
-function selectColor() {
- return exports.colors[prevColor++ % exports.colors.length];
-}
+var getUsersDatabaseUrl = function () {
+ var db = this;
+ return getUsersUrl(db);
+};
-/**
- * Create a debugger with the given `namespace`.
- *
- * @param {String} namespace
- * @return {Function}
- * @api public
- */
+function updateUser(db, user, opts, callback) {
+ var reservedWords = [
+ '_id',
+ '_rev',
+ 'name',
+ 'type',
+ 'roles',
+ 'password',
+ 'password_scheme',
+ 'iterations',
+ 'derived_key',
+ 'salt' ];
-function debug(namespace) {
+ if (opts.metadata) {
+ for (var key in opts.metadata) {
+ if (opts.metadata.hasOwnProperty(key) && reservedWords.indexOf(key) !== -1) {
+ return callback(new AuthError('cannot use reserved word in metadata: "' + key + '"'));
+ }
+ }
+ user = pouchdbUtils.assign(user, opts.metadata);
+ }
- // define the `disabled` version
- function disabled() {
+ if (opts.roles) {
+ user = pouchdbUtils.assign(user, {roles: opts.roles});
}
- disabled.enabled = false;
- // define the `enabled` version
- function enabled() {
+ var url = getUsersUrl(db) + '/' + encodeURIComponent(user._id);
+ var ajaxOpts = pouchdbUtils.assign({
+ method: 'PUT',
+ url: url,
+ body: user,
+ headers: getBasicAuthHeaders(db),
+ }, opts.ajax || {});
+ ajaxCore(ajaxOpts, wrapError(callback));
+}
- var self = enabled;
+var signUp = pouchdbUtils.toPromise(function (username, password, opts, callback) {
+ var db = this;
+ if (typeof callback === 'undefined') {
+ callback = typeof opts === 'undefined' ? (typeof password === 'undefined' ?
+ username : password) : opts;
+ opts = {};
+ }
+ if (['http', 'https'].indexOf(db.type()) === -1) {
+ return callback(new AuthError('This plugin only works for the http/https adapter. ' +
+ 'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
+ } else if (!username) {
+ return callback(new AuthError('You must provide a username'));
+ } else if (!password) {
+ return callback(new AuthError('You must provide a password'));
+ }
+
+ var userId = 'org.couchdb.user:' + username;
+ var user = {
+ name: username,
+ password: password,
+ roles: [],
+ type: 'user',
+ _id: userId,
+ };
- // set `diff` timestamp
- var curr = +new Date();
- var ms = curr - (prevTime || curr);
- self.diff = ms;
- self.prev = prevTime;
- self.curr = curr;
- prevTime = curr;
+ updateUser(db, user, opts, callback);
+});
- // add the `color` if not set
- if (null == self.useColors) self.useColors = exports.useColors();
- if (null == self.color && self.useColors) self.color = selectColor();
+var getUser = pouchdbUtils.toPromise(function (username, opts, callback) {
+ var db = this;
+ if (typeof callback === 'undefined') {
+ callback = typeof opts === 'undefined' ? username : opts;
+ opts = {};
+ }
+ if (!username) {
+ return callback(new AuthError('you must provide a username'));
+ }
- var args = Array.prototype.slice.call(arguments);
+ var url = getUsersUrl(db);
+ var ajaxOpts = pouchdbUtils.assign({
+ method: 'GET',
+ url: url + '/' + encodeURIComponent('org.couchdb.user:' + username),
+ headers: getBasicAuthHeaders(db),
+ }, opts.ajax || {});
+ ajaxCore(ajaxOpts, wrapError(callback));
+});
- args[0] = exports.coerce(args[0]);
+var putUser = pouchdbUtils.toPromise(function (username, opts, callback) {
+ var db = this;
+ if (typeof callback === 'undefined') {
+ callback = typeof opts === 'undefined' ? username : opts;
+ opts = {};
+ }
+ if (['http', 'https'].indexOf(db.type()) === -1) {
+ return callback(new AuthError('This plugin only works for the http/https adapter. ' +
+ 'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
+ } else if (!username) {
+ return callback(new AuthError('You must provide a username'));
+ }
- if ('string' !== typeof args[0]) {
- // anything else let's inspect with %o
- args = ['%o'].concat(args);
+ db.getUser(username, opts, function (error, user) {
+ if (error) {
+ return callback(error);
}
- // apply any `formatters` transformations
- var index = 0;
- args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {
- // if we encounter an escaped % then don't increase the array index
- if (match === '%%') return match;
- index++;
- var formatter = exports.formatters[format];
- if ('function' === typeof formatter) {
- var val = args[index];
- match = formatter.call(self, val);
+ updateUser(db, user, opts, callback);
+ });
+});
- // now we need to remove `args[index]` since it's inlined in the `format`
- args.splice(index, 1);
- index--;
- }
- return match;
- });
+var deleteUser = pouchdbUtils.toPromise(function (username, opts, callback) {
+ var db = this;
+ if (typeof callback === 'undefined') {
+ callback = typeof opts === 'undefined' ? username : opts;
+ opts = {};
+ }
+ if (['http', 'https'].indexOf(db.type()) === -1) {
+ return callback(new AuthError('This plugin only works for the http/https adapter. ' +
+ 'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
+ } else if (!username) {
+ return callback(new AuthError('You must provide a username'));
+ }
- if ('function' === typeof exports.formatArgs) {
- args = exports.formatArgs.apply(self, args);
+ db.getUser(username, opts, function (error, user) {
+ if (error) {
+ return callback(error);
}
- var logFn = enabled.log || exports.log || console.log.bind(console);
- logFn.apply(self, args);
+
+ var url = getUsersUrl(db) + '/' + encodeURIComponent(user._id) + '?rev=' + user._rev;
+ var ajaxOpts = pouchdbUtils.assign({
+ method: 'DELETE',
+ url: url,
+ headers: getBasicAuthHeaders(db),
+ }, opts.ajax || {});
+ ajaxCore(ajaxOpts, wrapError(callback));
+ });
+});
+
+var changePassword = pouchdbUtils.toPromise(function (username, password, opts, callback) {
+ var db = this;
+ if (typeof callback === 'undefined') {
+ callback = typeof opts === 'undefined' ? (typeof password === 'undefined' ?
+ username : password) : opts;
+ opts = {};
+ }
+ if (['http', 'https'].indexOf(db.type()) === -1) {
+ return callback(new AuthError('This plugin only works for the http/https adapter. ' +
+ 'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
+ } else if (!username) {
+ return callback(new AuthError('You must provide a username'));
+ } else if (!password) {
+ return callback(new AuthError('You must provide a password'));
}
- enabled.enabled = true;
- var fn = exports.enabled(namespace) ? enabled : disabled;
+ db.getUser(username, opts, function (error, user) {
+ if (error) {
+ return callback(error);
+ }
- fn.namespace = namespace;
+ user.password = password;
- return fn;
-}
+ var url = getUsersUrl(db) + '/' + encodeURIComponent(user._id);
+ var ajaxOpts = pouchdbUtils.assign({
+ method: 'PUT',
+ url: url,
+ headers: getBasicAuthHeaders(db),
+ body: user,
+ }, opts.ajax || {});
+ ajaxCore(ajaxOpts, wrapError(callback));
+ });
+});
-/**
- * Enables a debug mode by namespaces. This can include modes
- * separated by a colon and wildcards.
- *
- * @param {String} namespaces
- * @api public
- */
+var changeUsername = pouchdbUtils.toPromise(function (oldUsername, newUsername, opts, callback) {
+ var db = this;
+ var USERNAME_PREFIX = 'org.couchdb.user:';
+ var ajax = function (opts) {
+ return new Promise(function (resolve, reject) {
+ ajaxCore(opts, wrapError(function (err, res) {
+ if (err) {
+ return reject(err);
+ }
+ resolve(res);
+ }));
+ });
+ };
+ var updateUser = function (user, opts) {
+ var url = getUsersUrl(db) + '/' + encodeURIComponent(user._id);
+ var updateOpts = pouchdbUtils.assign({
+ method: 'PUT',
+ url: url,
+ headers: getBasicAuthHeaders(db),
+ body: user,
+ }, opts.ajax);
+ return ajax(updateOpts);
+ };
+ if (typeof callback === 'undefined') {
+ callback = opts;
+ opts = {};
+ }
+ opts.ajax = opts.ajax || {};
+ if (['http', 'https'].indexOf(db.type()) === -1) {
+ return callback(new AuthError('This plugin only works for the http/https adapter. ' +
+ 'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
+ }
+ if (!newUsername) {
+ return callback(new AuthError('You must provide a new username'));
+ }
+ if (!oldUsername) {
+ return callback(new AuthError('You must provide a username to rename'));
+ }
+
+ db.getUser(newUsername, opts)
+ .then(function () {
+ var error = new AuthError('user already exists');
+ error.taken = true;
+ throw error;
+ }, function () {
+ return db.getUser(oldUsername, opts);
+ })
+ .then(function (user) {
+ var newUser = pouchdbUtils.clone(user);
+ delete newUser._rev;
+ newUser._id = USERNAME_PREFIX + newUsername;
+ newUser.name = newUsername;
+ newUser.roles = opts.roles || user.roles || {};
+ return updateUser(newUser, opts).then(function () {
+ user._deleted = true;
+ return updateUser(user, opts);
+ });
+ }).then(function (res) {
+ callback(null, res);
+ }).catch(callback);
+});
-function enable(namespaces) {
- exports.save(namespaces);
+var plugin = {};
- var split = (namespaces || '').split(/[\s,]+/);
- var len = split.length;
+plugin.login = logIn;
+plugin.logIn = logIn;
+plugin.logout = logOut;
+plugin.logOut = logOut;
+plugin.getSession = getSession;
- for (var i = 0; i < len; i++) {
- if (!split[i]) continue; // ignore empty strings
- namespaces = split[i].replace(/\*/g, '.*?');
- if (namespaces[0] === '-') {
- exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
- } else {
- exports.names.push(new RegExp('^' + namespaces + '$'));
- }
- }
-}
+plugin.getMembership = getMembership;
+plugin.signUpAdmin = signUpAdmin;
+plugin.deleteAdmin = deleteAdmin;
-/**
- * Disable debug output.
- *
- * @api public
- */
+plugin.getUsersDatabaseUrl = getUsersDatabaseUrl;
+plugin.signup = signUp;
+plugin.signUp = signUp;
+plugin.getUser = getUser;
+plugin.putUser = putUser;
+plugin.deleteUser = deleteUser;
+plugin.changePassword = changePassword;
+plugin.changeUsername = changeUsername;
-function disable() {
- exports.enable('');
+if (typeof window !== 'undefined' && window.PouchDB) {
+ window.PouchDB.plugin(plugin);
}
-/**
- * Returns true if the given mode name is enabled, false otherwise.
- *
- * @param {String} name
- * @return {Boolean}
- * @api public
- */
+module.exports = plugin;
-function enabled(name) {
- var i, len;
- for (i = 0, len = exports.skips.length; i < len; i++) {
- if (exports.skips[i].test(name)) {
- return false;
- }
- }
- for (i = 0, len = exports.names.length; i < len; i++) {
- if (exports.names[i].test(name)) {
- return true;
- }
- }
- return false;
-}
+},{"10":10,"11":11,"15":15,"16":16,"5":5,"7":7,"9":9}],2:[function(require,module,exports){
+'use strict';
-/**
- * Coerce `val`.
- *
- * @param {Mixed} val
- * @return {Mixed}
- * @api private
- */
+module.exports = argsArray;
-function coerce(val) {
- if (val instanceof Error) return val.stack || val.message;
- return val;
+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, []);
+ }
+ };
}
-
-},{"10":10}],5:[function(require,module,exports){
+},{}],3:[function(require,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() {
- this._events = this._events || {};
+ 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.
-EventEmitter.defaultMaxListeners = 10;
+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(n) {
- if (!isNumber(n) || n < 0 || isNaN(n))
- throw TypeError('n must be a positive number');
+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;
};
-EventEmitter.prototype.emit = function(type) {
- var er, handler, len, args, i, listeners;
+function $getMaxListeners(that) {
+ if (that._maxListeners === undefined)
+ return EventEmitter.defaultMaxListeners;
+ return that._maxListeners;
+}
+
+EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
+ return $getMaxListeners(this);
+};
- if (!this._events)
- this._events = {};
+// 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 (type === 'error') {
- if (!this._events.error ||
- (isObject(this._events.error) && !this._events.error.length)) {
+ 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('Uncaught, unspecified "error" event. (' + er + ')');
- err.context = er;
- throw err;
- }
+ 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 = this._events[type];
+ handler = events[type];
- if (isUndefined(handler))
+ if (!handler)
return false;
- if (isFunction(handler)) {
- switch (arguments.length) {
+ var isFn = typeof handler === 'function';
+ len = arguments.length;
+ switch (len) {
// fast cases
- case 1:
- handler.call(this);
- break;
- case 2:
- handler.call(this, arguments[1]);
- break;
- case 3:
- handler.call(this, arguments[1], arguments[2]);
- break;
+ 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 = Array.prototype.slice.call(arguments, 1);
- handler.apply(this, args);
- }
- } else if (isObject(handler)) {
- args = Array.prototype.slice.call(arguments, 1);
- listeners = handler.slice();
- len = listeners.length;
- for (i = 0; i < len; i++)
- listeners[i].apply(this, args);
+ default:
+ args = new Array(len - 1);
+ for (i = 1; i < len; i++)
+ args[i - 1] = arguments[i];
+ emitMany(handler, isFn, this, args);
}
return true;
};
-EventEmitter.prototype.addListener = function(type, listener) {
+function _addListener(target, type, listener, prepend) {
var m;
+ var events;
+ var existing;
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
- if (!this._events)
- this._events = {};
+ 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);
- // To avoid recursion in the case that type === "newListener"! Before
- // adding it to the listeners, first emit "newListener".
- if (this._events.newListener)
- this.emit('newListener', type,
- isFunction(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 (!this._events[type])
+ if (!existing) {
// Optimize the case of one listener. Don't need the extra array object.
- this._events[type] = listener;
- else if (isObject(this._events[type]))
- // If we've already got an array, just append.
- this._events[type].push(listener);
- else
- // Adding the second element, need to change to array.
- this._events[type] = [this._events[type], listener];
-
- // Check for listener leak
- if (isObject(this._events[type]) && !this._events[type].warned) {
- if (!isUndefined(this._maxListeners)) {
- m = this._maxListeners;
+ 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 {
- m = EventEmitter.defaultMaxListeners;
- }
-
- if (m && m > 0 && this._events[type].length > m) {
- this._events[type].warned = true;
- console.error('(node) warning: possible EventEmitter memory ' +
- 'leak detected. %d listeners added. ' +
- 'Use emitter.setMaxListeners() to increase limit.',
- this._events[type].length);
- if (typeof console.trace === 'function') {
- // not supported in IE 10
- console.trace();
+ // 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 this;
+ return target;
+}
+
+EventEmitter.prototype.addListener = function addListener(type, listener) {
+ return _addListener(this, type, listener, false);
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
-EventEmitter.prototype.once = function(type, listener) {
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- var fired = false;
-
- function g() {
- this.removeListener(type, g);
+EventEmitter.prototype.prependListener =
+ function prependListener(type, listener) {
+ return _addListener(this, type, listener, true);
+ };
- if (!fired) {
- fired = true;
- listener.apply(this, arguments);
+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);
}
}
+}
- g.listener = listener;
- this.on(type, g);
+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;
};
-// emits a 'removeListener' event iff the listener was removed
-EventEmitter.prototype.removeListener = function(type, listener) {
- var list, position, length, i;
+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;
+ };
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
+// 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 (!this._events || !this._events[type])
- return this;
+ if (position < 0)
+ return this;
- list = this._events[type];
- length = list.length;
- position = -1;
-
- if (list === listener ||
- (isFunction(list.listener) && list.listener === listener)) {
- delete this._events[type];
- if (this._events.removeListener)
- this.emit('removeListener', type, listener);
-
- } else if (isObject(list)) {
- for (i = length; i-- > 0;) {
- if (list[i] === listener ||
- (list[i].listener && list[i].listener === listener)) {
- position = i;
- break;
+ 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);
}
- }
- if (position < 0)
return this;
+ };
- if (list.length === 1) {
- list.length = 0;
- delete this._events[type];
- } else {
- list.splice(position, 1);
- }
+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;
+ }
- if (this._events.removeListener)
- this.emit('removeListener', type, listener);
- }
+ // 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;
+ }
- return this;
-};
+ listeners = events[type];
-EventEmitter.prototype.removeAllListeners = function(type) {
- var key, listeners;
+ 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]);
+ }
+ }
- if (!this._events)
- return this;
+ return this;
+ };
- // not listening for removeListener, no need to emit
- if (!this._events.removeListener) {
- if (arguments.length === 0)
- this._events = {};
- else if (this._events[type])
- delete this._events[type];
- return this;
- }
+EventEmitter.prototype.listeners = function listeners(type) {
+ var evlistener;
+ var ret;
+ var events = this._events;
- // emit removeListener for all listeners on all events
- if (arguments.length === 0) {
- for (key in this._events) {
- if (key === 'removeListener') continue;
- this.removeAllListeners(key);
- }
- this.removeAllListeners('removeListener');
- this._events = {};
- return this;
+ if (!events)
+ ret = [];
+ else {
+ evlistener = events[type];
+ if (!evlistener)
+ ret = [];
+ else if (typeof evlistener === 'function')
+ ret = [evlistener.listener || evlistener];
+ else
+ ret = unwrapListeners(evlistener);
}
- listeners = this._events[type];
+ return ret;
+};
- if (isFunction(listeners)) {
- this.removeListener(type, listeners);
- } else if (listeners) {
- // LIFO order
- while (listeners.length)
- this.removeListener(type, listeners[listeners.length - 1]);
+EventEmitter.listenerCount = function(emitter, type) {
+ if (typeof emitter.listenerCount === 'function') {
+ return emitter.listenerCount(type);
+ } else {
+ return listenerCount.call(emitter, type);
}
- delete this._events[type];
-
- return this;
};
-EventEmitter.prototype.listeners = function(type) {
- var ret;
- if (!this._events || !this._events[type])
- ret = [];
- else if (isFunction(this._events[type]))
- ret = [this._events[type]];
- else
- ret = this._events[type].slice();
- return ret;
-};
+EventEmitter.prototype.listenerCount = listenerCount;
+function listenerCount(type) {
+ var events = this._events;
-EventEmitter.prototype.listenerCount = function(type) {
- if (this._events) {
- var evlistener = this._events[type];
+ if (events) {
+ var evlistener = events[type];
- if (isFunction(evlistener))
+ if (typeof evlistener === 'function') {
return 1;
- else if (evlistener)
+ } else if (evlistener) {
return evlistener.length;
+ }
}
+
return 0;
-};
+}
-EventEmitter.listenerCount = function(emitter, type) {
- return emitter.listenerCount(type);
+EventEmitter.prototype.eventNames = function eventNames() {
+ return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];
};
-function isFunction(arg) {
- return typeof arg === 'function';
+// 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 isNumber(arg) {
- return typeof arg === 'number';
+function arrayClone(arr, n) {
+ var copy = new Array(n);
+ for (var i = 0; i < n; ++i)
+ copy[i] = arr[i];
+ return copy;
}
-function isObject(arg) {
- return typeof arg === 'object' && arg !== null;
+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 isUndefined(arg) {
- return arg === void 0;
+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);
+ };
}
-},{}],6:[function(require,module,exports){
+},{}],4:[function(require,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 : {})
-},{}],7:[function(require,module,exports){
+},{}],5:[function(require,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
}
}
-},{}],8:[function(require,module,exports){
-(function(factory) {
- if(typeof exports === 'object') {
- factory(exports);
- } else {
- factory(this);
- }
-}).call(this, function(root) {
-
- var slice = Array.prototype.slice,
- each = Array.prototype.forEach;
-
- var extend = function(obj) {
- if(typeof obj !== 'object') throw obj + ' is not an object' ;
-
- var sources = slice.call(arguments, 1);
-
- each.call(sources, function(source) {
- if(source) {
- for(var prop in source) {
- if(typeof source[prop] === 'object' && obj[prop]) {
- extend.call(obj, obj[prop], source[prop]);
- } else {
- obj[prop] = source[prop];
- }
- }
- }
- });
-
- return obj;
- }
-
- root.extend = extend;
-});
-
-},{}],9:[function(require,module,exports){
+},{}],6:[function(require,module,exports){
'use strict';
-var immediate = require(6);
+var immediate = require(4);
/* istanbul ignore next */
function INTERNAL() {}
var handlers = {};
var REJECTED = ['REJECTED'];
var FULFILLED = ['FULFILLED'];
var PENDING = ['PENDING'];
module.exports = Promise;
function Promise(resolver) {
if (typeof resolver !== 'function') {
throw new TypeError('resolver must be a function');
}
this.state = PENDING;
this.queue = [];
this.outcome = void 0;
if (resolver !== INTERNAL) {
safelyResolveThenable(this, resolver);
}
}
Promise.prototype["catch"] = function (onRejected) {
return this.then(null, onRejected);
};
Promise.prototype.then = function (onFulfilled, onRejected) {
if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
typeof onRejected !== 'function' && this.state === REJECTED) {
return this;
}
var promise = new this.constructor(INTERNAL);
if (this.state !== PENDING) {
var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
unwrap(promise, resolver, this.outcome);
} else {
this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
}
return promise;
};
function QueueItem(promise, onFulfilled, onRejected) {
this.promise = promise;
if (typeof onFulfilled === 'function') {
this.onFulfilled = onFulfilled;
this.callFulfilled = this.otherCallFulfilled;
}
if (typeof onRejected === 'function') {
this.onRejected = onRejected;
this.callRejected = this.otherCallRejected;
}
}
QueueItem.prototype.callFulfilled = function (value) {
handlers.resolve(this.promise, value);
};
QueueItem.prototype.otherCallFulfilled = function (value) {
unwrap(this.promise, this.onFulfilled, value);
};
QueueItem.prototype.callRejected = function (value) {
handlers.reject(this.promise, value);
};
QueueItem.prototype.otherCallRejected = function (value) {
unwrap(this.promise, this.onRejected, value);
};
function unwrap(promise, func, value) {
immediate(function () {
var returnValue;
try {
returnValue = func(value);
} catch (e) {
return handlers.reject(promise, e);
}
if (returnValue === promise) {
handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));
} else {
handlers.resolve(promise, returnValue);
}
});
}
handlers.resolve = function (self, value) {
var result = tryCatch(getThen, value);
if (result.status === 'error') {
return handlers.reject(self, result.value);
}
var thenable = result.value;
if (thenable) {
safelyResolveThenable(self, thenable);
} else {
self.state = FULFILLED;
self.outcome = value;
var i = -1;
var len = self.queue.length;
while (++i < len) {
self.queue[i].callFulfilled(value);
}
}
return self;
};
handlers.reject = function (self, error) {
self.state = REJECTED;
self.outcome = error;
var i = -1;
var len = self.queue.length;
while (++i < len) {
self.queue[i].callRejected(error);
}
return self;
};
function getThen(obj) {
// Make sure we only access the accessor once as required by the spec
var then = obj && obj.then;
- if (obj && typeof obj === 'object' && typeof then === 'function') {
+ if (obj && (typeof obj === 'object' || typeof obj === 'function') && typeof then === 'function') {
return function appyThen() {
then.apply(obj, arguments);
};
}
}
function safelyResolveThenable(self, thenable) {
// Either fulfill, reject or reject with error
var called = false;
function onError(value) {
if (called) {
return;
}
called = true;
handlers.reject(self, value);
}
function onSuccess(value) {
if (called) {
return;
}
called = true;
handlers.resolve(self, value);
}
function tryToUnwrap() {
thenable(onSuccess, onError);
}
var result = tryCatch(tryToUnwrap);
if (result.status === 'error') {
onError(result.value);
}
}
function tryCatch(func, value) {
var out = {};
try {
out.value = func(value);
out.status = 'success';
} catch (e) {
out.status = 'error';
out.value = e;
}
return out;
}
Promise.resolve = resolve;
function resolve(value) {
if (value instanceof this) {
return value;
}
return handlers.resolve(new this(INTERNAL), value);
}
Promise.reject = reject;
function reject(reason) {
var promise = new this(INTERNAL);
return handlers.reject(promise, reason);
}
Promise.all = all;
function all(iterable) {
var self = this;
if (Object.prototype.toString.call(iterable) !== '[object Array]') {
return this.reject(new TypeError('must be an array'));
}
var len = iterable.length;
var called = false;
if (!len) {
return this.resolve([]);
}
var values = new Array(len);
var resolved = 0;
var i = -1;
var promise = new this(INTERNAL);
while (++i < len) {
allResolver(iterable[i], i);
}
return promise;
function allResolver(value, i) {
self.resolve(value).then(resolveFromAll, function (error) {
if (!called) {
called = true;
handlers.reject(promise, error);
}
});
function resolveFromAll(outValue) {
values[i] = outValue;
if (++resolved === len && !called) {
called = true;
handlers.resolve(promise, values);
}
}
}
}
Promise.race = race;
function race(iterable) {
var self = this;
if (Object.prototype.toString.call(iterable) !== '[object Array]') {
return this.reject(new TypeError('must be an array'));
}
var len = iterable.length;
var called = false;
if (!len) {
return this.resolve([]);
}
var i = -1;
var promise = new this(INTERNAL);
while (++i < len) {
resolver(iterable[i]);
}
return promise;
function resolver(value) {
self.resolve(value).then(function (response) {
if (!called) {
called = true;
handlers.resolve(promise, response);
}
}, function (error) {
if (!called) {
called = true;
handlers.reject(promise, error);
}
});
}
}
-},{"6":6}],10:[function(require,module,exports){
-/**
- * Helpers.
- */
-
-var s = 1000;
-var m = s * 60;
-var h = m * 60;
-var d = h * 24;
-var y = d * 365.25;
-
-/**
- * Parse or format the given `val`.
- *
- * Options:
- *
- * - `long` verbose formatting [false]
- *
- * @param {String|Number} val
- * @param {Object} options
- * @return {String|Number}
- * @api public
- */
-
-module.exports = function(val, options){
- options = options || {};
- if ('string' == typeof val) return parse(val);
- return options.long
- ? long(val)
- : short(val);
-};
-
-/**
- * Parse the given `str` and return milliseconds.
- *
- * @param {String} str
- * @return {Number}
- * @api private
- */
-
-function parse(str) {
- str = '' + str;
- if (str.length > 10000) return;
- var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);
- if (!match) return;
- var n = parseFloat(match[1]);
- var type = (match[2] || 'ms').toLowerCase();
- switch (type) {
- case 'years':
- case 'year':
- case 'yrs':
- case 'yr':
- case 'y':
- return n * y;
- case 'days':
- case 'day':
- case 'd':
- return n * d;
- case 'hours':
- case 'hour':
- case 'hrs':
- case 'hr':
- case 'h':
- return n * h;
- case 'minutes':
- case 'minute':
- case 'mins':
- case 'min':
- case 'm':
- return n * m;
- case 'seconds':
- case 'second':
- case 'secs':
- case 'sec':
- case 's':
- return n * s;
- case 'milliseconds':
- case 'millisecond':
- case 'msecs':
- case 'msec':
- case 'ms':
- return n;
- }
-}
-
-/**
- * Short format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function short(ms) {
- if (ms >= d) return Math.round(ms / d) + 'd';
- if (ms >= h) return Math.round(ms / h) + 'h';
- if (ms >= m) return Math.round(ms / m) + 'm';
- if (ms >= s) return Math.round(ms / s) + 's';
- return ms + 'ms';
-}
-
-/**
- * Long format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function long(ms) {
- return plural(ms, d, 'day')
- || plural(ms, h, 'hour')
- || plural(ms, m, 'minute')
- || plural(ms, s, 'second')
- || ms + ' ms';
-}
-
-/**
- * Pluralization helper.
- */
-
-function plural(ms, n, name) {
- if (ms < n) return;
- if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
- return Math.ceil(ms / n) + ' ' + name + 's';
-}
-
-},{}],11:[function(require,module,exports){
+},{"4":4}],7:[function(require,module,exports){
'use strict';
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
-var lie = _interopDefault(require(9));
-var jsExtend = require(8);
-var inherits = _interopDefault(require(7));
-var getArguments = _interopDefault(require(2));
-var debug = _interopDefault(require(3));
-var events = require(5);
-
-// 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);
- }
-}
-
-// simplified API. universal browser support is assumed
-function readAsArrayBuffer(blob, callback) {
- if (typeof FileReader === 'undefined') {
- // fix for Firefox in a web worker:
- // https://bugzilla.mozilla.org/show_bug.cgi?id=901097
- return callback(new FileReaderSync().readAsArrayBuffer(blob));
- }
-
- var reader = new FileReader();
- reader.onloadend = function (e) {
- var result = e.target.result || new ArrayBuffer(0);
- callback(result);
- };
- reader.readAsArrayBuffer(blob);
-}
-
-/* istanbul ignore next */
-var PouchPromise = typeof Promise === 'function' ? Promise : lie;
+var pouchdbUtils = require(11);
+var Promise = _interopDefault(require(10));
+var pouchdbBinaryUtils = require(9);
+var pouchdbErrors = require(8);
/* global fetch */
/* global Headers */
function wrappedFetch() {
var wrappedPromise = {};
- var promise = new PouchPromise(function (resolve, reject) {
+ var promise = new Promise(function (resolve, reject) {
wrappedPromise.resolve = resolve;
wrappedPromise.reject = reject;
});
var args = new Array(arguments.length);
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i];
}
wrappedPromise.promise = promise;
- PouchPromise.resolve().then(function () {
+ Promise.resolve().then(function () {
return fetch.apply(null, args);
}).then(function (response) {
wrappedPromise.resolve(response);
}).catch(function (error) {
wrappedPromise.reject(error);
});
return wrappedPromise;
}
function fetchRequest(options, callback) {
var wrappedPromise, timer, response;
var headers = new Headers();
var fetchOptions = {
method: options.method,
credentials: 'include',
headers: headers
};
if (options.json) {
headers.set('Accept', 'application/json');
headers.set('Content-Type', options.headers['Content-Type'] ||
'application/json');
}
- if (options.body && (options.body instanceof Blob)) {
- readAsArrayBuffer(options.body, function (arrayBuffer) {
- fetchOptions.body = arrayBuffer;
- });
- } else if (options.body &&
- options.processData &&
- typeof options.body !== 'string') {
+ if (options.body &&
+ options.processData &&
+ typeof options.body !== 'string') {
fetchOptions.body = JSON.stringify(options.body);
} else if ('body' in options) {
fetchOptions.body = options.body;
} else {
fetchOptions.body = null;
}
Object.keys(options.headers).forEach(function (key) {
if (options.headers.hasOwnProperty(key)) {
headers.set(key, options.headers[key]);
}
});
wrappedPromise = wrappedFetch(options.url, fetchOptions);
if (options.timeout > 0) {
timer = setTimeout(function () {
wrappedPromise.reject(new Error('Load timeout for resource: ' +
options.url));
}, options.timeout);
}
wrappedPromise.promise.then(function (fetchResponse) {
response = {
statusCode: fetchResponse.status
};
if (options.timeout > 0) {
clearTimeout(timer);
}
if (response.statusCode >= 200 && response.statusCode < 300) {
return options.binary ? fetchResponse.blob() : fetchResponse.text();
}
return fetchResponse.json();
}).then(function (result) {
if (response.statusCode >= 200 && response.statusCode < 300) {
callback(null, response, result);
} else {
- callback(result, response);
+ result.status = response.statusCode;
+ callback(result);
}
}).catch(function (error) {
- callback(error, response);
+ if (!error) {
+ // this happens when the listener is canceled
+ error = new Error('canceled');
+ }
+ callback(error);
});
return {abort: wrappedPromise.reject};
}
function xhRequest(options, callback) {
var xhr, timer;
var timedout = false;
var abortReq = function () {
xhr.abort();
cleanUp();
};
var timeoutReq = function () {
timedout = true;
xhr.abort();
cleanUp();
};
var ret = {abort: abortReq};
var cleanUp = function () {
clearTimeout(timer);
ret.abort = function () {};
if (xhr) {
xhr.onprogress = undefined;
if (xhr.upload) {
xhr.upload.onprogress = undefined;
}
xhr.onreadystatechange = undefined;
xhr = undefined;
}
};
if (options.xhr) {
xhr = new options.xhr();
} else {
xhr = new XMLHttpRequest();
}
try {
xhr.open(options.method, options.url);
} catch (exception) {
return callback(new Error(exception.name || 'Url is invalid'));
}
xhr.withCredentials = ('withCredentials' in options) ?
options.withCredentials : true;
if (options.method === 'GET') {
delete options.headers['Content-Type'];
} else if (options.json) {
options.headers.Accept = 'application/json';
options.headers['Content-Type'] = options.headers['Content-Type'] ||
'application/json';
if (options.body &&
options.processData &&
typeof options.body !== "string") {
options.body = JSON.stringify(options.body);
}
}
if (options.binary) {
xhr.responseType = 'arraybuffer';
}
if (!('body' in options)) {
options.body = null;
}
for (var key in options.headers) {
if (options.headers.hasOwnProperty(key)) {
xhr.setRequestHeader(key, options.headers[key]);
}
}
if (options.timeout > 0) {
timer = setTimeout(timeoutReq, options.timeout);
xhr.onprogress = function () {
clearTimeout(timer);
- if(xhr.readyState !== 4) {
+ if (xhr.readyState !== 4) {
timer = setTimeout(timeoutReq, options.timeout);
}
};
if (typeof xhr.upload !== 'undefined') { // does not exist in ie9
xhr.upload.onprogress = xhr.onprogress;
}
}
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) {
return;
}
var response = {
statusCode: xhr.status
};
if (xhr.status >= 200 && xhr.status < 300) {
var data;
if (options.binary) {
- data = createBlob([xhr.response || ''], {
+ data = pouchdbBinaryUtils.blob([xhr.response || ''], {
type: xhr.getResponseHeader('Content-Type')
});
} else {
data = xhr.responseText;
}
callback(null, response, data);
} else {
var err = {};
if (timedout) {
err = new Error('ETIMEDOUT');
err.code = 'ETIMEDOUT';
} else if (typeof xhr.response === 'string') {
try {
err = JSON.parse(xhr.response);
- } catch(e) {}
+ } catch (e) {}
}
err.status = xhr.status;
callback(err);
}
cleanUp();
};
if (options.body && (options.body instanceof Blob)) {
- readAsArrayBuffer(options.body, function (arrayBuffer) {
+ pouchdbBinaryUtils.readAsArrayBuffer(options.body, function (arrayBuffer) {
xhr.send(arrayBuffer);
});
} else {
xhr.send(options.body);
}
- return ret;
-}
-
-function testXhr() {
- try {
- new XMLHttpRequest();
- return true;
- } catch (err) {
- return false;
- }
-}
-
-var hasXhr = testXhr();
-
-function ajax$1(options, callback) {
- if (hasXhr || options.xhr) {
- return xhRequest(options, callback);
- } else {
- return fetchRequest(options, callback);
- }
-}
-
-inherits(PouchError, Error);
-
-function PouchError(opts) {
- Error.call(this, opts.reason);
- this.status = opts.status;
- this.name = opts.error;
- this.message = opts.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({
- status: 401,
- error: 'unauthorized',
- reason: "Name or password is incorrect."
-});
-
-var MISSING_BULK_DOCS = new PouchError({
- status: 400,
- error: 'bad_request',
- reason: "Missing JSON list of 'docs'"
-});
-
-var MISSING_DOC = new PouchError({
- status: 404,
- error: 'not_found',
- reason: 'missing'
-});
-
-var REV_CONFLICT = new PouchError({
- status: 409,
- error: 'conflict',
- reason: 'Document update conflict'
-});
-
-var INVALID_ID = new PouchError({
- status: 400,
- error: 'bad_request',
- reason: '_id field must contain a string'
-});
-
-var MISSING_ID = new PouchError({
- status: 412,
- error: 'missing_id',
- reason: '_id is required for puts'
-});
-
-var RESERVED_ID = new PouchError({
- status: 400,
- error: 'bad_request',
- reason: 'Only reserved document ids may start with underscore.'
-});
-
-var NOT_OPEN = new PouchError({
- status: 412,
- error: 'precondition_failed',
- reason: 'Database not open'
-});
-
-var UNKNOWN_ERROR = new PouchError({
- status: 500,
- error: 'unknown_error',
- reason: 'Database encountered an unknown error'
-});
-
-var BAD_ARG = new PouchError({
- status: 500,
- error: 'badarg',
- reason: 'Some query argument is invalid'
-});
-
-var INVALID_REQUEST = new PouchError({
- status: 400,
- error: 'invalid_request',
- reason: 'Request was invalid'
-});
-
-var QUERY_PARSE_ERROR = new PouchError({
- status: 400,
- error: 'query_parse_error',
- reason: 'Some query parameter is invalid'
-});
-
-var DOC_VALIDATION = new PouchError({
- status: 500,
- error: 'doc_validation',
- reason: 'Bad special document member'
-});
-
-var BAD_REQUEST = new PouchError({
- status: 400,
- error: 'bad_request',
- reason: 'Something wrong with the request'
-});
-
-var NOT_AN_OBJECT = new PouchError({
- status: 400,
- error: 'bad_request',
- reason: 'Document must be a JSON object'
-});
-
-var DB_MISSING = new PouchError({
- status: 404,
- error: 'not_found',
- reason: 'Database not found'
-});
-
-var IDB_ERROR = new PouchError({
- status: 500,
- error: 'indexed_db_went_bad',
- reason: 'unknown'
-});
-
-var WSQ_ERROR = new PouchError({
- status: 500,
- error: 'web_sql_went_bad',
- reason: 'unknown'
-});
-
-var LDB_ERROR = new PouchError({
- status: 500,
- error: 'levelDB_went_went_bad',
- reason: 'unknown'
-});
-
-var FORBIDDEN = new PouchError({
- status: 403,
- error: 'forbidden',
- reason: 'Forbidden by design doc validate_doc_update function'
-});
-
-var INVALID_REV = new PouchError({
- status: 400,
- error: 'bad_request',
- reason: 'Invalid rev format'
-});
-
-var FILE_EXISTS = new PouchError({
- status: 412,
- error: 'file_exists',
- reason: 'The database could not be created, the file already exists.'
-});
-
-var MISSING_STUB = new PouchError({
- status: 412,
- error: 'missing_stub'
-});
-
-var INVALID_URL = new PouchError({
- status: 413,
- error: 'invalid_url',
- reason: 'Provided URL is invalid'
-});
-
-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 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;
-}
-
-var log = debug('pouchdb:api');
-
-// 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;
-}
-
-function isChromeApp() {
- return (typeof chrome !== "undefined" &&
- typeof chrome.storage !== "undefined" &&
- typeof chrome.storage.local !== "undefined");
-}
-
-var hasLocal;
-
-if (isChromeApp()) {
- hasLocal = false;
-} else {
- try {
- localStorage.setItem('_pouch_check_localstorage', 1);
- hasLocal = !!localStorage.getItem('_pouch_check_localstorage');
- } catch (e) {
- hasLocal = false;
- }
-}
-
-function hasLocalStorage() {
- return hasLocal;
-}
-
-inherits(Changes, events.EventEmitter);
-
-/* istanbul ignore next */
-function attachBrowserEvents(self) {
- if (isChromeApp()) {
- chrome.storage.onChanged.addListener(function (e) {
- // make sure it's event addressed to us
- if (e.db_name != null) {
- //object only has oldValue, newValue members
- self.emit(e.dbName.newValue);
- }
- });
- } else if (hasLocalStorage()) {
- if (typeof addEventListener !== 'undefined') {
- addEventListener("storage", function (e) {
- self.emit(e.key);
- });
- } else { // old IE
- window.attachEvent("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'
- ]);
-
- /* 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') {
- setTimeout(function (){
- eventFunction();
- },0);
- }
- 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 (isChromeApp()) {
- chrome.storage.local.set({dbName: dbName});
- } else if (hasLocalStorage()) {
- localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
- }
-};
-
-Changes.prototype.notify = function (dbName) {
- this.emit(dbName);
- this.notifyLocalWindows(dbName);
-};
-
-// BEGIN Math.uuid.js
+ return ret;
+}
-/*!
-Math.uuid.js (v1.4)
-http://www.broofa.com
-mailto:robert@broofa.com
+function testXhr() {
+ try {
+ new XMLHttpRequest();
+ return true;
+ } catch (err) {
+ return false;
+ }
+}
-Copyright (c) 2010 Robert Kieffer
-Dual licensed under the MIT and GPL licenses.
-*/
+var hasXhr = testXhr();
-/*
- * Generate a random uuid.
- *
- * USAGE: Math.uuid(length, radix)
- * length - the desired number of characters
- * radix - the number of allowable values for each character.
- *
- * EXAMPLES:
- * // No arguments - returns RFC4122, version 4 ID
- * >>> Math.uuid()
- * "92329D39-6F5C-4520-ABFC-AAB64544E172"
- *
- * // One argument - returns ID of the specified length
- * >>> Math.uuid(15) // 15 character ID (default base=62)
- * "VcydxgltxrVZSTV"
- *
- * // Two arguments - returns ID of the specified length, and radix.
- * // (Radix must be <= 62)
- * >>> Math.uuid(8, 2) // 8 character ID (base=2)
- * "01001010"
- * >>> Math.uuid(8, 10) // 8 character ID (base=10)
- * "47473046"
- * >>> Math.uuid(8, 16) // 8 character ID (base=16)
- * "098F4D35"
- */
-var chars = (
- '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
- 'abcdefghijklmnopqrstuvwxyz'
-).split('');
+function ajax$1(options, callback) {
+ if (!false && (hasXhr || options.xhr)) {
+ return xhRequest(options, callback);
+ } else {
+ return fetchRequest(options, callback);
+ }
+}
// the blob already has a type; do nothing
-var res$2 = function () {};
function defaultBody() {
return '';
}
function ajaxCore(options, callback) {
- options = clone(options);
+ options = pouchdbUtils.clone(options);
var defaultOptions = {
method : "GET",
headers: {},
json: true,
processData: true,
timeout: 10000,
cache: false
};
- options = jsExtend.extend(defaultOptions, options);
+ options = pouchdbUtils.assign(defaultOptions, options);
function onSuccess(obj, resp, cb) {
if (!options.binary && options.json && typeof obj === 'string') {
/* istanbul ignore next */
try {
obj = JSON.parse(obj);
} catch (e) {
// Probably a malformed JSON from server
return cb(e);
}
}
if (Array.isArray(obj)) {
obj = obj.map(function (v) {
if (v.error || v.missing) {
- return generateErrorFromResponse(v);
+ return pouchdbErrors.generateErrorFromResponse(v);
} else {
return v;
}
});
}
if (options.binary) {
- res$2(obj, resp);
+
}
cb(null, obj, resp);
}
if (options.json) {
if (!options.binary) {
options.headers.Accept = 'application/json';
}
options.headers['Content-Type'] = options.headers['Content-Type'] ||
'application/json';
}
if (options.binary) {
options.encoding = null;
options.json = false;
}
if (!options.processData) {
options.json = false;
}
return ajax$1(options, function (err, response, body) {
if (err) {
- return callback(generateErrorFromResponse(err));
+ return callback(pouchdbErrors.generateErrorFromResponse(err));
}
var error;
var content_type = response.headers && response.headers['content-type'];
var data = body || defaultBody();
// CouchDB doesn't always return the right content-type for JSON data, so
// we check for ^{ and }$ (ignoring leading/trailing whitespace)
if (!options.binary && (options.json || !options.processData) &&
typeof data !== 'object' &&
(/json/.test(content_type) ||
(/^[\s]*\{/.test(data) && /\}[\s]*$/.test(data)))) {
try {
data = JSON.parse(data.toString());
} catch (e) {}
}
if (response.statusCode >= 200 && response.statusCode < 300) {
onSuccess(data, response, callback);
} else {
- error = generateErrorFromResponse(data);
+ error = pouchdbErrors.generateErrorFromResponse(data);
error.status = response.statusCode;
callback(error);
}
});
}
function ajax(opts, callback) {
// cache-buster, specifically designed to work around IE's aggressive caching
// see http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/
// Also Safari caches POSTs, so we need to cache-bust those too.
var ua = (navigator && navigator.userAgent) ?
navigator.userAgent.toLowerCase() : '';
var isSafari = ua.indexOf('safari') !== -1 && ua.indexOf('chrome') === -1;
var isIE = ua.indexOf('msie') !== -1;
+ var isTrident = ua.indexOf('trident') !== -1;
var isEdge = ua.indexOf('edge') !== -1;
// it appears the new version of safari also caches GETs,
// see https://github.com/pouchdb/pouchdb/issues/5010
var shouldCacheBust = (isSafari ||
- ((isIE || isEdge) && opts.method === 'GET'));
+ ((isIE || isTrident || isEdge) && opts.method === 'GET'));
var cache = 'cache' in opts ? opts.cache : true;
var isBlobUrl = /^blob:/.test(opts.url); // don't append nonces for blob URLs
if (!isBlobUrl && (shouldCacheBust || !cache)) {
var hasArgs = opts.url.indexOf('?') !== -1;
opts.url += (hasArgs ? '&' : '?') + '_nonce=' + Date.now();
}
return ajaxCore(opts, callback);
}
module.exports = ajax;
-},{"2":2,"3":3,"5":5,"7":7,"8":8,"9":9}],12:[function(require,module,exports){
-"use strict";
-// Extends method
-// (taken from http://code.jquery.com/jquery-1.9.0.js)
-// Populate the class2type map
-var class2type = {};
+},{"10":10,"11":11,"8":8,"9":9}],8:[function(require,module,exports){
+'use strict';
-var types = [
- "Boolean", "Number", "String", "Function", "Array",
- "Date", "RegExp", "Object", "Error"
-];
-for (var i = 0; i < types.length; i++) {
- var typename = types[i];
- class2type["[object " + typename + "]"] = typename.toLowerCase();
+Object.defineProperty(exports, '__esModule', { value: true });
+
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+var inherits = _interopDefault(require(5));
+
+inherits(PouchError, Error);
+
+function PouchError(status, error, reason) {
+ Error.call(this, reason);
+ this.status = status;
+ this.name = error;
+ this.message = reason;
+ this.error = true;
}
-var core_toString = class2type.toString;
-var core_hasOwn = class2type.hasOwnProperty;
+PouchError.prototype.toString = function () {
+ return JSON.stringify({
+ status: this.status,
+ name: this.name,
+ message: this.message,
+ reason: this.reason
+ });
+};
-function type(obj) {
- if (obj === null) {
- return String(obj);
+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;
+ }
}
- return typeof obj === "object" || typeof obj === "function" ?
- class2type[core_toString.call(obj)] || "object" :
- typeof obj;
+ CustomPouchError.prototype = PouchError.prototype;
+ return new CustomPouchError(reason);
}
-function isWindow(obj) {
- return obj !== null && obj === obj.window;
-}
+function generateErrorFromResponse(err) {
-function isPlainObject(obj) {
- // Must be an Object.
- // Because of IE, we also have to check the presence of
- // the constructor property.
- // Make sure that DOM nodes and window objects don't pass through, as well
- if (!obj || type(obj) !== "object" || obj.nodeType || isWindow(obj)) {
- return false;
+ if (typeof err !== 'object') {
+ var data = err;
+ err = UNKNOWN_ERROR;
+ err.data = data;
}
- try {
- // Not own constructor property must be Object
- if (obj.constructor &&
- !core_hasOwn.call(obj, "constructor") &&
- !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
- return false;
- }
- } catch ( e ) {
- // IE8,9 Will throw exceptions on certain host objects #9897
- return false;
+ if ('error' in err && err.error === 'conflict') {
+ err.name = 'conflict';
+ err.status = 409;
}
- // Own properties are enumerated firstly, so to speed up,
- // if last one is own, then all properties are own.
- var key;
- for (key in obj) {}
+ if (!('name' in err)) {
+ err.name = err.error || 'unknown';
+ }
- return key === undefined || core_hasOwn.call(obj, key);
-}
+ if (!('status' in err)) {
+ err.status = 500;
+ }
+ if (!('message' in err)) {
+ err.message = err.message || err.reason;
+ }
-function isFunction(obj) {
- return type(obj) === "function";
+ return err;
}
-var isArray = Array.isArray || function (obj) {
- return type(obj) === "array";
+exports.UNAUTHORIZED = UNAUTHORIZED;
+exports.MISSING_BULK_DOCS = MISSING_BULK_DOCS;
+exports.MISSING_DOC = MISSING_DOC;
+exports.REV_CONFLICT = REV_CONFLICT;
+exports.INVALID_ID = INVALID_ID;
+exports.MISSING_ID = MISSING_ID;
+exports.RESERVED_ID = RESERVED_ID;
+exports.NOT_OPEN = NOT_OPEN;
+exports.UNKNOWN_ERROR = UNKNOWN_ERROR;
+exports.BAD_ARG = BAD_ARG;
+exports.INVALID_REQUEST = INVALID_REQUEST;
+exports.QUERY_PARSE_ERROR = QUERY_PARSE_ERROR;
+exports.DOC_VALIDATION = DOC_VALIDATION;
+exports.BAD_REQUEST = BAD_REQUEST;
+exports.NOT_AN_OBJECT = NOT_AN_OBJECT;
+exports.DB_MISSING = DB_MISSING;
+exports.WSQ_ERROR = WSQ_ERROR;
+exports.LDB_ERROR = LDB_ERROR;
+exports.FORBIDDEN = FORBIDDEN;
+exports.INVALID_REV = INVALID_REV;
+exports.FILE_EXISTS = FILE_EXISTS;
+exports.MISSING_STUB = MISSING_STUB;
+exports.IDB_ERROR = IDB_ERROR;
+exports.INVALID_URL = INVALID_URL;
+exports.createError = createError;
+exports.generateErrorFromResponse = generateErrorFromResponse;
+
+},{"5":5}],9:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+var thisAtob = function (str) {
+ return atob(str);
};
-function extend() {
- // originally extend() was recursive, but this ended up giving us
- // "call stack exceeded", so it's been unrolled to use a literal stack
- // (see https://github.com/pouchdb/pouchdb/issues/2543)
- var stack = [];
- var i = -1;
- var len = arguments.length;
- var args = new Array(len);
- while (++i < len) {
- args[i] = arguments[i];
+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);
}
- var container = {};
- stack.push({args: args, result: {container: container, key: 'key'}});
- var next;
- while ((next = stack.pop())) {
- extendInner(stack, next.args, next.result);
- }
- return container.key;
-}
-
-function extendInner(stack, args, result) {
- var options, name, src, copy, copyIsArray, clone,
- target = args[0] || {},
- i = 1,
- length = args.length,
- deep = false,
- numericStringRegex = /\d+/,
- optionsIsArray;
-
- // Handle a deep copy situation
- if (typeof target === "boolean") {
- deep = target;
- target = args[1] || {};
- // skip the boolean and the target
- i = 2;
- }
-
- // Handle case when target is a string or something (possible in deep copy)
- if (typeof target !== "object" && !isFunction(target)) {
- target = {};
- }
-
- // extend jQuery itself if only one argument is passed
- if (length === i) {
- /* jshint validthis: true */
- target = this;
- --i;
- }
-
- for (; i < length; i++) {
- // Only deal with non-null/undefined values
- if ((options = args[i]) != null) {
- optionsIsArray = isArray(options);
- // Extend the base object
- for (name in options) {
- //if (options.hasOwnProperty(name)) {
- if (!(name in Object.prototype)) {
- if (optionsIsArray && !numericStringRegex.test(name)) {
- continue;
- }
+}
- src = target[name];
- copy = options[name];
+// 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;
+}
- // Prevent never-ending loop
- if (target === copy) {
- continue;
- }
+function binStringToBluffer(binString, type) {
+ return createBlob([binaryStringToArrayBuffer(binString)], {type: type});
+}
- // Recurse if we're merging plain objects or arrays
- if (deep && copy && (isPlainObject(copy) ||
- (copyIsArray = isArray(copy)))) {
- if (copyIsArray) {
- copyIsArray = false;
- clone = src && isArray(src) ? src : [];
+function b64ToBluffer(b64, type) {
+ return binStringToBluffer(thisAtob(b64), type);
+}
- } else {
- clone = src && isPlainObject(src) ? src : {};
- }
+//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;
+}
- // Never move original objects, clone them
- stack.push({
- args: [deep, clone, copy],
- result: {
- container: target,
- key: name
- }
- });
-
- // Don't bring in undefined values
- } else if (copy !== undefined) {
- if (!(isArray(options) && isFunction(copy))) {
- target[name] = copy;
- }
- }
- }
- }
+// shim for browsers that don't support it
+function readAsBinaryString(blob, callback) {
+ if (typeof FileReader === 'undefined') {
+ // fix for Firefox in a web worker
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=901097
+ return callback(arrayBufferToBinaryString(
+ new FileReaderSync().readAsArrayBuffer(blob)));
+ }
+
+ 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);
}
+}
- // "Return" the modified object by setting the key
- // on the given container
- result.container[result.key] = target;
+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) {
+ if (typeof FileReader === 'undefined') {
+ // fix for Firefox in a web worker:
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=901097
+ return callback(new FileReaderSync().readAsArrayBuffer(blob));
+ }
-module.exports = extend;
+ 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
+function typedBuffer() {
+}
+exports.atob = thisAtob;
+exports.btoa = thisBtoa;
+exports.base64StringToBlobOrBuffer = b64ToBluffer;
+exports.binaryStringToArrayBuffer = binaryStringToArrayBuffer;
+exports.binaryStringToBlobOrBuffer = binStringToBluffer;
+exports.blob = createBlob;
+exports.blobOrBufferToBase64 = blobToBase64;
+exports.blobOrBufferToBinaryString = blobToBinaryString;
+exports.readAsArrayBuffer = readAsArrayBuffer;
+exports.readAsBinaryString = readAsBinaryString;
+exports.typedBuffer = typedBuffer;
-},{}],13:[function(require,module,exports){
+},{}],10:[function(require,module,exports){
'use strict';
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
-var lie = _interopDefault(require(9));
+var lie = _interopDefault(require(6));
/* istanbul ignore next */
var PouchPromise = typeof Promise === 'function' ? Promise : lie;
module.exports = PouchPromise;
-},{"9":9}],14:[function(require,module,exports){
-(function (process){
+
+},{"6":6}],11:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
-var lie = _interopDefault(require(9));
+var uuidV4 = _interopDefault(require(18));
+var Promise = _interopDefault(require(10));
var getArguments = _interopDefault(require(2));
-var debug = _interopDefault(require(3));
-var events = require(5);
-var inherits = _interopDefault(require(7));
-
-/* istanbul ignore next */
-var PouchPromise = typeof Promise === 'function' ? Promise : lie;
+var pouchdbCollections = require(12);
+var events = require(3);
+var inherits = _interopDefault(require(5));
+var immediate = _interopDefault(require(4));
+var pouchdbErrors = require(13);
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;
- var tempCB =
- (typeof args[args.length - 1] === 'function') ? args.pop() : false;
// if the last argument is a function, assume its a callback
- var usedCB;
- if (tempCB) {
- // if it was a callback, create a new callback which calls it,
- // but do so async so we don't trap any errors
- usedCB = function (err, resp) {
- process.nextTick(function () {
- tempCB(err, resp);
- });
- };
- }
- var promise = new PouchPromise(function (fulfill, reject) {
+ 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;
});
}
-var log = debug('pouchdb:api');
-
-function adapterFun(name, callback) {
- function logApiCall(self, name, args) {
- /* istanbul ignore if */
- if (log.enabled) {
- var logArgs = [self.name, name];
- for (var i = 0; i < args.length - 1; i++) {
- logArgs.push(args[i]);
- }
- log.apply(null, logArgs);
-
- // override the callback itself to log the response
- var origCallback = args[args.length - 1];
- args[args.length - 1] = function (err, res) {
- var responseArgs = [self.name, name];
- responseArgs = responseArgs.concat(
- err ? ['error', err] : ['success', res]
- );
- log.apply(null, responseArgs);
- origCallback(err, res);
- };
- }
+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 PouchPromise.reject(new Error('database is closed'));
+ return Promise.reject(new Error('database is closed'));
}
if (this._destroyed) {
- return PouchPromise.reject(new Error('database is destroyed'));
+ return Promise.reject(new Error('database is destroyed'));
}
var self = this;
logApiCall(self, name, args);
if (!this.taskqueue.isReady) {
- return new PouchPromise(function (fulfill, reject) {
+ 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 = {};
+ var requestsById = new pouchdbCollections.Map();
requests.forEach(function (request) {
- if (request.id in requestsById) {
- requestsById[request.id].push(request);
+ if (requestsById.has(request.id)) {
+ requestsById.get(request.id).push(request);
} else {
- requestsById[request.id] = [request];
+ requestsById.set(request.id, [request]);
}
});
- var numDocs = Object.keys(requestsById).length;
+ 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 = Object.keys(requestsById);
+ 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[docId];
+ 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'].forEach(function (param) {
+ ['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();
}
function isChromeApp() {
return (typeof chrome !== "undefined" &&
typeof chrome.storage !== "undefined" &&
typeof chrome.storage.local !== "undefined");
}
var hasLocal;
if (isChromeApp()) {
hasLocal = false;
} else {
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
+// avoid using process.nextTick() directly because the polyfill is very large and we don't
+// need all of it (see: https://github.com/defunctzombie/node-process).
+// "immediate" 3.0.8 is used by lie, and it's a smaller version of the latest "immediate"
+// package, so it's the one we use.
+// When we use nextTick() in our codebase, we only care about not releasing Zalgo
+// (see: http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony).
+// Microtask vs macrotask doesn't matter to us. So we're free to use the fastest
+// (least latency) option, which is "immediate" due to use of microtasks.
+// All of our nextTicks are isolated to this one function so we can easily swap out one
+// implementation for another.
+
inherits(Changes, events.EventEmitter);
/* istanbul ignore next */
function attachBrowserEvents(self) {
if (isChromeApp()) {
chrome.storage.onChanged.addListener(function (e) {
// make sure it's event addressed to us
if (e.db_name != null) {
//object only has oldValue, newValue members
self.emit(e.dbName.newValue);
}
});
} else if (hasLocalStorage()) {
if (typeof addEventListener !== 'undefined') {
addEventListener("storage", function (e) {
self.emit(e.key);
});
} else { // old IE
window.attachEvent("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'
]);
/* 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') {
- setTimeout(function (){
- eventFunction();
- },0);
+ 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 (isChromeApp()) {
chrome.storage.local.set({dbName: dbName});
} else 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 (console !== 'undefined' && method in console) {
+ 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) {
+ 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);
-}
-
-function extendInner(obj, otherObj) {
- for (var key in otherObj) {
- if (otherObj.hasOwnProperty(key)) {
- var value = clone(otherObj[key]);
- if (typeof value !== 'undefined') {
- obj[key] = value;
- }
- }
- }
-}
-
-function extend(obj, obj2, obj3) {
- extendInner(obj, obj2);
- if (obj3) {
- extendInner(obj, obj3);
- }
- return obj;
-}
-
-inherits(PouchError, Error);
-
-function PouchError(opts) {
- Error.call(this, opts.reason);
- this.status = opts.status;
- this.name = opts.error;
- this.message = opts.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({
- status: 401,
- error: 'unauthorized',
- reason: "Name or password is incorrect."
-});
-
-var MISSING_BULK_DOCS = new PouchError({
- status: 400,
- error: 'bad_request',
- reason: "Missing JSON list of 'docs'"
-});
-
-var MISSING_DOC = new PouchError({
- status: 404,
- error: 'not_found',
- reason: 'missing'
-});
-
-var REV_CONFLICT = new PouchError({
- status: 409,
- error: 'conflict',
- reason: 'Document update conflict'
-});
-
-var INVALID_ID = new PouchError({
- status: 400,
- error: 'bad_request',
- reason: '_id field must contain a string'
-});
-
-var MISSING_ID = new PouchError({
- status: 412,
- error: 'missing_id',
- reason: '_id is required for puts'
-});
-
-var RESERVED_ID = new PouchError({
- status: 400,
- error: 'bad_request',
- reason: 'Only reserved document ids may start with underscore.'
-});
-
-var NOT_OPEN = new PouchError({
- status: 412,
- error: 'precondition_failed',
- reason: 'Database not open'
-});
-
-var UNKNOWN_ERROR = new PouchError({
- status: 500,
- error: 'unknown_error',
- reason: 'Database encountered an unknown error'
-});
-
-var BAD_ARG = new PouchError({
- status: 500,
- error: 'badarg',
- reason: 'Some query argument is invalid'
-});
-
-var INVALID_REQUEST = new PouchError({
- status: 400,
- error: 'invalid_request',
- reason: 'Request was invalid'
-});
-
-var QUERY_PARSE_ERROR = new PouchError({
- status: 400,
- error: 'query_parse_error',
- reason: 'Some query parameter is invalid'
-});
-
-var DOC_VALIDATION = new PouchError({
- status: 500,
- error: 'doc_validation',
- reason: 'Bad special document member'
-});
-
-var BAD_REQUEST = new PouchError({
- status: 400,
- error: 'bad_request',
- reason: 'Something wrong with the request'
-});
-
-var NOT_AN_OBJECT = new PouchError({
- status: 400,
- error: 'bad_request',
- reason: 'Document must be a JSON object'
-});
-
-var DB_MISSING = new PouchError({
- status: 404,
- error: 'not_found',
- reason: 'Database not found'
-});
-
-var IDB_ERROR = new PouchError({
- status: 500,
- error: 'indexed_db_went_bad',
- reason: 'unknown'
-});
-
-var WSQ_ERROR = new PouchError({
- status: 500,
- error: 'web_sql_went_bad',
- reason: 'unknown'
-});
-
-var LDB_ERROR = new PouchError({
- status: 500,
- error: 'levelDB_went_went_bad',
- reason: 'unknown'
-});
-
-var FORBIDDEN = new PouchError({
- status: 403,
- error: 'forbidden',
- reason: 'Forbidden by design doc validate_doc_update function'
-});
-
-var INVALID_REV = new PouchError({
- status: 400,
- error: 'bad_request',
- reason: 'Invalid rev format'
-});
-
-var FILE_EXISTS = new PouchError({
- status: 412,
- error: 'file_exists',
- reason: 'The database could not be created, the file already exists.'
-});
-
-var MISSING_STUB = new PouchError({
- status: 412,
- error: 'missing_stub'
-});
+ if (!min) {
+ max = 2000;
+ }
+ return randomNumber(min, max);
+}
-var INVALID_URL = new PouchError({
- status: 413,
- error: 'invalid_url',
- reason: 'Provided URL is invalid'
-});
+// 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);
+}
-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];
+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];
+ }
+ }
+ }
}
- }
- /* jshint ignore:end */
- if (reason !== undefined) {
- this.reason = reason;
- }
+ return to;
+ };
}
- CustomPouchError.prototype = PouchError.prototype;
- return new CustomPouchError(reason);
}
+var assign$1 = assign;
+
function tryFilter(filter, doc, req) {
try {
return !filter(doc, req);
} catch (err) {
var msg = 'Filter function threw: ' + err.toString();
- return createError(BAD_REQUEST, msg);
+ return pouchdbErrors.createError(pouchdbErrors.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,
// for browsers that don't support it like IE
/* istanbul ignore next */
function f() {}
var hasName = f.name;
var res;
// We dont run coverage in IE
/* istanbul ignore else */
if (hasName) {
res = function (fun) {
return fun.name;
};
} else {
res = function (fun) {
return fun.toString().match(/^\s*function\s*(\S*)\s*\(/)[1];
};
}
-var functionName = res;
+var res$1 = res;
// 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);
+ err = pouchdbErrors.createError(pouchdbErrors.MISSING_ID);
} else if (typeof id !== 'string') {
- err = createError(INVALID_ID);
+ err = pouchdbErrors.createError(pouchdbErrors.INVALID_ID);
} else if (/^_/.test(id) && !(/^_(design|local)/).test(id)) {
- err = createError(RESERVED_ID);
+ err = pouchdbErrors.createError(pouchdbErrors.RESERVED_ID);
}
if (err) {
throw err;
}
}
function isCordova() {
return (typeof cordova !== "undefined" ||
typeof PhoneGap !== "undefined" ||
typeof phonegap !== "undefined");
}
+// Checks if a PouchDB object is "remote" or not. This is
+// designed to opt-in to certain optimizations, such as
+// avoiding checks for "dependentDbs" and other things that
+// we know only apply to local databases. In general, "remote"
+// should be true for the http adapter, and for third-party
+// adapters with similar expensive boundaries to cross for
+// every API call, such as socket-pouch and worker-pouch.
+// Previously, this was handled via db.type() === 'http'
+// which is now deprecated.
+
+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
-/* jshint maxlen: false */
+/* 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 PouchPromise(function (fulfill, reject) {
+ 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);
});
}
-// BEGIN Math.uuid.js
-
-/*!
-Math.uuid.js (v1.4)
-http://www.broofa.com
-mailto:robert@broofa.com
-
-Copyright (c) 2010 Robert Kieffer
-Dual licensed under the MIT and GPL licenses.
-*/
-
-/*
- * Generate a random uuid.
- *
- * USAGE: Math.uuid(length, radix)
- * length - the desired number of characters
- * radix - the number of allowable values for each character.
- *
- * EXAMPLES:
- * // No arguments - returns RFC4122, version 4 ID
- * >>> Math.uuid()
- * "92329D39-6F5C-4520-ABFC-AAB64544E172"
- *
- * // One argument - returns ID of the specified length
- * >>> Math.uuid(15) // 15 character ID (default base=62)
- * "VcydxgltxrVZSTV"
- *
- * // Two arguments - returns ID of the specified length, and radix.
- * // (Radix must be <= 62)
- * >>> Math.uuid(8, 2) // 8 character ID (base=2)
- * "01001010"
- * >>> Math.uuid(8, 10) // 8 character ID (base=10)
- * "47473046"
- * >>> Math.uuid(8, 16) // 8 character ID (base=16)
- * "098F4D35"
- */
-var chars = (
- '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
- 'abcdefghijklmnopqrstuvwxyz'
-).split('');
-function getValue(radix) {
- return 0 | Math.random() * radix;
-}
-function uuid(len, radix) {
- radix = radix || chars.length;
- var out = '';
- var i = -1;
-
- if (len) {
- // Compact form
- while (++i < len) {
- out += chars[getValue(radix)];
- }
- return out;
- }
- // rfc4122, version 4 form
- // Fill in random data. At i==19 set the high bits of clock sequence as
- // per rfc4122, sec. 4.1.5
- while (++i < 36) {
- switch (i) {
- case 8:
- case 13:
- case 18:
- case 23:
- out += '-';
- break;
- case 19:
- out += chars[(getValue(16) & 0x3) | 0x8];
- break;
- default:
- out += chars[getValue(16)];
- }
- }
-
- return out;
+function rev() {
+ return uuidV4.v4().replace(/-/g, '').toLowerCase();
}
+var uuid = uuidV4.v4;
+
exports.adapterFun = adapterFun;
+exports.assign = assign$1;
exports.bulkGetShim = bulkGet;
exports.changesHandler = Changes;
exports.clone = clone;
exports.defaultBackOff = defaultBackOff;
exports.explainError = explainError;
-exports.extend = extend;
exports.filterChange = filterChange;
exports.flatten = flatten;
-exports.functionName = functionName;
+exports.functionName = res$1;
exports.guardedConsole = guardedConsole;
exports.hasLocalStorage = hasLocalStorage;
exports.invalidIdError = invalidIdError;
exports.isChromeApp = isChromeApp;
exports.isCordova = isCordova;
+exports.isRemote = isRemote;
exports.listenerCount = listenerCount;
+exports.nextTick = immediate;
exports.normalizeDdocFunctionName = normalizeDesignDocFunctionName;
exports.once = once;
exports.parseDdocFunctionName = parseDesignDocFunctionName;
exports.parseUri = parseUri;
exports.pick = pick;
+exports.rev = rev;
+exports.scopeEval = scopeEval;
exports.toPromise = toPromise;
exports.upsert = upsert;
exports.uuid = uuid;
-}).call(this,require(15))
-},{"15":15,"2":2,"3":3,"5":5,"7":7,"9":9}],15:[function(require,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.
+},{"10":10,"12":12,"13":13,"18":18,"2":2,"3":3,"4":4,"5":5}],12:[function(require,module,exports){
+'use strict';
-var cachedSetTimeout;
-var cachedClearTimeout;
+Object.defineProperty(exports, '__esModule', { value: true });
-function defaultSetTimout() {
- throw new Error('setTimeout has not been defined');
+function mangle(key) {
+ return '$' + key;
}
-function defaultClearTimeout () {
- throw new Error('clearTimeout has not been defined');
+function unmangle(key) {
+ return key.substring(1);
}
-(function () {
- try {
- if (typeof setTimeout === 'function') {
- cachedSetTimeout = setTimeout;
- } else {
- cachedSetTimeout = defaultSetTimout;
- }
- } catch (e) {
- cachedSetTimeout = defaultSetTimout;
+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]);
}
- try {
- if (typeof clearTimeout === 'function') {
- cachedClearTimeout = clearTimeout;
- } else {
- cachedClearTimeout = defaultClearTimeout;
- }
- } catch (e) {
- cachedClearTimeout = defaultClearTimeout;
+ }
+}
+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
+/* global Map,Set */
+
+{
+ if (supportsMapAndSet()) { // prefer built-in Map/Set
+ exports.Set = Set;
+ exports.Map = Map;
+ } else { // fall back to our polyfill
+ exports.Set = Set$1;
+ exports.Map = Map$1;
+ }
+}
+
+},{}],13:[function(require,module,exports){
+arguments[4][8][0].apply(exports,arguments)
+},{"5":5,"8":8}],14:[function(require,module,exports){
+'use strict';
+
+var has = Object.prototype.hasOwnProperty;
+
+/**
+ * Decode a URI encoded string.
+ *
+ * @param {String} input The URI encoded string.
+ * @returns {String} The decoded string.
+ * @api private
+ */
+function decode(input) {
+ return decodeURIComponent(input.replace(/\+/g, ' '));
+}
+
+/**
+ * Simple query string parser.
+ *
+ * @param {String} query The query string that needs to be parsed.
+ * @returns {Object}
+ * @api public
+ */
+function querystring(query) {
+ var parser = /([^=?&]+)=?([^&]*)/g
+ , result = {}
+ , part;
+
+ //
+ // Little nifty parsing hack, leverage the fact that RegExp.exec increments
+ // the lastIndex property so we can continue executing this loop until we've
+ // parsed all results.
+ //
+ for (;
+ part = parser.exec(query);
+ result[decode(part[1])] = decode(part[2])
+ );
+
+ return result;
+}
+
+/**
+ * Transform a query string to an object.
+ *
+ * @param {Object} obj Object that should be transformed.
+ * @param {String} prefix Optional prefix.
+ * @returns {String}
+ * @api public
+ */
+function querystringify(obj, prefix) {
+ prefix = prefix || '';
+
+ var pairs = [];
+
+ //
+ // Optionally prefix with a '?' if needed
+ //
+ if ('string' !== typeof prefix) prefix = '?';
+
+ for (var key in obj) {
+ if (has.call(obj, key)) {
+ pairs.push(encodeURIComponent(key) +'='+ encodeURIComponent(obj[key]));
+ }
+ }
+
+ return pairs.length ? prefix + pairs.join('&') : '';
+}
+
+//
+// Expose the module.
+//
+exports.stringify = querystringify;
+exports.parse = querystring;
+
+},{}],15:[function(require,module,exports){
+(function (name, context, definition) {
+ if (typeof module !== 'undefined' && module.exports) module.exports = definition();
+ else if (typeof define === 'function' && define.amd) define(definition);
+ else context[name] = definition();
+})('urljoin', this, function () {
+
+ function normalize (strArray) {
+ var resultArray = [];
+
+ // If the first part is a plain protocol, we combine it with the next part.
+ if (strArray[0].match(/^[^/:]+:\/*$/) && strArray.length > 1) {
+ var first = strArray.shift();
+ strArray[0] = first + strArray[0];
}
-} ())
-function runTimeout(fun) {
- if (cachedSetTimeout === setTimeout) {
- //normal enviroments in sane situations
- return setTimeout(fun, 0);
+
+ // There must be two or three slashes in the file protocol, two slashes in anything else.
+ if (strArray[0].match(/^file:\/\/\//)) {
+ strArray[0] = strArray[0].replace(/^([^/:]+):\/*/, '$1:///');
+ } else {
+ strArray[0] = strArray[0].replace(/^([^/:]+):\/*/, '$1://');
}
- // if setTimeout wasn't available but was latter defined
- if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
- cachedSetTimeout = setTimeout;
- return setTimeout(fun, 0);
+
+ for (var i = 0; i < strArray.length; i++) {
+ var component = strArray[i];
+
+ if (typeof component !== 'string') {
+ throw new TypeError('Url must be a string. Received ' + component);
+ }
+
+ if (component === '') { continue; }
+
+ if (i > 0) {
+ // Removing the starting slashes for each component but the first.
+ component = component.replace(/^[\/]+/, '');
+ }
+ if (i < strArray.length - 1) {
+ // Removing the ending slashes for each component but the last.
+ component = component.replace(/[\/]+$/, '');
+ } else {
+ // For the last component we will combine multiple slashes to a single one.
+ component = component.replace(/[\/]+$/, '/');
+ }
+
+ resultArray.push(component);
+
}
- 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);
- }
+
+ var str = resultArray.join('/');
+ // Each input component is now separated by a single slash except the possible first plain protocol part.
+
+ // remove trailing slash before parameters or hash
+ str = str.replace(/\/(\?|&|#[^!])/g, '$1');
+
+ // replace ? in parameters with &
+ var parts = str.split('?');
+ str = parts.shift() + (parts.length > 0 ? '?': '') + parts.join('&');
+
+ return str;
+ }
+
+ return function () {
+ var input;
+
+ if (typeof arguments[0] === 'object') {
+ input = arguments[0];
+ } else {
+ input = [].slice.call(arguments);
+ }
+
+ return normalize(input);
+ };
+
+});
+
+},{}],16:[function(require,module,exports){
+(function (global){
+'use strict';
+
+var required = require(17)
+ , qs = require(14)
+ , protocolre = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i
+ , slashes = /^[A-Za-z][A-Za-z0-9+-.]*:\/\//;
+
+/**
+ * These are the parse rules for the URL parser, it informs the parser
+ * about:
+ *
+ * 0. The char it Needs to parse, if it's a string it should be done using
+ * indexOf, RegExp using exec and NaN means set as current value.
+ * 1. The property we should set when parsing this value.
+ * 2. Indication if it's backwards or forward parsing, when set as number it's
+ * the value of extra chars that should be split off.
+ * 3. Inherit from location if non existing in the parser.
+ * 4. `toLowerCase` the resulting value.
+ */
+var rules = [
+ ['#', 'hash'], // Extract from the back.
+ ['?', 'query'], // Extract from the back.
+ ['/', 'pathname'], // Extract from the back.
+ ['@', 'auth', 1], // Extract from the front.
+ [NaN, 'host', undefined, 1, 1], // Set left over value.
+ [/:(\d+)$/, 'port', undefined, 1], // RegExp the back.
+ [NaN, 'hostname', undefined, 1, 1] // Set left over.
+];
+
+/**
+ * These properties should not be copied or inherited from. This is only needed
+ * for all non blob URL's as a blob URL does not include a hash, only the
+ * origin.
+ *
+ * @type {Object}
+ * @private
+ */
+var ignore = { hash: 1, query: 1 };
+
+/**
+ * The location object differs when your code is loaded through a normal page,
+ * Worker or through a worker using a blob. And with the blobble begins the
+ * trouble as the location object will contain the URL of the blob, not the
+ * location of the page where our code is loaded in. The actual origin is
+ * encoded in the `pathname` so we can thankfully generate a good "default"
+ * location from it so we can generate proper relative URL's again.
+ *
+ * @param {Object|String} loc Optional default location object.
+ * @returns {Object} lolcation object.
+ * @api public
+ */
+function lolcation(loc) {
+ loc = loc || global.location || {};
+
+ var finaldestination = {}
+ , type = typeof loc
+ , key;
+
+ if ('blob:' === loc.protocol) {
+ finaldestination = new URL(unescape(loc.pathname), {});
+ } else if ('string' === type) {
+ finaldestination = new URL(loc, {});
+ for (key in ignore) delete finaldestination[key];
+ } else if ('object' === type) {
+ for (key in loc) {
+ if (key in ignore) continue;
+ finaldestination[key] = loc[key];
+ }
+
+ if (finaldestination.slashes === undefined) {
+ finaldestination.slashes = slashes.test(loc.href);
+ }
+ }
+
+ return finaldestination;
+}
+
+/**
+ * @typedef ProtocolExtract
+ * @type Object
+ * @property {String} protocol Protocol matched in the URL, in lowercase.
+ * @property {Boolean} slashes `true` if protocol is followed by "//", else `false`.
+ * @property {String} rest Rest of the URL that is not part of the protocol.
+ */
+
+/**
+ * Extract protocol information from a URL with/without double slash ("//").
+ *
+ * @param {String} address URL we want to extract from.
+ * @return {ProtocolExtract} Extracted information.
+ * @api private
+ */
+function extractProtocol(address) {
+ var match = protocolre.exec(address);
+
+ return {
+ protocol: match[1] ? match[1].toLowerCase() : '',
+ slashes: !!match[2],
+ rest: match[3]
+ };
+}
+
+/**
+ * Resolve a relative URL pathname against a base URL pathname.
+ *
+ * @param {String} relative Pathname of the relative URL.
+ * @param {String} base Pathname of the base URL.
+ * @return {String} Resolved pathname.
+ * @api private
+ */
+function resolve(relative, base) {
+ var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/'))
+ , i = path.length
+ , last = path[i - 1]
+ , unshift = false
+ , up = 0;
+
+ while (i--) {
+ if (path[i] === '.') {
+ path.splice(i, 1);
+ } else if (path[i] === '..') {
+ path.splice(i, 1);
+ up++;
+ } else if (up) {
+ if (i === 0) unshift = true;
+ path.splice(i, 1);
+ up--;
}
+ }
+
+ if (unshift) path.unshift('');
+ if (last === '.' || last === '..') path.push('');
+
+ return path.join('/');
+}
+
+/**
+ * The actual URL instance. Instead of returning an object we've opted-in to
+ * create an actual constructor as it's much more memory efficient and
+ * faster and it pleases my OCD.
+ *
+ * @constructor
+ * @param {String} address URL we want to parse.
+ * @param {Object|String} location Location defaults for relative paths.
+ * @param {Boolean|Function} parser Parser for the query string.
+ * @api public
+ */
+function URL(address, location, parser) {
+ if (!(this instanceof URL)) {
+ return new URL(address, location, parser);
+ }
+
+ var relative, extracted, parse, instruction, index, key
+ , instructions = rules.slice()
+ , type = typeof location
+ , url = this
+ , i = 0;
+
+ //
+ // The following if statements allows this module two have compatibility with
+ // 2 different API:
+ //
+ // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments
+ // where the boolean indicates that the query string should also be parsed.
+ //
+ // 2. The `URL` interface of the browser which accepts a URL, object as
+ // arguments. The supplied object will be used as default values / fall-back
+ // for relative paths.
+ //
+ if ('object' !== type && 'string' !== type) {
+ parser = location;
+ location = null;
+ }
+
+ if (parser && 'function' !== typeof parser) parser = qs.parse;
+
+ location = lolcation(location);
+
+ //
+ // Extract protocol information before running the instructions.
+ //
+ extracted = extractProtocol(address || '');
+ relative = !extracted.protocol && !extracted.slashes;
+ url.slashes = extracted.slashes || relative && location.slashes;
+ url.protocol = extracted.protocol || location.protocol || '';
+ address = extracted.rest;
+
+ //
+ // When the authority component is absent the URL starts with a path
+ // component.
+ //
+ if (!extracted.slashes) instructions[2] = [/(.*)/, 'pathname'];
+
+ for (; i < instructions.length; i++) {
+ instruction = instructions[i];
+ parse = instruction[0];
+ key = instruction[1];
+
+ if (parse !== parse) {
+ url[key] = address;
+ } else if ('string' === typeof parse) {
+ if (~(index = address.indexOf(parse))) {
+ if ('number' === typeof instruction[2]) {
+ url[key] = address.slice(0, index);
+ address = address.slice(index + instruction[2]);
+ } else {
+ url[key] = address.slice(index);
+ address = address.slice(0, index);
+ }
+ }
+ } else if ((index = parse.exec(address))) {
+ url[key] = index[1];
+ address = address.slice(0, index.index);
+ }
+
+ url[key] = url[key] || (
+ relative && instruction[3] ? location[key] || '' : ''
+ );
+
+ //
+ // Hostname, host and protocol should be lowercased so they can be used to
+ // create a proper `origin`.
+ //
+ if (instruction[4]) url[key] = url[key].toLowerCase();
+ }
+
+ //
+ // Also parse the supplied query string in to an object. If we're supplied
+ // with a custom parser as function use that instead of the default build-in
+ // parser.
+ //
+ if (parser) url.query = parser(url.query);
+
+ //
+ // If the URL is relative, resolve the pathname against the base URL.
+ //
+ if (
+ relative
+ && location.slashes
+ && url.pathname.charAt(0) !== '/'
+ && (url.pathname !== '' || location.pathname !== '')
+ ) {
+ url.pathname = resolve(url.pathname, location.pathname);
+ }
+
+ //
+ // We should not add port numbers if they are already the default port number
+ // for a given protocol. As the host also contains the port number we're going
+ // override it with the hostname which contains no port number.
+ //
+ if (!required(url.port, url.protocol)) {
+ url.host = url.hostname;
+ url.port = '';
+ }
+
+ //
+ // Parse down the `auth` for the username and password.
+ //
+ url.username = url.password = '';
+ if (url.auth) {
+ instruction = url.auth.split(':');
+ url.username = instruction[0] || '';
+ url.password = instruction[1] || '';
+ }
+
+ url.origin = url.protocol && url.host && url.protocol !== 'file:'
+ ? url.protocol +'//'+ url.host
+ : 'null';
+
+ //
+ // The href is just the compiled result.
+ //
+ url.href = url.toString();
+}
+
+/**
+ * This is convenience method for changing properties in the URL instance to
+ * insure that they all propagate correctly.
+ *
+ * @param {String} part Property we need to adjust.
+ * @param {Mixed} value The newly assigned value.
+ * @param {Boolean|Function} fn When setting the query, it will be the function
+ * used to parse the query.
+ * When setting the protocol, double slash will be
+ * removed from the final url if it is true.
+ * @returns {URL}
+ * @api public
+ */
+function set(part, value, fn) {
+ var url = this;
+
+ switch (part) {
+ case 'query':
+ if ('string' === typeof value && value.length) {
+ value = (fn || qs.parse)(value);
+ }
+
+ url[part] = value;
+ break;
+
+ case 'port':
+ url[part] = value;
+
+ if (!required(value, url.protocol)) {
+ url.host = url.hostname;
+ url[part] = '';
+ } else if (value) {
+ url.host = url.hostname +':'+ value;
+ }
+
+ break;
+
+ case 'hostname':
+ url[part] = value;
+
+ if (url.port) value += ':'+ url.port;
+ url.host = value;
+ break;
+
+ case 'host':
+ url[part] = value;
+
+ if (/:\d+$/.test(value)) {
+ value = value.split(':');
+ url.port = value.pop();
+ url.hostname = value.join(':');
+ } else {
+ url.hostname = value;
+ url.port = '';
+ }
+
+ break;
+
+ case 'protocol':
+ url.protocol = value.toLowerCase();
+ url.slashes = !fn;
+ break;
+
+ case 'pathname':
+ case 'hash':
+ if (value) {
+ var char = part === 'pathname' ? '/' : '#';
+ url[part] = value.charAt(0) !== char ? char + value : value;
+ } else {
+ url[part] = value;
+ }
+ break;
+ default:
+ url[part] = value;
+ }
-}
-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);
- }
- }
+ for (var i = 0; i < rules.length; i++) {
+ var ins = rules[i];
+ if (ins[4]) url[ins[1]] = url[ins[1]].toLowerCase();
+ }
+ url.origin = url.protocol && url.host && url.protocol !== 'file:'
+ ? url.protocol +'//'+ url.host
+ : 'null';
-}
-var queue = [];
-var draining = false;
-var currentQueue;
-var queueIndex = -1;
+ url.href = url.toString();
-function cleanUpNextTick() {
- if (!draining || !currentQueue) {
- return;
- }
- draining = false;
- if (currentQueue.length) {
- queue = currentQueue.concat(queue);
- } else {
- queueIndex = -1;
- }
- if (queue.length) {
- drainQueue();
- }
+ return url;
}
-function drainQueue() {
- if (draining) {
- return;
- }
- var timeout = runTimeout(cleanUpNextTick);
- draining = true;
+/**
+ * Transform the properties back in to a valid and full URL string.
+ *
+ * @param {Function} stringify Optional query stringify function.
+ * @returns {String}
+ * @api public
+ */
+function toString(stringify) {
+ if (!stringify || 'function' !== typeof stringify) stringify = qs.stringify;
- 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);
-}
+ var query
+ , url = this
+ , protocol = url.protocol;
-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);
- }
-};
+ if (protocol && protocol.charAt(protocol.length - 1) !== ':') protocol += ':';
+
+ var result = protocol + (url.slashes ? '//' : '');
+
+ if (url.username) {
+ result += url.username;
+ if (url.password) result += ':'+ url.password;
+ result += '@';
+ }
+
+ result += url.host + url.pathname;
-// v8 likes predictible objects
-function Item(fun, array) {
- this.fun = fun;
- this.array = array;
+ query = 'object' === typeof url.query ? stringify(url.query) : url.query;
+ if (query) result += '?' !== query.charAt(0) ? '?'+ query : query;
+
+ if (url.hash) result += url.hash;
+
+ return result;
}
-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.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; };
+URL.prototype = { set: set, toString: toString };
-},{}],16:[function(require,module,exports){
-(function (name, context, definition) {
- if (typeof module !== 'undefined' && module.exports) module.exports = definition();
- else if (typeof define === 'function' && define.amd) define(definition);
- else context[name] = definition();
-})('urljoin', this, function () {
+//
+// Expose the URL parser and some additional properties that might be useful for
+// others or testing.
+//
+URL.extractProtocol = extractProtocol;
+URL.location = lolcation;
+URL.qs = qs;
+
+module.exports = URL;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"14":14,"17":17}],17:[function(require,module,exports){
+'use strict';
- function normalize (str, options) {
+/**
+ * Check if we're required to add a port number.
+ *
+ * @see https://url.spec.whatwg.org/#default-port
+ * @param {Number|String} port Port number we need to check
+ * @param {String} protocol Protocol we need to check against.
+ * @returns {Boolean} Is it a default port for the given protocol
+ * @api private
+ */
+module.exports = function required(port, protocol) {
+ protocol = protocol.split(':')[0];
+ port = +port;
- // make sure protocol is followed by two slashes
- str = str.replace(/:\//g, '://');
+ if (!port) return false;
- // remove consecutive slashes
- str = str.replace(/([^:\s])\/+/g, '$1/');
+ switch (protocol) {
+ case 'http':
+ case 'ws':
+ return port !== 80;
- // remove trailing slash before parameters or hash
- str = str.replace(/\/(\?|&|#[^!])/g, '$1');
+ case 'https':
+ case 'wss':
+ return port !== 443;
- // replace ? in parameters with &
- str = str.replace(/(\?.+)\?/g, '$1&');
+ case 'ftp':
+ return port !== 21;
- return str;
+ case 'gopher':
+ return port !== 70;
+
+ case 'file':
+ return false;
}
- return function () {
- var input = arguments;
- var options = {};
+ return port !== 0;
+};
- if (typeof arguments[0] === 'object') {
- // new syntax with array and options
- input = arguments[0];
- options = arguments[1] || {};
- }
+},{}],18:[function(require,module,exports){
+var v1 = require(21);
+var v4 = require(22);
- var joined = [].slice.call(input, 0).join('/');
- return normalize(joined, options);
- };
+var uuid = v4;
+uuid.v1 = v1;
+uuid.v4 = v4;
-});
+module.exports = uuid;
-},{}],17:[function(require,module,exports){
-'use strict';
+},{"21":21,"22":22}],19:[function(require,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);
+}
-var utils = require(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++]];
+}
-function wrapError(callback) {
- // provide more helpful error message
- return function (err, res) {
- if (err) {
- if (err.name === 'unknown_error') {
- err.message = (err.message || '') +
- ' Unknown error! Did you remember to enable CORS?';
- }
- }
- return callback(err, res);
+module.exports = bytesToUuid;
+
+},{}],20:[function(require,module,exports){
+(function (global){
+// 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
+var rng;
+
+var crypto = global.crypto || global.msCrypto; // for IE 11
+if (crypto && crypto.getRandomValues) {
+ // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
+ var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef
+ rng = function whatwgRNG() {
+ crypto.getRandomValues(rnds8);
+ return rnds8;
};
}
-function putUser(db, user, opts, callback) {
- var reservedWords = ['name', 'password', 'roles', 'type', 'salt', 'metadata'];
- if (opts.metadata) {
- for (var key in opts.metadata) {
- if (opts.hasOwnProperty(key)) {
- if (reservedWords.indexOf(key) !== -1 || key.startsWith('_')) {
- return callback(new AuthError('cannot use reserved word in metadata: "' + key + '"'));
- }
- }
+if (!rng) {
+ // Math.random()-based (RNG)
+ //
+ // If all else fails, use Math.random(). It's fast, but is of unspecified
+ // quality.
+ var rnds = new Array(16);
+ rng = function() {
+ for (var i = 0, r; i < 16; i++) {
+ if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
+ rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
}
- user = utils.extend(true, user, opts.metadata);
- }
- var url = utils.getUsersUrl(db) + '/' + encodeURIComponent(user._id);
- var ajaxOpts = utils.extend(true, {
- method : 'PUT',
- url : url,
- body : user
- }, opts.ajax || {});
- utils.ajax(ajaxOpts, wrapError(callback));
+ return rnds;
+ };
}
-exports.signup = utils.toPromise(function (username, password, opts, callback) {
- var db = this;
- if (typeof callback === 'undefined') {
- callback = typeof opts === 'undefined' ? (typeof password === 'undefined' ?
- username : password) : opts;
- opts = {};
- }
- if (['http', 'https'].indexOf(db.type()) === -1) {
- return callback(new AuthError('This plugin only works for the http/https adapter. ' +
- 'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
- } else if (!username) {
- return callback(new AuthError('You must provide a username'));
- } else if (!password) {
- return callback(new AuthError('You must provide a password'));
- }
+module.exports = rng;
- var userId = 'org.couchdb.user:' + username;
- var user = {
- name : username,
- password : password,
- roles : opts.roles || [],
- type : 'user',
- _id : userId
- };
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],21:[function(require,module,exports){
+var rng = require(20);
+var bytesToUuid = require(19);
- putUser(db, user, opts, callback);
-});
+// **`v1()` - Generate time-based UUID**
+//
+// Inspired by https://github.com/LiosK/UUID.js
+// and http://docs.python.org/library/uuid.html
-exports.signUp = exports.signup;
+// random #'s we need to init node and clockseq
+var _seedBytes = rng();
-exports.login = utils.toPromise(function (username, password, opts, callback) {
- var db = this;
- if (typeof callback === 'undefined') {
- callback = opts;
- opts = {};
- }
- if (['http', 'https'].indexOf(db.type()) === -1) {
- return callback(new AuthError('this plugin only works for the http/https adapter'));
- }
+// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
+var _nodeId = [
+ _seedBytes[0] | 0x01,
+ _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]
+];
- if (!username) {
- return callback(new AuthError('you must provide a username'));
- } else if (!password) {
- return callback(new AuthError('you must provide a password'));
- }
+// Per 4.2.2, randomize (14 bit) clockseq
+var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;
- var ajaxOpts = utils.extend(true, {
- method : 'POST',
- url : utils.getSessionUrl(db),
- headers : {'Content-Type': 'application/json'},
- body : JSON.stringify({name: username, password: password})
- }, opts.ajax || {});
- utils.ajax(ajaxOpts, wrapError(callback));
-});
+// Previous uuid creation time
+var _lastMSecs = 0, _lastNSecs = 0;
-exports.logIn = exports.login;
+// See https://github.com/broofa/node-uuid for API details
+function v1(options, buf, offset) {
+ var i = buf && offset || 0;
+ var b = buf || [];
-exports.logout = utils.toPromise(function (opts, callback) {
- var db = this;
- if (typeof callback === 'undefined') {
- callback = opts;
- opts = {};
- }
- var ajaxOpts = utils.extend(true, {
- method : 'DELETE',
- url : utils.getSessionUrl(db)
- }, opts.ajax || {});
- utils.ajax(ajaxOpts, wrapError(callback));
-});
+ options = options || {};
-exports.logOut = exports.logout;
+ var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;
-exports.getSession = utils.toPromise(function (opts, callback) {
- var db = this;
- if (typeof callback === 'undefined') {
- callback = opts;
- opts = {};
- }
- var url = utils.getSessionUrl(db);
+ // 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();
- var ajaxOpts = utils.extend(true, {
- method : 'GET',
- url : url
- }, opts.ajax || {});
- utils.ajax(ajaxOpts, wrapError(callback));
-});
+ // 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;
-exports.getUser = utils.toPromise(function (username, opts, callback) {
- var db = this;
- if (typeof callback === 'undefined') {
- callback = typeof opts === 'undefined' ? username : opts;
- opts = {};
- }
- if (!username) {
- return callback(new AuthError('you must provide a username'));
- }
+ // Time since last uuid creation (in msecs)
+ var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;
- var url = utils.getUsersUrl(db);
- var ajaxOpts = utils.extend(true, {
- method : 'GET',
- url : url + '/' + encodeURIComponent('org.couchdb.user:' + username)
- }, opts.ajax || {});
- utils.ajax(ajaxOpts, wrapError(callback));
-});
+ // Per 4.2.1.2, Bump clockseq on clock regression
+ if (dt < 0 && options.clockseq === undefined) {
+ clockseq = clockseq + 1 & 0x3fff;
+ }
-exports.putUser = utils.toPromise(function (username, opts, callback) {
- var db = this;
- if (typeof callback === 'undefined') {
- callback = typeof opts === 'undefined' ? username : opts;
- opts = {};
+ // 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;
}
- if (['http', 'https'].indexOf(db.type()) === -1) {
- return callback(new AuthError('This plugin only works for the http/https adapter. ' +
- 'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
- } else if (!username) {
- return callback(new AuthError('You must provide a username'));
+
+ // 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');
}
- return db.getUser(username, opts, function (error, user) {
- if (error) {
- return callback(error);
- }
+ _lastMSecs = msecs;
+ _lastNSecs = nsecs;
+ _clockseq = clockseq;
- putUser(db, user, opts, callback);
- });
-});
+ // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
+ msecs += 12219292800000;
-exports.changePassword = utils.toPromise(function (username, password, opts, callback) {
- var db = this;
- if (typeof callback === 'undefined') {
- callback = typeof opts === 'undefined' ? (typeof password === 'undefined' ?
- username : password) : opts;
- opts = {};
- }
- if (['http', 'https'].indexOf(db.type()) === -1) {
- return callback(new AuthError('This plugin only works for the http/https adapter. ' +
- 'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
- } else if (!username) {
- return callback(new AuthError('You must provide a username'));
- } else if (!password) {
- return callback(new AuthError('You must provide a password'));
- }
+ // `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;
- return db.getUser(username, opts, function (error, user) {
- if (error) {
- return callback(error);
- }
+ // `time_mid`
+ var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
+ b[i++] = tmh >>> 8 & 0xff;
+ b[i++] = tmh & 0xff;
- user.password = password;
+ // `time_high_and_version`
+ b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
+ b[i++] = tmh >>> 16 & 0xff;
- var url = utils.getUsersUrl(db) + '/' + encodeURIComponent(user._id);
- var ajaxOpts = utils.extend(true, {
- method : 'PUT',
- url : url,
- body : user
- }, opts.ajax || {});
- utils.ajax(ajaxOpts, wrapError(callback));
- });
-});
+ // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
+ b[i++] = clockseq >>> 8 | 0x80;
-exports.changeUsername = utils.toPromise(function (oldUsername, newUsername, opts, callback) {
- var db = this;
- var USERNAME_PREFIX = 'org.couchdb.user:';
- var ajax = function (opts) {
- return new utils.Promise(function (resolve, reject) {
- utils.ajax(opts, wrapError(function (err, res) {
- if (err) {
- return reject(err);
- }
- resolve(res);
- }));
- });
- };
- var updateUser = function (user, opts) {
- var url = utils.getUsersUrl(db) + '/' + encodeURIComponent(user._id);
- var updateOpts = utils.extend(true, {
- method : 'PUT',
- url : url,
- body: user
- }, opts.ajax);
- return ajax(updateOpts);
- };
- if (typeof callback === 'undefined') {
- callback = opts;
- opts = {};
- }
- opts.ajax = opts.ajax || {};
- if (['http', 'https'].indexOf(db.type()) === -1) {
- return callback(new AuthError('This plugin only works for the http/https adapter. ' +
- 'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
- }
- if (!newUsername) {
- return callback(new AuthError('You must provide a new username'));
- }
- if (!oldUsername) {
- return callback(new AuthError('You must provide a username to rename'));
+ // `clock_seq_low`
+ b[i++] = clockseq & 0xff;
+
+ // `node`
+ var node = options.node || _nodeId;
+ for (var n = 0; n < 6; ++n) {
+ b[i + n] = node[n];
}
- return db.getUser(newUsername, opts)
- .then(function () {
- var error = new AuthError('user already exists');
- error.taken = true;
- throw error;
- }, function () {
- return db.getUser(oldUsername, opts);
- })
- .then(function (user) {
- var newUser = utils.clone(user);
- delete newUser._rev;
- newUser._id = USERNAME_PREFIX + newUsername;
- newUser.name = newUsername;
- newUser.roles = opts.roles || user.roles || {};
- return updateUser(newUser, opts).then(function () {
- user._deleted = true;
- return updateUser(user, opts);
- });
- }).then(function (res) {
- callback(null, res);
- }).catch(callback);
-});
+ return buf ? buf : bytesToUuid(b);
+}
+module.exports = v1;
-function AuthError(message) {
- this.status = 400;
- this.name = 'authentication_error';
- this.message = message;
- this.error = true;
- try {
- Error.captureStackTrace(this, AuthError);
- } catch (e) {}
-}
+},{"19":19,"20":20}],22:[function(require,module,exports){
+var rng = require(20);
+var bytesToUuid = require(19);
-utils.inherits(AuthError, Error);
+function v4(options, buf, offset) {
+ var i = buf && offset || 0;
-if (typeof window !== 'undefined' && window.PouchDB) {
- window.PouchDB.plugin(exports);
+ 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);
}
-},{"1":1}]},{},[17])(17)
+module.exports = v4;
+
+},{"19":19,"20":20}]},{},[1])(1)
});
\ No newline at end of file
diff --git a/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb.find.min.js b/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb.find.min.js
index 4e587fc..3b5ab84 100644
--- a/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb.find.min.js
+++ b/desuto-viewer/Desuto-webviewer/public/js/pouchdb/pouchdb.find.min.js
@@ -1,2 +1,5763 @@
-!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.pouchdbFind=e()}}(function(){var e;return function t(e,n,r){function o(u,a){if(!n[u]){if(!e[u]){var c="function"==typeof require&&require;if(!a&&c)return c(u,!0);if(i)return i(u,!0);var s=new Error("Cannot find module '"+u+"'");throw s.code="MODULE_NOT_FOUND",s}var f=n[u]={exports:{}};e[u][0].call(f.exports,function(t){var n=e[u][1][t];return o(n?n:t)},f,f.exports,t,e,n,r)}return n[u].exports}for(var i="function"==typeof require&&require,u=0;u<r.length;u++)o(r[u]);return o}({1:[function(e,t,n){"use strict";function r(e){if(!e)return"undefined";switch(typeof e){case"function":return e.toString();case"string":return e.toString();default:return JSON.stringify(e)}}var o=e(4),i=e(5),u=i.Promise;t.exports=function(e){var t=e.db,n=e.viewName,a=e.map,c=e.reduce,s=e.temporary,f=e.pluginName,l=r(a)+r(c)+"undefined";if(!s&&t._cachedViews){var d=t._cachedViews[l];if(d)return u.resolve(d)}return t.info().then(function(e){function r(e){e.views=e.views||{};var t=n;-1===t.indexOf("/")&&(t=n+"/"+n);var r=e.views[t]=e.views[t]||{};if(!r[u])return r[u]=!0,e}var u=e.db_name+"-mrview-"+(s?"temp":i.MD5(l));return o(t,"_local/"+f,r).then(function(){return t.registerDependentDatabase(u).then(function(e){var n=e.db;n.auto_compaction=!0;var r={name:u,db:n,sourceDB:t,adapter:t.adapter,mapFun:a,reduceFun:c};return r.db.get("_local/lastSeq")["catch"](function(e){if(404!==e.status)throw e}).then(function(e){return r.seq=e?e.seq:0,s||(t._cachedViews=t._cachedViews||{},t._cachedViews[l]=r,r.db.on("destroyed",function(){delete t._cachedViews[l]})),r})})})})}},{4:4,5:5}],2:[function(e,t,n){(function(n){"use strict";function r(e){this.status=400,this.name="query_parse_error",this.message=e,this.error=!0;try{Error.captureStackTrace(this,r)}catch(t){}}function o(e){this.status=404,this.name="not_found",this.message=e,this.error=!0;try{Error.captureStackTrace(this,o)}catch(t){}}function i(e){return-1===e.indexOf("/")?[e,e]:e.split("/")}function u(e){return 1===e.length&&/^1-/.test(e[0].rev)}function a(e,t){var n=m(e.key,t.key);return 0!==n?n:m(e.value,t.value)}function c(e,t,n){return n=n||0,"number"==typeof t?e.slice(n,t+n):n>0?e.slice(n):e}function s(e){var t=e.value,n=t&&"object"==typeof t&&t._id||e.id;return n}function f(e,t){try{e.emit("error",t)}catch(n){console.error("The user's map/reduce function threw an uncaught error.\nYou can debug this error by doing:\nmyDatabase.on('error', function (err) { debugger; });\nPlease double-check your map/reduce function."),console.error(t)}}function l(e,t,n){try{return{output:t.apply(null,n)}}catch(r){return f(e,r),{error:r}}}function d(e,t){var n=e.descending?"endkey":"startkey",o=e.descending?"startkey":"endkey";if("undefined"!=typeof e[n]&&"undefined"!=typeof e[o]&&m(e[n],e[o])>0)throw new r("No rows can match your key range, reverse your start_key and end_key or set {descending : true}");if(t.reduce&&e.reduce!==!1){if(e.include_docs)throw new r("{include_docs:true} is invalid for reduce");if(e.keys&&e.keys.length>1&&!e.group&&!e.group_level)throw new r("Multi-key fetches for reduce views must use {group: true}")}if(e.group_level){if("number"!=typeof e.group_level)throw new r('Invalid value for integer: "'+e.group_level+'"');if(e.group_level<0)throw new r('Invalid value for positive integer: "'+e.group_level+'"')}}function h(e){return function(t){if(404===t.status)return e;throw t}}function p(e){function t(e,t,n){function r(){return u(l)?x.resolve(c):t.db.get(a)["catch"](h(c))}function o(e){return e.keys.length?t.db.allDocs({keys:e.keys,include_docs:!0}):x.resolve({rows:[]})}function i(e,t){for(var n=[],r={},o=0,i=t.rows.length;i>o;o++){var u=t.rows[o],a=u.doc;if(a&&(n.push(a),r[a._id]=!0,a._deleted=!f[a._id],!a._deleted)){var c=f[a._id];"value"in c&&(a.value=c.value)}}var s=Object.keys(f);return s.forEach(function(e){if(!r[e]){var t={_id:e},o=f[e];"value"in o&&(t.value=o.value),n.push(t)}}),e.keys=_.uniq(s.concat(e.keys)),n.push(e),n}var a="_local/doc_"+e,c={_id:a,keys:[]},s=n[e],f=s.indexableKeysToKeyValues,l=s.changes;return r().then(function(e){return o(e).then(function(t){return i(e,t)})})}function r(e,n,r){var o="_local/lastSeq";return e.db.get(o)["catch"](h({_id:o,seq:0})).then(function(o){var i=Object.keys(n);return x.all(i.map(function(r){return t(r,e,n)})).then(function(t){var n=_.flatten(t);return o.seq=r,n.push(o),e.db.bulkDocs({docs:n})})})}function f(e){var t="string"==typeof e?e:e.name,n=$[t];return n||(n=$[t]=new g),n}function p(e){return _.sequentialize(f(e),function(){return y(e)})()}function y(e){function t(e,t){var n={id:i._id,key:w(e)};"undefined"!=typeof t&&null!==t&&(n.value=w(t)),o.push(n)}function n(t,n){return function(){return r(e,t,n)}}var o,i,u=D(e.mapFun,t),c=e.seq||0,s=new g;return new x(function(t,r){function f(){s.finish().then(function(){e.seq=c,t()})}function d(){function t(e){r(e)}e.sourceDB.changes({conflicts:!0,include_docs:!0,style:"all_docs",since:c,limit:O}).on("complete",function(t){var r=t.results;if(!r.length)return f();for(var h={},p=0,y=r.length;y>p;p++){var v=r[p];if("_"!==v.doc._id[0]){o=[],i=v.doc,i._deleted||l(e.sourceDB,u,[i]),o.sort(a);for(var g,w={},k=0,_=o.length;_>k;k++){var x=o[k],$=[x.key,x.id];0===m(x.key,g)&&$.push(k);var j=b($);w[j]=x,g=x.key}h[v.doc._id]={indexableKeysToKeyValues:w,changes:v.changes}}c=v.seq}return s.add(n(h,c)),r.length<O?f():d()}).on("error",t)}d()})}function A(e,t,n){0===n.group_level&&delete n.group_level;var r=n.group||n.group_level,o=M(e.reduceFun),i=[],u=n.group_level;t.forEach(function(e){var t=i[i.length-1],n=r?e.key:null;return r&&Array.isArray(n)&&"number"==typeof u&&(n=n.length>u?n.slice(0,u):n),t&&0===m(t.key[0][0],n)?(t.key.push([n,e.id]),void t.value.push(e.value)):void i.push({key:[[n,e.id]],value:[e.value]})});for(var a=0,s=i.length;s>a;a++){var f=i[a],d=l(e.sourceDB,o,[f.key,f.value,!1]);if(d.error&&/BuiltInError/.test(d.error.constructor))throw d.error;f.value=d.error?null:d.output,f.key=f.key[0][0]}return{rows:c(i,n.limit,n.skip)}}function E(e,t){return _.sequentialize(f(e),function(){return q(e,t)})()}function q(e,t){function n(t){return t.include_docs=!0,e.db.allDocs(t).then(function(e){return o=e.total_rows,e.rows.map(function(e){if("value"in e.doc&&"object"==typeof e.doc.value&&null!==e.doc.value){var t=Object.keys(e.doc.value).sort(),n=["id","key","value"];if(!(n>t||t>n))return e.doc.value}var r=v.parseIndexableString(e.doc._id);return{key:r[0],id:r[1],value:"value"in e.doc?e.doc.value:null}})})}function r(n){var r;if(r=i?A(e,n,t):{total_rows:o,offset:u,rows:n},t.include_docs){var a=_.uniq(n.map(s));return e.sourceDB.allDocs({keys:a,include_docs:!0,conflicts:t.conflicts,attachments:t.attachments,binary:t.binary}).then(function(e){var t={};return e.rows.forEach(function(e){e.doc&&(t["$"+e.id]=e.doc)}),n.forEach(function(e){var n=s(e),r=t["$"+n];r&&(e.doc=r)}),r})}return r}var o,i=e.reduceFun&&t.reduce!==!1,u=t.skip||0;"undefined"==typeof t.keys||t.keys.length||(t.limit=0,delete t.keys);var a=function(e){return e.reduce(function(e,t){return e.concat(t)})};if("undefined"!=typeof t.keys){var c=t.keys,f=c.map(function(e){var t={startkey:b([e]),endkey:b([e,{}])};return n(t)});return x.all(f).then(a).then(r)}var l={descending:t.descending};if("undefined"!=typeof t.startkey&&(l.startkey=b(t.descending?[t.startkey,{}]:[t.startkey])),"undefined"!=typeof t.endkey){var d=t.inclusive_end!==!1;t.descending&&(d=!d),l.endkey=b(d?[t.endkey,{}]:[t.endkey])}if("undefined"!=typeof t.key){var h=b([t.key]),p=b([t.key,{}]);l.descending?(l.endkey=h,l.startkey=p):(l.startkey=h,l.endkey=p)}return i||("number"==typeof t.limit&&(l.limit=t.limit),l.skip=u),n(l).then(r)}function F(e){return e.get("_local/"+S).then(function(t){var n={};Object.keys(t.views).forEach(function(e){var t=i(e),r="_design/"+t[0],o=t[1];n[r]=n[r]||{},n[r][o]=!0});var r={keys:Object.keys(n),include_docs:!0};return e.allDocs(r).then(function(r){var o={};r.rows.forEach(function(e){var r=e.key.substring(8);Object.keys(n[e.key]).forEach(function(n){var i=r+"/"+n;t.views[i]||(i=n);var u=Object.keys(t.views[i]),a=e.doc&&e.doc.views&&e.doc.views[n];u.forEach(function(e){o[e]=o[e]||a})})});var i=Object.keys(o).filter(function(e){return!o[e]}),u=i.map(function(t){return _.sequentialize(f(t),function(){return new e.constructor(t,e.__opts).destroy()})()});return x.all(u).then(function(){return{ok:!0}})})},h({ok:!0}))}function I(e,t,r){if("string"!=typeof t){d(r,t);var u={db:e,viewName:"temp_view/temp_view",map:t.map,reduce:t.reduce,temporary:!0,pluginName:S};return j.add(function(){return k(u).then(function(e){function t(){return e.db.destroy()}return _.fin(p(e).then(function(){return E(e,r)}),t)})}),j.finish()}var a=t,c=i(a),s=c[0],f=c[1];return e.get("_design/"+s).then(function(t){var i=t.views&&t.views[f];if(!i)throw new o("ddoc "+t._id+" has no view named "+f);C(t,f),d(r,i);var u={db:e,viewName:a,map:i.map,reduce:i.reduce,pluginName:S};return k(u).then(function(e){return"ok"===r.stale||"update_after"===r.stale?("update_after"===r.stale&&n.nextTick(function(){p(e)}),E(e,r)):p(e).then(function(){return E(e,r)})})})}var S=e.name,D=e.mapper,M=e.reducer,C=e.ddocValidator,T=function(e,t,n){var r=this;"function"==typeof t&&(n=t,t={}),t=_.extend(!0,{},t),"function"==typeof e&&(e={map:e});var o=x.resolve().then(function(){return I(r,e,t)});return _.promisedCallback(o,n),o},B=_.callbackify(function(){var e=this;return F(e)});return{query:T,viewCleanup:B}}var y,v=e(26),g=e(3),m=v.collate,b=v.toIndexableString,w=v.normalizeKey,k=e(1);y="undefined"!=typeof console&&"function"==typeof console.log?Function.prototype.bind.call(console.log,console):function(){};var _=e(5),x=_.Promise,$={},j=new g,O=50;_.inherits(r,Error),_.inherits(o,Error),t.exports=p}).call(this,e(34))},{1:1,26:26,3:3,34:34,5:5}],3:[function(e,t,n){"use strict";function r(){this.promise=new o(function(e){e()})}var o=e(5).Promise;r.prototype.add=function(e){return this.promise=this.promise["catch"](function(){}).then(function(){return e()}),this.promise},r.prototype.finish=function(){return this.promise},t.exports=r},{5:5}],4:[function(e,t,n){"use strict";var r=e(31).upsert;t.exports=function(e,t,n){return r.apply(e,[t,n])}},{31:31}],5:[function(e,t,n){(function(t){"use strict";n.Promise=e(29),n.inherits=e(23),n.extend=e(28);var r=e(18);n.promisedCallback=function(e,n){return n&&e.then(function(e){t.nextTick(function(){n(null,e)})},function(e){t.nextTick(function(){n(e)})}),e},n.callbackify=function(e){return r(function(t){var r=t.pop(),o=e.apply(this,t);return"function"==typeof r&&n.promisedCallback(o,r),o})},n.fin=function(e,t){return e.then(function(e){var n=t();return"function"==typeof n.then?n.then(function(){return e}):e},function(e){var n=t();if("function"==typeof n.then)return n.then(function(){throw e});throw e})},n.sequentialize=function(e,t){return function(){var n=arguments,r=this;return e.add(function(){return t.apply(r,n)})}},n.flatten=function(e){for(var t=[],n=0,r=e.length;r>n;n++)t=t.concat(e[n]);return t},n.uniq=function(e){for(var t={},n=0,r=e.length;r>n;n++)t["$"+e[n]]=!0;var o=Object.keys(t),i=new Array(o.length);for(n=0,r=o.length;r>n;n++)i[n]=o[n].substring(1);return i};var o=e(19),i=e(35);n.MD5=function(e){return t.browser?i.hash(e):o.createHash("md5").update(e).digest("hex")}}).call(this,e(34))},{18:18,19:19,23:23,28:28,29:29,34:34,35:35}],6:[function(e,t,n){"use strict";function r(e,t,n){t=a(t),e.request({method:"POST",url:"_index",body:t},n)}function o(e,t,n){e.request({method:"POST",url:"_find",body:t},n)}function i(e,t){e.request({method:"GET",url:"_index"},t)}function u(e,t,n){var r=t.ddoc,o=t.type||"json",i=t.name;if(!r)return n(new Error("you must provide an index's ddoc"));if(!i)return n(new Error("you must provide an index's name"));var u="_index/"+[r,o,i].map(encodeURIComponent).join("/");e.request({method:"DELETE",url:u},n)}var a=e(16);n.createIndex=r,n.find=o,n.getIndexes=i,n.deleteIndex=u},{16:16}],7:[function(e,t,n){"use strict";function r(e,t){return function(n){for(var r=[],o=0,i=e.length;i>o;o++){for(var u=p(e[o]),a=n,c=0,s=u.length;s>c;c++){var f=u[c];if(a=a[f],!a)break}r.push(a)}t(r)}}function o(e,t){var n=p(e);return function(e){for(var r=e,o=0,i=n.length;i>o;o++){var u=n[o];if(r=r[u],!r)return}t(r)}}function i(e,t){return function(n){t(n[e])}}function u(e,t){return function(n){for(var r=[],o=0,i=e.length;i>o;o++)r.push(n[e[o]]);t(r)}}function a(e){for(var t=0,n=e.length;n>t;t++){var r=e[t];if(-1!==r.indexOf("."))return!1}return!0}function c(e,t){var n=a(e),c=1===e.length;return n?c?i(e[0],t):u(e,t):c?o(e[0],t):r(e,t)}function s(e,t){var n=Object.keys(e.fields);return c(n,t)}function f(){throw new Error("reduce not supported")}function l(e,t){var n=e.views[t];if(!n.map||!n.map.fields)throw new Error("ddoc "+e._id+" with view "+t+" doesn't have map.fields defined. maybe it wasn't created by this plugin?")}var d=e(15),h=e(2),p=d.parseField,y=h({name:"indexes",mapper:s,reducer:f,ddocValidator:l});t.exports=y},{15:15,2:2}],8:[function(e,t,n){"use strict";function r(e,t,n){return a.upsert.call(e,t,n)}function o(e,t){function n(e){return e._rev&&"query"!==e.language&&(y=!0),e.language="query",e.views=e.views||{},(v=!!e.views[s])?!1:(e.views[s]={map:{fields:i.mergeObjects(t.index.fields)},reduce:"_count",options:{def:o}},e)}t=d(t);var o=i.clone(t.index);t.index=l(t.index),f(t.index);var a=i.MD5(JSON.stringify(t)),s=t.name||"idx-"+a,h=t.ddoc||"idx-"+a,p="_design/"+h,y=!1,v=!1;return u("creating index",p),r(e,p,n).then(function(){if(y)throw new Error('invalid language for ddoc with id "'+p+'" (should be "query")')}).then(function(){var t=h+"/"+s;return c.query.call(e,t,{limit:0,reduce:!1}).then(function(){return{id:p,name:s,result:v?"exists":"created"}})})}var i=e(17),u=i.log,a=e(31),c=e(7),s=e(15),f=s.validateIndex,l=s.massageIndexDef,d=e(16);t.exports=o},{15:15,16:16,17:17,31:31,7:7}],9:[function(e,t,n){"use strict";function r(e,t){function n(e){return 1===Object.keys(e.views).length&&e.views[u]?{_id:r,_deleted:!0}:(delete e.views[u],e)}if(!t.ddoc)throw new Error("you must supply an index.ddoc when deleting");if(!t.name)throw new Error("you must supply an index.name when deleting");var r=t.ddoc,u=t.name;return i(e,r,n).then(function(){return o.viewCleanup.apply(e)}).then(function(){return{ok:!0}})}var o=e(7),i=e(4);t.exports=r},{4:4,7:7}],10:[function(e,t,n){"use strict";function r(e){function t(t){return e.map(function(e){var n=k(e),r=x(n),o=j(t,r);return o})}return function(e,n){var r=t(e.doc),o=t(n.doc),i=m(r,o);return 0!==i?i:$.compare(e.doc._id,n.doc._id)}}function o(e,t,n){if(e=e.filter(function(e){return i(e.doc,t.selector,n)}),t.sort){var o=r(t.sort);e=e.sort(o),"string"!=typeof t.sort[0]&&"desc"===_(t.sort[0])&&(e=e.reverse())}if("limit"in t||"skip"in t){var u=t.skip||0,a=("limit"in t?t.limit:e.length)+u;e=e.slice(u,a)}return e}function i(e,t,n){return n.every(function(n){var r=t[n],o=x(n),i=j(e,o);return w(n)?a(n,r,e):u(r,e,o,i)})}function u(e,t,n,r){return e?Object.keys(e).every(function(o){var i=e[o];return c(o,t,i,n,r)}):!0}function a(e,t,n){return"$or"===e?t.some(function(e){return i(n,e,Object.keys(e))}):"$not"===e?!i(n,t,Object.keys(t)):!t.find(function(e){return i(n,e,Object.keys(e))})}function c(e,t,n,r,o){if(!O[e])throw new Error('unknown operator "'+e+'" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, $nin, $size, $mod, $regex, $elemMatch, $type or $all');return O[e](t,n,r,o)}function s(e){return"undefined"!=typeof e&&null!==e}function f(e){return"undefined"!=typeof e}function l(e,t){var n=t[0],r=t[1];if(0===n)throw new Error("Bad divisor, cannot divide by zero");if(parseInt(n,10)!==n)throw new Error("Divisor is not an integer");if(parseInt(r,10)!==r)throw new Error("Modulus is not an integer");return parseInt(e,10)!==e?!1:e%n===r}function d(e,t){return t.some(function(t){return e instanceof Array?e.indexOf(t)>-1:e===t})}function h(e,t){return t.every(function(t){return e.indexOf(t)>-1})}function p(e,t){return e.length===t}function y(e,t){var n=new RegExp(t);return n.test(e)}function v(e,t){switch(t){case"null":return null===e;case"boolean":return"boolean"==typeof e;case"number":return"number"==typeof e;case"string":return"string"==typeof e;case"array":return e instanceof Array;case"object":return"[object Object]"==={}.toString.call(e)}throw new Error(t+" not supported as a type.Please use one of object, string, array, number, boolean or null.")}var g=e(24),m=e(26).collate,b=e(15),w=b.isCombinationalField,k=b.getKey,_=b.getValue,x=b.parseField,$=e(17),j=$.getFieldFromDoc,O={$elemMatch:function(e,t,n,r){return g(r)?0===r.length?!1:"object"==typeof r[0]?r.some(function(e){return i(e,t,Object.keys(t))}):r.some(function(r){return u(t,e,n,r)}):!1},$eq:function(e,t,n,r){return f(r)&&0===m(r,t)},$gte:function(e,t,n,r){return f(r)&&m(r,t)>=0},$gt:function(e,t,n,r){return f(r)&&m(r,t)>0},$lte:function(e,t,n,r){return f(r)&&m(r,t)<=0},$lt:function(e,t,n,r){return f(r)&&m(r,t)<0},$exists:function(e,t,n,r){return t?f(r):!f(r)},$mod:function(e,t,n,r){return s(r)&&l(r,t)},$ne:function(e,t,n,r){return t.every(function(e){return 0!==m(r,e)})},$in:function(e,t,n,r){return s(r)&&d(r,t)},$nin:function(e,t,n,r){return s(r)&&!d(r,t)},$size:function(e,t,n,r){return s(r)&&p(r,t)},$all:function(e,t,n,r){return g(r)&&h(r,t)},$regex:function(e,t,n,r){return s(r)&&y(r,t)},$type:function(e,t,n,r){return v(r,t)}};t.exports=o},{15:15,17:17,24:24,26:26}],11:[function(e,t,n){"use strict";function r(e){return e.ddoc.substring(8)+"/"+e.name}function o(e,t){var n=a(t);return n.descending?("endkey"in n&&"string"!=typeof n.endkey&&(n.endkey=""),"startkey"in n&&"string"!=typeof n.startkey&&(n.limit=0)):("startkey"in n&&"string"!=typeof n.startkey&&(n.startkey=""),"endkey"in n&&"string"!=typeof n.endkey&&(n.limit=0)),"key"in n&&"string"!=typeof n.key&&(n.limit=0),e.allDocs(n)}function i(e,t){return t.selector&&(t.selector=p(t.selector)),t.sort&&(t.sort=y(t.sort)),g(t),c(e).then(function(n){var i=l(t,n.indexes),a=i.index;m(t,a);var c=u.extend(!0,{include_docs:!0,reduce:!1},i.queryOpts);if("startkey"in c&&"endkey"in c&&s(c.startkey,c.endkey)>0)return{docs:[]};var d=t.sort&&"string"!=typeof t.sort[0]&&"desc"===v(t.sort[0]);return d&&(c.descending=!0,c=b(c)),i.inMemoryFields.length||("limit"in t&&(c.limit=t.limit),"skip"in t&&(c.skip=t.skip)),k.resolve().then(function(){if("_all_docs"===a.name)return o(e,c);var t=r(a);return f.query.call(e,t,c)}).then(function(e){c.inclusive_start===!1&&(e.rows=w(e.rows,c.startkey,a)),i.inMemoryFields.length&&(e.rows=h(e.rows,t,i.inMemoryFields));var n={docs:e.rows.map(function(e){var n=e.doc;return t.fields?u.pick(n,t.fields):n})};return a.defaultUsed&&(n.warning="no matching index found, create an index to optimize query time"),n})})}var u=e(17),a=u.clone,c=e(13),s=e(26).collate,f=e(7),l=e(12),d=e(15),h=e(10),p=d.massageSelector,y=d.massageSort,v=d.getValue,g=d.validateFindRequest,m=d.validateSort,b=d.reverseOptions,w=d.filterInclusiveStart,k=u.Promise;t.exports=i},{10:10,12:12,13:13,15:15,17:17,26:26,7:7}],12:[function(e,t,n){"use strict";function r(e,t){for(var n=e.def.fields.map(j),r=0,o=n.length;o>r;r++){var i=n[r];if(t===i)return!0}return!1}function o(e,t){var n=e[t],r=j(n);return"$eq"!==r}function i(e,t){var n=t.def.fields.map(j);return e.slice().sort(function(e,t){var r=n.indexOf(e),o=n.indexOf(t);return-1===r&&(r=Number.MAX_VALUE),-1===o&&(o=Number.MAX_VALUE),_.compare(r,o)})}function u(e,t,n){n=i(n,e);for(var u=!1,a=0,c=n.length;c>a;a++){var s=n[a];if(u||!r(e,s))return n.slice(a);c-1>a&&o(t,s)&&(u=!0)}return[]}function a(e){var t=[];return Object.keys(e).forEach(function(n){var r=e[n];Object.keys(r).forEach(function(e){"$ne"===e&&t.push(n)})}),t}function c(e,t,n,r){var o=_.flatten(e,u(t,n,r),a(n));return i(_.uniq(o),t)}function s(e,t,n){if(t){var r=_.oneArrayIsStrictSubArrayOfOther(t,e),o=_.oneArrayIsSubArrayOfOther(n,e);return r&&o}return _.oneSetIsSubArrayOfOther(n,e)}function f(e){return-1===q.indexOf(e)}function l(e,t){var n=e[0],r=t[n],o=Object.keys(r).some(function(e){return!f(e)});if(!o)return!1;var i=1===Object.keys(r).length&&"$ne"===j(r);return!i}function d(e,t,n,r){var o=e.def.fields.map(j),i=s(o,t,n);return i?l(o,r):!1}function h(e,t,n,r){return r.reduce(function(r,o){var i=d(o,n,t,e);return i&&r.push(o),r},[])}function p(e,t,n,r){function o(e){for(var t=e.def.fields.map(j),n=0,r=0,o=t.length;o>r;r++){var i=t[r];a[i]&&n++}return n}var i=h(e,t,n,r);if(0===i.length){var u=r[0];return u.defaultUsed=!0,u}if(1===i.length)return i[0];var a=_.arrayToObject(t);return _.max(i,o)}function y(e,t){switch(e){case"$eq":return{key:t};case"$lte":return{endkey:t};case"$gte":return{startkey:t};case"$lt":return{endkey:t,inclusive_end:!1};case"$gt":return{startkey:t,inclusive_start:!1}}}function v(e,t){var n,r=j(t.def.fields[0]),o=e[r],i=[],u=Object.keys(o);return u.forEach(function(e){if(f(e))return void i.push(r);var t=o[e],u=y(e,t);n=n?_.mergeObjects([n,u]):u}),{queryOpts:n,inMemoryFields:i}}function g(e,t){switch(e){case"$eq":return{startkey:t,endkey:t};case"$lte":return{endkey:t};case"$gte":return{startkey:t};case"$lt":return{endkey:t,inclusive_end:!1};case"$gt":return{startkey:t,inclusive_start:!1}}}function m(e,t){function n(e){r!==!1&&a.push(A),o!==!1&&c.push(E),u=i.slice(e)}for(var r,o,i=t.def.fields.map(j),u=[],a=[],c=[],s=0,f=i.length;f>s;s++){var l=i[s],d=e[l];if(!d){n(s);break}if(s>0){if("$ne"in d){n(s);break}var h="$gt"in d||"$gte"in d||"$lt"in d||"$lte"in d,p=Object.keys(e[i[s-1]]),y=_.arrayEquals(p,["$eq"]),v=_.arrayEquals(p,Object.keys(d)),m=h&&!y&&!v;if(m){n(s);break}}for(var b=Object.keys(d),w=null,k=0;k<b.length;k++){var x=b[k],$=d[x],O=g(x,$);w=w?_.mergeObjects([w,O]):O}a.push("startkey"in w?w.startkey:A),c.push("endkey"in w?w.endkey:E),"inclusive_start"in w&&(r=w.inclusive_start),"inclusive_end"in w&&(o=w.inclusive_end)}var q={startkey:a,endkey:c};return"undefined"!=typeof r&&(q.inclusive_start=r),"undefined"!=typeof o&&(q.inclusive_end=o),{queryOpts:q,inMemoryFields:u}}function b(){return{queryOpts:{startkey:null},inMemoryFields:[]}}function w(e,t){return t.defaultUsed?b(e,t):1===t.def.fields.length?v(e,t):m(e,t)}function k(e,t){x("planning query",e);var n=e.selector,r=e.sort,o=O(n,r),i=o.fields,u=o.sortOrder,a=p(n,i,u,t),s=w(n,a),f=s.queryOpts,l=s.inMemoryFields,d=c(l,a,n,i),h={queryOpts:f,index:a,inMemoryFields:d};return x("query plan",h),h}var _=e(17),x=_.log,$=e(15),j=$.getKey,O=$.getUserFields,A=null,E={"￿":{}},q=["$eq","$gt","$gte","$lt","$lte"];t.exports=k},{15:15,17:17}],13:[function(e,t,n){"use strict";function r(e){return e.allDocs({startkey:"_design/",endkey:"_design/￿",include_docs:!0}).then(function(e){var t={indexes:[{ddoc:null,name:"_all_docs",type:"special",def:{fields:[{_id:"asc"}]}}]};return t.indexes=o.flatten(t.indexes,e.rows.filter(function(e){return"query"===e.doc.language}).map(function(e){var t=void 0!==e.doc.views?Object.keys(e.doc.views):[];return t.map(function(t){var n=e.doc.views[t];return{ddoc:e.id,name:t,type:"json",def:u(n.options.def)}})})),t.indexes.sort(function(e,t){return o.compare(e.name,t.name)}),t.total_rows=t.indexes.length,t})}var o=e(17),i=e(15),u=i.massageIndexDef;t.exports=r},{15:15,17:17}],14:[function(e,t,n){"use strict";var r=e(17),o=r.callbackify;n.createIndex=o(e(8)),n.find=o(e(11)),n.getIndexes=o(e(13)),n.deleteIndex=o(e(9))},{11:11,13:13,17:17,8:8,9:9}],15:[function(e,t,n){"use strict";function r(e){return Object.keys(e)[0]}function o(e){return e[r(e)]}function i(e){if(!Array.isArray(e))throw new Error("invalid sort json - should be an array");return e.map(function(e){if("string"==typeof e){var t={};return t[e]="asc",t}return e})}function u(e){return x.indexOf(e)>-1}function a(e,t,n){"undefined"==typeof n.$eq&&("undefined"!=typeof n.$gte?"$gte"===e?t>n.$gte&&(n.$gte=t):t>=n.$gte&&(delete n.$gte,n.$gt=t):"undefined"!=typeof n.$gt?"$gte"===e?t>n.$gt&&(delete n.$gt,n.$gte=t):t>n.$gt&&(n.$gt=t):n[e]=t)}function c(e,t,n){"undefined"==typeof n.$eq&&("undefined"!=typeof n.$lte?"$lte"===e?t<n.$lte&&(n.$lte=t):t<=n.$lte&&(delete n.$lte,n.$lt=t):"undefined"!=typeof n.$lt?"$lte"===e?t<n.$lt&&(delete n.$lt,n.$lte=t):t<n.$lt&&(n.$lt=t):n[e]=t)}function s(e,t){"$ne"in t?t.$ne.push(e):t.$ne=[e]}function f(e,t){delete t.$gt,delete t.$gte,delete t.$lt,delete t.$lte,delete t.$ne,t.$eq=e}function l(e){var t={};return e.forEach(function(e){Object.keys(e).forEach(function(n){var r=e[n];if("object"!=typeof r&&(r={$eq:r}),u(n))r instanceof Array?t[n]=r.map(function(e){return l([e])}):t[n]=l([r]);else{var o=t[n]=t[n]||{};Object.keys(r).forEach(function(e){var t=r[e];return"$gt"===e||"$gte"===e?a(e,t,o):"$lt"===e||"$lte"===e?c(e,t,o):"$ne"===e?s(t,o):"$eq"===e?f(t,o):void(o[e]=t)})}})}),t}function d(e){var t=k.clone(e),n=!1;"$and"in t&&(t=l(t.$and),n=!0),"$not"in t&&(t.$not=l([t.$not]));for(var r=Object.keys(t),o=0;o<r.length;o++){var i=r[o],u=t[i];"object"!=typeof u||null===u?u={$eq:u}:"$ne"in u&&!n&&(u.$ne=[u.$ne]),t[i]=u}return t}function h(e){return e.fields=e.fields.map(function(e){if("string"==typeof e){var t={};return t[e]="asc",t}return e}),e}function p(e,t){for(var n=[],o=0;o<t.def.fields.length;o++){var i=r(t.def.fields[o]);n.push(e[i])}return n}function y(e,t,n){for(var r=n.def.fields,o=0,i=e.length;i>o;o++){var u=e[o],a=p(u.doc,n);if(1===r.length)a=a[0];else for(;a.length>t.length;)a.pop();if(Math.abs(_.collate(a,t))>0)break}return o>0?e.slice(o):e}function v(e){var t=k.clone(e);return delete t.startkey,delete t.endkey,delete t.inclusive_start,delete t.inclusive_end,"endkey"in e&&(t.startkey=e.endkey),"startkey"in e&&(t.endkey=e.startkey),"inclusive_start"in e&&(t.inclusive_end=e.inclusive_start),"inclusive_end"in e&&(t.inclusive_start=e.inclusive_end),t}function g(e){var t=e.fields.filter(function(e){return"asc"===o(e)});if(0!==t.length&&t.length!==e.fields.length)throw new Error("unsupported mixed sorting")}function m(e,t){if(t.defaultUsed&&e.sort){var n=e.sort.filter(function(e){return"_id"!==Object.keys(e)[0]}).map(function(e){return Object.keys(e)[0]});if(n.length>0)throw new Error('Cannot sort on field(s) "'+n.join(",")+'" when using the default index')}t.defaultUsed}function b(e){if("object"!=typeof e.selector)throw new Error("you must provide a selector when you find()")}function w(e,t){var n,o=Object.keys(e),i=t?t.map(r):[];return n=o.length>=i.length?o:i,0===i.length?{fields:n}:(n=n.sort(function(e,t){var n=i.indexOf(e);-1===n&&(n=Number.MAX_VALUE);var r=i.indexOf(t);return-1===r&&(r=Number.MAX_VALUE),r>n?-1:n>r?1:0}),{fields:n,sortOrder:t.map(r)})}var k=e(17),_=e(26),x=["$or","$nor","$not"];t.exports={getKey:r,getValue:o,massageSort:i,massageSelector:d,validateIndex:g,validateFindRequest:b,validateSort:m,reverseOptions:v,filterInclusiveStart:y,massageIndexDef:h,parseField:k.parseField,getUserFields:w,isCombinationalField:u}},{17:17,26:26}],16:[function(e,t,n){"use strict";var r=e(17),o=r.clone;t.exports=function(e){return e=o(e),e.index||(e.index={}),["type","name","ddoc"].forEach(function(t){e.index[t]&&(e[t]=e.index[t],delete e.index[t])}),e.fields&&(e.index.fields=e.fields,delete e.fields),e.type||(e.type="json"),e}},{17:17}],17:[function(e,t,n){(function(t){"use strict";var r=e(29);n.once=function(e){var t=!1;return n.getArguments(function(n){if(t)throw console.trace(),new Error("once called more than once");t=!0,e.apply(this,n)})},n.getArguments=function(e){return function(){for(var t=arguments.length,n=new Array(t),r=-1;++r<t;)n[r]=arguments[r];return e.call(this,n)}},n.toPromise=function(e){return n.getArguments(function(o){var i,u=this,a="function"==typeof o[o.length-1]?o.pop():!1;a&&(i=function(e,n){t.nextTick(function(){a(e,n)})});var c=new r(function(t,r){try{var i=n.once(function(e,n){e?r(e):t(n)});o.push(i),e.apply(u,o)}catch(a){r(a)}});return i&&c.then(function(e){i(null,e)},i),c.cancel=function(){return this},c})},n.inherits=e(23),n.Promise=r,n.clone=function(e){return n.extend(!0,{},e)},n.extend=e(28),n.callbackify=function(e){return n.getArguments(function(t){var r=t.pop(),o=e.apply(this,t);return n.promisedCallback(o,r),o})},n.promisedCallback=function(e,n){return e.then(function(e){t.nextTick(function(){n(null,e)})},function(e){t.nextTick(function(){n(e)})}),e};var o=e(19),i=e(35);n.MD5=function(e){return t.browser?i.hash(e):o.createHash("md5").update(e).digest("hex")},n.flatten=n.getArguments(function(e){for(var t=[],r=0,o=e.length;o>r;r++){var i=e[r];Array.isArray(i)?t=t.concat(n.flatten.apply(null,i)):t.push(i)}return t}),n.mergeObjects=function(e){for(var t={},r=0,o=e.length;o>r;r++)t=n.extend(!0,t,e[r]);return t},n.getFieldFromDoc=function(e,t){for(var n=e,r=0,o=t.length;o>r;r++){var i=t[r];if(n=n[i],!n)break}return n},n.setFieldInDoc=function(e,t,n){for(var r=0,o=t.length;o-1>r;r++){var i=t[r];e=e[i]={}}e[t[o-1]]=n},n.parseField=function(e){for(var t=[],n="",r=0,o=e.length;o>r;r++){var i=e[r];"."===i?r>0&&"\\"===e[r-1]?n=n.substring(0,n.length-1)+".":(t.push(n),n=""):n+=i}return t.push(n),t},n.pick=function(e,t){for(var r={},o=0,i=t.length;i>o;o++){var u=n.parseField(t[o]),a=n.getFieldFromDoc(e,u);"undefined"!=typeof a&&n.setFieldInDoc(r,u,a)}return r},n.oneArrayIsSubArrayOfOther=function(e,t){for(var n=0,r=Math.min(e.length,t.length);r>n;n++)if(e[n]!==t[n])return!1;return!0},n.oneArrayIsStrictSubArrayOfOther=function(e,t){return e.length>t.length?!1:n.oneArrayIsSubArrayOfOther(e,t)},n.oneSetIsSubArrayOfOther=function(e,t){e=e.slice();for(var n=0,r=t.length;r>n;n++){var o=t[n];if(!e.length)break;var i=e.indexOf(o);if(-1===i)return!1;e.splice(i,1)}return!0},n.compare=function(e,t){return t>e?-1:e>t?1:0},n.arrayToObject=function(e){for(var t={},n=0,r=e.length;r>n;n++)t[e[n]]=!0;return t},n.max=function(e,t){for(var n=null,r=-1,o=0,i=e.length;i>o;o++){var u=e[o],a=t(u);a>r&&(r=a,n=u)}return n},n.arrayEquals=function(e,t){if(e.length!==t.length)return!1;for(var n=0,r=e.length;r>n;n++)if(e[n]!==t[n])return!1;return!0},n.uniq=function(e){for(var t={},n=0;n<e.length;n++)t["$"+e[n]]=!0;return Object.keys(t).map(function(e){return e.substring(1)})},n.log=e(20)("pouchdb:find")}).call(this,e(34))},{19:19,20:20,23:23,28:28,29:29,34:34,35:35}],18:[function(e,t,n){"use strict";function r(e){return function(){var t=arguments.length;if(t){for(var n=[],r=-1;++r<t;)n[r]=arguments[r];return e.call(this,n)}return e.call(this,[])}}t.exports=r},{}],19:[function(e,t,n){},{}],20:[function(e,t,n){function r(){return"WebkitAppearance"in document.documentElement.style||window.console&&(console.firebug||console.exception&&console.table)||navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31}function o(){var e=arguments,t=this.useColors;if(e[0]=(t?"%c":"")+this.namespace+(t?" %c":" ")+e[0]+(t?"%c ":" ")+"+"+n.humanize(this.diff),!t)return e;var r="color: "+this.color;e=[e[0],r,"color: inherit"].concat(Array.prototype.slice.call(e,1));var o=0,i=0;return e[0].replace(/%[a-z%]/g,function(e){"%%"!==e&&(o++,"%c"===e&&(i=o))}),e.splice(i,0,r),e}function i(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function u(e){try{null==e?n.storage.removeItem("debug"):n.storage.debug=e}catch(t){}}function a(){var e;try{e=n.storage.debug}catch(t){}return e}function c(){try{return window.localStorage}catch(e){}}n=t.exports=e(21),n.log=i,n.formatArgs=o,n.save=u,n.load=a,n.useColors=r,n.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:c(),n.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],n.formatters.j=function(e){return JSON.stringify(e)},n.enable(a())},{21:21}],21:[function(e,t,n){function r(){return n.colors[f++%n.colors.length]}function o(e){function t(){}function o(){var e=o,t=+new Date,i=t-(s||t);e.diff=i,e.prev=s,e.curr=t,s=t,null==e.useColors&&(e.useColors=n.useColors()),null==e.color&&e.useColors&&(e.color=r());var u=Array.prototype.slice.call(arguments);
-u[0]=n.coerce(u[0]),"string"!=typeof u[0]&&(u=["%o"].concat(u));var a=0;u[0]=u[0].replace(/%([a-z%])/g,function(t,r){if("%%"===t)return t;a++;var o=n.formatters[r];if("function"==typeof o){var i=u[a];t=o.call(e,i),u.splice(a,1),a--}return t}),"function"==typeof n.formatArgs&&(u=n.formatArgs.apply(e,u));var c=o.log||n.log||console.log.bind(console);c.apply(e,u)}t.enabled=!1,o.enabled=!0;var i=n.enabled(e)?o:t;return i.namespace=e,i}function i(e){n.save(e);for(var t=(e||"").split(/[\s,]+/),r=t.length,o=0;r>o;o++)t[o]&&(e=t[o].replace(/\*/g,".*?"),"-"===e[0]?n.skips.push(new RegExp("^"+e.substr(1)+"$")):n.names.push(new RegExp("^"+e+"$")))}function u(){n.enable("")}function a(e){var t,r;for(t=0,r=n.skips.length;r>t;t++)if(n.skips[t].test(e))return!1;for(t=0,r=n.names.length;r>t;t++)if(n.names[t].test(e))return!0;return!1}function c(e){return e instanceof Error?e.stack||e.message:e}n=t.exports=o,n.coerce=c,n.disable=u,n.enable=i,n.enabled=a,n.humanize=e(25),n.names=[],n.skips=[],n.formatters={};var s,f=0},{25:25}],22:[function(e,t,n){(function(e){"use strict";function n(){f=!0;for(var e,t,n=l.length;n;){for(t=l,l=[],e=-1;++e<n;)t[e]();n=l.length}f=!1}function r(e){1!==l.push(e)||f||o()}var o,i=e.MutationObserver||e.WebKitMutationObserver;if(i){var u=0,a=new i(n),c=e.document.createTextNode("");a.observe(c,{characterData:!0}),o=function(){c.data=u=++u%2}}else if(e.setImmediate||"undefined"==typeof e.MessageChannel)o="document"in e&&"onreadystatechange"in e.document.createElement("script")?function(){var t=e.document.createElement("script");t.onreadystatechange=function(){n(),t.onreadystatechange=null,t.parentNode.removeChild(t),t=null},e.document.documentElement.appendChild(t)}:function(){setTimeout(n,0)};else{var s=new e.MessageChannel;s.port1.onmessage=n,o=function(){s.port2.postMessage(0)}}var f,l=[];t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],23:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],24:[function(e,t,n){var r=Array.isArray,o=Object.prototype.toString;t.exports=r||function(e){return!!e&&"[object Array]"==o.call(e)}},{}],25:[function(e,t,n){function r(e){if(e=""+e,!(e.length>1e4)){var t=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(e);if(t){var n=parseFloat(t[1]),r=(t[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"yrs":case"yr":case"y":return n*l;case"days":case"day":case"d":return n*f;case"hours":case"hour":case"hrs":case"hr":case"h":return n*s;case"minutes":case"minute":case"mins":case"min":case"m":return n*c;case"seconds":case"second":case"secs":case"sec":case"s":return n*a;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n}}}}function o(e){return e>=f?Math.round(e/f)+"d":e>=s?Math.round(e/s)+"h":e>=c?Math.round(e/c)+"m":e>=a?Math.round(e/a)+"s":e+"ms"}function i(e){return u(e,f,"day")||u(e,s,"hour")||u(e,c,"minute")||u(e,a,"second")||e+" ms"}function u(e,t,n){return t>e?void 0:1.5*t>e?Math.floor(e/t)+" "+n:Math.ceil(e/t)+" "+n+"s"}var a=1e3,c=60*a,s=60*c,f=24*s,l=365.25*f;t.exports=function(e,t){return t=t||{},"string"==typeof e?r(e):t["long"]?i(e):o(e)}},{}],26:[function(e,t,n){"use strict";function r(e){if(null!==e)switch(typeof e){case"boolean":return e?1:0;case"number":return f(e);case"string":return e.replace(/\u0002/g,"").replace(/\u0001/g,"").replace(/\u0000/g,"");case"object":var t=Array.isArray(e),r=t?e:Object.keys(e),o=-1,i=r.length,u="";if(t)for(;++o<i;)u+=n.toIndexableString(r[o]);else for(;++o<i;){var a=r[o];u+=n.toIndexableString(a)+n.toIndexableString(e[a])}return u}return""}function o(e,t){var n,r=t,o="1"===e[t];if(o)n=0,t++;else{var i="0"===e[t];t++;var u="",a=e.substring(t,t+d),c=parseInt(a,10)+l;for(i&&(c=-c),t+=d;;){var s=e[t];if("\x00"===s)break;u+=s,t++}u=u.split("."),n=1===u.length?parseInt(u,10):parseFloat(u[0]+"."+u[1]),i&&(n-=10),0!==c&&(n=parseFloat(n+"e"+c))}return{num:n,length:t-r}}function i(e,t){var n=e.pop();if(t.length){var r=t[t.length-1];n===r.element&&(t.pop(),r=t[t.length-1]);var o=r.element,i=r.index;if(Array.isArray(o))o.push(n);else if(i===e.length-2){var u=e.pop();o[u]=n}else e.push(n)}}function u(e,t){for(var r=Math.min(e.length,t.length),o=0;r>o;o++){var i=n.collate(e[o],t[o]);if(0!==i)return i}return e.length===t.length?0:e.length>t.length?1:-1}function a(e,t){return e===t?0:e>t?1:-1}function c(e,t){for(var r=Object.keys(e),o=Object.keys(t),i=Math.min(r.length,o.length),u=0;i>u;u++){var a=n.collate(r[u],o[u]);if(0!==a)return a;if(a=n.collate(e[r[u]],t[o[u]]),0!==a)return a}return r.length===o.length?0:r.length>o.length?1:-1}function s(e){var t=["boolean","number","string","object"],n=t.indexOf(typeof e);return~n?null===e?1:Array.isArray(e)?5:3>n?n+2:n+3:Array.isArray(e)?5:void 0}function f(e){if(0===e)return"1";var t=e.toExponential().split(/e\+?/),n=parseInt(t[1],10),r=0>e,o=r?"0":"2",i=(r?-n:n)-l,u=p.padLeft(i.toString(),"0",d);o+=h+u;var a=Math.abs(parseFloat(t[0]));r&&(a=10-a);var c=a.toFixed(20);return c=c.replace(/\.?0+$/,""),o+=h+c}var l=-324,d=3,h="",p=e(27);n.collate=function(e,t){if(e===t)return 0;e=n.normalizeKey(e),t=n.normalizeKey(t);var r=s(e),o=s(t);if(r-o!==0)return r-o;if(null===e)return 0;switch(typeof e){case"number":return e-t;case"boolean":return e===t?0:t>e?-1:1;case"string":return a(e,t)}return Array.isArray(e)?u(e,t):c(e,t)},n.normalizeKey=function(e){switch(typeof e){case"undefined":return null;case"number":return e===1/0||e===-(1/0)||isNaN(e)?null:e;case"object":var t=e;if(Array.isArray(e)){var r=e.length;e=new Array(r);for(var o=0;r>o;o++)e[o]=n.normalizeKey(t[o])}else{if(e instanceof Date)return e.toJSON();if(null!==e){e={};for(var i in t)if(t.hasOwnProperty(i)){var u=t[i];"undefined"!=typeof u&&(e[i]=n.normalizeKey(u))}}}}return e},n.toIndexableString=function(e){var t="\x00";return e=n.normalizeKey(e),s(e)+h+r(e)+t},n.parseIndexableString=function(e){for(var t=[],n=[],r=0;;){var u=e[r++];if("\x00"!==u)switch(u){case"1":t.push(null);break;case"2":t.push("1"===e[r]),r++;break;case"3":var a=o(e,r);t.push(a.num),r+=a.length;break;case"4":for(var c="";;){var s=e[r];if("\x00"===s)break;c+=s,r++}c=c.replace(/\u0001\u0001/g,"\x00").replace(/\u0001\u0002/g,"").replace(/\u0002\u0002/g,""),t.push(c);break;case"5":var f={element:[],index:t.length};t.push(f.element),n.push(f);break;case"6":var l={element:{},index:t.length};t.push(l.element),n.push(l);break;default:throw new Error("bad collationIndex or unexpectedly reached end of input: "+u)}else{if(1===t.length)return t.pop();i(t,n)}}}},{27:27}],27:[function(e,t,n){"use strict";function r(e,t,n){for(var r="",o=n-e.length;r.length<o;)r+=t;return r}n.padLeft=function(e,t,n){var o=r(e,t,n);return o+e},n.padRight=function(e,t,n){var o=r(e,t,n);return e+o},n.stringLexCompare=function(e,t){var n,r=e.length,o=t.length;for(n=0;r>n;n++){if(n===o)return 1;var i=e.charAt(n),u=t.charAt(n);if(i!==u)return u>i?-1:1}return o>r?-1:0},n.intToDecimalForm=function(e){var t=0>e,n="";do{var r=t?-Math.ceil(e%10):Math.floor(e%10);n=r+n,e=t?Math.ceil(e/10):Math.floor(e/10)}while(e);return t&&"0"!==n&&(n="-"+n),n}},{}],28:[function(e,t,n){"use strict";function r(e){return null===e?String(e):"object"==typeof e||"function"==typeof e?s[h.call(e)]||"object":typeof e}function o(e){return null!==e&&e===e.window}function i(e){if(!e||"object"!==r(e)||e.nodeType||o(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(t){return!1}var n;for(n in e);return void 0===n||p.call(e,n)}function u(e){return"function"===r(e)}function a(){for(var e=[],t=-1,n=arguments.length,r=new Array(n);++t<n;)r[t]=arguments[t];var o={};e.push({args:r,result:{container:o,key:"key"}});for(var i;i=e.pop();)c(e,i.args,i.result);return o.key}function c(e,t,n){var r,o,a,c,s,f,l,d=t[0]||{},h=1,p=t.length,v=!1,g=/\d+/;for("boolean"==typeof d&&(v=d,d=t[1]||{},h=2),"object"==typeof d||u(d)||(d={}),p===h&&(d=this,--h);p>h;h++)if(null!=(r=t[h])){l=y(r);for(o in r)if(!(o in Object.prototype)){if(l&&!g.test(o))continue;if(a=d[o],c=r[o],d===c)continue;v&&c&&(i(c)||(s=y(c)))?(s?(s=!1,f=a&&y(a)?a:[]):f=a&&i(a)?a:{},e.push({args:[v,f,c],result:{container:d,key:o}})):void 0!==c&&(y(r)&&u(c)||(d[o]=c))}}n.container[n.key]=d}for(var s={},f=["Boolean","Number","String","Function","Array","Date","RegExp","Object","Error"],l=0;l<f.length;l++){var d=f[l];s["[object "+d+"]"]=d.toLowerCase()}var h=s.toString,p=s.hasOwnProperty,y=Array.isArray||function(e){return"array"===r(e)};t.exports=a},{}],29:[function(e,t,n){"use strict";function r(e){return e&&"object"==typeof e&&"default"in e?e["default"]:e}var o=r(e(30)),i="function"==typeof Promise?Promise:o;t.exports=i},{30:30}],30:[function(e,t,n){"use strict";function r(){}function o(e){if("function"!=typeof e)throw new TypeError("resolver must be a function");this.state=m,this.queue=[],this.outcome=void 0,e!==r&&c(this,e)}function i(e,t,n){this.promise=e,"function"==typeof t&&(this.onFulfilled=t,this.callFulfilled=this.otherCallFulfilled),"function"==typeof n&&(this.onRejected=n,this.callRejected=this.otherCallRejected)}function u(e,t,n){p(function(){var r;try{r=t(n)}catch(o){return y.reject(e,o)}r===e?y.reject(e,new TypeError("Cannot resolve promise with itself")):y.resolve(e,r)})}function a(e){var t=e&&e.then;return e&&"object"==typeof e&&"function"==typeof t?function(){t.apply(e,arguments)}:void 0}function c(e,t){function n(t){i||(i=!0,y.reject(e,t))}function r(t){i||(i=!0,y.resolve(e,t))}function o(){t(r,n)}var i=!1,u=s(o);"error"===u.status&&n(u.value)}function s(e,t){var n={};try{n.value=e(t),n.status="success"}catch(r){n.status="error",n.value=r}return n}function f(e){return e instanceof this?e:y.resolve(new this(r),e)}function l(e){var t=new this(r);return y.reject(t,e)}function d(e){function t(e,t){function r(e){u[t]=e,++a!==o||i||(i=!0,y.resolve(s,u))}n.resolve(e).then(r,function(e){i||(i=!0,y.reject(s,e))})}var n=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var o=e.length,i=!1;if(!o)return this.resolve([]);for(var u=new Array(o),a=0,c=-1,s=new this(r);++c<o;)t(e[c],c);return s}function h(e){function t(e){n.resolve(e).then(function(e){i||(i=!0,y.resolve(a,e))},function(e){i||(i=!0,y.reject(a,e))})}var n=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var o=e.length,i=!1;if(!o)return this.resolve([]);for(var u=-1,a=new this(r);++u<o;)t(e[u]);return a}var p=e(22),y={},v=["REJECTED"],g=["FULFILLED"],m=["PENDING"];t.exports=o,o.prototype["catch"]=function(e){return this.then(null,e)},o.prototype.then=function(e,t){if("function"!=typeof e&&this.state===g||"function"!=typeof t&&this.state===v)return this;var n=new this.constructor(r);if(this.state!==m){var o=this.state===g?e:t;u(n,o,this.outcome)}else this.queue.push(new i(n,e,t));return n},i.prototype.callFulfilled=function(e){y.resolve(this.promise,e)},i.prototype.otherCallFulfilled=function(e){u(this.promise,this.onFulfilled,e)},i.prototype.callRejected=function(e){y.reject(this.promise,e)},i.prototype.otherCallRejected=function(e){u(this.promise,this.onRejected,e)},y.resolve=function(e,t){var n=s(a,t);if("error"===n.status)return y.reject(e,n.value);var r=n.value;if(r)c(e,r);else{e.state=g,e.outcome=t;for(var o=-1,i=e.queue.length;++o<i;)e.queue[o].callFulfilled(t)}return e},y.reject=function(e,t){e.state=v,e.outcome=t;for(var n=-1,r=e.queue.length;++n<r;)e.queue[n].callRejected(t);return e},o.resolve=f,o.reject=l,o.all=d,o.race=h},{22:22}],31:[function(e,t,n){"use strict";function r(e,t,n){return"string"!=typeof t?i.reject(new Error("doc id is required")):e.get(t)["catch"](function(e){if(404!==e.status)throw e;return{}}).then(function(r){var i=r._rev,u=n(r);return u?(u._id=t,u._rev=i,o(e,u,n)):{updated:!1,rev:i}})}function o(e,t,n){return e.put(t).then(function(e){return{updated:!0,rev:e.rev}},function(o){if(409!==o.status)throw o;return r(e,t._id,n)})}var i=e(33);n.upsert=function(e,t,n){var o=this,i=r(o,e,t);return"function"!=typeof n?i:void i.then(function(e){n(null,e)},n)},n.putIfNotExists=function(e,t,n){var o=this;"string"!=typeof e&&(n=t,t=e,e=t._id);var i=function(e){return e._rev?!1:t},u=r(o,e,i);return"function"!=typeof n?u:void u.then(function(e){n(null,e)},n)},"undefined"!=typeof window&&window.PouchDB&&window.PouchDB.plugin(n)},{33:33}],32:[function(e,t,n){arguments[4][30][0].apply(n,arguments)},{22:22,30:30}],33:[function(e,t,n){arguments[4][29][0].apply(n,arguments)},{29:29,32:32}],34:[function(e,t,n){function r(){f&&a&&(f=!1,a.length?s=a.concat(s):l=-1,s.length&&o())}function o(){if(!f){var e=setTimeout(r);f=!0;for(var t=s.length;t;){for(a=s,s=[];++l<t;)a&&a[l].run();l=-1,t=s.length}a=null,f=!1,clearTimeout(e)}}function i(e,t){this.fun=e,this.array=t}function u(){}var a,c=t.exports={},s=[],f=!1,l=-1;c.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];s.push(new i(e,t)),1!==s.length||f||setTimeout(o,0)},i.prototype.run=function(){this.fun.apply(null,this.array)},c.title="browser",c.browser=!0,c.env={},c.argv=[],c.version="",c.versions={},c.on=u,c.addListener=u,c.once=u,c.off=u,c.removeListener=u,c.removeAllListeners=u,c.emit=u,c.binding=function(e){throw new Error("process.binding is not supported")},c.cwd=function(){return"/"},c.chdir=function(e){throw new Error("process.chdir is not supported")},c.umask=function(){return 0}},{}],35:[function(t,n,r){!function(t){if("object"==typeof r)n.exports=t();else if("function"==typeof e&&e.amd)e(t);else{var o;try{o=window}catch(i){o=self}o.SparkMD5=t()}}(function(e){"use strict";var t=function(e,t){return e+t&4294967295},n=function(e,n,r,o,i,u){return n=t(t(n,e),t(o,u)),t(n<<i|n>>>32-i,r)},r=function(e,t,r,o,i,u,a){return n(t&r|~t&o,e,t,i,u,a)},o=function(e,t,r,o,i,u,a){return n(t&o|r&~o,e,t,i,u,a)},i=function(e,t,r,o,i,u,a){return n(t^r^o,e,t,i,u,a)},u=function(e,t,r,o,i,u,a){return n(r^(t|~o),e,t,i,u,a)},a=function(e,n){var a=e[0],c=e[1],s=e[2],f=e[3];a=r(a,c,s,f,n[0],7,-680876936),f=r(f,a,c,s,n[1],12,-389564586),s=r(s,f,a,c,n[2],17,606105819),c=r(c,s,f,a,n[3],22,-1044525330),a=r(a,c,s,f,n[4],7,-176418897),f=r(f,a,c,s,n[5],12,1200080426),s=r(s,f,a,c,n[6],17,-1473231341),c=r(c,s,f,a,n[7],22,-45705983),a=r(a,c,s,f,n[8],7,1770035416),f=r(f,a,c,s,n[9],12,-1958414417),s=r(s,f,a,c,n[10],17,-42063),c=r(c,s,f,a,n[11],22,-1990404162),a=r(a,c,s,f,n[12],7,1804603682),f=r(f,a,c,s,n[13],12,-40341101),s=r(s,f,a,c,n[14],17,-1502002290),c=r(c,s,f,a,n[15],22,1236535329),a=o(a,c,s,f,n[1],5,-165796510),f=o(f,a,c,s,n[6],9,-1069501632),s=o(s,f,a,c,n[11],14,643717713),c=o(c,s,f,a,n[0],20,-373897302),a=o(a,c,s,f,n[5],5,-701558691),f=o(f,a,c,s,n[10],9,38016083),s=o(s,f,a,c,n[15],14,-660478335),c=o(c,s,f,a,n[4],20,-405537848),a=o(a,c,s,f,n[9],5,568446438),f=o(f,a,c,s,n[14],9,-1019803690),s=o(s,f,a,c,n[3],14,-187363961),c=o(c,s,f,a,n[8],20,1163531501),a=o(a,c,s,f,n[13],5,-1444681467),f=o(f,a,c,s,n[2],9,-51403784),s=o(s,f,a,c,n[7],14,1735328473),c=o(c,s,f,a,n[12],20,-1926607734),a=i(a,c,s,f,n[5],4,-378558),f=i(f,a,c,s,n[8],11,-2022574463),s=i(s,f,a,c,n[11],16,1839030562),c=i(c,s,f,a,n[14],23,-35309556),a=i(a,c,s,f,n[1],4,-1530992060),f=i(f,a,c,s,n[4],11,1272893353),s=i(s,f,a,c,n[7],16,-155497632),c=i(c,s,f,a,n[10],23,-1094730640),a=i(a,c,s,f,n[13],4,681279174),f=i(f,a,c,s,n[0],11,-358537222),s=i(s,f,a,c,n[3],16,-722521979),c=i(c,s,f,a,n[6],23,76029189),a=i(a,c,s,f,n[9],4,-640364487),f=i(f,a,c,s,n[12],11,-421815835),s=i(s,f,a,c,n[15],16,530742520),c=i(c,s,f,a,n[2],23,-995338651),a=u(a,c,s,f,n[0],6,-198630844),f=u(f,a,c,s,n[7],10,1126891415),s=u(s,f,a,c,n[14],15,-1416354905),c=u(c,s,f,a,n[5],21,-57434055),a=u(a,c,s,f,n[12],6,1700485571),f=u(f,a,c,s,n[3],10,-1894986606),s=u(s,f,a,c,n[10],15,-1051523),c=u(c,s,f,a,n[1],21,-2054922799),a=u(a,c,s,f,n[8],6,1873313359),f=u(f,a,c,s,n[15],10,-30611744),s=u(s,f,a,c,n[6],15,-1560198380),c=u(c,s,f,a,n[13],21,1309151649),a=u(a,c,s,f,n[4],6,-145523070),f=u(f,a,c,s,n[11],10,-1120210379),s=u(s,f,a,c,n[2],15,718787259),c=u(c,s,f,a,n[9],21,-343485551),e[0]=t(a,e[0]),e[1]=t(c,e[1]),e[2]=t(s,e[2]),e[3]=t(f,e[3])},c=function(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e.charCodeAt(t)+(e.charCodeAt(t+1)<<8)+(e.charCodeAt(t+2)<<16)+(e.charCodeAt(t+3)<<24);return n},s=function(e){var t,n=[];for(t=0;64>t;t+=4)n[t>>2]=e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24);return n},f=function(e){var t,n,r,o,i,u,s=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;s>=t;t+=64)a(f,c(e.substring(t-64,t)));for(e=e.substring(t-64),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e.charCodeAt(t)<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(a(f,r),t=0;16>t;t+=1)r[t]=0;return o=8*s,o=o.toString(16).match(/(.*?)(.{0,8})$/),i=parseInt(o[2],16),u=parseInt(o[1],16)||0,r[14]=i,r[15]=u,a(f,r),f},l=function(e){var t,n,r,o,i,u,c=e.length,f=[1732584193,-271733879,-1732584194,271733878];for(t=64;c>=t;t+=64)a(f,s(e.subarray(t-64,t)));for(e=c>t-64?e.subarray(t-64):new Uint8Array(0),n=e.length,r=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t=0;n>t;t+=1)r[t>>2]|=e[t]<<(t%4<<3);if(r[t>>2]|=128<<(t%4<<3),t>55)for(a(f,r),t=0;16>t;t+=1)r[t]=0;return o=8*c,o=o.toString(16).match(/(.*?)(.{0,8})$/),i=parseInt(o[2],16),u=parseInt(o[1],16)||0,r[14]=i,r[15]=u,a(f,r),f},d=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"],h=function(e){var t,n="";for(t=0;4>t;t+=1)n+=d[e>>8*t+4&15]+d[e>>8*t&15];return n},p=function(e){var t;for(t=0;t<e.length;t+=1)e[t]=h(e[t]);return e.join("")},y=function(e){return p(f(e))},v=function(){this.reset()};return"5d41402abc4b2a76b9719d911017c592"!==y("hello")&&(t=function(e,t){var n=(65535&e)+(65535&t),r=(e>>16)+(t>>16)+(n>>16);return r<<16|65535&n}),v.prototype.append=function(e){return/[\u0080-\uFFFF]/.test(e)&&(e=unescape(encodeURIComponent(e))),this.appendBinary(e),this},v.prototype.appendBinary=function(e){this._buff+=e,this._length+=e.length;var t,n=this._buff.length;for(t=64;n>=t;t+=64)a(this._state,c(this._buff.substring(t-64,t)));return this._buff=this._buff.substr(t-64),this},v.prototype.end=function(e){var t,n,r=this._buff,o=r.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;o>t;t+=1)i[t>>2]|=r.charCodeAt(t)<<(t%4<<3);return this._finish(i,o),n=e?this._state:p(this._state),this.reset(),n},v.prototype._finish=function(e,t){var n,r,o,i=t;if(e[i>>2]|=128<<(i%4<<3),i>55)for(a(this._state,e),i=0;16>i;i+=1)e[i]=0;n=8*this._length,n=n.toString(16).match(/(.*?)(.{0,8})$/),r=parseInt(n[2],16),o=parseInt(n[1],16)||0,e[14]=r,e[15]=o,a(this._state,e)},v.prototype.reset=function(){return this._buff="",this._length=0,this._state=[1732584193,-271733879,-1732584194,271733878],this},v.prototype.destroy=function(){delete this._state,delete this._buff,delete this._length},v.hash=function(e,t){/[\u0080-\uFFFF]/.test(e)&&(e=unescape(encodeURIComponent(e)));var n=f(e);return t?n:p(n)},v.hashBinary=function(e,t){var n=f(e);return t?n:p(n)},v.ArrayBuffer=function(){this.reset()},v.ArrayBuffer.prototype.append=function(e){var t,n=this._concatArrayBuffer(this._buff,e),r=n.length;for(this._length+=e.byteLength,t=64;r>=t;t+=64)a(this._state,s(n.subarray(t-64,t)));return this._buff=r>t-64?n.subarray(t-64):new Uint8Array(0),this},v.ArrayBuffer.prototype.end=function(e){var t,n,r=this._buff,o=r.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;o>t;t+=1)i[t>>2]|=r[t]<<(t%4<<3);return this._finish(i,o),n=e?this._state:p(this._state),this.reset(),n},v.ArrayBuffer.prototype._finish=v.prototype._finish,v.ArrayBuffer.prototype.reset=function(){return this._buff=new Uint8Array(0),this._length=0,this._state=[1732584193,-271733879,-1732584194,271733878],this},v.ArrayBuffer.prototype.destroy=v.prototype.destroy,v.ArrayBuffer.prototype._concatArrayBuffer=function(e,t){var n=e.length,r=new Uint8Array(n+t.byteLength);return r.set(e),r.set(new Uint8Array(t),n),r},v.ArrayBuffer.hash=function(e,t){var n=l(new Uint8Array(e));return t?n:p(n)},v})},{}],36:[function(e,t,n){"use strict";var r=e(17),o=e(6),i=e(14),u={};u.createIndex=r.toPromise(function(e,t){if("object"!=typeof e)return t(new Error("you must provide an index to create"));var n="http"===this.type()?o:i;n.createIndex(this,e,t)}),u.find=r.toPromise(function(e,t){if("undefined"==typeof t&&(t=e,e=void 0),"object"!=typeof e)return t(new Error("you must provide search parameters to find()"));var n="http"===this.type()?o:i;n.find(this,e,t)}),u.getIndexes=r.toPromise(function(e){var t="http"===this.type()?o:i;t.getIndexes(this,e)}),u.deleteIndex=r.toPromise(function(e,t){if("object"!=typeof e)return t(new Error("you must provide an index to delete"));var n="http"===this.type()?o:i;n.deleteIndex(this,e,t)}),t.exports=u,"undefined"!=typeof window&&window.PouchDB&&window.PouchDB.plugin(u)},{14:14,17:17,6:6}]},{},[36])(36)});
+// pouchdb-find plugin 7.1.1
+// Based on Mango: https://github.com/cloudant/mango
+//
+// (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(){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){
+(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;
+}));
+
+},{}],6:[function(_dereq_,module,exports){
+var v1 = _dereq_(9);
+var v4 = _dereq_(10);
+
+var uuid = v4;
+uuid.v1 = v1;
+uuid.v4 = v4;
+
+module.exports = uuid;
+
+},{"10":10,"9":9}],7:[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;
+
+},{}],8:[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;
+ };
+}
+
+},{}],9:[function(_dereq_,module,exports){
+var rng = _dereq_(8);
+var bytesToUuid = _dereq_(7);
+
+// **`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;
+
+},{"7":7,"8":8}],10:[function(_dereq_,module,exports){
+var rng = _dereq_(8);
+var bytesToUuid = _dereq_(7);
+
+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;
+
+},{"7":7,"8":8}],11:[function(_dereq_,module,exports){
+(function (global){
+'use strict';
+
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+var immediate = _interopDefault(_dereq_(3));
+var events = _dereq_(2);
+var uuidV4 = _interopDefault(_dereq_(6));
+var Md5 = _interopDefault(_dereq_(5));
+var getArguments = _interopDefault(_dereq_(1));
+var inherits = _interopDefault(_dereq_(4));
+
+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 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;
+ }
+}
+
+// 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;
+}
+
+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);
+ }
+}
+
+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 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 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,
+
+// 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;
+}
+
+// originally parseUri 1.2.2, now patched by us
+
+// Based on https://github.com/alexdavid/scope-eval v0.0.3
+
+// 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);
+};
+
+// 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
+
+// simplified API. universal browser support is assumed
+
+// this is not used in the browser
+
+var setImmediateShim = global.setImmediate || global.setTimeout;
+
+function stringMd5(string) {
+ return Md5.hash(string);
+}
+
+var uuid = uuidV4.v4;
+
+var h = Headers;
+
+// we restucture the supplied JSON considerably, because the official
+// Mango API is very particular about a lot of this stuff, but we like
+// to be liberal with what we accept in order to prevent mental
+// breakdowns in our users
+function massageCreateIndexRequest(requestDef) {
+ requestDef = clone(requestDef);
+
+ if (!requestDef.index) {
+ requestDef.index = {};
+ }
+
+ ['type', 'name', 'ddoc'].forEach(function (key) {
+ if (requestDef.index[key]) {
+ requestDef[key] = requestDef.index[key];
+ delete requestDef.index[key];
+ }
+ });
+
+ if (requestDef.fields) {
+ requestDef.index.fields = requestDef.fields;
+ delete requestDef.fields;
+ }
+
+ if (!requestDef.type) {
+ requestDef.type = 'json';
+ }
+ return requestDef;
+}
+
+function dbFetch(db, path, opts, callback) {
+ var status, ok;
+ opts.headers = new h({'Content-type': 'application/json'});
+ db.fetch(path, opts).then(function (response) {
+ status = response.status;
+ ok = response.ok;
+ return response.json();
+ }).then(function (json) {
+ if (!ok) {
+ json.status = status;
+ var err = generateErrorFromResponse(json);
+ callback(err);
+ } else {
+ callback(null, json);
+ }
+ })["catch"](callback);
+}
+
+function createIndex(db, requestDef, callback) {
+ requestDef = massageCreateIndexRequest(requestDef);
+ dbFetch(db, '_index', {
+ method: 'POST',
+ body: JSON.stringify(requestDef)
+ }, callback);
+}
+
+function find(db, requestDef, callback) {
+ dbFetch(db, '_find', {
+ method: 'POST',
+ body: JSON.stringify(requestDef)
+ }, callback);
+}
+
+function explain(db, requestDef, callback) {
+ dbFetch(db, '_explain', {
+ method: 'POST',
+ body: JSON.stringify(requestDef)
+ }, callback);
+}
+
+function getIndexes(db, callback) {
+ dbFetch(db, '_index', {
+ method: 'GET'
+ }, callback);
+}
+
+function deleteIndex(db, indexDef, callback) {
+
+
+ var ddoc = indexDef.ddoc;
+ var type = indexDef.type || 'json';
+ var name = indexDef.name;
+
+ if (!ddoc) {
+ return callback(new Error('you must provide an index\'s ddoc'));
+ }
+
+ if (!name) {
+ return callback(new Error('you must provide an index\'s name'));
+ }
+
+ var url = '_index/' + [ddoc, type, name].map(encodeURIComponent).join('/');
+
+ dbFetch(db, url, {method: 'DELETE'}, callback);
+}
+
+// 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 setFieldInDoc(doc, parsedField, value) {
+ for (var i = 0, len = parsedField.length; i < len-1; i++) {
+ var elem = parsedField[i];
+ doc = doc[elem] = {};
+ }
+ doc[parsedField[len-1]] = value;
+}
+
+function compare(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(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);
+ }
+};
+
+function getArguments$1(fun) {
+ return function () {
+ var len = arguments.length;
+ var args = new Array(len);
+ var i = -1;
+ while (++i < len) {
+ args[i] = arguments[i];
+ }
+ return fun.call(this, args);
+ };
+}
+
+function callbackify(fun) {
+ return getArguments$1(function (args) {
+ var cb = args.pop();
+ var promise = fun.apply(this, args);
+ promisedCallback(promise, cb);
+ return promise;
+ });
+}
+
+function promisedCallback(promise, callback) {
+ promise.then(function (res) {
+ immediate(function () {
+ callback(null, res);
+ });
+ }, function (reason) {
+ immediate(function () {
+ callback(reason);
+ });
+ });
+ return promise;
+}
+
+var flatten$1 = getArguments$1(function (args) {
+ var res = [];
+ for (var i = 0, len = args.length; i < len; i++) {
+ var subArr = args[i];
+ if (Array.isArray(subArr)) {
+ res = res.concat(flatten$1.apply(null, subArr));
+ } else {
+ res.push(subArr);
+ }
+ }
+ return res;
+});
+
+function mergeObjects(arr) {
+ var res = {};
+ for (var i = 0, len = arr.length; i < len; i++) {
+ res = $inject_Object_assign(res, arr[i]);
+ }
+ return res;
+}
+
+// Selects a list of fields defined in dot notation from one doc
+// and copies them to a new doc. Like underscore _.pick but supports nesting.
+function pick$1(obj, arr) {
+ var res = {};
+ for (var i = 0, len = arr.length; i < len; i++) {
+ var parsedField = parseField(arr[i]);
+ var value = getFieldFromDoc(obj, parsedField);
+ if (typeof value !== 'undefined') {
+ setFieldInDoc(res, parsedField, value);
+ }
+ }
+ return res;
+}
+
+// e.g. ['a'], ['a', 'b'] is true, but ['b'], ['a', 'b'] is false
+function oneArrayIsSubArrayOfOther(left, right) {
+
+ for (var i = 0, len = Math.min(left.length, right.length); i < len; i++) {
+ if (left[i] !== right[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// e.g.['a', 'b', 'c'], ['a', 'b'] is false
+function oneArrayIsStrictSubArrayOfOther(left, right) {
+
+ if (left.length > right.length) {
+ return false;
+ }
+
+ return oneArrayIsSubArrayOfOther(left, right);
+}
+
+// same as above, but treat the left array as an unordered set
+// e.g. ['b', 'a'], ['a', 'b', 'c'] is true, but ['c'], ['a', 'b', 'c'] is false
+function oneSetIsSubArrayOfOther(left, right) {
+ left = left.slice();
+ for (var i = 0, len = right.length; i < len; i++) {
+ var field = right[i];
+ if (!left.length) {
+ break;
+ }
+ var leftIdx = left.indexOf(field);
+ if (leftIdx === -1) {
+ return false;
+ } else {
+ left.splice(leftIdx, 1);
+ }
+ }
+ return true;
+}
+
+function arrayToObject(arr) {
+ var res = {};
+ for (var i = 0, len = arr.length; i < len; i++) {
+ res[arr[i]] = true;
+ }
+ return res;
+}
+
+function max(arr, fun) {
+ var max = null;
+ var maxScore = -1;
+ for (var i = 0, len = arr.length; i < len; i++) {
+ var element = arr[i];
+ var score = fun(element);
+ if (score > maxScore) {
+ maxScore = score;
+ max = element;
+ }
+ }
+ return max;
+}
+
+function arrayEquals(arr1, arr2) {
+ if (arr1.length !== arr2.length) {
+ return false;
+ }
+ for (var i = 0, len = arr1.length; i < len; i++) {
+ if (arr1[i] !== arr2[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+function uniq(arr) {
+ var obj = {};
+ for (var i = 0; i < arr.length; i++) {
+ obj['$' + arr[i]] = true;
+ }
+ return Object.keys(obj).map(function (key) {
+ return key.substring(1);
+ });
+}
+
+/*
+ * Simple task queue to sequentialize actions. Assumes
+ * callbacks will eventually fire (once).
+ */
+
+
+function TaskQueue() {
+ this.promise = new Promise(function (fulfill) {fulfill(); });
+}
+TaskQueue.prototype.add = function (promiseFactory) {
+ this.promise = this.promise["catch"](function () {
+ // just recover
+ }).then(function () {
+ return promiseFactory();
+ });
+ return this.promise;
+};
+TaskQueue.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;
+}
+
+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$1(promise, callback) {
+ if (callback) {
+ promise.then(function (res) {
+ immediate(function () {
+ callback(null, res);
+ });
+ }, function (reason) {
+ immediate(function () {
+ callback(reason);
+ });
+ });
+ }
+ return promise;
+}
+
+function callbackify$1(fun) {
+ return getArguments(function (args) {
+ var cb = args.pop();
+ var promise = fun.apply(this, args);
+ if (typeof cb === 'function') {
+ promisedCallback$1(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$1(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;
+}
+
+var persistentQueues = {};
+var tempViewQueue = new TaskQueue();
+var CHANGES_BATCH_SIZE = 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$1(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();
+ }
+ 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();
+
+ function processNextBatch() {
+ return view.sourceDB.changes({
+ return_docs: true,
+ conflicts: true,
+ include_docs: true,
+ style: 'all_docs',
+ since: currentSeq,
+ limit: CHANGES_BATCH_SIZE
+ }).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) {
+ 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$1(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$1(promise, callback);
+ return promise;
+ }
+
+ var abstractViewCleanup = callbackify$1(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
+ };
+}
+
+//
+// One thing about these mappers:
+//
+// Per the advice of John-David Dalton (http://youtu.be/NthmeLEhDDM),
+// what you want to do in this case is optimize for the smallest possible
+// function, since that's the thing that gets run over and over again.
+//
+// This code would be a lot simpler if all the if/elses were inside
+// the function, but it would also be a lot less performant.
+//
+
+
+function createDeepMultiMapper(fields, emit) {
+ return function (doc) {
+ var toEmit = [];
+ for (var i = 0, iLen = fields.length; i < iLen; i++) {
+ var parsedField = parseField(fields[i]);
+ var value = doc;
+ for (var j = 0, jLen = parsedField.length; j < jLen; j++) {
+ var key = parsedField[j];
+ value = value[key];
+ if (typeof value === 'undefined') {
+ return; // don't emit
+ }
+ }
+ toEmit.push(value);
+ }
+ emit(toEmit);
+ };
+}
+
+function createDeepSingleMapper(field, emit) {
+ var parsedField = parseField(field);
+ return function (doc) {
+ var value = doc;
+ for (var i = 0, len = parsedField.length; i < len; i++) {
+ var key = parsedField[i];
+ value = value[key];
+ if (typeof value === 'undefined') {
+ return; // do nothing
+ }
+ }
+ emit(value);
+ };
+}
+
+function createShallowSingleMapper(field, emit) {
+ return function (doc) {
+ emit(doc[field]);
+ };
+}
+
+function createShallowMultiMapper(fields, emit) {
+ return function (doc) {
+ var toEmit = [];
+ for (var i = 0, len = fields.length; i < len; i++) {
+ toEmit.push(doc[fields[i]]);
+ }
+ emit(toEmit);
+ };
+}
+
+function checkShallow(fields) {
+ for (var i = 0, len = fields.length; i < len; i++) {
+ var field = fields[i];
+ if (field.indexOf('.') !== -1) {
+ return false;
+ }
+ }
+ return true;
+}
+
+function createMapper(fields, emit) {
+ var isShallow = checkShallow(fields);
+ var isSingle = fields.length === 1;
+
+ // notice we try to optimize for the most common case,
+ // i.e. single shallow indexes
+ if (isShallow) {
+ if (isSingle) {
+ return createShallowSingleMapper(fields[0], emit);
+ } else { // multi
+ return createShallowMultiMapper(fields, emit);
+ }
+ } else { // deep
+ if (isSingle) {
+ return createDeepSingleMapper(fields[0], emit);
+ } else { // multi
+ return createDeepMultiMapper(fields, emit);
+ }
+ }
+}
+
+function mapper(mapFunDef, emit) {
+ // mapFunDef is a list of fields
+
+ var fields = Object.keys(mapFunDef.fields);
+
+ return createMapper(fields, emit);
+}
+
+/* istanbul ignore next */
+function reducer(/*reduceFunDef*/) {
+ throw new Error('reduce not supported');
+}
+
+function ddocValidator(ddoc, viewName) {
+ var view = ddoc.views[viewName];
+ // This doesn't actually need to be here apparently, but
+ // I feel safer keeping it.
+ /* istanbul ignore if */
+ if (!view.map || !view.map.fields) {
+ throw new Error('ddoc ' + ddoc._id +' with view ' + viewName +
+ ' doesn\'t have map.fields defined. ' +
+ 'maybe it wasn\'t created by this plugin?');
+ }
+}
+
+var abstractMapper = createAbstractMapReduce(
+ /* localDocName */ 'indexes',
+ mapper,
+ reducer,
+ ddocValidator
+);
+
+function abstractMapper$1 (db) {
+ return db._customFindAbstractMapper || abstractMapper;
+}
+
+// normalize the "sort" value
+function massageSort(sort) {
+ if (!Array.isArray(sort)) {
+ throw new Error('invalid sort json - should be an array');
+ }
+ return sort.map(function (sorting) {
+ if (typeof sorting === 'string') {
+ var obj = {};
+ obj[sorting] = 'asc';
+ return obj;
+ } else {
+ return sorting;
+ }
+ });
+}
+
+function massageUseIndex(useIndex) {
+ var cleanedUseIndex = [];
+ if (typeof useIndex === 'string') {
+ cleanedUseIndex.push(useIndex);
+ } else {
+ cleanedUseIndex = useIndex;
+ }
+
+ return cleanedUseIndex.map(function (name) {
+ return name.replace('_design/', '');
+ });
+}
+
+function massageIndexDef(indexDef) {
+ indexDef.fields = indexDef.fields.map(function (field) {
+ if (typeof field === 'string') {
+ var obj = {};
+ obj[field] = 'asc';
+ return obj;
+ }
+ return field;
+ });
+ return indexDef;
+}
+
+function getKeyFromDoc(doc, index) {
+ var res = [];
+ for (var i = 0; i < index.def.fields.length; i++) {
+ var field = getKey(index.def.fields[i]);
+ res.push(doc[field]);
+ }
+ return res;
+}
+
+// have to do this manually because REASONS. I don't know why
+// CouchDB didn't implement inclusive_start
+function filterInclusiveStart(rows, targetValue, index) {
+ var indexFields = index.def.fields;
+ for (var i = 0, len = rows.length; i < len; i++) {
+ var row = rows[i];
+
+ // shave off any docs at the beginning that are <= the
+ // target value
+
+ var docKey = getKeyFromDoc(row.doc, index);
+ if (indexFields.length === 1) {
+ docKey = docKey[0]; // only one field, not multi-field
+ } else { // more than one field in index
+ // in the case where e.g. the user is searching {$gt: {a: 1}}
+ // but the index is [a, b], then we need to shorten the doc key
+ while (docKey.length > targetValue.length) {
+ docKey.pop();
+ }
+ }
+ //ABS as we just looking for values that don't match
+ if (Math.abs(collate(docKey, targetValue)) > 0) {
+ // no need to filter any further; we're past the key
+ break;
+ }
+ }
+ return i > 0 ? rows.slice(i) : rows;
+}
+
+function reverseOptions(opts) {
+ var newOpts = clone(opts);
+ delete newOpts.startkey;
+ delete newOpts.endkey;
+ delete newOpts.inclusive_start;
+ delete newOpts.inclusive_end;
+
+ if ('endkey' in opts) {
+ newOpts.startkey = opts.endkey;
+ }
+ if ('startkey' in opts) {
+ newOpts.endkey = opts.startkey;
+ }
+ if ('inclusive_start' in opts) {
+ newOpts.inclusive_end = opts.inclusive_start;
+ }
+ if ('inclusive_end' in opts) {
+ newOpts.inclusive_start = opts.inclusive_end;
+ }
+ return newOpts;
+}
+
+function validateIndex(index) {
+ var ascFields = index.fields.filter(function (field) {
+ return getValue(field) === 'asc';
+ });
+ if (ascFields.length !== 0 && ascFields.length !== index.fields.length) {
+ throw new Error('unsupported mixed sorting');
+ }
+}
+
+function validateSort(requestDef, index) {
+ if (index.defaultUsed && requestDef.sort) {
+ var noneIdSorts = requestDef.sort.filter(function (sortItem) {
+ return Object.keys(sortItem)[0] !== '_id';
+ }).map(function (sortItem) {
+ return Object.keys(sortItem)[0];
+ });
+
+ if (noneIdSorts.length > 0) {
+ throw new Error('Cannot sort on field(s) "' + noneIdSorts.join(',') +
+ '" when using the default index');
+ }
+ }
+
+ if (index.defaultUsed) {
+ return;
+ }
+}
+
+function validateFindRequest(requestDef) {
+ if (typeof requestDef.selector !== 'object') {
+ throw new Error('you must provide a selector when you find()');
+ }
+
+ /*var selectors = requestDef.selector['$and'] || [requestDef.selector];
+ for (var i = 0; i < selectors.length; i++) {
+ var selector = selectors[i];
+ var keys = Object.keys(selector);
+ if (keys.length === 0) {
+ throw new Error('invalid empty selector');
+ }
+ //var selection = selector[keys[0]];
+ /*if (Object.keys(selection).length !== 1) {
+ throw new Error('invalid selector: ' + JSON.stringify(selection) +
+ ' - it must have exactly one key/value');
+ }
+ }*/
+}
+
+// determine the maximum number of fields
+// we're going to need to query, e.g. if the user
+// has selection ['a'] and sorting ['a', 'b'], then we
+// need to use the longer of the two: ['a', 'b']
+function getUserFields(selector, sort) {
+ var selectorFields = Object.keys(selector);
+ var sortFields = sort? sort.map(getKey) : [];
+ var userFields;
+ if (selectorFields.length >= sortFields.length) {
+ userFields = selectorFields;
+ } else {
+ userFields = sortFields;
+ }
+
+ if (sortFields.length === 0) {
+ return {
+ fields: userFields
+ };
+ }
+
+ // sort according to the user's preferred sorting
+ userFields = userFields.sort(function (left, right) {
+ var leftIdx = sortFields.indexOf(left);
+ if (leftIdx === -1) {
+ leftIdx = Number.MAX_VALUE;
+ }
+ var rightIdx = sortFields.indexOf(right);
+ if (rightIdx === -1) {
+ rightIdx = Number.MAX_VALUE;
+ }
+ return leftIdx < rightIdx ? -1 : leftIdx > rightIdx ? 1 : 0;
+ });
+
+ return {
+ fields: userFields,
+ sortOrder: sort.map(getKey)
+ };
+}
+
+function createIndex$1(db, requestDef) {
+ requestDef = massageCreateIndexRequest(requestDef);
+ var originalIndexDef = clone(requestDef.index);
+ requestDef.index = massageIndexDef(requestDef.index);
+
+ validateIndex(requestDef.index);
+
+ // calculating md5 is expensive - memoize and only
+ // run if required
+ var md5;
+ function getMd5() {
+ return md5 || (md5 = stringMd5(JSON.stringify(requestDef)));
+ }
+
+ var viewName = requestDef.name || ('idx-' + getMd5());
+
+ var ddocName = requestDef.ddoc || ('idx-' + getMd5());
+ var ddocId = '_design/' + ddocName;
+
+ var hasInvalidLanguage = false;
+ var viewExists = false;
+
+ function updateDdoc(doc) {
+ if (doc._rev && doc.language !== 'query') {
+ hasInvalidLanguage = true;
+ }
+ doc.language = 'query';
+ doc.views = doc.views || {};
+
+ viewExists = !!doc.views[viewName];
+
+ if (viewExists) {
+ return false;
+ }
+
+ doc.views[viewName] = {
+ map: {
+ fields: mergeObjects(requestDef.index.fields)
+ },
+ reduce: '_count',
+ options: {
+ def: originalIndexDef
+ }
+ };
+
+ return doc;
+ }
+
+ db.constructor.emit('debug', ['find', 'creating index', ddocId]);
+
+ return upsert(db, ddocId, updateDdoc).then(function () {
+ if (hasInvalidLanguage) {
+ throw new Error('invalid language for ddoc with id "' +
+ ddocId +
+ '" (should be "query")');
+ }
+ }).then(function () {
+ // kick off a build
+ // TODO: abstract-pouchdb-mapreduce should support auto-updating
+ // TODO: should also use update_after, but pouchdb/pouchdb#3415 blocks me
+ var signature = ddocName + '/' + viewName;
+ return abstractMapper$1(db).query.call(db, signature, {
+ limit: 0,
+ reduce: false
+ }).then(function () {
+ return {
+ id: ddocId,
+ name: viewName,
+ result: viewExists ? 'exists' : 'created'
+ };
+ });
+ });
+}
+
+function getIndexes$1(db) {
+ // just search through all the design docs and filter in-memory.
+ // hopefully there aren't that many ddocs.
+ return db.allDocs({
+ startkey: '_design/',
+ endkey: '_design/\uffff',
+ include_docs: true
+ }).then(function (allDocsRes) {
+ var res = {
+ indexes: [{
+ ddoc: null,
+ name: '_all_docs',
+ type: 'special',
+ def: {
+ fields: [{_id: 'asc'}]
+ }
+ }]
+ };
+
+ res.indexes = flatten$1(res.indexes, allDocsRes.rows.filter(function (row) {
+ return row.doc.language === 'query';
+ }).map(function (row) {
+ var viewNames = row.doc.views !== undefined ? Object.keys(row.doc.views) : [];
+
+ return viewNames.map(function (viewName) {
+ var view = row.doc.views[viewName];
+ return {
+ ddoc: row.id,
+ name: viewName,
+ type: 'json',
+ def: massageIndexDef(view.options.def)
+ };
+ });
+ }));
+
+ // these are sorted by view name for some reason
+ res.indexes.sort(function (left, right) {
+ return compare(left.name, right.name);
+ });
+ res.total_rows = res.indexes.length;
+ return res;
+ });
+}
+
+// couchdb lowest collation value
+var COLLATE_LO = null;
+
+// couchdb highest collation value (TODO: well not really, but close enough amirite)
+var COLLATE_HI = {"\uffff": {}};
+
+// couchdb second-lowest collation value
+
+function checkFieldInIndex(index, field) {
+ var indexFields = index.def.fields.map(getKey);
+ for (var i = 0, len = indexFields.length; i < len; i++) {
+ var indexField = indexFields[i];
+ if (field === indexField) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// so when you do e.g. $eq/$eq, we can do it entirely in the database.
+// but when you do e.g. $gt/$eq, the first part can be done
+// in the database, but the second part has to be done in-memory,
+// because $gt has forced us to lose precision.
+// so that's what this determines
+function userOperatorLosesPrecision(selector, field) {
+ var matcher = selector[field];
+ var userOperator = getKey(matcher);
+
+ return userOperator !== '$eq';
+}
+
+// sort the user fields by their position in the index,
+// if they're in the index
+function sortFieldsByIndex(userFields, index) {
+ var indexFields = index.def.fields.map(getKey);
+
+ return userFields.slice().sort(function (a, b) {
+ var aIdx = indexFields.indexOf(a);
+ var bIdx = indexFields.indexOf(b);
+ if (aIdx === -1) {
+ aIdx = Number.MAX_VALUE;
+ }
+ if (bIdx === -1) {
+ bIdx = Number.MAX_VALUE;
+ }
+ return compare(aIdx, bIdx);
+ });
+}
+
+// first pass to try to find fields that will need to be sorted in-memory
+function getBasicInMemoryFields(index, selector, userFields) {
+
+ userFields = sortFieldsByIndex(userFields, index);
+
+ // check if any of the user selectors lose precision
+ var needToFilterInMemory = false;
+ for (var i = 0, len = userFields.length; i < len; i++) {
+ var field = userFields[i];
+ if (needToFilterInMemory || !checkFieldInIndex(index, field)) {
+ return userFields.slice(i);
+ }
+ if (i < len - 1 && userOperatorLosesPrecision(selector, field)) {
+ needToFilterInMemory = true;
+ }
+ }
+ return [];
+}
+
+function getInMemoryFieldsFromNe(selector) {
+ var fields = [];
+ Object.keys(selector).forEach(function (field) {
+ var matcher = selector[field];
+ Object.keys(matcher).forEach(function (operator) {
+ if (operator === '$ne') {
+ fields.push(field);
+ }
+ });
+ });
+ return fields;
+}
+
+function getInMemoryFields(coreInMemoryFields, index, selector, userFields) {
+ var result = flatten$1(
+ // in-memory fields reported as necessary by the query planner
+ coreInMemoryFields,
+ // combine with another pass that checks for any we may have missed
+ getBasicInMemoryFields(index, selector, userFields),
+ // combine with another pass that checks for $ne's
+ getInMemoryFieldsFromNe(selector)
+ );
+
+ return sortFieldsByIndex(uniq(result), index);
+}
+
+// check that at least one field in the user's query is represented
+// in the index. order matters in the case of sorts
+function checkIndexFieldsMatch(indexFields, sortOrder, fields) {
+ if (sortOrder) {
+ // array has to be a strict subarray of index array. furthermore,
+ // the sortOrder fields need to all be represented in the index
+ var sortMatches = oneArrayIsStrictSubArrayOfOther(sortOrder, indexFields);
+ var selectorMatches = oneArrayIsSubArrayOfOther(fields, indexFields);
+
+ return sortMatches && selectorMatches;
+ }
+
+ // all of the user's specified fields still need to be
+ // on the left side of the index array, although the order
+ // doesn't matter
+ return oneSetIsSubArrayOfOther(fields, indexFields);
+}
+
+var logicalMatchers = ['$eq', '$gt', '$gte', '$lt', '$lte'];
+function isNonLogicalMatcher(matcher) {
+ return logicalMatchers.indexOf(matcher) === -1;
+}
+
+// check all the index fields for usages of '$ne'
+// e.g. if the user queries {foo: {$ne: 'foo'}, bar: {$eq: 'bar'}},
+// then we can neither use an index on ['foo'] nor an index on
+// ['foo', 'bar'], but we can use an index on ['bar'] or ['bar', 'foo']
+function checkFieldsLogicallySound(indexFields, selector) {
+ var firstField = indexFields[0];
+ var matcher = selector[firstField];
+
+ if (typeof matcher === 'undefined') {
+ /* istanbul ignore next */
+ return true;
+ }
+
+ var isInvalidNe = Object.keys(matcher).length === 1 &&
+ getKey(matcher) === '$ne';
+
+ return !isInvalidNe;
+}
+
+function checkIndexMatches(index, sortOrder, fields, selector) {
+
+ var indexFields = index.def.fields.map(getKey);
+
+ var fieldsMatch = checkIndexFieldsMatch(indexFields, sortOrder, fields);
+
+ if (!fieldsMatch) {
+ return false;
+ }
+
+ return checkFieldsLogicallySound(indexFields, selector);
+}
+
+//
+// the algorithm is very simple:
+// take all the fields the user supplies, and if those fields
+// are a strict subset of the fields in some index,
+// then use that index
+//
+//
+function findMatchingIndexes(selector, userFields, sortOrder, indexes) {
+
+ return indexes.reduce(function (res, index) {
+ var indexMatches = checkIndexMatches(index, sortOrder, userFields, selector);
+ if (indexMatches) {
+ res.push(index);
+ }
+ return res;
+ }, []);
+}
+
+// find the best index, i.e. the one that matches the most fields
+// in the user's query
+function findBestMatchingIndex(selector, userFields, sortOrder, indexes, useIndex) {
+
+ var matchingIndexes = findMatchingIndexes(selector, userFields, sortOrder, indexes);
+
+ if (matchingIndexes.length === 0) {
+ if (useIndex) {
+ throw {
+ error: "no_usable_index",
+ message: "There is no index available for this selector."
+ };
+ }
+ //return `all_docs` as a default index;
+ //I'm assuming that _all_docs is always first
+ var defaultIndex = indexes[0];
+ defaultIndex.defaultUsed = true;
+ return defaultIndex;
+ }
+ if (matchingIndexes.length === 1 && !useIndex) {
+ return matchingIndexes[0];
+ }
+
+ var userFieldsMap = arrayToObject(userFields);
+
+ function scoreIndex(index) {
+ var indexFields = index.def.fields.map(getKey);
+ var score = 0;
+ for (var i = 0, len = indexFields.length; i < len; i++) {
+ var indexField = indexFields[i];
+ if (userFieldsMap[indexField]) {
+ score++;
+ }
+ }
+ return score;
+ }
+
+ if (useIndex) {
+ var useIndexDdoc = '_design/' + useIndex[0];
+ var useIndexName = useIndex.length === 2 ? useIndex[1] : false;
+ var index = matchingIndexes.find(function (index) {
+ if (useIndexName && index.ddoc === useIndexDdoc && useIndexName === index.name) {
+ return true;
+ }
+
+ if (index.ddoc === useIndexDdoc) {
+ /* istanbul ignore next */
+ return true;
+ }
+
+ return false;
+ });
+
+ if (!index) {
+ throw {
+ error: "unknown_error",
+ message: "Could not find that index or could not use that index for the query"
+ };
+ }
+ return index;
+ }
+
+ return max(matchingIndexes, scoreIndex);
+}
+
+function getSingleFieldQueryOptsFor(userOperator, userValue) {
+ switch (userOperator) {
+ case '$eq':
+ return {key: userValue};
+ case '$lte':
+ return {endkey: userValue};
+ case '$gte':
+ return {startkey: userValue};
+ case '$lt':
+ return {
+ endkey: userValue,
+ inclusive_end: false
+ };
+ case '$gt':
+ return {
+ startkey: userValue,
+ inclusive_start: false
+ };
+ }
+
+ return {
+ startkey: COLLATE_LO
+ };
+}
+
+function getSingleFieldCoreQueryPlan(selector, index) {
+ var field = getKey(index.def.fields[0]);
+ //ignoring this because the test to exercise the branch is skipped at the moment
+ /* istanbul ignore next */
+ var matcher = selector[field] || {};
+ var inMemoryFields = [];
+
+ var userOperators = Object.keys(matcher);
+
+ var combinedOpts;
+
+ userOperators.forEach(function (userOperator) {
+
+ if (isNonLogicalMatcher(userOperator)) {
+ inMemoryFields.push(field);
+ }
+
+ var userValue = matcher[userOperator];
+
+ var newQueryOpts = getSingleFieldQueryOptsFor(userOperator, userValue);
+
+ if (combinedOpts) {
+ combinedOpts = mergeObjects([combinedOpts, newQueryOpts]);
+ } else {
+ combinedOpts = newQueryOpts;
+ }
+ });
+
+ return {
+ queryOpts: combinedOpts,
+ inMemoryFields: inMemoryFields
+ };
+}
+
+function getMultiFieldCoreQueryPlan(userOperator, userValue) {
+ switch (userOperator) {
+ case '$eq':
+ return {
+ startkey: userValue,
+ endkey: userValue
+ };
+ case '$lte':
+ return {
+ endkey: userValue
+ };
+ case '$gte':
+ return {
+ startkey: userValue
+ };
+ case '$lt':
+ return {
+ endkey: userValue,
+ inclusive_end: false
+ };
+ case '$gt':
+ return {
+ startkey: userValue,
+ inclusive_start: false
+ };
+ }
+}
+
+function getMultiFieldQueryOpts(selector, index) {
+
+ var indexFields = index.def.fields.map(getKey);
+
+ var inMemoryFields = [];
+ var startkey = [];
+ var endkey = [];
+ var inclusiveStart;
+ var inclusiveEnd;
+
+
+ function finish(i) {
+
+ if (inclusiveStart !== false) {
+ startkey.push(COLLATE_LO);
+ }
+ if (inclusiveEnd !== false) {
+ endkey.push(COLLATE_HI);
+ }
+ // keep track of the fields where we lost specificity,
+ // and therefore need to filter in-memory
+ inMemoryFields = indexFields.slice(i);
+ }
+
+ for (var i = 0, len = indexFields.length; i < len; i++) {
+ var indexField = indexFields[i];
+
+ var matcher = selector[indexField];
+
+ if (!matcher || !Object.keys(matcher).length) { // fewer fields in user query than in index
+ finish(i);
+ break;
+ } else if (i > 0) {
+ if (Object.keys(matcher).some(isNonLogicalMatcher)) { // non-logical are ignored
+ finish(i);
+ break;
+ }
+ var usingGtlt = (
+ '$gt' in matcher || '$gte' in matcher ||
+ '$lt' in matcher || '$lte' in matcher);
+ var previousKeys = Object.keys(selector[indexFields[i - 1]]);
+ var previousWasEq = arrayEquals(previousKeys, ['$eq']);
+ var previousWasSame = arrayEquals(previousKeys, Object.keys(matcher));
+ var gtltLostSpecificity = usingGtlt && !previousWasEq && !previousWasSame;
+ if (gtltLostSpecificity) {
+ finish(i);
+ break;
+ }
+ }
+
+ var userOperators = Object.keys(matcher);
+
+ var combinedOpts = null;
+
+ for (var j = 0; j < userOperators.length; j++) {
+ var userOperator = userOperators[j];
+ var userValue = matcher[userOperator];
+
+ var newOpts = getMultiFieldCoreQueryPlan(userOperator, userValue);
+
+ if (combinedOpts) {
+ combinedOpts = mergeObjects([combinedOpts, newOpts]);
+ } else {
+ combinedOpts = newOpts;
+ }
+ }
+
+ startkey.push('startkey' in combinedOpts ? combinedOpts.startkey : COLLATE_LO);
+ endkey.push('endkey' in combinedOpts ? combinedOpts.endkey : COLLATE_HI);
+ if ('inclusive_start' in combinedOpts) {
+ inclusiveStart = combinedOpts.inclusive_start;
+ }
+ if ('inclusive_end' in combinedOpts) {
+ inclusiveEnd = combinedOpts.inclusive_end;
+ }
+ }
+
+ var res = {
+ startkey: startkey,
+ endkey: endkey
+ };
+
+ if (typeof inclusiveStart !== 'undefined') {
+ res.inclusive_start = inclusiveStart;
+ }
+ if (typeof inclusiveEnd !== 'undefined') {
+ res.inclusive_end = inclusiveEnd;
+ }
+
+ return {
+ queryOpts: res,
+ inMemoryFields: inMemoryFields
+ };
+}
+
+function getDefaultQueryPlan(selector) {
+ //using default index, so all fields need to be done in memory
+ return {
+ queryOpts: {startkey: null},
+ inMemoryFields: [Object.keys(selector)]
+ };
+}
+
+function getCoreQueryPlan(selector, index) {
+ if (index.defaultUsed) {
+ return getDefaultQueryPlan(selector, index);
+ }
+
+ if (index.def.fields.length === 1) {
+ // one field in index, so the value was indexed as a singleton
+ return getSingleFieldCoreQueryPlan(selector, index);
+ }
+ // else index has multiple fields, so the value was indexed as an array
+ return getMultiFieldQueryOpts(selector, index);
+}
+
+function planQuery(request, indexes) {
+
+ var selector = request.selector;
+ var sort = request.sort;
+
+ var userFieldsRes = getUserFields(selector, sort);
+
+ var userFields = userFieldsRes.fields;
+ var sortOrder = userFieldsRes.sortOrder;
+ var index = findBestMatchingIndex(selector, userFields, sortOrder, indexes, request.use_index);
+
+ var coreQueryPlan = getCoreQueryPlan(selector, index);
+ var queryOpts = coreQueryPlan.queryOpts;
+ var coreInMemoryFields = coreQueryPlan.inMemoryFields;
+
+ var inMemoryFields = getInMemoryFields(coreInMemoryFields, index, selector, userFields);
+
+ var res = {
+ queryOpts: queryOpts,
+ index: index,
+ inMemoryFields: inMemoryFields
+ };
+ return res;
+}
+
+function indexToSignature(index) {
+ // remove '_design/'
+ return index.ddoc.substring(8) + '/' + index.name;
+}
+
+function doAllDocs(db, originalOpts) {
+ var opts = clone(originalOpts);
+
+ // CouchDB responds in weird ways when you provide a non-string to _id;
+ // we mimic the behavior for consistency. See issue66 tests for details.
+
+ if (opts.descending) {
+ if ('endkey' in opts && typeof opts.endkey !== 'string') {
+ opts.endkey = '';
+ }
+ if ('startkey' in opts && typeof opts.startkey !== 'string') {
+ opts.limit = 0;
+ }
+ } else {
+ if ('startkey' in opts && typeof opts.startkey !== 'string') {
+ opts.startkey = '';
+ }
+ if ('endkey' in opts && typeof opts.endkey !== 'string') {
+ opts.limit = 0;
+ }
+ }
+ if ('key' in opts && typeof opts.key !== 'string') {
+ opts.limit = 0;
+ }
+
+ return db.allDocs(opts)
+ .then(function (res) {
+ // filter out any design docs that _all_docs might return
+ res.rows = res.rows.filter(function (row) {
+ return !/^_design\//.test(row.id);
+ });
+ return res;
+ });
+}
+
+function find$1(db, requestDef, explain) {
+ if (requestDef.selector) {
+ requestDef.selector = massageSelector(requestDef.selector);
+ }
+
+ if (requestDef.sort) {
+ requestDef.sort = massageSort(requestDef.sort);
+ }
+
+ if (requestDef.use_index) {
+ requestDef.use_index = massageUseIndex(requestDef.use_index);
+ }
+
+ validateFindRequest(requestDef);
+
+ return getIndexes$1(db).then(function (getIndexesRes) {
+
+ db.constructor.emit('debug', ['find', 'planning query', requestDef]);
+ var queryPlan = planQuery(requestDef, getIndexesRes.indexes);
+ db.constructor.emit('debug', ['find', 'query plan', queryPlan]);
+
+ var indexToUse = queryPlan.index;
+
+ validateSort(requestDef, indexToUse);
+
+ var opts = $inject_Object_assign({
+ include_docs: true,
+ reduce: false
+ }, queryPlan.queryOpts);
+
+ if ('startkey' in opts && 'endkey' in opts &&
+ collate(opts.startkey, opts.endkey) > 0) {
+ // can't possibly return any results, startkey > endkey
+ /* istanbul ignore next */
+ return {docs: []};
+ }
+
+ var isDescending = requestDef.sort &&
+ typeof requestDef.sort[0] !== 'string' &&
+ getValue(requestDef.sort[0]) === 'desc';
+
+ if (isDescending) {
+ // either all descending or all ascending
+ opts.descending = true;
+ opts = reverseOptions(opts);
+ }
+
+ if (!queryPlan.inMemoryFields.length) {
+ // no in-memory filtering necessary, so we can let the
+ // database do the limit/skip for us
+ if ('limit' in requestDef) {
+ opts.limit = requestDef.limit;
+ }
+ if ('skip' in requestDef) {
+ opts.skip = requestDef.skip;
+ }
+ }
+
+ if (explain) {
+ return Promise.resolve(queryPlan, opts);
+ }
+
+ return Promise.resolve().then(function () {
+ if (indexToUse.name === '_all_docs') {
+ return doAllDocs(db, opts);
+ } else {
+ var signature = indexToSignature(indexToUse);
+ return abstractMapper$1(db).query.call(db, signature, opts);
+ }
+ }).then(function (res) {
+ if (opts.inclusive_start === false) {
+ // may have to manually filter the first one,
+ // since couchdb has no true inclusive_start option
+ res.rows = filterInclusiveStart(res.rows, opts.startkey, indexToUse);
+ }
+
+ if (queryPlan.inMemoryFields.length) {
+ // need to filter some stuff in-memory
+ res.rows = filterInMemoryFields(res.rows, requestDef, queryPlan.inMemoryFields);
+ }
+
+ var resp = {
+ docs: res.rows.map(function (row) {
+ var doc = row.doc;
+ if (requestDef.fields) {
+ return pick$1(doc, requestDef.fields);
+ }
+ return doc;
+ })
+ };
+
+ if (indexToUse.defaultUsed) {
+ resp.warning = 'no matching index found, create an index to optimize query time';
+ }
+
+ return resp;
+ });
+ });
+}
+
+function explain$1(db, requestDef) {
+ return find$1(db, requestDef, true)
+ .then(function (queryPlan) {
+ return {
+ dbname: db.name,
+ index: queryPlan.index,
+ selector: requestDef.selector,
+ range: {
+ start_key: queryPlan.queryOpts.startkey,
+ end_key: queryPlan.queryOpts.endkey
+ },
+ opts: {
+ use_index: requestDef.use_index || [],
+ bookmark: "nil", //hardcoded to match CouchDB since its not supported,
+ limit: requestDef.limit,
+ skip: requestDef.skip,
+ sort: requestDef.sort || {},
+ fields: requestDef.fields,
+ conflicts: false, //hardcoded to match CouchDB since its not supported,
+ r: [49] // hardcoded to match CouchDB since its not support
+ },
+ limit: requestDef.limit,
+ skip: requestDef.skip || 0,
+ fields: requestDef.fields
+ };
+ });
+}
+
+function deleteIndex$1(db, index) {
+
+ if (!index.ddoc) {
+ throw new Error('you must supply an index.ddoc when deleting');
+ }
+
+ if (!index.name) {
+ throw new Error('you must supply an index.name when deleting');
+ }
+
+ var docId = index.ddoc;
+ var viewName = index.name;
+
+ function deltaFun(doc) {
+ if (Object.keys(doc.views).length === 1 && doc.views[viewName]) {
+ // only one view in this ddoc, delete the whole ddoc
+ return {_id: docId, _deleted: true};
+ }
+ // more than one view here, just remove the view
+ delete doc.views[viewName];
+ return doc;
+ }
+
+ return upsert(db, docId, deltaFun).then(function () {
+ return abstractMapper$1(db).viewCleanup.apply(db);
+ }).then(function () {
+ return {ok: true};
+ });
+}
+
+var createIndexAsCallback = callbackify(createIndex$1);
+var findAsCallback = callbackify(find$1);
+var explainAsCallback = callbackify(explain$1);
+var getIndexesAsCallback = callbackify(getIndexes$1);
+var deleteIndexAsCallback = callbackify(deleteIndex$1);
+
+var plugin = {};
+plugin.createIndex = toPromise(function (requestDef, callback) {
+
+ if (typeof requestDef !== 'object') {
+ return callback(new Error('you must provide an index to create'));
+ }
+
+ var createIndex$$1 = isRemote(this) ?
+ createIndex : createIndexAsCallback;
+ createIndex$$1(this, requestDef, callback);
+});
+
+plugin.find = toPromise(function (requestDef, callback) {
+
+ if (typeof callback === 'undefined') {
+ callback = requestDef;
+ requestDef = undefined;
+ }
+
+ if (typeof requestDef !== 'object') {
+ return callback(new Error('you must provide search parameters to find()'));
+ }
+
+ var find$$1 = isRemote(this) ? find : findAsCallback;
+ find$$1(this, requestDef, callback);
+});
+
+plugin.explain = toPromise(function (requestDef, callback) {
+
+ if (typeof callback === 'undefined') {
+ callback = requestDef;
+ requestDef = undefined;
+ }
+
+ if (typeof requestDef !== 'object') {
+ return callback(new Error('you must provide search parameters to explain()'));
+ }
+
+ var find$$1 = isRemote(this) ? explain : explainAsCallback;
+ find$$1(this, requestDef, callback);
+});
+
+plugin.getIndexes = toPromise(function (callback) {
+
+ var getIndexes$$1 = isRemote(this) ? getIndexes : getIndexesAsCallback;
+ getIndexes$$1(this, callback);
+});
+
+plugin.deleteIndex = toPromise(function (indexDef, callback) {
+
+ if (typeof indexDef !== 'object') {
+ return callback(new Error('you must provide an index to delete'));
+ }
+
+ var deleteIndex$$1 = isRemote(this) ?
+ deleteIndex : deleteIndexAsCallback;
+ deleteIndex$$1(this, indexDef, callback);
+});
+
+/* global PouchDB */
+
+if (typeof PouchDB === 'undefined') {
+ guardedConsole('error', 'pouchdb-find plugin error: ' +
+ 'Cannot find global "PouchDB" object! ' +
+ 'Did you remember to include pouchdb.js?');
+} else {
+ PouchDB.plugin(plugin);
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"1":1,"2":2,"3":3,"4":4,"5":5,"6":6}]},{},[11]);
diff --git a/desuto-viewer/Desuto-webviewer/public/js/svg-edit/config.js b/desuto-viewer/Desuto-webviewer/public/js/svg-edit/config.js
index 706c1e1..8ad6113 100644
--- a/desuto-viewer/Desuto-webviewer/public/js/svg-edit/config.js
+++ b/desuto-viewer/Desuto-webviewer/public/js/svg-edit/config.js
@@ -1,142 +1,142 @@
/*globals svgEditor*/
/*
The config.js file is intended for the setting of configuration or
preferences which must run early on; if this is not needed, it is
recommended that you create an extension instead (for greater
reusability and modularity).
*/
// CONFIG AND EXTENSION SETTING
/*
See defaultConfig and defaultExtensions in svg-editor.js for a list
of possible configuration settings.
See svg-editor.js for documentation on using setConfig().
*/
// URL OVERRIDE CONFIG
svgEditor.setConfig({
/**
To override the ability for URLs to set URL-based SVG content,
uncomment the following:
*/
// preventURLContentLoading: true,
/**
To override the ability for URLs to set other configuration (including
extension config), uncomment the following:
*/
// preventAllURLConfig: true,
/**
To override the ability for URLs to set their own extensions,
uncomment the following (note that if setConfig() is used in
extension code, it will still be additive to extensions,
however):
*/
// lockExtensions: true,
});
svgEditor.setConfig({
/*
Provide default values here which differ from that of the editor but
which the URL can override
*/
}, {allowInitialUserOverride: true});
// EXTENSION CONFIG
svgEditor.setConfig({
extensions: [
- 'ext-annotation.js', 'ext-realtime.js', 'ext-pouchdb.js'
+ 'ext-annotation.js', 'ext-realtime.js', 'ext-pouchdb.js', 'ext-point.js'
// 'ext-overview_window.js', 'ext-markers.js', 'ext-connector.js', 'ext-eyedropper.js', 'ext-shapes.js', 'ext-imagelib.js', 'ext-grid.js', 'ext-polygon.js', 'ext-star.js', 'ext-panning.js', 'ext-storage.js'
]
// , noDefaultExtensions: false, // noDefaultExtensions can only be meaningfully used in config.js or in the URL
});
// OTHER CONFIG
svgEditor.setConfig({
// canvasName: 'default',
canvas_expansion: 1,
initFill: {
color: 'FFFFFF', // solid white
opacity: 0
},
initStroke: {
width: 3,
color: '000000', // solid black
// opacity: 1
},
// initOpacity: 1,
// colorPickerCSS: null,
// initTool: 'select',
// exportWindowType: 'new', // 'same'
wireframe: false,
showlayers: false,
// no_save_warning: false,
// PATH CONFIGURATION
// imgPath: 'images/',
// langPath: 'locale/',
// extPath: 'extensions/',
// jGraduatePath: 'jgraduate/images/',
/*
Uncomment the following to allow at least same domain (embedded) access,
including file:// access.
Setting as `['*']` would allow any domain to access but would be unsafe to
data privacy and integrity.
*/
// allowedOrigins: [window.location.origin || 'null'], // May be 'null' (as a string) when used as a file:// URL
// DOCUMENT PROPERTIES
dimensions: [777, 666],
// EDITOR OPTIONS
// gridSnapping: false,
// gridColor: '#000',
// baseUnit: 'px',
// snappingStep: 10,
showRulers: false,
// EXTENSION-RELATED (GRID)
// showGrid: false, // Set by ext-grid.js
// EXTENSION-RELATED (STORAGE)
// noStorageOnLoad: false, // Some interaction with ext-storage.js; prevent even the loading of previously saved local storage
// forceStorage: false, // Some interaction with ext-storage.js; strongly discouraged from modification as it bypasses user privacy by preventing them from choosing whether to keep local storage or not
// emptyStorageOnDecline: true, // Used by ext-storage.js; empty any prior storage if the user declines to store
});
// PREF CHANGES
/**
setConfig() can also be used to set preferences in addition to
configuration (see defaultPrefs in svg-editor.js for a list of
possible settings), but at least if you are using ext-storage.js
to store preferences, it will probably be better to let your
users control these.
As with configuration, one may use allowInitialUserOverride, but
in the case of preferences, any previously stored preferences
will also thereby be enabled to override this setting (and at a
higher priority than any URL preference setting overrides).
Failing to use allowInitialUserOverride will ensure preferences
are hard-coded here regardless of URL or prior user storage setting.
*/
svgEditor.setConfig(
{
// lang: '', // Set dynamically within locale.js if not previously set
// iconsize: '', // Will default to 's' if the window height is smaller than the minimum height and 'm' otherwise
/**
* When showing the preferences dialog, svg-editor.js currently relies
* on curPrefs instead of $.pref, so allowing an override for bkgd_color
* means that this value won't have priority over block auto-detection as
* far as determining which color shows initially in the preferences
* dialog (though it can be changed and saved).
*/
bkgd_color: 'transparent',
bkgd_url: '',
// img_save: 'embed',
// Only shows in UI as far as alert notices
// save_notice_done: false,
// export_notice_done: false
}
);
svgEditor.setConfig(
{
// Indicate pref settings here if you wish to allow user storage or URL settings
// to be able to override your default preferences (unless other config options
// have already explicitly prevented one or the other)
},
{allowInitialUserOverride: true}
);
diff --git a/desuto-viewer/Desuto-webviewer/public/js/svg-edit/extensions/ext-point.js b/desuto-viewer/Desuto-webviewer/public/js/svg-edit/extensions/ext-point.js
new file mode 100644
index 0000000..f6ac8b8
--- /dev/null
+++ b/desuto-viewer/Desuto-webviewer/public/js/svg-edit/extensions/ext-point.js
@@ -0,0 +1,83 @@
+//# sourceURL=ext-point.js
+
+/*globals svgEditor, svgedit, svgCanvas, $*/
+/*jslint vars: true, eqeq: true*/
+/*
+ * ext-point.js
+ *
+ *
+ * Copyright(c) 2010 CloudCanvas, Inc.
+ * All rights reserved
+ *
+ */
+
+svgEditor.addExtension('point', function(S){'use strict';
+
+ var // NS = svgedit.NS,
+ selElems,
+ started,
+ newFO,
+ shape;
+
+ return {
+ name: 'point',
+ buttons: [{
+ id: 'tool_point',
+ type: 'mode',
+ title: 'Point Tool',
+ events: {
+ click: function(){
+ svgCanvas.setMode('point');
+ }
+ }
+ }],
+
+ callback: function(){
+ },
+
+ mouseDown: function(opts){
+ var rgb = 'blue';
+ // var ccRgbEl = rgb.substring(1, rgb.length);
+ //var sRgb = svgCanvas.getColor('stroke');
+ // var ccSRgbEl = sRgb.substring(1, rgb.length);
+ //var sWidth = svgCanvas.getStrokeWidth();
+
+ if (svgCanvas.getMode() == 'point') {
+ //started = true;
+
+ newFO = S.addSvgElementFromJson({
+ 'element': 'circle',
+ 'attr': {
+ 'cx': opts.start_x,
+ 'cy': opts.start_y,
+ 'r': 0.005,
+ 'id': S.getNextId(),
+ 'vector-effect':'non-scaling-stroke',
+ 'fill': rgb,
+ 'stroke': rgb,
+ 'histopatho-annotation': 'Tumor',
+ 'histopatho-annotator': annotator
+ }
+ });
+ return {
+ started: true
+ };
+ }
+ },
+ mouseMove: function(opts){
+ if (svgCanvas.getMode() == "point") {
+
+ }
+ },
+ mouseUp: function(){
+ if (svgCanvas.getMode() == "point") {
+ var keep = true;
+ // svgCanvas.addToSelection([newFO], true);
+ return {
+ keep: keep,
+ element: newFO
+ };
+ }
+ }
+ };
+});
diff --git a/desuto-viewer/Desuto-webviewer/public/js/svg-editor.js b/desuto-viewer/Desuto-webviewer/public/js/svg-editor.js
index 2e132e1..b805c56 100644
--- a/desuto-viewer/Desuto-webviewer/public/js/svg-editor.js
+++ b/desuto-viewer/Desuto-webviewer/public/js/svg-editor.js
@@ -1,5181 +1,5189 @@
/*globals svgEditor:true, globalStorage, widget, svgedit, jQuery, $, DOMParser, FileReader */
/*jslint vars: true, eqeq: true, todo: true, forin: true, continue: true, regexp: true */
/*
* svg-editor.js
*
* Licensed under the MIT License
*
* Copyright(c) 2010 Alexis Deveria
* Copyright(c) 2010 Pavol Rusnak
* Copyright(c) 2010 Jeff Schiller
* Copyright(c) 2010 Narendra Sisodiya
* Copyright(c) 2014 Brett Zamir
*
*/
// Dependencies:
// 1) units.js
// 2) browser.js
// 3) svgcanvas.js
/*
TODOS
1. JSDoc
*/
(function() {
if (window.svgEditor) {
return;
}
window.svgEditor = (function($) {
var editor = {};
// EDITOR PROPERTIES: (defined below)
// curPrefs, curConfig, canvas, storage, uiStrings
//
// STATE MAINTENANCE PROPERTIES
editor.tool_scale = 1; // Dependent on icon size, so any use to making configurable instead? Used by JQuerySpinBtn.js
editor.exportWindowCt = 0;
editor.langChanged = false;
editor.showSaveWarning = false;
editor.storagePromptClosed = false; // For use with ext-storage.js
var svgCanvas, urldata,
Utils = svgedit.utilities,
isReady = false,
customExportImage = false,
customExportPDF = false,
callbacks = [],
/**
* PREFS AND CONFIG
*/
// The iteration algorithm for defaultPrefs does not currently support array/objects
defaultPrefs = {
// EDITOR OPTIONS (DIALOG)
lang: '', // Default to "en" if locale.js detection does not detect another language
iconsize: '', // Will default to 's' if the window height is smaller than the minimum height and 'm' otherwise
bkgd_color: '#FFF',
bkgd_url: '',
// DOCUMENT PROPERTIES (DIALOG)
img_save: 'embed',
// ALERT NOTICES
// Only shows in UI as far as alert notices, but useful to remember, so keeping as pref
save_notice_done: false,
export_notice_done: false
},
curPrefs = {},
// Note: The difference between Prefs and Config is that Prefs
// can be changed in the UI and are stored in the browser,
// while config cannot
curConfig = {
// We do not put on defaultConfig to simplify object copying
// procedures (we obtain instead from defaultExtensions)
extensions: [],
/**
* Can use window.location.origin to indicate the current
* origin. Can contain a '*' to allow all domains or 'null' (as
* a string) to support all file:// URLs. Cannot be set by
* URL for security reasons (not safe, at least for
* privacy or data integrity of SVG content).
* Might have been fairly safe to allow
* `new URL(window.location.href).origin` by default but
* avoiding it ensures some more security that even third
* party apps on the same domain also cannot communicate
* with this app by default.
* For use with ext-xdomain-messaging.js
* @todo We might instead make as a user-facing preference.
*/
allowedOrigins: []
},
defaultExtensions = [
//'ext-overview_window.js',
//'ext-markers.js',
//'ext-connector.js',
//'ext-eyedropper.js',
//'ext-shapes.js',
//'ext-imagelib.js',
//'ext-grid.js',
//'ext-polygon.js',
//'ext-star.js',
//'ext-panning.js',
//'ext-storage.js'
],
defaultConfig = {
// Todo: svgcanvas.js also sets and checks: show_outside_canvas, selectNew; add here?
// Change the following to preferences and add pref controls to the UI (e.g., initTool, wireframe, showlayers)?
canvasName: 'default',
canvas_expansion: 3,
initFill: {
color: 'FF0000', // solid red
opacity: 1
},
initStroke: {
width: 5,
color: '000000', // solid black
opacity: 1
},
initOpacity: 1,
colorPickerCSS: null, // Defaults to 'left' with a position equal to that of the fill_color or stroke_color element minus 140, and a 'bottom' equal to 40
initTool: 'select',
exportWindowType: 'new', // 'same' (todo: also support 'download')
wireframe: false,
showlayers: false,
no_save_warning: true,
// PATH CONFIGURATION
// The following path configuration items are disallowed in the URL (as should any future path configurations)
imgPath: 'img/',
langPath: 'js/svg-edit/locale/',
extPath: 'js/svg-edit/extensions/',
jGraduatePath: 'jgraduate/images/',
// DOCUMENT PROPERTIES
// Change the following to a preference (already in the Document Properties dialog)?
dimensions: [640, 480],
// EDITOR OPTIONS
// Change the following to preferences (already in the Editor Options dialog)?
gridSnapping: false,
gridColor: '#000',
baseUnit: 'px',
snappingStep: 10,
showRulers: true,
// URL BEHAVIOR CONFIGURATION
preventAllURLConfig: false,
preventURLContentLoading: false,
// EXTENSION CONFIGURATION (see also preventAllURLConfig)
lockExtensions: false, // Disallowed in URL setting
noDefaultExtensions: false, // noDefaultExtensions can only be meaningfully used in config.js or in the URL
// EXTENSION-RELATED (GRID)
showGrid: false, // Set by ext-grid.js
// EXTENSION-RELATED (STORAGE)
noStorageOnLoad: false, // Some interaction with ext-storage.js; prevent even the loading of previously saved local storage
forceStorage: false, // Some interaction with ext-storage.js; strongly discouraged from modification as it bypasses user privacy by preventing them from choosing whether to keep local storage or not
emptyStorageOnDecline: false // Used by ext-storage.js; empty any prior storage if the user declines to store
},
/**
* LOCALE
* @todo Can we remove now that we are always loading even English? (unless locale is set to null)
*/
uiStrings = editor.uiStrings = {
common: {
ok: 'OK',
cancel: 'Cancel',
key_up: 'Up',
key_down: 'Down',
key_backspace: 'Backspace',
key_del: 'Del'
},
// This is needed if the locale is English, since the locale strings are not read in that instance.
layers: {
layer: 'Layer'
},
notification: {
invalidAttrValGiven: 'Invalid value given',
noContentToFitTo: 'No content to fit to',
dupeLayerName: 'There is already a layer named that!',
enterUniqueLayerName: 'Please enter a unique layer name',
enterNewLayerName: 'Please enter the new layer name',
layerHasThatName: 'Layer already has that name',
QmoveElemsToLayer: 'Move selected elements to layer \'%s\'?',
QwantToClear: 'Do you want to clear the drawing?\nThis will also erase your undo history!',
QwantToOpen: 'Do you want to open a new file?\nThis will also erase your undo history!',
QerrorsRevertToSource: 'There were parsing errors in your SVG source.\nRevert back to original SVG source?',
QignoreSourceChanges: 'Ignore changes made to SVG source?',
featNotSupported: 'Feature not supported',
enterNewImgURL: 'Enter the new image URL',
defsFailOnSave: 'NOTE: Due to a bug in your browser, this image may appear wrong (missing gradients or elements). It will however appear correct once actually saved.',
loadingImage: 'Loading image, please wait...',
saveFromBrowser: 'Select \'Save As...\' in your browser to save this image as a %s file.',
noteTheseIssues: 'Also note the following issues: ',
unsavedChanges: 'There are unsaved changes.',
enterNewLinkURL: 'Enter the new hyperlink URL',
errorLoadingSVG: 'Error: Unable to load SVG data',
URLloadFail: 'Unable to load from URL',
retrieving: 'Retrieving \'%s\' ...'
}
};
function loadSvgString (str, callback) {
var success = svgCanvas.setSvgString(str) !== false;
callback = callback || $.noop;
if (success) {
callback(true);
} else {
$.alert(uiStrings.notification.errorLoadingSVG, function() {
callback(false);
});
}
}
/**
* EXPORTS
*/
/**
* Store and retrieve preferences
* @param {string} key The preference name to be retrieved or set
* @param {string} [val] The value. If the value supplied is missing or falsey, no change to the preference will be made.
* @returns {string} If val is missing or falsey, the value of the previously stored preference will be returned.
* @todo Can we change setting on the jQuery namespace (onto editor) to avoid conflicts?
* @todo Review whether any remaining existing direct references to
* getting curPrefs can be changed to use $.pref() getting to ensure
* defaultPrefs fallback (also for sake of allowInitialUserOverride); specifically, bkgd_color could be changed so that
* the pref dialog has a button to auto-calculate background, but otherwise uses $.pref() to be able to get default prefs
* or overridable settings
*/
$.pref = function (key, val) {
if (val) {
curPrefs[key] = val;
editor.curPrefs = curPrefs; // Update exported value
return;
}
return (key in curPrefs) ? curPrefs[key] : defaultPrefs[key];
};
/**
* EDITOR PUBLIC METHODS
* locale.js also adds "putLang" and "readLang" as editor methods
* @todo Sort these methods per invocation order, ideally with init at the end
* @todo Prevent execution until init executes if dependent on it?
*/
/**
* Where permitted, sets canvas and/or defaultPrefs based on previous
* storage. This will override URL settings (for security reasons) but
* not config.js configuration (unless initial user overriding is explicitly
* permitted there via allowInitialUserOverride).
* @todo Split allowInitialUserOverride into allowOverrideByURL and
* allowOverrideByUserStorage so config.js can disallow some
* individual items for URL setting but allow for user storage AND/OR
* change URL setting so that it always uses a different namespace,
* so it won't affect pre-existing user storage (but then if users saves
* that, it will then be subject to tampering
*/
editor.loadContentAndPrefs = function () {
if (!curConfig.forceStorage && (curConfig.noStorageOnLoad || !document.cookie.match(/(?:^|;\s*)store=(?:prefsAndContent|prefsOnly)/))) {
return;
}
// LOAD CONTENT
if (editor.storage && // Cookies do not have enough available memory to hold large documents
(curConfig.forceStorage || (!curConfig.noStorageOnLoad && document.cookie.match(/(?:^|;\s*)store=prefsAndContent/)))
) {
var name = 'svgedit-' + curConfig.canvasName;
var cached = editor.storage.getItem(name);
if (cached) {
editor.loadFromString(cached);
}
}
// LOAD PREFS
var key;
for (key in defaultPrefs) {
if (defaultPrefs.hasOwnProperty(key)) { // It's our own config, so we don't need to iterate up the prototype chain
var storeKey = 'svg-edit-' + key;
if (editor.storage) {
var val = editor.storage.getItem(storeKey);
if (val) {
defaultPrefs[key] = String(val); // Convert to string for FF (.value fails in Webkit)
}
}
else if (window.widget) {
defaultPrefs[key] = widget.preferenceForKey(storeKey);
}
else {
var result = document.cookie.match(new RegExp('(?:^|;\\s*)' + Utils.preg_quote(encodeURIComponent(storeKey)) + '=([^;]+)'));
defaultPrefs[key] = result ? decodeURIComponent(result[1]) : '';
}
}
}
};
/**
* Allows setting of preferences or configuration (including extensions).
* @param {object} opts The preferences or configuration (including extensions)
* @param {object} [cfgCfg] Describes configuration which applies to the particular batch of supplied options
* @param {boolean} [cfgCfg.allowInitialUserOverride=false] Set to true if you wish
* to allow initial overriding of settings by the user via the URL
* (if permitted) or previously stored preferences (if permitted);
* note that it will be too late if you make such calls in extension
* code because the URL or preference storage settings will
* have already taken place.
* @param {boolean} [cfgCfg.overwrite=true] Set to false if you wish to
* prevent the overwriting of prior-set preferences or configuration
* (URL settings will always follow this requirement for security
* reasons, so config.js settings cannot be overridden unless it
* explicitly permits via "allowInitialUserOverride" but extension config
* can be overridden as they will run after URL settings). Should
* not be needed in config.js.
*/
editor.setConfig = function (opts, cfgCfg) {
cfgCfg = cfgCfg || {};
function extendOrAdd (cfgObj, key, val) {
if (cfgObj[key] && typeof cfgObj[key] === 'object') {
$.extend(true, cfgObj[key], val);
}
else {
cfgObj[key] = val;
}
return;
}
$.each(opts, function(key, val) {
if (opts.hasOwnProperty(key)) {
// Only allow prefs defined in defaultPrefs
if (defaultPrefs.hasOwnProperty(key)) {
if (cfgCfg.overwrite === false && (
curConfig.preventAllURLConfig ||
curPrefs.hasOwnProperty(key)
)) {
return;
}
if (cfgCfg.allowInitialUserOverride === true) {
defaultPrefs[key] = val;
}
else {
$.pref(key, val);
}
}
else if (['extensions', 'allowedOrigins'].indexOf(key) > -1) {
if (cfgCfg.overwrite === false &&
(
curConfig.preventAllURLConfig ||
key === 'allowedOrigins' ||
(key === 'extensions' && curConfig.lockExtensions)
)
) {
return;
}
curConfig[key] = curConfig[key].concat(val); // We will handle any dupes later
}
// Only allow other curConfig if defined in defaultConfig
else if (defaultConfig.hasOwnProperty(key)) {
if (cfgCfg.overwrite === false && (
curConfig.preventAllURLConfig ||
curConfig.hasOwnProperty(key)
)) {
return;
}
// Potentially overwriting of previously set config
if (curConfig.hasOwnProperty(key)) {
if (cfgCfg.overwrite === false) {
return;
}
extendOrAdd(curConfig, key, val);
}
else {
if (cfgCfg.allowInitialUserOverride === true) {
extendOrAdd(defaultConfig, key, val);
}
else {
if (defaultConfig[key] && typeof defaultConfig[key] === 'object') {
curConfig[key] = {};
$.extend(true, curConfig[key], val); // Merge properties recursively, e.g., on initFill, initStroke objects
}
else {
curConfig[key] = val;
}
}
}
}
}
});
editor.curConfig = curConfig; // Update exported value
};
/**
* @param {object} opts Extension mechanisms may call setCustomHandlers with three functions: opts.open, opts.save, and opts.exportImage
* opts.open's responsibilities are:
* - invoke a file chooser dialog in 'open' mode
* - let user pick a SVG file
* - calls svgCanvas.setSvgString() with the string contents of that file
* opts.save's responsibilities are:
* - accept the string contents of the current document
* - invoke a file chooser dialog in 'save' mode
* - save the file to location chosen by the user
* opts.exportImage's responsibilities (with regard to the object it is supplied in its 2nd argument) are:
* - inform user of any issues supplied via the "issues" property
* - convert the "svg" property SVG string into an image for export;
* utilize the properties "type" (currently 'PNG', 'JPEG', 'BMP',
* 'WEBP', 'PDF'), "mimeType", and "quality" (for 'JPEG' and 'WEBP'
* types) to determine the proper output.
*/
editor.setCustomHandlers = function (opts) {
editor.ready(function() {
if (opts.open) {
$('#tool_open > input[type="file"]').remove();
$('#tool_open').show();
svgCanvas.open = opts.open;
}
if (opts.save) {
editor.showSaveWarning = false;
svgCanvas.bind('saved', opts.save);
}
});
};
editor.randomizeIds = function () {
svgCanvas.randomizeIds(arguments);
};
editor.init = function () {
// var host = location.hostname,
// onWeb = host && host.indexOf('.') >= 0;
// Some FF versions throw security errors here when directly accessing
try {
if ('localStorage' in window) { // && onWeb removed so Webkit works locally
editor.storage = localStorage;
}
} catch(err) {}
// Todo: Avoid var-defined functions and group functions together, etc. where possible
var good_langs = [];
$('#lang_select option').each(function() {
good_langs.push(this.value);
});
function setupCurPrefs () {
curPrefs = $.extend(true, {}, defaultPrefs, curPrefs); // Now safe to merge with priority for curPrefs in the event any are already set
// Export updated prefs
editor.curPrefs = curPrefs;
}
function setupCurConfig () {
curConfig = $.extend(true, {}, defaultConfig, curConfig); // Now safe to merge with priority for curConfig in the event any are already set
// Now deal with extensions and other array config
if (!curConfig.noDefaultExtensions) {
curConfig.extensions = curConfig.extensions.concat(defaultExtensions);
}
// ...and remove any dupes
$.each(['extensions', 'allowedOrigins'], function (i, cfg) {
curConfig[cfg] = $.grep(curConfig[cfg], function (n, i) {
return i === curConfig[cfg].indexOf(n);
});
});
// Export updated config
editor.curConfig = curConfig;
}
(function() {
// Load config/data from URL if given
var src, qstr;
//urldata = $.deparam.querystring(true);
/*if (!$.isEmptyObject(urldata)) {
if (urldata.dimensions) {
urldata.dimensions = urldata.dimensions.split(',');
}
if (urldata.bkgd_color) {
urldata.bkgd_color = '#' + urldata.bkgd_color;
}
if (urldata.extensions) {
// For security reasons, disallow cross-domain or cross-folder extensions via URL
urldata.extensions = urldata.extensions.match(/[:\/\\]/) ? '' : urldata.extensions.split(',');
}
// Disallowing extension paths via URL for
// security reasons, even for same-domain
// ones given potential to interact in undesirable
// ways with other script resources
$.each(
[
'extPath', 'imgPath',
'langPath', 'jGraduatePath'
],
function (pathConfig) {
if (urldata[pathConfig]) {
delete urldata[pathConfig];
}
}
);
editor.setConfig(urldata, {overwrite: false}); // Note: source and url (as with storagePrompt later) are not set on config but are used below
setupCurConfig();
if (!curConfig.preventURLContentLoading) {
src = urldata.source;
qstr = $.param.querystring();
if (!src) { // urldata.source may have been null if it ended with '='
if (qstr.indexOf('source=data:') >= 0) {
src = qstr.match(/source=(data:[^&]*)/)[1];
}
}
if (src) {
if (src.indexOf('data:') === 0) {
editor.loadFromDataURI(src);
} else {
editor.loadFromString(src);
}
return;
}
if (urldata.url) {
editor.loadFromURL(urldata.url);
return;
}
}
if (!urldata.noStorageOnLoad || curConfig.forceStorage) {
editor.loadContentAndPrefs();
}
setupCurPrefs();
}
else {*/
setupCurConfig();
editor.loadContentAndPrefs();
setupCurPrefs();
//}
}());
// For external openers
(function() {
// let the opener know SVG Edit is ready (now that config is set up)
var svgEditorReadyEvent,
w = window.opener;
if (w) {
try {
svgEditorReadyEvent = w.document.createEvent('Event');
svgEditorReadyEvent.initEvent('svgEditorReady', true, true);
w.document.documentElement.dispatchEvent(svgEditorReadyEvent);
}
catch(e) {}
}
}());
var setIcon = editor.setIcon = function(elem, icon_id, forcedSize) {
var icon = (typeof icon_id === 'string') ? $.getSvgIcon(icon_id, true) : icon_id.clone();
if (!icon) {
console.log('NOTE: Icon image missing: ' + icon_id);
return;
}
$(elem).empty().append(icon);
};
var extFunc = function() {
$.each(curConfig.extensions, function() {
var extname = this;
if (!extname.match(/^ext-.*\.js/)) { // Ensure URL cannot specify some other unintended file in the extPath
return;
}
$.getScript(curConfig.extPath + extname, function(d) {
// Fails locally in Chrome 5
if (!d) {
var s = document.createElement('script');
s.src = curConfig.extPath + extname;
document.querySelector('head').appendChild(s);
}
});
});
// var lang = ('lang' in curPrefs) ? curPrefs.lang : null;
editor.putLocale(null, good_langs);
};
// Load extensions
// Bit of a hack to run extensions in local Opera/IE9
if (document.location.protocol === 'file:') {
setTimeout(extFunc, 100);
} else {
extFunc();
}
$.svgIcons(curConfig.imgPath + 'svg_edit_icons-fa.svg', {
w:24, h:24,
id_match: false,
no_img: !svgedit.browser.isWebkit(), // Opera & Firefox 4 gives odd behavior w/images
fallback_path: curConfig.imgPath,
fallback: {
'new_image': 'clear.png',
'save': 'save.png',
'open': 'open.png',
'source': 'source.png',
'docprops': 'document-properties.png',
'wireframe': 'wireframe.png',
'undo': 'undo.png',
'redo': 'redo.png',
'select': 'select.png',
'select_node': 'select_node.png',
'pencil': 'fhpath.png',
'pen': 'line.png',
'square': 'square.png',
'rect': 'rect.png',
'fh_rect': 'freehand-square.png',
'circle': 'circle.png',
'ellipse': 'ellipse.png',
'fh_ellipse': 'freehand-circle.png',
'path': 'path.png',
'text': 'text.png',
'image': 'image.png',
'zoom': 'zoom.png',
'clone': 'clone.png',
'node_clone': 'node_clone.png',
'delete': 'delete.png',
'node_delete': 'node_delete.png',
'group': 'shape_group_elements.png',
'ungroup': 'shape_ungroup.png',
'move_top': 'move_top.png',
'move_bottom': 'move_bottom.png',
'to_path': 'to_path.png',
'link_controls': 'link_controls.png',
'reorient': 'reorient.png',
'align_left': 'align-left.png',
'align_center': 'align-center.png',
'align_right': 'align-right.png',
'align_top': 'align-top.png',
'align_middle': 'align-middle.png',
'align_bottom': 'align-bottom.png',
'go_up': 'go-up.png',
'go_down': 'go-down.png',
'ok': 'save.png',
'cancel': 'cancel.png',
'arrow_right': 'flyouth.png',
'arrow_down': 'dropdown.gif'
},
placement: {
'#logo': 'logo',
'#tool_clear div,#layer_new': 'new_image',
'#tool_save': 'save',
'#tool_export div': 'export',
'#tool_open div div': 'open',
'#tool_import div div': 'import',
'#tool_source': 'source',
'#tool_docprops > div': 'docprops',
'#tool_wireframe': 'wireframe',
'#tool_undo': 'undo',
'#tool_redo': 'redo',
'#tool_select': 'select',
'#tool_fhpath': 'pencil',
'#tool_line': 'pen',
'#tool_rect,#tools_rect_show': 'rect',
'#tool_square': 'square',
'#tool_fhrect': 'fh_rect',
'#tool_ellipse,#tools_ellipse_show': 'ellipse',
'#tool_circle': 'circle',
'#tool_fhellipse': 'fh_ellipse',
'#tool_path': 'path',
'#tool_text,#layer_rename': 'text',
'#tool_image': 'image',
'#tool_zoom': 'zoom',
+ '#tool_point': 'point',
'#tool_clone,#tool_clone_multi': 'clone',
'#tool_node_clone': 'node_clone',
'#layer_delete,#tool_delete,#tool_delete_multi': 'delete',
'#tool_node_delete': 'node_delete',
'#tool_add_subpath': 'add_subpath',
'#tool_openclose_path': 'open_path',
'#tool_move_top': 'move_top',
'#tool_move_bottom': 'move_bottom',
'#tool_topath': 'to_path',
'#tool_node_link': 'link_controls',
'#tool_reorient': 'reorient',
'#tool_group_elements': 'group_elements',
'#tool_ungroup': 'ungroup',
'#tool_unlink_use': 'unlink_use',
'#tool_alignleft, #tool_posleft': 'align_left',
'#tool_aligncenter, #tool_poscenter': 'align_center',
'#tool_alignright, #tool_posright': 'align_right',
'#tool_aligntop, #tool_postop': 'align_top',
'#tool_alignmiddle, #tool_posmiddle': 'align_middle',
'#tool_alignbottom, #tool_posbottom': 'align_bottom',
'#cur_position': 'align',
'#linecap_butt,#cur_linecap': 'linecap_butt',
'#linecap_round': 'linecap_round',
'#linecap_square': 'linecap_square',
'#linejoin_miter,#cur_linejoin': 'linejoin_miter',
'#linejoin_round': 'linejoin_round',
'#linejoin_bevel': 'linejoin_bevel',
'#url_notice': 'warning',
'#layer_up': 'go_up',
'#layer_down': 'go_down',
'#layer_moreopts': 'context_menu',
'#layerlist td.layervis': 'eye',
'#tool_source_save,#tool_docprops_save,#tool_prefs_save': 'ok',
'#tool_source_cancel,#tool_docprops_cancel,#tool_prefs_cancel': 'cancel',
'#rwidthLabel, #iwidthLabel': 'width',
'#rheightLabel, #iheightLabel': 'height',
'#cornerRadiusLabel span': 'c_radius',
'#angleLabel': 'angle',
'#linkLabel,#tool_make_link,#tool_make_link_multi': 'globe_link',
'#zoomLabel': 'zoom',
'#tool_fill label': 'fill',
'#tool_stroke .icon_label': 'stroke',
'#group_opacityLabel': 'opacity',
'#blurLabel': 'blur',
'#font_sizeLabel': 'fontsize',
'.flyout_arrow_horiz': 'arrow_right',
'.dropdown button, #main_button .dropdown': 'arrow_down',
'#palette .palette_item:first, #fill_bg, #stroke_bg': 'no_color'
},
resize: {
'#logo .svg_icon': 28,
'.flyout_arrow_horiz .svg_icon': 5,
'.layer_button .svg_icon, #layerlist td.layervis .svg_icon': 14,
'.dropdown button .svg_icon': 7,
'#main_button .dropdown .svg_icon': 9,
'.palette_item:first .svg_icon' : 15,
'#fill_bg .svg_icon, #stroke_bg .svg_icon': 16,
'.toolbar_button button .svg_icon': 16,
'.stroke_tool div div .svg_icon': 20,
'#tools_bottom label .svg_icon': 18
},
callback: function(icons) {
$('.toolbar_button button > svg, .toolbar_button button > img').each(function() {
$(this).parent().prepend(this);
});
var min_height,
tleft = $('#tools_left');
if (tleft.length !== 0) {
min_height = tleft.offset().top + tleft.outerHeight();
}
var size = $.pref('iconsize');
editor.setIconSize(size || ($(window).height() < min_height ? 's': 'm'));
// Look for any missing flyout icons from plugins
$('.tools_flyout').each(function() {
var shower = $('#' + this.id + '_show');
var sel = shower.attr('data-curopt');
// Check if there's an icon here
if (!shower.children('svg, img').length) {
var clone = $(sel).children().clone();
if (clone.length) {
clone[0].removeAttribute('style'); //Needed for Opera
shower.append(clone);
}
}
});
editor.runCallbacks();
setTimeout(function() {
$('.flyout_arrow_horiz:empty').each(function() {
$(this).append($.getSvgIcon('arrow_right').width(5).height(5));
});
}, 1);
}
});
editor.canvas = svgCanvas = new $.SvgCanvas(document.getElementById('svgcanvas'), curConfig);
var supportsNonSS, resize_timer, changeZoom, Actions, curScrollPos,
palette = [ // Todo: Make into configuration item?
'#000000', '#3f3f3f', '#7f7f7f', '#bfbfbf', '#ffffff',
'#ff0000', '#ff7f00', '#ffff00', '#7fff00',
'#00ff00', '#00ff7f', '#00ffff', '#007fff',
'#0000ff', '#7f00ff', '#ff00ff', '#ff007f',
'#7f0000', '#7f3f00', '#7f7f00', '#3f7f00',
'#007f00', '#007f3f', '#007f7f', '#003f7f',
'#00007f', '#3f007f', '#7f007f', '#7f003f',
'#ffaaaa', '#ffd4aa', '#ffffaa', '#d4ffaa',
'#aaffaa', '#aaffd4', '#aaffff', '#aad4ff',
'#aaaaff', '#d4aaff', '#ffaaff', '#ffaad4'
],
modKey = (svgedit.browser.isMac() ? 'meta+' : 'ctrl+'), // ⌘
path = svgCanvas.pathActions,
undoMgr = svgCanvas.undoMgr,
defaultImageURL = curConfig.imgPath + 'rotate.png',
workarea = $('#workarea'),
canv_menu = $('#cmenu_canvas'),
// layer_menu = $('#cmenu_layers'), // Unused
exportWindow = null,
zoomInIcon = 'crosshair',
zoomOutIcon = 'crosshair',
ui_context = 'toolbars',
origSource = '',
paintBox = {fill: null, stroke:null};
// This sets up alternative dialog boxes. They mostly work the same way as
// their UI counterparts, expect instead of returning the result, a callback
// needs to be included that returns the result as its first parameter.
// In the future we may want to add additional types of dialog boxes, since
// they should be easy to handle this way.
/*(function() {
$('#dialog_container').draggable({cancel: '#dialog_content, #dialog_buttons *', containment: 'window'});
var box = $('#dialog_box'),
btn_holder = $('#dialog_buttons'),
dialog_content = $('#dialog_content'),
dbox = function(type, msg, callback, defaultVal, opts, changeCb, checkbox) {
var ok, ctrl, chkbx;
dialog_content.html('<p>'+msg.replace(/\n/g, '</p><p>')+'</p>')
.toggleClass('prompt', (type == 'prompt'));
btn_holder.empty();
ok = $('<input type="button" value="' + uiStrings.common.ok + '">').appendTo(btn_holder);
if (type !== 'alert') {
$('<input type="button" value="' + uiStrings.common.cancel + '">')
.appendTo(btn_holder)
.click(function() { box.hide(); if (callback) {callback(false);}});
}
if (type === 'prompt') {
ctrl = $('<input type="text">').prependTo(btn_holder);
ctrl.val(defaultVal || '');
ctrl.bind('keydown', 'return', function() {ok.click();});
}
else if (type === 'select') {
var div = $('<div style="text-align:center;">');
ctrl = $('<select>').appendTo(div);
if (checkbox) {
var label = $('<label>').text(checkbox.label);
chkbx = $('<input type="checkbox">').appendTo(label);
chkbx.val(checkbox.value);
if (checkbox.tooltip) {
label.attr('title', checkbox.tooltip);
}
chkbx.prop('checked', !!checkbox.checked);
div.append($('<div>').append(label));
}
$.each(opts || [], function (opt, val) {
if (typeof val === 'object') {
ctrl.append($('<option>').val(val.value).html(val.text));
}
else {
ctrl.append($('<option>').html(val));
}
});
dialog_content.append(div);
if (defaultVal) {
ctrl.val(defaultVal);
}
if (changeCb) {
ctrl.bind('change', 'return', changeCb);
}
ctrl.bind('keydown', 'return', function() {ok.click();});
}
else if (type === 'process') {
ok.hide();
}
box.show();
ok.click(function() {
box.hide();
var resp = (type === 'prompt' || type === 'select') ? ctrl.val() : true;
if (callback) {
if (chkbx) {
callback(resp, chkbx.prop('checked'));
}
else {
callback(resp);
}
}
}).focus();
if (type === 'prompt' || type === 'select') {
ctrl.focus();
}
};
$.alert = function(msg, cb) { dbox('alert', msg, cb);};
$.confirm = function(msg, cb) { dbox('confirm', msg, cb);};
$.process_cancel = function(msg, cb) { dbox('process', msg, cb);};
$.prompt = function(msg, txt, cb) { dbox('prompt', msg, cb, txt);};
$.select = function(msg, opts, cb, changeCb, txt, checkbox) { dbox('select', msg, cb, txt, opts, changeCb, checkbox);};
}());*/
var setSelectMode = function() {
var curr = $('.tool_button_current');
if (curr.length && curr[0].id !== 'tool_select') {
curr.removeClass('tool_button_current').addClass('tool_button');
$('#tool_select').addClass('tool_button_current').removeClass('tool_button');
$('#styleoverrides').text('#svgcanvas svg *{cursor:move;pointer-events:all} #svgcanvas svg{cursor:default}');
}
svgCanvas.setMode('select');
workarea.css('cursor', 'auto');
};
// used to make the flyouts stay on the screen longer the very first time
// var flyoutspeed = 1250; // Currently unused
var textBeingEntered = false;
var selectedElement = null;
var multiselected = false;
var editingsource = false;
var docprops = false;
var preferences = false;
var cur_context = '';
var origTitle = $('title:first').text();
// Make [1,2,5] array
var r_intervals = [];
var i;
for (i = 0.1; i < 1E5; i *= 10) {
r_intervals.push(i);
r_intervals.push(2 * i);
r_intervals.push(5 * i);
}
// This function highlights the layer passed in (by fading out the other layers)
// if no layer is passed in, this function restores the other layers
var toggleHighlightLayer = function(layerNameToHighlight) {
var i, curNames = [], numLayers = svgCanvas.getCurrentDrawing().getNumLayers();
for (i = 0; i < numLayers; i++) {
curNames[i] = svgCanvas.getCurrentDrawing().getLayerName(i);
}
if (layerNameToHighlight) {
for (i = 0; i < numLayers; ++i) {
if (curNames[i] != layerNameToHighlight) {
svgCanvas.getCurrentDrawing().setLayerOpacity(curNames[i], 0.5);
}
}
} else {
for (i = 0; i < numLayers; ++i) {
svgCanvas.getCurrentDrawing().setLayerOpacity(curNames[i], 1.0);
}
}
};
var populateLayers = function() {
svgCanvas.clearSelection();
var layerlist = $('#layerlist tbody').empty();
var selLayerNames = $('#selLayerNames').empty();
var drawing = svgCanvas.getCurrentDrawing();
var currentLayerName = drawing.getCurrentLayerName();
var layer = svgCanvas.getCurrentDrawing().getNumLayers();
var icon = $.getSvgIcon('eye');
// we get the layers in the reverse z-order (the layer rendered on top is listed first)
while (layer--) {
var name = drawing.getLayerName(layer);
var layerTr = $('<tr class="layer">').toggleClass('layersel', name === currentLayerName);
var layerVis = $('<td class="layervis">').toggleClass('layerinvis', !drawing.getLayerVisibility(name));
var layerName = $('<td class="layername">' + name + '</td>');
layerlist.append(layerTr.append(layerVis, layerName));
selLayerNames.append('<option value="' + name + '">' + name + '</option>');
}
if (icon !== undefined) {
var copy = icon.clone();
$('td.layervis', layerlist).append(copy);
$.resizeSvgIcons({'td.layervis .svg_icon': 14});
}
// handle selection of layer
$('#layerlist td.layername')
.mouseup(function(evt) {
$('#layerlist tr.layer').removeClass('layersel');
$(this.parentNode).addClass('layersel');
svgCanvas.setCurrentLayer(this.textContent);
evt.preventDefault();
})
.mouseover(function() {
toggleHighlightLayer(this.textContent);
})
.mouseout(function() {
toggleHighlightLayer();
});
$('#layerlist td.layervis').click(function() {
var row = $(this.parentNode).prevAll().length;
var name = $('#layerlist tr.layer:eq(' + row + ') td.layername').text();
var vis = $(this).hasClass('layerinvis');
svgCanvas.setLayerVisibility(name, vis);
$(this).toggleClass('layerinvis');
});
// if there were too few rows, let's add a few to make it not so lonely
var num = 5 - $('#layerlist tr.layer').size();
while (num-- > 0) {
// FIXME: there must a better way to do this
layerlist.append('<tr><td style="color:white">_</td><td/></tr>');
}
};
var showSourceEditor = function(e, forSaving) {
if (editingsource) {return;}
editingsource = true;
origSource = svgCanvas.getSvgString();
$('#save_output_btns').toggle(!!forSaving);
$('#tool_source_back').toggle(!forSaving);
$('#svg_source_textarea').val(origSource);
$('#svg_source_editor').fadeIn();
$('#svg_source_textarea').focus();
};
var togglePathEditMode = function(editmode, elems) {
$('#path_node_panel').toggle(editmode);
$('#tools_bottom_2,#tools_bottom_3').toggle(!editmode);
if (editmode) {
// Change select icon
$('.tool_button_current').removeClass('tool_button_current').addClass('tool_button');
$('#tool_select').addClass('tool_button_current').removeClass('tool_button');
setIcon('#tool_select', 'select_node');
multiselected = false;
if (elems.length) {
selectedElement = elems[0];
}
} else {
setTimeout(function () {
setIcon('#tool_select', 'select');
}, 1000);
}
};
var saveHandler = function(wind, svg) {
editor.showSaveWarning = false;
// by default, we add the XML prolog back, systems integrating SVG-edit (wikis, CMSs)
// can just provide their own custom save handler and might not want the XML prolog
svg = '<?xml version="1.0"?>\n' + svg;
// IE9 doesn't allow standalone Data URLs
// https://connect.microsoft.com/IE/feedback/details/542600/data-uri-images-fail-when-loaded-by-themselves
if (svgedit.browser.isIE()) {
showSourceEditor(0, true);
return;
}
// Opens the SVG in new window
var win = wind.open('data:image/svg+xml;base64,' + Utils.encode64(svg));
// Alert will only appear the first time saved OR the first time the bug is encountered
var done = $.pref('save_notice_done');
if (done !== 'all') {
var note = uiStrings.notification.saveFromBrowser.replace('%s', 'SVG');
// Check if FF and has <defs/>
if (svgedit.browser.isGecko()) {
if (svg.indexOf('<defs') !== -1) {
// warning about Mozilla bug #308590 when applicable (seems to be fixed now in Feb 2013)
note += '\n\n' + uiStrings.notification.defsFailOnSave;
$.pref('save_notice_done', 'all');
done = 'all';
} else {
$.pref('save_notice_done', 'part');
}
} else {
$.pref('save_notice_done', 'all');
}
if (done !== 'part') {
win.alert(note);
}
}
};
var exportHandler = function(win, data) {
var issues = data.issues,
exportWindowName = data.exportWindowName;
if (exportWindowName) {
exportWindow = window.open('', exportWindowName); // A hack to get the window via JSON-able name without opening a new one
}
exportWindow.location.href = data.datauri;
var done = $.pref('export_notice_done');
if (done !== 'all') {
var note = uiStrings.notification.saveFromBrowser.replace('%s', data.type);
// Check if there's issues
if (issues.length) {
var pre = '\n \u2022 ';
note += ('\n\n' + uiStrings.notification.noteTheseIssues + pre + issues.join(pre));
}
// Note that this will also prevent the notice even though new issues may appear later.
// May want to find a way to deal with that without annoying the user
$.pref('export_notice_done', 'all');
exportWindow.alert(note);
}
};
var operaRepaint = function() {
// Repaints canvas in Opera. Needed for stroke-dasharray change as well as fill change
if (!window.opera) {
return;
}
$('<p/>').hide().appendTo('body').remove();
};
function setStrokeOpt(opt, changeElem) {
var id = opt.id;
var bits = id.split('_');
var pre = bits[0];
var val = bits[1];
if (changeElem) {
svgCanvas.setStrokeAttr('stroke-' + pre, val);
}
operaRepaint();
setIcon('#cur_' + pre, id, 20);
$(opt).addClass('current').siblings().removeClass('current');
}
// This is a common function used when a tool has been clicked (chosen)
// It does several common things:
// - removes the tool_button_current class from whatever tool currently has it
// - hides any flyouts
// - adds the tool_button_current class to the button passed in
var toolButtonClick = editor.toolButtonClick = function(button, noHiding) {
if ($(button).hasClass('disabled')) {return false;}
if ($(button).parent().hasClass('tools_flyout')) {return true;}
var fadeFlyouts = 'normal';
if (!noHiding) {
$('.tools_flyout').fadeOut(fadeFlyouts);
}
$('#styleoverrides').text('');
workarea.css('cursor', 'auto');
$('.tool_button_current').removeClass('tool_button_current').addClass('tool_button');
$(button).addClass('tool_button_current').removeClass('tool_button');
return true;
};
var clickSelect = editor.clickSelect = function() {
if (toolButtonClick('#tool_select')) {
svgCanvas.setMode('select');
$('#styleoverrides').text('#svgcanvas svg *{cursor:move;pointer-events:all}, #svgcanvas svg{cursor:default}');
}
};
var setImageURL = editor.setImageURL = function(url) {
if (!url) {
url = defaultImageURL;
}
svgCanvas.setImageURL(url);
$('#image_url').val(url);
if (url.indexOf('data:') === 0) {
// data URI found
$('#image_url').hide();
$('#change_image_url').show();
} else {
// regular URL
svgCanvas.embedImage(url, function(dataURI) {
// Couldn't embed, so show warning
$('#url_notice').toggle(!dataURI);
defaultImageURL = url;
});
$('#image_url').show();
$('#change_image_url').hide();
}
};
function setBackground (color, url) {
// if (color == $.pref('bkgd_color') && url == $.pref('bkgd_url')) {return;}
$.pref('bkgd_color', color);
$.pref('bkgd_url', url);
// This should be done in svgcanvas.js for the borderRect fill
svgCanvas.setBackground(color, url);
}
function promptImgURL() {
var curhref = svgCanvas.getHref(selectedElement);
curhref = curhref.indexOf('data:') === 0 ? '' : curhref;
$.prompt(uiStrings.notification.enterNewImgURL, curhref, function(url) {
if (url) {setImageURL(url);}
});
}
var setInputWidth = function(elem) {
var w = Math.min(Math.max(12 + elem.value.length * 6, 50), 300);
$(elem).width(w);
};
function updateRulers(scanvas, zoom) {
if (!zoom) {zoom = svgCanvas.getZoom();}
if (!scanvas) {scanvas = $('#svgcanvas');}
var d, i;
var limit = 30000;
var contentElem = svgCanvas.getContentElem();
var units = svgedit.units.getTypeMap();
var unit = units[curConfig.baseUnit]; // 1 = 1px
// draw x ruler then y ruler
for (d = 0; d < 2; d++) {
var isX = (d === 0);
var dim = isX ? 'x' : 'y';
var lentype = isX ? 'width' : 'height';
var contentDim = Number(contentElem.getAttribute(dim));
var $hcanv_orig = $('#ruler_' + dim + ' canvas:first');
// Bit of a hack to fully clear the canvas in Safari & IE9
var $hcanv = $hcanv_orig.clone();
$hcanv_orig.replaceWith($hcanv);
var hcanv = $hcanv[0];
// Set the canvas size to the width of the container
var ruler_len = scanvas[lentype]();
var total_len = ruler_len;
hcanv.parentNode.style[lentype] = total_len + 'px';
var ctx_num = 0;
var ctx = hcanv.getContext('2d');
var ctx_arr, num, ctx_arr_num;
ctx.fillStyle = 'rgb(200,0,0)';
ctx.fillRect(0, 0, hcanv.width, hcanv.height);
// Remove any existing canvasses
$hcanv.siblings().remove();
// Create multiple canvases when necessary (due to browser limits)
if (ruler_len >= limit) {
ctx_arr_num = parseInt(ruler_len / limit, 10) + 1;
ctx_arr = [];
ctx_arr[0] = ctx;
var copy;
for (i = 1; i < ctx_arr_num; i++) {
hcanv[lentype] = limit;
copy = hcanv.cloneNode(true);
hcanv.parentNode.appendChild(copy);
ctx_arr[i] = copy.getContext('2d');
}
copy[lentype] = ruler_len % limit;
// set copy width to last
ruler_len = limit;
}
hcanv[lentype] = ruler_len;
var u_multi = unit * zoom;
// Calculate the main number interval
var raw_m = 50 / u_multi;
var multi = 1;
for (i = 0; i < r_intervals.length; i++) {
num = r_intervals[i];
multi = num;
if (raw_m <= num) {
break;
}
}
var big_int = multi * u_multi;
ctx.font = '9px sans-serif';
var ruler_d = ((contentDim / u_multi) % multi) * u_multi;
var label_pos = ruler_d - big_int;
// draw big intervals
while (ruler_d < total_len) {
label_pos += big_int;
// var real_d = ruler_d - contentDim; // Currently unused
var cur_d = Math.round(ruler_d) + 0.5;
if (isX) {
ctx.moveTo(cur_d, 15);
ctx.lineTo(cur_d, 0);
}
else {
ctx.moveTo(15, cur_d);
ctx.lineTo(0, cur_d);
}
num = (label_pos - contentDim) / u_multi;
var label;
if (multi >= 1) {
label = Math.round(num);
}
else {
var decs = String(multi).split('.')[1].length;
label = num.toFixed(decs);
}
// Change 1000s to Ks
if (label !== 0 && label !== 1000 && label % 1000 === 0) {
label = (label / 1000) + 'K';
}
if (isX) {
ctx.fillText(label, ruler_d+2, 8);
} else {
// draw label vertically
var str = String(label).split('');
for (i = 0; i < str.length; i++) {
ctx.fillText(str[i], 1, (ruler_d+9) + i*9);
}
}
var part = big_int / 10;
// draw the small intervals
for (i = 1; i < 10; i++) {
var sub_d = Math.round(ruler_d + part * i) + 0.5;
if (ctx_arr && sub_d > ruler_len) {
ctx_num++;
ctx.stroke();
if (ctx_num >= ctx_arr_num) {
i = 10;
ruler_d = total_len;
continue;
}
ctx = ctx_arr[ctx_num];
ruler_d -= limit;
sub_d = Math.round(ruler_d + part * i) + 0.5;
}
// odd lines are slighly longer
var line_num = (i % 2) ? 12 : 10;
if (isX) {
ctx.moveTo(sub_d, 15);
ctx.lineTo(sub_d, line_num);
} else {
ctx.moveTo(15, sub_d);
ctx.lineTo(line_num, sub_d);
}
}
ruler_d += big_int;
}
ctx.strokeStyle = '#000';
ctx.stroke();
}
}
var updateCanvas = editor.updateCanvas = function(center, new_ctr) {
//ROGERMOD - This whole method is useless in our case,
//we are not zooming or manipulating the drawing canvas
//directly, only through the OpenSeaDragon overlay!
/*var w = workarea.width(), h = workarea.height();
var w_orig = w, h_orig = h;
var zoom = svgCanvas.getZoom();
var w_area = workarea;
var cnvs = $('#svgcanvas');
var old_ctr = {
x: w_area[0].scrollLeft + w_orig/2,
y: w_area[0].scrollTop + h_orig/2
};
var multi = curConfig.canvas_expansion;*/
//ROGERMOD - We're not zooming the SVG directly anymore!
//w = Math.max(w_orig, svgCanvas.contentW * zoom * multi);
//h = Math.max(h_orig, svgCanvas.contentH * zoom * multi);
/*if (w == w_orig && h == h_orig) {
workarea.css('overflow', 'hidden');
} else {
workarea.css('overflow', 'scroll');
}*/
/*var old_can_y = cnvs.height()/2;
var old_can_x = cnvs.width()/2;
cnvs.width(w).height(h);
var new_can_y = h/2;
var new_can_x = w/2;*/
//ROGERMOD - Size Canvas to 100%
var offset = svgCanvas.updateCanvas('100%', '100%');
//var offset = svgCanvas.updateCanvas(w, h);
/*var ratio = new_can_x / old_can_x;
var scroll_x = w/2 - w_orig/2;
var scroll_y = h/2 - h_orig/2;*/
/*if (!new_ctr) {
var old_dist_x = old_ctr.x - old_can_x;
var new_x = new_can_x + old_dist_x * ratio;
var old_dist_y = old_ctr.y - old_can_y;
var new_y = new_can_y + old_dist_y * ratio;
new_ctr = {
x: new_x,
y: new_y
};
} else {
new_ctr.x += offset.x;
new_ctr.y += offset.y;
}*/
/*if (center) {
// Go to top-left for larger documents
if (svgCanvas.contentW > w_area.width()) {
// Top-left
workarea[0].scrollLeft = offset.x - 10;
workarea[0].scrollTop = offset.y - 10;
} else {
// Center
w_area[0].scrollLeft = scroll_x;
w_area[0].scrollTop = scroll_y;
}
} else {
w_area[0].scrollLeft = new_ctr.x - w_orig/2;
w_area[0].scrollTop = new_ctr.y - h_orig/2;
}*/
/*if (curConfig.showRulers) {
updateRulers(cnvs, zoom);
workarea.scroll();
}*/
//ROGERMOD - Removed storage prompt
/*if (urldata.storagePrompt !== true && !editor.storagePromptClosed) {
$('#dialog_box').hide();
}*/
};
var updateToolButtonState = function() {
var index, button;
var bNoFill = (svgCanvas.getColor('fill') == 'none');
var bNoStroke = (svgCanvas.getColor('stroke') == 'none');
var buttonsNeedingStroke = [ '#tool_fhpath', '#tool_line' ];
var buttonsNeedingFillAndStroke = [ '#tools_rect .tool_button', '#tools_ellipse .tool_button', '#tool_text', '#tool_path'];
if (bNoStroke) {
for (index in buttonsNeedingStroke) {
button = buttonsNeedingStroke[index];
if ($(button).hasClass('tool_button_current')) {
clickSelect();
}
$(button).addClass('disabled');
}
} else {
for (index in buttonsNeedingStroke) {
button = buttonsNeedingStroke[index];
$(button).removeClass('disabled');
}
}
if (bNoStroke && bNoFill) {
for (index in buttonsNeedingFillAndStroke) {
button = buttonsNeedingFillAndStroke[index];
if ($(button).hasClass('tool_button_current')) {
clickSelect();
}
$(button).addClass('disabled');
}
} else {
for (index in buttonsNeedingFillAndStroke) {
button = buttonsNeedingFillAndStroke[index];
$(button).removeClass('disabled');
}
}
svgCanvas.runExtensions('toolButtonStateUpdate', {
nofill: bNoFill,
nostroke: bNoStroke
});
// Disable flyouts if all inside are disabled
$('.tools_flyout').each(function() {
var shower = $('#' + this.id + '_show');
var has_enabled = false;
$(this).children().each(function() {
if (!$(this).hasClass('disabled')) {
has_enabled = true;
}
});
shower.toggleClass('disabled', !has_enabled);
});
operaRepaint();
};
// Updates the toolbar (colors, opacity, etc) based on the selected element
// This function also updates the opacity and id elements that are in the context panel
var updateToolbar = function() {
var i, len;
if (selectedElement != null) {
switch (selectedElement.tagName) {
case 'use':
case 'image':
case 'foreignObject':
break;
case 'g':
case 'a':
// Look for common styles
var gWidth = null;
var childs = selectedElement.getElementsByTagName('*');
for (i = 0, len = childs.length; i < len; i++) {
var swidth = childs[i].getAttribute('stroke-width');
if (i === 0) {
gWidth = swidth;
} else if (gWidth !== swidth) {
gWidth = null;
}
}
$('#stroke_width').val(gWidth === null ? '' : gWidth);
paintBox.fill.update(true);
paintBox.stroke.update(true);
break;
default:
//ROGERMOD - Updated Color Picker
$('select[name="colorpicker"]').simplecolorpicker('selectColor', colourNameToHex(selectedElement.getAttribute("stroke")));
//paintBox.fill.update(true);
//paintBox.stroke.update(true);
/*//$('#stroke_width').val(selectedElement.getAttribute('stroke-width') || 1);
$('#stroke_style').val(selectedElement.getAttribute('stroke-dasharray') || 'none');
var attr = selectedElement.getAttribute('stroke-linejoin') || 'miter';
if ($('#linejoin_' + attr).length != 0) {
setStrokeOpt($('#linejoin_' + attr)[0]);
}
attr = selectedElement.getAttribute('stroke-linecap') || 'butt';
if ($('#linecap_' + attr).length != 0) {
setStrokeOpt($('#linecap_' + attr)[0]);
}*/
}
}
// All elements including image and group have opacity
/*if (selectedElement != null) {
var opac_perc = ((selectedElement.getAttribute('opacity')||1.0)*100);
$('#group_opacity').val(opac_perc);
$('#opac_slider').slider('option', 'value', opac_perc);
$('#elem_id').val(selectedElement.id);
}*/
updateToolButtonState();
};
// updates the context panel tools based on the selected element
var updateContextPanel = function() {
var elem = selectedElement;
// If element has just been deleted, consider it null
if (elem != null && !elem.parentNode) {elem = null;}
var currentLayerName = svgCanvas.getCurrentDrawing().getCurrentLayerName();
var currentMode = svgCanvas.getMode();
var unit = curConfig.baseUnit !== 'px' ? curConfig.baseUnit : null;
var is_node = currentMode == 'pathedit'; //elem ? (elem.id && elem.id.indexOf('pathpointgrip') == 0) : false;
var menu_items = $('#cmenu_canvas li');
$('#selected_panel, #multiselected_panel, #g_panel, #rect_panel, #circle_panel,'+
'#ellipse_panel, #line_panel, #text_panel, #image_panel, #container_panel,'+
' #use_panel, #a_panel').hide();
if (elem != null) {
var elname = elem.nodeName;
// If this is a link with no transform and one child, pretend
// its child is selected
// if (elname === 'a') { // && !$(elem).attr('transform')) {
// elem = elem.firstChild;
// }
var angle = svgCanvas.getRotationAngle(elem);
$('#angle').val(angle);
/*
var blurval = svgCanvas.getBlur(elem);
$('#blur').val(blurval);
$('#blur_slider').slider('option', 'value', blurval);
*/
if (svgCanvas.addedNew) {
if (elname === 'image') {
// Prompt for URL if not a data URL
if (svgCanvas.getHref(elem).indexOf('data:') !== 0) {
promptImgURL();
}
} /*else if (elname == 'text') {
// TODO: Do something here for new text
}*/
}
if (!is_node && currentMode != 'pathedit') {
$('#selected_panel').show();
// Elements in this array already have coord fields
if (['line', 'circle', 'ellipse'].indexOf(elname) >= 0) {
$('#xy_panel').hide();
} else {
var x, y;
// Get BBox vals for g, polyline and path
if (['g', 'polyline', 'path'].indexOf(elname) >= 0) {
var bb = svgCanvas.getStrokedBBox([elem]);
if (bb) {
x = bb.x;
y = bb.y;
}
} else {
x = elem.getAttribute('x');
y = elem.getAttribute('y');
}
if (unit) {
x = svgedit.units.convertUnit(x);
y = svgedit.units.convertUnit(y);
}
$('#selected_x').val(x || 0);
$('#selected_y').val(y || 0);
$('#xy_panel').show();
}
// Elements in this array cannot be converted to a path
var no_path = ['image', 'text', 'path', 'g', 'use'].indexOf(elname) == -1;
$('#tool_topath').toggle(no_path);
$('#tool_reorient').toggle(elname === 'path');
$('#tool_reorient').toggleClass('disabled', angle === 0);
} else {
var point = path.getNodePoint();
$('#tool_add_subpath').removeClass('push_button_pressed').addClass('tool_button');
$('#tool_node_delete').toggleClass('disabled', !path.canDeleteNodes);
// Show open/close button based on selected point
setIcon('#tool_openclose_path', path.closed_subpath ? 'open_path' : 'close_path');
if (point) {
var seg_type = $('#seg_type');
if (unit) {
point.x = svgedit.units.convertUnit(point.x);
point.y = svgedit.units.convertUnit(point.y);
}
$('#path_node_x').val(point.x);
$('#path_node_y').val(point.y);
if (point.type) {
seg_type.val(point.type).removeAttr('disabled');
} else {
seg_type.val(4).attr('disabled', 'disabled');
}
}
return;
}
// update contextual tools here
var panels = {
g: [],
a: [],
rect: ['rx', 'width', 'height'],
image: ['width', 'height'],
circle: ['cx', 'cy', 'r'],
ellipse: ['cx', 'cy', 'rx', 'ry'],
line: ['x1', 'y1', 'x2', 'y2'],
text: [],
use: []
};
var el_name = elem.tagName;
// if ($(elem).data('gsvg')) {
// $('#g_panel').show();
// }
var link_href = null;
if (el_name === 'a') {
link_href = svgCanvas.getHref(elem);
$('#g_panel').show();
}
if (elem.parentNode.tagName === 'a') {
if (!$(elem).siblings().length) {
$('#a_panel').show();
link_href = svgCanvas.getHref(elem.parentNode);
}
}
// Hide/show the make_link buttons
$('#tool_make_link, #tool_make_link').toggle(!link_href);
if (link_href) {
$('#link_url').val(link_href);
}
if (panels[el_name]) {
var cur_panel = panels[el_name];
$('#' + el_name + '_panel').show();
$.each(cur_panel, function(i, item) {
var attrVal = elem.getAttribute(item);
if (curConfig.baseUnit !== 'px' && elem[item]) {
var bv = elem[item].baseVal.value;
attrVal = svgedit.units.convertUnit(bv);
}
$('#' + el_name + '_' + item).val(attrVal || 0);
});
if (el_name == 'text') {
$('#text_panel').css('display', 'inline');
if (svgCanvas.getItalic()) {
$('#tool_italic').addClass('push_button_pressed').removeClass('tool_button');
} else {
$('#tool_italic').removeClass('push_button_pressed').addClass('tool_button');
}
if (svgCanvas.getBold()) {
$('#tool_bold').addClass('push_button_pressed').removeClass('tool_button');
} else {
$('#tool_bold').removeClass('push_button_pressed').addClass('tool_button');
}
$('#font_family').val(elem.getAttribute('font-family'));
$('#font_size').val(elem.getAttribute('font-size'));
$('#text').val(elem.textContent);
if (svgCanvas.addedNew) {
// Timeout needed for IE9
setTimeout(function() {
$('#text').focus().select();
}, 100);
}
} // text
else if (el_name == 'image') {
setImageURL(svgCanvas.getHref(elem));
} // image
else if (el_name === 'g' || el_name === 'use') {
$('#container_panel').show();
var title = svgCanvas.getTitle();
var label = $('#g_title')[0];
label.value = title;
setInputWidth(label);
$('#g_title').prop('disabled', el_name == 'use');
}
}
menu_items[(el_name === 'g' ? 'en' : 'dis') + 'ableContextMenuItems']('#ungroup');
menu_items[((el_name === 'g' || !multiselected) ? 'dis' : 'en') + 'ableContextMenuItems']('#group');
} // if (elem != null)
else if (multiselected) {
$('#multiselected_panel').show();
menu_items
.enableContextMenuItems('#group')
.disableContextMenuItems('#ungroup');
} else {
menu_items.disableContextMenuItems('#delete,#cut,#copy,#group,#ungroup,#move_front,#move_up,#move_down,#move_back');
}
// update history buttons
$('#tool_undo').toggleClass('disabled', undoMgr.getUndoStackSize() === 0);
$('#tool_redo').toggleClass('disabled', undoMgr.getRedoStackSize() === 0);
svgCanvas.addedNew = false;
if ( (elem && !is_node) || multiselected) {
// update the selected elements' layer
$('#selLayerNames').removeAttr('disabled').val(currentLayerName);
// Enable regular menu options
canv_menu.enableContextMenuItems('#delete,#cut,#copy,#move_front,#move_up,#move_down,#move_back');
} else {
$('#selLayerNames').attr('disabled', 'disabled');
}
};
var updateWireFrame = function() {
// Test support
if (supportsNonSS) {return;}
var rule = '#workarea.wireframe #svgcontent * { stroke-width: ' + 1/svgCanvas.getZoom() + 'px; }';
$('#wireframe_rules').text(workarea.hasClass('wireframe') ? rule : '');
};
var updateTitle = function(title) {
title = title || svgCanvas.getDocumentTitle();
var newTitle = origTitle + (title ? ': ' + title : '');
// Remove title update with current context info, isn't really necessary
// if (cur_context) {
// new_title = new_title + cur_context;
// }
$('title:first').text(newTitle);
};
// called when we've selected a different element
var selectedChanged = function(win, elems) {
var mode = svgCanvas.getMode();
if (mode === 'select') {
setSelectMode();
}
var is_node = (mode == "pathedit");
// if elems[1] is present, then we have more than one element
selectedElement = (elems.length === 1 || elems[1] == null ? elems[0] : null);
multiselected = (elems.length >= 2 && elems[1] != null);
if (selectedElement != null) {
// unless we're already in always set the mode of the editor to select because
// upon creation of a text element the editor is switched into
// select mode and this event fires - we need our UI to be in sync
if (!is_node) {
updateToolbar();
}
} // if (elem != null)
// Deal with pathedit mode
togglePathEditMode(is_node, elems);
updateContextPanel();
svgCanvas.runExtensions('selectedChanged', {
elems: elems,
selectedElement: selectedElement,
multiselected: multiselected
});
};
// Call when part of element is in process of changing, generally
// on mousemove actions like rotate, move, etc.
var elementTransition = function(win, elems) {
var mode = svgCanvas.getMode();
var elem = elems[0];
if (!elem) {
return;
}
multiselected = (elems.length >= 2 && elems[1] != null);
// Only updating fields for single elements for now
if (!multiselected) {
switch (mode) {
case 'rotate':
var ang = svgCanvas.getRotationAngle(elem);
$('#angle').val(ang);
$('#tool_reorient').toggleClass('disabled', ang === 0);
break;
// TODO: Update values that change on move/resize, etc
// case "select":
// case "resize":
// break;
}
}
svgCanvas.runExtensions('elementTransition', {
elems: elems
});
};
// called when any element has changed
var elementChanged = function(win, elems) {
var i,
mode = svgCanvas.getMode();
if (mode === 'select') {
setSelectMode();
}
for (i = 0; i < elems.length; ++i) {
var elem = elems[i];
// if the element changed was the svg, then it could be a resolution change
if (elem && elem.tagName === 'svg') {
populateLayers();
updateCanvas();
}
// Update selectedElement if element is no longer part of the image.
// This occurs for the text elements in Firefox
else if (elem && selectedElement && selectedElement.parentNode == null) {
// || elem && elem.tagName == "path" && !multiselected) { // This was added in r1430, but not sure why
selectedElement = elem;
}
}
editor.showSaveWarning = true;
// we update the contextual panel with potentially new
// positional/sizing information (we DON'T want to update the
// toolbar here as that creates an infinite loop)
// also this updates the history buttons
// we tell it to skip focusing the text control if the
// text element was previously in focus
updateContextPanel();
// In the event a gradient was flipped:
/*if (selectedElement && mode === 'select') {
paintBox.fill.update();
paintBox.stroke.update();
}*/
svgCanvas.runExtensions('elementChanged', {
elems: elems
});
};
var zoomDone = function() {
updateWireFrame();
// updateCanvas(); // necessary?
};
var zoomChanged = svgCanvas.zoomChanged = function(win, bbox, autoCenter) {
var scrbar = 15,
// res = svgCanvas.getResolution(), // Currently unused
w_area = workarea;
// var canvas_pos = $('#svgcanvas').position(); // Currently unused
var z_info = svgCanvas.setBBoxZoom(bbox, w_area.width()-scrbar, w_area.height()-scrbar);
if (!z_info) {return;}
var zoomlevel = z_info.zoom,
bb = z_info.bbox;
if (zoomlevel < 0.001) {
changeZoom({value: 0.1});
return;
}
$('#zoom').val((zoomlevel*100).toFixed(1));
if (autoCenter) {
updateCanvas();
} else {
updateCanvas(false, {x: bb.x * zoomlevel + (bb.width * zoomlevel)/2, y: bb.y * zoomlevel + (bb.height * zoomlevel)/2});
}
if (svgCanvas.getMode() == 'zoom' && bb.width) {
// Go to select if a zoom box was drawn
setSelectMode();
}
//zoomDone();
};
changeZoom = function(ctl) {
var zoomlevel = ctl.value / 100;
if (zoomlevel < 0.001) {
ctl.value = 0.1;
return;
}
var zoom = svgCanvas.getZoom();
var w_area = workarea;
zoomChanged(window, {
width: 0,
height: 0,
// center pt of scroll position
x: (w_area[0].scrollLeft + w_area.width()/2)/zoom,
y: (w_area[0].scrollTop + w_area.height()/2)/zoom,
zoom: zoomlevel
}, true);
};
$('#cur_context_panel').delegate('a', 'click', function() {
var link = $(this);
if (link.attr('data-root')) {
svgCanvas.leaveContext();
} else {
svgCanvas.setContext(link.text());
}
svgCanvas.clearSelection();
return false;
});
var contextChanged = function(win, context) {
var link_str = '';
if (context) {
var str = '';
link_str = '<a href="#" data-root="y">' + svgCanvas.getCurrentDrawing().getCurrentLayerName() + '</a>';
$(context).parentsUntil('#svgcontent > g').andSelf().each(function() {
if (this.id) {
str += ' > ' + this.id;
if (this !== context) {
link_str += ' > <a href="#">' + this.id + '</a>';
} else {
link_str += ' > ' + this.id;
}
}
});
cur_context = str;
} else {
cur_context = null;
}
$('#cur_context_panel').toggle(!!context).html(link_str);
updateTitle();
};
// Makes sure the current selected paint is available to work with
var prepPaints = function() {
paintBox.fill.prep();
paintBox.stroke.prep();
};
var flyout_funcs = {};
var setFlyoutTitles = function() {
$('.tools_flyout').each(function() {
var shower = $('#' + this.id + '_show');
if (shower.data('isLibrary')) {
return;
}
var tooltips = [];
$(this).children().each(function() {
tooltips.push(this.title);
});
shower[0].title = tooltips.join(' / ');
});
};
var setFlyoutPositions = function() {
$('.tools_flyout').each(function() {
var shower = $('#' + this.id + '_show');
var pos = shower.offset();
var w = shower.outerWidth();
$(this).css({left: (pos.left + w) * editor.tool_scale, top: pos.top});
});
};
var setupFlyouts = function(holders) {
$.each(holders, function(hold_sel, btn_opts) {
var buttons = $(hold_sel).children();
var show_sel = hold_sel + '_show';
var shower = $(show_sel);
var def = false;
buttons.addClass('tool_button')
.unbind('click mousedown mouseup') // may not be necessary
.each(function(i) {
// Get this buttons options
var opts = btn_opts[i];
// Remember the function that goes with this ID
flyout_funcs[opts.sel] = opts.fn;
if (opts.isDefault) {def = i;}
// Clicking the icon in flyout should set this set's icon
var func = function(event) {
var options = opts;
//find the currently selected tool if comes from keystroke
if (event.type === 'keydown') {
var flyoutIsSelected = $(options.parent + '_show').hasClass('tool_button_current');
var currentOperation = $(options.parent + '_show').attr('data-curopt');
$.each(holders[opts.parent], function(i, tool) {
if (tool.sel == currentOperation) {
if (!event.shiftKey || !flyoutIsSelected) {
options = tool;
} else {
options = holders[opts.parent][i+1] || holders[opts.parent][0];
}
}
});
}
if ($(this).hasClass('disabled')) {return false;}
if (toolButtonClick(show_sel)) {
options.fn();
}
var icon;
if (options.icon) {
icon = $.getSvgIcon(options.icon, true);
} else {
icon = $(options.sel).children().eq(0).clone();
}
icon[0].setAttribute('width', shower.width());
icon[0].setAttribute('height', shower.height());
shower.children(':not(.flyout_arrow_horiz)').remove();
shower.append(icon).attr('data-curopt', options.sel); // This sets the current mode
};
$(this).mouseup(func);
if (opts.key) {
$(document).bind('keydown', opts.key[0] + ' shift+' + opts.key[0], func);
}
});
if (def) {
shower.attr('data-curopt', btn_opts[def].sel);
} else if (!shower.attr('data-curopt')) {
// Set first as default
shower.attr('data-curopt', btn_opts[0].sel);
}
var timer;
var pos = $(show_sel).position();
// Clicking the "show" icon should set the current mode
shower.mousedown(function(evt) {
if (shower.hasClass('disabled')) {
return false;
}
var holder = $(hold_sel);
var l = pos.left + 34;
var w = holder.width() * -1;
var time = holder.data('shown_popop') ? 200 : 0;
timer = setTimeout(function() {
// Show corresponding menu
if (!shower.data('isLibrary')) {
holder.css('left', w).show().animate({
left: l
}, 150);
} else {
holder.css('left', l).show();
}
holder.data('shown_popop', true);
},time);
evt.preventDefault();
}).mouseup(function(evt) {
clearTimeout(timer);
var opt = $(this).attr('data-curopt');
// Is library and popped up, so do nothing
if (shower.data('isLibrary') && $(show_sel.replace('_show', '')).is(':visible')) {
toolButtonClick(show_sel, true);
return;
}
if (toolButtonClick(show_sel) && flyout_funcs[opt]) {
flyout_funcs[opt]();
}
});
// $('#tools_rect').mouseleave(function(){$('#tools_rect').fadeOut();});
});
setFlyoutTitles();
setFlyoutPositions();
};
var makeFlyoutHolder = function(id, child) {
var div = $('<div>', {
'class': 'tools_flyout',
id: id
}).appendTo('#svg_editor').append(child);
return div;
};
var uaPrefix = (function() {
var prop;
var regex = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/;
var someScript = document.getElementsByTagName('script')[0];
for (prop in someScript.style) {
if (regex.test(prop)) {
// test is faster than match, so it's better to perform
// that on the lot and match only when necessary
return prop.match(regex)[0];
}
}
// Nothing found so far?
if ('WebkitOpacity' in someScript.style) {return 'Webkit';}
if ('KhtmlOpacity' in someScript.style) {return 'Khtml';}
return '';
}());
var scaleElements = function(elems, scale) {
// var prefix = '-' + uaPrefix.toLowerCase() + '-'; // Currently unused
var sides = ['top', 'left', 'bottom', 'right'];
elems.each(function() {
// Handled in CSS
// this.style[uaPrefix + 'Transform'] = 'scale(' + scale + ')';
var i;
var el = $(this);
var w = el.outerWidth() * (scale - 1);
var h = el.outerHeight() * (scale - 1);
// var margins = {}; // Currently unused
for (i = 0; i < 4; i++) {
var s = sides[i];
var cur = el.data('orig_margin-' + s);
if (cur == null) {
cur = parseInt(el.css('margin-' + s), 10);
// Cache the original margin
el.data('orig_margin-' + s, cur);
}
var val = cur * scale;
if (s === 'right') {
val += w;
} else if (s === 'bottom') {
val += h;
}
el.css('margin-' + s, val);
// el.css('outline', '1px solid red');
}
});
};
var setIconSize = editor.setIconSize = function (size) {
// var elems = $('.tool_button, .push_button, .tool_button_current, .disabled, .icon_label, #url_notice, #tool_open');
var sel_toscale = '#tools_top .toolset, #editor_panel > *, #history_panel > *,'+
' #main_button, #tools_left > *, #path_node_panel > *, #multiselected_panel > *,'+
' #g_panel > *, #tool_font_size > *, .tools_flyout';
var elems = $(sel_toscale);
var scale = 1;
if (typeof size === 'number') {
scale = size;
} else {
var icon_sizes = {s: 0.75, m:1, l: 1.25, xl: 1.5};
scale = icon_sizes[size];
}
editor.tool_scale = scale;
setFlyoutPositions();
// $('.tools_flyout').each(function() {
// var pos = $(this).position();
// console.log($(this), pos.left+(34 * scale));
// $(this).css({'left': pos.left+(34 * scale), 'top': pos.top+(77 * scale)});
// console.log('l', $(this).css('left'));
// });
// var scale = .75;
var hidden_ps = elems.parents(':hidden');
hidden_ps.css('visibility', 'hidden').show();
scaleElements(elems, scale);
hidden_ps.css('visibility', 'visible').hide();
// return;
$.pref('iconsize', size);
$('#iconsize').val(size);
// Change icon size
// $('.tool_button, .push_button, .tool_button_current, .disabled, .icon_label, #url_notice, #tool_open')
// .find('> svg, > img').each(function() {
// this.setAttribute('width',size_num);
// this.setAttribute('height',size_num);
// });
//
// $.resizeSvgIcons({
// '.flyout_arrow_horiz > svg, .flyout_arrow_horiz > img': size_num / 5,
// '#logo > svg, #logo > img': size_num * 1.3,
// '#tools_bottom .icon_label > *': (size_num === 16 ? 18 : size_num * .75)
// });
// if (size != 's') {
// $.resizeSvgIcons({'#layerbuttons svg, #layerbuttons img': size_num * .6});
// }
// Note that all rules will be prefixed with '#svg_editor' when parsed
var cssResizeRules = {
// '.tool_button,\
// .push_button,\
// .tool_button_current,\
// .push_button_pressed,\
// .disabled,\
// .icon_label,\
// .tools_flyout .tool_button': {
// 'width': {s: '16px', l: '32px', xl: '48px'},
// 'height': {s: '16px', l: '32px', xl: '48px'},
// 'padding': {s: '1px', l: '2px', xl: '3px'}
// },
// '.tool_sep': {
// 'height': {s: '16px', l: '32px', xl: '48px'},
// 'margin': {s: '2px 2px', l: '2px 5px', xl: '2px 8px'}
// },
// '#main_icon': {
// 'width': {s: '31px', l: '53px', xl: '75px'},
// 'height': {s: '22px', l: '42px', xl: '64px'}
// },
'#tools_top': {
'left': 50 + $('#main_button').width(),
'height': 72
},
'#tools_left': {
'width': 31,
'top': 74
},
'div#workarea': {
'left': 38,
'top': 74
}
// '#tools_bottom': {
// 'left': {s: '27px', l: '46px', xl: '65px'},
// 'height': {s: '58px', l: '98px', xl: '145px'}
// },
// '#color_tools': {
// 'border-spacing': {s: '0 1px'},
// 'margin-top': {s: '-1px'}
// },
// '#color_tools .icon_label': {
// 'width': {l:'43px', xl: '60px'}
// },
// '.color_tool': {
// 'height': {s: '20px'}
// },
// '#tool_opacity': {
// 'top': {s: '1px'},
// 'height': {s: 'auto', l:'auto', xl:'auto'}
// },
// '#tools_top input, #tools_bottom input': {
// 'margin-top': {s: '2px', l: '4px', xl: '5px'},
// 'height': {s: 'auto', l: 'auto', xl: 'auto'},
// 'border': {s: '1px solid #555', l: 'auto', xl: 'auto'},
// 'font-size': {s: '.9em', l: '1.2em', xl: '1.4em'}
// },
// '#zoom_panel': {
// 'margin-top': {s: '3px', l: '4px', xl: '5px'}
// },
// '#copyright, #tools_bottom .label': {
// 'font-size': {l: '1.5em', xl: '2em'},
// 'line-height': {s: '15px'}
// },
// '#tools_bottom_2': {
// 'width': {l: '295px', xl: '355px'},
// 'top': {s: '4px'}
// },
// '#tools_top > div, #tools_top': {
// 'line-height': {s: '17px', l: '34px', xl: '50px'}
// },
// '.dropdown button': {
// 'height': {s: '18px', l: '34px', xl: '40px'},
// 'line-height': {s: '18px', l: '34px', xl: '40px'},
// 'margin-top': {s: '3px'}
// },
// '#tools_top label, #tools_bottom label': {
// 'font-size': {s: '1em', l: '1.5em', xl: '2em'},
// 'height': {s: '25px', l: '42px', xl: '64px'}
// },
// 'div.toolset': {
// 'height': {s: '25px', l: '42px', xl: '64px'}
// },
// '#tool_bold, #tool_italic': {
// 'font-size': {s: '1.5em', l: '3em', xl: '4.5em'}
// },
// '#sidepanels': {
// 'top': {s: '50px', l: '88px', xl: '125px'},
// 'bottom': {s: '51px', l: '68px', xl: '65px'}
// },
// '#layerbuttons': {
// 'width': {l: '130px', xl: '175px'},
// 'height': {l: '24px', xl: '30px'}
// },
// '#layerlist': {
// 'width': {l: '128px', xl: '150px'}
// },
// '.layer_button': {
// 'width': {l: '19px', xl: '28px'},
// 'height': {l: '19px', xl: '28px'}
// },
// 'input.spin-button': {
// 'background-image': {l: 'url('images/spinbtn_updn_big.png')', xl: 'url('images/spinbtn_updn_big.png')'},
// 'background-position': {l: '100% -5px', xl: '100% -2px'},
// 'padding-right': {l: '24px', xl: '24px' }
// },
// 'input.spin-button.up': {
// 'background-position': {l: '100% -45px', xl: '100% -42px'}
// },
// 'input.spin-button.down': {
// 'background-position': {l: '100% -85px', xl: '100% -82px'}
// },
// '#position_opts': {
// 'width': {all: (size_num*4) +'px'}
// }
};
var rule_elem = $('#tool_size_rules');
if (!rule_elem.length) {
rule_elem = $('<style id="tool_size_rules"></style>').appendTo('head');
} else {
rule_elem.empty();
}
if (size !== 'm') {
var styleStr = '';
$.each(cssResizeRules, function(selector, rules) {
selector = '#svg_editor ' + selector.replace(/,/g,', #svg_editor');
styleStr += selector + '{';
$.each(rules, function(prop, values) {
var val;
if (typeof values === 'number') {
val = (values * scale) + 'px';
} else if (values[size] || values.all) {
val = (values[size] || values.all);
}
styleStr += (prop + ':' + val + ';');
});
styleStr += '}';
});
//this.style[uaPrefix + 'Transform'] = 'scale(' + scale + ')';
var prefix = '-' + uaPrefix.toLowerCase() + '-';
styleStr += (sel_toscale + '{' + prefix + 'transform: scale(' + scale + ');}'
+ ' #svg_editor div.toolset .toolset {' + prefix + 'transform: scale(1); margin: 1px !important;}' // Hack for markers
+ ' #svg_editor .ui-slider {' + prefix + 'transform: scale(' + (1/scale) + ');}' // Hack for sliders
);
rule_elem.text(styleStr);
}
setFlyoutPositions();
};
// TODO: Combine this with addDropDown or find other way to optimize
var addAltDropDown = function(elem, list, callback, opts) {
var button = $(elem);
list = $(list);
var on_button = false;
var dropUp = opts.dropUp;
if (dropUp) {
$(elem).addClass('dropup');
}
list.find('li').bind('mouseup', function() {
if (opts.seticon) {
setIcon('#cur_' + button[0].id , $(this).children());
$(this).addClass('current').siblings().removeClass('current');
}
callback.apply(this, arguments);
});
$(window).mouseup(function(evt) {
if (!on_button) {
button.removeClass('down');
list.hide();
list.css({top:0, left:0});
}
on_button = false;
});
// var height = list.height(); // Currently unused
button.bind('mousedown',function() {
var off = button.offset();
if (dropUp) {
off.top -= list.height();
off.left += 8;
} else {
off.top += button.height();
}
list.offset(off);
if (!button.hasClass('down')) {
list.show();
on_button = true;
} else {
// CSS position must be reset for Webkit
list.hide();
list.css({top:0, left:0});
}
button.toggleClass('down');
}).hover(function() {
on_button = true;
}).mouseout(function() {
on_button = false;
});
if (opts.multiclick) {
list.mousedown(function() {
on_button = true;
});
}
};
var extsPreLang = [];
var extAdded = function(win, ext) {
if (!ext) {
return;
}
var cb_called = false;
var resize_done = false;
var cb_ready = true; // Set to false to delay callback (e.g. wait for $.svgIcons)
if (ext.langReady) {
if (editor.langChanged) { // We check for this since the "lang" pref could have been set by storage
var lang = $.pref('lang');
ext.langReady({lang:lang, uiStrings:uiStrings});
}
else {
extsPreLang.push(ext);
}
}
function prepResize() {
if (resize_timer) {
clearTimeout(resize_timer);
resize_timer = null;
}
if (!resize_done) {
resize_timer = setTimeout(function() {
resize_done = true;
setIconSize($.pref('iconsize'));
}, 50);
}
}
var runCallback = function() {
if (ext.callback && !cb_called && cb_ready) {
cb_called = true;
ext.callback();
}
};
var btn_selects = [];
if (ext.context_tools) {
$.each(ext.context_tools, function(i, tool) {
// Add select tool
var html;
var cont_id = tool.container_id ? (' id="' + tool.container_id + '"') : '';
var panel = $('#' + tool.panel);
// create the panel if it doesn't exist
if (!panel.length) {
panel = $('<div>', {id: tool.panel}).appendTo('#tools_top');
}
// TODO: Allow support for other types, or adding to existing tool
switch (tool.type) {
case 'tool_button':
html = '<div class="tool_button">' + tool.id + '</div>';
var div = $(html).appendTo(panel);
if (tool.events) {
$.each(tool.events, function(evt, func) {
$(div).bind(evt, func);
});
}
break;
case 'select':
html = '<label' + cont_id + '>'
+ '<select id="' + tool.id + '">';
$.each(tool.options, function(val, text) {
var sel = (val == tool.defval) ? ' selected' : '';
html += '<option value="'+val+'"' + sel + '>' + text + '</option>';
});
html += '</select></label>';
// Creates the tool, hides & adds it, returns the select element
var sel = $(html).appendTo(panel).find('select');
$.each(tool.events, function(evt, func) {
$(sel).bind(evt, func);
});
break;
case 'button-select':
html = '<div id="' + tool.id + '" class="dropdown toolset" title="' + tool.title + '">'
+ '<div id="cur_' + tool.id + '" class="icon_label"></div><button></button></div>';
var list = $('<ul id="' + tool.id + '_opts"></ul>').appendTo('#option_lists');
if (tool.colnum) {
list.addClass('optcols' + tool.colnum);
}
// Creates the tool, hides & adds it, returns the select element
var dropdown = $(html).appendTo(panel).children();
btn_selects.push({
elem: ('#' + tool.id),
list: ('#' + tool.id + '_opts'),
title: tool.title,
callback: tool.events.change,
cur: ('#cur_' + tool.id)
});
break;
case 'input':
html = '<label' + cont_id + '>'
+ '<span id="' + tool.id + '_label">'
+ tool.label + ':</span>'
+ '<input id="' + tool.id + '" title="' + tool.title
+ '" size="' + (tool.size || '4') + '" value="' + (tool.defval || '') + '" type="text"/></label>';
// Creates the tool, hides & adds it, returns the select element
// Add to given tool.panel
var inp = $(html).appendTo(panel).find('input');
if (tool.spindata) {
inp.SpinButton(tool.spindata);
}
if (tool.events) {
$.each(tool.events, function(evt, func) {
inp.bind(evt, func);
});
}
break;
default:
break;
}
});
}
if (ext.buttons) {
var fallback_obj = {},
placement_obj = {},
svgicons = ext.svgicons,
holders = {};
// Add buttons given by extension
$.each(ext.buttons, function(i, btn) {
var icon, svgicon, tls_id;
var id = btn.id;
var num = i;
// Give button a unique ID
while($('#'+id).length) {
id = btn.id + '_' + (++num);
}
if (!svgicons) {
icon = $('<img src="' + btn.icon + '">');
} else {
fallback_obj[id] = btn.icon;
svgicon = btn.svgicon || btn.id;
if (btn.type == 'app_menu') {
placement_obj['#' + id + ' > div'] = svgicon;
} else {
placement_obj['#' + id] = svgicon;
}
}
var cls, parent;
// Set button up according to its type
switch ( btn.type ) {
case 'mode_flyout':
case 'mode':
cls = 'tool_button';
parent = '#tools_left';
break;
case 'context':
cls = 'tool_button';
parent = '#' + btn.panel;
// create the panel if it doesn't exist
if (!$(parent).length) {
$('<div>', {id: btn.panel}).appendTo('#tools_top');
}
break;
case 'app_menu':
cls = '';
parent = '#main_menu ul';
break;
}
var flyout_holder, cur_h, show_btn, ref_data, ref_btn;
var button = $((btn.list || btn.type == 'app_menu') ? '<li/>' : '<div/>')
.attr('id', id)
.attr('title', btn.title)
.addClass(cls);
if (!btn.includeWith && !btn.list) {
if ('position' in btn) {
if ($(parent).children().eq(btn.position).length) {
$(parent).children().eq(btn.position).before(button);
}
else {
$(parent).children().last().before(button);
}
} else {
button.appendTo(parent);
}
if (btn.type =='mode_flyout') {
// Add to flyout menu / make flyout menu
// var opts = btn.includeWith;
// // opts.button, default, position
ref_btn = $(button);
flyout_holder = ref_btn.parent();
// Create a flyout menu if there isn't one already
if (!ref_btn.parent().hasClass('tools_flyout')) {
// Create flyout placeholder
tls_id = ref_btn[0].id.replace('tool_', 'tools_');
show_btn = ref_btn.clone()
.attr('id', tls_id + '_show')
.append($('<div>', {'class': 'flyout_arrow_horiz'}));
ref_btn.before(show_btn);
// Create a flyout div
flyout_holder = makeFlyoutHolder(tls_id, ref_btn);
flyout_holder.data('isLibrary', true);
show_btn.data('isLibrary', true);
}
// ref_data = Actions.getButtonData(opts.button);
placement_obj['#' + tls_id + '_show'] = btn.id;
// TODO: Find way to set the current icon using the iconloader if this is not default
// Include data for extension button as well as ref button
cur_h = holders['#'+flyout_holder[0].id] = [{
sel: '#'+id,
fn: btn.events.click,
icon: btn.id,
// key: btn.key,
isDefault: true
}, ref_data];
//
// // {sel:'#tool_rect', fn: clickRect, evt: 'mouseup', key: 4, parent: '#tools_rect', icon: 'rect'}
//
// var pos = ('position' in opts)?opts.position:'last';
// var len = flyout_holder.children().length;
//
// // Add at given position or end
// if (!isNaN(pos) && pos >= 0 && pos < len) {
// flyout_holder.children().eq(pos).before(button);
// } else {
// flyout_holder.append(button);
// cur_h.reverse();
// }
} else if (btn.type == 'app_menu') {
button.append('<div>').append(btn.title);
}
}
else if (btn.list) {
// Add button to list
button.addClass('push_button');
$('#' + btn.list + '_opts').append(button);
if (btn.isDefault) {
$('#cur_' + btn.list).append(button.children().clone());
svgicon = btn.svgicon || btn.id;
placement_obj['#cur_' + btn.list] = svgicon;
}
}
else if (btn.includeWith) {
// Add to flyout menu / make flyout menu
var opts = btn.includeWith;
// opts.button, default, position
ref_btn = $(opts.button);
flyout_holder = ref_btn.parent();
// Create a flyout menu if there isn't one already
if (!ref_btn.parent().hasClass('tools_flyout')) {
// Create flyout placeholder
tls_id = ref_btn[0].id.replace('tool_', 'tools_');
show_btn = ref_btn.clone()
.attr('id',tls_id + '_show')
.append($('<div>', {'class': 'flyout_arrow_horiz'}));
ref_btn.before(show_btn);
// Create a flyout div
flyout_holder = makeFlyoutHolder(tls_id, ref_btn);
}
ref_data = Actions.getButtonData(opts.button);
if (opts.isDefault) {
placement_obj['#' + tls_id + '_show'] = btn.id;
}
// TODO: Find way to set the current icon using the iconloader if this is not default
// Include data for extension button as well as ref button
cur_h = holders['#' + flyout_holder[0].id] = [{
sel: '#' + id,
fn: btn.events.click,
icon: btn.id,
key: btn.key,
isDefault: btn.includeWith ? btn.includeWith.isDefault : 0
}, ref_data];
// {sel:'#tool_rect', fn: clickRect, evt: 'mouseup', key: 4, parent: '#tools_rect', icon: 'rect'}
var pos = ('position' in opts) ? opts.position : 'last';
var len = flyout_holder.children().length;
// Add at given position or end
if (!isNaN(pos) && pos >= 0 && pos < len) {
flyout_holder.children().eq(pos).before(button);
} else {
flyout_holder.append(button);
cur_h.reverse();
}
}
if (!svgicons) {
button.append(icon);
}
if (!btn.list) {
// Add given events to button
$.each(btn.events, function(name, func) {
if (name == 'click' && btn.type == 'mode') {
if (btn.includeWith) {
button.bind(name, func);
} else {
button.bind(name, function() {
if (toolButtonClick(button)) {
func();
}
});
}
if (btn.key) {
$(document).bind('keydown', btn.key, func);
if (btn.title) {
button.attr('title', btn.title + ' ['+btn.key+']');
}
}
} else {
button.bind(name, func);
}
});
}
setupFlyouts(holders);
});
$.each(btn_selects, function() {
addAltDropDown(this.elem, this.list, this.callback, {seticon: true});
});
if (svgicons) {
cb_ready = false; // Delay callback
}
$.svgIcons(svgicons, {
w: 24, h: 24,
id_match: false,
no_img: (!svgedit.browser.isWebkit()),
fallback: fallback_obj,
placement: placement_obj,
callback: function (icons) {
// Non-ideal hack to make the icon match the current size
//if (curPrefs.iconsize && curPrefs.iconsize !== 'm') {
if ($.pref('iconsize') !== 'm') {
prepResize();
}
cb_ready = true; // Ready for callback
runCallback();
}
});
}
runCallback();
};
var getPaint = function(color, opac, type) {
// update the editor's fill paint
var opts = { alpha: opac };
if (color.indexOf('url(#') === 0) {
var refElem = svgCanvas.getRefElem(color);
if (refElem) {
refElem = refElem.cloneNode(true);
} else {
refElem = $('#' + type + '_color defs *')[0];
}
opts[refElem.tagName] = refElem;
} else if (color.indexOf('#') === 0) {
opts.solidColor = color.substr(1);
} else {
opts.solidColor = 'none';
}
return new $.jGraduate.Paint(opts);
};
$('#text').focus( function(){ textBeingEntered = true; } );
$('#text').blur( function(){ textBeingEntered = false; } );
// bind the selected event to our function that handles updates to the UI
svgCanvas.bind('selected', selectedChanged);
svgCanvas.bind('transition', elementTransition);
svgCanvas.bind('changed', elementChanged);
//ROGERMOD - Disable default save handler
//svgCanvas.bind('saved', saveHandler);
svgCanvas.bind('exported', exportHandler);
svgCanvas.bind('exportedPDF', function (win, data) {
var exportWindowName = data.exportWindowName;
if (exportWindowName) {
exportWindow = window.open('', exportWindowName); // A hack to get the window via JSON-able name without opening a new one
}
exportWindow.location.href = data.dataurlstring;
});
//svgCanvas.bind('zoomed', zoomChanged);
svgCanvas.bind('contextset', contextChanged);
svgCanvas.bind('extension_added', extAdded);
svgCanvas.textActions.setInputElem($('#text')[0]);
var str = '<div class="palette_item" data-rgb="none"></div>';
$.each(palette, function(i, item) {
str += '<div class="palette_item" style="background-color: ' + item + ';" data-rgb="' + item + '"></div>';
});
$('#palette').append(str);
// Set up editor background functionality
// TODO add checkerboard as "pattern"
var color_blocks = ['#FFF', '#888', '#000']; // ,'url(data:image/gif;base64,R0lGODlhEAAQAIAAAP%2F%2F%2F9bW1iH5BAAAAAAALAAAAAAQABAAAAIfjG%2Bgq4jM3IFLJgpswNly%2FXkcBpIiVaInlLJr9FZWAQA7)'];
str = '';
$.each(color_blocks, function() {
str += '<div class="color_block" style="background-color:' + this + ';"></div>';
});
$('#bg_blocks').append(str);
var blocks = $('#bg_blocks div');
var cur_bg = 'cur_background';
blocks.each(function() {
var blk = $(this);
blk.click(function() {
blocks.removeClass(cur_bg);
$(this).addClass(cur_bg);
});
});
setBackground($.pref('bkgd_color'), $.pref('bkgd_url'));
$('#image_save_opts input').val([$.pref('img_save')]);
var changeRectRadius = function(ctl) {
svgCanvas.setRectRadius(ctl.value);
};
var changeFontSize = function(ctl) {
svgCanvas.setFontSize(ctl.value);
};
var changeStrokeWidth = function(ctl) {
var val = ctl.value;
if (val == 0 && selectedElement && ['line', 'polyline'].indexOf(selectedElement.nodeName) >= 0) {
val = ctl.value = 1;
}
svgCanvas.setStrokeWidth(val);
};
var changeRotationAngle = function(ctl) {
svgCanvas.setRotationAngle(ctl.value);
$('#tool_reorient').toggleClass('disabled', parseInt(ctl.value, 10) === 0);
};
var changeOpacity = function(ctl, val) {
if (val == null) {val = ctl.value;}
$('#group_opacity').val(val);
if (!ctl || !ctl.handle) {
$('#opac_slider').slider('option', 'value', val);
}
svgCanvas.setOpacity(val/100);
};
var changeBlur = function(ctl, val, noUndo) {
if (val == null) {val = ctl.value;}
$('#blur').val(val);
var complete = false;
if (!ctl || !ctl.handle) {
$('#blur_slider').slider('option', 'value', val);
complete = true;
}
if (noUndo) {
svgCanvas.setBlurNoUndo(val);
} else {
svgCanvas.setBlur(val, complete);
}
};
$('#stroke_style').change(function() {
svgCanvas.setStrokeAttr('stroke-dasharray', $(this).val());
operaRepaint();
});
$('#stroke_linejoin').change(function() {
svgCanvas.setStrokeAttr('stroke-linejoin', $(this).val());
operaRepaint();
});
// Lose focus for select elements when changed (Allows keyboard shortcuts to work better)
$('select').change(function(){$(this).blur();});
// fired when user wants to move elements to another layer
var promptMoveLayerOnce = false;
$('#selLayerNames').change(function() {
var destLayer = this.options[this.selectedIndex].value;
var confirmStr = uiStrings.notification.QmoveElemsToLayer.replace('%s', destLayer);
var moveToLayer = function(ok) {
if (!ok) {return;}
promptMoveLayerOnce = true;
svgCanvas.moveSelectedToLayer(destLayer);
svgCanvas.clearSelection();
populateLayers();
};
if (destLayer) {
if (promptMoveLayerOnce) {
moveToLayer(true);
} else {
$.confirm(confirmStr, moveToLayer);
}
}
});
$('#font_family').change(function() {
svgCanvas.setFontFamily(this.value);
});
$('#seg_type').change(function() {
svgCanvas.setSegType($(this).val());
});
$('#text').keyup(function() {
svgCanvas.setTextContent(this.value);
});
$('#image_url').change(function() {
setImageURL(this.value);
});
$('#link_url').change(function() {
if (this.value.length) {
svgCanvas.setLinkURL(this.value);
} else {
svgCanvas.removeHyperlink();
}
});
$('#g_title').change(function() {
svgCanvas.setGroupTitle(this.value);
});
$('.attr_changer').change(function() {
var attr = this.getAttribute('data-attr');
var val = this.value;
var valid = svgedit.units.isValidUnit(attr, val, selectedElement);
if (!valid) {
$.alert(uiStrings.notification.invalidAttrValGiven);
this.value = selectedElement.getAttribute(attr);
return false;
}
if (attr !== 'id') {
if (isNaN(val)) {
val = svgCanvas.convertToNum(attr, val);
} else if (curConfig.baseUnit !== 'px') {
// Convert unitless value to one with given unit
var unitData = svgedit.units.getTypeMap();
if (selectedElement[attr] || svgCanvas.getMode() === 'pathedit' || attr === 'x' || attr === 'y') {
val *= unitData[curConfig.baseUnit];
}
}
}
// if the user is changing the id, then de-select the element first
// change the ID, then re-select it with the new ID
if (attr === 'id') {
var elem = selectedElement;
svgCanvas.clearSelection();
elem.id = val;
svgCanvas.addToSelection([elem],true);
} else {
svgCanvas.changeSelectedAttribute(attr, val);
}
this.blur();
});
// Prevent selection of elements when shift-clicking
$('#palette').mouseover(function() {
var inp = $('<input type="hidden">');
$(this).append(inp);
inp.focus().remove();
});
$('.palette_item').mousedown(function(evt) {
// shift key or right click for stroke
var picker = evt.shiftKey || evt.button === 2 ? 'stroke' : 'fill';
var color = $(this).data('rgb');
var paint;
// Webkit-based browsers returned 'initial' here for no stroke
if (color === 'none' || color === 'transparent' || color === 'initial') {
color = 'none';
paint = new $.jGraduate.Paint();
} else {
paint = new $.jGraduate.Paint({alpha: 100, solidColor: color.substr(1)});
}
paintBox[picker].setPaint(paint);
svgCanvas.setColor(picker, color);
if (color !== 'none' && svgCanvas.getPaintOpacity(picker) !== 1) {
svgCanvas.setPaintOpacity(picker, 1.0);
}
updateToolButtonState();
}).bind('contextmenu', function(e) {e.preventDefault();});
$('#toggle_stroke_tools').on('click', function() {
$('#tools_bottom').toggleClass('expanded');
});
(function() {
var last_x = null, last_y = null, w_area = workarea[0],
panning = false, keypan = false;
$('#svgcanvas').bind('mousemove mouseup', function(evt) {
if (panning === false) {return;}
w_area.scrollLeft -= (evt.clientX - last_x);
w_area.scrollTop -= (evt.clientY - last_y);
last_x = evt.clientX;
last_y = evt.clientY;
if (evt.type === 'mouseup') {panning = false;}
return false;
}).mousedown(function(evt) {
if (evt.button === 1 || keypan === true) {
panning = true;
last_x = evt.clientX;
last_y = evt.clientY;
return false;
}
});
$(window).mouseup(function() {
panning = false;
});
/*$(document).bind('keydown', 'space', function(evt) {
svgCanvas.spaceKey = keypan = true;
evt.preventDefault();
}).bind('keyup', 'space', function(evt) {
evt.preventDefault();
svgCanvas.spaceKey = keypan = false;
}).bind('keydown', 'shift', function(evt) {
if (svgCanvas.getMode() === 'zoom') {
workarea.css('cursor', zoomOutIcon);
}
}).bind('keyup', 'shift', function(evt) {
if (svgCanvas.getMode() === 'zoom') {
workarea.css('cursor', zoomInIcon);
}
});*/
editor.setPanning = function(active) {
svgCanvas.spaceKey = keypan = active;
};
}());
(function () {
var button = $('#main_icon');
var overlay = $('#main_icon span');
var list = $('#main_menu');
var on_button = false;
var height = 0;
var js_hover = true;
var set_click = false;
/*
// Currently unused
var hideMenu = function() {
list.fadeOut(200);
};
*/
$(window).mouseup(function(evt) {
if (!on_button) {
button.removeClass('buttondown');
// do not hide if it was the file input as that input needs to be visible
// for its change event to fire
if (evt.target.tagName != 'INPUT') {
list.fadeOut(200);
} else if (!set_click) {
set_click = true;
$(evt.target).click(function() {
list.css('margin-left', '-9999px').show();
});
}
}
on_button = false;
}).mousedown(function(evt) {
// $('.contextMenu').hide();
var islib = $(evt.target).closest('div.tools_flyout, .contextMenu').length;
if (!islib) {$('.tools_flyout:visible,.contextMenu').fadeOut(250);}
});
overlay.bind('mousedown',function() {
if (!button.hasClass('buttondown')) {
// Margin must be reset in case it was changed before;
list.css('margin-left', 0).show();
if (!height) {
height = list.height();
}
// Using custom animation as slideDown has annoying 'bounce effect'
list.css('height',0).animate({
'height': height
}, 200);
on_button = true;
} else {
list.fadeOut(200);
}
button.toggleClass('buttondown buttonup');
}).hover(function() {
on_button = true;
}).mouseout(function() {
on_button = false;
});
var list_items = $('#main_menu li');
// Check if JS method of hovering needs to be used (Webkit bug)
list_items.mouseover(function() {
js_hover = ($(this).css('background-color') == 'rgba(0, 0, 0, 0)');
list_items.unbind('mouseover');
if (js_hover) {
list_items.mouseover(function() {
this.style.backgroundColor = '#FFC';
}).mouseout(function() {
this.style.backgroundColor = 'transparent';
return true;
});
}
});
}());
// Made public for UI customization.
// TODO: Group UI functions into a public editor.ui interface.
editor.addDropDown = function(elem, callback, dropUp) {
if ($(elem).length == 0) {return;} // Quit if called on non-existant element
var button = $(elem).find('button');
var list = $(elem).find('ul').attr('id', $(elem)[0].id + '-list');
var on_button = false;
if (dropUp) {
$(elem).addClass('dropup');
} else {
// Move list to place where it can overflow container
$('#option_lists').append(list);
}
list.find('li').bind('mouseup', callback);
$(window).mouseup(function(evt) {
if (!on_button) {
button.removeClass('down');
list.hide();
}
on_button = false;
});
button.bind('mousedown',function() {
if (!button.hasClass('down')) {
if (!dropUp) {
var pos = $(elem).position();
list.css({
top: pos.top + 24,
left: pos.left - 10
});
}
list.show();
on_button = true;
} else {
list.hide();
}
button.toggleClass('down');
}).hover(function() {
on_button = true;
}).mouseout(function() {
on_button = false;
});
};
editor.addDropDown('#font_family_dropdown', function() {
$('#font_family').val($(this).text()).change();
});
editor.addDropDown('#opacity_dropdown', function() {
if ($(this).find('div').length) {return;}
var perc = parseInt($(this).text().split('%')[0], 10);
changeOpacity(false, perc);
}, true);
// For slider usage, see: http://jqueryui.com/demos/slider/
/*$('#opac_slider').slider({
start: function() {
$('#opacity_dropdown li:not(.special)').hide();
},
stop: function() {
$('#opacity_dropdown li').show();
$(window).mouseup();
},
slide: function(evt, ui) {
changeOpacity(ui);
}
});*/
editor.addDropDown('#blur_dropdown', $.noop);
var slideStart = false;
/*$('#blur_slider').slider({
max: 10,
step: 0.1,
stop: function(evt, ui) {
slideStart = false;
changeBlur(ui);
$('#blur_dropdown li').show();
$(window).mouseup();
},
start: function() {
slideStart = true;
},
slide: function(evt, ui) {
changeBlur(ui, null, slideStart);
}
});*/
/*editor.addDropDown('#zoom_dropdown', function() {
var item = $(this);
var val = item.data('val');
if (val) {
zoomChanged(window, val);
} else {
changeZoom({value: parseFloat(item.text())});
}
}, true);*/
addAltDropDown('#stroke_linecap', '#linecap_opts', function() {
setStrokeOpt(this, true);
}, {dropUp: true});
addAltDropDown('#stroke_linejoin', '#linejoin_opts', function() {
setStrokeOpt(this, true);
}, {dropUp: true});
addAltDropDown('#tool_position', '#position_opts', function() {
var letter = this.id.replace('tool_pos', '').charAt(0);
svgCanvas.alignSelectedElements(letter, 'page');
}, {multiclick: true});
/*
When a flyout icon is selected
(if flyout) {
- Change the icon
- Make pressing the button run its stuff
}
- Run its stuff
When its shortcut key is pressed
- If not current in list, do as above
, else:
- Just run its stuff
*/
// Unfocus text input when workarea is mousedowned.
(function() {
var inp;
var unfocus = function() {
$(inp).blur();
};
$('#svg_editor').find('button, select, input:not(#text)').focus(function() {
inp = this;
ui_context = 'toolbars';
workarea.mousedown(unfocus);
}).blur(function() {
ui_context = 'canvas';
workarea.unbind('mousedown', unfocus);
// Go back to selecting text if in textedit mode
if (svgCanvas.getMode() == 'textedit') {
$('#text').focus();
}
});
}());
var clickFHPath = function() {
if (toolButtonClick('#tool_fhpath')) {
svgCanvas.setMode('fhpath');
}
};
var clickLine = function() {
if (toolButtonClick('#tool_line')) {
svgCanvas.setMode('line');
}
};
var clickSquare = function() {
if (toolButtonClick('#tool_square')) {
svgCanvas.setMode('square');
}
};
var clickRect = function() {
if (toolButtonClick('#tool_rect')) {
svgCanvas.setMode('rect');
}
};
var clickFHRect = function() {
if (toolButtonClick('#tool_fhrect')) {
svgCanvas.setMode('fhrect');
}
};
var clickCircle = function() {
if (toolButtonClick('#tool_circle')) {
svgCanvas.setMode('circle');
}
};
var clickEllipse = function() {
if (toolButtonClick('#tool_ellipse')) {
svgCanvas.setMode('ellipse');
}
};
var clickFHEllipse = function() {
if (toolButtonClick('#tool_fhellipse')) {
svgCanvas.setMode('fhellipse');
}
};
var clickImage = function() {
if (toolButtonClick('#tool_image')) {
svgCanvas.setMode('image');
}
};
var clickZoom = function() {
if (toolButtonClick('#tool_zoom')) {
svgCanvas.setMode('zoom');
workarea.css('cursor', zoomInIcon);
}
};
+ var clickPoint = function() {
+ if (toolButtonClick('#tool_point')) {
+ svgCanvas.setMode('point');
+ }
+ };
+
var zoomImage = function(multiplier) {
var res = svgCanvas.getResolution();
multiplier = multiplier;
//multiplier = multiplier ? res.zoom * multiplier : 1;
// setResolution(res.w * multiplier, res.h * multiplier, true);
//$('#zoom').val(multiplier * 100);
svgCanvas.setZoom(multiplier);
//zoomDone();
//updateCanvas(true);
};
//ROGERMOD - Created this to apply a given transform to the canvas
editor.applyTransform = function(scale, translateX, translateY){
svgCanvas.translateSelector(translateX, translateY);
//svgCanvas.zoomSelector(scale);
zoomImage(scale);
}
var dblclickZoom = function() {
if (toolButtonClick('#tool_zoom')) {
zoomImage();
setSelectMode();
}
};
var clickText = function() {
if (toolButtonClick('#tool_text')) {
svgCanvas.setMode('text');
}
};
var clickPath = function() {
if (toolButtonClick('#tool_path')) {
svgCanvas.setMode('path');
}
};
// Delete is a contextual tool that only appears in the ribbon if
// an element has been selected
var deleteSelected = function() {
if (selectedElement != null || multiselected) {
svgCanvas.deleteSelectedElements();
}
};
var cutSelected = function() {
if (selectedElement != null || multiselected) {
svgCanvas.cutSelectedElements();
}
};
var copySelected = function() {
if (selectedElement != null || multiselected) {
svgCanvas.copySelectedElements();
}
};
var pasteInCenter = function() {
var zoom = svgCanvas.getZoom();
var x = (workarea[0].scrollLeft + workarea.width()/2)/zoom - svgCanvas.contentW;
var y = (workarea[0].scrollTop + workarea.height()/2)/zoom - svgCanvas.contentH;
svgCanvas.pasteElements('point', x, y);
};
var moveToTopSelected = function() {
if (selectedElement != null) {
svgCanvas.moveToTopSelectedElement();
}
};
var moveToBottomSelected = function() {
if (selectedElement != null) {
svgCanvas.moveToBottomSelectedElement();
}
};
var moveUpDownSelected = function(dir) {
if (selectedElement != null) {
svgCanvas.moveUpDownSelected(dir);
}
};
var convertToPath = function() {
if (selectedElement != null) {
svgCanvas.convertToPath();
}
};
var reorientPath = function() {
if (selectedElement != null) {
path.reorient();
}
};
var makeHyperlink = function() {
if (selectedElement != null || multiselected) {
$.prompt(uiStrings.notification.enterNewLinkURL, 'http://', function(url) {
if (url) {svgCanvas.makeHyperlink(url);}
});
}
};
var moveSelected = function(dx,dy) {
if (selectedElement != null || multiselected) {
if (curConfig.gridSnapping) {
// Use grid snap value regardless of zoom level
var multi = svgCanvas.getZoom() * curConfig.snappingStep;
dx *= multi;
dy *= multi;
}
svgCanvas.moveSelectedElements(dx,dy);
}
};
var linkControlPoints = function() {
$('#tool_node_link').toggleClass('push_button_pressed tool_button');
var linked = $('#tool_node_link').hasClass('push_button_pressed');
path.linkControlPoints(linked);
};
var clonePathNode = function() {
if (path.getNodePoint()) {
path.clonePathNode();
}
};
var deletePathNode = function() {
if (path.getNodePoint()) {
path.deletePathNode();
}
};
var addSubPath = function() {
var button = $('#tool_add_subpath');
var sp = !button.hasClass('push_button_pressed');
button.toggleClass('push_button_pressed tool_button');
path.addSubPath(sp);
};
var opencloseSubPath = function() {
path.opencloseSubPath();
};
var selectNext = function() {
svgCanvas.cycleElement(1);
};
var selectPrev = function() {
svgCanvas.cycleElement(0);
};
var rotateSelected = function(cw, step) {
if (selectedElement == null || multiselected) {return;}
if (!cw) {step *= -1;}
var angle = parseFloat($('#angle').val()) + step;
svgCanvas.setRotationAngle(angle);
updateContextPanel();
};
var clickClear = function() {
var dims = curConfig.dimensions;
$.confirm(uiStrings.notification.QwantToClear, function(ok) {
if (!ok) {return;}
setSelectMode();
svgCanvas.clear();
svgCanvas.setResolution(dims[0], dims[1]);
updateCanvas(true);
zoomImage();
populateLayers();
updateContextPanel();
prepPaints();
svgCanvas.runExtensions('onNewDocument');
});
};
var clickBold = function() {
svgCanvas.setBold( !svgCanvas.getBold() );
updateContextPanel();
return false;
};
var clickItalic = function() {
svgCanvas.setItalic( !svgCanvas.getItalic() );
updateContextPanel();
return false;
};
var clickSave = function() {
// In the future, more options can be provided here
var saveOpts = {
'images': $.pref('img_save'),
'round_digits': 6
};
svgCanvas.save(saveOpts);
};
var clickExport = function() {
$.select('Select an image type for export: ', [
// See http://kangax.github.io/jstests/toDataUrl_mime_type_test/ for a useful list of MIME types and browser support
// 'ICO', // Todo: Find a way to preserve transparency in SVG-Edit if not working presently and do full packaging for x-icon; then switch back to position after 'PNG'
'PNG',
'JPEG', 'BMP', 'WEBP', 'PDF'
], function (imgType) { // todo: replace hard-coded msg with uiStrings.notification.
if (!imgType) {
return;
}
// Open placeholder window (prevents popup)
var exportWindowName;
function openExportWindow () {
var str = uiStrings.notification.loadingImage;
if (curConfig.exportWindowType === 'new') {
editor.exportWindowCt++;
}
exportWindowName = curConfig.canvasName + editor.exportWindowCt;
exportWindow = window.open(
'data:text/html;charset=utf-8,' + encodeURIComponent('<title>' + str + '</title><h1>' + str + '</h1>'),
exportWindowName
);
}
if (imgType === 'PDF') {
if (!customExportPDF) {
openExportWindow();
}
svgCanvas.exportPDF(exportWindowName);
}
else {
if (!customExportImage) {
openExportWindow();
}
var quality = parseInt($('#image-slider').val(), 10)/100;
svgCanvas.rasterExport(imgType, quality, exportWindowName);
}
}, function () {
var sel = $(this);
if (sel.val() === 'JPEG' || sel.val() === 'WEBP') {
if (!$('#image-slider').length) {
$('<div><label>Quality: <input id="image-slider" type="range" min="1" max="100" value="92" /></label></div>').appendTo(sel.parent()); // Todo: i18n-ize label
}
}
else {
$('#image-slider').parent().remove();
}
});
};
// by default, svgCanvas.open() is a no-op.
// it is up to an extension mechanism (opera widget, etc)
// to call setCustomHandlers() which will make it do something
var clickOpen = function() {
svgCanvas.open();
};
var clickImport = function() {
};
var clickUndo = function() {
if (undoMgr.getUndoStackSize() > 0) {
undoMgr.undo();
populateLayers();
}
};
var clickRedo = function() {
if (undoMgr.getRedoStackSize() > 0) {
undoMgr.redo();
populateLayers();
}
};
var clickGroup = function() {
// group
if (multiselected) {
svgCanvas.groupSelectedElements();
}
// ungroup
else if (selectedElement) {
svgCanvas.ungroupSelectedElement();
}
};
var clickClone = function() {
svgCanvas.cloneSelectedElements(20, 20);
};
var clickAlign = function() {
var letter = this.id.replace('tool_align', '').charAt(0);
svgCanvas.alignSelectedElements(letter, $('#align_relative_to').val());
};
var clickWireframe = function() {
$('#tool_wireframe').toggleClass('push_button_pressed tool_button');
workarea.toggleClass('wireframe');
if (supportsNonSS) {return;}
var wf_rules = $('#wireframe_rules');
if (!wf_rules.length) {
wf_rules = $('<style id="wireframe_rules"></style>').appendTo('head');
} else {
wf_rules.empty();
}
updateWireFrame();
};
//$('#svg_docprops_container, #svg_prefs_container').draggable({cancel: 'button,fieldset', containment: 'window'});
var showDocProperties = function() {
if (docprops) {return;}
docprops = true;
// This selects the correct radio button by using the array notation
$('#image_save_opts input').val([$.pref('img_save')]);
// update resolution option with actual resolution
var res = svgCanvas.getResolution();
if (curConfig.baseUnit !== 'px') {
res.w = svgedit.units.convertUnit(res.w) + curConfig.baseUnit;
res.h = svgedit.units.convertUnit(res.h) + curConfig.baseUnit;
}
$('#canvas_width').val(res.w);
$('#canvas_height').val(res.h);
$('#canvas_title').val(svgCanvas.getDocumentTitle());
$('#svg_docprops').show();
};
var showPreferences = function() {
if (preferences) {return;}
preferences = true;
$('#main_menu').hide();
// Update background color with current one
var blocks = $('#bg_blocks div');
var cur_bg = 'cur_background';
var canvas_bg = curPrefs.bkgd_color;
var url = $.pref('bkgd_url');
blocks.each(function() {
var blk = $(this);
var is_bg = blk.css('background-color') == canvas_bg;
blk.toggleClass(cur_bg, is_bg);
if (is_bg) {$('#canvas_bg_url').removeClass(cur_bg);}
});
if (!canvas_bg) {blocks.eq(0).addClass(cur_bg);}
if (url) {
$('#canvas_bg_url').val(url);
}
$('#grid_snapping_on').prop('checked', curConfig.gridSnapping);
$('#grid_snapping_step').attr('value', curConfig.snappingStep);
$('#grid_color').attr('value', curConfig.gridColor);
$('#svg_prefs').show();
};
var hideSourceEditor = function() {
$('#svg_source_editor').hide();
editingsource = false;
$('#svg_source_textarea').blur();
};
var saveSourceEditor = function() {
if (!editingsource) {return;}
var saveChanges = function() {
svgCanvas.clearSelection();
hideSourceEditor();
zoomImage();
populateLayers();
updateTitle();
prepPaints();
};
if (!svgCanvas.setSvgString($('#svg_source_textarea').val())) {
$.confirm(uiStrings.notification.QerrorsRevertToSource, function(ok) {
if (!ok) {return false;}
saveChanges();
});
} else {
saveChanges();
}
setSelectMode();
};
var hideDocProperties = function() {
$('#svg_docprops').hide();
$('#canvas_width,#canvas_height').removeAttr('disabled');
$('#resolution')[0].selectedIndex = 0;
$('#image_save_opts input').val([$.pref('img_save')]);
docprops = false;
};
var hidePreferences = function() {
$('#svg_prefs').hide();
preferences = false;
};
var saveDocProperties = function() {
// set title
var newTitle = $('#canvas_title').val();
updateTitle(newTitle);
svgCanvas.setDocumentTitle(newTitle);
// update resolution
var width = $('#canvas_width'), w = width.val();
var height = $('#canvas_height'), h = height.val();
if (w != 'fit' && !svgedit.units.isValidUnit('width', w)) {
$.alert(uiStrings.notification.invalidAttrValGiven);
width.parent().addClass('error');
return false;
}
width.parent().removeClass('error');
if (h != 'fit' && !svgedit.units.isValidUnit('height', h)) {
$.alert(uiStrings.notification.invalidAttrValGiven);
height.parent().addClass('error');
return false;
}
height.parent().removeClass('error');
if (!svgCanvas.setResolution(w, h)) {
$.alert(uiStrings.notification.noContentToFitTo);
return false;
}
// Set image save option
$.pref('img_save', $('#image_save_opts :checked').val());
updateCanvas();
hideDocProperties();
};
var savePreferences = editor.savePreferences = function() {
// Set background
var color = $('#bg_blocks div.cur_background').css('background-color') || '#FFF';
setBackground(color, $('#canvas_bg_url').val());
// set language
var lang = $('#lang_select').val();
if (lang !== $.pref('lang')) {
editor.putLocale(lang, good_langs);
}
// set icon size
setIconSize($('#iconsize').val());
// set grid setting
curConfig.gridSnapping = $('#grid_snapping_on')[0].checked;
curConfig.snappingStep = $('#grid_snapping_step').val();
curConfig.gridColor = $('#grid_color').val();
curConfig.showRulers = $('#show_rulers')[0].checked;
$('#rulers').toggle(curConfig.showRulers);
if (curConfig.showRulers) {updateRulers();}
curConfig.baseUnit = $('#base_unit').val();
svgCanvas.setConfig(curConfig);
updateCanvas();
hidePreferences();
};
var resetScrollPos = $.noop;
var cancelOverlays = function() {
$('#dialog_box').hide();
if (!editingsource && !docprops && !preferences) {
if (cur_context) {
svgCanvas.leaveContext();
}
return;
}
if (editingsource) {
if (origSource !== $('#svg_source_textarea').val()) {
$.confirm(uiStrings.notification.QignoreSourceChanges, function(ok) {
if (ok) {hideSourceEditor();}
});
} else {
hideSourceEditor();
}
} else if (docprops) {
hideDocProperties();
} else if (preferences) {
hidePreferences();
}
resetScrollPos();
};
var win_wh = {width:$(window).width(), height:$(window).height()};
// Fix for Issue 781: Drawing area jumps to top-left corner on window resize (IE9)
if (svgedit.browser.isIE()) {
(function() {
resetScrollPos = function() {
if (workarea[0].scrollLeft === 0 && workarea[0].scrollTop === 0) {
workarea[0].scrollLeft = curScrollPos.left;
workarea[0].scrollTop = curScrollPos.top;
}
};
curScrollPos = {
left: workarea[0].scrollLeft,
top: workarea[0].scrollTop
};
$(window).resize(resetScrollPos);
editor.ready(function() {
// TODO: Find better way to detect when to do this to minimize
// flickering effect
setTimeout(function() {
resetScrollPos();
}, 500);
});
workarea.scroll(function() {
curScrollPos = {
left: workarea[0].scrollLeft,
top: workarea[0].scrollTop
};
});
}());
}
$(window).resize(function(evt) {
$.each(win_wh, function(type, val) {
var curval = $(window)[type]();
workarea[0]['scroll' + (type === 'width' ? 'Left' : 'Top')] -= (curval - val)/2;
win_wh[type] = curval;
});
setFlyoutPositions();
});
//ROGERMOD - Update canvas on resize
//$(window).on("debouncedresize", updateCanvas);
$(document)
/*(function() {
workarea.scroll(function() {
// TODO: jQuery's scrollLeft/Top() wouldn't require a null check
if ($('#ruler_x').length != 0) {
$('#ruler_x')[0].scrollLeft = workarea[0].scrollLeft;
}
if ($('#ruler_y').length != 0) {
$('#ruler_y')[0].scrollTop = workarea[0].scrollTop;
}
});
}());*/
$('#url_notice').click(function() {
$.alert(this.title);
});
$('#change_image_url').click(promptImgURL);
// added these event handlers for all the push buttons so they
// behave more like buttons being pressed-in and not images
(function() {
var toolnames = ['clear', 'open', 'save', 'source', 'delete', 'delete_multi', 'paste', 'clone', 'clone_multi', 'move_top', 'move_bottom'];
var all_tools = '';
var cur_class = 'tool_button_current';
$.each(toolnames, function(i, item) {
all_tools += (i ? ',' : '') + '#tool_' + item;
});
$(all_tools).mousedown(function() {
$(this).addClass(cur_class);
}).bind('mousedown mouseout', function() {
$(this).removeClass(cur_class);
});
$('#tool_undo, #tool_redo').mousedown(function() {
if (!$(this).hasClass('disabled')) {$(this).addClass(cur_class);}
}).bind('mousedown mouseout',function() {
$(this).removeClass(cur_class);}
);
}());
// switch modifier key in tooltips if mac
// NOTE: This code is not used yet until I can figure out how to successfully bind ctrl/meta
// in Opera and Chrome
if (svgedit.browser.isMac() && !window.opera) {
var shortcutButtons = ['tool_clear', 'tool_save', 'tool_source', 'tool_undo', 'tool_redo', 'tool_clone'];
i = shortcutButtons.length;
while (i--) {
var button = document.getElementById(shortcutButtons[i]);
if (button) {
var title = button.title;
var index = title.indexOf('Ctrl+');
button.title = [title.substr(0, index), 'Cmd+', title.substr(index + 5)].join('');
}
}
}
// TODO: go back to the color boxes having white background-color and then setting
// background-image to none.png (otherwise partially transparent gradients look weird)
var colorPicker = function(elem) {
var picker = elem.attr('id') == 'stroke_color' ? 'stroke' : 'fill';
// var opacity = (picker == 'stroke' ? $('#stroke_opacity') : $('#fill_opacity'));
var paint = paintBox[picker].paint;
var title = (picker == 'stroke' ? 'Pick a Stroke Paint and Opacity' : 'Pick a Fill Paint and Opacity');
// var was_none = false; // Currently unused
var pos = elem.offset();
$('#color_picker')
.draggable({cancel: '.jGraduate_tabs, .jGraduate_colPick, .jGraduate_gradPick, .jPicker', containment: 'window'})
.css(curConfig.colorPickerCSS || {'left': pos.left - 140, 'bottom': 40})
.jGraduate(
{
paint: paint,
window: { pickerTitle: title },
images: { clientPath: curConfig.jGraduatePath },
newstop: 'inverse'
},
function(p) {
paint = new $.jGraduate.Paint(p);
paintBox[picker].setPaint(paint);
svgCanvas.setPaint(picker, paint);
$('#color_picker').hide();
},
function() {
$('#color_picker').hide();
});
};
var PaintBox = function(container, type) {
var paintColor, paintOpacity,
cur = curConfig[type === 'fill' ? 'initFill' : 'initStroke'];
// set up gradients to be used for the buttons
var svgdocbox = new DOMParser().parseFromString(
'<svg xmlns="http://www.w3.org/2000/svg"><rect width="16.5" height="16.5"'+
' fill="#' + cur.color + '" opacity="' + cur.opacity + '"/>'+
' <defs><linearGradient id="gradbox_"/></defs></svg>', 'text/xml');
var docElem = svgdocbox.documentElement;
docElem = $(container)[0].appendChild(document.importNode(docElem, true));
docElem.setAttribute('width',16.5);
this.rect = docElem.firstChild;
this.defs = docElem.getElementsByTagName('defs')[0];
this.grad = this.defs.firstChild;
this.paint = new $.jGraduate.Paint({solidColor: cur.color});
this.type = type;
this.setPaint = function(paint, apply) {
this.paint = paint;
var fillAttr = 'none';
var ptype = paint.type;
var opac = paint.alpha / 100;
switch ( ptype ) {
case 'solidColor':
fillAttr = (paint[ptype] != 'none') ? '#' + paint[ptype] : paint[ptype];
break;
case 'linearGradient':
case 'radialGradient':
this.defs.removeChild(this.grad);
this.grad = this.defs.appendChild(paint[ptype]);
var id = this.grad.id = 'gradbox_' + this.type;
fillAttr = 'url(#' + id + ')';
break;
}
this.rect.setAttribute('fill', fillAttr);
this.rect.setAttribute('opacity', opac);
if (apply) {
svgCanvas.setColor(this.type, paintColor, true);
svgCanvas.setPaintOpacity(this.type, paintOpacity, true);
}
};
this.update = function(apply) {
if (!selectedElement) {return;}
var i, len;
var type = this.type;
switch (selectedElement.tagName) {
case 'use':
case 'image':
case 'foreignObject':
// These elements don't have fill or stroke, so don't change
// the current value
return;
case 'g':
case 'a':
var gPaint = null;
var childs = selectedElement.getElementsByTagName('*');
for (i = 0, len = childs.length; i < len; i++) {
var elem = childs[i];
var p = elem.getAttribute(type);
if (i === 0) {
gPaint = p;
} else if (gPaint !== p) {
gPaint = null;
break;
}
}
if (gPaint === null) {
// No common color, don't update anything
paintColor = null;
return;
}
paintColor = gPaint;
paintOpacity = 1;
break;
default:
paintOpacity = parseFloat(selectedElement.getAttribute(type + '-opacity'));
if (isNaN(paintOpacity)) {
paintOpacity = 1.0;
}
var defColor = type === 'fill' ? 'black' : 'none';
paintColor = selectedElement.getAttribute(type) || defColor;
}
if (apply) {
svgCanvas.setColor(type, paintColor, true);
svgCanvas.setPaintOpacity(type, paintOpacity, true);
}
paintOpacity *= 100;
var paint = getPaint(paintColor, paintOpacity, type);
// update the rect inside #fill_color/#stroke_color
this.setPaint(paint);
};
this.prep = function() {
var ptype = this.paint.type;
switch ( ptype ) {
case 'linearGradient':
case 'radialGradient':
var paint = new $.jGraduate.Paint({copy: this.paint});
svgCanvas.setPaint(type, paint);
break;
}
};
};
//paintBox.fill = new PaintBox('#fill_color', 'fill');
//paintBox.stroke = new PaintBox('#stroke_color', 'stroke');
//$('#stroke_width').val(curConfig.initStroke.width);
//$('#group_opacity').val(curConfig.initOpacity * 100);
/* ROGER - not using an element to test for vector-effect support*/
supportsNonSS = (document.documentElement.style.vectorEffect === undefined);
// Use this SVG elem to test vectorEffect support
/*var testEl = paintBox.fill.rect.cloneNode(false);
testEl.setAttribute('style', 'vector-effect:non-scaling-stroke');
supportsNonSS = (testEl.style.vectorEffect === 'non-scaling-stroke');
testEl.removeAttribute('style');
var svgdocbox = paintBox.fill.rect.ownerDocument;
// Use this to test support for blur element. Seems to work to test support in Webkit
var blurTest = svgdocbox.createElementNS(svgedit.NS.SVG, 'feGaussianBlur');
if (blurTest.stdDeviationX === undefined) {
$('#tool_blur').hide();
}
$(blurTest).remove();*/
// Test for zoom icon support
(function() {
var pre = '-' + uaPrefix.toLowerCase() + '-zoom-';
var zoom = pre + 'in';
workarea.css('cursor', zoom);
if (workarea.css('cursor') === zoom) {
zoomInIcon = zoom;
zoomOutIcon = pre + 'out';
}
workarea.css('cursor', 'auto');
}());
// Test for embedImage support (use timeout to not interfere with page load)
setTimeout(function() {
svgCanvas.embedImage('img/rotate.png', function(datauri) {
if (!datauri) {
// Disable option
$('#image_save_opts [value=embed]').attr('disabled', 'disabled');
$('#image_save_opts input').val(['ref']);
$.pref('img_save', 'ref');
$('#image_opt_embed').css('color', '#666').attr('title', uiStrings.notification.featNotSupported);
}
});
}, 1000);
$('#fill_color, #tool_fill .icon_label').click(function() {
colorPicker($('#fill_color'));
updateToolButtonState();
});
$('#stroke_color, #tool_stroke .icon_label').click(function() {
colorPicker($('#stroke_color'));
updateToolButtonState();
});
$('#group_opacityLabel').click(function() {
$('#opacity_dropdown button').mousedown();
$(window).mouseup();
});
$('#zoomLabel').click(function() {
$('#zoom_dropdown button').mousedown();
$(window).mouseup();
});
$('#tool_move_top').mousedown(function(evt) {
$('#tools_stacking').show();
evt.preventDefault();
});
$('.layer_button').mousedown(function() {
$(this).addClass('layer_buttonpressed');
}).mouseout(function() {
$(this).removeClass('layer_buttonpressed');
}).mouseup(function() {
$(this).removeClass('layer_buttonpressed');
});
$('.push_button').mousedown(function() {
if (!$(this).hasClass('disabled')) {
$(this).addClass('push_button_pressed').removeClass('push_button');
}
}).mouseout(function() {
$(this).removeClass('push_button_pressed').addClass('push_button');
}).mouseup(function() {
$(this).removeClass('push_button_pressed').addClass('push_button');
});
// ask for a layer name
$('#layer_new').click(function() {
var uniqName,
i = svgCanvas.getCurrentDrawing().getNumLayers();
do {
uniqName = uiStrings.layers.layer + ' ' + (++i);
} while(svgCanvas.getCurrentDrawing().hasLayer(uniqName));
$.prompt(uiStrings.notification.enterUniqueLayerName, uniqName, function(newName) {
if (!newName) {return;}
if (svgCanvas.getCurrentDrawing().hasLayer(newName)) {
$.alert(uiStrings.notification.dupeLayerName);
return;
}
svgCanvas.createLayer(newName);
updateContextPanel();
populateLayers();
});
});
function deleteLayer() {
if (svgCanvas.deleteCurrentLayer()) {
updateContextPanel();
populateLayers();
// This matches what SvgCanvas does
// TODO: make this behavior less brittle (svg-editor should get which
// layer is selected from the canvas and then select that one in the UI)
$('#layerlist tr.layer').removeClass('layersel');
$('#layerlist tr.layer:first').addClass('layersel');
}
}
function cloneLayer() {
var name = svgCanvas.getCurrentDrawing().getCurrentLayerName() + ' copy';
$.prompt(uiStrings.notification.enterUniqueLayerName, name, function(newName) {
if (!newName) {return;}
if (svgCanvas.getCurrentDrawing().hasLayer(newName)) {
$.alert(uiStrings.notification.dupeLayerName);
return;
}
svgCanvas.cloneLayer(newName);
updateContextPanel();
populateLayers();
});
}
function mergeLayer() {
if ($('#layerlist tr.layersel').index() == svgCanvas.getCurrentDrawing().getNumLayers()-1) {
return;
}
svgCanvas.mergeLayer();
updateContextPanel();
populateLayers();
}
function moveLayer(pos) {
var curIndex = $('#layerlist tr.layersel').index();
var total = svgCanvas.getCurrentDrawing().getNumLayers();
if (curIndex > 0 || curIndex < total-1) {
curIndex += pos;
svgCanvas.setCurrentLayerPosition(total-curIndex-1);
populateLayers();
}
}
$('#layer_delete').click(deleteLayer);
$('#layer_up').click(function() {
moveLayer(-1);
});
$('#layer_down').click(function() {
moveLayer(1);
});
$('#layer_rename').click(function() {
// var curIndex = $('#layerlist tr.layersel').prevAll().length; // Currently unused
var oldName = $('#layerlist tr.layersel td.layername').text();
$.prompt(uiStrings.notification.enterNewLayerName, '', function(newName) {
if (!newName) {return;}
if (oldName == newName || svgCanvas.getCurrentDrawing().hasLayer(newName)) {
$.alert(uiStrings.notification.layerHasThatName);
return;
}
svgCanvas.renameCurrentLayer(newName);
populateLayers();
});
});
var SIDEPANEL_MAXWIDTH = 300;
var SIDEPANEL_OPENWIDTH = 150;
var sidedrag = -1, sidedragging = false, allowmove = false;
var changeSidePanelWidth = function(delta) {
var rulerX = $('#ruler_x');
$('#sidepanels').width('+=' + delta);
$('#layerpanel').width('+=' + delta);
rulerX.css('right', parseInt(rulerX.css('right'), 10) + delta);
workarea.css('right', parseInt(workarea.css('right'), 10) + delta);
svgCanvas.runExtensions('workareaResized');
};
var resizeSidePanel = function(evt) {
if (!allowmove) {return;}
if (sidedrag == -1) {return;}
sidedragging = true;
var deltaX = sidedrag - evt.pageX;
var sideWidth = $('#sidepanels').width();
if (sideWidth + deltaX > SIDEPANEL_MAXWIDTH) {
deltaX = SIDEPANEL_MAXWIDTH - sideWidth;
sideWidth = SIDEPANEL_MAXWIDTH;
} else if (sideWidth + deltaX < 2) {
deltaX = 2 - sideWidth;
sideWidth = 2;
}
if (deltaX == 0) {return;}
sidedrag -= deltaX;
changeSidePanelWidth(deltaX);
};
// if width is non-zero, then fully close it, otherwise fully open it
// the optional close argument forces the side panel closed
var toggleSidePanel = function(close) {
var w = $('#sidepanels').width();
var deltaX = (w > 2 || close ? 2 : SIDEPANEL_OPENWIDTH) - w;
changeSidePanelWidth(deltaX);
};
$('#sidepanel_handle')
.mousedown(function(evt) {
sidedrag = evt.pageX;
$(window).mousemove(resizeSidePanel);
allowmove = false;
// Silly hack for Chrome, which always runs mousemove right after mousedown
setTimeout(function() {
allowmove = true;
}, 20);
})
.mouseup(function(evt) {
if (!sidedragging) {toggleSidePanel();}
sidedrag = -1;
sidedragging = false;
});
$(window).mouseup(function() {
sidedrag = -1;
sidedragging = false;
$('#svg_editor').unbind('mousemove', resizeSidePanel);
});
populateLayers();
// function changeResolution(x,y) {
// var zoom = svgCanvas.getResolution().zoom;
// setResolution(x * zoom, y * zoom);
// }
var centerCanvas = function() {
// this centers the canvas vertically in the workarea (horizontal handled in CSS)
workarea.css('line-height', workarea.height() + 'px');
};
function stepFontSize(elem, step) {
var orig_val = Number(elem.value);
var sug_val = orig_val + step;
var increasing = sug_val >= orig_val;
if (step === 0) {return orig_val;}
if (orig_val >= 24) {
if (increasing) {
return Math.round(orig_val * 1.1);
}
return Math.round(orig_val / 1.1);
}
if (orig_val <= 1) {
if (increasing) {
return orig_val * 2;
}
return orig_val / 2;
}
return sug_val;
}
function stepZoom(elem, step) {
var orig_val = Number(elem.value);
if (orig_val === 0) {return 100;}
var sug_val = orig_val + step;
if (step === 0) {return orig_val;}
if (orig_val >= 100) {
return sug_val;
}
if (sug_val >= orig_val) {
return orig_val * 2;
}
return orig_val / 2;
}
// function setResolution(w, h, center) {
// updateCanvas();
// // w-=0; h-=0;
// // $('#svgcanvas').css( { 'width': w, 'height': h } );
// // $('#canvas_width').val(w);
// // $('#canvas_height').val(h);
// //
// // if (center) {
// // var w_area = workarea;
// // var scroll_y = h/2 - w_area.height()/2;
// // var scroll_x = w/2 - w_area.width()/2;
// // w_area[0].scrollTop = scroll_y;
// // w_area[0].scrollLeft = scroll_x;
// // }
// }
$('#resolution').change(function() {
var wh = $('#canvas_width,#canvas_height');
if (!this.selectedIndex) {
if ($('#canvas_width').val() == 'fit') {
wh.removeAttr('disabled').val(100);
}
} else if (this.value == 'content') {
wh.val('fit').attr('disabled', 'disabled');
} else {
var dims = this.value.split('x');
$('#canvas_width').val(dims[0]);
$('#canvas_height').val(dims[1]);
wh.removeAttr('disabled');
}
});
//Prevent browser from erroneously repopulating fields
$('input,select').attr('autocomplete', 'off');
// Associate all button actions as well as non-button keyboard shortcuts
Actions = (function() {
// sel:'selector', fn:function, evt:'event', key:[key, preventDefault, NoDisableInInput]
var tool_buttons = [
{sel: '#tool_select', fn: clickSelect, evt: 'click', key: ['V', true]},
{sel: '#tool_fhpath', fn: clickFHPath, evt: 'click', key: ['Q', true]},
{sel: '#tool_line', fn: clickLine, evt: 'click', key: ['L', true]},
{sel: '#tool_rect', fn: clickRect, evt: 'mouseup', key: ['R', true], parent: '#tools_rect', icon: 'rect'},
{sel: '#tool_square', fn: clickSquare, evt: 'mouseup', parent: '#tools_rect', icon: 'square'},
{sel: '#tool_fhrect', fn: clickFHRect, evt: 'mouseup', parent: '#tools_rect', icon: 'fh_rect'},
{sel: '#tool_ellipse', fn: clickEllipse, evt: 'mouseup', key: ['E', true], parent: '#tools_ellipse', icon: 'ellipse'},
{sel: '#tool_circle', fn: clickCircle, evt: 'mouseup', parent: '#tools_ellipse', icon: 'circle'},
{sel: '#tool_fhellipse', fn: clickFHEllipse, evt: 'mouseup', parent: '#tools_ellipse', icon: 'fh_ellipse'},
{sel: '#tool_path', fn: clickPath, evt: 'click', key: ['P', true]},
{sel: '#tool_text', fn: clickText, evt: 'click', key: ['T', true]},
{sel: '#tool_image', fn: clickImage, evt: 'mouseup'},
{sel: '#tool_zoom', fn: clickZoom, evt: 'mouseup', key: ['Z', true]},
{sel: '#tool_clear', fn: clickClear, evt: 'mouseup', key: ['N', true]},
+ {sel: '#tool_point', fn: clickPoint, evt: 'mouseup'},
{sel: '#tool_save', fn: function() {
if (editingsource) {
saveSourceEditor();
}
else {
clickSave();
}
}, evt: 'mouseup', key: ['S', true]},
{sel: '#tool_export', fn: clickExport, evt: 'mouseup'},
{sel: '#tool_open', fn: clickOpen, evt: 'mouseup', key: ['O', true]},
{sel: '#tool_import', fn: clickImport, evt: 'mouseup'},
{sel: '#tool_source', fn: showSourceEditor, evt: 'click', key: ['U', true]},
{sel: '#tool_wireframe', fn: clickWireframe, evt: 'click', key: ['F', true]},
{sel: '#tool_source_cancel,.overlay,#tool_docprops_cancel,#tool_prefs_cancel', fn: cancelOverlays, evt: 'click', key: ['esc', false, false], hidekey: true},
{sel: '#tool_source_save', fn: saveSourceEditor, evt: 'click'},
{sel: '#tool_docprops_save', fn: saveDocProperties, evt: 'click'},
{sel: '#tool_docprops', fn: showDocProperties, evt: 'mouseup'},
{sel: '#tool_prefs_save', fn: savePreferences, evt: 'click'},
{sel: '#tool_prefs_option', fn: function() {showPreferences(); return false;}, evt: 'mouseup'},
{sel: '#tool_delete,#tool_delete_multi', fn: deleteSelected, evt: 'click', key: ['del/backspace', true]},
{sel: '#tool_reorient', fn: reorientPath, evt: 'click'},
{sel: '#tool_node_link', fn: linkControlPoints, evt: 'click'},
{sel: '#tool_node_clone', fn: clonePathNode, evt: 'click'},
{sel: '#tool_node_delete', fn: deletePathNode, evt: 'click'},
{sel: '#tool_openclose_path', fn: opencloseSubPath, evt: 'click'},
{sel: '#tool_add_subpath', fn: addSubPath, evt: 'click'},
{sel: '#tool_move_top', fn: moveToTopSelected, evt: 'click', key: 'ctrl+shift+]'},
{sel: '#tool_move_bottom', fn: moveToBottomSelected, evt: 'click', key: 'ctrl+shift+['},
{sel: '#tool_topath', fn: convertToPath, evt: 'click'},
{sel: '#tool_make_link,#tool_make_link_multi', fn: makeHyperlink, evt: 'click'},
{sel: '#tool_undo', fn: clickUndo, evt: 'click', key: ['Z', true]},
{sel: '#tool_redo', fn: clickRedo, evt: 'click', key: ['Y', true]},
{sel: '#tool_clone,#tool_clone_multi', fn: clickClone, evt: 'click', key: ['D', true]},
{sel: '#tool_group_elements', fn: clickGroup, evt: 'click', key: ['G', true]},
{sel: '#tool_ungroup', fn: clickGroup, evt: 'click'},
{sel: '#tool_unlink_use', fn: clickGroup, evt: 'click'},
{sel: '[id^=tool_align]', fn: clickAlign, evt: 'click'},
// these two lines are required to make Opera work properly with the flyout mechanism
// {sel: '#tools_rect_show', fn: clickRect, evt: 'click'},
// {sel: '#tools_ellipse_show', fn: clickEllipse, evt: 'click'},
{sel: '#tool_bold', fn: clickBold, evt: 'mousedown'},
{sel: '#tool_italic', fn: clickItalic, evt: 'mousedown'},
{sel: '#sidepanel_handle', fn: toggleSidePanel, key: ['X']},
{sel: '#copy_save_done', fn: cancelOverlays, evt: 'click'},
// Shortcuts not associated with buttons
{key: 'ctrl+left', fn: function(){rotateSelected(0,1);}},
{key: 'ctrl+right', fn: function(){rotateSelected(1,1);}},
{key: 'ctrl+shift+left', fn: function(){rotateSelected(0,5);}},
{key: 'ctrl+shift+right', fn: function(){rotateSelected(1,5);}},
{key: 'shift+O', fn: selectPrev},
{key: 'shift+P', fn: selectNext},
{key: [modKey+'up', true], fn: function(){zoomImage(2);}},
{key: [modKey+'down', true], fn: function(){zoomImage(0.5);}},
{key: [modKey+']', true], fn: function(){moveUpDownSelected('Up');}},
{key: [modKey+'[', true], fn: function(){moveUpDownSelected('Down');}},
{key: ['up', true], fn: function(){moveSelected(0,-1);}},
{key: ['down', true], fn: function(){moveSelected(0,1);}},
{key: ['left', true], fn: function(){moveSelected(-1,0);}},
{key: ['right', true], fn: function(){moveSelected(1,0);}},
{key: 'shift+up', fn: function(){moveSelected(0,-10);}},
{key: 'shift+down', fn: function(){moveSelected(0,10);}},
{key: 'shift+left', fn: function(){moveSelected(-10,0);}},
{key: 'shift+right', fn: function(){moveSelected(10,0);}},
{key: ['alt+up', true], fn: function(){svgCanvas.cloneSelectedElements(0,-1);}},
{key: ['alt+down', true], fn: function(){svgCanvas.cloneSelectedElements(0,1);}},
{key: ['alt+left', true], fn: function(){svgCanvas.cloneSelectedElements(-1,0);}},
{key: ['alt+right', true], fn: function(){svgCanvas.cloneSelectedElements(1,0);}},
{key: ['alt+shift+up', true], fn: function(){svgCanvas.cloneSelectedElements(0,-10);}},
{key: ['alt+shift+down', true], fn: function(){svgCanvas.cloneSelectedElements(0,10);}},
{key: ['alt+shift+left', true], fn: function(){svgCanvas.cloneSelectedElements(-10,0);}},
{key: ['alt+shift+right', true], fn: function(){svgCanvas.cloneSelectedElements(10,0);}},
{key: 'A', fn: function(){svgCanvas.selectAllInCurrentLayer();}},
// Standard shortcuts
{key: modKey+'z', fn: clickUndo},
{key: modKey + 'shift+z', fn: clickRedo},
{key: modKey + 'y', fn: clickRedo},
{key: modKey+'x', fn: cutSelected},
{key: modKey+'c', fn: copySelected},
{key: modKey+'v', fn: pasteInCenter}
];
// Tooltips not directly associated with a single function
var key_assocs = {
'4/Shift+4': '#tools_rect_show',
'5/Shift+5': '#tools_ellipse_show'
};
return {
setAll: function() {
var flyouts = {};
$.each(tool_buttons, function(i, opts) {
// Bind function to button
var btn;
if (opts.sel) {
btn = $(opts.sel);
//ROGERMOD - Don't skip actually, we still want keyboard shortcuts to work
//if (btn.length == 0) {return true;} // Skip if markup does not exist
if (opts.evt) {
if (svgedit.browser.isTouch() && opts.evt === 'click') {
opts.evt = 'mousedown';
}
btn[opts.evt](opts.fn);
}
// Add to parent flyout menu, if able to be displayed
if (opts.parent && $(opts.parent + '_show').length != 0) {
var f_h = $(opts.parent);
if (!f_h.length) {
f_h = makeFlyoutHolder(opts.parent.substr(1));
}
f_h.append(btn);
if (!$.isArray(flyouts[opts.parent])) {
flyouts[opts.parent] = [];
}
flyouts[opts.parent].push(opts);
}
}
// Bind function to shortcut key
if (opts.key) {
// Set shortcut based on options
var keyval, disInInp = true, fn = opts.fn, pd = false;
if ($.isArray(opts.key)) {
keyval = opts.key[0];
if (opts.key.length > 1) {pd = opts.key[1];}
if (opts.key.length > 2) {disInInp = opts.key[2];}
} else {
keyval = opts.key;
}
keyval += '';
$.each(keyval.split('/'), function(i, key) {
$(document).bind('keydown', key, function(e) {
//ROGERMOD - Only when in annotating mode
if(annotating){
fn();
if (pd) {
e.preventDefault();
}
// Prevent default on ALL keys?
return false;
}
});
});
// Put shortcut in title
if (opts.sel && !opts.hidekey && btn.attr('title')) {
var newTitle = btn.attr('title').split('[')[0] + ' (' + keyval + ')';
key_assocs[keyval] = opts.sel;
// Disregard for menu items
if (!btn.parents('#main_menu').length) {
btn.attr('title', newTitle);
}
}
}
});
// Setup flyouts
setupFlyouts(flyouts);
// Misc additional actions
// Make 'return' keypress trigger the change event
$('.attr_changer, #image_url').bind('keydown', 'return',
function(evt) {$(this).change();evt.preventDefault();}
);
$(window).bind('keydown', 'tab', function(e) {
if (ui_context === 'canvas') {
e.preventDefault();
selectNext();
}
}).bind('keydown', 'shift+tab', function(e) {
if (ui_context === 'canvas') {
e.preventDefault();
selectPrev();
}
});
$('#tool_zoom').dblclick(dblclickZoom);
},
setTitles: function() {
$.each(key_assocs, function(keyval, sel) {
var menu = ($(sel).parents('#main_menu').length);
$(sel).each(function() {
var t;
if (menu) {
t = $(this).text().split(' [')[0];
} else {
t = this.title.split(' [')[0];
}
var key_str = '';
// Shift+Up
$.each(keyval.split('/'), function(i, key) {
var mod_bits = key.split('+'), mod = '';
if (mod_bits.length > 1) {
mod = mod_bits[0] + '+';
key = mod_bits[1];
}
key_str += (i?'/':'') + mod + (uiStrings['key_'+key] || key);
});
if (menu) {
this.lastChild.textContent = t +' ['+key_str+']';
} else {
this.title = t +' ['+key_str+']';
}
});
});
},
getButtonData: function(sel) {
var b;
$.each(tool_buttons, function(i, btn) {
if (btn.sel === sel) {b = btn;}
});
return b;
}
};
}());
Actions.setAll();
// Select given tool
editor.ready(function() {
var tool,
itool = curConfig.initTool,
container = $('#tools_left, #svg_editor .tools_flyout'),
pre_tool = container.find('#tool_' + itool),
reg_tool = container.find('#' + itool);
if (pre_tool.length) {
tool = pre_tool;
} else if (reg_tool.length) {
tool = reg_tool;
} else {
tool = $('#tool_select');
}
tool.click().mouseup();
if (curConfig.wireframe) {
$('#tool_wireframe').click();
}
if (curConfig.showlayers) {
toggleSidePanel();
}
$('#rulers').toggle(!!curConfig.showRulers);
if (curConfig.showRulers) {
$('#show_rulers')[0].checked = true;
}
if (curConfig.baseUnit) {
$('#base_unit').val(curConfig.baseUnit);
}
if (curConfig.gridSnapping) {
$('#grid_snapping_on')[0].checked = true;
}
if (curConfig.snappingStep) {
$('#grid_snapping_step').val(curConfig.snappingStep);
}
if (curConfig.gridColor) {
$('#grid_color').val(curConfig.gridColor);
}
});
// init SpinButtons
/*
$('#rect_rx').SpinButton({ min: 0, max: 1000, callback: changeRectRadius });
$('#stroke_width').SpinButton({ min: 0, max: 99, smallStep: 0.1, callback: changeStrokeWidth });
$('#angle').SpinButton({ min: -180, max: 180, step: 5, callback: changeRotationAngle });
$('#font_size').SpinButton({ min: 0.001, stepfunc: stepFontSize, callback: changeFontSize });
$('#group_opacity').SpinButton({ min: 0, max: 100, step: 5, callback: changeOpacity });
$('#blur').SpinButton({ min: 0, max: 10, step: 0.1, callback: changeBlur });
$('#zoom').SpinButton({ min: 0.001, max: 10000, step: 50, stepfunc: stepZoom, callback: changeZoom })
// Set default zoom
.val(svgCanvas.getZoom() * 100);
*/
$('#workarea').contextMenu({
menu: 'cmenu_canvas',
inSpeed: 0
},
function(action, el, pos) {
switch (action) {
case 'delete':
deleteSelected();
break;
case 'cut':
cutSelected();
break;
case 'copy':
copySelected();
break;
case 'paste':
svgCanvas.pasteElements();
break;
case 'paste_in_place':
svgCanvas.pasteElements('in_place');
break;
case 'group_elements':
svgCanvas.groupSelectedElements();
break;
case 'ungroup':
svgCanvas.ungroupSelectedElement();
break;
case 'move_front':
moveToTopSelected();
break;
case 'move_up':
moveUpDownSelected('Up');
break;
case 'move_down':
moveUpDownSelected('Down');
break;
case 'move_back':
moveToBottomSelected();
break;
default:
if (svgedit.contextmenu && svgedit.contextmenu.hasCustomHandler(action)) {
svgedit.contextmenu.getCustomHandler(action).call();
}
break;
}
if (svgCanvas.clipBoard.length) {
canv_menu.enableContextMenuItems('#paste,#paste_in_place');
}
}
);
var lmenu_func = function(action, el, pos) {
switch ( action ) {
case 'dupe':
cloneLayer();
break;
case 'delete':
deleteLayer();
break;
case 'merge_down':
mergeLayer();
break;
case 'merge_all':
svgCanvas.mergeAllLayers();
updateContextPanel();
populateLayers();
break;
}
};
$('#layerlist').contextMenu({
menu: 'cmenu_layers',
inSpeed: 0
},
lmenu_func
);
$('#layer_moreopts').contextMenu({
menu: 'cmenu_layers',
inSpeed: 0,
allowLeft: true
},
lmenu_func
);
$('.contextMenu li').mousedown(function(ev) {
ev.preventDefault();
});
$('#cmenu_canvas li').disableContextMenu();
canv_menu.enableContextMenuItems('#delete,#cut,#copy');
window.addEventListener('beforeunload', function(e) {
// Suppress warning if page is empty
if (undoMgr.getUndoStackSize() === 0) {
editor.showSaveWarning = false;
}
// showSaveWarning is set to 'false' when the page is saved.
if (!curConfig.no_save_warning && editor.showSaveWarning) {
// Browser already asks question about closing the page
e.returnValue = uiStrings.notification.unsavedChanges; // Firefox needs this when beforeunload set by addEventListener (even though message is not used)
return uiStrings.notification.unsavedChanges;
}
}, false);
editor.openPrep = function(func) {
$('#main_menu').hide();
if (undoMgr.getUndoStackSize() === 0) {
func(true);
} else {
$.confirm(uiStrings.notification.QwantToOpen, func);
}
};
function onDragEnter(e) {
e.stopPropagation();
e.preventDefault();
// and indicator should be displayed here, such as "drop files here"
}
function onDragOver(e) {
e.stopPropagation();
e.preventDefault();
}
function onDragLeave(e) {
e.stopPropagation();
e.preventDefault();
// hypothetical indicator should be removed here
}
// Use HTML5 File API: http://www.w3.org/TR/FileAPI/
// if browser has HTML5 File API support, then we will show the open menu item
// and provide a file input to click. When that change event fires, it will
// get the text contents of the file and send it to the canvas
if (window.FileReader) {
var importImage = function(e) {
$.process_cancel(uiStrings.notification.loadingImage);
e.stopPropagation();
e.preventDefault();
$('#workarea').removeAttr('style');
$('#main_menu').hide();
var file = (e.type == 'drop') ? e.dataTransfer.files[0] : this.files[0];
if (!file) {
$('#dialog_box').hide();
return;
}
/* if (file.type === 'application/pdf') { // Todo: Handle PDF imports
}
else */
if (file.type.indexOf('image') != -1) {
// Detected an image
// svg handling
var reader;
if (file.type.indexOf('svg') != -1) {
reader = new FileReader();
reader.onloadend = function(e) {
svgCanvas.importSvgString(e.target.result, true);
svgCanvas.ungroupSelectedElement();
svgCanvas.ungroupSelectedElement();
svgCanvas.groupSelectedElements();
svgCanvas.alignSelectedElements('m', 'page');
svgCanvas.alignSelectedElements('c', 'page');
$('#dialog_box').hide();
};
reader.readAsText(file);
}
else {
//bitmap handling
reader = new FileReader();
reader.onloadend = function(e) {
// let's insert the new image until we know its dimensions
var insertNewImage = function(width, height) {
var newImage = svgCanvas.addSvgElementFromJson({
element: 'image',
attr: {
x: 0,
y: 0,
width: width,
height: height,
id: svgCanvas.getNextId(),
'vector-effect':'non-scaling-stroke',
style: 'pointer-events:inherit'
}
});
svgCanvas.setHref(newImage, e.target.result);
svgCanvas.selectOnly([newImage]);
svgCanvas.alignSelectedElements('m', 'page');
svgCanvas.alignSelectedElements('c', 'page');
updateContextPanel();
$('#dialog_box').hide();
};
// create dummy img so we know the default dimensions
var imgWidth = 100;
var imgHeight = 100;
var img = new Image();
img.src = e.target.result;
img.style.opacity = 0;
img.onload = function() {
imgWidth = img.offsetWidth;
imgHeight = img.offsetHeight;
insertNewImage(imgWidth, imgHeight);
};
};
reader.readAsDataURL(file);
}
}
};
workarea[0].addEventListener('dragenter', onDragEnter, false);
workarea[0].addEventListener('dragover', onDragOver, false);
workarea[0].addEventListener('dragleave', onDragLeave, false);
workarea[0].addEventListener('drop', importImage, false);
var open = $('<input type="file">').change(function() {
var f = this;
editor.openPrep(function(ok) {
if (!ok) {return;}
svgCanvas.clear();
if (f.files.length === 1) {
$.process_cancel(uiStrings.notification.loadingImage);
var reader = new FileReader();
reader.onloadend = function(e) {
loadSvgString(e.target.result);
updateCanvas();
};
reader.readAsText(f.files[0]);
}
});
});
$('#tool_open').show().prepend(open);
var imgImport = $('<input type="file">').change(importImage);
$('#tool_import').show().prepend(imgImport);
}
// $(function() {
updateCanvas(true);
// });
// var revnums = "svg-editor.js ($Rev: 2875 $) ";
// revnums += svgCanvas.getVersion();
// $('#copyright')[0].setAttribute('title', revnums);
// For Compatibility with older extensions
$(function() {
window.svgCanvas = svgCanvas;
svgCanvas.ready = editor.ready;
});
editor.setLang = function(lang, allStrings) {
editor.langChanged = true;
$.pref('lang', lang);
$('#lang_select').val(lang);
if (!allStrings) {
return;
}
// var notif = allStrings.notification; // Currently unused
// $.extend will only replace the given strings
var oldLayerName = $('#layerlist tr.layersel td.layername').text();
var rename_layer = (oldLayerName == uiStrings.common.layer + ' 1');
$.extend(uiStrings, allStrings);
svgCanvas.setUiStrings(allStrings);
Actions.setTitles();
if (rename_layer) {
svgCanvas.renameCurrentLayer(uiStrings.common.layer + ' 1');
populateLayers();
}
// In case extensions loaded before the locale, now we execute a callback on them
if (extsPreLang.length) {
while (extsPreLang.length) {
var ext = extsPreLang.shift();
ext.langReady({lang: lang, uiStrings: uiStrings});
}
}
else {
svgCanvas.runExtensions('langReady', {lang: lang, uiStrings: uiStrings});
}
svgCanvas.runExtensions('langChanged', lang);
// Update flyout tooltips
setFlyoutTitles();
// Copy title for certain tool elements
var elems = {
'#stroke_color': '#tool_stroke .icon_label, #tool_stroke .color_block',
'#fill_color': '#tool_fill label, #tool_fill .color_block',
'#linejoin_miter': '#cur_linejoin',
'#linecap_butt': '#cur_linecap'
};
$.each(elems, function(source, dest) {
$(dest).attr('title', $(source)[0].title);
});
// Copy alignment titles
$('#multiselected_panel div[id^=tool_align]').each(function() {
$('#tool_pos' + this.id.substr(10))[0].title = this.title;
});
};
};
editor.ready = function (cb) {
if (!isReady) {
callbacks.push(cb);
} else {
cb();
}
};
editor.runCallbacks = function () {
$.each(callbacks, function() {
this();
});
isReady = true;
};
editor.loadFromString = function (str) {
editor.ready(function() {
loadSvgString(str);
});
};
editor.disableUI = function (featList) {
// $(function() {
// $('#tool_wireframe, #tool_image, #main_button, #tool_source, #sidepanels').remove();
// $('#tools_top').css('left', 5);
// });
};
editor.loadFromURL = function (url, opts) {
if (!opts) {opts = {};}
var cache = opts.cache;
var cb = opts.callback;
editor.ready(function() {
$.ajax({
'url': url,
'dataType': 'text',
cache: !!cache,
beforeSend:function(){
$.process_cancel(uiStrings.notification.loadingImage);
},
success: function(str) {
loadSvgString(str, cb);
},
error: function(xhr, stat, err) {
if (xhr.status != 404 && xhr.responseText) {
loadSvgString(xhr.responseText, cb);
} else {
$.alert(uiStrings.notification.URLloadFail + ': \n' + err, cb);
}
},
complete:function(){
$('#dialog_box').hide();
}
});
});
};
editor.loadFromDataURI = function(str) {
editor.ready(function() {
var base64 = false;
var pre = str.match(/^data:image\/svg\+xml;base64,/);
if (pre) {
base64 = true;
}
else {
pre = str.match(/^data:image\/svg\+xml(?:;(?:utf8)?)?,/);
}
if (pre) {
pre = pre[0];
}
var src = str.slice(pre.length);
loadSvgString(base64 ? Utils.decode64(src) : decodeURIComponent(src));
});
};
editor.addExtension = function () {
var args = arguments;
// Note that we don't want this on editor.ready since some extensions
// may want to run before then (like server_opensave).
$(function() {
if (svgCanvas) {svgCanvas.addExtension.apply(this, args);}
});
};
return editor;
}(jQuery));
// Run init once DOM is loaded
/*$(function(){
svgEditor.init();
});*/
}());
diff --git a/desuto-viewer/Desuto-webviewer/public/stylesheets/theme.css b/desuto-viewer/Desuto-webviewer/public/stylesheets/theme.css
index 4d6a65a..ca935b9 100644
--- a/desuto-viewer/Desuto-webviewer/public/stylesheets/theme.css
+++ b/desuto-viewer/Desuto-webviewer/public/stylesheets/theme.css
@@ -1,647 +1,658 @@
/*
Created on : Apr 28, 2015, 10:06:04 AM
Author : sro
*/
html, body {
font-family: Helvetica, Arial, sans-serif;
margin-top: 0px;
margin: 0px;
height: 100%;
min-height: 100%;
}
nav {
margin-bottom: 0px !important;
}
.clear {
clear: both;
}
.centered {
text-align: center;
}
#maincontainer {
height: calc(100% - 52px);
width: 100%;
min-width: 800px;
position: absolute;
}
#container {
float: left;
width: 100%;
height: 100%;
overflow: hidden;
}
#left {
padding-right: 1em;
margin-right: 320px;
height: 80%;
}
#annotation-details {
position: absolute;
top: 0em;
right: 120px;
width: 200px;
}
#annotation-details p {
margin-top: .75em;
margin-bottom: .25em;
}
#annotation-details hr {
margin: 5px 0;
border-top-color: #ccc;
}
#toggle-annotation {
float: left;
}
#sync {
float: left;
margin-left: 1em;
}
#footer {
clear: both;
width: 100%;
padding: 0 0.5em;
font-size: smaller;
}
#image-list, #feature-list {
padding: 1em;
}
#image-list ul li, #feature-list ul li {
font-size: smaller;
padding: 0.15em 0;
}
/*#image-list{
margin-left: -310px;
overflow-x: auto;
white-space: nowrap;
}
#feature-list{
margin-left:-150px;
overflow-x: auto;
}*/
.upload-process {
display: none;
}
#sidenavMenu {
text-align: center;
position: absolute;
top: 0;
right: 0;
width: 120px;
}
#sidenavMenu div {
cursor: pointer;
}
#sidenavMenu div:hover {
text-decoration: underline;
}
#sidenavMenu i {
margin: 1em 0;
margin-right: 0.5em;
}
#openseadragon {
position: relative;
}
#openseadragon-features {
pointer-events: none; /*feature overlay should NOT react to any events*/
z-index: 2;
}
#svg-overlay {
position: absolute;
z-index: 3;
}
#openseadragon .navigator {
z-index: 4;
}
#feature-opacity {
width: 100px;
}
#feature-opacity-label {
vertical-align: super;
font-size: smaller;
}
#image-list h2, #feature-list h2 {
margin-top: 0.5em;
}
ul#image-list-entries, ul#feature-list-entries {
list-style-type: none;
padding-left: 0em;
}
li a.active {
color: #D21038;
}
/* Annotation button */
#annotation-menu {
float: left;
margin-left: 0.1em;
line-height: 38px;
text-align: center;
}
#annotation-menu button {
font-size: larger;
}
/* Container for toolbars */
#toolbar-div {
z-index: 1;
margin: 0.5em 0em;
margin-bottom: 0.1em;
height: 38px;
}
/* Viewing tools */
#tools-viewer {
float: right;
height: 38px;
line-height: 37px;
margin-right: 0.5em;
}
#tools-viewer .fa {
font-size: 1.2em;
}
#tools-viewer .toolbar-button {
color: black;
padding: 0 0.25em;
display: inline-block;
position: relative;
}
/* Drawing tools */
#tools-drawing-container {
float: right;
margin-right: 0.5em;
display: none;
}
#tools-drawing {
float: right;
/*position: absolute;
border-right: none;
top:6px;
left: 0px;
padding-left: 2px;*/
/*background: #D0D0D0; /* Needed so flyout icons don't appear on the left */
z-index: 2;
}
#tools-drawing * {
box-sizing: content-box !important;
}
#tools-drawing .tool_button, #tools-drawing .tool_button_current {
display: inline-block;
}
/* Where the annotation is written */
#annotation-container {
display: none;
margin: 0.0em;
width: 100%;
}
#annotation-container .float {
float: left;
}
#annotation-text {
/*width:65%;*/
width: 100%;
}
#annotation-stats {
/*display:none;*/
}
#annotation-patch img {
max-width: 200px;
max-height: 200px;
}
/*.fancybox-slide--iframe .fancybox-content {
width : 800px;
height : 600px;
max-width : 80%;
max-height : 80%;
margin: 0;
}*/
#annotation-tooltip {
display: none;
position: absolute;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.7);
color: white;
padding: 0.5em 0.75em;
font-size: smaller;
border-radius: 8px;
z-index: 5;
}
#annotation {
margin-top: 0.25em;
width: 98%;
height: 3em;
resize: vertical;
font-family: Helvetica, Arial, sans-serif;
}
#normal {
padding: 0px;
/*margin: 9px 0px;
height: 20px;*/
}
-#annotation-type{
+#annotation-type, #download-annotations{
display: inline-block;
}
#annotation-type span{
line-height: 38px;
}
+#download-annotations{
+ line-height: 38px;
+ float: right;
+ margin-right: 1em;
+}
+
+#download-annotations img{
+ height: 24px;
+ margin-bottom: 4px;
+}
+
/* Color picker */
.simplecolorpicker.inline {
padding: 0px;
height: 38px;
}
.simplecolorpicker.inline .color {
margin: 0px;
margin-right: 5px;
margin-top: 8px;
}
/* SVG Editor */
/* Remove text underline in toolbar icons */
.tool_button:hover,
.push_button:hover,
.buttonup:hover,
.buttondown,
.tool_button_current,
.push_button_pressed {
/*background-color: #ffc !important;*/
border: 1px dashed black;
}
.tool_button_current,
.push_button_pressed,
.buttondown {
/*background-color: #f4e284 !important;*/
border: 1px solid black !important;
/*-webkit-box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4), 1px 1px 0 white !important;
-moz-box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4), 1px 1px 0 white !important;
box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4), 1px 1px 0 white !important;*/
}
.toolbar-button {
text-decoration: none !important;
}
.toolbar_button button {
border: 1px solid #dedede;
line-height: 130%;
float: left;
background: #E8E8E8 none;
padding: 5px 10px 5px 7px; /* Firefox */
line-height: 17px; /* Safari */
margin: 5px 20px 0 0;
border: 1px #808080 solid;
border-top-color: #FFF;
border-left-color: #FFF;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
.toolbar_button button:hover {
border: 1px #e0a874 solid;
border-top-color: #fcd9ba;
border-left-color: #fcd9ba;
background-color: #FFC;
}
.toolbar_button button:active {
background-color: #F4E284;
border-left: 1px solid #663300;
border-top: 1px solid #663300;
}
.toolbar_button button .svg_icon {
margin: 0 3px -3px 0 !important;
padding: 0;
border: none;
width: 16px;
height: 16px;
}
#tools_left .tool_button,
#tools_left .tool_button_current {
position: relative;
z-index: 11;
}
.tool_button,
.push_button,
.tool_button_current,
.push_button_pressed {
height: 24px;
width: 24px;
margin: 2px 2px 4px 2px;
padding: 3px;
/*-webkit-box-shadow: inset 1px 1px 2px white, 1px 1px 1px rgba(0,0,0,0.3);
moz-box-shadow: inset 1px 1px 2px white, 1px 1px 1px rgba(0,0,0,0.3);
box-shadow: inset 1px 1px 2px white, 1px 1px 1px rgba(0,0,0,0.3);*/
background-color: #fff;
border: 1px solid transparent;
cursor: pointer;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
#menu-top {
margin-bottom: 1em;
}
/* Generic context menu styles */
.contextMenu {
position: absolute;
z-index: 99999;
border: solid 1px rgba(0, 0, 0, .33);
background: rgba(255, 255, 255, .95);
padding: 5px 0;
margin: 0px;
/* ROGERMOD - fix contextmenu position */
margin-top: -58px;
margin-left: -10px;
display: none;
font: 12px/15px Lucida Sans, Helvetica, Verdana, sans-serif;
border-radius: 5px;
-moz-border-radius: 5px;
-moz-box-shadow: 2px 5px 10px rgba(0, 0, 0, .3);
-webkit-box-shadow: 2px 5px 10px rgba(0, 0, 0, .3);
box-shadow: 2px 5px 10px rgba(0, 0, 0, .3);
}
.contextMenu LI {
list-style: none;
padding: 0px;
margin: 0px;
}
.contextMenu .shortcut {
width: 115px;
text-align: right;
float: right;
}
.contextMenu A {
-moz-user-select: none;
-webkit-user-select: none;
color: #222;
text-decoration: none;
display: block;
line-height: 20px;
height: 20px;
background-position: 6px center;
background-repeat: no-repeat;
outline: none;
padding: 0px 15px 1px 20px;
}
.contextMenu LI.hover A {
background-color: #2e5dea;
color: white;
cursor: default;
}
.contextMenu LI.disabled A {
color: #999;
}
.contextMenu LI.hover.disabled A {
background-color: transparent;
}
.contextMenu LI.separator {
border-top: solid 1px #E3E3E3;
padding-top: 5px;
margin-top: 5px;
}
/* Sizing */
#openseadragon-container {
width: 100%;
height: 100%;
position: relative;
border: 1px solid transparent;
}
#openseadragon-container * {
outline: none;
}
#locks {
display: none;
}
#locks i {
position: absolute;
padding: 10px;
z-index: 100;
}
#tl-lock {
top: 0;
left: 0;
background-color: rgba(255, 255, 255, .5);
}
#tl-lock span {
font-family: Helvetica, Arial, sans-serif;
font-weight: bold;
padding-left: .5em;
}
#tr-lock {
top: 0;
right: 0;
}
#bl-lock {
bottom: 0;
left: 0;
}
#br-lock {
bottom: 0;
right: 0;
}
#openseadragon, #openseadragon-features {
position: absolute;
}
#openseadragon, #openseadragon-features, #workarea {
width: 100%;
height: 100%;
}
#svg-overlay, #svg_editor, #svgcanvas, #svgroot {
width: 100%;
height: 100%;
}
#svg-overlay {
}
#svgcanvas {
}
#svgroot {
display: inline-block;
position: absolute;
}
#selectorGrip_rotate, #selectorGrip_rotateconnector {
display: none;
}
/* The side navigation menu */
.sidenav {
height: 100%; /* 100% Full-height */
width: 0; /* 0 width - change this with JavaScript */
position: fixed; /* Stay in place */
z-index: 10; /* Stay on top */
top: 0;
right: 0;
background-color: rgba(255, 255, 255, 0.95); /* Black*/
border-left: 1px solid grey;
overflow-x: hidden; /* Disable horizontal scroll */
transition: 0.5s; /* 0.5 second transition effect to slide in the sidenav */
}
.sidenav .ui-state-focus {
outline: none;
}
.sidenav h3 {
font-size: medium;
cursor: pointer;
}
.sidenav .ui-accordion-content {
max-height: 650px;
}
/* The navigation menu links */
.sidenav a {
text-decoration: none;
color: #818181;
display: block;
transition: 0.3s
}
/* When you mouse over the navigation links, change their color */
.sidenav a:hover, .offcanvas a:focus {
color: #0E0E0E;
}
/* Position and style the close button (top right corner) */
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
/* Little search result */
.little-result {
max-height: 85px !important;
max-width: 85px !important;
margin: 3px !important;
cursor: pointer;
}
.unselectable {
pointer-events: none;
-webkit-user-select: none; /* Chrome/Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+ */
/* Rules below not implemented in browsers yet */
-o-user-select: none;
user-select: none;
cursor: default;
}
.no-cursor {
pointer-events: none;
}
/* Style page content - use this if you want to push the page content to the right when you open the side navigation */
/*#maincontainer {
transition: margin-left .5s;
padding: 20px;
}*/
/* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */
@media screen and (max-height: 450px) {
.sidenav {
padding-top: 15px;
}
.sidenav a {
font-size: 18px;
}
}
diff --git a/desuto-viewer/Desuto-webviewer/views/viewer.pug b/desuto-viewer/Desuto-webviewer/views/viewer.pug
index ef148c0..b07c3a9 100644
--- a/desuto-viewer/Desuto-webviewer/views/viewer.pug
+++ b/desuto-viewer/Desuto-webviewer/views/viewer.pug
@@ -1,378 +1,389 @@
-- var admin = 'pathologists'
-- var regions = 'regions'
+- var pathologist = 'pathologists'
+- var annotationadmin = 'annotationadmins'
doctype html
html
head
title #{title}
link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css')
link(rel='stylesheet', href='stylesheets/jquery.fancybox.min.css')
link(rel='stylesheet', href='//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css')
// Latest compiled and minified CSS
link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u', crossorigin='anonymous')
// Optional theme
link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css', integrity='sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp', crossorigin='anonymous')
- if !roles || roles.indexOf(admin) > -1
+ if !roles || roles.indexOf(pathologist) > -1
link(rel='stylesheet', href='stylesheets/jquery.simplecolorpicker.css')
link(rel='stylesheet', href='stylesheets/jquery.simplecolorpicker-fontawesome.css')
link(rel='stylesheet', href='stylesheets/theme.css')
body
nav.navbar.navbar-default
.container-fluid
.navbar-header
button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#navbar', aria-expanded='false', aria-controls='navbar')
span.sr-only Toggle navigation
span.icon-bar
span.icon-bar
span.icon-bar
a.navbar-brand(href='#') Desuto
#navbar.collapse.navbar-collapse
ul.nav.navbar-nav
li.active
a(href='#') Home
li
a(href='#about') About
- if !roles || roles.indexOf(admin) > -1
+ if !roles || roles.indexOf(pathologist) > -1
li
a(href='/upload') Upload new images
ul.nav.navbar-nav.navbar-right
li.dropdown
a.dropdown-toggle(href='#', data-toggle='dropdown', role='button', aria-haspopup='true', aria-expanded='false')
| #{user}
span.caret
ul.dropdown-menu
// Footer
#footer
span Logged in as a&nbsp;
- if roles.indexOf(admin) > -1
+ if roles.indexOf(pathologist) > -1
strong pathologist (#{user})
else
strong user (#{user})
| :
a(href='/logout') logout
li
a(href='/logout') Logout
// /.nav-collapse
canvas#papercanvas(style='position:absolute; visibility:hidden')
#maincontainer.container-fluid
// Content container
#container
#left
// Navbar (top)
#menu-top
// Toolbar
#toolbar-div
// Pathologists only !
- if !roles || roles.indexOf(admin) > -1
+ if roles.indexOf(pathologist) > -1
// Drawing tools wrapper
#tools-drawing-container
- #annotation-type
- span.title Draw
- if !roles || roles.indexOf(regions) > -1
- select#normal(name='normal')
- optgroup(label='Regions')
- option(value='Green', style='background: #229922; color: #FFF;') Ra. Normal
- option(value='Blue', style='background: #222299; color: #FFF;') Rb. Susp. Gleason 3
- option(value='Red', style='background: #992222; color: #FFF;') Rc. Susp. Gleason 3-4
- option(value='Red', style='background: #992222; color: #FFF;') Rd. Susp. Gleason 4
- option(value='Black', style='background: #222222; color: #FFF;') Re. Susp. Gleason 4-5
- option(value='Black', style='background: #222222; color: #FFF;') Rf. Susp. Gleason 5
- else
- select#normal(name='normal')
- optgroup(label='1. Normal')
- option(value='Green') 1a. Healthy glands
- option(value='Green') 1b. Basal cells
- option(value='Green') 1c. Bening glands, athropy
- option(value='Green') 1d. Bening glands (smaller than normal)
- option(value='Other') e. Other
- optgroup(label='2. Atypical, benign (but maybe suspicious)')
- option(value='Yellow') 2a. Atypical
- option(value='Yellow') 2b. PIN
- option(value='Yellow') 2c. Other
- optgroup(label='3. Gleason pattern 3')
- option(value='Blue') 3a. “classic”
- option(value='Blue') 3b. “invasive - infiltrating non-neoplastic tissue”
- option(value='Blue') 3c. “mucinous lakes”
- option(value='Blue') 3d. Other (to be specified in text)
- optgroup(label='4. Gleason pattern 4')
- option(value='Red') 4a. “classic"
- option(value='Red') 4b. “cribriform”
- option(value='Red') 4c. “prostatic ductal adenocarcinoma“
- option(value='Red') 4d. “hypernephromatiod”
- option(value='Red') 4e. “invasive - infiltrating non-neoplastic tissue”
- option(value='Red') 4f. “mucinous lakes”
- option(value='Red') 4g. Other (to be specified in text)
- optgroup(label='5. Gleason pattern 5')
- option(value='Black') 5a. “classic” (Signet ring-cell like)
- option(value='Black') 5b. “cribriform with central necrosis”
- option(value='Black') 5c. Other (to be specified in text)
- optgroup(label='6. Other type of carcinoma')
- option(value='Purple') 6a. Neuroendocrine cells (eosinophilic granules)
- option(value='Purple') 6b. Small cell carcinoma of prostate (Does NOT assign Gleason grade)
- optgroup(label='7. Normal other structures')
- option(value='Purple') 7a. Necrosis
- option(value='Purple') 7b. Stroma
- option(value='Purple') 7c. Inflammatory cells, lymphocytes
- option(value='Purple') 7d. Inflammatory cells, neutrophils
- option(value='Purple') 7e. Vessel
- option(value='Purple') 7f. Nerves
- option(value='Purple') 7g. Fat
- option(value='Purple') 7h. Folding artefact
- option(value='Purple') 7i. Scanning artefact
- option(value='Purple') 7j. Other (to be specified in text)
+ if roles.indexOf(annotationadmin) === -1
+ #annotation-type
+ span.title Draw
+ select#normal(name='normal')
+ optgroup(label='Regions')
+ option(value='Green', style='background: #229922; color: #FFF;') Ra. Normal
+ option(value='Blue', style='background: #222299; color: #FFF;') Rb. Susp. Gleason 3
+ option(value='Red', style='background: #992222; color: #FFF;') Rc. Susp. Gleason 3-4
+ option(value='Red', style='background: #992222; color: #FFF;') Rd. Susp. Gleason 4
+ option(value='Black', style='background: #222222; color: #FFF;') Re. Susp. Gleason 4-5
+ option(value='Black', style='background: #222222; color: #FFF;') Rf. Susp. Gleason 5
+ //
+ select#normal(name='normal')
+ optgroup(label='1. Normal')
+ option(value='Green') 1a. Healthy glands
+ option(value='Green') 1b. Basal cells
+ option(value='Green') 1c. Bening glands, athropy
+ option(value='Green') 1d. Bening glands (smaller than normal)
+ option(value='Other') e. Other
+ optgroup(label='2. Atypical, benign (but maybe suspicious)')
+ option(value='Yellow') 2a. Atypical
+ option(value='Yellow') 2b. PIN
+ option(value='Yellow') 2c. Other
+ optgroup(label='3. Gleason pattern 3')
+ option(value='Blue') 3a. “classic”
+ option(value='Blue') 3b. “invasive - infiltrating non-neoplastic tissue”
+ option(value='Blue') 3c. “mucinous lakes”
+ option(value='Blue') 3d. Other (to be specified in text)
+ optgroup(label='4. Gleason pattern 4')
+ option(value='Red') 4a. “classic"
+ option(value='Red') 4b. “cribriform”
+ option(value='Red') 4c. “prostatic ductal adenocarcinoma“
+ option(value='Red') 4d. “hypernephromatiod”
+ option(value='Red') 4e. “invasive - infiltrating non-neoplastic tissue”
+ option(value='Red') 4f. “mucinous lakes”
+ option(value='Red') 4g. Other (to be specified in text)
+ optgroup(label='5. Gleason pattern 5')
+ option(value='Black') 5a. “classic” (Signet ring-cell like)
+ option(value='Black') 5b. “cribriform with central necrosis”
+ option(value='Black') 5c. Other (to be specified in text)
+ optgroup(label='6. Other type of carcinoma')
+ option(value='Purple') 6a. Neuroendocrine cells (eosinophilic granules)
+ option(value='Purple') 6b. Small cell carcinoma of prostate (Does NOT assign Gleason grade)
+ optgroup(label='7. Normal other structures')
+ option(value='Purple') 7a. Necrosis
+ option(value='Purple') 7b. Stroma
+ option(value='Purple') 7c. Inflammatory cells, lymphocytes
+ option(value='Purple') 7d. Inflammatory cells, neutrophils
+ option(value='Purple') 7e. Vessel
+ option(value='Purple') 7f. Nerves
+ option(value='Purple') 7g. Fat
+ option(value='Purple') 7h. Folding artefact
+ option(value='Purple') 7i. Scanning artefact
+ option(value='Purple') 7j. Other (to be specified in text)
// Tools for drawing
#tools-drawing
// <div class="tool_button" id="tool_save" title="Save Tool"></div>
#tool_select.tool_button(title='Select Tool')
- #tool_line.tool_button(title='Line Tool')
- #tool_rect.tool_button(title='Rectangle Tool')
- #tool_ellipse.tool_button(title='Ellipse Tool')
- #tool_fhpath.tool_button(title='Pencil Tool')
+ //#tool_line.tool_button(title='Line Tool')
+ #tool_point.tool_button(title='Point Tool')
+ if roles.indexOf(annotationadmin) > -1
+ #tool_rect.tool_button(title='Rectangle Tool')
+ //#tool_ellipse.tool_button(title='Ellipse Tool')
+ if roles.indexOf(annotationadmin) === -1
+ #tool_fhpath.tool_button(title='Pencil Tool')
// Annotation button
#annotation-menu
button.btn.btn-primary#toggle-annotation(title='Press (ESC) to toggle mode') Start Annotating
#sync
i.fa.fa-spin.fa-refresh
//span &nbsp; Syncing DB...
// Tools for the viewer
#tools-viewer
span View
a#zoom-in.toolbar-button(href='#zoom-in', title='Zoom In')
i.fa.fa-search-plus
a#zoom-out.toolbar-button(href='#zoom-out', title='Zoom Out')
i.fa.fa-search-minus
a#home.toolbar-button(href='#home', title='Home')
i.fa.fa-home
a#zoom-1x.toolbar-button(href='#zoom-5x', title='Zoom to 5 times')
span
strong 1
small x
a#zoom-5x.toolbar-button(href='#zoom-5x', title='Zoom to 5 times')
span
strong 5
small x
a#zoom-10x.toolbar-button(href='#zoom-10x', title='Zoom to 10 times')
span
strong 10
small x
a#zoom-20x.toolbar-button(href='#zoom-20x', title='Zoom to 20 times')
span
strong 20
small x
a#zoom-40x.toolbar-button(href='#zoom-40x', title='Zoom to 40 times')
span
strong 40
small x
+ // Download annotations button
+ if roles.indexOf(annotationadmin) > -1
+ #download-annotations
+ a(href='#')
+ img(src='img/download.png',title='Download Annotations')
// Clear floats
// <div class="clear"></div>
#openseadragon-container
#locks.unselectable
i#tl-lock.fa.fa-lock
span Annotation mode - View locked
i#tr-lock.fa.fa-lock
i#bl-lock.fa.fa-lock
i#br-lock.fa.fa-lock
// OpenSeadragon
#openseadragon
// OpenSeadragon (features)
#openseadragon-features
// SVG-Edit
// Is inserted dynamically via JS now
// Context menu
ul#cmenu_canvas.contextMenu
li
a(href='#cut') Cut
li
a(href='#copy') Copy
li
a(href='#paste') Paste
li
a(href='#paste_in_place') Paste in Place
li.separator
a(href='#delete') Delete
// Current annotation details
#annotation-details
// Annotations container (temporary solution)
#annotation-container
#annotation-text.float
p
strong Annotation description text
textarea#annotation(placeholder='Enter annotation here')
#annotation-stats.float
p
strong Characteristics
div
#annotation-patch.float
p
strong Selected area
img#patch-preview(src='https://placehold.it/200?text=Preview')
// Annotations tooltip
#annotation-tooltip
div Annotation placeholder
// Use any element to open the sidenav
#sidenavMenu
div(onclick='openNav("imagesSidenav")')
i.fa.fa-image
span Images
div(onclick='openNav("featuresSidenav")')
i.fa.fa-bar-chart
span Features
#imagesSidenav.sidenav
a.closebtn(href='javascript:void(0)', onclick='closeNav("imagesSidenav")') ×
// Image List
#image-list
h2 Images
#imagesets
if images && imagesets
each imageset in imagesets
h3= imageset
div
ul#image-list-entries
each image, index in images[imageset]
li
a.image-link(href='?image=' + image) #{image.substr(image.indexOf('/') + 1)}
#featuresSidenav.sidenav
a.closebtn(href='javascript:void(0)', onclick='closeNav("featuresSidenav")') ×
// Feature List
#feature-list
h2 Features
p Feature opacity
input#feature-opacity(type='range', min='0', max='100', step='1')
label#feature-opacity-label(for='feature-opacity') --%
p Feature list
ul#feature-list-entries
li
a.feature-link.active(href='#none') none
if features
each feature in features
li
a.feature-link(href='#' + feature) #{feature}
// ********************
// Javascript libraries
// ********************
// Values from server
script
| annotator = '#{user}';
- | defaultImage = 'ALABplus4M.tif';
+ | defaultImage = 'contextvision/401.tif';
// Configuration (modifiable)
script(src='js/config/config.js')
// jQuery
script(src='//code.jquery.com/jquery-2.1.3.js')
// jQuery UI
script(src='//code.jquery.com/ui/1.12.1/jquery-ui.min.js')
// Paper.js
script(src='js/paper-full.min.js')
// Snap.SVG
script(src='js/snap.svg-min.js')
+ // FileSaver.js
+ script(src='js/FileSaver.js')
+
// Polyfills
script(src='js/polyfills/pathseg.js')
// PouchDB
- script(src='js/pouchdb/pouchdb-6.2.0.min.js')
+ script(src='js/pouchdb/pouchdb-7.1.1.min.js')
script(src='js/pouchdb/pouchdb.find.min.js')
script(src='js/pouchdb/pouchdb.authentication.js')
// Set up DB
script(src='js/db.js')
// OpenSeadragon lib
script(src='js/openseadragon/openseadragon.js')
script(src='js/openseadragon/openseadragon-svg-overlay.js')
script(src='js/openseadragon/openseadragon-scalebar.js')
script(src='js/openseadragon/openseadragon-viewerinputhook.js')
script(src='js/openseadragon/openseadragon-imaginghelper.js')
// underscore.js
script(src='//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js')
// qTip
script(src='//cdn.jsdelivr.net/qtip2/2.2.1/jquery.qtip.js')
// Bootstrap
script(src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js', integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa', crossorigin='anonymous')
////////////////////
// jQuery Plugins //
////////////////////
// Fancybox
script(src='js/jquery.fancybox.min.js')
// Hotkeys
script(src='js/jquery-plugins/jquery.hotkeys.min.js')
// Load SVG icons from a single file
script(src='js/jquery-plugins/jquery.svgicons.js')
// jQuery SVG manipulation
script(src='js/jquery-plugins/jquery-svg.js')
// Context menu
script(src='js/jquery-plugins/jquery.contextMenu.js')
// Throttle / Debounce
script(src='js/jquery-plugins/jquery.ba-throttle-debounce.min.js')
// CouchDB
script(src='js/jquery-plugins/jquery.couch.js')
// Utils
script(src='js/utils.js')
////////////////////
// SVG-Edit //
////////////////////
// Globals
script(src='js/svg-edit/svgedit.js')
// Browser support check
script(src='js/svg-edit/browser.js')
// Units
script(src='js/svg-edit/units.js')
// SVG transformations
script(src='js/svg-edit/svgtransformlist.js')
// SVG Utils
script(src='js/svg-edit/svgutils.js')
// Pathologists only !
- if !roles || roles.indexOf(admin) > -1
+ if !roles || roles.indexOf(pathologist) > -1
// Math functions
script(src='js/svg-edit/math.js')
// Color picker
script(src='js/jquery-plugins/jquery.simplecolorpicker.js')
// Manage history
script(src='js/svg-edit/history.js')
// Coordinates system
script(src='js/svg-edit/coords.js')
// Recalculate (not sure)
script(src='js/svg-edit/recalculate.js')
// Selection of objects
script(src='js/svg-edit/select.js')
// Drawing
script(src='js/svg-edit/draw.js')
// Path definition
script(src='js/svg-edit/path.js')
// Touch events
script(src='js/svg-edit/touch.js')
// Sanitize SVG code
script(src='js/svg-edit/sanitize.js')
// SVG Canvas manipulation
script(src='js/svg-edit/svgcanvas.js')
// Main code and JS files depening on it //
// Main editor code
script(src='js/svg-editor.js')
//If you do not wish to add extensions by URL, you can load them
//by creating the following file and adding by calls to svgEditor.setConfig
script(src='js/svg-edit/config.js')
// Locale
script(src='js/svg-edit/locale/locale.js')
// Context menu
script(src='js/svg-edit/contextmenu.js')
// Main app
script(src='js/app-main.js')

Event Timeline