diff --git a/.meteor/packages b/.meteor/packages index da820fd..a7c0206 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -33,8 +33,8 @@ arillo:flow-router-helpers # Provides various template helpers such as {{pathFo #tomwasd:flow-router-seo kadira:blaze-layout -shell-server@0.4.0 # ??? -meteortoys:allthings +#shell-server@0.4.0 # ??? +#meteortoys:allthings stylus@2.513.13 session@1.2.0 ##browser-policy # Adds support for specifying browser level security rules related to content and what's allowed to laod on the page. @@ -55,7 +55,7 @@ aldeed:collection2 #twbs:bootstrap # Requires jquery 1.9-2.x, not 3+ fortawesome:fontawesome momentjs:moment -mizzao:bootboxjs # ??? +#mizzao:bootboxjs # ??? aldeed:template-extension juliancwirko:s-alert # Client error/alert handling jcbernack:reactive-aggregate # Allows us to create a new client collection (from the server) with the contents being an aggregate of server data. Note that aggregation can only be done on the server currently as mini-mongo does not support it. @@ -66,3 +66,4 @@ markdown@1.0.12 wcrisman:jquery-custom-scrollbar underscore@1.0.10 meteorhacks:aggregate # Allows databaseName.aggragate(pipeline) calls the exact same way you would on the command line in the mongo tool. +babrahams:constellation diff --git a/.meteor/versions b/.meteor/versions index 424b559..ccce0d4 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -12,6 +12,9 @@ arillo:flow-router-helpers@0.5.2 autoupdate@1.6.0 babel-compiler@7.3.4 babel-runtime@1.3.0 +babrahams:constellation@0.4.10 +babrahams:editable-json@0.6.5 +babrahams:temple@0.4.7 base64@1.0.12 binary-heap@1.0.11 blaze@2.3.3 @@ -23,6 +26,14 @@ caching-html-compiler@1.1.3 callback-hook@1.1.0 check@1.3.1 coffeescript@1.0.17 +constellation:autopublish@0.4.7 +constellation:console@1.4.7 +constellation:plugins@0.4.9 +constellation:position@0.4.7 +constellation:session@0.4.7 +constellation:subscriptions@0.4.7 +constellation:tiny@0.4.7 +dburles:mongo-collection-instances@0.3.5 ddp@1.4.0 ddp-client@2.3.3 ddp-common@1.4.0 @@ -41,6 +52,8 @@ es5-shim@4.8.0 fetch@0.1.1 fortawesome:fontawesome@4.7.0 geojson-utils@1.0.10 +gwendall:body-events@0.1.6 +gwendall:session-json@0.1.7 hot-code-push@1.0.4 html-tools@1.0.11 htmljs@1.0.11 @@ -52,6 +65,7 @@ jquery@1.11.11 juliancwirko:s-alert@3.2.0 kadira:blaze-layout@2.3.0 kadira:flow-router@2.12.1 +lai:collection-extensions@0.2.1_1 launch-screen@1.1.1 livedata@1.0.18 localstorage@1.2.0 @@ -62,27 +76,9 @@ meteor@1.9.3 meteor-base@1.4.0 meteorhacks:aggregate@1.3.0 meteorhacks:collection-utils@1.2.0 -meteortoys:allthings@4.0.0 -meteortoys:authenticate@4.0.0 -meteortoys:autopub@4.0.0 -meteortoys:blueprint@4.0.0 -meteortoys:email@4.0.0 -meteortoys:hotreload@4.0.0 -meteortoys:listen@4.0.0 -meteortoys:method@4.0.0 -meteortoys:mobile@4.0.0 -meteortoys:pub@4.0.0 -meteortoys:result@4.0.0 -meteortoys:shell@4.0.0 -meteortoys:status@4.0.0 -meteortoys:sub@4.0.0 -meteortoys:throttle@4.0.0 -meteortoys:toggle@4.0.0 -meteortoys:toykit@4.0.2 minifier-css@1.4.2 minifier-js@2.4.1 minimongo@1.4.5 -mizzao:bootboxjs@4.4.0 mobile-experience@1.0.5 mobile-status-bar@1.0.14 modern-browsers@0.1.4 @@ -94,8 +90,6 @@ mongo-decimal@0.1.1 mongo-dev-server@1.1.0 mongo-id@1.0.7 mongo-livedata@1.0.12 -msavin:jetsetter@4.0.0 -msavin:mongol@4.0.1 npm-bcrypt@0.9.3 npm-mongo@3.1.2 observe-sequence@1.0.16 @@ -115,7 +109,6 @@ routepolicy@1.1.0 service-configuration@1.0.11 session@1.2.0 sha@1.0.9 -shell-server@0.4.0 socket-stream-client@0.2.2 softwarerero:accounts-t9n@1.3.11 spacebars@1.0.15 diff --git a/README.md b/README.md index 6d2f85f..525d0f5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,22 @@ -# Petit Teton Data Management Application (PTApp) +# Current Configuration + +See below for initial setup and updating instructions. + +Currently we have three servers in two locations. Media and FS2 are computers residing on the 18501 property (big barn back top room, and Wynne/Sarah house), and FS1 is a computer residing in SF. All three are accessible via Putty (a windows SSH client - any SSH client will work) via the IP's 192.168.3.101 (Media), 192.168.2.239 (FS1), and 192.168.3.164 (FS2). Note that FS1 is in SF, but is accessible via the LAN because we have a VPN setup between our routers (192.168.3.1, and 192.168.2.1). The VPN makes them look like they are on the same network. + +If you SSH (Putty) into each server you can update the server using APT (`sudo apt update`, followed by `update apt upgrade`), reboot `sudo shutdown -r now`, and perform other maintenance routines. + +**Currently** Media is the primary server for the PTApp (the Meteor Petit Teton Webapp - versus the Petit Teton web site which is a customer focused informational web site). FS2 is the primary server for all other web sites and web apps and it clones its SSL certifications and www folders to the other two machines. Ultimately the PTApp will need to also be on FS2 primarily along with SSL certificates and an Nginx configuration that only allows certain access outside our LAN (for sales interaction at markets and Cam's home access). The database (MongoDB) is installed on all three machines, forming a cluster such that data written to any of the three is propagated to the other two automatically. + +Database backups are not trivial due to the cluster system. Essentially we are doing a simple backup/restore and ignoring the possibility that the database we take from might not have all the latest updates. Doing this on our primary server (FS2) helps ensure that we don't have any problems. MongoDB being a very flexible database and our app not caring too much about data integrity helps as well. + +TODO: Linux update procedure. + +TODO: Backup procedure. + +TODO: Mongo update procedure. + +# Setup Petit Teton Data Management Application (PTApp) This application is designed to track sales and production data. @@ -27,21 +45,22 @@ Package this application by running 'npm run build' from the command line in the 4. Modify the system to always start Mongod: `sudo systemctl enable mongod` 10. Run tools: (see [descriptions](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/#packages)) - mongod (the mongo database server) - - mongo (command line shell for interacting with a running db) - - mongoimport (imports data from: Extended JSON, CSV, or TSV formats created by mongoexport or 3rd party tools) - - bsondump (converts bson file formats [binary] into human readable formats [JSON] - use with mongodump files) - - mongodump (produces binary output for backups - not for use with shared clusters and replica sets) - - mongoexport (produces JSON or CSV data) - - mongofiles (command line gridfs integration - for manipulating files) - - mongooplog (replication & polling - ?) - - mongoperf - - mongorestore - - mongostat - - mongotop (stats) + - mongo (command line shell for interacting with a running db) + - mongoimport (imports data from: Extended JSON, CSV, or TSV formats created by mongoexport or 3rd party tools) + - bsondump (converts bson file formats [binary] into human readable formats [JSON] - use with mongodump files) + - mongodump (produces binary output for backups - not for use with shared clusters and replica sets) + - mongoexport (produces JSON or CSV data) + - mongofiles (command line gridfs integration - for manipulating files) + - mongooplog (replication & polling - ?) + - mongoperf + - mongorestore + - mongostat + - mongotop (stats) 11. Install nodejs & npm 1. `sudo apt-get install nodejs` 2. `sudo apt-get install npm` 12. Install n + 1. `sudo npm install -g n` 13. Update nodejs to 4.7.0 (for use with meteor 1.4 - may be another nodejs version for newer meteor versions): `n bin 4.7.0` (may need to first download 4.7.0 - see other docs on linux & nodejs) 1. `sudo n 4.7.0` @@ -93,11 +112,12 @@ Package this application by running 'npm run build' from the command line in the NOTE: Use MongoBooster on a windows development machine to connect to the dev database (localhost:3001) and to export. -#Updating a Meteor Deployment +# Updating a Meteor Deployment (OLD) + 1. Run the NPM script for building the app. This can be done either from Webstorm by viewing the NPM display (shows a list of scripts in the package.json file), or typing `npm run build` from the command line. Alternatively you can simply type the build command in the command line: `meteor build --server-only ../` to build it. The command should exit with code zero for success. 2. Find the archive file: it should be in the parent directory if you ran the above script exactly, otherwise it is where ever you specified (path at the end of the command). It should be called "PetitTetonMeteor.tar.gz" as of the writing of this documentation. -3. Copy the archive to the server. Use what ever tools you want for this, samba and drag and drop works great. Otherwise sftp, or other method also works. -4. Navigate to /var/www/PTApp (or what ever the folder is). +3. Copy the archive to the server (**currently** Media/www/PTApp). Use what ever tools you want for this, samba and drag and drop works great. Otherwise sftp, or other method also works. +4. Navigate to /var/www/PTApp (or what ever the folder is). `cd /var/www/PTApp` 5. Use `sudo tar -xvzf PetitTetonMeteor.tar.gz` to unpack it. 6. Delete the archive (optional): `sudo rm PetitTetonMeteor.tar.gz` 7. Modify the owner of the app: `sudo chown -R www-data bundle` Run this from inside the project directory /var/www/PTApp. @@ -105,23 +125,27 @@ NOTE: Use MongoBooster on a windows development machine to connect to the dev da 9. Optional: Run NPM's install to update the dependancies (if they changed): `cd /var/www/PTApp/bundle/programs/server && npm install && cd /var/www/PTApp` 10. Restart the meteor app: `sudo passenger-config restart-app /var/www/PTApp` -# Updating a Meteor Deployment #2 +# Updating a Meteor Deployment (NEW) 1. Run the NPM script for building the app `npm run build` which will package the app for the selected platform (in the package.json definition for the build script). Can double click the build script in WebStorm's UI for NPM alternatively. Can also manually run the script: `npm install --product && meteor build --architecture os.linux.x86_64 --server-only ../`. This will generate an archive file for the project that is production ready. -2. Copy the archive to the deployment server. Can use Samba for this. I place it in the web folder for the app. +2. Copy the archive to the deployment server (**currently** Media/www/PTApp). Can use Samba for this. I place it in the web folder for the app. 3. Run the deploy.sh script `sudo ./deploy.sh` which exists in the web directory for the app: `/var/www/PTApp`. This will unpack the archive, remove the archive, change file permissions, run NPM's install on the app, and restart the app in Phusion Passenger. 4. Look at the debug output by viewing the html files stored in `/tmp`. Use Samba to view them remotely. 5. Look at the Nginx logs (should be the same as the stuff in /tmp). # Updating a Meteor Deployment *with* a NodeJS and Meteor version change. +Check which version of meteor you have on the development machine (meteor is not installed ever on the production machine). If the version has changed, it may require a newer version of NodeJS. You have to read the Meteor notes for your version (or older versions) to figure out which NodeJS is required. + 1. Update the meteor app as normal (copy it to the /var/www/xxx directory as a build bundle, then run the script to unpack it). 2. Run `sudo n` to get the current version of NodeJS being used. Use `sudo n x.x.x` to download and change to the new version of NodeJS. 3. Edit the app's nginx file in /etc/nginx/sites-available/ to reference the new NodeJS install location. For example my current install location is specified as `server {... passenger_nodejs /usr/local/n/versions/node/8.9.3/bin/node ...}`} +## Running Server Side Code -#Running Server Side Code This is useful for importing data or running scripts that might perform some one time task. + 1. Open a console and enter the server shell for meteor. -#Server Error Handling +## Server Error Handling + Errors are generated in meteor, but handled by passenger. Passenger will log the error on the client screen with a code, and will log the same message in the nginx error logs. The error will be findable in the tmp folder as an html file starting with passenger and ending with the code. This is the place to look for the real error output. \ No newline at end of file diff --git a/client/client.js b/client/client.js index b6c437b..5f413b9 100644 --- a/client/client.js +++ b/client/client.js @@ -14,6 +14,7 @@ import '/imports/util/resize/ResizeSensor.js'; import '/imports/util/resize/ElementQueries.js'; import '/imports/ui/layouts/Body.js'; import '/imports/ui/layouts/Login.js'; +import '/imports/ui/layouts/Empty.js'; import '/imports/ui/accounts/accounts.js'; import '/imports/util/select2/select2.css'; import '/imports/util/select2/select2.full.js'; diff --git a/client/head.html b/client/head.html index cc91107..18e3b3f 100644 --- a/client/head.html +++ b/client/head.html @@ -1,5 +1,6 @@ PT App + diff --git a/client/main.css b/client/main.css new file mode 100644 index 0000000..0931f75 --- /dev/null +++ b/client/main.css @@ -0,0 +1,4195 @@ +* { + -webkit-tap-highlight-color: transparent; + -webkit-font-smoothing: antialiased; +} +*, +*:after, +*:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; + margin: 0; +} +html { + scrollbar-face-color: #808080; + scrollbar-highlight-color: #808080; + scrollbar-3dlight-color: #707070; + scrollbar-darkshadow-color: #808080; + scrollbar-shadow-color: #7e7e7e; + scrollbar-arrow-color: #fff; + scrollbar-track-color: #505050; + height: 100%; + min-height: 100%; +} +body { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 12px; + height: 100%; + min-height: 100%; +} +#__blaze-root { + height: 100%; +} +.noselect { + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Chrome/Safari/Opera */ + -khtml-user-select: none; /* Konqueror */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently not supported by any browser */ +} +.clickable { + cursor: pointer; +} +.nonclickable { + cursor: default; +} +.left { + text-align: left; +} +.right { + text-align: right; +} +.center { + text-align: center; +} +.floatLeft { + float: left; +} +.floatRight { + float: right; +} +.table { + padding: 0; + margin: 0; + border-collapse: collapse; + border: 1px solid #ddddf9; +} +.table > thead > tr > th { + border: 0; + padding: 4px 4px 8px 4px; + vertical-align: top; + color: #fff; + background: #6f6fec; +} +.table > thead > tr > th input { + padding: 2px; + border-radius: 3px; +} +.table > tbody > tr { + border-bottom: 1px solid #aaa; +} +.table > tbody > tr > td { + padding: 4px 4px; +} +.table > tbody > tr.selected { + background-attachment: fixed; + background-repeat: no-repeat; + background-position: 0 0; + background-image: linear-gradient(to left, #e0dcba 70%, #f1da36 100%); +} +.table > tbody > tr:nth-child(odd).selected { + background-attachment: fixed; + background-repeat: no-repeat; + background-position: 0 0; + background-image: linear-gradient(to left, #fcf8d1 70%, #f1da36 100%); +} +.table-striped > tbody > tr:nth-child(even) { + background-color: #f4f4f4; +} +.table-striped > tbody > tr:nth-child(odd) { + background-color: #fff; +} +.table-hover > tbody > tr:hover { + background-color: #ded; +} +.pagination { + text-align: right; + font-size: 15px; + line-height: 34px; + font-family: "Arial Black", "Arial Bold", Gadget, sans-serif; + margin: 0 0 10px 0; + overflow: visible; + white-space: nowrap; + display: inline-block; +} +.pagination span { + padding: 2px 8px 3px 8px; + margin: 0 8px; + border: 2px solid #7b9961; + border-radius: 5px; + background-color: #90b272; + cursor: pointer; + overflow: visible; + whitespace: nowrap; +} +.pagination span:hover { + background-color: #4ca84c; +} +.pagination span:active { + background-color: #3c983c; +} +.pagination span.disabled { + background-color: #ccc; + border-color: #c5c5c5; + color: #fff; + cursor: default; +} +.pagination span.disabled:hover { + background-color: #ccc; +} +.pagination span.disabled:active { + background-color: #ccc; +} +.grid { + overflow: visible !important; + max-width: none !important; +} +.mCSB_1_scrollbar { + z-index: 999; +} +@-webkit-keyframes neon6 { + from { + text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + to { + text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; + } +} +@-moz-keyframes neon6 { + from { + text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + to { + text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; + } +} +@-webkit-keyframes neon7 { + from { + text-shadow: 0 0 10px #bbb, 0 0 20px #bbb, 0 0 30px #bbb, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + to { + text-shadow: 0 0 5px #bbb, 0 0 10px #bbb, 0 0 15px #bbb, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; + } +} +@-moz-keyframes neon7 { + from { + text-shadow: 0 0 10px #bbb, 0 0 20px #bbb, 0 0 30px #bbb, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + to { + text-shadow: 0 0 5px #bbb, 0 0 10px #bbb, 0 0 15px #bbb, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; + } +} +@-moz-keyframes neon6 { + from { + text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + to { + text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; + } +} +@-webkit-keyframes neon6 { + from { + text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + to { + text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; + } +} +@-o-keyframes neon6 { + from { + text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + to { + text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; + } +} +@keyframes neon6 { + from { + text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + to { + text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; + } +} +@-moz-keyframes neon7 { + from { + text-shadow: 0 0 10px #bbb, 0 0 20px #bbb, 0 0 30px #bbb, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + to { + text-shadow: 0 0 5px #bbb, 0 0 10px #bbb, 0 0 15px #bbb, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; + } +} +@-webkit-keyframes neon7 { + from { + text-shadow: 0 0 10px #bbb, 0 0 20px #bbb, 0 0 30px #bbb, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + to { + text-shadow: 0 0 5px #bbb, 0 0 10px #bbb, 0 0 15px #bbb, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; + } +} +@-o-keyframes neon7 { + from { + text-shadow: 0 0 10px #bbb, 0 0 20px #bbb, 0 0 30px #bbb, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + to { + text-shadow: 0 0 5px #bbb, 0 0 10px #bbb, 0 0 15px #bbb, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; + } +} +@keyframes neon7 { + from { + text-shadow: 0 0 10px #bbb, 0 0 20px #bbb, 0 0 30px #bbb, 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de, 0 0 150px #ff00de; + } + to { + text-shadow: 0 0 5px #bbb, 0 0 10px #bbb, 0 0 15px #bbb, 0 0 20px #ff00de, 0 0 35px #ff00de, 0 0 40px #ff00de, 0 0 50px #ff00de, 0 0 75px #ff00de; + } +} +@-moz-keyframes neon6_drop { + from { + filter: drop-shadow(0px 0px 20px rgba(194,0,0,0.7)) brightness(120%); + } + 50% { + filter: drop-shadow(0px 0px 20px #f00) brightness(80%); + } + to { + filter: drop-shadow(0px 0px 20px rgba(194,0,0,0.7)) brightness(100%); + } +} +@-webkit-keyframes neon6_drop { + from { + filter: drop-shadow(0px 0px 20px rgba(194,0,0,0.7)) brightness(120%); + } + 50% { + filter: drop-shadow(0px 0px 20px #f00) brightness(80%); + } + to { + filter: drop-shadow(0px 0px 20px rgba(194,0,0,0.7)) brightness(100%); + } +} +@-o-keyframes neon6_drop { + from { + filter: drop-shadow(0px 0px 20px rgba(194,0,0,0.7)) brightness(120%); + } + 50% { + filter: drop-shadow(0px 0px 20px #f00) brightness(80%); + } + to { + filter: drop-shadow(0px 0px 20px rgba(194,0,0,0.7)) brightness(100%); + } +} +@keyframes neon6_drop { + from { + filter: drop-shadow(0px 0px 20px rgba(194,0,0,0.7)) brightness(120%); + } + 50% { + filter: drop-shadow(0px 0px 20px #f00) brightness(80%); + } + to { + filter: drop-shadow(0px 0px 20px rgba(194,0,0,0.7)) brightness(100%); + } +} +span.button { + margin: 0 0 0 1px; + padding: 0.5em 1em; + border: 1px solid #d4d4d4; + border-radius: 50em; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + cursor: pointer; + outline: none; + background-color: #ececec; + color: #333; + font: 11px/normal sans-serif; + text-shadow: 1px 1px 0 #fff; + text-align: center; + text-decoration: none; + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Chrome/Safari/Opera */ + -khtml-user-select: none; /* Konqueror */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently not supported by any browser */ +} +span.button:hover { + color: #00f; +} +span.button:active { + color: #fff; + background-color: #141414; + text-shadow: 1px 1px 0 #000; + border: 1px solid #292929; +} +span.button.primary { + font-weight: 800; +} +span.button.selected { + color: #fff; + background-color: #141414; + text-shadow: 1px 1px 0 #000; + cursor: default; +} +span.buttonGroup :not(:first-child):not(:last-child) { + border-radius: 0; +} +span.buttonGroup :first-child { + border-top-left-radius: 50em; + border-bottom-left-radius: 50em; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + margin-left: 0; +} +span.buttonGroup :last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-top-right-radius: 50em; + border-bottom-right-radius: 50em; +} +section.maxHeightContainer, +div.maxHeightContainer { + display: table; + height: 100%; + width: 100%; +} +section.maxHeightContainer section.maxHeightRow, +div.maxHeightContainer section.maxHeightRow, +section.maxHeightContainer div.maxHeightRow, +div.maxHeightContainer div.maxHeightRow { + display: table-row; +} +section.maxHeightContainer section.maxHeightRow section.maxHeightContent, +div.maxHeightContainer section.maxHeightRow section.maxHeightContent, +section.maxHeightContainer div.maxHeightRow section.maxHeightContent, +div.maxHeightContainer div.maxHeightRow section.maxHeightContent, +section.maxHeightContainer section.maxHeightRow div.maxHeightContent, +div.maxHeightContainer section.maxHeightRow div.maxHeightContent, +section.maxHeightContainer div.maxHeightRow div.maxHeightContent, +div.maxHeightContainer div.maxHeightRow div.maxHeightContent { + display: table-cell; + height: 1px; +} +section.maxHeightContainer section.maxHeightRow section.maxHeightContentExpandAndScroll, +div.maxHeightContainer section.maxHeightRow section.maxHeightContentExpandAndScroll, +section.maxHeightContainer div.maxHeightRow section.maxHeightContentExpandAndScroll, +div.maxHeightContainer div.maxHeightRow section.maxHeightContentExpandAndScroll, +section.maxHeightContainer section.maxHeightRow div.maxHeightContentExpandAndScroll, +div.maxHeightContainer section.maxHeightRow div.maxHeightContentExpandAndScroll, +section.maxHeightContainer div.maxHeightRow div.maxHeightContentExpandAndScroll, +div.maxHeightContainer div.maxHeightRow div.maxHeightContentExpandAndScroll { + display: table-cell; + height: 100%; + position: relative; +} +section.maxHeightContainer section.maxHeightRow section.maxHeightContentExpandAndScroll section.maxHeightContentScrolled, +div.maxHeightContainer section.maxHeightRow section.maxHeightContentExpandAndScroll section.maxHeightContentScrolled, +section.maxHeightContainer div.maxHeightRow section.maxHeightContentExpandAndScroll section.maxHeightContentScrolled, +div.maxHeightContainer div.maxHeightRow section.maxHeightContentExpandAndScroll section.maxHeightContentScrolled, +section.maxHeightContainer section.maxHeightRow div.maxHeightContentExpandAndScroll section.maxHeightContentScrolled, +div.maxHeightContainer section.maxHeightRow div.maxHeightContentExpandAndScroll section.maxHeightContentScrolled, +section.maxHeightContainer div.maxHeightRow div.maxHeightContentExpandAndScroll section.maxHeightContentScrolled, +div.maxHeightContainer div.maxHeightRow div.maxHeightContentExpandAndScroll section.maxHeightContentScrolled, +section.maxHeightContainer section.maxHeightRow section.maxHeightContentExpandAndScroll div.maxHeightContentScrolled, +div.maxHeightContainer section.maxHeightRow section.maxHeightContentExpandAndScroll div.maxHeightContentScrolled, +section.maxHeightContainer div.maxHeightRow section.maxHeightContentExpandAndScroll div.maxHeightContentScrolled, +div.maxHeightContainer div.maxHeightRow section.maxHeightContentExpandAndScroll div.maxHeightContentScrolled, +section.maxHeightContainer section.maxHeightRow div.maxHeightContentExpandAndScroll div.maxHeightContentScrolled, +div.maxHeightContainer section.maxHeightRow div.maxHeightContentExpandAndScroll div.maxHeightContentScrolled, +section.maxHeightContainer div.maxHeightRow div.maxHeightContentExpandAndScroll div.maxHeightContentScrolled, +div.maxHeightContainer div.maxHeightRow div.maxHeightContentExpandAndScroll div.maxHeightContentScrolled { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + overflow-y: auto; +} +.vscFixed { + flex: 0 0 auto; + width: 100%; +} +.vscExpand { + flex: 1 1 1px; + width: 100%; +} +.verticalStack { + width: 100%; + height: 100%; + display: flex; + flex-flow: column; + justify-content: flex-start; + align-items: flex-start; + align-content: stretch; +} +.columnContainer { + display: flex; + flex-direction: column; + flex-wrap: wrap; + justify-content: flex-start; + align-items: stretch; + align-content: flex-start; + overflow-x: auto; +} +.columnContent { + flex: none; +} +ul.tabRow { + position: relative; + text-align: left; + list-style: none; + margin: 0; + padding: 0 0 0 10px; + line-height: 24px; + height: 26px; + font-size: 12px; + overflow: hidden; +} +ul.tabRow li { + position: relative; + z-index: 0; + border: 1px solid #aaa; + background: #d1d1d1; + display: inline-block; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + background: -o-linear-gradient(top, #ececec 50%, #d1d1d1 100%); + background: -ms-linear-gradient(top, #ececec 50%, #d1d1d1 100%); + background: -moz-linear-gradient(top, #ececec 50%, #d1d1d1 100%); + background: -webkit-linear-gradient(top, #ececec 50%, #d1d1d1 100%); + background: linear-gradient(top, #ececec 50%, #d1d1d1 100%); + box-shadow: 0 3px 3px rgba(0,0,0,0.4), inset 0 1px 0 #fff; + text-shadow: 0 1px #fff; + margin: 0 -5px; + padding: 0 20px; +} +ul.tabRow li:before, +ul.tabRow li:after { + position: absolute; + bottom: -1px; + width: 5px; + height: 5px; + content: " "; + border: 1px solid #aaa; +} +ul.tabRow li:before { + left: -6px; + border-bottom-right-radius: 6px; + border-width: 0 1px 1px 0; + box-shadow: 2px 2px 0 #d1d1d1; +} +ul.tabRow li:after { + right: -6px; + border-bottom-left-radius: 6px; + border-width: 0 0 1px 1px; + box-shadow: -2px 2px 0 #d1d1d1; +} +ul.tabRow li.selected { + z-index: 2; + background: #fff; + color: #333; + border-bottom-color: #fff; +} +ul.tabRow li.selected:before { + box-shadow: 2px 2px 0 #fff; +} +ul.tabRow li.selected:after { + box-shadow: -2px 2px 0 #fff; +} +ul.tabRow:before { + position: absolute; + width: 100%; + bottom: 0; + left: 0; + border-bottom: 1px solid #aaa; + z-index: 1; + content: " "; +} +.select2-container { + font-size: 10px; +} +.select2-selection { + font-size: 13px; + margin-bottom: 0px; + min-height: 10px !important; + padding-bottom: 2px; +} +input { + padding: 6px; + border-radius: 4px; + border-width: 1px; + border-style: solid; + border-color: #ccc; +} +.form-control, +.select2-selection { + font-size: 14px; + margin-bottom: 0px; +} +.form-group { + margin: 4px 0; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); + box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); +} +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"].form-control, + input[type="time"].form-control, + input[type="datetime-local"].form-control, + input[type="month"].form-control { + line-height: 34px; + } +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); + box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); + -webkit-transition: border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s; + -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; +} +input[type="date"], +input[type="datetime-local"], +input[type="month"], +input[type="time"], +input[type="week"] { + align-items: center; + -webkit-padding-start: 1px; + overflow: hidden; + padding-left: 10px; +} +input { + -webkit-appearance: textfield; + background-color: #fff; + -webkit-rtl-ordering: logical; + user-select: text; + cursor: auto; + padding: 1px; + border-width: 2px; + border-style: inset; + border-color: initial; + border-image: initial; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + background-color: #eee; + opacity: 1; +} +input, +textarea, +keygen, +select, +button { + text-rendering: auto; + color: initial; + letter-spacing: normal; + word-spacing: normal; + text-transform: none; + text-indent: 0px; + text-shadow: none; + display: inline-block; + text-align: start; + margin: 0em 0em 0em 0em; + font: 13.3333px Arial; +} +input, +textarea, +keygen, +select, +button, +meter, +progress { + -webkit-writing-mode: horizontal-tb; +} +.comboList { + z-index: 1000; + max-height: 160px; + overflow-y: auto; + -moz-box-shadow: 0 2px 3px #ccc; + -webkit-box-shadow: 0 2px 3px #ccc; + box-shadow: 0 2px 3px #ccc; + border: 1px solid #d1d1d1; + list-style-type: none; + padding: 0; + margin: 0; + display: none; + background: #fff; +} +.comboList li { + display: block; + padding: 5px 10px; + margin: 0; + text-indent: 0; + background: #fff; +} +.comboList li.selected { + background-color: #ffe184 !important; +} +.comboList li[role='node'] { + font-weight: 800; +} +.comboList li[role='leaf'] { + padding-left: 2em; +} +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #333; + text-decoration: none; +} +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,0.125); + box-shadow: inset 0 3px 5px rgba(0,0,0,0.125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; + opacity: 0.65; +} +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} +.btn-default:focus, +.btn-default.focus { + color: #333; + background-color: #e6e6e6; + border-color: #8c8c8c; +} +.btn-default:hover { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active:hover, +.btn-default.active:hover, +.open > .dropdown-toggle.btn-default:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.open > .dropdown-toggle.btn-default:focus, +.btn-default:active.focus, +.btn-default.active.focus, +.open > .dropdown-toggle.btn-default.focus { + color: #333; + background-color: #d4d4d4; + border-color: #8c8c8c; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus { + background-color: #fff; + border-color: #ccc; +} +.btn-default .badge { + color: #fff; + background-color: #333; +} +.btn-primary { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary:focus, +.btn-primary.focus { + color: #fff; + background-color: #286090; + border-color: #122b40; +} +.btn-primary:hover { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active:hover, +.btn-primary.active:hover, +.open > .dropdown-toggle.btn-primary:hover, +.btn-primary:active:focus, +.btn-primary.active:focus, +.open > .dropdown-toggle.btn-primary:focus, +.btn-primary:active.focus, +.btn-primary.active.focus, +.open > .dropdown-toggle.btn-primary.focus { + color: #fff; + background-color: #204d74; + border-color: #122b40; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus { + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary .badge { + color: #337ab7; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:focus, +.btn-success.focus { + color: #fff; + background-color: #449d44; + border-color: #255625; +} +.btn-success:hover { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active:hover, +.btn-success.active:hover, +.open > .dropdown-toggle.btn-success:hover, +.btn-success:active:focus, +.btn-success.active:focus, +.open > .dropdown-toggle.btn-success:focus, +.btn-success:active.focus, +.btn-success.active.focus, +.open > .dropdown-toggle.btn-success.focus { + color: #fff; + background-color: #398439; + border-color: #255625; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:focus, +.btn-info.focus { + color: #fff; + background-color: #31b0d5; + border-color: #1b6d85; +} +.btn-info:hover { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active:hover, +.btn-info.active:hover, +.open > .dropdown-toggle.btn-info:hover, +.btn-info:active:focus, +.btn-info.active:focus, +.open > .dropdown-toggle.btn-info:focus, +.btn-info:active.focus, +.btn-info.active.focus, +.open > .dropdown-toggle.btn-info.focus { + color: #fff; + background-color: #269abc; + border-color: #1b6d85; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:focus, +.btn-warning.focus { + color: #fff; + background-color: #ec971f; + border-color: #985f0d; +} +.btn-warning:hover { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active:hover, +.btn-warning.active:hover, +.open > .dropdown-toggle.btn-warning:hover, +.btn-warning:active:focus, +.btn-warning.active:focus, +.open > .dropdown-toggle.btn-warning:focus, +.btn-warning:active.focus, +.btn-warning.active.focus, +.open > .dropdown-toggle.btn-warning.focus { + color: #fff; + background-color: #d58512; + border-color: #985f0d; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:focus, +.btn-danger.focus { + color: #fff; + background-color: #c9302c; + border-color: #761c19; +} +.btn-danger:hover { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active:hover, +.btn-danger.active:hover, +.open > .dropdown-toggle.btn-danger:hover, +.btn-danger:active:focus, +.btn-danger.active:focus, +.open > .dropdown-toggle.btn-danger:focus, +.btn-danger:active.focus, +.btn-danger.active.focus, +.open > .dropdown-toggle.btn-danger.focus { + color: #fff; + background-color: #ac2925; + border-color: #761c19; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + font-weight: normal; + color: #337ab7; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link.active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #23527c; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #777; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +#mainBody { + margin: 0; + padding: 0; + border: 0; + height: 100%; + width: 100%; +} +@media not print { + #mainBody nav.leftSidebarContainer { + z-index: 999; + position: fixed; + top: 0; + width: 220px; + padding: 0; + height: 100%; + border: 0; + vertical-align: top; + text-align: left; + background-color: #90b272; + background: -moz-linear-gradient(-180deg, #90b272 0%, #4d7727 100%); + background: -webkit-linear-gradient(-180deg, #90b272 0%, #4d7727 100%); + background: linear-gradient(180deg, #90b272 0%, #4d7727 100%); + font-size: 14px; + font-weight: 700; + overflow: visible; + margin: 0 0 0 -220px; + -webkit-transition: 0.5s ease-in; + -moz-transition: 0.5s ease-in; + -o-transition: 0.5s ease-in; + -ms-transition: 0.5s ease-in; + transition: 0.5s ease-in; + } + #mainBody nav.leftSidebarContainer .leftSidebarMenuButton { + position: absolute; + right: -30px; + -webkit-transition: 0.5s ease-in; + -moz-transition: 0.5s ease-in; + -o-transition: 0.5s ease-in; + -ms-transition: 0.5s ease-in; + transition: 0.5s ease-in; + -webkit-border-top-right-radius: 5px; + -webkit-border-bottom-right-radius: 5px; + -moz-border-radius-topright: 5px; + -moz-border-radius-bottomright: 5px; + border-top-right-radius: 5px; + border-bottom-right-radius: 5px; + color: #000; + font-size: 20px; + line-height: 20px; + font-weight: 900; + text-align: center; + text-decoration: none; + width: 30px; + height: 30px; + padding: 5px 0; + background-color: #90b272; + display: block; + border-top: 1px solid #494; + border-right: 1px solid #494; + border-bottom: 1px solid #494; + } + #mainBody nav.leftSidebarContainer .leftSidebarMenuButton:hover { + color: rgba(150,0,0,0.5); + } + #mainBody nav.generalSidebar .leftSidebarMenuButton { + top: 10px; + } + #mainBody nav.graphsSidebar .leftSidebarMenuButton { + top: 50px; + } + #mainBody nav.settingsSidebar .leftSidebarMenuButton { + top: 90px; + } + #mainBody nav.menuHide .leftSidebarMenuButton { + right: 60px; + } + #mainBody nav.menuShow { + margin: 0; + } + #mainBody nav.menuShow .leftSidebarMenuButton { + right: -15px; + -webkit-transform: rotate(45deg) !important; + -moz-transform: rotate(45deg) !important; + -o-transform: rotate(45deg) !important; + -ms-transform: rotate(45deg) !important; + transform: rotate(45deg) !important; + -moz-border-radius-bottomright: 0; + border-bottom-right-radius: 0; + border-bottom: 0; + } + #mainBody .leftSidebar { + flex: 0 0 auto; + display: flex; + flex-flow: column; + justify-content: flex-start; + align-items: flex-start; + align-content: stretch; + height: 100%; + border: 0; + vertical-align: top; + padding: 0; + text-align: left; + width: 220px; + background-color: #90b272; + background: -moz-linear-gradient(-180deg, #90b272 0%, #4d7727 100%); + background: -webkit-linear-gradient(-180deg, #90b272 0%, #4d7727 100%); + background: linear-gradient(180deg, #90b272 0%, #4d7727 100%); + font-size: 14px; + font-weight: 700; + overflow: hidden; + } + #mainBody .leftSidebar .logoArea { + flex: 0 0 auto; + width: 100%; + } + #mainBody .leftSidebar .logoArea .signOut { + position: absolute; + left: 10px; + top: 10px; + color: #fff; + cursor: pointer; + } + #mainBody .leftSidebar .logoArea .signOut:hover { + color: #bbb; + } + #mainBody .leftSidebar .logoArea .signOut:active { + color: #000; + } + #mainBody .leftSidebar .logoArea .logo { + text-align: center; + margin-top: 20px; + } + #mainBody .leftSidebar .logoArea .logo img:hover { + animation: neon6_drop 1.5s ease-in-out infinite alternate; + } + #mainBody .leftSidebar .menuArea { + flex: 1 1 auto; + width: 100%; + } + #mainBody .leftSidebar .menuArea ul { + padding: 20px 0 0 0; + margin: 0; + list-style: none; + } + #mainBody .leftSidebar .menuArea ul li:first-child { + border-top: 1px solid #e4e5e7; + } + #mainBody .leftSidebar .menuArea ul li { + border-bottom: 1px solid #e4e5e7; + color: #96a2ae; + text-transform: uppercase; + display: block; + } + #mainBody .leftSidebar .menuArea ul li a { + color: #000; + padding: 10px 20px; + cursor: pointer; + text-decoration: none; + display: block; + } + #mainBody .leftSidebar .menuArea ul li a .tag { + padding: 0.3em 0.6em; + margin-top: -0.2em; + font-size: 0.8em; + color: #ddd; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0.5em; + border: 1px solid #000; + float: right; + } + #mainBody .leftSidebar .menuArea ul li a .subMenu { + background-color: #999; + padding: 0.3em 0.6em; + margin-top: -0.2em; + font-size: 0.8em; + color: #fff; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0.5em; + border: 1px solid #000; + float: right; + } + #mainBody .leftSidebar .menuArea ul li a .subMenu.active { + background-color: #333; + } + #mainBody .leftSidebar .menuArea ul li:hover { + background-color: #666; + -webkit-animation: neon6 1.5s ease-in-out infinite alternate; + -moz-animation: neon6 1.5s ease-in-out infinite alternate; + animation: neon6 1.5s ease-in-out infinite alternate; + } + #mainBody .leftSidebar .menuArea ul li:hover .subMenu { + background-color: #999; + -webkit-animation: neon7 1.5s ease-in-out infinite alternate; + -moz-animation: neon7 1.5s ease-in-out infinite alternate; + animation: neon7 1.5s ease-in-out infinite alternate; + } + #mainBody .leftSidebar .menuArea ul li.active { + background-color: #333; + } + #mainBody .leftSidebar .menuArea ul li.active > a { + color: #96a2ae; + } + #mainBody .leftSidebar .menuArea ul li.active:hover { + background-color: #333; + } + #mainBody .leftSidebar .menuArea ul li.active:hover > a { + color: #fff; + } + #mainBody .leftSidebar .footer { + flex: 0 0 auto; + width: 100%; + font-size: 9px; + text-align: center; + } + #mainBody .contentBody { + flex: 1 1 1px; + padding: 10px 20px; + -webkit-box-shadow: inset 4px 2px 10px -3px #a8a5a8; + -moz-box-shadow: inset 4px 2px 10px -3px #a8a5a8; + box-shadow: inset 8px 0 10px -3px #a8a5a8; + overflow: hidden; + } +} +@media print { + #mainBody nav.leftSidebarContainer { + display: none; + } + #mainBody .contentBody { + flex: 1 1 1px; + padding: 0; + margin: 0; + overflow: hidden; + } +} +#login.content { + background: #fff; +} +#login.content .contentBox { + margin: 0 auto; + max-width: 600px; + background-color: #88d15a; + -webkit-box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.5); + -moz-box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.5); + box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.5); + margin-top: 5%; + padding: 40px 10px; + text-align: center; +} +#login.content .contentBox img { + height: 120px; + vertical-align: top; +} +#login.content .contentBox .form { + display: inline-block; + margin-left: 20px; +} +#login.content .contentBox .form input { + padding: 8px; + width: 300px; + margin-bottom: 10px; +} +#login.content .contentBox .form label { + display: none; +} +#login.content .contentBox .form fieldset { + border: none; +} +#login.content .contentBox .form .at-btn { + margin-bottom: 6px; + text-align: center; + width: 300px; + background: #34d955; + background-image: -webkit-linear-gradient(top, #5d942b, #4b7d26); + background-image: -moz-linear-gradient(top, #5d942b, #4b7d26); + background-image: -ms-linear-gradient(top, #5d942b, #4b7d26); + background-image: -o-linear-gradient(top, #5d942b, #4b7d26); + background-image: linear-gradient(to bottom, #5d942b, #4b7d26); + font-family: "Arial Black", Arial; + color: #fff; + font-size: 14px; + line-height: 16px; + padding: 10px 20px 10px 20px; + text-decoration: none; + text-transform: uppercase; + border: none; +} +#login.content .contentBox .form .at-btn:hover { + background: #29b54f; + background-image: -webkit-linear-gradient(top, #29b54f, #186b31); + background-image: -moz-linear-gradient(top, #29b54f, #186b31); + background-image: -ms-linear-gradient(top, #29b54f, #186b31); + background-image: -o-linear-gradient(top, #29b54f, #186b31); + background-image: linear-gradient(to bottom, #29b54f, #186b31); + text-decoration: none; + cursor: pointer; +} +#login.content .contentBox .form .at-link { + color: #1555b4; + font: Arial; + font-size: 12px; + font-weight: 800; + text-decoration: none; +} +#login.content .contentBox .form .at-link:hover { + text-decoration: underline; +} +#userManagement { + display: table; + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; +} +#userManagement .tableControls { + display: table; + width: 100%; + text-align: right; + margin-right: 20px; +} +#userManagement .tableControls .contentControls { + vertical-align: bottom; + display: table-cell; + text-align: right; + min-width: 100px; +} +#userManagement .tableControls .contentControls a { + font-size: 12px; + font-family: "Arial", san-serif; + font-weight: 800; + color: #2d1b8c; + text-decoration: none; +} +#userManagement .tableControls .contentControls a:hover { + text-decoration: underline; +} +#userManagement .tableControls .contentControls a.disabled { + visibility: hidden; +} +#userManagement .editor { + height: 100%; + overflow-y: auto; +} +#userManagement .insert { + flex: none; + width: 100%; +} +#userManagement .insert .col-md-6 { + padding: 10px 30px 0 30px; + background: #efefef; + border-radius: 1em; +} +#userManagement .insert .formGroupHeading { + font-size: 1.6em; + font-family: "Arial Black", "Arial Bold", Gadget, sans-serif; + font-style: normal; + font-variant: normal; + font-weight: 500; +} +#userManagement .table { + table-layout: fixed; + min-width: 100%; +} +#userManagement .table thead > tr > .username, +#userManagement .table tbody > tr > .username { + width: 50%; + min-width: 100px; +} +#userManagement .table thead > tr > .email, +#userManagement .table tbody > tr > .email { + width: 50%; + min-width: 100px; +} +#userManagement .table thead > tr > .roles, +#userManagement .table tbody > tr > .roles { + width: 260px; + min-width: 260px; +} +#userManagement .table thead > tr > .actions, +#userManagement .table tbody > tr > .actions { + width: 80px; + min-width: 80px; +} +#userManagement .separatedTableHeader .actions { + text-align: center; +} +#userManagement .separatedTableHeader .actions .newUserButton { + margin-top: 4px; + padding: 0 12px; +} +#userManagement .separatedTableHeader .actions .newUserButton .fa-plus-circle { + display: inline-block; +} +#userManagement .separatedTableHeader .actions .newUserButton .fa-times-circle { + display: none; +} +#userManagement .separatedTableHeader .actions .newUserButton.active { + background-color: #fb557b; + color: #000; +} +#userManagement .separatedTableHeader .actions .newUserButton.active .fa-times-circle { + display: inline-block; +} +#userManagement .separatedTableHeader .actions .newUserButton.active .fa-plus-circle { + display: none; +} +#userManagement .listRow { + display: table-row; +} +#userManagement .listRow .listCell { + display: table-cell; + position: relative; + height: 100%; + width: 100%; +} +#userManagement .listRow .listCell .tableContainer { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + border: 0; + font-size: 12.5px; + overflow-y: auto; +} +#userManagement .listRow .listCell .tableContainer table { + table-layout: fixed; + width: 100%; +} +#userManagement .listRow .listCell .tableContainer table thead { + display: none; + visibility: hidden; +} +#userManagement .listRow .listCell .tableContainer table .userRemove { + color: #f00; +} +#userManagement .listRow .listCell .tableContainer table .userEdit { + color: #00008b; +} +#userManagement .listRow .listCell .tableContainer table .editorApply { + color: #008000; +} +#userManagement .listRow .listCell .tableContainer table .editorCancel { + color: #f00; +} +#userManagement .listRow .listCell .tableContainer table .userEditor > div { + display: table; +} +#userManagement .listRow .listCell .tableContainer table .userEditor > div > div { + display: table-cell; + padding: 10px; +} +#userManagement .listRow .listCell .tableContainer table .userEditor > div .roles .role { + vertical-align: middle; +} +#userManagement td.roles .role { + padding: 4px 4px; + border: 1px solid #555; + border-radius: 0.25em; + background: #fff; + color: #999; + cursor: pointer; +} +#userManagement td.roles .selected { + color: #000; +} +#userManagement div.roles { + padding: 4px 0; +} +#userManagement div.roles .role { + padding: 4px 4px; + border: 1px solid #555; + border-radius: 0.25em; + background: #fff; + color: #999; + cursor: pointer; +} +#userManagement div.roles .selected { + color: #000; +} +#userManagement .center { + vertical-align: middle !important; +} +#miscManagement { + display: table; + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; +} +#miscManagement .controls { + text-align: right; + margin-right: 20px; +} +#miscManagement .pageContentRow { + display: table-row; +} +#miscManagement .pageContentRow .pageContentCell { + display: table-cell; + position: relative; + height: 100%; + width: 100%; +} +#miscManagement .pageContentRow .pageContentCell .pageContentContainer { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + border: 0; + font-size: 12.5px; + overflow-y: auto; +} +#miscManagement .pageContentRow .pageContentCell .pageContentContainer .logs { + list-style-type: none; + height: 100%; +} +#miscManagement .pageContentRow .pageContentCell .pageContentContainer .logs :hover { + background: #ccc; +} +#measures { + display: table; + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; +} +#measures .tableControls { + display: table; + width: 100%; + text-align: right; + margin-right: 20px; +} +#measures .tableControls .showHidden { + display: table-cell; + width: 100%; +} +#measures .tableControls .showHidden .controlLabel { + font-size: 9px; + font-weight: 700; + color: #5a5a5a; + position: relative; + top: -2px; +} +#measures .tableControls .showHidden .toggleShowHidden { + margin: 0 40px 0 0; + position: relative; + top: -4px; + display: inline-block; +} +#measures .tableControls .contentControls { + vertical-align: bottom; + display: table-cell; + text-align: right; + min-width: 100px; +} +#measures .tableControls .contentControls a { + font-size: 12px; + font-family: "Arial", san-serif; + font-weight: 800; + color: #2d1b8c; + text-decoration: none; +} +#measures .tableControls .contentControls a:hover { + text-decoration: underline; +} +#measures .tableControls .contentControls a.disabled { + visibility: hidden; +} +#measures .table { + table-layout: fixed; + min-width: 100%; +} +#measures .table thead > tr > .name, +#measures .table tbody > tr > .name { + width: 50%; + min-width: 100px; +} +#measures .table thead > tr > .postfix, +#measures .table tbody > tr > .postfix { + width: 50%; + min-width: 100px; +} +#measures .table thead > tr > .actions, +#measures .table tbody > tr > .actions { + width: 90px; + min-width: 90px; +} +#measures .separatedTableHeader table thead > tr .actions { + text-align: center; +} +#measures .separatedTableHeader table thead > tr .actions .newMeasureButton { + margin-top: 4px; + padding: 0 12px; +} +#measures .separatedTableHeader table thead > tr .actions .newMeasureButton .fa-plus-circle { + display: inline-block; +} +#measures .separatedTableHeader table thead > tr .actions .newMeasureButton .fa-times-circle { + display: none; +} +#measures .separatedTableHeader table thead > tr .actions .newMeasureButton.active { + background-color: #fb557b; + color: #000; +} +#measures .separatedTableHeader table thead > tr .actions .newMeasureButton.active .fa-times-circle { + display: inline-block; +} +#measures .separatedTableHeader table thead > tr .actions .newMeasureButton.active .fa-plus-circle { + display: none; +} +#measures .listRow { + display: table-row; +} +#measures .listRow .listCell { + display: table-cell; + position: relative; + height: 100%; + width: 100%; +} +#measures .listRow .listCell .tableContainer { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + border: 0; + font-size: 12.5px; + overflow-y: auto; +} +#measures .listRow .listCell .tableContainer table { + table-layout: fixed; + width: 100%; +} +#measures .listRow .listCell .tableContainer table .measureSearch { + margin: 3px 0 2px 1px; +} +#measures .listRow .listCell .tableContainer table .measureEditorTd { + background: #deeac0; +} +#measures .listRow .listCell .tableContainer table input[name="name"], +#measures .listRow .listCell .tableContainer table input[name="postfix"] { + width: 100%; +} +#measures .listRow .listCell .tableContainer table .editorDiv { + margin: 4px 0; +} +#measures .listRow .listCell .tableContainer table .editorDiv label { + font-family: "Arial Black", "Arial Bold", Gadget, sans-serif; + font-size: 0.9em; + padding-bottom: 4px; +} +#measures .listRow .listCell .tableContainer table .editorDiv select2 { + font-size: 0.4em; +} +#measures .listRow .listCell .tableContainer table > thead { + display: none; + visibility: hidden; +} +#measures .listRow .listCell .tableContainer table > tbody > tr .actionRemove { + color: #f77; +} +#measures .listRow .listCell .tableContainer table > tbody > tr .actionEdit { + color: #44f; +} +#measures .listRow .listCell .tableContainer table > tbody > tr .editorApply { + color: #008000; +} +#measures .listRow .listCell .tableContainer table > tbody > tr .editorCancel { + color: #f00; +} +#measures .listRow .listCell .tableContainer table > tbody > tr.deactivated { + background-color: #fac0d1; +} +#measures .listRow .listCell .tableContainer table > tbody > tr.deactivated .actionActivate { + color: #158b18; +} +#measures .listRow .listCell .tableContainer table > tbody > tr.deactivated .actionHide { + color: #6a0707; +} +#measures .listRow .listCell .tableContainer table > tbody > tr.deactivated .actionEdit { + color: #0101e4; +} +#measures .listRow .listCell .tableContainer table > tbody > tr.deactivated:hover { + background-color: #ffcadb; +} +#measures .listRow .listCell .tableContainer table > tbody > tr.hidden { + background-color: #e995ff; +} +#measures .listRow .listCell .tableContainer table > tbody > tr.hidden .actionEdit { + color: #0101e4; +} +#measures .listRow .listCell .tableContainer table > tbody > tr.hidden .actionShow { + color: #027905; +} +#measures .listRow .listCell .tableContainer table > tbody > tr.hidden:hover { + background-color: #ffb5ff; +} +#venues { + display: table; + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; +} +#venues .tableControls { + display: table; + width: 100%; + text-align: right; + margin-right: 20px; +} +#venues .tableControls .showHidden { + display: table-cell; + width: 100%; +} +#venues .tableControls .showHidden .controlLabel { + font-size: 9px; + font-weight: 700; + color: #5a5a5a; + position: relative; + top: -2px; +} +#venues .tableControls .showHidden .toggleShowHidden { + margin: 0 40px 0 0; + position: relative; + top: -4px; + display: inline-block; +} +#venues .tableControls .contentControls { + vertical-align: bottom; + display: table-cell; + text-align: right; + min-width: 100px; +} +#venues .tableControls .contentControls a { + font-size: 12px; + font-family: "Arial", san-serif; + font-weight: 800; + color: #2d1b8c; + text-decoration: none; +} +#venues .tableControls .contentControls a:hover { + text-decoration: underline; +} +#venues .tableControls .contentControls a.disabled { + visibility: hidden; +} +#venues .table { + table-layout: fixed; + min-width: 100%; +} +#venues .table thead > tr > .name, +#venues .table tbody > tr > .name { + width: 33%; + min-width: 100px; +} +#venues .table thead > tr > .type, +#venues .table tbody > tr > .type { + width: 33%; + min-width: 100px; +} +#venues .table thead > tr > .frequency, +#venues .table tbody > tr > .frequency { + width: 33%; + min-width: 100px; +} +#venues .table thead > tr > .actions, +#venues .table tbody > tr > .actions { + width: 90px; + min-width: 90px; +} +#venues .separatedTableHeader table thead > tr .actions { + text-align: center; +} +#venues .separatedTableHeader table thead > tr .actions .newVenueButton { + margin-top: 4px; + padding: 0px 12px; +} +#venues .separatedTableHeader table thead > tr .actions .newVenueButton .fa-plus-circle { + display: inline-block; +} +#venues .separatedTableHeader table thead > tr .actions .newVenueButton .fa-times-circle { + display: none; +} +#venues .separatedTableHeader table thead > tr .actions .newVenueButton.active { + background-color: #fb557b; + color: #000; +} +#venues .separatedTableHeader table thead > tr .actions .newVenueButton.active .fa-times-circle { + display: inline-block; +} +#venues .separatedTableHeader table thead > tr .actions .newVenueButton.active .fa-plus-circle { + display: none; +} +#venues .listRow { + display: table-row; +} +#venues .listRow .listCell { + display: table-cell; + position: relative; + height: 100%; + width: 100%; +} +#venues .listRow .listCell .tableContainer { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + border: 0; + font-size: 12.5px; + overflow-y: auto; +} +#venues .listRow .listCell .tableContainer table { + table-layout: fixed; + width: 100%; +} +#venues .listRow .listCell .tableContainer table .venueSearch { + margin: 3px 0 2px 1px; +} +#venues .listRow .listCell .tableContainer table .venueEditorTd { + background: #deeac0; +} +#venues .listRow .listCell .tableContainer table input[name="name"], +#venues .listRow .listCell .tableContainer table input[name="type"] { + width: 100%; +} +#venues .listRow .listCell .tableContainer table .editorDiv { + margin: 4px 0; +} +#venues .listRow .listCell .tableContainer table .editorDiv label { + font-family: "Arial Black", "Arial Bold", Gadget, sans-serif; + font-size: 0.9em; + padding-bottom: 4px; +} +#venues .listRow .listCell .tableContainer table .editorDiv select2 { + font-size: 0.4em; +} +#venues .listRow .listCell .tableContainer table > thead { + display: none; + visibility: hidden; +} +#venues .listRow .listCell .tableContainer table > tbody > tr .actionRemove { + color: #f77; +} +#venues .listRow .listCell .tableContainer table > tbody > tr .actionEdit { + color: #44f; +} +#venues .listRow .listCell .tableContainer table > tbody > tr .editorApply { + color: #008000; +} +#venues .listRow .listCell .tableContainer table > tbody > tr .editorCancel { + color: #f00; +} +#venues .listRow .listCell .tableContainer table > tbody > tr.deactivated { + background-color: #fac0d1; +} +#venues .listRow .listCell .tableContainer table > tbody > tr.deactivated .actionActivate { + color: #158b18; +} +#venues .listRow .listCell .tableContainer table > tbody > tr.deactivated .actionHide { + color: #6a0707; +} +#venues .listRow .listCell .tableContainer table > tbody > tr.deactivated .actionEdit { + color: #0101e4; +} +#venues .listRow .listCell .tableContainer table > tbody > tr.deactivated:hover { + background-color: #ffcadb; +} +#venues .listRow .listCell .tableContainer table > tbody > tr.hidden { + background-color: #e995ff; +} +#venues .listRow .listCell .tableContainer table > tbody > tr.hidden .actionEdit { + color: #0101e4; +} +#venues .listRow .listCell .tableContainer table > tbody > tr.hidden .actionShow { + color: #027905; +} +#venues .listRow .listCell .tableContainer table > tbody > tr.hidden:hover { + background-color: #ffb5ff; +} +#products { + display: table; + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; +} +#products .tableControls { + text-align: right; + margin-right: 20px; + margin-bottom: 4px; + display: table; + width: 100%; +} +#products .tableControls .showHidden { + display: table-cell; + text-align: right; + width: 100%; +} +#products .tableControls .showHidden .controlLabel { + font-size: 9px; + font-weight: 700; + color: #5a5a5a; + position: relative; + top: -2px; +} +#products .tableControls .showHidden .toggleShowHidden { + margin: 0 40px 0 0; + position: relative; + top: -4px; + display: inline-block; +} +#products .tableControls .contentControls { + vertical-align: bottom; + display: table-cell; + text-align: right; + min-width: 100px; +} +#products .tableControls .contentControls a { + font-size: 12px; + font-family: "Arial", san-serif; + font-weight: 800; + color: #2d1b8c; + text-decoration: none; +} +#products .tableControls .contentControls a:hover { + text-decoration: underline; +} +#products .tableControls .contentControls a.disabled { + visibility: hidden; +} +#products .table { + table-layout: fixed; + min-width: 100%; +} +#products .table thead > tr > .name, +#products .table tbody > tr > .name { + width: 100%; +} +#products .table thead > tr > .tags, +#products .table tbody > tr > .tags { + width: 220px; + min-width: 220px; +} +#products .table thead > tr > .aliases, +#products .table tbody > tr > .aliases { + width: 220px; + min-width: 220px; +} +#products .table thead > tr > .measures, +#products .table tbody > tr > .measures { + width: 220px; + min-width: 220px; +} +#products .table thead > tr > .actions, +#products .table tbody > tr > .actions { + width: 90px; + min-width: 90px; +} +#products .separatedTableHeader table thead > tr > th.actions { + text-align: center; +} +#products .separatedTableHeader table thead > tr > th.actions .newButton { + margin-top: 4px; + padding: 0 12px; +} +#products .separatedTableHeader table thead > tr > th.actions .newButton .fa-plus-circle { + display: inline-block; +} +#products .separatedTableHeader table thead > tr > th.actions .newButton .fa-times-circle { + display: none; +} +#products .separatedTableHeader table thead > tr > th.actions .newButton:active { + background-color: #fb557b; + color: #000; +} +#products .separatedTableHeader table thead > tr > th.actions .newButton:active .fa-times-circle { + display: inline-block; +} +#products .separatedTableHeader table thead > tr > th.actions .newButton:active .fa-plus-circle { + display: none; +} +#products .listRow { + display: table-row; +} +#products .listRow .listCell { + display: table-cell; + position: relative; + height: 100%; + width: 100%; +} +#products .listRow .listCell .tableContainer { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + border: 0; + font-size: 12.5px; + overflow-y: auto; +} +#products .listRow .listCell .tableContainer table thead { + visibility: hidden; + display: none; +} +#products .listRow .listCell .tableContainer table .search { + margin: 3px 0 2px 1px; +} +#products .listRow .listCell .tableContainer table .editorTd { + background: #deeac0; +} +#products .listRow .listCell .tableContainer table input[name="name"], +#products .listRow .listCell .tableContainer table .productTagsEditor, +#products .listRow .listCell .tableContainer table .productAliasesEditor, +#products .listRow .listCell .tableContainer table .productMeasuresEditor { + width: 100%; +} +#products .listRow .listCell .tableContainer table .editorDiv { + margin: 4px 0; +} +#products .listRow .listCell .tableContainer table .editorDiv label { + font-family: "Arial Black", "Arial Bold", Gadget, sans-serif; + font-size: 0.9em; + padding-bottom: 4px; +} +#products .listRow .listCell .tableContainer table .editorDiv select2 { + font-size: 0.4em; +} +#products .listRow .listCell .tableContainer table > tbody > tr .actionRemove { + color: #f77; +} +#products .listRow .listCell .tableContainer table > tbody > tr .actionEdit { + color: #44f; +} +#products .listRow .listCell .tableContainer table > tbody > tr .editorApply { + color: #008000; +} +#products .listRow .listCell .tableContainer table > tbody > tr .editorCancel { + color: #f00; +} +#products .listRow .listCell .tableContainer table > tbody > tr.deactivated { + background-color: #fac0d1; +} +#products .listRow .listCell .tableContainer table > tbody > tr.deactivated .actionActivate { + color: #158b18; +} +#products .listRow .listCell .tableContainer table > tbody > tr.deactivated .actionHide { + color: #6a0707; +} +#products .listRow .listCell .tableContainer table > tbody > tr.deactivated .actionEdit { + color: #0101e4; +} +#products .listRow .listCell .tableContainer table > tbody > tr.deactivated:hover { + background-color: #ffcadb; +} +#products .listRow .listCell .tableContainer table > tbody > tr.hidden { + background-color: #e995ff; +} +#products .listRow .listCell .tableContainer table > tbody > tr.hidden .actionEdit { + color: #0101e4; +} +#products .listRow .listCell .tableContainer table > tbody > tr.hidden .actionShow { + color: #027905; +} +#products .listRow .listCell .tableContainer table > tbody > tr.hidden .actionConvert { + color: #fb0909; +} +#products .listRow .listCell .tableContainer table > tbody > tr.hidden:hover { + background-color: #ffb5ff; +} +#productTags { + display: table; + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; +} +#productTags .tagInfo { + display: block; + margin-bottom: 20px; +} +#productTags .tagInfo .tagControls { + display: block; + width: 100%; +} +#productTags .tagInfo .tagControls label { + display: inline-block; +} +#productTags .tagInfo .tagControls input[name="tagName"] { + width: 140px; + display: inline-block; +} +#productTags .tagInfo .tagControls input[name="addTag"] { + margin-top: -4px; +} +#productTags .tagInfo .floatRight { + float: right; +} +#productTags .tagInfo .floatRight .editTags { + font-size: 2em; + border: 1px solid #999; + background: #f7f3a0; + border-radius: 4px; + padding: 2px 3px; +} +#productTags .tagInfo .floatRight .switch { + position: relative; + display: inline-block; + width: 60px; + height: 34px; +/* Hide default HTML checkbox */ +/* The slider */ +/* Rounded sliders */ +} +#productTags .tagInfo .floatRight .switch input { + display: none; +} +#productTags .tagInfo .floatRight .switch .slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + -webkit-transition: 0.4s; + transition: 0.4s; +} +#productTags .tagInfo .floatRight .switch .slider:before { + position: absolute; + font-family: FontAwesome; + padding-left: 4px; + font-size: 20px; + line-height: 26px; + color: #ffa398; + content: "\f040"; + height: 26px; + width: 26px; + left: 4px; + bottom: 4px; + background-color: #fff; + -webkit-transition: 0.4s; + transition: 0.4s; +} +#productTags .tagInfo .floatRight .switch input:checked + .slider { + background-color: #5cb85c; +} +#productTags .tagInfo .floatRight .switch input:focus + .slider { + box-shadow: 0 0 1px #2196f3; +} +#productTags .tagInfo .floatRight .switch input:checked + .slider:before { + -webkit-transform: translateX(26px); + -ms-transform: translateX(26px); + transform: translateX(26px); +} +#productTags .tagInfo .floatRight .switch .slider.round { + border-radius: 34px; +} +#productTags .tagInfo .floatRight .switch .slider.round:before { + border-radius: 50%; +} +#productTags .tagInfo .tableTop { + display: table; + width: 100%; + margin-top: 10px; +} +#productTags .tagInfo .tableTop .tagDisplay { + display: table-cell; + width: auto; +} +#productTags .tagInfo .tableTop .tagDisplay .productTagExp { + font-family: "Arial Black", "Arial Bold", Gadget, sans-serif; + font-size: 14px; + line-height: 34px; + margin: 0; + padding: 4px 14px; + border: 1px solid #999; + border-radius: 4px; + white-space: nowrap; + cursor: pointer; +} +#productTags .tagInfo .tableTop .tagDisplay .productTagExp .hidden { + display: none; +} +#productTags .tagInfo .tableTop .tagDisplay .productTagExp .productTagEditor { + display: inline-block; + font-size: 1em; + height: 20px; + background: transparent; + border: 0; + padding: 0; + margin: 0; +} +#productTags .tagInfo .tableTop .tagDisplay .productTagExp .productTagName { + border: 0; + padding: 0; + margin: 0; +} +#productTags .tagInfo .tableTop .contentControls { + vertical-align: bottom; + display: table-cell; + text-align: right; + min-width: 100px; +} +#productTags .tagInfo .tableTop .contentControls a { + font-size: 12px; + font-family: "Arial", san-serif; + font-weight: 800; + color: #2d1b8c; + text-decoration: none; +} +#productTags .tagInfo .tableTop .contentControls a:hover { + text-decoration: underline; +} +#productTags .tagInfo .tableTop .contentControls a.disabled { + visibility: hidden; +} +#productTags .table { + table-layout: fixed; + min-width: 100%; +} +#productTags .table thead > tr > .name, +#productTags .table tbody > tr > .name { + width: 100%; + min-width: 100px; +} +#productTags .table thead > tr > .tags, +#productTags .table tbody > tr > .tags { + width: 100%; + min-width: 100px; +} +#productTags .listRow { + display: table-row; +} +#productTags .listRow .listCell { + display: table-cell; + position: relative; + height: 100%; + width: 100%; +} +#productTags .listRow .listCell .tableContainer { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + border: 0; + font-size: 12.5px; + overflow-y: auto; +} +#productTags .listRow .listCell .tableContainer table { + table-layout: fixed; + width: 100%; +} +#productTags .listRow .listCell .tableContainer table > thead > tr.deactivated, +#productTags .listRow .listCell .tableContainer table > tbody > tr.deactivated { + background-color: #fac0d1; +} +#productTags .listRow .listCell .tableContainer table > thead > tr.deactivated:hover, +#productTags .listRow .listCell .tableContainer table > tbody > tr.deactivated:hover { + background-color: #ffcadb; +} +#productTags td.roles .role { + padding: 4px 4px; + border: 1px solid #555; + border-radius: 0.25em; + background: #fff; + color: #999; + cursor: pointer; +} +#productTags td.roles .selected { + color: #000; +} +#productTags div.roles { + padding: 4px 0; +} +#productTags div.roles .role { + padding: 4px 4px; + border: 1px solid #555; + border-radius: 0.25em; + background: #fff; + color: #999; + cursor: pointer; +} +#productTags div.roles .selected { + color: #000; +} +#productTags .center { + vertical-align: middle !important; +} +#salesMain { + display: table; + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; +} +#salesMain .controls { + text-align: left; + display: table; + width: 100%; +} +#salesMain .controls .pageControls { + padding: 4px 8px; + margin: 4px 8px; + display: table-cell; + width: 240px; +} +#salesMain .controls .tableControls { + text-align: right; + padding: 4px 8px; + margin: 4px 12px 4px 8px; + display: table-cell; +} +#salesMain .table { + table-layout: fixed; + min-width: 100%; +} +#salesMain .table thead > tr > .amount, +#salesMain .table tbody > tr > .amount { + width: 90px; + min-width: 90px; +} +#salesMain .table thead > tr > .product, +#salesMain .table tbody > tr > .product { + width: 100%; + min-width: 140px; +} +#salesMain .table thead > tr > .price, +#salesMain .table tbody > tr > .price { + width: 140px; + min-width: 140px; +} +#salesMain .table thead > tr > .measure, +#salesMain .table tbody > tr > .measure { + width: 100px; + min-width: 100px; +} +#salesMain .table thead > tr > .saleDate, +#salesMain .table tbody > tr > .saleDate { + width: 150px; + min-width: 150px; +} +#salesMain .table thead > tr > .createdDate, +#salesMain .table tbody > tr > .createdDate { + width: 100px; + min-width: 100px; +} +#salesMain .table thead > tr > .venue, +#salesMain .table tbody > tr > .venue { + width: 160px; + min-width: 160px; +} +#salesMain .table thead > tr > .actions, +#salesMain .table tbody > tr > .actions { + width: 90px; + min-width: 90px; +} +#salesMain .separatedTableHeader table thead > tr > th.actions .newSaleButton { + padding: 0 12px; +} +#salesMain .separatedTableHeader table thead > tr > th.actions .newSaleButton .fa-plus-circle { + display: inline-block; +} +#salesMain .separatedTableHeader table thead > tr > th.actions .newSaleButton .fa-times-circle { + display: none; +} +#salesMain .separatedTableHeader table thead > tr > th.actions .newSaleButton.active { + background-color: #fb557b; + color: #000; +} +#salesMain .separatedTableHeader table thead > tr > th.actions .newSaleButton.active .fa-times-circle { + display: inline-block; +} +#salesMain .separatedTableHeader table thead > tr > th.actions .newSaleButton.active .fa-plus-circle { + display: none; +} +#salesMain .separatedTableHeader table thead > tr > th.actions .showOnlyComments { + color: #bcb95f; + padding: 4px 8px; +} +#salesMain .separatedTableHeader table thead > tr > th.actions .showOnlyComments:hover { + color: #fff; + text-shadow: 0px 0px 10px #ff6d1f; +} +#salesMain .separatedTableHeader table thead > tr > th.actions .showOnlyComments.on { + color: #fff; +} +#salesMain .separatedTableHeader table thead > tr > th.saleDate input { + width: 130px; +} +#salesMain .listRow { + display: table-row; +} +#salesMain .listRow .listCell { + display: table-cell; + position: relative; + height: 100%; + width: 100%; +} +#salesMain .listRow .listCell .tableContainer { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + border: 0; + font-size: 12.5px; + overflow-y: scroll; +} +#salesMain .listRow .listCell .tableContainer label { + font-size: 10px; + font-weight: 800; +} +#salesMain .listRow .listCell .tableContainer table thead { + visibility: hidden; + display: none; +} +#salesMain .listRow .listCell .tableContainer table .saleRemove { + color: #f00; + margin-left: 8px; +} +#salesMain .listRow .listCell .tableContainer table .saleEdit { + color: #00008b; + margin-right: 8px; +} +#salesMain .listRow .listCell .tableContainer table .editorApply { + color: #008000; +} +#salesMain .listRow .listCell .tableContainer table .editorCancel { + color: #f00; +} +#salesMain .listRow .listCell .tableContainer table .saleDate { + text-align: left; +} +#salesMain .listRow .listCell .tableContainer table .createdDate { + text-align: left; +} +#salesMain .listRow .listCell .tableContainer .editComment { + color: #808080; +} +#salesMain .listRow .listCell .tableContainer .hasComment { + color: #000; +} +#salesMain .listRow .listCell .tableContainer .actionEdit { + margin-right: 6px; + color: #44f; +} +#salesMain .saleEditor .heading { + font-size: 2em; + font-family: verdana, arial, helvetica, sans-serif; + text-transform: uppercase; + font-weight: 800; + margin: 6px 0 14px 0; +} +#salesMain .saleEditor .priceContainer { + display: table; + width: 100%; +} +#salesMain .saleEditor .priceContainer .price { + display: table-cell; + padding-right: 10px; +} +#salesMain .saleEditor .priceContainer .priceButtons { + display: table-cell; + width: 1.5em; +} +#salesMain .saleEditor .priceContainer .priceButtons .setDefaultPrice { + font-size: 1.5em; + padding: 6px 8px; + margin-left: 8px; + border-radius: 8px; +} +#salesMain .saleEditor .priceContainer .priceButtons .setDefaultPrice:hover { + text-shadow: 0px 0px 6px #00b900; +} +#salesMain .saleEditor .priceContainer .priceButtons .setDefaultPrice:active { + text-shadow: 0px 0px 6px #808080; +} +#salesMain .insertSaleForm .form-group, +#salesMain .insertSaleForm label { + text-align: left; +} +#salesMain .insertSaleForm .formGroupHeading { + font-size: 1.6em; + font-family: "Arial Black", "Arial Bold", Gadget, sans-serif; + font-style: normal; + font-variant: normal; + font-weight: 500; +} +#saleDuplicates { + display: table; + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; +} +#saleDuplicates .controls { + text-align: left; + display: table; + width: 100%; +} +#saleDuplicates .controls .pageControls { + padding: 4px 8px; + margin: 4px 8px; + display: table-cell; + width: 240px; +} +#saleDuplicates .controls .tableControls { + text-align: right; + padding: 4px 8px; + margin: 4px 12px 4px 8px; + display: table-cell; +} +#saleDuplicates .controls .tableControls .toggleShowHidden { + margin: 0 40px 0 0; + position: relative; + top: -4px; + display: inline-block; +} +#saleDuplicates .listRow { + display: table-row; +} +#saleDuplicates .listRow .listCell { + display: table-cell; + position: relative; + height: 100%; + width: 100%; +} +#saleDuplicates .listRow .listCell .tableContainer { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + border: 0; + font-size: 12.5px; + overflow-y: auto; +} +#saleDuplicates .listRow .listCell .tableContainer label { + font-size: 10px; + font-weight: 800; +} +#saleDuplicates .listRow .listCell .tableContainer table { + table-layout: fixed; + min-width: 100%; +} +#saleDuplicates .listRow .listCell .tableContainer table .saleRemove { + color: #f00; + margin-left: 8px; +} +#saleDuplicates .listRow .listCell .tableContainer table .saleEdit { + color: #00008b; + margin-right: 8px; +} +#saleDuplicates .listRow .listCell .tableContainer table .editorApply { + color: #008000; +} +#saleDuplicates .listRow .listCell .tableContainer table .editorCancel { + color: #f00; +} +#saleDuplicates .listRow .listCell .tableContainer table thead > tr > th.amount { + width: 90px; +} +#saleDuplicates .listRow .listCell .tableContainer table thead > tr > th.product { + width: auto; + min-width: 140px; +} +#saleDuplicates .listRow .listCell .tableContainer table thead > tr > th.price { + width: 140px; +} +#saleDuplicates .listRow .listCell .tableContainer table thead > tr > th.measure { + width: 100px; +} +#saleDuplicates .listRow .listCell .tableContainer table thead > tr > th.saleDate { + width: 140px; +} +#saleDuplicates .listRow .listCell .tableContainer table thead > tr > th.createdDate { + width: 100px; +} +#saleDuplicates .listRow .listCell .tableContainer table thead > tr > th.venue { + width: 160px; +} +#saleDuplicates .listRow .listCell .tableContainer table thead > tr > th.actions { + width: 90px; +} +#saleDuplicates .listRow .listCell .tableContainer table tbody > tr > td.actions .ignoreDuplicatesButton { + padding: 0 2px; + color: #008000; +} +#saleDuplicates .listRow .listCell .tableContainer table tbody > tr > td.actions .ignoreDuplicatesButton:hover { + color: #0b0; +} +#saleDuplicates .listRow .listCell .tableContainer table tbody > tr > td.actions .ignoreDuplicatesButton:active { + color: #000; +} +#saleDuplicates .listRow .listCell .tableContainer table tbody > tr > td.actions .ignoreDuplicatesButton.hidden { + visibility: hidden; +} +#saleDuplicates .listRow .listCell .tableContainer table tbody > tr > td.actions .removeAllDuplicatesButton, +#saleDuplicates .listRow .listCell .tableContainer table tbody > tr > td.actions .removeOneDuplicateButton { + padding: 0 2px; + color: #a00000; +} +#saleDuplicates .listRow .listCell .tableContainer table tbody > tr > td.actions .removeAllDuplicatesButton:hover, +#saleDuplicates .listRow .listCell .tableContainer table tbody > tr > td.actions .removeOneDuplicateButton:hover { + color: #f00; +} +#saleDuplicates .listRow .listCell .tableContainer table tbody > tr > td.actions .removeAllDuplicatesButton:active, +#saleDuplicates .listRow .listCell .tableContainer table tbody > tr > td.actions .removeOneDuplicateButton:active { + color: #000; +} +#saleDuplicates .listRow .listCell .tableContainer table tbody > tr.hidden:nth-child(odd) { + background-color: #f4f0ab; +} +#saleDuplicates .listRow .listCell .tableContainer table tbody > tr.hidden:nth-child(even) { + background-color: #fff6c0; +} +#saleDuplicates .listRow .listCell .tableContainer table tbody > tr.hidden:hover { + background-color: #ded; +} +#saleDuplicates .listRow .listCell .tableContainer .editComment { + color: #808080; +} +#saleDuplicates .listRow .listCell .tableContainer .hasComment { + color: #000; +} +#saleDuplicates .listRow .listCell .tableContainer .actionEdit { + margin-right: 6px; + color: #44f; +} +#saleDuplicates .saleEditor .heading { + font-size: 2em; + font-family: verdana, arial, helvetica, sans-serif; + text-transform: uppercase; + font-weight: 800; + margin: 6px 0 14px 0; +} +#saleDuplicates .saleEditor .priceContainer { + display: table; + width: 100%; +} +#saleDuplicates .saleEditor .priceContainer .price { + display: table-cell; + padding-right: 10px; +} +#saleDuplicates .saleEditor .priceContainer .priceButtons { + display: table-cell; + width: 1.5em; +} +#saleDuplicates .saleEditor .priceContainer .priceButtons .setDefaultPrice { + font-size: 1.5em; + padding: 6px 8px; + margin-left: 8px; + border-radius: 8px; +} +#saleDuplicates .saleEditor .priceContainer .priceButtons .setDefaultPrice:hover { + text-shadow: 0px 0px 6px #00b900; +} +#saleDuplicates .saleEditor .priceContainer .priceButtons .setDefaultPrice:active { + text-shadow: 0px 0px 6px #808080; +} +#saleDuplicates .insertSaleForm .form-group, +#saleDuplicates .insertSaleForm label { + text-align: left; +} +#saleDuplicates .insertSaleForm .formGroupHeading { + font-size: 1.6em; + font-family: "Arial Black", "Arial Bold", Gadget, sans-serif; + font-style: normal; + font-variant: normal; + font-weight: 500; +} +#salesSheetsMain { + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; +} +#salesSheetsMain label { + font-family: "Segoe UI", Candara, "Bitstream Vera Sans", "DejaVu Sans", "Bitstream Vera Sans", "Trebuchet MS", Verdana, "Verdana Ref", sans-serif; + font-weight: 800; + text-transform: uppercase; +} +#salesSheetsMain .optionsSection { + display: flex; + flex-flow: column; + justify-content: flex-start; + align-items: flex-start; + align-content: stretch; + width: 100%; +} +#salesSheetsMain .optionsSection .options { + flex: 0 0 auto; + display: flex; + flex-flow: row; + justify-content: flex-start; + align-items: center; + align-content: stretch; + padding: 6px 20px 10px 20px; + white-space: nowrap; + overflow: hidden; + height: 50px; +} +#salesSheetsMain .optionsSection .options .form-control { + display: inline; +} +#salesSheetsMain .optionsSection .options label { + flex: 0 0 auto; + vertical-align: text-bottom; + font-size: 1.2em; +} +#salesSheetsMain .optionsSection .options select[name="sheetSelection"] { + flex: 0 0 auto; + font-size: 1.2em; + padding: 2px; + margin-right: 4px; + min-width: 160px; + width: auto; +} +#salesSheetsMain .optionsSection .options input[name="newSheetName"] { + flex: 0 0 auto; + transition: all 0.75s ease; + width: 0; + border: 0; + opacity: 0; + font-size: 1.2em; +} +#salesSheetsMain .optionsSection .options input[name="newSheetName"].show { + opacity: 1; + border: 1px solid #ccc; + border-radius: 4px; + width: 200px; + transform: translateX(4px); +} +#salesSheetsMain .optionsSection .options .createSheet, +#salesSheetsMain .optionsSection .options .editSheet, +#salesSheetsMain .optionsSection .options .deleteSheet { + flex: 0 0 auto; + padding: 6px; + margin: 0 4px; + width: 33px; + text-align: center; + font-size: 1.5em; + border-radius: 8px; + border: 1px solid rgba(0,0,0,0); + box-sizing: border-box; +} +#salesSheetsMain .optionsSection .options .createSheet:hover, +#salesSheetsMain .optionsSection .options .editSheet:hover, +#salesSheetsMain .optionsSection .options .deleteSheet:hover { + border: 1px inset #b100d1; + -webkit-box-shadow: inset 0px 0px 20px 0px #de7cff; + -moz-box-shadow: inset 0px 0px 20px 0px #de7cff; + box-shadow: inset 0px 0px 20px 0px #de7cff; +} +#salesSheetsMain .optionsSection .options .editSheet.selected { + color: #fff; + border: 1px inset #b100d1; + -webkit-box-shadow: inset 0px 0px 36px 0px #57006c; + -moz-box-shadow: inset 0px 0px 36px 0px #57006c; + box-shadow: inset 0px 0px 36px 0px #57006c; +} +#salesSheetsMain .optionsSection .options .editSheet { + vertical-align: top; + white-space: nowrap; + overflow: hidden; +} +#salesSheetsMain .optionsSection .options .disabled { + color: #808080; + cursor: default; +} +#salesSheetsMain .optionsSection .options .createSheet { + transform: translateX(-25px) rotate(0deg); + transition: all 0.75s ease; +} +#salesSheetsMain .optionsSection .options .createSheet.move { + transform: translateX(6px) rotate(720deg); +} +#salesSheetsMain .optionsSection .separator { + flex: 0 0 auto; + width: 100%; + margin: 0 auto; + padding-top: 6px; + height: 1px; + border-bottom: 1px solid #333; +} +#salesSheetsMain .optionsSection .separator:last-child { + margin-bottom: 10px; +} +#salesSheetsMain .salesSheetProducts > div { + width: 400px; + margin: 0 4px 0 4px; +} +#salesSheetsMain .salesSheetProducts .header { + padding-top: 4px; +} +#salesSheetsMain .salesSheetProducts .header .name { + font-size: 1.5em; + text-transform: uppercase; + color: #0a6f10; + text-shadow: 0px 0px 12px #8fa4d1; + background: #fff; + font-weight: 800; + width: 100%; + padding: 4px 6px 6px 6px; + border-bottom: 2px solid #335a4a; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} +#salesSheetsMain .salesSheetProducts .product { + background-color: #ffecde; + -webkit-box-shadow: inset 0px 0px 40px 14px #fff; + -moz-box-shadow: inset 0px 0px 40px 14px #fff; + box-shadow: inset 0px 0px 40px 14px #fff; +} +#salesSheetsMain .salesSheetProducts .product .nameAndTotal { + display: flex; + flex-flow: row wrap; + justify-content: flex-start; + align-items: center; + align-content: stretch; + margin-bottom: 4px; +} +#salesSheetsMain .salesSheetProducts .product .nameAndTotal .name { + flex: 1 1 auto; + font-size: 1.5em; + color: #575757; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} +#salesSheetsMain .salesSheetProducts .product .nameAndTotal .total { + flex: 0 0 auto; + width: 80px; + font-size: 1.2em; + color: #00378b; + text-shadow: 0px 0px 8px #7690d1; + overflow: hidden; +} +#salesSheetsMain .salesSheetProducts .product .measures { + display: flex; + flex-flow: row wrap; + justify-content: flex-start; + align-items: center; + align-content: stretch; + margin-bottom: 6px; +} +#salesSheetsMain .salesSheetProducts .product .measures .measure { + flex: 1 0 auto; + display: flex; + flex-flow: row wrap; + justify-content: flex-start; + align-items: center; + align-content: stretch; +} +#salesSheetsMain .salesSheetProducts .product .measures .measure .label { + font-size: 1em; + font-weight: 600; + margin-right: 4px; +} +#salesSheetsMain .salesSheetProducts .product .measures .measure input[name="price"] { + width: 63px; +} +#salesSheetsMain .salesSheetProducts .product .measures .measure input[name="amount"] { + width: 47px; +} +#salesSheetsMain .salesSheetProducts .product.odd { + background-color: #ede0f1; + -webkit-box-shadow: inset 0px 0px 40px 14px #fff; + -moz-box-shadow: inset 0px 0px 40px 14px #fff; + box-shadow: inset 0px 0px 40px 14px #fff; +} +#salesSheetsMain .salesSheetProducts .sheetControls { + padding-top: 4px; + display: flex; + flex-flow: row wrap; + justify-content: flex-start; + align-items: center; + align-content: stretch; +} +#salesSheetsMain .salesSheetProducts .sheetControls .saveSheet, +#salesSheetsMain .salesSheetProducts .sheetControls .resetSheet { + flex: 1 1 auto; + font-size: 1em; + color: #e9e9e9; + font-weight: 800; + text-transform: uppercase; + text-align: center; + padding: 10px; + margin: 4px; +} +#salesSheetsMain .salesSheetProducts .sheetControls .saveSheet { + background: #007200; + -webkit-box-shadow: inset 0px 0px 20px -2px #fff; + -moz-box-shadow: inset 0px 0px 20px -2px #fff; + box-shadow: inset 0px 0px 20px -2px #fff; +} +#salesSheetsMain .salesSheetProducts .sheetControls .resetSheet { + background: #960000; + -webkit-box-shadow: inset 0px 0px 20px -2px #fff; + -moz-box-shadow: inset 0px 0px 20px -2px #fff; + box-shadow: inset 0px 0px 20px -2px #fff; +} +#salesSheetsMain .salesSheetProducts .sheetControls .saveSheet:hover, +#salesSheetsMain .salesSheetProducts .sheetControls .resetSheet:hover { + text-shadow: 0px 0px 16px #fff; +} +#salesSheetsMain .salesSheetProducts .sheetControls .saveSheet:hover { + background: #005600; +} +#salesSheetsMain .salesSheetProducts .sheetControls .resetSheet:hover { + background: #7f0000; +} +#salesSheetsMain .salesSheetProducts .sheetControls .saveSheet:active { + background: #009000; +} +#salesSheetsMain .salesSheetProducts .sheetControls .resetSheet:active { + background: #b90000; +} +#salesSheetsMain .salesSheetEditorControls { + margin-bottom: 8px; +} +#salesSheetsMain .tableControls { + margin-bottom: 8px; + width: 100%; + border-bottom: 2px solid #a7a8ff; + display: flex; + flex-flow: row nowrap; + justify-content: flex-start; + align-items: center; + align-content: stretch; +} +#salesSheetsMain .tableControls div, +#salesSheetsMain .tableControls span, +#salesSheetsMain .tableControls i { + flex: 0 0 auto; + margin-right: 4px; +} +#salesSheetsMain .tableControls .controlLabel { + font-size: 9px; + font-weight: 700; + color: #5a5a5a; + position: relative; + top: -2px; +} +#salesSheetsMain .tableControls .toggleShowHidden { + margin: 0 40px 0 0; + position: relative; + top: -4px; + display: inline-block; +} +#salesSheetsMain .tableControls input[name='productFilter'] { + font-size: 1.2em; + display: inline; + width: auto; +} +#salesSheetsMain .tableControls .showAlternateNames { + margin-right: 20px; +} +#salesSheetsMain .tableControls .heading { + display: inline-block; +} +#salesSheetsMain .tableControls .heading .name { + padding: 6px 10px; + margin-bottom: 6px; + border-radius: 10px; + font-size: 1.4em; + text-transform: uppercase; + font-weight: 800; + background: #c1c2ff; +} +#salesSheetsMain .tableControls .heading .nameEditor { + display: none; +} +#salesSheetsMain .tableControls .clearFilter { + font-size: 1.6em; +} +#salesSheetsMain .selectionProductsListing { + width: 100%; +} +#salesSheetsMain .selectionProductsListing .selectionProduct { + color: #9f9f9f; + font-size: 1.3em; + width: 400px; +} +#salesSheetsMain .selectionProductsListing .selectionProduct .include, +#salesSheetsMain .selectionProductsListing .selectionProduct .includeAs { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} +#salesSheetsMain .selectionProductsListing .selectionProduct .includedRemove, +#salesSheetsMain .selectionProductsListing .selectionProduct .includedAdd { + cursor: pointer; +} +#salesSheetsMain .selectionProductsListing .selectionProduct .includedRemove:hover, +#salesSheetsMain .selectionProductsListing .selectionProduct .includedAdd:hover { + color: #00f; +} +#salesSheetsMain .selectionProductsListing .selectionProduct span.deactivated { + background: #ff0; + box-shadow: inset 0px 0 100px 0px #fff; +} +#salesSheetsMain .selectionProductsListing .selectionProduct span.hidden { + background: rgba(255,20,20,0.7); + box-shadow: inset 0px 0px 100px 0px #fff; +} +#salesSheetsMain .selectionProductsListing .selectionProduct.selected { + color: #000; +} +#salesSheetsMain .configurationProductsListing { + width: 100%; +} +#salesSheetsMain .configurationProductsListing .product { + width: 300px; +} +#salesSheetsMain .configurationProductsListing .product .name { + color: #4a4a4a; + font-size: 1.1em; + margin-bottom: 6px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} +#salesSheetsMain .configurationProductsListing .product .name.edit { + display: none; +} +#salesSheetsMain .configurationProductsListing .product .nameEditor { + display: none; + margin-bottom: 6px; +} +#salesSheetsMain .configurationProductsListing .product .nameEditor input[name='name'] { + flex: 1 1 auto; + display: inline-block; +} +#salesSheetsMain .configurationProductsListing .product .nameEditor .accept, +#salesSheetsMain .configurationProductsListing .product .nameEditor .reject { + flex: 0 0 auto; + font-size: 1.7em; + margin-left: 8px; +} +#salesSheetsMain .configurationProductsListing .product .nameEditor .accept:hover { + color: #008000; +} +#salesSheetsMain .configurationProductsListing .product .nameEditor .reject:hover { + color: #f00; +} +#salesSheetsMain .configurationProductsListing .product .nameEditor .accept:active { + text-shadow: 0px 0px 10px #fda1ff; +} +#salesSheetsMain .configurationProductsListing .product .nameEditor .reject:active { + text-shadow: 0px 0px 10px #fda1ff; +} +#salesSheetsMain .configurationProductsListing .product .nameEditor.edit { + display: flex; + flex-flow: row nowrap; + justify-content: flex-start; + align-items: center; + align-content: stretch; +} +#salesSheetsMain .configurationProductsListing .product .measures { + margin: 1px 0 8px 0; +} +#salesSheetsMain .configurationProductsListing .heading { + width: 300px; +} +#salesSheetsMain .configurationProductsListing .heading .headingNameRow { + display: flex; + flex-flow: row nowrap; + justify-content: flex-start; + align-items: center; + align-content: stretch; + margin-top: 4px; + margin-bottom: 2px; + border-bottom: 1px solid #808080; +} +#salesSheetsMain .configurationProductsListing .heading .headingNameRow .name { + flex: 1 0 auto; + color: #000; + font-size: 1.5em; + text-transform: uppercase; + font-weight: 800; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} +#salesSheetsMain .configurationProductsListing .heading .headingNameRow .sort { + flex: 0 0 auto; +} +#salesSheetsMain .configurationProductsListing .heading .headingNameRow.edit { + display: none; +} +#salesSheetsMain .configurationProductsListing .heading .nameEditor { + display: none; +} +#salesSheetsMain .configurationProductsListing .heading .nameEditor input[name='name'] { + flex: 1 1 auto; + display: inline-block; +} +#salesSheetsMain .configurationProductsListing .heading .nameEditor .accept, +#salesSheetsMain .configurationProductsListing .heading .nameEditor .reject { + flex: 0 0 auto; + font-size: 1.7em; + margin-left: 8px; +} +#salesSheetsMain .configurationProductsListing .heading .nameEditor .accept:hover { + color: #008000; +} +#salesSheetsMain .configurationProductsListing .heading .nameEditor .reject:hover { + color: #f00; +} +#salesSheetsMain .configurationProductsListing .heading .nameEditor .accept:active { + text-shadow: 0px 0px 10px #fda1ff; +} +#salesSheetsMain .configurationProductsListing .heading .nameEditor .reject:active { + text-shadow: 0px 0px 10px #fda1ff; +} +#salesSheetsMain .configurationProductsListing .heading .nameEditor.edit { + display: flex; + flex-flow: row nowrap; + justify-content: flex-start; + align-items: center; + align-content: stretch; +} +.heading.gu-mirror { + width: 300px; +} +.heading.gu-mirror .name { + color: #000; + font-size: 1.5em; + text-transform: uppercase; + font-weight: 800; + margin-top: 4px; + margin-bottom: 2px; + border-bottom: 1px solid #808080; +} +.heading.gu-mirror .nameEditor { + display: none; +} +.product.gu-mirror { + color: #9f9f9f; + font-size: 1.5em; + width: 300px; +} +.product.gu-mirror .name { + font-size: 1em; +} +.product.gu-mirror .nameEditor { + display: none; +} +.product.gu-mirror .measures { + display: none; +} +#pricing { + display: table; + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; +} +#pricing .controls { + text-align: left; + display: table; + width: 100%; +} +#pricing .controls .measureGroup { + padding: 4px 8px; + margin: 4px 8px; + display: table-cell; + width: 240px; +} +#pricing .controls .measureGroup select { + width: 100%; +} +#pricing .controls .measureGroup option.deactivated { + color: #a6a6a6; +} +#pricing .controls .controlGroup { + padding: 4px 8px; + margin: 4px 8px; + display: table-cell; +} +#pricing .controls .pagination { + display: table-cell; + width: 240px; + vertical-align: bottom; +} +#pricing .controls .previousSettings { + padding: 4px 8px; + margin: 4px 8px; + display: inline-block; +} +#pricing .controls .outline { + border: 2px dotted #32747e; + border-radius: 10px; +} +#pricing .controls .floatLeft { + float: left; +} +#pricing .controls .floatRight { + float: right; +} +#pricing .controls .controlLabel { + font-size: 0.9em; + font-weight: 700; + margin-top: -2px; +} +#pricing .controls select[name="measures"] { + padding: 4px 8px; + font-size: 1.5em; +} +#pricing .controls input { + padding: 4px 8px; + font-size: 1.5em; +} +#pricing .controls input[type="number"] { + width: 80px; +} +#pricing .controls input[type="button"] { + margin-top: -6px; + margin-right: 20px; +} +#pricing .controls .toggleUpdateHistory { + margin: 0; + position: relative; + top: -4px; + display: inline-block; +} +#pricing .controls input[type="date"] { + width: 180px; + display: inline-block; +} +#pricing .controls .resetButton { + margin-left: 20px; +} +#pricing .controls .contentControls { + vertical-align: bottom; + display: table-cell; + text-align: right; +} +#pricing .controls .contentControls a { + font-size: 12px; + font-family: "Arial", san-serif; + font-weight: 800; + color: #2d1b8c; + text-decoration: none; +} +#pricing .controls .contentControls a:hover { + text-decoration: underline; +} +#pricing .controls .contentControls a.disabled { + visibility: hidden; +} +#pricing .table { + table-layout: fixed; + min-width: 100%; +} +#pricing .table thead tr > .name, +#pricing .table tbody tr > .name { + width: 100%; + min-width: 100px; +} +#pricing .table thead tr > .current, +#pricing .table tbody tr > .current { + width: 200px; + min-width: 200px; +} +#pricing .table thead tr > .previous, +#pricing .table tbody tr > .previous { + width: 200px; + min-width: 200px; +} +#pricing .table thead tr > .changeDate, +#pricing .table tbody tr > .changeDate { + width: 200px; + min-width: 200px; +} +#pricing .listRow { + display: table-row; +} +#pricing .listRow .listCell { + display: table-cell; + position: relative; + height: 100%; + width: 100%; +} +#pricing .listRow .listCell .tableContainer { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + border: 0; + font-size: 12.5px; + overflow-y: auto; +} +#pricing .listRow .listCell .tableContainer table { + table-layout: fixed; + width: 100%; +} +#pricing .listRow .listCell .tableContainer table > thead { + visibility: hidden; + display: none; +} +#pricing .listRow .listCell .tableContainer table > tbody > tr.deactivated { + background-color: #fac0d1; +} +#pricing .listRow .listCell .tableContainer table > tbody > tr.deactivated:hover { + background-color: #ffcadb; +} +#production { + display: table; + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; +} +#production .tableControls { + text-align: right; + margin-right: 20px; + margin-bottom: 4px; + display: table; + width: 100%; +} +#production .tableControls .contentControls { + vertical-align: bottom; + display: table-cell; + text-align: right; + min-width: 100px; +} +#production .tableControls .contentControls a { + font-size: 12px; + font-family: "Arial", san-serif; + font-weight: 800; + color: #2d1b8c; + text-decoration: none; +} +#production .tableControls .contentControls a:hover { + text-decoration: underline; +} +#production .tableControls .contentControls a.disabled { + visibility: hidden; +} +#production .table { + table-layout: fixed; + min-width: 100%; +} +#production .table thead > tr > .hasLabels, +#production .table tbody > tr > .hasLabels { + width: 30px; +} +#production .table thead > tr > .hasLabels .hasLabels, +#production .table tbody > tr > .hasLabels .hasLabels { + color: #008000; +} +#production .table thead > tr > .hasLabels .noLabels, +#production .table tbody > tr > .hasLabels .noLabels { + color: #f00; +} +#production .table thead > tr > .name, +#production .table tbody > tr > .name { + width: 100%; +} +#production .table thead > tr > .date, +#production .table tbody > tr > .date { + min-width: 150px; + max-width: 180px; +} +#production .table thead > tr > .amount, +#production .table tbody > tr > .amount { + min-width: 100px; + max-width: 100px; +} +#production .table thead > tr > .cook, +#production .table tbody > tr > .cook { + min-width: 150px; + max-width: 180px; +} +#production .table thead > tr > .canner, +#production .table tbody > tr > .canner { + min-width: 150px; + max-width: 180px; +} +#production .table thead > tr > .comment, +#production .table tbody > tr > .comment { + width: 220px; + min-width: 220px; + max-width: 220px; +} +#production .table thead > tr > .actions, +#production .table tbody > tr > .actions { + width: 90px; + min-width: 90px; + max-width: 90px; +} +#production .table thead > tr.deleted, +#production .table tbody > tr.deleted { + background-color: #808080; +} +#production .separatedTableHeader table thead > tr > th.actions { + text-align: center; +} +#production .separatedTableHeader table thead > tr > th.actions .newButton { + margin-top: 4px; + padding: 0 12px; +} +#production .separatedTableHeader table thead > tr > th.actions .newButton .fa-plus-circle { + display: inline-block; +} +#production .separatedTableHeader table thead > tr > th.actions .newButton .fa-times-circle { + display: none; +} +#production .separatedTableHeader table thead > tr > th.actions .newButton:active { + background-color: #fb557b; + color: #000; +} +#production .separatedTableHeader table thead > tr > th.actions .newButton:active .fa-times-circle { + display: inline-block; +} +#production .separatedTableHeader table thead > tr > th.actions .newButton:active .fa-plus-circle { + display: none; +} +#production .separatedTableHeader table thead > tr > th.actions .showDeletedButton { + margin-top: 4px; + padding: 0 12px; + color: #808080; +} +#production .separatedTableHeader table thead > tr > th.actions .showDeletedButton.selected { + color: #000; +} +#production .listRow { + display: table-row; +} +#production .listRow .listCell { + display: table-cell; + position: relative; + height: 100%; + width: 100%; +} +#production .listRow .listCell .tableContainer { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + border: 0; + font-size: 12.5px; + overflow-y: auto; +} +#production .listRow .listCell .tableContainer table thead { + visibility: hidden; + display: none; +} +#production .listRow .listCell .tableContainer table .search { + margin: 3px 0 2px 1px; +} +#production .listRow .listCell .tableContainer table .editorTd { + background: #deeac0; +} +#production .listRow .listCell .tableContainer table input, +#production .listRow .listCell .tableContainer table select { + width: 100%; +} +#production .listRow .listCell .tableContainer table .editorDiv { + margin: 4px 0; +} +#production .listRow .listCell .tableContainer table .editorDiv label { + font-family: "Arial Black", "Arial Bold", Gadget, sans-serif; + font-size: 0.9em; + padding-bottom: 4px; +} +#production .listRow .listCell .tableContainer table .editorDiv select2 { + font-size: 0.4em; +} +#production .listRow .listCell .tableContainer table > tbody > tr .actionRemove { + color: #f77; +} +#production .listRow .listCell .tableContainer table > tbody > tr .actionEdit { + color: #44f; +} +#production .listRow .listCell .tableContainer table > tbody > tr .editorApply { + color: #008000; +} +#production .listRow .listCell .tableContainer table > tbody > tr .editorCancel { + color: #f00; +} +#workers { + display: table; + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; +} +#workers .tableControls { + display: table; + width: 100%; + text-align: right; + margin-right: 20px; +} +#workers .tableControls .showHidden { + display: table-cell; + width: 100%; +} +#workers .tableControls .showHidden .controlLabel { + font-size: 9px; + font-weight: 700; + color: #5a5a5a; + position: relative; + top: -2px; +} +#workers .tableControls .showHidden .toggleShowHidden { + margin: 0 40px 0 0; + position: relative; + top: -4px; + display: inline-block; +} +#workers .tableControls .contentControls { + vertical-align: bottom; + display: table-cell; + text-align: right; + min-width: 100px; +} +#workers .tableControls .contentControls a { + font-size: 12px; + font-family: "Arial", san-serif; + font-weight: 800; + color: #2d1b8c; + text-decoration: none; +} +#workers .tableControls .contentControls a:hover { + text-decoration: underline; +} +#workers .tableControls .contentControls a.disabled { + visibility: hidden; +} +#workers .table { + table-layout: fixed; + min-width: 100%; +} +#workers .table thead > tr > .name, +#workers .table tbody > tr > .name { + width: 30%; + min-width: 100px; +} +#workers .table thead > tr > .activities, +#workers .table tbody > tr > .activities { + width: 50%; + min-width: 100px; +} +#workers .table thead > tr > .hourlyRate, +#workers .table tbody > tr > .hourlyRate { + width: 20%; + min-width: 100px; +} +#workers .table thead > tr > .actions, +#workers .table tbody > tr > .actions { + width: 90px; + min-width: 90px; +} +#workers .separatedTableHeader table thead > tr .actions { + text-align: center; +} +#workers .separatedTableHeader table thead > tr .actions .newWorkerButton { + margin-top: 4px; + padding: 0 12px; +} +#workers .separatedTableHeader table thead > tr .actions .newWorkerButton .fa-plus-circle { + display: inline-block; +} +#workers .separatedTableHeader table thead > tr .actions .newWorkerButton .fa-times-circle { + display: none; +} +#workers .separatedTableHeader table thead > tr .actions .newWorkerButton.active { + background-color: #fb557b; + color: #000; +} +#workers .separatedTableHeader table thead > tr .actions .newWorkerButton.active .fa-times-circle { + display: inline-block; +} +#workers .separatedTableHeader table thead > tr .actions .newWorkerButton.active .fa-plus-circle { + display: none; +} +#workers .listRow { + display: table-row; +} +#workers .listRow .listCell { + display: table-cell; + position: relative; + height: 100%; + width: 100%; +} +#workers .listRow .listCell .tableContainer { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + border: 0; + font-size: 12.5px; + overflow-y: auto; +} +#workers .listRow .listCell .tableContainer table { + table-layout: fixed; + width: 100%; +} +#workers .listRow .listCell .tableContainer table .workerSearch { + margin: 3px 0 2px 1px; +} +#workers .listRow .listCell .tableContainer table .workerEditorTd { + background: #deeac0; +} +#workers .listRow .listCell .tableContainer table input[name="name"], +#workers .listRow .listCell .tableContainer table .activitiesEditor, +#workers .listRow .listCell .tableContainer table input[name="hourlyRate"] { + width: 100%; +} +#workers .listRow .listCell .tableContainer table .editorDiv { + margin: 4px 0; +} +#workers .listRow .listCell .tableContainer table .editorDiv label { + font-family: "Arial Black", "Arial Bold", Gadget, sans-serif; + font-size: 0.9em; + padding-bottom: 4px; +} +#workers .listRow .listCell .tableContainer table .editorDiv select2 { + font-size: 0.4em; +} +#workers .listRow .listCell .tableContainer table > thead { + display: none; + visibility: hidden; +} +#workers .listRow .listCell .tableContainer table > tbody > tr .actionRemove { + color: #f77; +} +#workers .listRow .listCell .tableContainer table > tbody > tr .actionEdit { + color: #44f; +} +#workers .listRow .listCell .tableContainer table > tbody > tr .editorApply { + color: #008000; +} +#workers .listRow .listCell .tableContainer table > tbody > tr .editorCancel { + color: #f00; +} +#workers .listRow .listCell .tableContainer table > tbody > tr.deactivated { + background-color: #fac0d1; +} +#workers .listRow .listCell .tableContainer table > tbody > tr.deactivated .actionActivate { + color: #158b18; +} +#workers .listRow .listCell .tableContainer table > tbody > tr.deactivated .actionHide { + color: #6a0707; +} +#workers .listRow .listCell .tableContainer table > tbody > tr.deactivated .actionEdit { + color: #0101e4; +} +#workers .listRow .listCell .tableContainer table > tbody > tr.deactivated:hover { + background-color: #ffcadb; +} +#workers .listRow .listCell .tableContainer table > tbody > tr.hidden { + background-color: #e995ff; +} +#workers .listRow .listCell .tableContainer table > tbody > tr.hidden .actionEdit { + color: #0101e4; +} +#workers .listRow .listCell .tableContainer table > tbody > tr.hidden .actionShow { + color: #027905; +} +#workers .listRow .listCell .tableContainer table > tbody > tr.hidden:hover { + background-color: #ffb5ff; +} +#graphs { + display: table; + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; +} +#graphs svg { + width: 100%; +} +#graphs .bar { + fill: #4682b4; +} +#graphs .xAxisLabels { + font-size: 7px; + font-family: "Arial", Gadget, sans-serif; + font-weight: 100; +} +#graphs .yAxisLabels { + font-size: 12px; + font-family: "Arial Black", "Arial Bold", Gadget, sans-serif; + font-weight: 800; +} +#graphs .barText { + font-size: 14px; + font-family: "Arial Black", "Arial Bold", Gadget, sans-serif; + font-weight: 800; +} +#graphs .table { + table-layout: fixed; +} +#graphs .table .total { + width: 200px; +} +#graphs .table .market { + width: 200px; +} +#graphs .table .week { + width: 200px; +} +#graphs .table .month { + width: 200px; +} +#graphs .table .year { + width: 200px; +} +#graphs .listRow { + display: table-row; +} +#graphs .listRow .listCell { + display: table-cell; + position: relative; + height: 100%; + width: auto; + min-width: 300px; +} +#graphs .listRow .listCell .salesTable { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + border: 0; + font-size: 12.5px; + overflow-y: scroll; +} +#graphs .listRow .listCell .salesTable .table > thead { + display: none; +} +#graphs .listRow .listCell .salesTable .table > tbody > tr.deactivated { + background-color: #fac0d1; +} +#graphs .listRow .listCell .salesTable .table > tbody > tr.deactivated:hover { + background-color: #ffcadb; +} +#graphs .listRow .spacerCell { + display: table-cell; + position: relative; + width: 100%; + height: 100%; +} +#reports { + display: table; + content-box: border-box; + padding: 10px 20px; + height: 100%; + width: 100%; + text-align: left; + margin-left: 20px; +} +#labelMaker { + margin: 10px 20px; + height: 100%; + width: 100%; + overflow-y: auto; +} +@media not print { + #labelMaker .labelOptions label { + font-family: TimesNewRoman, Times New Roman, Times; + font-weight: 200; + font-size: 14px; + } + #labelMaker .labelOptions .title1 { + width: 500px; + font-family: TimesNewRoman, Times New Roman, Times; + font-size: 0.142in; + font-weight: 800; + line-height: 0.142in; + } + #labelMaker .labelOptions .title2 { + width: 500px; + font-family: TimesNewRoman, Times New Roman, Times; + font-size: 14px; + font-weight: 800; + line-height: 16px; + } + #labelMaker .labelOptions .ingredients { + width: 500px; + height: 100px; + font-family: TimesNewRoman, Times New Roman, Times; + font-size: 12px; + font-weight: 100; + line-height: 14px; + } + #labelMaker .labelOptions .date { + width: 500px; + font-family: TimesNewRoman, Times New Roman, Times; + font-size: 12px; + font-weight: 100; + line-height: 14px; + } + #labelMaker .labelContainer { + text-align: center; + width: 100%; + width-min: 3in; + height-min: 2in; + background-color: #808080; + padding: 20px; + } + #labelMaker .labels { + display: none; + } + #labelMaker .printableLabel { + display: none; + } + #labelMaker .label { + display: inline-block; + width: 3in; + height: 2in; + } + #labelMaker .canvasContainer { + padding: 10px; + background-color: #808080; + } +} +@media all { + #labelMaker .label { + position: relative; + background-color: #fff; + color: #000; + text-align: center; + font-family: TimesNewRoman, Times New Roman, Times; + font-size: 0.1in; + width: 3in; + height: 2in; + } + #labelMaker .label .barcodeContainer { + position: absolute; + transform: rotate(270deg) scale(0.7); + right: -10em; + top: 7em; + } + #labelMaker .label .qrcode { + position: absolute; + left: 3px; + top: 3px; + } + #labelMaker .label .labelLogo { + width: 8em; + padding: 0; + margin: 0; + padding-top: 0.15em; + margin-bottom: 0.2em; + } + #labelMaker .label .labelLogo3 { + width: 14em; + padding: 0; + margin: 0; + padding-top: 0.15em; + margin-bottom: 0.8em; + } + #labelMaker .label .labelTagline { + font-size: 1em; + font-weight: 100; + line-height: 1em; + } + #labelMaker .label .title1 { + width: 100%; + font-size: 2.5em; + line-height: 0.9em; + font-weight: 800; + text-transform: uppercase; + } + #labelMaker .label .title2 { + width: 100%; + font-size: 1.5em; + line-height: 0.9em; + font-weight: 800; + padding-bottom: 0.2em; + } + #labelMaker .label .ingredients { + width: 100%; + font-size: 1.2em; + font-weight: 100; + line-height: 1em; + min-height: 2em; + } + #labelMaker .label .ingredientsEnding { + width: 100%; + font-size: 1.2em; + font-weight: 100; + } + #labelMaker .label .instructions { + width: 100%; + font-size: 1.2em; + font-weight: 800; + } + #labelMaker .label .address { + width: 100%; + font-size: 1.2em; + font-weight: 100; + } + #labelMaker .label .website { + width: 100%; + font-size: 1.2em; + font-weight: 100; + } +} +@media print { + @page { + size: 3in 2in; + margin: 0; + padding: 0; + } + #labelMaker .labelOptions, + #labelMaker .labelContainer, + #labelMaker .canvasContainer, + #labelMaker .labelCanvas { + display: none; + } + #labelMaker .printableLabel { + display: block; + margin: 0; + padding: 0; + } + #labelMaker .canvasContainer { + display: none; + } +} +@media print { + .labelMaker { + margin: 0; + padding: 0; + overflow: visible; + } +} +#testList { + margin: 10px 20px; + height: 100%; +} +#PrintLabel .labelContainer { + text-align: center; + width-min: 3in; + width: 3in; + height-min: 2in; + height: 2in; +} +#PrintLabel .labels { + display: none; +} +#PrintLabel .printableLabel { + display: none; +} +#PrintLabel .label { + display: inline-block; + width: 3in; + height: 2in; +} +#PrintLabel .canvasContainer { + padding: 10px; + background-color: #808080; +} +#PrintLabel .label { + position: relative; + background-color: #fff; + color: #000; + text-align: center; + font-family: TimesNewRoman, Times New Roman, Times; + font-size: 0.1in; + width: 3in; + height: 2in; +} +#PrintLabel .label .barcodeContainer { + position: absolute; + transform: rotate(270deg); + right: -4.5em; + top: 5em; +} +#PrintLabel .label .qrcode { + position: absolute; + left: 10px; + top: 10px; +} +#PrintLabel .label .labelLogo { + width: 8em; + padding: 0; + margin: 0; + padding-top: 0.15em; + margin-bottom: 0.2em; +} +#PrintLabel .label .labelLogo3 { + width: 14em; + padding: 0; + margin: 0; + padding-top: 0.15em; + margin-bottom: 0.8em; +} +#PrintLabel .label .labelTagline { + font-size: 1em; + font-weight: 100; + line-height: 1em; +} +#PrintLabel .label .title1 { + width: 100%; + font-size: 2.5em; + line-height: 0.9em; + font-weight: 800; + text-transform: uppercase; +} +#PrintLabel .label .title2 { + width: 100%; + font-size: 1.5em; + line-height: 0.9em; + font-weight: 800; + padding-bottom: 0.2em; +} +#PrintLabel .label .ingredients { + width: 100%; + font-size: 1.2em; + font-weight: 100; + line-height: 1em; + min-height: 2em; +} +#PrintLabel .label .ingredientsEnding { + width: 100%; + font-size: 1.2em; + font-weight: 100; +} +#PrintLabel .label .instructions { + width: 100%; + font-size: 1.2em; + font-weight: 800; +} +#PrintLabel .label .address { + width: 100%; + font-size: 1.2em; + font-weight: 100; +} +#PrintLabel .label .website { + width: 100%; + font-size: 1.2em; + font-weight: 100; +} diff --git a/client/main.styl b/client/main.styl index 375ca43..e1eb162 100644 --- a/client/main.styl +++ b/client/main.styl @@ -188,4 +188,6 @@ body @import "../imports/ui/Graphs.import.styl" @import "../imports/ui/Reports.import.styl" @import "../imports/ui/Label.import.styl" -@import "../imports/ui/TestList.import.styl" \ No newline at end of file +@import "../imports/ui/TestList.import.styl" + +@import "../imports/ui/PrintLabel.import.styl" \ No newline at end of file diff --git a/imports/api/Barcode.js b/imports/api/Barcode.js new file mode 100644 index 0000000..6b9c0b7 --- /dev/null +++ b/imports/api/Barcode.js @@ -0,0 +1,81 @@ +import {Mongo} from "meteor/mongo"; +import { Meteor } from 'meteor/meteor'; +import { check } from 'meteor/check'; +import {SimpleSchema} from 'meteor/aldeed:simple-schema'; + +Barcodes = new Mongo.Collection('Barcodes'); + +// A simple mapping between a concatenation of the product & measure ID and a unique sequential number for the barcode. This allows us to have a small number to keep our barcodes simple, while maintaining the more traditional MongoDB ID's for the Product and Measure. +const BarcodesSchema = new SimpleSchema({ + barcodeId: { + type: Number, + label: "Barcode ID", + optional: false, + index: 1, + unique: true + }, + productAndMeasureId: { //Just the two ids jammed together with a single space between them. + type: String, + label: "Product And Measure ID", + optional: false, + index: 1, + unique: true + } +}); + +if(Meteor.isServer) { + //Meteor.publish('barcodes', function() { + // return Barcodes.find({}); + //}); + + Meteor.methods({ + getBarcodeId: function(productId, measureId) { + check(productId, String); + check(measureId, String); + + let hasProduct = Meteor.collections.Products.findOne({_id: productId}, {fields: {}}); + let hasMeasure = Meteor.collections.Measures.findOne({_id: measureId}, {fields: {}}); + + if(hasProduct && hasMeasure) { + let existing = Barcodes.findOne({productAndMeasureId: productId + ' ' + measureId}); + + if(existing) { + return existing.barcodeId; + } + else { + let c = 0; + + //Try a thousand times before failing. Should never fail, should also not ever need to try a thousand times (unless we somehow automate label generation to the point where a 1000 processes at once are requesting labels that have never been generated before - highly unlikely). + while(c++ < 1000) { + //Lookup the most likely next barcode id from the db, then attempt to insert with it. If it fails due to duplication, then increment and repeat. + let cursor = Products.find({}, {barcodeId: 1}).sort({barcodeId: -1}).limit(1); //Since currently products are never removed, we shouldn't need to detect sequence gaps and fill them in (odds are we will never use more than 10k numbers anyway). + let barcodeId = cursor.hasNext() ? cursor.next().barcodeId + 1 : 1; + + Barcodes.insert({productAndMeasureId: productId + ' ' + measureId, barcodeId}, function(err, id) { + if(err) console.log(err); + else return barcodeId; + }); + } + + //If we are still here, then there was a massive failure (c exceeded 1000). + console.log("We failed to generate a new barcode ID 1000 times, so we are giving up. This should never happen."); + throw new Meteor.Error(403, "Unable to generate a barcode ID."); + } + } + else { + //Cannot find either the product or the measure in the db. Cannot give an id. + console.log("Unable to generate a barcode ID because we could not find the product " + productId + " OR we could not find the measure " + measureId); + throw new Meteor.Error(403, "Unable to find the product or the measure. Both must exist in order to generate a barcode ID."); + } + }, + }); +} + +//Allows the client to do DB interaction without calling server side methods, while still retaining control over whether the user can make changes. +Barcodes.allow({ + insert: function() {return false;}, + update: function() {return false;}, + remove: function() {return false;} +}); + +export default Barcodes; \ No newline at end of file diff --git a/imports/api/Batch.js b/imports/api/Batch.js new file mode 100644 index 0000000..d5fd9f7 --- /dev/null +++ b/imports/api/Batch.js @@ -0,0 +1,265 @@ +import { Meteor } from 'meteor/meteor'; +import { Mongo } from 'meteor/mongo'; +import { check } from 'meteor/check'; +import {SimpleSchema} from 'meteor/aldeed:simple-schema'; + +/** + * Notes: + * The Batch object has a date field which stores the date as a number in the format YYYYMMDD. Converting this number into a local date is done with moment(batch.date.toString(), "YYYYMMDD").toDate(), and converting it to a number from a date can be accomplished with ~~(moment(date).format("YYYYMMDD")), where the ~~ is a bitwise not and converts a string to a number quickly and reliably. + * A Batch in this system refers to one or more instances of cooking or preparing a product on a given date. It does NOT refer to each instance of cooking the product on that date (what might be called a batch in a kitchen). This might be more effectively called a Run, but that is a confusing word to use in a software system, so I chose to reuse the word Batch since we will not be tracking kitchen batches, just kitchen runs. + */ + +let Batches = new Mongo.Collection('Batches'); +let BatchesSchema = new SimpleSchema({ + date: { + type: Number, // A number in the format of YYYYMMDD to allow for searching using greater and less than, and to prevent timezones from messing everything up. + label: "Date", + optional: false, + index: 1 + }, + timestamp: { //This is based off the date with zero for the time and set to GMT (Zulu time). + type: Date, + label: "Timestamp", + optional: true + }, + weekOfYear: { + type: Number, + label: "Week Of Year", + optional: true + }, + amount: { + type: Number, + label: "Amount", + optional: false, + decimal: true + }, + measureId: { + type: String, + label: "Measure Id", + trim: false, + regEx: SimpleSchema.RegEx.Id, + index: 1 + }, + productId: { + type: String, + label: "Product Id", + trim: false, + regEx: SimpleSchema.RegEx.Id, + index: 1, + optional: false + }, + cookId: { + type: String, + label: "Cook Worker Id", + trim: false, + regEx: SimpleSchema.RegEx.Id, + index: 1 + }, + cannerId: { + type: String, + label: "Canner Worker Id", + trim: false, + regEx: SimpleSchema.RegEx.Id, + index: 1, + optional: false + }, + hasLabels: { + type: Boolean, + label: "Has Labels", + optional: false, + defaultValue: false + }, + comment: { + type: String, + trim: false, + optional: true + }, + createdAt: { + type: Date, + label: "Created On", + optional: false + }, + deletedAt: { + type: Date, + label: "Deleted On", + optional: true + } +}); +Batches.attachSchema(BatchesSchema); +//Ensure that the product ID, measure ID, and date combination are unique. +// Note: I took this out because while it provides for cleaner views, it is overly complicated and could be easily done with a cleanup routine after the fact, or by aggregating the data in the queries. +// What makes this complicated is the notes, cook, and canner references which may not be the same. +//Batches.createIndex({productId: 1, measureId: 1, date: 1}, {unique: true, name: "ProductMeasureDateIndex"}); + +if(Meteor.isServer) { + Meteor.publish('batches', function(query, sort, limit = 100, skipCount) { + let dbQuery = []; + + if(query) { + _.each(_.keys(query), function(key) { + //if(_.isObject(query[key])) dbQuery.push({[key]: query[key]}); + if(_.isObject(query[key])) { + if(query[key].type === 'dateRange') { + if(query[key].start && query[key].end) + dbQuery.push({[key]: {$gte: query[key].start, $lte: query[key].end}}); + else if(query[key].start) + dbQuery.push({[key]: {$gte: query[key].start}}); + else if(query[key].end) + dbQuery.push({[key]: {$lte: query[key].end}}); + // Do nothing if a start and/or end are not provided. + } + else { + dbQuery.push({[key]: query[key]}); + } + } + else if(_.isNumber(query[key])) dbQuery.push({[key]: query[key]}); + else { + let searchValue = query[key]; + let searches = searchValue && searchValue.length > 0 ? searchValue.split(/\s+/) : undefined; + + for(let search of searches) { + dbQuery.push({[key]: {$regex: '\\b' + search, $options: 'i'}}); + } + } + }); + } + + if(!_.isNumber(limit)) limit = 100; + if(!_.isNumber(skipCount) || skipCount < 0) skipCount = 0; + + dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {}; + return Meteor.collections.Batches.find(dbQuery, {limit: limit, sort, skip: skipCount}); + }); + + Meteor.methods({ + getBatchCount: function(query) { + //TODO: Validate the query? + return Sales.find(query).count(); + }, + insertBatches: function(batches) { //Insert one or more batches (if one, you can pass just the batch). + if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) { + //Force it to be an array if it isn't. + if(!Array.isArray(batches)) batches = [batches]; + + //Validate them all. + for(let batch of batches) { + check(batch, { + date: Number, // TODO: Check that the format is YYYYMMDD + amount: Match.Where(function(x) { + check(x, Number); + return x > 0; + }), + measureId: String, + productId: String, + cookId: String, + cannerId: String, + comment: Match.Optional(String) + }); + } + + for(let batch of batches) { + let dateString = batch.date.toString(); + + batch.createdAt = new Date(); + batch.timestamp = new Date(dateString.substring(0, 4) + "-" + dateString.substring(4, 6) + "-" + dateString.substring(6, 8) + "T00:00:00Z"); + batch.weekOfYear = batch.timestamp.getWeek().toString(); + + if(batch.hasLabels === undefined) batch.hasLabels = false; + } + + for(let batch of batches) { + Batches.insert(batch, function(err, id) { + if(err) console.log(err); + }, {bypassCollection2: true}); + } + } + else throw new Meteor.Error(403, "Not authorized."); + }, + deleteBatch: function(id) { //Does not actually delete the batch, but rather just marks it for deleting by applying a deletion date. + check(id, String); + + if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) { + let deletedAt = new Date(); + + //Batches.remove(id); + Batches.update(id, {$set: {deletedAt}}, function(err, id) { + if(err) console.log(err); + }); + } + else throw new Meteor.Error(403, "Not authorized."); + }, + undeleteBatch: function(id) { //Revokes the previous deletion. + check(id, String); + + if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) { + Batches.update(id, {$unset: {deletedAt:""}}, function(err, id) { + if(err) console.log(err); + }); + } + else throw new Meteor.Error(403, "Not authorized."); + }, + editBatchComment: function(id, comment) { + check(id, String); + check(comment, String); + //Trim and convert empty comment to undefined. + comment = comment ? comment.trim() : undefined; + comment = comment && comment.length > 0 ? comment : undefined; + + if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) { + console.log("Changed comment of " + id + " to: " + comment); + + if(comment) { + Batches.update(id, {$set: {comment}}, function(error, count) { + if(error) throw new Meteor.Error(400, "Unexpected database error: " + error); + }); + } + else { + Batches.update(id, {$unset: {comment: ""}}, function(error, count) { + if(error) throw new Meteor.Error(400, "Unexpected database error: " + error); + }); + } + } + else throw new Meteor.Error(403, "Not authorized."); + }, + updateBatch: function(id, date, amount) { + check(id, String); + check(date, Number); // TODO: Check that the format is YYYYMMDD + check(amount, Number); + + let dateString = date.toString(); + let timestamp = new Date(dateString.substring(0, 4) + "-" + dateString.substring(4, 6) + "-" + dateString.substring(6, 8) + "T00:00:00Z"); + let weekOfYear = timestamp.getWeek().toString(); + + if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) { + Batches.update(id, {$set: {date, amount, timestamp, weekOfYear}}, function(err, id) { + if(err) console.log(err); + }, {bypassCollection2: true}); + } + else throw new Meteor.Error(403, "Not authorized."); + }, + setBatchHasLabels: function(id, hasLabels) { + //console.log(id); + //console.log(hasLabels); + //check(id, Meteor.validators.ObjectID); + check(id, String); + check(hasLabels, Boolean); + + if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) { + Batches.update(id, {$set: {hasLabels}}, function(err, id) { + if(err) console.log(err); + }, {bypassCollection2: true}); + } + else throw new Meteor.Error(403, "Not authorized."); + } + }); +} + + +//Allows the client to do DB interaction without calling server side methods, while still retaining control over whether the user can make changes. +Batches.allow({ + insert: function() {return false;}, + update: function() {return false;}, + remove: function() {return false;} +}); + +export default Batches; \ No newline at end of file diff --git a/imports/api/Label.js b/imports/api/Label.js new file mode 100644 index 0000000..9ff2497 --- /dev/null +++ b/imports/api/Label.js @@ -0,0 +1,130 @@ +import { Meteor } from 'meteor/meteor'; +import { Mongo } from 'meteor/mongo'; +import { check } from 'meteor/check'; +import {SimpleSchema} from 'meteor/aldeed:simple-schema'; + + +if(Meteor.isServer) { + const puppeteer = require('puppeteer'); + //let Future = Npm.require('fibers/future'); + // + //async function printLabels(data, callback) { + // let params = ""; + // let url = Meteor.absoluteUrl("/LabelPrint"); + // + // params = Object.keys(data).map(function(k) { + // return encodeURIComponent(k) + "=" + encodeURIComponent(data[k]); + // }).join('&'); + // + // url += "?" + params; + // + // const browser = await puppeteer.launch(); + // const page = await browser.newPage(); + // console.log("Going to: " + url); + // await page.goto(url, {waitUntil: 'networkidle0'}); + // // By removing the `path` option, we will receive a `Buffer` from `page.pdf`. + // const pdf = await page.pdf({ width: "6in", height: "4in"}); // format: "A4" //path: 'C:\\Users\\Grumpy\\label.pdf' + // + // await browser.close(); + // callback(null, pdf); + //} + + Meteor.methods({ + //printLabels: function(width, height, layout, title1, title2, ingredients, date) { + // console.log("Loaded Label"); + // let future = new Future(); + // + // let boundCallback = Meteor.bindEnvironment(function(err, res) { + // if(err) { + // future.throw(err); + // } + // else { + // future.return(res); + // } + // }); + // + // printLabels({width, height, layout, title1, title2, ingredients, date}, boundCallback); + // + // return future.wait(); + //} + + async printLabels(width, height, layout, title1, title2, ingredients, date) { + let data = {width, height, layout, title1, title2, ingredients, date}; + let params = ""; + let url = Meteor.absoluteUrl("/PrintLabel"); + + //Switch to the static page - for some reason the Meteor page is not loading correctly (it just appears blank). + //url = Meteor.absoluteUrl("/LabelPrint.html"); + + params = Object.keys(data).map(function(k) { + return encodeURIComponent(k) + "=" + encodeURIComponent(data[k]); + }).join('&'); + + url += "?" + params; + + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + //url = Meteor.absoluteUrl("/StaticTest.html"); + //url = Meteor.absoluteUrl("/StaticTest.html"); + console.log("Going to: " + url); + await page.goto(url, {waitUntil: 'networkidle0'}); //, {waitUntil: 'networkidle0'} + const pdf = await page.pdf({width: '3in', height: '2in'}); //path: 'C:\\Users\\Grumpy\\label.pdf', + //const pdf = await page.pdf({format: 'A4'}); + //await page.pdf({path: 'C:\\Users\\Grumpy\\label.pdf', width: '6in', height: '4in'}); + await browser.close(); + + return new Uint8Array(pdf, 0, pdf.length); + } + }); + + //Returns a JSON containing a denormalized list of products {product_id, measure_id, product_name, measure_name, price, } + WebApp.connectHandlers.use("/labels/GetBarCodeData", (req, res, next) => { + try { + let barcodes = Meteor.collections.Barcodes.find({}, {fields: {_id: 0, barcodeId: 1, productAndMeasureId: 1}}); + let measures = Meteor.collections.Measures.find({}, {fields: {_id: 1, name: 1}, sort: {order: 1}}).fetch(); + //Note: Price data looks like this: {XZ5Z3CM49NDrJNADA /* MeasureID */: {price: 10.5, effectiveDate: ISODate("2017-01-12T13:14:18.876-08:00"), previousPrice: 9}, ...} + //Measures is an array of MeasureIDs valid for this product. + let products = Meteor.collections.Products.find({}, {fields: {_id: 1, name: 1, measures: 1, prices: 1}, sort: {order: 1}}).fetch(); + //let measuresById = measures.reduce((map, measure) => (map[measure._id] = measure), {}); + let measuresById = {}; + let barcodesByProductAndMeasureIds = {}; + let result = {}; + let today = new Date(); + + for(measure of measures) measuresById[measure._id] = measure; + for(barcode of barcodes) barcodesByProductAndMeasureIds[barcode.productAndMeasureId] = barcode.barcodeId; + //console.log(measuresById); + + //for(let measureId of Object.keys(measuresById)) { + // console.log(measureId + ":" + measuresById[measureId].name); + //} + + for(let product of products) { + for(let measureId of product.measures) { + let measureName = measuresById[measureId] ? measuresById[measureId].name : undefined; + let priceData = product.prices ? product.prices[measureId] : undefined; + let price = (priceData ? (priceData.effectiveDate && moment(priceData.effectiveDate).isAfter(today) ? priceData.previousPrice : priceData.price) : 0); //Get the price based on the effective date - whether we should use the new price or the old. + let barcodeId = barcodesByProductAndMeasureIds[productId + " " + measureId]; + + //Ignore any product/measure combinations that don't have barcodes. + if(barcodeId) { + result[barcodeId] = {productId: product._id, measureId: measureId, productName: product.name, measureName, price}; + } + + //TODO: Pass the product & measure data separately from the barcodes also to handle the missing barcode scenario. When a user types in a product name and picks a measure, we can record in the sale the product ID and measure ID, and we can lookup any pricing data. + + //Log any errors so we can figure out what is going on. + if(measureName === undefined) { + //Note: We will pass a price of zero if the price is unknown. This should be fine for now. + console.log(product._id + " " + product.name + " references a measure (" + measureId + ") which is not in the measures array."); + } + } + } + + res.end(JSON.stringify(result), "JSON"); + } catch(err) { + console.log(err); + res.end(); + } + }); +} \ No newline at end of file diff --git a/imports/api/Measure.js b/imports/api/Measure.js index c4c57de..6477869 100644 --- a/imports/api/Measure.js +++ b/imports/api/Measure.js @@ -120,4 +120,11 @@ if(Meteor.isServer) { }); } +//Allows the client to do DB interaction without calling server side methods, while still retaining control over whether the user can make changes. +Measures.allow({ + insert: function() {return false;}, + update: function() {return false;}, + remove: function() {return false;} +}); + export default Measures; \ No newline at end of file diff --git a/imports/api/Product.js b/imports/api/Product.js index 9309488..e880113 100644 --- a/imports/api/Product.js +++ b/imports/api/Product.js @@ -132,12 +132,12 @@ const ProductsSchema = new SimpleSchema({ label: "Updated On", optional: true }, - deactivated: { + deactivated: { //This is turned on first, if true it will hide the product in production views, but keep the product available in the sale views. It is intended to be turned on for products that are no longer produced, but for which we have remaining inventory. type: Boolean, label: "Deactivated", optional: true }, - hidden: { + hidden: { //Deactivated must first be true. Hides the product everywhere in the system except in historical pages. The inventory should be all sold prior to hiding a product. type: Boolean, label: "Hidden", optional: true @@ -188,6 +188,10 @@ if(Meteor.isServer) { if(measures) check(measures, [String]); if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) { + //Lookup the most likely next barcode id from the db, then attempt to insert with it. If it fails due to duplication, then increment and repeat. + //let cursor = Products.find({}, {barCodeId: 1}).sort({barCodeId: -1}).limit(1); //Since currently products are never removed, we shouldn't need to detect sequence gaps and fill them in (odds are we will never use more than 10k numbers anyway). + //let barCodeId = cursor.hasNext() ? cursor.next().barCodeId : 1; + // Products.insert({name, tags, aliases, measures, createdAt: new Date()}, {bypassCollection2: true}, function(err, id) { if(err) console.log(err); }); diff --git a/imports/api/ProductTag.js b/imports/api/ProductTag.js index 74d5452..39da302 100644 --- a/imports/api/ProductTag.js +++ b/imports/api/ProductTag.js @@ -90,4 +90,11 @@ if(Meteor.isServer) { }); } +//Allows the client to do DB interaction without calling server side methods, while still retaining control over whether the user can make changes. +ProductTags.allow({ + insert: function() {return false;}, + update: function() {return false;}, + remove: function() {return false;} +}); + export default ProductTags; \ No newline at end of file diff --git a/imports/api/SalesSheet.js b/imports/api/SalesSheet.js index 0891492..eda0cb5 100644 --- a/imports/api/SalesSheet.js +++ b/imports/api/SalesSheet.js @@ -157,4 +157,11 @@ if(Meteor.isServer) { }); } +//Allows the client to do DB interaction without calling server side methods, while still retaining control over whether the user can make changes. +SalesSheets.allow({ + insert: function() {return false;}, + update: function() {return false;}, + remove: function() {return false;} +}); + export default SalesSheets; \ No newline at end of file diff --git a/imports/api/Venue.js b/imports/api/Venue.js index 49557ff..3e9a64c 100644 --- a/imports/api/Venue.js +++ b/imports/api/Venue.js @@ -126,4 +126,11 @@ if(Meteor.isServer) { }); } +//Allows the client to do DB interaction without calling server side methods, while still retaining control over whether the user can make changes. +Venues.allow({ + insert: function() {return false;}, + update: function() {return false;}, + remove: function() {return false;} +}); + export default Venues; \ No newline at end of file diff --git a/imports/api/Worker.js b/imports/api/Worker.js index 7660999..e64315e 100644 --- a/imports/api/Worker.js +++ b/imports/api/Worker.js @@ -3,7 +3,7 @@ import { Mongo } from 'meteor/mongo'; import { check } from 'meteor/check'; import {SimpleSchema} from 'meteor/aldeed:simple-schema'; -Workers = new Mongo.Collection('Workers'); +let Workers = new Mongo.Collection('Workers'); let WORKER_ACTIVITIES = ['sales', 'prep', 'canning', 'farming']; let workersSchema = new SimpleSchema({ name: { @@ -60,7 +60,7 @@ let workersSchema = new SimpleSchema({ workersSchema.constants = {activities: WORKER_ACTIVITIES}; Workers.attachSchema(workersSchema); -if(Meteor.isServer) Meteor.publish('Workers', function() { +if(Meteor.isServer) Meteor.publish('workers', function() { return Workers.find({}); }); @@ -122,4 +122,11 @@ if(Meteor.isServer) { }); } +//Allows the client to do DB interaction without calling server side methods, while still retaining control over whether the user can make changes. +Workers.allow({ + insert: function() {return false;}, + update: function() {return false;}, + remove: function() {return false;} +}); + export default Workers; \ No newline at end of file diff --git a/imports/api/index.js b/imports/api/index.js index 65ed194..ef57950 100644 --- a/imports/api/index.js +++ b/imports/api/index.js @@ -1,3 +1,4 @@ +import {Mongo} from 'meteor/mongo'; import Measures from "./Measure.js"; import Venues from "./Venue.js"; import Products from "./Product.js"; @@ -8,15 +9,18 @@ import Logs from "./Logs.js"; import Users from "./User.js"; import UserRoles from "./Roles.js"; import Workers from "./Worker.js"; +import Barcodes from "./Barcode.js"; +import Batches from "./Batch.js"; import './Reports.js'; +import './Label.js'; //Save the collections in the Meteor.collections property for easy access without name conflicts. -Meteor.collections = {Measures, Venues, Products, ProductTags, Sales, SalesSheets, Logs, Users, UserRoles, Workers}; +Meteor.collections = {Measures, Venues, Products, ProductTags, Sales, SalesSheets, Logs, Users, UserRoles, Workers, Barcodes, Batches}; //If this is the server then setup the default admin user if none exist. if(Meteor.isServer) { //Change this to find admin users, create a default admin user if none exists. - if(Users.find({}).count() == 0) { + if(Users.find({}).count() === 0) { try { console.log("Creating a default admin user: admin/admin"); @@ -28,4 +32,14 @@ if(Meteor.isServer) { console.log(err); } } + + Meteor.validators = {}; + Meteor.validators.ObjectID = Match.Where(function(id) { + if(id instanceof Mongo.ObjectID) { + id = id._str; + } + + check(id, String); + return /[0-9a-fA-F]{24}/.test(id); + }); } \ No newline at end of file diff --git a/imports/startup/client/routes.js b/imports/startup/client/routes.js index f187434..036fcfa 100644 --- a/imports/startup/client/routes.js +++ b/imports/startup/client/routes.js @@ -123,6 +123,13 @@ pri.route('/labels', { BlazeLayout.render('Body', {content: 'LabelMaker'}); } }); +FlowRouter.route('/PrintLabel', { + name: 'PrintLabel', + action: function(params, queryParams) { + require("/imports/ui/PrintLabel.js"); + BlazeLayout.render('Empty', {content: 'PrintLabel'}); + } +}); pri.route('/testList', { name: 'TestList', action: function(params, queryParams) { diff --git a/imports/ui/Label.html b/imports/ui/Label.html index e056112..090d5d1 100644 --- a/imports/ui/Label.html +++ b/imports/ui/Label.html @@ -1,31 +1,46 @@ + + + + + + + +
- diff --git a/imports/ui/Label.import.styl b/imports/ui/Label.import.styl index df74bac..b301206 100644 --- a/imports/ui/Label.import.styl +++ b/imports/ui/Label.import.styl @@ -1,93 +1,163 @@ + #labelMaker - margin: 10px 20px - height: 100% - width: 100% + margin 10px 20px + height 100% + width 100% + overflow-y auto - .labelContents - label - font-family: TimesNewRoman, Times New Roman, Times - font-weight: 200 - font-size: 14px - .title1 - width: 500px - font-family: TimesNewRoman, Times New Roman, Times - font-size: .142in - font-weight: 800 - line-height: .142in - .title2 - width: 500px - font-family: TimesNewRoman, Times New Roman, Times - font-size: 14px - font-weight: 800 - line-height: 16px - .ingredients - width: 500px - height: 100px - font-family: TimesNewRoman, Times New Roman, Times - font-size: 12px - font-weight: 100 - line-height: 14px - .date - width: 500px - font-family: TimesNewRoman, Times New Roman, Times - font-size: 12px - font-weight: 100 - line-height: 14px - .labelContainer - text-align: center - width: 100% - width-min: 3in - height-min: 2in - background-color: grey - padding: 20px - .labelSample - display: inline-block - width: 3in - height: 2in - background-color: white - color: black - text-align: center - .labelLogo - width: .8in - .labelTagline - font-family: TimesNewRoman, Times New Roman, Times - font-size: .1in - font-weight: 100 - line-height: .2in + @media not print + .labelOptions + label + font-family TimesNewRoman, Times New Roman, Times + font-weight 200 + font-size 14px .title1 - width: 100% - font-family: TimesNewRoman, Times New Roman, Times - font-size: .2in - font-weight: 800 - text-transform: uppercase + width 500px + font-family TimesNewRoman, Times New Roman, Times + font-size .142in + font-weight 800 + line-height .142in .title2 - width: 100% - font-family: TimesNewRoman, Times New Roman, Times - font-size: .15in - font-weight: 800 + width 500px + font-family TimesNewRoman, Times New Roman, Times + font-size 14px + font-weight 800 + line-height 16px .ingredients - width: 100% - font-family: TimesNewRoman, Times New Roman, Times - font-size: .1in - font-weight: 100 + width 500px + height 100px + font-family TimesNewRoman, Times New Roman, Times + font-size 12px + font-weight 100 + line-height 14px + .date + width 500px + font-family TimesNewRoman, Times New Roman, Times + font-size 12px + font-weight 100 + line-height 14px + .labelContainer + text-align center + width 100% + width-min 3in + height-min 2in + background-color grey + padding 20px + .labels + display none + .printableLabel + display none + .label + display inline-block + width 3in + height 2in + .canvasContainer + padding 10px + background-color gray + @media all + .label + position relative + background-color white + color black + text-align center + font-family TimesNewRoman, Times New Roman, Times + //font-family Arial, Helvetica, sans-serif + font-size .1in + width 3in + height 2in + .barcodeContainer + position absolute + transform rotate(270deg) scale(0.7) + right -10em + top 7em + .qrcode + position absolute + left 3px + top 3px + //padding: 2px + //border: 2px solid black + .labelLogo + width 8em + padding 0 + margin 0 + padding-top .15em + margin-bottom .2em + .labelLogo3 + width 14em + padding 0 + margin 0 + padding-top .15em + margin-bottom .8em + .labelTagline + font-size 1em + font-weight 100 + line-height 1em + .title1 + width 100% + font-size 2.5em + line-height .9em + font-weight 800 + text-transform uppercase + .title2 + width 100% + font-size 1.5em + line-height .9em + font-weight 800 + padding-bottom .2em + .ingredients + width 100% + font-size 1.2em + font-weight 100 + line-height 1em + min-height 2em .ingredientsEnding - width: 100% - font-family: TimesNewRoman, Times New Roman, Times - font-size: .1in - font-weight: 100 + width 100% + font-size 1.2em + font-weight 100 .instructions - width: 100% - font-family: TimesNewRoman, Times New Roman, Times - font-size: .1in - font-weight: 800 + width 100% + font-size 1.2em + font-weight 800 .address - width: 100% - font-family: TimesNewRoman, Times New Roman, Times - font-size: .1in - font-weight: 100 + width 100% + font-size 1.2em + font-weight 100 .website - width: 100% - font-family: TimesNewRoman, Times New Roman, Times - font-size: .1in - font-weight: 100 + width 100% + font-size 1.2em + font-weight 100 + @media print + @page + size 3in 2in + margin 0 + padding 0 + .labelOptions, .labelContainer, .canvasContainer, .labelCanvas + display none + .printableLabel + display block + margin 0 + padding 0 + //.printableLabels + // display inline-block + // margin 0 + // padding 0 + //#labelMaker + // display none + //.labels + // display block + //.label + // display block + // width 3in + // height 2in + // //width 100% + // //height 100% + // page-break-after always + // page-break-inside avoid + .canvasContainer + display none +@media print + .labelMaker + margin 0 + padding 0 + overflow visible \ No newline at end of file diff --git a/imports/ui/Label.js b/imports/ui/Label.js index bf023c8..7d0ffc2 100644 --- a/imports/ui/Label.js +++ b/imports/ui/Label.js @@ -1,75 +1,416 @@ - +import dti from 'dom-to-image'; import './Label.html'; +import PDF from 'jspdf'; +import { saveAs } from 'file-saver'; import swal from 'sweetalert2'; import dragula from 'dragula'; +//import JsBarcode from 'JsBarcode'; +import QRCode from '/imports/util/qrcode/qrcode'; +//let QRCode = require('/imports/util/qrcode/qrcode.js'); + +console.log(QRCode); + +//let {qrcode, svg2url} = require('pure-svg-code'); +//let QRCode = require('qrcode-svg'); //****************************************************************** //** Creates printable labels for a roll style printer. //****************************************************************** let PREFIX = "LabelMaker_"; +let PX_PER_MM = 300 / 25.4; +let SCREEN_PX_PER_MM = 96 / 25.4; +let imagePath = "/images/3x2 Label Logo BW.svg";//"/images/Logo_0.8x0.73_300ppi.png"; + +function generateLabels(title1, title2, ingredients, date, count, topSpacing, bottomSpacing) { + //TODO: Allow logo to be removed or altered with an alternative logo for sizing fixes + let label = "
" + + "
" + + //"
" + + //"" + + "" + + //"
We grow it. We can it.
" + + "
" + title1 + "
" + + "
" + (title2 === undefined ? "" : title2) + "
" + + "
Ingredients:" + ingredients + "
" + + "
*grown by us 8oz FD1951 (" + date + ")
" + + "
Refrigerate after opening; return jar when done
" + + "
18601 Hwy 128, Yorkville, CA 95494
" + + "
www.PetitTeton.com
" + + //"
" + + "
"; + let labels = ""; + + //TODO: Include bar code and identifying numbers. + for(let i = 0; i < count; i++) { + labels += label; + } + + return labels; +} + +function printImageOld(template, dataUrl) { + let img = new Image(); + + img.onload = function() { + let imageCanvas = $('.labelCanvas')[0]; + let ctx = imageCanvas.getContext('2d'); + //let threshold = 255 + 200 + 0; + let desiredContrast = 100; + let contrastCorrectionFactor = (259 * (desiredContrast + 255)) / (255 * (259 - desiredContrast)); + + imageCanvas.width = img.width; + imageCanvas.height = img.height; + //console.log("Generated image: " + img.width + ", " + img.height); + //ctx.scale(0.25, 0.25); + ctx.drawImage(img, 0, 0); + + let imageData = ctx.getImageData(0, 0, imageCanvas.width, imageCanvas.height); + let data = imageData.data; + + //Run three times + for(let c = 0; c < 3; c++) { + //Set each pixel to either black or white with the given threshold. + for(let i = 0; i < data.length; i += 4) { + data[i] = contrastCorrectionFactor * (data[i] - 128) + 128; + data[i + 1] = contrastCorrectionFactor * (data[i + 1] - 128) + 128; + data[i + 2] = contrastCorrectionFactor * (data[i + 2] - 128) + 128; + //if(data[i] + data[i + 1] + data[i + 2] < threshold) { + // data[i] = 0; + // data[i + 1] = 0; + // data[i + 2] = 0; + //} + //else { + // data[i] = 255; + // data[i + 1] = 255; + // data[i + 2] = 255; + //} + data[i + 3] = 255; + } + } + + ctx.putImageData(imageData, 0, 0); + + //Convert the canvas content to an image for printing. (cannot print a canvas?) + //sendToPrinter(template, imageCanvas.toDataURL("image/png")); + + //Save to disk. + //imageCanvas.toBlob(function(blob) { + // saveAs(blob, "label.png"); + //}, "image/png", 1); + + //imageCanvas.toBlob(function(blob) { + // let url = URL.createObjectURL(blob); + // window.open(url, "_blank"); + //}, "image/png", 1); + + //let imgData = imageCanvas.toDataURL('image/jpeg', 1.0); + imageCanvas.toBlob(function(blob) { + let pdf = new PDF(); + let url = URL.createObjectURL(blob); + pdf.addImage(url, "image/png", 0, 0); + pdf.save("label.pdf"); + }, "image/png", 1); + }; + img.src = dataUrl; +} + +function printImage(template, raw, width, height) { + let data = raw; + //Run three times + for(let c = 0; c < 3; c++) { + //Set each pixel to either black or white with the given threshold. + for(let i = 0; i < data.length; i += 4) { + data[i] = contrastCorrectionFactor * (data[i] - 128) + 128; + data[i + 1] = contrastCorrectionFactor * (data[i + 1] - 128) + 128; + data[i + 2] = contrastCorrectionFactor * (data[i + 2] - 128) + 128; + //if(data[i] + data[i + 1] + data[i + 2] < threshold) { + // data[i] = 0; + // data[i + 1] = 0; + // data[i + 2] = 0; + //} + //else { + // data[i] = 255; + // data[i + 1] = 255; + // data[i + 2] = 255; + //} + data[i + 3] = 255; + } + } + + let url = URL.createObjectURL(new Blob(raw, {type: "image/png"})); + let test = new Image(); + test.src = url; + $('.testImage').html(test); +} +// Note: Not working correctly. Output seems to be at 96dpi instead of 300+dpi. Using a large image scaled down in in an Image tag seems to not print well. +function sendToPrinter(template, dataUrl) { + let canvasImg = new Image(); + canvasImg.onload = function() { + //window.print(); + }; + canvasImg.src = dataUrl; + canvasImg.style.height = template.labelHeight.get() + "mm"; + canvasImg.style.width = template.labelWidth.get() + "mm"; + $(".printableLabel").html(canvasImg); + + //$('.printableLabel').html(img); + window.print(); +} + +function loadImage(url) { + return new Promise(r => { let i = new Image(); i.onload = (() => r(i)); i.src = url; }); +} +async function refreshLabelCanvas(template) { + let mmWidth = template.labelWidth.get(); + let mmHeight = template.labelHeight.get(); + let title1 = template.title1.get(); + let title1Font = template.title1Font.get(); + let title1YOffset = template.title1YOffset.get(); + let title2 = template.title2.get(); + let title2Font = template.title2Font.get(); + let title2YOffset = template.title2YOffset.get(); + let ingredients = template.ingredients.get(); + let ingredientsFont = template.ingredientsFont.get(); + let ingredientsYOffset = template.ingredientsYOffset.get(); + let date = template.date.get(); + let $labelCanvas = $('.labelCanvas'); + let ctx = $labelCanvas[0].getContext('2d'); + let width = Math.floor(mmWidth * PX_PER_MM); + let height = Math.floor(mmHeight * PX_PER_MM); + let center = width / 2; + + let img = await loadImage(imagePath); + let imageWidth = 241; + let imageHeight = 219; + + let ingredientsY = 180; + let ingredientsEndingY = 240; + let instructionsY = 280; + let addressY = 320; + let websiteY = 380; + + ctx.fillStyle = 'white'; + ctx.fillRect(0,0, width, height); + ctx.fillStyle = 'black'; + ctx.drawImage(img, center - (imageWidth / 2), 0); + ctx.font = title1Font; + ctx.textAlign = 'center'; + ctx.fillText(title1, center, title1YOffset); + + + + ////TODO: Allow logo to be removed or altered with an alternative logo for sizing fixes + //let label = "
" + + // "
" + + // //"" + + // "" + + // "
We grow it. We can it.
" + + // "
" + title1 + "
" + + // "
" + (title2 === undefined ? "" : title2) + "
" + + // "
Ingredients:" + ingredients + "
" + + // "
*grown by us 8oz FD1951 (" + date + ")
" + + // "
Refrigerate after opening; return jar when done
" + + // "
18601 Hwy 128, Yorkville, CA 95494
" + + // "
www.PetitTeton.com
" + + // "
" + + // "
"; + //let labels = ""; + // + ////TODO: Include bar code and identifying numbers. + //for(let i = 0; i < count; i++) { + // labels += label; + //} + // + //return labels; +} +function bufferToBase64(buf) { + var binstr = Array.prototype.map.call(buf, function (ch) { + return String.fromCharCode(ch); + }).join(''); + return btoa(binstr); +} Template.LabelMaker.onCreated(function() { + this.labelWidth = new ReactiveVar(76); + this.labelHeight = new ReactiveVar(50); + + this.title1 = new ReactiveVar("Strawberry"); + this.title2 = new ReactiveVar("w/ Espelette"); + this.ingredients = new ReactiveVar("*strawberry, sugar, *espelette"); + + this.date = new ReactiveVar(19001); + + //Session.set(PREFIX + "title1", "Strawberry"); + //Session.set(PREFIX + "title1Font", "50px Times New Roman"); + //Session.set(PREFIX + "title1YOffset", 260); + //Session.set(PREFIX + "title2", "w/ Espelette"); + //Session.set(PREFIX + "title2Font", "40px Times New Roman"); + //Session.set(PREFIX + "title2YOffset", 340); + //Session.set(PREFIX + "ingredients", "*strawberry, sugar, *espelette"); + //Session.set(PREFIX + "date", 19001); + //Session.set(PREFIX + "count", 3); }); Template.LabelMaker.onRendered(function() { let template = this; + + //Re-run this routine when ever the session variables change. + //Tracker.autorun(function() { + // //refreshLabelCanvas(Session.get(PREFIX + "title1"), Session.get(PREFIX + "title2"), Session.get(PREFIX + "ingredients"), Session.get(PREFIX + "date"), 1, Session.get(PREFIX + "labelSpacing"), 0); + // refreshLabelCanvas(template); + //}); + // + //template.$('.labelContainer').on('DOMSubtreeModified', function() { + // console.log("Initialized barcode"); + // // + //}); + //JsBarcode(".barcode").init(); + + + //const svgString = qrcode({content: "1234567890", padding: 0, width: 60, height: 60, color: "#000000", background: "#FFFFFF", ecl: "L"}); + //this.$('.qrcode').attr('src', svg2url(svgString)); + + //this.$('.qrcode').attr('src', svg2url(new QRCode({content: '1234567890', width: 80, height: 80, color: "#000000", background: "#FFFFFF"}).svg())); + + new QRCode(document.getElementById("qrcode"), {text: "1234567890", width: 60, height: 60}); }); Template.LabelMaker.onDestroyed(function() { }); Template.LabelMaker.events({ - 'change .title1': function(event, template) { - Session.set(PREFIX + "title1", $(event.target).val()); + 'change .labelWidth': function(e, t) { + let x = $(e.target).val(); + + t.labelWidth.set(!Number.isNaN(x) && x > 0 ? parseFloat(x) : 76); }, - 'change .title2': function(event, template) { - Session.set(PREFIX + "title2", $(event.target).val()); + 'change .labelHeight': function(event, template) { + let x = $(event.target).val(); + + t.labelHeight.set(!Number.isNaN(x) && x > 0 ? parseFloat(x) : 50); }, - 'change .ingredients': function(event, template) { - Session.set(PREFIX + "ingredients", $(event.target).val()); - }, - 'change .date': function(event, template) { - Session.set(PREFIX + "date", parseInt($(event.target).val())); - }, - 'click .generate': function(event, template) { + 'change .title1': function(e, t) {t.title1.set($(e.target).val());}, + 'change .title1Font': function(e, t) {t.title1Font.set($(e.target).val());}, + 'change .title1YOffset': function(e, t) {t.title1YOffset.set(parseInt($(e.target).val()));}, + + 'change .title2': function(e, t) {t.title2.set($(e.target).val());}, + 'change .title2Font': function(e, t) {t.title2Font.set($(e.target).val());}, + 'change .title2YOffset': function(e, t) {t.title2YOffset.set(parseInt($(e.target).val()));}, + + 'change .ingredients': function(e, t) {t.ingredients.set($(e.target).val());}, + 'change .ingredientsFont': function(e, t) {t.ingredientsFont.set($(e.target).val());}, + 'change .ingredientsYOffset': function(e, t) {t.ingredientsYOffset.set(parseInt($(e.target).val()));}, + + 'change .date': function(e, t) {t.date.set(parseInt($(e.target).val()));}, + 'click .preview': function(event, template) { + let params = {}; + + params['title1'] = "Strawberry"; + params['title2'] = ""; + params['ingredients'] = "Fairies"; + params['date'] = "1234"; + window.open('/PrintLabel?' + $.param(params)); + }, + 'click .print': function(event, template) { + let _this = template; + let node = $('.label')[0]; + let width = _this.labelWidth.get(); + let height =_this.labelHeight.get(); + let title1 =_this.title1.get(); + let title2 =_this.title2.get(); + let ingredients =_this.ingredients.get(); + let date =_this.date.get(); + + Meteor.call('printLabels', width, height, "3x2Standard", title1, title2, ingredients, date, (error, result) => { + if(error) { + console.log(error); + } + else { + const blob = new Blob([result], {type: 'application/pdf'}); + const link = document.createElement('a'); + link.href = window.URL.createObjectURL(blob); + link.download = "labels.pdf"; + link.click(); + } + }); + + //dti.toBlob(node, {bgcolor: 'white'}).then(function(blob) { + // printImage(template, blob); + //}).catch(function(err) { + // console.log(err); + //}); + + //dti.toPng(node, {bgcolor: 'white'}).then(function(dataUrl) { + // printImageOld(template, dataUrl); + //}).catch(function(err) { + // console.log(err); + //}); + + + //let count = template.$('input[name="count"]').val(); + //let spacing = Session.get(PREFIX + "labelSpacing"); + // + ////count = (count === undefined || Number.isNaN(count)) ? 1 : parseInt(count); + //// + ////if(count < 1) { + //// count = 1; + ////} + //// + ////Session.set(PREFIX + "generatedLabels", generateLabels(Session.get(PREFIX + "title1"), Session.get(PREFIX + "title2"), Session.get(PREFIX + "ingredients"), Session.get(PREFIX + "date"), count, 0, spacing)); + // + //let $label = $('.printableLabel'); + // + //console.log($label); + //console.log($label.length); + //domtoimage.toPng($label).then(function(dataUrl) { + // console.log("A"); + // let img = new Image(); + // img.src = dataUrl; + // $('.printableLabel').html(img); + // //caman('.printableLabel img', function() { + // // this.contrast(100); + // // this.render(); + // // window.print(); + // //}); + //}).catch(function(error) { + // console.error("failed to convert dom to image"); + // console.error(error); + //}); } }); Template.LabelMaker.helpers({ - title1: function() {return Session.get(PREFIX + "title1")}, - title2: function() {return Session.get(PREFIX + "title2")}, - ingredients: function() {return Session.get(PREFIX + "ingredients")}, - date: function() {return Session.get(PREFIX + "date")}, - labelText: function() { - return "
" + Session.get(PREFIX + "title1") + "
" + - "
" + Session.get(PREFIX + "title2") + "
" + - "
Ingredients:" + Session.get(PREFIX + "ingredients") + "
" + - "
*grown by us 8oz FD1951 (" + Session.get(PREFIX + "date") + ")
" + - "
Refrigerate after opening; return jar when done
" + - "
18601 Hwy 128, Yorkville, CA 95494
" + - "
www.PetitTeton.com
"; - } -}); - -Template.Labels.onCreated(function() { -}); -Template.Labels.onRendered(function() { - let template = this; -}); -Template.Labels.onDestroyed(function() { -}); -Template.Labels.events({ -}); -Template.Labels.helpers({ - labels: function() {return Session.get(PREFIX + "labels")}, - title2: function() {return Session.get(PREFIX + "title2")}, - ingredients: function() {return Session.get(PREFIX + "ingredients")}, - date: function() {return Session.get(PREFIX + "date")}, - labelText: function() { - return "
" + Session.get(PREFIX + "title1") + "
" + - "
" + Session.get(PREFIX + "title2") + "
" + - "
Ingredients:" + Session.get(PREFIX + "ingredients") + "
" + - "
*grown by us 8oz FD1951 (" + Session.get(PREFIX + "date") + ")
" + - "
Refrigerate after opening; return jar when done
" + - "
18601 Hwy 128, Yorkville, CA 95494
" + - "
www.PetitTeton.com
"; + title1: function() {return Template.instance().title1.get();}, + title2: function() {return Template.instance().title2.get();}, + ingredients: function() {return Template.instance().ingredients.get();}, + date: function() {return Template.instance().date.get();}, + labelWidth: function() {return Template.instance().labelWidth.get();}, + labelHeight: function() {return Template.instance().labelHeight.get();}, + sampleLabel: function() { + let t = Template.instance(); + setTimeout(function() {JsBarcode(".barcode").init();}, 500); + return generateLabels(t.title1.get(), t.title2.get(), t.ingredients.get(), t.date.get(), 1, 0); + }, + //canvasLabel: function() { + // return generateLabelCanvas(Session.get(PREFIX + "title1"), Session.get(PREFIX + "title2"), Session.get(PREFIX + "ingredients"), Session.get(PREFIX + "date"), 1, Session.get(PREFIX + "labelSpacing"), 0); + //}, + labels: function() { + return Session.get(PREFIX + "generatedLabels"); + }, + labelPxWidth: function() { + //console.log("label width: " + Template.instance().labelWidth.get()); + //console.log("px_per_mm: " + PX_PER_MM); + //console.log("labelPxWidth: " + (Template.instance().labelWidth.get() * PX_PER_MM)); + return Math.floor(Template.instance().labelWidth.get() * PX_PER_MM); + }, + labelPxHeight: function() { + return Math.floor(Template.instance().labelHeight.get() * PX_PER_MM); + }, + labelPxWidthActual: function() { + //console.log("label width: " + Template.instance().labelWidth.get()); + //console.log("px_per_mm: " + PX_PER_MM); + //console.log("labelPxWidth: " + (Template.instance().labelWidth.get() * PX_PER_MM)); + return Math.floor(Template.instance().labelWidth.get() * SCREEN_PX_PER_MM); + }, + labelPxHeightActual: function() { + return Math.floor(Template.instance().labelHeight.get() * SCREEN_PX_PER_MM); } }); diff --git a/imports/ui/PrintLabel.html b/imports/ui/PrintLabel.html new file mode 100644 index 0000000..e4b5755 --- /dev/null +++ b/imports/ui/PrintLabel.html @@ -0,0 +1,19 @@ + \ No newline at end of file diff --git a/imports/ui/PrintLabel.import.css b/imports/ui/PrintLabel.import.css new file mode 100644 index 0000000..515b8be --- /dev/null +++ b/imports/ui/PrintLabel.import.css @@ -0,0 +1,85 @@ +#PrintLabel .labelContainer { + text-align: center; + width: 100%; + width-min: 3in; + height-min: 2in; + background-color: #808080; + padding: 20px; +} +#PrintLabel .labels { + display: none; +} +#PrintLabel .printableLabel { + display: none; +} +#PrintLabel .label { + display: inline-block; + width: 3in; + height: 2in; +} +#PrintLabel .canvasContainer { + padding: 10px; + background-color: #808080; +} +#PrintLabel .label { + background-color: #fff; + color: #000; + text-align: center; + font-family: TimesNewRoman, Times New Roman, Times; + font-size: 0.2in; + width: 6in; + height: 4in; +} +#PrintLabel .label .labelLogo { + width: 8em; + padding: 0; + margin: 0; + padding-top: 0.15em; + margin-bottom: -0.25em; +} +#PrintLabel .label .labelTagline { + font-size: 1em; + font-weight: 100; + line-height: 1em; +} +#PrintLabel .label .title1 { + width: 100%; + font-size: 2.5em; + line-height: 0.9em; + font-weight: 800; + text-transform: uppercase; +} +#PrintLabel .label .title2 { + width: 100%; + font-size: 1.5em; + line-height: 0.9em; + font-weight: 800; + padding-bottom: 0.2em; +} +#PrintLabel .label .ingredients { + width: 100%; + font-size: 1.2em; + font-weight: 100; + line-height: 1em; + min-height: 2em; +} +#PrintLabel .label .ingredientsEnding { + width: 100%; + font-size: 1.2em; + font-weight: 100; +} +#PrintLabel .label .instructions { + width: 100%; + font-size: 1.2em; + font-weight: 800; +} +#PrintLabel .label .address { + width: 100%; + font-size: 1.2em; + font-weight: 100; +} +#PrintLabel .label .website { + width: 100%; + font-size: 1.2em; + font-weight: 100; +} diff --git a/imports/ui/PrintLabel.import.styl b/imports/ui/PrintLabel.import.styl new file mode 100644 index 0000000..3632d3d --- /dev/null +++ b/imports/ui/PrintLabel.import.styl @@ -0,0 +1,92 @@ + +#PrintLabel + .labelContainer + text-align center + //width 100% + width-min 3in + width 3in + height-min 2in + height 2in + //background-color grey + //padding 20px + .labels + display none + .printableLabel + display none + .label + display inline-block + width 3in + height 2in + .canvasContainer + padding 10px + background-color gray + + .label + position relative + background-color white + color black + text-align center + font-family TimesNewRoman, Times New Roman, Times + //font-family Arial, Helvetica, sans-serif + font-size .1in + width 3in + height 2in + .barcodeContainer + position absolute + transform rotate(270deg) + right -4.5em + top 5em + .qrcode + position absolute + left 10px + top 10px + .labelLogo + width 8em + padding 0 + margin 0 + padding-top .15em + margin-bottom .2em + .labelLogo3 + width 14em + padding 0 + margin 0 + padding-top .15em + margin-bottom .8em + .labelTagline + font-size 1em + font-weight 100 + line-height 1em + .title1 + width 100% + font-size 2.5em + line-height .9em + font-weight 800 + text-transform uppercase + .title2 + width 100% + font-size 1.5em + line-height .9em + font-weight 800 + padding-bottom .2em + .ingredients + width 100% + font-size 1.2em + font-weight 100 + line-height 1em + min-height 2em + .ingredientsEnding + width 100% + font-size 1.2em + font-weight 100 + .instructions + width 100% + font-size 1.2em + font-weight 800 + .address + width 100% + font-size 1.2em + font-weight 100 + .website + width 100% + font-size 1.2em + font-weight 100 \ No newline at end of file diff --git a/imports/ui/PrintLabel.js b/imports/ui/PrintLabel.js new file mode 100644 index 0000000..0aa05ee --- /dev/null +++ b/imports/ui/PrintLabel.js @@ -0,0 +1,32 @@ +import './PrintLabel.html'; +import JsBarcode from 'JsBarcode'; +//import QRCode from "../util/qrcode/qrcode"; +import QRCode from '/imports/util/qrcode/qrcode'; + +//let {qrcode, svg2url} = require('pure-svg-code'); + +Template.PrintLabel.onCreated(function() { + function getUrlVars() { + let vars = {}; + let parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { + vars[key] = decodeURIComponent(value); + }); + return vars; + } + + this.vars = getUrlVars(); +}); + +Template.PrintLabel.onRendered(function() { + let vars = this.vars; + $('.title1').html(vars['title1']); + $('.title2').html(vars['title2'] === undefined ? "" : vars['title2']); + $('.ingredients').append(vars['ingredients']); + $('.date').html(vars['date']); + $('.size').html(vars['size']); + //JsBarcode(".barcode").init(); + + //const svgString = qrcode({content: "1234567890", padding: 0, width: 50, height: 50, color: "#000000", background: "#FFFFFF", ecl: "L"}); + //this.$('.qrcode').attr('src', svg2url(svgString)); + new QRCode(document.getElementById("qrcode"), {text: "1234567890", width: 60, height: 60}); +}); \ No newline at end of file diff --git a/imports/ui/Production.html b/imports/ui/Production.html index fedd598..652ec06 100644 --- a/imports/ui/Production.html +++ b/imports/ui/Production.html @@ -1,5 +1,136 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/imports/ui/Production.import.styl b/imports/ui/Production.import.styl index 457c9fc..55177af 100644 --- a/imports/ui/Production.import.styl +++ b/imports/ui/Production.import.styl @@ -1,60 +1,142 @@ #production - margin: 10px 20px + display: table + content-box: border-box + padding: 10px 20px height: 100% - //Flex container options. - flex-flow: column nowrap - justify-content: space-around //Spacing between sales along the primary axis. (vertical spacing for a column layout) - align-items: flex-start //Align the sales within a line along the primary axis. (horizontal alignment for a column layout) - align-content: center //Spacing between lines along the secondary axis. (spacing between columns for a column layout) - display: -webkit-box - display: -moz-box - display: -ms-flexbox - display: -moz-flex - display: -webkit-flex - display: flex + width: 100% + text-align: left - .editor - height: 100% - overflow-y: auto - - .insertSale - flex: none + .tableControls + text-align: right + margin-right: 20px + margin-bottom: 4px + display: table width: 100% + .contentControls + vertical-align: bottom + display: table-cell + text-align: right + min-width: 100px + a + font-size: 12px + font-family: "Arial", san-serif + font-weight: 800 + color: #2d1b8c + text-decoration: none + a:hover + text-decoration: underline + a.disabled + visibility: hidden - .formGroupHeading - font-size: 1.6em - font-family: "Arial Black", "Arial Bold", Gadget, sans-serif - font-style: normal - font-variant: normal - font-weight: 500 - - .grid - flex: auto - align-self: stretch - overflow-y: auto - overflow-x: auto - margin-bottom: 20px - border: 0 - padding-top: 20px - - .table > thead > tr > th - border: 0 - padding-top: 0 - padding-bottom: 6px - - .left - text-align: left - .center - text-align: center - - .dataTable - table-layout: fixed - - .tdLarge - font-size: 1.3em - .saleRemove - color: red - margin-left: 8px - .saleEdit - color: darkblue - margin-right: 8px + .table + table-layout: fixed + min-width: 100% + thead, tbody + > tr + > .hasLabels + width: 30px + .hasLabels + color green + .noLabels + color red + > .name + //width: auto + width: 100% + > .date + //width: auto + min-width: 150px + max-width: 180px + > .amount + //width: auto + min-width: 100px + max-width: 100px + > .cook + //width: auto + min-width: 150px + max-width: 180px + > .canner + //width: auto + min-width: 150px + max-width: 180px + > .comment + width: 220px + min-width: 220px + max-width: 220px + > .actions + width: 90px + min-width: 90px + max-width: 90px + > tr.deleted + background-color: gray + .separatedTableHeader + table + thead + > tr + > th.actions + text-align: center + .newButton + margin-top: 4px + padding: 0 12px + .fa-plus-circle + display: inline-block + .fa-times-circle + display: none + .newButton:active + background-color: #fb557b + color: black + .fa-times-circle + display: inline-block + .fa-plus-circle + display: none + .showDeletedButton + margin-top: 4px + padding: 0 12px + color gray + .showDeletedButton.selected + color black + .listRow + display: table-row + .listCell + display: table-cell + position: relative + height: 100% + width: 100% + .tableContainer + position: absolute + top: 0 + bottom: 0 + left: 0 + right: 0 + width: auto + height: auto + border: 0 + font-size: 12.5px + overflow-y: auto + table + thead + visibility: hidden + display: none + .search + margin: 3px 0 2px 1px + .editorTd + background: #deeac0 + input, select + width: 100% + .editorDiv + margin: 4px 0 + label + font-family: "Arial Black", "Arial Bold", Gadget, sans-serif + font-size: .9em + padding-bottom: 4px + select2 + font-size: .4em + > tbody + > tr + .actionRemove + color: #F77 + .actionEdit + color: #44F + .editorApply + color: green + .editorCancel + color: red \ No newline at end of file diff --git a/imports/ui/Production.js b/imports/ui/Production.js index c72cc88..2c092d7 100644 --- a/imports/ui/Production.js +++ b/imports/ui/Production.js @@ -1,2 +1,446 @@ import './Production.html'; + +let QUERY_LIMIT = 100; +let QUERY_LIMIT_INCREMENT = 100; +let PREFIX = "Production."; + +Tracker.autorun(function() { + //Meteor.subscribe("batches"); + Meteor.subscribe("workers"); + Meteor.subscribe("products"); + Meteor.subscribe("measures"); +}); + +Template.Production.onCreated(function() { + Session.set(PREFIX + "displayNew", false); //Whether the new dialog is inlined in the table and visible. + + Session.set(PREFIX + "sortOption", 'date'); //Allows us to sort the results of the batch query by batch attribute. + Session.set(PREFIX + 'skipCount', 0); //Allows us to page through the results of the batch query. Currently not used. + Session.set(PREFIX + 'batchCount', 0); //A count of all batches in the system (that fit our current query). Useful for paging and dynamic loading. + Session.set(PREFIX + "queryLimit", QUERY_LIMIT); + Session.set(PREFIX + "showDeleted", false); + Session.set(PREFIX + "editedId", undefined); + + Tracker.autorun(function() { + let sortOption = Session.get(PREFIX + "sortOption"); + let sort = sortOption == 'createdAt' ? {createdAt: -1} : {date: -1, createdAt: -1}; + //let showOnlyComments = Session.get(PREFIX + "showOnlyComments"); //Not needed here. Shows how to limit the query to only records with certain features. + let query = _.clone(Session.get(PREFIX + 'searchQuery')); + + //if(showOnlyComments) { + // if(!query) query = {}; + // query.comment = {$exists: true}; + //} + + if(!Session.get(PREFIX + "showDeleted")) { + if(!query) query = {}; + query.deletedAt = {$exists: false}; + } + + Template.Production.batchesSubscription = Meteor.subscribe("batches", query, sort, QUERY_LIMIT, Session.get(PREFIX + 'skipCount')); + Session.set(PREFIX + 'batchCount', Meteor.call('getBatchCount', Session.get(PREFIX + 'searchQuery'))); + }); +}); +Template.Production.onDestroyed(function() { + if(Template.Production.batchSubscription) { + Template.Production.batchSubscription.stop(); + } +}); +Template.Production.onRendered(function() { + $(".tableContainer").mCustomScrollbar({ + scrollButtons: {enable:true}, + theme: "light-thick", + scrollbarPosition: "outside", + scrollEasing: "linear" + }); +}); +Template.Production.helpers({ + displayNew: function() { + return Session.get(PREFIX + "displayNew"); + }, + batches: function() { + let sortOption = Session.get(PREFIX + "sortOption"); + + return Meteor.collections.Batches.find({}, {sort: (sortOption == 'createdAt' ? {createdAt: -1} : {date: -1, createdAt: -1})}); + }, + disableLoadMore: function() { + return Session.get(PREFIX + 'batchCount') - (Session.get(PREFIX + 'skipCount') || 0) - Session.get(PREFIX + "queryLimit") <= 0; + }, + showDeletedSelected: function() { + return (Session.get(PREFIX + "showDeleted")) ? "selected" : ""; + } +}); +Template.Production.events({ + 'click .loadMoreLink': function(event, template) { + event.preventDefault(); + Session.set(PREFIX + 'queryLimit', Session.get(PREFIX + "queryLimit") + QUERY_LIMIT_INCREMENT); + }, + 'click .newButton': function(event, template) { + if(template.$('.newButton').hasClass('active')) { + Session.set(PREFIX + 'displayNew', false); + } + else { + Session.set(PREFIX + 'displayNew', true); + Session.set(PREFIX + "editedId", undefined); //Clear the edited product so that only one editor is open at a time. + } + template.$('.newButton').toggleClass('active'); + }, + 'click .showDeletedButton': function(event, template) { + Session.set(PREFIX + "showDeleted", !Session.get(PREFIX + "showDeleted")); //Toggle the display of deleted production. + } +}); + + +Template.Batch.onCreated(function() { +}); +Template.Batch.onRendered(function() { +}); +Template.Batch.helpers({ + hasLabelsClass: function() { + return this.hasLabels === true ? "hasLabels" : "noLabels"; + }, + name: function() { + let product = Meteor.collections.Products.findOne({_id: this.productId}); + let measure = Meteor.collections.Measures.findOne({_id: this.measureId}); + return product.name + " (" + measure.name + ")"; + }, + date: function() { + return moment(this.date, "YYYYMMDD").format("MM/DD/YYYY"); + }, + cook: function() { + let worker = Meteor.collections.Workers.findOne({_id: this.cookId}); + return worker.name; + }, + canner: function() { + let worker = Meteor.collections.Workers.findOne({_id: this.cannerId}); + return worker.name; + }, + editing: function() { + let editedId = Session.get(PREFIX + "editedId"); + + return editedId && editedId.toString() === this._id.toString(); + }, + getRowClass: function() { + return this.deletedAt ? "deleted" : ""; + }, + isDeleted: function() { + return this.deletedAt; + } +}); +Template.Batch.events({ + "click .hasLabels": function(event, template) { + Meteor.call('setBatchHasLabels', this._id, !(this.hasLabels === true), function(error, result) { + if(error) sAlert.error(error); + }); + }, + "click .actionEdit": function(event, template) { + Session.set(PREFIX + "editedId", this._id); + Session.set(PREFIX + 'displayNew', false); //Ensure the new editor is closed. + template.parentTemplate().$('.newButton').removeClass('active'); + }, + "click .actionDelete": function(event, template) { + Meteor.call('deleteBatch', this._id, function(error, result) { + if(error) sAlert.error(error); + else sAlert.success("Production Batch Deleted"); + }); + }, + 'click .actionUndelete': function(event, template) { + Meteor.call('undeleteBatch', this._id, function(error, result) { + if(error) sAlert.error(error); + else sAlert.success("Production Batch No Longer Deleted"); + }); + } +}); + + +Template.BatchEditor.onCreated(function() { +}); +Template.BatchEditor.onRendered(function() { +}); +Template.BatchEditor.helpers({ + name: function() { + let product = Meteor.collections.Products.findOne({_id: this.productId}); + let measure = Meteor.collections.Measures.findOne({_id: this.measureId}); + + return (product ? product.name : "") + " (" + (measure ? measure.name : "") + ")"; + }, + date: function() { + return moment(this.date, "YYYYMMDD").format("MM/DD/YYYY"); + }, + cook: function() { + let worker = Meteor.collections.Workers.findOne({_id: this.cookId}); + return worker.name; + }, + canner: function() { + let worker = Meteor.collections.Workers.findOne({_id: this.cannerId}); + return worker.name; + } +}); +Template.BatchEditor.events({ + 'click .editorCancel': function(event, template) { + Session.set(PREFIX + "editedId", undefined); + }, + 'click input[type="submit"]': function(event, template) { + event.preventDefault(); + template.$('.insertForm').data('bs.validator').validate(function(isValid) { + if(isValid) { + //Allow the user to edit the comment and the amount produced. Sometimes jars pop after the product cools and these things need to be recorded. + + //TODO + } + }); + } +}); + + +Template.BatchNew.onCreated(function() { + this.selectedProduct = new ReactiveVar(); + this.selectedCook = new ReactiveVar(); + this.selectedCanner = new ReactiveVar(); +}); +Template.BatchNew.onRendered(function() { + this.$('.insertForm').validator(); + this.$('[name="product"]').buildCombo({cursor: Meteor.collections.Products.find({$or: [{hidden: false}, {hidden: {$exists:false}}]}), selection: this.selectedProduct, textAttr: 'name', listClass: 'comboList', getClasses: function(data) { + return (data && data.deactivated) ? "deactivated" : ""; + }}); + this.$('[name="cook"]').buildCombo({cursor: Meteor.collections.Workers.find({}), selection: this.selectedCook, textAttr: 'name', listClass: 'comboList'}); + this.$('[name="canner"]').buildCombo({cursor: Meteor.collections.Workers.find({}), selection: this.selectedCanner, textAttr: 'name', listClass: 'comboList'}); + this.$('input[name="product"]').focus(); +}); +Template.BatchNew.helpers({ + //products: function() { + // return Meteor.collections.Products.find({}); + //}, + //productSelected: function() { + // let product = this; + // let batch = Template.parentData(); + // + // return batch.productId === product._id ? "selected" : ""; + //}, + productMeasures: function() { + //Show only the list allowed by the product + let product = Template.instance().selectedProduct.get(); + + if(product) { + let measures = Meteor.collections.Measures.find({}).fetch(); + let measuresById = {}; + let allowedMeasureIds = product.measures; + let allowedMeasures = []; + + //Create a hashmap of measures by their id. + for(let measure of measures) measuresById[measure._id.toString()] = measure; + + //Create a list of measures allowed for the product. + for(let measureId of allowedMeasureIds) { + allowedMeasures.push(measuresById[measureId.toString()]); + } + + return allowedMeasures; + } + else return []; + }, + today: () => { + return moment().format("YYYY-MM-DD"); + } +}); +Template.BatchNew.events({ + 'change input[name="date"]': function(event, template) { + template.selectedDate.set(moment(event.target.value, "YYYY-MM-DD").toDate()); + }, + 'click .editorCancel': function(event, template) { + Session.set(PREFIX + "editedId", undefined); + }, + 'click .editorApply': function(event, template) { + event.preventDefault(); + template.$('.insertForm').data('bs.validator').validate(function(isValid) { + if(isValid) { + let batches = []; + let insertMeasure = template.$(".insertMeasure"); + + let batch = { + date: ~~(moment(template.find("[name='date']").value, "YYYY-MM-DD").format("YYYYMMDD")), // Note: ~~ performs a bitwise not which is a fast method of converting a string to a number. + productId: template.selectedProduct.get()._id, + cookId: template.selectedCook.get()._id, + cannerId: template.selectedCanner.get()._id, + comment: template.$('.comment').val() + }; + + //Iterate over the measures for the batch (based on the product chosen) and amounts. + for(let next = 0; next < insertMeasure.length; next++) { + let nextMeasure = $(insertMeasure[next]); + let measureId = nextMeasure.find(".measureId").val(); + let amount = parseFloat(nextMeasure.find(".amount").val()); + + if(amount > 0) { + let next = _.clone(batch); + + next.measureId = measureId; + next.amount = amount; + batches.push(next); + } + } + + Meteor.call('insertBatches', batches, function(error) { + if(error) sAlert.error("Failed to insert the batch!\n" + error); + else { + let productCombo = template.$("input[name='product']"); + let measureFields = template.$(".amount"); + + sAlert.success("Production batches created."); + + //Clear the measure quantity fields so the user can enter another sale without the quantities already set. + measureFields.val(0); + //Set the focus to the product field of the form. + //productCombo.focus(); + //Clear the product since it is highly unlikely the same product will be added twice for the same date. + productCombo.val(""); + Session.set(PREFIX + "displayNew", false); + } + }); + } + }); + } +}); + + +Template.InsertBatchMeasure.onCreated(function() { + let _this = this; + + this.amount = new ReactiveVar(0); +}); +Template.InsertBatchMeasure.onRendered(function() { +}); +Template.InsertBatchMeasure.helpers({ + amount: function() { + return Template.instance().amount.get(); + } +}); +Template.InsertBatchMeasure.events({ + 'change .amount': function(event, template) { + template.amount.set(parseFloat($(event.target).val())); + }, + 'focus input[name="amount"]': function(event, template) { + //See http://stackoverflow.com/questions/3150275/jquery-input-select-all-on-focus + //Handle selecting the text in the field on receipt of focus. + let $this = $(this) + .one('mouseup.mouseupSelect', function() { + $this.select(); + return false; + }) + .one('mousedown', function() { + // compensate for untriggered 'mouseup' caused by focus via tab + $this.off('mouseup.mouseupSelect'); + }) + .select(); + } +}); + + +Template.BatchSearch.onCreated(function() { +}); +Template.BatchSearch.onRendered(function() { +}); +Template.BatchSearch.helpers({ + searchValue: function() { + let searchFields = Session.get(PREFIX + 'searchFields'); + + return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : ''; + } +}); +Template.BatchSearch.events({ + "keyup .searchInput": _.throttle(function(event, template) { + let searchQuery = Session.get(PREFIX + 'searchQuery') || {}; + let searchFields = Session.get(PREFIX + 'searchFields') || {}; + let searchValue = template.$(event.target).val(); + + if(searchValue) { + if(this.number) searchValue = parseFloat(searchValue); + + // A collection name will be provided if there is a related table of data that will contain the text provided and will map to an ID that is then searched for in the current table of data. + // For example we are displaying a table of Sales which has the ID of a Product. The Product table has a Name field and the search box searches for Product Names. The ID's of the Products found should be used to filter the Sales by Product ID. + if(this.collection) { + let ids = Meteor.collections[this.collection].find({[this.collectionQueryColumnName]: {$regex: searchValue, $options: 'i'}}, {fields: {[this.collectionResultColumnName]: 1}}).fetch(); + + //Convert the ids to an array of ids instead of an array of objects containing an id. + for(let i = 0; i < ids.length; i++) {ids[i] = ids[i]._id;} + searchQuery[this.columnName] = {$in: ids}; + searchFields[this.columnName] = searchValue; + } + else { + searchFields[this.columnName] = searchQuery[this.columnName] = searchValue; + } + } + else { + //Remove columns from the search query whose values are empty so we don't bother the database with them. + delete searchQuery[this.columnName]; + delete searchFields[this.columnName]; + } + + Session.set(PREFIX + 'searchQuery', searchQuery); + Session.set(PREFIX + 'searchFields', searchFields); + Session.set(PREFIX + 'skipCount', 0); //Reset the paging of the results. + Session.set(PREFIX + "queryLimit", QUERY_LIMIT); //Reset the query limit in case we loaded more + }, 500) +}); + + +Template.BatchDateRangeSearch.helpers({ + startDate: function() { + let searchFields = Session.get(PREFIX + 'searchFields'); + let searchValue = (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : {}; + + return searchValue.start ? moment(searchValue.start.toString(), "YYYYMMDD").format("MM/DD/YYYY") : ""; + }, + endDate: function() { + let searchFields = Session.get(PREFIX + 'searchFields'); + let searchValue = (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : {}; + + return searchValue.end ? moment(searchValue.end.toString(), "YYYYMMDD").format("MM/DD/YYYY") : ""; + } +}); +Template.BatchDateRangeSearch.events({ + "change .searchDateStartInput": function(event, template) {Template.DateRangeSearch.dateChanged(true, event, template)}, + "keyup .searchDateStartInput": _.throttle(function(event, template) {Template.DateRangeSearch.dateChanged(true, event, template)}, 500), + "change .searchDateEndInput": function(event, template) {Template.DateRangeSearch.dateChanged(false, event, template)}, + "keyup .searchDateEndInput": _.throttle(function(event, template) {Template.DateRangeSearch.dateChanged(false, event, template)}, 500) +}); +Template.BatchDateRangeSearch.dateChanged = function(isStart, event, template) { + let searchQuery = Session.get(PREFIX + 'searchQuery') || {}; + let searchFields = Session.get(PREFIX + 'searchFields') || {}; + let searchValue = template.$(event.target).val(); + let columnName = template.data.columnName; + + if(searchValue) { + let search = searchQuery[columnName]; + + // Create a search object and attach it to the searchFields and searchQuery objects if needed. + if(!search) { + search = {type: 'dateRange'}; + searchFields[columnName] = searchQuery[columnName] = search; + } + + // Use moment to parse date and convert it to YYYYMMDD for searching the database. + searchValue = ~~(moment(searchValue, searchValue.includes("-") ? "YYYY-MM-DD" : "MM/DD/YYYY").format("YYYYMMDD")); // Note: ~~ performs a bitwise not which is a fast method of converting a string to a number. + // Save the search ending date. + isStart ? search.start = searchValue : search.end = searchValue; + } + else { + if(searchQuery[columnName]) { + // Remove columns from the search query whose values are empty so we don't bother the database with them. + if(isStart) { + delete searchQuery[columnName].start; + delete searchFields[columnName].start; + } + else { + delete searchQuery[columnName].end; + delete searchFields[columnName].end; + } + } + } + + Session.set(PREFIX + 'searchQuery', searchQuery); + Session.set(PREFIX + 'searchFields', searchFields); + Session.set(PREFIX + 'skipCount', 0); //Reset the paging of the results. + Session.set(PREFIX + "queryLimit", QUERY_LIMIT); //Reset the query limit in case we loaded more +}; \ No newline at end of file diff --git a/imports/ui/Products.html b/imports/ui/Products.html index 9d015e7..6f5378a 100644 --- a/imports/ui/Products.html +++ b/imports/ui/Products.html @@ -22,7 +22,7 @@ Tags {{>ProductSearch columnName='tags' collectionQueryColumnName='name' collection='ProductTags' collectionResultColumnName='_id'}} Aliases {{>ProductSearch columnName='aliases'}} Measures {{>ProductSearch columnName='measures' collectionQueryColumnName='name' collection='Measures' collectionResultColumnName='_id'}} - Actions + Actions @@ -32,7 +32,7 @@
- {{#if displayNewProduct}} + {{#if displayNew}} {{> ProductEditor isNew=true}} {{/if}} {{#each products}} @@ -75,7 +75,7 @@ \ No newline at end of file diff --git a/imports/ui/Products.import.styl b/imports/ui/Products.import.styl index 2673ba2..d7823dc 100644 --- a/imports/ui/Products.import.styl +++ b/imports/ui/Products.import.styl @@ -69,14 +69,14 @@ > tr > th.actions text-align: center - .newProductButton + .newButton margin-top: 4px padding: 0 12px .fa-plus-circle display: inline-block .fa-times-circle display: none - .newProductButton:active + .newButton:active background-color: #fb557b color: black .fa-times-circle @@ -105,9 +105,9 @@ thead visibility: hidden display: none - .productSearch + .search margin: 3px 0 2px 1px - .productEditorTd + .editorTd background: #deeac0 input[name="name"], .productTagsEditor, .productAliasesEditor, .productMeasuresEditor width: 100% diff --git a/imports/ui/Products.js b/imports/ui/Products.js index 9894dcc..9f974aa 100644 --- a/imports/ui/Products.js +++ b/imports/ui/Products.js @@ -12,7 +12,7 @@ Tracker.autorun(function() { }); Template.Products.onCreated(function() { - Session.set(PREFIX + "displayNewProduct", false); + Session.set(PREFIX + "displayNew", false); Session.set(PREFIX + "showHidden", false); Session.set(PREFIX + "queryLimit", QUERY_LIMIT); }); @@ -25,8 +25,8 @@ Template.Products.onRendered(function() { }); }); Template.Products.helpers({ - displayNewProduct: function() { - return Session.get(PREFIX + "displayNewProduct"); + displayNew: function() { + return Session.get(PREFIX + "displayNew"); }, products: function() { let skipCount = Session.get(PREFIX + 'skipCount') || 0; @@ -68,16 +68,16 @@ Template.Products.events({ event.preventDefault(); Session.set(PREFIX + 'queryLimit', Session.get(PREFIX + "queryLimit") + QUERY_LIMIT_INCREMENT); }, - 'click .newProductButton': function(event, template) { - if(template.$('.newProductButton').hasClass('active')) { - Session.set(PREFIX + 'displayNewProduct', false); + 'click .newButton': function(event, template) { + if(template.$('.newButton').hasClass('active')) { + Session.set(PREFIX + 'displayNew', false); } else { - Session.set(PREFIX + 'displayNewProduct', true); - Session.set(PREFIX + "editedProduct", undefined); //Clear the edited product so that only one editor is open at a time. + Session.set(PREFIX + 'displayNew', true); + Session.set(PREFIX + "editedId", undefined); //Clear the edited product so that only one editor is open at a time. Session.set(PREFIX + "convertedProduct", undefined); //Clear the converted product so that only one editor is open at a time. } - template.$('.newProductButton').toggleClass('active'); + template.$('.newButton').toggleClass('active'); }, 'change input[name="showHidden"]': function(event, template) { //console.log("changed " + $(event.target).prop('checked')); @@ -166,9 +166,9 @@ Template.Product.helpers({ return result; }, editing: function() { - let editedProduct = Session.get(PREFIX + "editedProduct"); + let editedId = Session.get(PREFIX + "editedId"); - return editedProduct == this._id; + return editedId == this._id; }, converting: function() { let convertedProduct = Session.get(PREFIX + "convertedProduct"); @@ -181,10 +181,10 @@ Template.Product.helpers({ }); Template.Product.events({ "click .actionEdit": function(event, template) { - Session.set(PREFIX + "editedProduct", this._id); - Session.set(PREFIX + 'displayNewProduct', false); //Ensure the new product editor is closed. + Session.set(PREFIX + "editedId", this._id); + Session.set(PREFIX + 'displayNew', false); //Ensure the new editor is closed. Session.set(PREFIX + "convertedProduct", undefined); //Clear the converted product so that only one editor is open at a time. - template.parentTemplate().$('.newProductButton').removeClass('active'); + template.parentTemplate().$('.newButton').removeClass('active'); }, "click .actionDeactivate": function(event, template) { Meteor.call('deactivateProduct', this._id, function(error, result) { @@ -206,9 +206,9 @@ Template.Product.events({ }, "click .actionConvert": function(event, template) { Session.set(PREFIX + "convertedProduct", this._id); - Session.set(PREFIX + 'displayNewProduct', false); //Ensure the new product editor is closed. - Session.set(PREFIX + "editedProduct", undefined); //Clear the edited product so that only one editor is open at a time. - template.$('.newProductButton').removeClass('active'); + Session.set(PREFIX + 'displayNew', false); //Ensure the new editor is closed. + Session.set(PREFIX + "editedId", undefined); //Clear the edited product so that only one editor is open at a time. + template.$('.newButton').removeClass('active'); }, 'click .actionHide': function(event, template) { Meteor.call('hideProduct', this._id, function(error, result) { @@ -249,9 +249,9 @@ Template.ProductEditor.helpers({ }); Template.ProductEditor.events({ "click .editorCancel": function(event, template) { - Session.set(PREFIX + "editedProduct", undefined); - Session.set(PREFIX + 'displayNewProduct', false); - template.parentTemplate().$('.newProductButton').removeClass('active'); + Session.set(PREFIX + "editedId", undefined); + Session.set(PREFIX + 'displayNew', false); + template.parentTemplate().$('.newButton').removeClass('active'); }, "click .editorApply": function(event, template) { let name = template.$("input[name='name']").val().trim(); @@ -263,13 +263,13 @@ Template.ProductEditor.events({ aliases = aliases.map((n)=>n.id); measures = measures.map((n)=>n.id); - if(Session.get(PREFIX + 'displayNewProduct')) { + if(Session.get(PREFIX + 'displayNew')) { Meteor.call("createProduct", name, tags, aliases, measures, function(error, result) { if(error) sAlert.error(error); else { sAlert.success("Product created."); - Session.set(PREFIX + 'displayNewProduct', false); - template.parentTemplate().$('.newProductButton').removeClass('active'); + Session.set(PREFIX + 'displayNew', false); + template.parentTemplate().$('.newButton').removeClass('active'); } }); } @@ -278,8 +278,8 @@ Template.ProductEditor.events({ if(error) sAlert.error(error); else { sAlert.success("Product updated."); - Session.set(PREFIX + "editedProduct", undefined); - template.parentTemplate().$('.newProductButton').removeClass('active'); + Session.set(PREFIX + "editedId", undefined); + template.parentTemplate().$('.newButton').removeClass('active'); } }); } @@ -296,10 +296,10 @@ Template.ConvertProduct.onRendered(function() { }); Template.ConvertProduct.events({ "click .editorCancel": function(event, template) { - Session.set(PREFIX + "editedProduct", undefined); + Session.set(PREFIX + "editedId", undefined); Session.set(PREFIX + "convertedProduct", undefined); - Session.set(PREFIX + 'displayNewProduct', false); - template.parentTemplate().$('.newProductButton').removeClass('active'); + Session.set(PREFIX + 'displayNew', false); + template.parentTemplate().$('.newButton').removeClass('active'); }, "click .editorApply": function(event, template) { let productId = template.selectedProduct.get()._id; @@ -308,10 +308,10 @@ Template.ConvertProduct.events({ if(error) sAlert.error(error); else { sAlert.success("Sales of this product were converted."); - Session.set(PREFIX + "editedProduct", undefined); + Session.set(PREFIX + "editedId", undefined); Session.set(PREFIX + "convertedProduct", undefined); - Session.set(PREFIX + 'displayNewProduct', false); - template.parentTemplate().$('.newProductButton').removeClass('active'); + Session.set(PREFIX + 'displayNew', false); + template.parentTemplate().$('.newButton').removeClass('active'); } }); } diff --git a/imports/ui/layouts/Body.html b/imports/ui/layouts/Body.html index bc4b1d9..14e90bb 100644 --- a/imports/ui/layouts/Body.html +++ b/imports/ui/layouts/Body.html @@ -128,45 +128,4 @@ {{> Template.dynamic template=content}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/imports/ui/layouts/Body.import.styl b/imports/ui/layouts/Body.import.styl index 2ad1145..29ab8d4 100644 --- a/imports/ui/layouts/Body.import.styl +++ b/imports/ui/layouts/Body.import.styl @@ -18,202 +18,211 @@ height: 100% width: 100% - nav.leftSidebarContainer - z-index:999 - position: fixed - top: 0 - width: 220px - padding: 0 - height: 100% - border: 0 - vertical-align: top - text-align: left - background-color: #90b272 //Old browsers - background: -moz-linear-gradient(-180deg, #90b272 0%, #4d7727 100%) //FF3.6-15 - background: -webkit-linear-gradient(-180deg, #90b272 0%,#4d7727 100%) //Chrome10-25,Safari5.1-6 - background: linear-gradient(180deg, #90b272 0%,#4d7727 100%) //W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ - font-size: 14px - font-weight: 700 - overflow: visible - margin: 0 0 0 -220px - -webkit-transition: .5s ease-in - -moz-transition: .5s ease-in - -o-transition: .5s ease-in - -ms-transition: .5s ease-in - transition: .5s ease-in - .leftSidebarMenuButton - position: absolute - right: -30px + @media not print + nav.leftSidebarContainer + z-index:999 + position: fixed + top: 0 + width: 220px + padding: 0 + height: 100% + border: 0 + vertical-align: top + text-align: left + background-color: #90b272 //Old browsers + background: -moz-linear-gradient(-180deg, #90b272 0%, #4d7727 100%) //FF3.6-15 + background: -webkit-linear-gradient(-180deg, #90b272 0%,#4d7727 100%) //Chrome10-25,Safari5.1-6 + background: linear-gradient(180deg, #90b272 0%,#4d7727 100%) //W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ + font-size: 14px + font-weight: 700 + overflow: visible + margin: 0 0 0 -220px -webkit-transition: .5s ease-in -moz-transition: .5s ease-in -o-transition: .5s ease-in -ms-transition: .5s ease-in transition: .5s ease-in - -webkit-border-top-right-radius: 5px - -webkit-border-bottom-right-radius: 5px - -moz-border-radius-topright: 5px - -moz-border-radius-bottomright: 5px - border-top-right-radius: 5px - border-bottom-right-radius: 5px - color: black - font-size: 20px - line-height: 20px - font-weight: 900 - text-align: center - text-decoration: none - width: 30px - height: 30px - padding: 5px 0 - background-color: #90b272 - display: block - border-top: 1px solid #494 - border-right: 1px solid #494 - border-bottom: 1px solid #494 - .leftSidebarMenuButton:hover - color: rgba(150,0,0,.5) - nav.generalSidebar - .leftSidebarMenuButton - top: 10px - nav.graphsSidebar - .leftSidebarMenuButton - top: 50px - nav.settingsSidebar - .leftSidebarMenuButton - top: 90px - nav.menuHide .leftSidebarMenuButton - right: 60px - nav.menuShow - margin: 0 - nav.menuShow .leftSidebarMenuButton - right: -15px - -webkit-transform: rotate(45deg) !important - -moz-transform: rotate(45deg) !important - -o-transform: rotate(45deg) !important - -ms-transform: rotate(45deg) !important - transform: rotate(45deg) !important - -moz-border-radius-bottomright: 0 - //border-top-right-radius: 0 - border-bottom-right-radius: 0 - border-bottom: 0 - .leftSidebar - flex: 0 0 auto - display: flex - flex-flow: column - justify-content: flex-start - align-items: flex-start - align-content: stretch - height: 100% - //position: absolute - border: 0 - vertical-align: top - padding: 0 - text-align: left - //top: 0px - //left: 0px - //bottom: 0px - width: 220px - //Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#627d4d+0,1f3b08+100;Olive+3D - background-color: #90b272 //Old browsers - background: -moz-linear-gradient(-180deg, #90b272 0%, #4d7727 100%) //FF3.6-15 - background: -webkit-linear-gradient(-180deg, #90b272 0%,#4d7727 100%) //Chrome10-25,Safari5.1-6 - background: linear-gradient(180deg, #90b272 0%,#4d7727 100%) //W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ - font-size: 14px - font-weight: 700 - overflow: hidden - - .logoArea - flex: 0 0 auto - width: 100% - .signOut + .leftSidebarMenuButton position: absolute - left: 10px - top: 10px - color: white - cursor: pointer - .signOut:hover - color: #BBB - .signOut:active + right: -30px + -webkit-transition: .5s ease-in + -moz-transition: .5s ease-in + -o-transition: .5s ease-in + -ms-transition: .5s ease-in + transition: .5s ease-in + -webkit-border-top-right-radius: 5px + -webkit-border-bottom-right-radius: 5px + -moz-border-radius-topright: 5px + -moz-border-radius-bottomright: 5px + border-top-right-radius: 5px + border-bottom-right-radius: 5px color: black - .logo + font-size: 20px + line-height: 20px + font-weight: 900 text-align: center - margin-top: 20px - img:hover - //-webkit-animation: neon6_drop 1.5s ease-in-out infinite alternate; - //-moz-animation: neon6_drop 1.5s ease-in-out infinite alternate; - animation: neon6_drop 1.5s ease-in-out infinite alternate; - .menuArea - flex: 1 1 auto - width: 100% - ul - padding: 20px 0 0 0 - margin: 0 - list-style: none - li:first-child - border-top: 1px solid #e4e5e7 - li - border-bottom: 1px solid #e4e5e7 - color: #96a2ae - text-transform: uppercase - display: block - a - color: black - padding: 10px 20px - cursor: pointer - text-decoration: none - display: block - .tag - padding: .3em .6em - margin-top: -.2em - font-size: .8em - color: #ddd - white-space: nowrap - vertical-align: baseline - border-radius: .5em - border: 1px solid #000000 - float: right - .subMenu - background-color: #999 - padding: .3em .6em - margin-top: -.2em - font-size: .8em - color: #fff - white-space: nowrap - vertical-align: baseline - border-radius: .5em - border: 1px solid #000000 - float: right - .subMenu.active - background-color: #333 - li:hover - // Note: neon6 is defined in effects.import.styl - background-color: #666 - -webkit-animation: neon6 1.5s ease-in-out infinite alternate - -moz-animation: neon6 1.5s ease-in-out infinite alternate - animation: neon6 1.5s ease-in-out infinite alternate - .subMenu - // Note: neon6 is defined in effects.import.styl - background-color: #999 - -webkit-animation: neon7 1.5s ease-in-out infinite alternate - -moz-animation: neon7 1.5s ease-in-out infinite alternate - animation: neon7 1.5s ease-in-out infinite alternate - li.active - background-color: #333 - > a - color: #96a2ae - li.active:hover - background-color: #333 - > a - color: white - .footer + text-decoration: none + width: 30px + height: 30px + padding: 5px 0 + background-color: #90b272 + display: block + border-top: 1px solid #494 + border-right: 1px solid #494 + border-bottom: 1px solid #494 + .leftSidebarMenuButton:hover + color: rgba(150,0,0,.5) + nav.generalSidebar + .leftSidebarMenuButton + top: 10px + nav.graphsSidebar + .leftSidebarMenuButton + top: 50px + nav.settingsSidebar + .leftSidebarMenuButton + top: 90px + nav.menuHide .leftSidebarMenuButton + right: 60px + nav.menuShow + margin: 0 + nav.menuShow .leftSidebarMenuButton + right: -15px + -webkit-transform: rotate(45deg) !important + -moz-transform: rotate(45deg) !important + -o-transform: rotate(45deg) !important + -ms-transform: rotate(45deg) !important + transform: rotate(45deg) !important + -moz-border-radius-bottomright: 0 + //border-top-right-radius: 0 + border-bottom-right-radius: 0 + border-bottom: 0 + .leftSidebar flex: 0 0 auto - width: 100% - font-size: 9px - text-align: center + display: flex + flex-flow: column + justify-content: flex-start + align-items: flex-start + align-content: stretch + height: 100% + //position: absolute + border: 0 + vertical-align: top + padding: 0 + text-align: left + //top: 0px + //left: 0px + //bottom: 0px + width: 220px + //Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#627d4d+0,1f3b08+100;Olive+3D + background-color: #90b272 //Old browsers + background: -moz-linear-gradient(-180deg, #90b272 0%, #4d7727 100%) //FF3.6-15 + background: -webkit-linear-gradient(-180deg, #90b272 0%,#4d7727 100%) //Chrome10-25,Safari5.1-6 + background: linear-gradient(180deg, #90b272 0%,#4d7727 100%) //W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ + font-size: 14px + font-weight: 700 + overflow: hidden - .contentBody - flex: 1 1 1px - padding: 10px 20px - -webkit-box-shadow: inset 4px 2px 10px -3px rgba(168,165,168,1) - -moz-box-shadow: inset 4px 2px 10px -3px rgba(168,165,168,1) - box-shadow: inset 8px 0px 10px -3px rgba(168,165,168,1) - overflow: hidden \ No newline at end of file + .logoArea + flex: 0 0 auto + width: 100% + .signOut + position: absolute + left: 10px + top: 10px + color: white + cursor: pointer + .signOut:hover + color: #BBB + .signOut:active + color: black + .logo + text-align: center + margin-top: 20px + img:hover + //-webkit-animation: neon6_drop 1.5s ease-in-out infinite alternate; + //-moz-animation: neon6_drop 1.5s ease-in-out infinite alternate; + animation: neon6_drop 1.5s ease-in-out infinite alternate; + .menuArea + flex: 1 1 auto + width: 100% + ul + padding: 20px 0 0 0 + margin: 0 + list-style: none + li:first-child + border-top: 1px solid #e4e5e7 + li + border-bottom: 1px solid #e4e5e7 + color: #96a2ae + text-transform: uppercase + display: block + a + color: black + padding: 10px 20px + cursor: pointer + text-decoration: none + display: block + .tag + padding: .3em .6em + margin-top: -.2em + font-size: .8em + color: #ddd + white-space: nowrap + vertical-align: baseline + border-radius: .5em + border: 1px solid #000000 + float: right + .subMenu + background-color: #999 + padding: .3em .6em + margin-top: -.2em + font-size: .8em + color: #fff + white-space: nowrap + vertical-align: baseline + border-radius: .5em + border: 1px solid #000000 + float: right + .subMenu.active + background-color: #333 + li:hover + // Note: neon6 is defined in effects.import.styl + background-color: #666 + -webkit-animation: neon6 1.5s ease-in-out infinite alternate + -moz-animation: neon6 1.5s ease-in-out infinite alternate + animation: neon6 1.5s ease-in-out infinite alternate + .subMenu + // Note: neon6 is defined in effects.import.styl + background-color: #999 + -webkit-animation: neon7 1.5s ease-in-out infinite alternate + -moz-animation: neon7 1.5s ease-in-out infinite alternate + animation: neon7 1.5s ease-in-out infinite alternate + li.active + background-color: #333 + > a + color: #96a2ae + li.active:hover + background-color: #333 + > a + color: white + .footer + flex: 0 0 auto + width: 100% + font-size: 9px + text-align: center + .contentBody + flex: 1 1 1px + padding: 10px 20px + -webkit-box-shadow: inset 4px 2px 10px -3px rgba(168,165,168,1) + -moz-box-shadow: inset 4px 2px 10px -3px rgba(168,165,168,1) + box-shadow: inset 8px 0 10px -3px rgba(168,165,168,1) + overflow: hidden + + @media print + nav.leftSidebarContainer + display: none + .contentBody + flex: 1 1 1px + padding: 0 + margin: 0 + overflow: hidden \ No newline at end of file diff --git a/imports/ui/layouts/Empty.html b/imports/ui/layouts/Empty.html new file mode 100644 index 0000000..652b731 --- /dev/null +++ b/imports/ui/layouts/Empty.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/imports/ui/layouts/Empty.js b/imports/ui/layouts/Empty.js new file mode 100644 index 0000000..5d0cc58 --- /dev/null +++ b/imports/ui/layouts/Empty.js @@ -0,0 +1,2 @@ +import { Template } from 'meteor/templating'; +import './Empty.html'; \ No newline at end of file diff --git a/imports/util/qrcode/README.md b/imports/util/qrcode/README.md new file mode 100644 index 0000000..5e2d2dc --- /dev/null +++ b/imports/util/qrcode/README.md @@ -0,0 +1,46 @@ +# QRCode.js +QRCode.js is javascript library for making QRCode. QRCode.js supports Cross-browser with HTML5 Canvas and table tag in DOM. +QRCode.js has no dependencies. + +## Basic Usages +``` +
+ +``` + +or with some options + +``` +
+ +``` + +and you can use some methods + +``` +qrcode.clear(); // clear the code. +qrcode.makeCode("http://naver.com"); // make another code. +``` + +## Browser Compatibility +IE6~10, Chrome, Firefox, Safari, Opera, Mobile Safari, Android, Windows Mobile, ETC. + +## License +MIT License + +## Contact +twitter @davidshimjs + +[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/davidshimjs/qrcodejs/trend.png)](https://bitdeli.com/free "Bitdeli Badge") + diff --git a/imports/util/qrcode/qrcode.js b/imports/util/qrcode/qrcode.js new file mode 100644 index 0000000..bdc3872 --- /dev/null +++ b/imports/util/qrcode/qrcode.js @@ -0,0 +1,616 @@ +/** + * @fileoverview + * - Using the 'QRCode for Javascript library' + * - Fixed dataset of 'QRCode for Javascript library' for support full-spec. + * - this library has no dependencies. + * + * @author davidshimjs + * @see http://www.d-project.com/ + * @see http://jeromeetienne.github.com/jquery-qrcode/ + */ +var QRCode; + +(function () { + //--------------------------------------------------------------------- + // QRCode for JavaScript + // + // Copyright (c) 2009 Kazuhiko Arase + // + // URL: http://www.d-project.com/ + // + // Licensed under the MIT license: + // http://www.opensource.org/licenses/mit-license.php + // + // The word "QR Code" is registered trademark of + // DENSO WAVE INCORPORATED + // http://www.denso-wave.com/qrcode/faqpatent-e.html + // + //--------------------------------------------------------------------- + function QR8bitByte(data) { + this.mode = QRMode.MODE_8BIT_BYTE; + this.data = data; + this.parsedData = []; + + // Added to support UTF-8 Characters + for (var i = 0, l = this.data.length; i < l; i++) { + var byteArray = []; + var code = this.data.charCodeAt(i); + + if (code > 0x10000) { + byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18); + byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12); + byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[3] = 0x80 | (code & 0x3F); + } else if (code > 0x800) { + byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12); + byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[2] = 0x80 | (code & 0x3F); + } else if (code > 0x80) { + byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6); + byteArray[1] = 0x80 | (code & 0x3F); + } else { + byteArray[0] = code; + } + + this.parsedData.push(byteArray); + } + + this.parsedData = Array.prototype.concat.apply([], this.parsedData); + + if (this.parsedData.length != this.data.length) { + this.parsedData.unshift(191); + this.parsedData.unshift(187); + this.parsedData.unshift(239); + } + } + + QR8bitByte.prototype = { + getLength: function (buffer) { + return this.parsedData.length; + }, + write: function (buffer) { + for (var i = 0, l = this.parsedData.length; i < l; i++) { + buffer.put(this.parsedData[i], 8); + } + } + }; + + function QRCodeModel(typeNumber, errorCorrectLevel) { + this.typeNumber = typeNumber; + this.errorCorrectLevel = errorCorrectLevel; + this.modules = null; + this.moduleCount = 0; + this.dataCache = null; + this.dataList = []; + } + + QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);} + return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row=7){this.setupTypeNumber(test);} + if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);} + this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} + return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;} + for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}} + for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}} + this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex>>bitIndex)&1)==1);} + var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;} + this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}} + row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;itotalDataCount*8){throw new Error("code length overflow. (" + +buffer.getLengthInBits() + +">" + +totalDataCount*8 + +")");} + if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} + while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} + while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD1,8);} + return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r=0)?modPoly.get(modIndex):0;}} + var totalCodeCount=0;for(var i=0;i=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));} + return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));} + return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;} + return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i5){lostPoint+=(3+sameCount-5);}}} + for(var row=0;row=256){n-=255;} + return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);} + if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));} + this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]]; + + function _isSupportCanvas() { + return typeof CanvasRenderingContext2D != "undefined"; + } + + // android 2.x doesn't support Data-URI spec + function _getAndroid() { + var android = false; + var sAgent = navigator.userAgent; + + if (/android/i.test(sAgent)) { // android + android = true; + var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i); + + if (aMat && aMat[1]) { + android = parseFloat(aMat[1]); + } + } + + return android; + } + + var svgDrawer = (function() { + + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + + this.clear(); + + function makeSVG(tag, attrs) { + var el = document.createElementNS('http://www.w3.org/2000/svg', tag); + for (var k in attrs) + if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]); + return el; + } + + var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight}); + svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); + _el.appendChild(svg); + + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"})); + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"})); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + if (oQRCode.isDark(row, col)) { + var child = makeSVG("use", {"x": String(col), "y": String(row)}); + child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template") + svg.appendChild(child); + } + } + } + }; + Drawing.prototype.clear = function () { + while (this._el.hasChildNodes()) + this._el.removeChild(this._el.lastChild); + }; + return Drawing; + })(); + + var useSVG = document.documentElement.tagName.toLowerCase() === "svg"; + + // Drawing in DOM by using Table tag + var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () { + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + var aHTML = ['
']; + + for (var row = 0; row < nCount; row++) { + aHTML.push(''); + + for (var col = 0; col < nCount; col++) { + aHTML.push(''); + } + + aHTML.push(''); + } + + aHTML.push('
'); + _el.innerHTML = aHTML.join(''); + + // Fix the margin values as real size. + var elTable = _el.childNodes[0]; + var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2; + var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2; + + if (nLeftMarginTable > 0 && nTopMarginTable > 0) { + elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px"; + } + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._el.innerHTML = ''; + }; + + return Drawing; + })() : (function () { // Drawing in Canvas + function _onMakeImage() { + this._elImage.src = this._elCanvas.toDataURL("image/png"); + this._elImage.style.display = "block"; + this._elCanvas.style.display = "none"; + } + + // Android 2.1 bug workaround + // http://code.google.com/p/android/issues/detail?id=5141 + if (this._android && this._android <= 2.1) { + var factor = 1 / window.devicePixelRatio; + var drawImage = CanvasRenderingContext2D.prototype.drawImage; + CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) { + if (("nodeName" in image) && /img/i.test(image.nodeName)) { + for (var i = arguments.length - 1; i >= 1; i--) { + arguments[i] = arguments[i] * factor; + } + } else if (typeof dw == "undefined") { + arguments[1] *= factor; + arguments[2] *= factor; + arguments[3] *= factor; + arguments[4] *= factor; + } + + drawImage.apply(this, arguments); + }; + } + + /** + * Check whether the user's browser supports Data URI or not + * + * @private + * @param {Function} fSuccess Occurs if it supports Data URI + * @param {Function} fFail Occurs if it doesn't support Data URI + */ + function _safeSetDataURI(fSuccess, fFail) { + var self = this; + self._fFail = fFail; + self._fSuccess = fSuccess; + + // Check it just once + if (self._bSupportDataURI === null) { + var el = document.createElement("img"); + var fOnError = function() { + self._bSupportDataURI = false; + + if (self._fFail) { + self._fFail.call(self); + } + }; + var fOnSuccess = function() { + self._bSupportDataURI = true; + + if (self._fSuccess) { + self._fSuccess.call(self); + } + }; + + el.onabort = fOnError; + el.onerror = fOnError; + el.onload = fOnSuccess; + el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data. + return; + } else if (self._bSupportDataURI === true && self._fSuccess) { + self._fSuccess.call(self); + } else if (self._bSupportDataURI === false && self._fFail) { + self._fFail.call(self); + } + }; + + /** + * Drawing QRCode by using canvas + * + * @constructor + * @param {HTMLElement} el + * @param {Object} htOption QRCode Options + */ + var Drawing = function (el, htOption) { + this._bIsPainted = false; + this._android = _getAndroid(); + + this._htOption = htOption; + this._elCanvas = document.createElement("canvas"); + this._elCanvas.width = htOption.width; + this._elCanvas.height = htOption.height; + el.appendChild(this._elCanvas); + this._el = el; + this._oContext = this._elCanvas.getContext("2d"); + this._bIsPainted = false; + this._elImage = document.createElement("img"); + this._elImage.alt = "Scan me!"; + this._elImage.style.display = "none"; + this._el.appendChild(this._elImage); + this._bSupportDataURI = null; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _elImage = this._elImage; + var _oContext = this._oContext; + var _htOption = this._htOption; + + var nCount = oQRCode.getModuleCount(); + var nWidth = _htOption.width / nCount; + var nHeight = _htOption.height / nCount; + var nRoundedWidth = Math.round(nWidth); + var nRoundedHeight = Math.round(nHeight); + + _elImage.style.display = "none"; + this.clear(); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + var bIsDark = oQRCode.isDark(row, col); + var nLeft = col * nWidth; + var nTop = row * nHeight; + _oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.lineWidth = 1; + _oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.fillRect(nLeft, nTop, nWidth, nHeight); + + // 안티 앨리어싱 방지 처리 + _oContext.strokeRect( + Math.floor(nLeft) + 0.5, + Math.floor(nTop) + 0.5, + nRoundedWidth, + nRoundedHeight + ); + + _oContext.strokeRect( + Math.ceil(nLeft) - 0.5, + Math.ceil(nTop) - 0.5, + nRoundedWidth, + nRoundedHeight + ); + } + } + + this._bIsPainted = true; + }; + + /** + * Make the image from Canvas if the browser supports Data URI. + */ + Drawing.prototype.makeImage = function () { + if (this._bIsPainted) { + _safeSetDataURI.call(this, _onMakeImage); + } + }; + + /** + * Return whether the QRCode is painted or not + * + * @return {Boolean} + */ + Drawing.prototype.isPainted = function () { + return this._bIsPainted; + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height); + this._bIsPainted = false; + }; + + /** + * @private + * @param {Number} nNumber + */ + Drawing.prototype.round = function (nNumber) { + if (!nNumber) { + return nNumber; + } + + return Math.floor(nNumber * 1000) / 1000; + }; + + return Drawing; + })(); + + /** + * Get the type by string length + * + * @private + * @param {String} sText + * @param {Number} nCorrectLevel + * @return {Number} type + */ + function _getTypeNumber(sText, nCorrectLevel) { + var nType = 1; + var length = _getUTF8Length(sText); + + for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) { + var nLimit = 0; + + switch (nCorrectLevel) { + case QRErrorCorrectLevel.L : + nLimit = QRCodeLimitLength[i][0]; + break; + case QRErrorCorrectLevel.M : + nLimit = QRCodeLimitLength[i][1]; + break; + case QRErrorCorrectLevel.Q : + nLimit = QRCodeLimitLength[i][2]; + break; + case QRErrorCorrectLevel.H : + nLimit = QRCodeLimitLength[i][3]; + break; + } + + if (length <= nLimit) { + break; + } else { + nType++; + } + } + + if (nType > QRCodeLimitLength.length) { + throw new Error("Too long data"); + } + + return nType; + } + + function _getUTF8Length(sText) { + var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a'); + return replacedText.length + (replacedText.length != sText ? 3 : 0); + } + + /** + * @class QRCode + * @constructor + * @example + * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie"); + * + * @example + * var oQRCode = new QRCode("test", { + * text : "http://naver.com", + * width : 128, + * height : 128 + * }); + * + * oQRCode.clear(); // Clear the QRCode. + * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode. + * + * @param {HTMLElement|String} el target element or 'id' attribute of element. + * @param {Object|String} vOption + * @param {String} vOption.text QRCode link data + * @param {Number} [vOption.width=256] + * @param {Number} [vOption.height=256] + * @param {String} [vOption.colorDark="#000000"] + * @param {String} [vOption.colorLight="#ffffff"] + * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] + */ + QRCode = function (el, vOption) { + this._htOption = { + width : 256, + height : 256, + typeNumber : 4, + colorDark : "#000000", + colorLight : "#ffffff", + correctLevel : QRErrorCorrectLevel.H + }; + + if (typeof vOption === 'string') { + vOption = { + text : vOption + }; + } + + // Overwrites options + if (vOption) { + for (var i in vOption) { + this._htOption[i] = vOption[i]; + } + } + + if (typeof el == "string") { + el = document.getElementById(el); + } + + if (this._htOption.useSVG) { + Drawing = svgDrawer; + } + + this._android = _getAndroid(); + this._el = el; + this._oQRCode = null; + this._oDrawing = new Drawing(this._el, this._htOption); + + if (this._htOption.text) { + this.makeCode(this._htOption.text); + } + }; + + /** + * Make the QRCode + * + * @param {String} sText link data + */ + QRCode.prototype.makeCode = function (sText) { + this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel); + this._oQRCode.addData(sText); + this._oQRCode.make(); + this._el.title = sText; + this._oDrawing.draw(this._oQRCode); + this.makeImage(); + }; + + /** + * Make the Image from Canvas element + * - It occurs automatically + * - Android below 3 doesn't support Data-URI spec. + * + * @private + */ + QRCode.prototype.makeImage = function () { + if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) { + this._oDrawing.makeImage(); + } + }; + + /** + * Clear the QRCode + */ + QRCode.prototype.clear = function () { + this._oDrawing.clear(); + }; + + /** + * @name QRCode.CorrectLevel + */ + QRCode.CorrectLevel = QRErrorCorrectLevel; +})(); + +export default QRCode; \ No newline at end of file diff --git a/imports/util/qrcode/qrcode.min.js b/imports/util/qrcode/qrcode.min.js new file mode 100644 index 0000000..993e88f --- /dev/null +++ b/imports/util/qrcode/qrcode.min.js @@ -0,0 +1 @@ +var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d8f7c12..8befc95 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,25 +4,100 @@ "lockfileVersion": 1, "dependencies": { "@babel/runtime": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.2.0.tgz", - "integrity": "sha512-oouEibCbHMVdZSDlJBO6bZmID/zA/G/Qx3H1d3rSNPTD+L8UNKvCat7aKWSJ74zYbm5zWGh0GQN0hKj8zYFTCg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz", + "integrity": "sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==", "requires": { - "regenerator-runtime": "^0.12.0" + "regenerator-runtime": "^0.13.2" }, "dependencies": { "regenerator-runtime": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" } } }, + "abab": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", + "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=" + }, + "acorn": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", + "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=" + }, + "acorn-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz", + "integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=", + "requires": { + "acorn": "^2.1.0" + } + }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, "atoa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/atoa/-/atoa-1.0.0.tgz", "integrity": "sha1-DMDpGkgOc4+SPrwQNnZHF3mzSkk=" }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -32,11 +107,95 @@ "regenerator-runtime": "^0.11.0" } }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "canvg": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/canvg/-/canvg-1.5.3.tgz", + "integrity": "sha512-7Gn2IuQzvUQWPIuZuFHrzsTM0gkPz2RRT9OcbdmA03jeKk8kltrD8gqUzNX15ghY/4PV5bbe5lmD6yDLDY6Ybg==", + "requires": { + "jsdom": "^8.1.0", + "rgbcolor": "^1.0.1", + "stackblur-canvas": "^1.4.1", + "xmldom": "^0.1.22" + }, + "dependencies": { + "stackblur-canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-1.4.1.tgz", + "integrity": "sha1-hJqm+UsnL/JvZHH6QTDtH35HlVs=" + } + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, "commander": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", "integrity": "sha1-FXFS/R56bI2YpbcVzzdt+SgARWM=" }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, "contra": { "version": "1.9.4", "resolved": "https://registry.npmjs.org/contra/-/contra-1.9.4.tgz", @@ -51,6 +210,11 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, "crossvent": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/crossvent/-/crossvent-1.5.4.tgz", @@ -59,10 +223,31 @@ "custom-event": "1.0.0" } }, + "css-line-break": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-1.0.1.tgz", + "integrity": "sha1-GfIGOjPpX7KDG4ZEbAuAwYivRQo=", + "requires": { + "base64-arraybuffer": "^0.1.5" + } + }, + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + }, + "cssstyle": { + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", + "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", + "requires": { + "cssom": "0.3.x" + } + }, "csv-parse": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-1.2.3.tgz", - "integrity": "sha1-RmIGtR6vd8y1DD+t69CYzessaec=" + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.4.6.tgz", + "integrity": "sha512-VisC5TBBhOF+70zjrF9FOiqI2LZOhXK/vAWlOrqyqz3lLa+P8jzJ7L/sg90MHmkSY/brAXWwrmGSZR0tM5yi4g==" }, "custom-event": { "version": "1.0.0", @@ -324,6 +509,37 @@ "d3-transition": "1" } }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "dom-to-image": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/dom-to-image/-/dom-to-image-2.6.0.tgz", + "integrity": "sha1-ilA2CAiMh7HCL5A0rgMuGJiVWGc=" + }, "dragula": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/dragula/-/dragula-3.7.2.tgz", @@ -333,36 +549,468 @@ "crossvent": "1.5.4" } }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escodegen": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", + "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extract-zip": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", + "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", + "requires": { + "concat-stream": "1.6.2", + "debug": "2.6.9", + "mkdirp": "0.5.1", + "yauzl": "2.4.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "requires": { + "pend": "~1.2.0" + } + }, + "file-saver": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.2.tgz", + "integrity": "sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw==" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "html2canvas": { + "version": "1.0.0-alpha.12", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.0.0-alpha.12.tgz", + "integrity": "sha1-OxmS48mz9WBjw1/WIElPN+uohRM=", + "requires": { + "css-line-break": "1.0.1" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", + "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + } + } }, "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", "integrity": "sha1-90aPYBNfXl2tM5nAqBvpoWA6CCs=" }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, "jquery": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz", - "integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c=" + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", + "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==" }, "jquery-mousewheel": { "version": "3.1.13", "resolved": "https://registry.npmjs.org/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz", "integrity": "sha1-BvAzXxbjU6aV5yBr9QUDy1I6buU=" }, - "lodash._reinterpolate": { + "jsbarcode": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/jsbarcode/-/jsbarcode-3.11.0.tgz", + "integrity": "sha512-/ozCd7wsa+VIHo9sUc03HneVEQrH7cVWfJolUT/WOW1m8mJ2e3iYZje6C9X3LFHdczlesqFHRpxLtbVsNtjyow==" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsdom": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-8.5.0.tgz", + "integrity": "sha1-1Nj12/J2hjW2KmKCO5R89wcevJg=", + "requires": { + "abab": "^1.0.0", + "acorn": "^2.4.0", + "acorn-globals": "^1.0.4", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.0 < 0.4.0", + "cssstyle": ">= 0.2.34 < 0.3.0", + "escodegen": "^1.6.1", + "iconv-lite": "^0.4.13", + "nwmatcher": ">= 1.3.7 < 2.0.0", + "parse5": "^1.5.1", + "request": "^2.55.0", + "sax": "^1.1.4", + "symbol-tree": ">= 3.1.0 < 4.0.0", + "tough-cookie": "^2.2.0", + "webidl-conversions": "^3.0.1", + "whatwg-url": "^2.0.1", + "xml-name-validator": ">= 2.0.1 < 3.0.0" + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jspdf": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-1.5.3.tgz", + "integrity": "sha512-J9X76xnncMw+wIqb15HeWfPMqPwYxSpPY8yWPJ7rAZN/ZDzFkjCSZObryCyUe8zbrVRNiuCnIeQteCzMn7GnWw==", + "requires": { + "canvg": "1.5.3", + "file-saver": "github:eligrey/FileSaver.js#e865e37af9f9947ddcced76b549e27dc45c1cb2e", + "html2canvas": "1.0.0-alpha.12", + "omggif": "1.0.7", + "promise-polyfill": "8.1.0", + "stackblur-canvas": "2.2.0" + }, + "dependencies": { + "file-saver": { + "version": "github:eligrey/FileSaver.js#e865e37af9f9947ddcced76b549e27dc45c1cb2e", + "from": "github:eligrey/FileSaver.js#1.3.8" + } + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lodash._basecallback": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/lodash._basecallback/-/lodash._basecallback-3.3.1.tgz", + "integrity": "sha1-t7K7Q9whYEJKIczybFfkQ3cqjic=", + "requires": { + "lodash._baseisequal": "^3.0.0", + "lodash._bindcallback": "^3.0.0", + "lodash.isarray": "^3.0.0", + "lodash.pairs": "^3.0.0" + } + }, + "lodash._baseeach": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash._baseeach/-/lodash._baseeach-3.0.4.tgz", + "integrity": "sha1-z4cGVyyhROjZ11InyZDamC+TKvM=", + "requires": { + "lodash.keys": "^3.0.0" + } + }, + "lodash._basefind": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + "resolved": "https://registry.npmjs.org/lodash._basefind/-/lodash._basefind-3.0.0.tgz", + "integrity": "sha1-srugXMZF+XLeLPkl+iv2Og9gyK4=" + }, + "lodash._basefindindex": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/lodash._basefindindex/-/lodash._basefindindex-3.6.0.tgz", + "integrity": "sha1-8IM2ChsCJBjtgbyJm+sxLiHnSk8=" + }, + "lodash._baseisequal": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/lodash._baseisequal/-/lodash._baseisequal-3.0.7.tgz", + "integrity": "sha1-2AJfdjOdKTQnZ9zIh85cuVpbUfE=", + "requires": { + "lodash.isarray": "^3.0.0", + "lodash.istypedarray": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "lodash._baseismatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lodash._baseismatch/-/lodash._baseismatch-3.1.3.tgz", + "integrity": "sha1-Byj8SO+hFpnT1fLXMEnyqxPED9U=", + "requires": { + "lodash._baseisequal": "^3.0.0" + } + }, + "lodash._basematches": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._basematches/-/lodash._basematches-3.2.0.tgz", + "integrity": "sha1-9H4D8H7CB4SrCWjQy2y1l+IQEVg=", + "requires": { + "lodash._baseismatch": "^3.0.0", + "lodash.pairs": "^3.0.0" + } + }, + "lodash._bindcallback": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=" + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" + }, + "lodash.every": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.every/-/lodash.every-4.6.0.tgz", + "integrity": "sha1-64mYS+vENkJ5uzrvu9HKGb+mxqc=" + }, + "lodash.find": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", + "integrity": "sha1-ywcE1Hq3F4n/oN6Ll92Sb7iLE7E=" + }, + "lodash.findwhere": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.findwhere/-/lodash.findwhere-3.1.0.tgz", + "integrity": "sha1-eTfTTz6sgY3sf6lOjKXib9uhz8E=", + "requires": { + "lodash._basematches": "^3.0.0", + "lodash.find": "^3.0.0" + }, + "dependencies": { + "lodash.find": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-3.2.1.tgz", + "integrity": "sha1-BG4xnzrOkSrGySRsf2g8XsB7Nq0=", + "requires": { + "lodash._basecallback": "^3.0.0", + "lodash._baseeach": "^3.0.0", + "lodash._basefind": "^3.0.0", + "lodash._basefindindex": "^3.0.0", + "lodash.isarray": "^3.0.0", + "lodash.keys": "^3.0.0" + } + } + } }, "lodash.foreach": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" + }, "lodash.isempty": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", @@ -373,10 +1021,48 @@ "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=" }, - "lodash.merge": { + "lodash.istypedarray": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz", + "integrity": "sha1-yaR3SYYHUB2OhJTSg7h8OSgc72I=" + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "requires": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=" + }, + "lodash.pairs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.pairs/-/lodash.pairs-3.0.1.tgz", + "integrity": "sha1-u+CNV4bu6qCaFckevw3LfSvjJqk=", + "requires": { + "lodash.keys": "^3.0.0" + } + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" + }, + "lodash.union": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz", - "integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU=" + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" }, "lodash.without": { "version": "4.4.0", @@ -392,37 +1078,17 @@ } }, "message-box": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/message-box/-/message-box-0.1.1.tgz", - "integrity": "sha1-d4VlhUzUUn0mc3P8IBJN4Ycpjaw=", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/message-box/-/message-box-0.2.2.tgz", + "integrity": "sha512-A32m9D2ZaE08ZaXoE74AjcKwjtwwEhDT2EeY7A3YMAEB4ypL0uMZw7HegwZ806GIWyY4VLwe3kGO9reIdjwiRg==", "requires": { - "lodash.merge": "^4.6.0", - "lodash.template": "^4.4.0" - }, - "dependencies": { - "lodash.template": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", - "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", - "requires": { - "lodash._reinterpolate": "~3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", - "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", - "requires": { - "lodash._reinterpolate": "~3.0.0" - } - } + "lodash": "^4.17.14" } }, "meteor-node-stubs": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/meteor-node-stubs/-/meteor-node-stubs-0.2.11.tgz", - "integrity": "sha1-cV5Owc6IgkiylgThbQkiVrDLfjQ=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/meteor-node-stubs/-/meteor-node-stubs-0.4.1.tgz", + "integrity": "sha512-UO2OStvLOKoApmOdIP5eCqoLaa/ritMXRg4ffJVdkNLEsczzPvTjgC0Mxk4cM4R8MZkwll90FYgjDf5qUTJdMA==", "requires": { "assert": "^1.4.1", "browserify-zlib": "^0.1.4", @@ -432,16 +1098,16 @@ "crypto-browserify": "^3.11.0", "domain-browser": "^1.1.7", "events": "^1.1.1", - "http-browserify": "^1.7.0", "https-browserify": "0.0.1", "os-browserify": "^0.2.1", "path-browserify": "0.0.0", "process": "^0.11.9", "punycode": "^1.4.1", "querystring-es3": "^0.2.1", - "readable-stream": "git+https://github.com/meteor/readable-stream.git#2e9112d7d31a2af6e0682db0e18679b1e5fd4694", + "readable-stream": "^2.3.6", "stream-browserify": "^2.0.1", - "string_decoder": "^1.0.1", + "stream-http": "^2.8.0", + "string_decoder": "^1.1.0", "timers-browserify": "^1.4.2", "tty-browserify": "0.0.0", "url": "^0.11.0", @@ -449,15 +1115,9 @@ "vm-browserify": "0.0.4" }, "dependencies": { - "Base64": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/Base64/-/Base64-0.2.1.tgz", - "integrity": "sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg=" - }, "asn1.js": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.0.tgz", - "integrity": "sha1-9xoSQ/PnnUbXsH1/v0gk7nOvBUo=", + "version": "4.10.1", + "bundled": true, "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", @@ -466,43 +1126,38 @@ }, "assert": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "bundled": true, "requires": { "util": "0.10.3" } }, "base64-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.0.tgz", - "integrity": "sha1-o5mS1yNYSBGYK+XikLtqU9hnAPE=" + "version": "1.3.0", + "bundled": true }, "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" + "version": "4.11.8", + "bundled": true }, "brorand": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.0.6.tgz", - "integrity": "sha1-QChwa5FfkfezSaLgvzw3YDnSFuU=" + "version": "1.1.0", + "bundled": true }, "browserify-aes": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.6.tgz", - "integrity": "sha1-Xncl297x/Vkw1OurSFZ85FHEigo=", + "version": "1.2.0", + "bundled": true, "requires": { - "buffer-xor": "^1.0.2", + "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "inherits": "^2.0.1" + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "browserify-cipher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", - "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "version": "1.0.1", + "bundled": true, "requires": { "browserify-aes": "^1.0.4", "browserify-des": "^1.0.0", @@ -510,9 +1165,8 @@ } }, "browserify-des": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", - "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "version": "1.0.1", + "bundled": true, "requires": { "cipher-base": "^1.0.1", "des.js": "^1.0.0", @@ -521,17 +1175,15 @@ }, "browserify-rsa": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "bundled": true, "requires": { "bn.js": "^4.1.0", "randombytes": "^2.0.1" } }, "browserify-sign": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.0.tgz", - "integrity": "sha1-EHc5EMPCBtVCCkaq2GlPgguFlo8=", + "version": "4.0.4", + "bundled": true, "requires": { "bn.js": "^4.1.1", "browserify-rsa": "^4.0.0", @@ -544,16 +1196,14 @@ }, "browserify-zlib": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", - "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "bundled": true, "requires": { "pako": "~0.2.0" } }, "buffer": { "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "bundled": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4", @@ -562,63 +1212,69 @@ }, "buffer-xor": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + "bundled": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "bundled": true }, "cipher-base": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.3.tgz", - "integrity": "sha1-7qvxlEGc6QDaMBjCB9IS8qbfCgc=", + "version": "1.0.4", + "bundled": true, "requires": { - "inherits": "^2.0.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "console-browserify": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "bundled": true, "requires": { "date-now": "^0.1.4" } }, "constants-browserify": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" + "bundled": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true }, "create-ecdh": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", - "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "version": "4.0.3", + "bundled": true, "requires": { "bn.js": "^4.1.0", "elliptic": "^6.0.0" } }, "create-hash": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.2.tgz", - "integrity": "sha1-USEAYte7dHn2xlu0GpIgix1hq60=", + "version": "1.2.0", + "bundled": true, "requires": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", - "ripemd160": "^1.0.0", - "sha.js": "^2.3.6" + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" } }, "create-hmac": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.4.tgz", - "integrity": "sha1-0/tLolPriz9W456i+8uK90e9MXA=", + "version": "1.1.7", + "bundled": true, "requires": { + "cipher-base": "^1.0.3", "create-hash": "^1.1.0", - "inherits": "^2.0.1" + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, "crypto-browserify": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.0.tgz", - "integrity": "sha1-NlKgkGq5sqfgw85mpAjpV6JIVSI=", + "version": "3.12.0", + "bundled": true, "requires": { "browserify-cipher": "^1.0.0", "browserify-sign": "^4.0.0", @@ -629,27 +1285,25 @@ "inherits": "^2.0.1", "pbkdf2": "^3.0.3", "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0" + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" } }, "date-now": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" + "bundled": true }, "des.js": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "bundled": true, "requires": { "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0" } }, "diffie-hellman": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", - "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "version": "5.0.3", + "bundled": true, "requires": { "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", @@ -657,104 +1311,120 @@ } }, "domain-browser": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", - "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=" + "version": "1.2.0", + "bundled": true }, "elliptic": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.2.tgz", - "integrity": "sha1-5MgeCCnPCmWrcOmYuCMnI7XBvEg=", + "version": "6.4.0", + "bundled": true, "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", "hash.js": "^1.0.0", - "inherits": "^2.0.1" + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" } }, "events": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + "bundled": true }, "evp_bytestokey": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz", - "integrity": "sha1-SXtmrZ/vZc18CKYYCCS6FHa2blM=", + "version": "1.0.3", + "bundled": true, "requires": { - "create-hash": "^1.1.1" + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "hash-base": { + "version": "3.0.4", + "bundled": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "hash.js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz", - "integrity": "sha1-EzL/ABVsCg/92CNgE9B7d6BFFXM=", + "version": "1.1.3", + "bundled": true, "requires": { - "inherits": "^2.0.1" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "bundled": true + } } }, - "http-browserify": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/http-browserify/-/http-browserify-1.7.0.tgz", - "integrity": "sha1-M3la3nLfiKz7/TZ3PO/tp2RzWyA=", + "hmac-drbg": { + "version": "1.0.1", + "bundled": true, "requires": { - "Base64": "~0.2.0", - "inherits": "~2.0.1" + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" } }, "https-browserify": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", - "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=" + "bundled": true }, "ieee754": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", - "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" + "version": "1.1.11", + "bundled": true }, "indexof": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + "bundled": true }, "inherits": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + "bundled": true }, "isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "bundled": true + }, + "md5.js": { + "version": "1.3.4", + "bundled": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } }, "miller-rabin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.0.tgz", - "integrity": "sha1-SmL7HUKTPAVYOYL0xxb2+55sbT0=", + "version": "4.0.1", + "bundled": true, "requires": { "bn.js": "^4.0.0", "brorand": "^1.0.1" } }, "minimalistic-assert": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", - "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=" + "version": "1.0.1", + "bundled": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "bundled": true }, "os-browserify": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", - "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=" + "bundled": true }, "pako": { "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=" + "bundled": true }, "parse-asn1": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.0.0.tgz", - "integrity": "sha1-NQYPbVAV03Yox3D04JGgtaJ4vCM=", + "version": "5.1.1", + "bundled": true, "requires": { "asn1.js": "^4.0.0", "browserify-aes": "^1.0.0", @@ -765,31 +1435,30 @@ }, "path-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", - "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=" + "bundled": true }, "pbkdf2": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.9.tgz", - "integrity": "sha1-8sSyWmAAWLPDdzwIbDfbvuH/5pM=", + "version": "3.0.16", + "bundled": true, "requires": { - "create-hmac": "^1.1.2" + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, "process": { - "version": "0.11.9", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.9.tgz", - "integrity": "sha1-e9WtIapiU+fahoImTx4R0RwDGME=" + "version": "0.11.10", + "bundled": true }, "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + "version": "2.0.0", + "bundled": true }, "public-encrypt": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", - "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "version": "4.0.2", + "bundled": true, "requires": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", @@ -800,88 +1469,114 @@ }, "punycode": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "bundled": true }, "querystring": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + "bundled": true }, "querystring-es3": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" + "bundled": true }, "randombytes": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.3.tgz", - "integrity": "sha1-Z0yZdgkBw8QRJ3GjHlIdw0nMCew=" + "version": "2.0.6", + "bundled": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "bundled": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } }, "readable-stream": { - "version": "git+https://github.com/meteor/readable-stream.git#2e9112d7d31a2af6e0682db0e18679b1e5fd4694", - "from": "git+https://github.com/meteor/readable-stream.git", + "version": "2.3.6", + "bundled": true, "requires": { - "inherits": "~2.0.1", + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "safe-buffer": "^5.0.1", - "string_decoder": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "bundled": true + } } }, "ripemd160": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz", - "integrity": "sha1-k6S71JQrxXS2mo+lfHHeEOzKfW4=" + "version": "2.0.2", + "bundled": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } }, "safe-buffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", - "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=" + "version": "5.1.2", + "bundled": true }, "sha.js": { - "version": "2.4.8", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", - "integrity": "sha1-NwaMLEdra69ALRSknGf1l5IfY08=", + "version": "2.4.11", + "bundled": true, "requires": { - "inherits": "^2.0.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "stream-browserify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", - "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "bundled": true, "requires": { "inherits": "~2.0.1", "readable-stream": "^2.0.2" } }, - "string_decoder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", - "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", + "stream-http": { + "version": "2.8.1", + "bundled": true, "requires": { - "safe-buffer": "^5.0.1" + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.3", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "requires": { + "safe-buffer": "~5.1.0" } }, "timers-browserify": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", - "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "bundled": true, "requires": { "process": "~0.11.0" } }, + "to-arraybuffer": { + "version": "1.0.1", + "bundled": true + }, "tty-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" + "bundled": true }, "url": { "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "bundled": true, "requires": { "punycode": "1.3.2", "querystring": "0.2.0" @@ -889,38 +1584,77 @@ "dependencies": { "punycode": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + "bundled": true } } }, "util": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "bundled": true, "requires": { "inherits": "2.0.1" } }, "util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "bundled": true }, "vm-browserify": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "bundled": true, "requires": { "indexof": "0.0.1" } + }, + "xtend": { + "version": "4.0.1", + "bundled": true } } }, + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, "mongo-object": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/mongo-object/-/mongo-object-0.0.2.tgz", - "integrity": "sha1-Pcq6+RRuGvtjqAlAYUa4VE0olko=", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/mongo-object/-/mongo-object-0.1.3.tgz", + "integrity": "sha512-m3vs+a1JkvRXELJMe2ieMmBe03NUy6bctGjWicRhReYj8brDi0ojKHLKLmXWr/RupNaFP8Q7/x8xG8GpFtp9wg==", "requires": { "lodash.foreach": "^4.5.0", "lodash.isempty": "^4.4.0", @@ -928,6 +1662,92 @@ "lodash.without": "^4.4.0" } }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nocache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", + "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" + }, + "nwmatcher": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", + "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "omggif": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.7.tgz", + "integrity": "sha1-WdLuywJj3oRjWz/riHwMmXPx5J0=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "parse5": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", + "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "promise-polyfill": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.0.tgz", + "integrity": "sha512-OzSf6gcCUQ01byV4BgwyUCswlaQQ6gzXc23aLQWhicvfX9kfsUiUhgt3CCQej8jDnl8/PhGF31JdHX2/MzF3WA==" + }, "properties-reader": { "version": "0.0.15", "resolved": "https://registry.npmjs.org/properties-reader/-/properties-reader-0.0.15.tgz", @@ -943,32 +1763,213 @@ } } }, + "proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=" + }, + "psl": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", + "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "puppeteer": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz", + "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==", + "requires": { + "debug": "^4.1.0", + "extract-zip": "^1.6.6", + "https-proxy-agent": "^2.2.1", + "mime": "^2.0.3", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^2.6.1", + "ws": "^6.1.0" + } + }, + "pure-svg-code": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pure-svg-code/-/pure-svg-code-1.0.6.tgz", + "integrity": "sha512-uxq2BMTdnKW7jDghpLJrczCd9KDOdyghFtEEpfomqMJkUM83/N+W7sFJPJ3AxBf0mJ3xtxAycl6NW8p6F53jEw==" + }, + "qrcode-svg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/qrcode-svg/-/qrcode-svg-1.0.0.tgz", + "integrity": "sha1-Jb3fDAbH5UZiL0tZWjVT76Jke84=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, "regenerator-runtime": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", "integrity": "sha1-flT+W1zNXWYk6mJVw0c74JC4AuE=" }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "rgbcolor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz", + "integrity": "sha1-1lBezbMEplldom+ktDMHMGd1lF0=" + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, "rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "simpl-schema": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/simpl-schema/-/simpl-schema-0.3.2.tgz", - "integrity": "sha1-LHVETpN4UFrFJSGTlN4GPOT28Gg=", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/simpl-schema/-/simpl-schema-1.5.5.tgz", + "integrity": "sha512-LEAKeqXS9VDpH7sVXmsIJsED7fdMj/WAP0roZw0u0IzOgQV7n3x7jcf722cl7WM6U5ANwI4wwv0dujLuwv266A==", "requires": { "clone": "^2.1.1", "extend": "^3.0.1", - "message-box": "^0.1.1", - "mongo-object": "^0.0.2", - "underscore": "^1.8.3" + "lodash.every": "^4.6.0", + "lodash.find": "^4.6.0", + "lodash.findwhere": "^3.1.0", + "lodash.includes": "^4.3.0", + "lodash.isempty": "^4.4.0", + "lodash.isobject": "^3.0.2", + "lodash.omit": "^4.5.0", + "lodash.pick": "^4.4.0", + "lodash.union": "^4.6.0", + "lodash.uniq": "^4.5.0", + "message-box": "^0.2.0", + "mongo-object": "^0.1.3" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stackblur-canvas": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.2.0.tgz", + "integrity": "sha512-5Gf8dtlf8k6NbLzuly2NkGrkS/Ahh+I5VUjO7TnFizdJtgpfpLLEdQlLe9umbcnZlitU84kfYjXE67xlSXfhfQ==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" }, "dependencies": { - "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=" + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, @@ -977,20 +1978,138 @@ "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-6.10.1.tgz", "integrity": "sha1-WyhHd6VG+xFCmRW1dwiEc6ok4P0=" }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, "ticky": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ticky/-/ticky-1.0.1.tgz", "integrity": "sha1-t8+nHnaPHJAAxJe5FRswlHxQ5G0=" }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-2.0.1.tgz", + "integrity": "sha1-U5ayBD8CDub3BNnEXqhRnnJN5lk=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xml-name-validator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", + "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=" + }, + "xmldom": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", + "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" }, "xmlhttprequest": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "requires": { + "fd-slicer": "~1.0.1" + } } } } diff --git a/package.json b/package.json index 911c32b..0273045 100644 --- a/package.json +++ b/package.json @@ -6,16 +6,24 @@ "build": "npm install --product && meteor build --architecture os.linux.x86_64 --server-only ../" }, "dependencies": { - "@babel/runtime": "^7.2.0", + "@babel/runtime": "^7.5.5", "babel-runtime": "^6.18.0", - "csv-parse": "latest", + "csv-parse": "^4.4.6", "d3": "^4.4.2", + "dom-to-image": "latest", "dragula": "^3.7.2", - "jquery": "^3.1.1", + "file-saver": "^2.0.2", + "jquery": "^3.4.1", "jquery-mousewheel": "^3.1.13", + "jsbarcode": "^3.11.0", + "jspdf": "^1.5.3", "malihu-custom-scrollbar-plugin": "latest", - "meteor-node-stubs": "^0.2.4", + "meteor-node-stubs": "^0.4.1", + "nocache": "^2.1.0", "properties-reader": "0.0.15", + "puppeteer": "^1.20.0", + "pure-svg-code": "^1.0.6", + "qrcode-svg": "^1.0.0", "simpl-schema": "latest", "sweetalert2": "^6.3.8" } diff --git a/public/JsBarcode.all.min.js b/public/JsBarcode.all.min.js new file mode 100644 index 0000000..e1db1b5 --- /dev/null +++ b/public/JsBarcode.all.min.js @@ -0,0 +1,3 @@ +/*! JsBarcode v3.6.0 | (c) Johan Lindell | MIT license */ +!function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var n={};return e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,e,n){Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var n=t&&t.__esModule?function(){return t["default"]}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=42)}([function(t,e){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var r=function o(t,e){n(this,o),this.data=t,this.text=e.text||t,this.options=e};e["default"]=r},function(t,e){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(){n(this,t),this.startBin="101",this.endBin="101",this.middleBin="01010",this.Lbinary=["0001101","0011001","0010011","0111101","0100011","0110001","0101111","0111011","0110111","0001011"],this.Gbinary=["0100111","0110011","0011011","0100001","0011101","0111001","0000101","0010001","0001001","0010111"],this.Rbinary=["1110010","1100110","1101100","1000010","1011100","1001110","1010000","1000100","1001000","1110100"]}return t.prototype.encode=function(t,e,n){var r="";n=n||"";for(var o=0;o=200)r=t[0]-105,t.shift(),99===r?n=this.nextC(t,e+1):100===r?n=this.nextB(t,e+1):98===r?(t[0]=t[0]>95?t[0]-96:t[0],n=this.nextA(t,e+1)):n=this.nextA(t,e+1);else{var o=t[0];r=o<32?o+64:o-32,t.shift(),n=this.nextA(t,e+1)}var i=this.getEncoding(r),a=r*e;return{result:i+n.result,checksum:a+n.checksum}},e.prototype.nextB=function(t,e){if(t.length<=0)return{result:"",checksum:0};var n,r;t[0]>=200?(r=t[0]-105,t.shift(),99===r?n=this.nextC(t,e+1):101===r?n=this.nextA(t,e+1):98===r?(t[0]=t[0]<32?t[0]+96:t[0],n=this.nextB(t,e+1)):n=this.nextB(t,e+1)):(r=t[0]-32,t.shift(),n=this.nextB(t,e+1));var o=this.getEncoding(r),i=r*e;return{result:o+n.result,checksum:i+n.checksum}},e.prototype.nextC=function(t,e){if(t.length<=0)return{result:"",checksum:0};var n,r;t[0]>=200?(r=t[0]-105,t.shift(),n=100===r?this.nextB(t,e+1):101===r?this.nextA(t,e+1):this.nextC(t,e+1)):(r=10*(t[0]-48)+t[1]-48,t.shift(),t.shift(),n=this.nextC(t,e+1));var o=this.getEncoding(r),i=r*e;return{result:o+n.result,checksum:i+n.checksum}},e}(s["default"]),f=function(t){function e(){o(this,e);var n=i(this,t.call(this));return n.name="InvalidStartCharacterException",n.message="The encoding does not start with a start character.",n}return a(e,t),e}(Error);e["default"]=c},function(t,e){"use strict";function n(t){for(var e=0,n=0;n0?e.fontSize+e.textMargin:0)+e.marginTop+e.marginBottom}function i(t,e,n){if(n.displayValue&&ee&&(e=t[n].height);return e}function c(t,e,n){var r;r="undefined"==typeof n?document.createElement("canvas").getContext("2d"):n,r.font=e.fontOptions+" "+e.fontSize+"px "+e.font;var o=r.measureText(t).width;return o}Object.defineProperty(e,"__esModule",{value:!0}),e.getTotalWidthOfEncodings=e.calculateEncodingAttributes=e.getBarcodePadding=e.getEncodingHeight=e.getMaximumHeightOfEncodings=void 0;var f=n(3),l=r(f);e.getMaximumHeightOfEncodings=s,e.getEncodingHeight=o,e.getBarcodePadding=i,e.calculateEncodingAttributes=a,e.getTotalWidthOfEncodings=u},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(20),o=n(19),i=n(26),a=n(29),u=n(28),s=n(34),c=n(36),f=n(35),l=n(27);e["default"]={CODE39:r.CODE39,CODE128:o.CODE128,CODE128A:o.CODE128A,CODE128B:o.CODE128B,CODE128C:o.CODE128C,EAN13:i.EAN13,EAN8:i.EAN8,EAN5:i.EAN5,EAN2:i.EAN2,UPC:i.UPC,ITF14:a.ITF14,ITF:u.ITF,MSI:s.MSI,MSI10:s.MSI10,MSI11:s.MSI11,MSI1010:s.MSI1010,MSI1110:s.MSI1110,pharmacode:c.pharmacode,codabar:f.codabar,GenericBarcode:l.GenericBarcode}},function(t,e){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(e){n(this,t),this.api=e}return t.prototype.handleCatch=function(t){if("InvalidInputException"!==t.name)throw t;if(this.api._options.valid===this.api._defaults.valid)throw t.message;this.api._options.valid(!1),this.api.render=function(){}},t.prototype.wrapBarcodeCall=function(t){try{var e=t.apply(void 0,arguments);return this.api._options.valid(!0),e}catch(n){return this.handleCatch(n),this.api}},t}();e["default"]=r},function(t,e){"use strict";function n(t){return t.marginTop=t.marginTop||t.margin,t.marginBottom=t.marginBottom||t.margin,t.marginRight=t.marginRight||t.margin,t.marginLeft=t.marginLeft||t.margin,t}Object.defineProperty(e,"__esModule",{value:!0}),e["default"]=n},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t){if("string"==typeof t)return i(t);if(Array.isArray(t)){for(var e=[],n=0;n=2?String.fromCharCode(210)+f(t):n>r?String.fromCharCode(208)+s(t):String.fromCharCode(209)+c(t),e=e.replace(/[\xCD\xCE]([^])[\xCD\xCE]/,function(t,e){return String.fromCharCode(203)+e})}function s(t){var e=t.match(/^([\x00-\x5F\xC8-\xCF]+?)(([0-9]{2}){2,})([^0-9]|$)/);if(e)return e[1]+String.fromCharCode(204)+f(t.substring(e[1].length));var n=t.match(/^[\x00-\x5F\xC8-\xCF]+/);return n[0].length===t.length?t:n[0]+String.fromCharCode(205)+c(t.substring(n[0].length))}function c(t){var e=t.match(/^([\x20-\x7F\xC8-\xCF]+?)(([0-9]{2}){2,})([^0-9]|$)/);if(e)return e[1]+String.fromCharCode(204)+f(t.substring(e[1].length));var n=t.match(/^[\x20-\x7F\xC8-\xCF]+/);return n[0].length===t.length?t:n[0]+String.fromCharCode(206)+s(t.substring(n[0].length))}function f(t){var e=t.match(/^(\xCF*[0-9]{2}\xCF*)+/)[0],n=e.length;if(n===t.length)return t;t=t.substring(n);var r=t.match(/^[\x00-\x5F\xC8-\xCF]*/)[0].length,o=t.match(/^[\x20-\x7F\xC8-\xCF]*/)[0].length;return r>=o?e+String.fromCharCode(206)+s(t):e+String.fromCharCode(205)+c(t)}Object.defineProperty(e,"__esModule",{value:!0});var l=n(4),p=r(l),h=function(t){function e(n,r){if(o(this,e),n.search(/^[\x00-\x7F\xC8-\xD3]+$/)!==-1)var a=i(this,t.call(this,u(n),r));else var a=i(this,t.call(this,n,r));return i(a)}return a(e,t),e}(p["default"]);e["default"]=h},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(e,"__esModule",{value:!0}),e.CODE128C=e.CODE128B=e.CODE128A=e.CODE128=void 0;var o=n(18),i=r(o),a=n(15),u=r(a),s=n(16),c=r(s),f=n(17),l=r(f);e.CODE128=i["default"],e.CODE128A=u["default"],e.CODE128B=c["default"],e.CODE128C=l["default"]},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function a(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function u(t){return s(f(t))}function s(t){return b[t].toString(2)}function c(t){return y[t]}function f(t){return y.indexOf(t)}function l(t){for(var e=0,n=0;n10*r.width?a.fontSize=10*r.width:a.fontSize=r.fontSize,a.guardHeight=r.height+a.fontSize/2+r.textMargin,a.lastChar=r.lastChar,a}return a(e,t),e.prototype.valid=function(){return this.data.search(/^[0-9]{13}$/)!==-1&&this.data[12]==u(this.data)},e.prototype.encode=function(){return this.options.flat?this.flatEncoding():this.guardedEncoding()},e.prototype.getStructure=function(){return["LLLLLL","LLGLGG","LLGGLG","LLGGGL","LGLLGG","LGGLLG","LGGGLL","LGLGLG","LGLGGL","LGGLGL"]},e.prototype.guardedEncoding=function(){var t=new c["default"],e=[],n=this.getStructure()[this.data[0]],r=this.data.substr(1,6),o=this.data.substr(7,6);return this.options.displayValue&&e.push({data:"000000000000",text:this.text.substr(0,1),options:{textAlign:"left",fontSize:this.fontSize}}),e.push({data:"101",options:{height:this.guardHeight}}),e.push({data:t.encode(r,n),text:this.text.substr(1,6),options:{fontSize:this.fontSize}}),e.push({data:"01010",options:{height:this.guardHeight}}),e.push({data:t.encode(o,"RRRRRR"),text:this.text.substr(7,6),options:{fontSize:this.fontSize}}),e.push({data:"101",options:{height:this.guardHeight}}),this.options.lastChar&&this.options.displayValue&&(e.push({data:"00"}),e.push({data:"00000",text:this.options.lastChar,options:{fontSize:this.fontSize}})),e},e.prototype.flatEncoding=function(){var t=new c["default"],e="",n=this.getStructure()[this.data[0]];return e+="101",e+=t.encode(this.data.substr(1,6),n),e+="01010",e+=t.encode(this.data.substr(7,6),"RRRRRR"),e+="101",{data:e,text:this.text}},e}(l["default"]);e["default"]=p},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function a(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}Object.defineProperty(e,"__esModule",{value:!0});var u=n(1),s=r(u),c=n(0),f=r(c),l=function(t){function e(n,r){o(this,e);var a=i(this,t.call(this,n,r));return a.structure=["LL","LG","GL","GG"],a}return a(e,t),e.prototype.valid=function(){return this.data.search(/^[0-9]{2}$/)!==-1},e.prototype.encode=function(){var t=new s["default"],e=this.structure[parseInt(this.data)%4],n="1011";return n+=t.encode(this.data,e,"01"),{data:n,text:this.text}},e}(f["default"]);e["default"]=l},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function a(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}Object.defineProperty(e,"__esModule",{value:!0});var u=n(1),s=r(u),c=n(0),f=r(c),l=function(t){function e(n,r){o(this,e);var a=i(this,t.call(this,n,r));return a.structure=["GGLLL","GLGLL","GLLGL","GLLLG","LGGLL","LLGGL","LLLGG","LGLGL","LGLLG","LLGLG"],a}return a(e,t),e.prototype.valid=function(){return this.data.search(/^[0-9]{5}$/)!==-1},e.prototype.encode=function(){var t=new s["default"],e=this.checksum(),n="1011";return n+=t.encode(this.data,this.structure[e],"01"),{data:n,text:this.text}},e.prototype.checksum=function(){var t=0;return t+=3*parseInt(this.data[0]),t+=9*parseInt(this.data[1]),t+=3*parseInt(this.data[2]),t+=9*parseInt(this.data[3]),t+=3*parseInt(this.data[4]),t%10},e}(f["default"]);e["default"]=l},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function a(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function u(t){var e,n=0;for(e=0;e<7;e+=2)n+=3*parseInt(t[e]);for(e=1;e<7;e+=2)n+=parseInt(t[e]);return(10-n%10)%10}Object.defineProperty(e,"__esModule",{value:!0});var s=n(1),c=r(s),f=n(0),l=r(f),p=function(t){function e(n,r){return o(this,e),n.search(/^[0-9]{7}$/)!==-1&&(n+=u(n)),i(this,t.call(this,n,r))}return a(e,t),e.prototype.valid=function(){return this.data.search(/^[0-9]{8}$/)!==-1&&this.data[7]==u(this.data)},e.prototype.encode=function(){var t=new c["default"],e="",n=this.data.substr(0,4),r=this.data.substr(4,4);return e+=t.startBin,e+=t.encode(n,"LLLL"),e+=t.middleBin,e+=t.encode(r,"RRRR"),e+=t.endBin,{data:e,text:this.text}},e}(l["default"]);e["default"]=p},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function a(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function u(t){var e,n=0;for(e=1;e<11;e+=2)n+=parseInt(t[e]);for(e=0;e<11;e+=2)n+=3*parseInt(t[e]);return(10-n%10)%10}Object.defineProperty(e,"__esModule",{value:!0});var s=n(1),c=r(s),f=n(0),l=r(f),p=function(t){function e(n,r){o(this,e),n.search(/^[0-9]{11}$/)!==-1&&(n+=u(n));var a=i(this,t.call(this,n,r));return a.displayValue=r.displayValue,r.fontSize>10*r.width?a.fontSize=10*r.width:a.fontSize=r.fontSize,a.guardHeight=r.height+a.fontSize/2+r.textMargin,a}return a(e,t),e.prototype.valid=function(){return this.data.search(/^[0-9]{12}$/)!==-1&&this.data[11]==u(this.data)},e.prototype.encode=function(){return this.options.flat?this.flatEncoding():this.guardedEncoding()},e.prototype.flatEncoding=function(){var t=new c["default"],e="";return e+="101",e+=t.encode(this.data.substr(0,6),"LLLLLL"),e+="01010",e+=t.encode(this.data.substr(6,6),"RRRRRR"),e+="101",{data:e,text:this.text}},e.prototype.guardedEncoding=function(){var t=new c["default"],e=[];return this.displayValue&&e.push({data:"00000000",text:this.text.substr(0,1),options:{textAlign:"left",fontSize:this.fontSize}}),e.push({data:"101"+t.encode(this.data[0],"L"),options:{height:this.guardHeight}}),e.push({data:t.encode(this.data.substr(1,5),"LLLLL"),text:this.text.substr(1,5),options:{fontSize:this.fontSize}}),e.push({data:"01010",options:{height:this.guardHeight}}),e.push({data:t.encode(this.data.substr(6,5),"RRRRR"),text:this.text.substr(6,5),options:{fontSize:this.fontSize}}),e.push({data:t.encode(this.data[11],"R")+"101",options:{height:this.guardHeight}}),this.displayValue&&e.push({data:"00000000",text:this.text.substr(11,1),options:{textAlign:"right",fontSize:this.fontSize}}),e},e}(l["default"]);e["default"]=p},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(e,"__esModule",{value:!0}),e.UPC=e.EAN2=e.EAN5=e.EAN8=e.EAN13=void 0;var o=n(21),i=r(o),a=n(24),u=r(a),s=n(23),c=r(s),f=n(22),l=r(f),p=n(25),h=r(p);e.EAN13=i["default"],e.EAN8=u["default"],e.EAN5=c["default"],e.EAN2=l["default"],e.UPC=h["default"]},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function a(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}Object.defineProperty(e,"__esModule",{value:!0}),e.GenericBarcode=void 0;var u=n(0),s=r(u),c=function(t){function e(n,r){return o(this,e),i(this,t.call(this,n,r))}return a(e,t),e.prototype.encode=function(){return{data:"10101010101010101010101010101010101010101",text:this.text}},e.prototype.valid=function(){return!0},e}(s["default"]);e.GenericBarcode=c},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function a(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}Object.defineProperty(e,"__esModule",{value:!0}),e.ITF=void 0;var u=n(0),s=r(u),c=function(t){function e(n,r){o(this,e);var a=i(this,t.call(this,n,r));return a.binaryRepresentation={0:"00110",1:"10001",2:"01001",3:"11000",4:"00101",5:"10100",6:"01100",7:"00011",8:"10010",9:"01010"},a}return a(e,t),e.prototype.valid=function(){return this.data.search(/^([0-9]{2})+$/)!==-1},e.prototype.encode=function(){for(var t="1010",e=0;e=3&&this.number<=131070},e}(s["default"]);e.pharmacode=c},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t){var e={};for(var n in s["default"])s["default"].hasOwnProperty(n)&&(t.hasAttribute("jsbarcode-"+n.toLowerCase())&&(e[n]=t.getAttribute("jsbarcode-"+n.toLowerCase())),t.hasAttribute("data-"+n.toLowerCase())&&(e[n]=t.getAttribute("data-"+n.toLowerCase())));return e.value=t.getAttribute("jsbarcode-value")||t.getAttribute("data-value"),e=(0,a["default"])(e)}Object.defineProperty(e,"__esModule",{value:!0});var i=n(7),a=r(i),u=n(8),s=r(u);e["default"]=o},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var i=n(3),a=r(i),u=n(9),s=function(){function t(e,n,r){o(this,t),this.canvas=e,this.encodings=n,this.options=r}return t.prototype.render=function(){if(!this.canvas.getContext)throw new Error("The browser does not support canvas.");this.prepareCanvas();for(var t=0;t0?(o=0,n.textAlign="left"):"right"==t.textAlign?(o=e.width-1,n.textAlign="right"):(o=e.width/2,n.textAlign="center"),n.fillText(e.text,o,i)}},t.prototype.moveCanvasDrawing=function(t){var e=this.canvas.getContext("2d");e.translate(t.width,0)},t.prototype.restoreCanvas=function(){var t=this.canvas.getContext("2d");t.restore()},t}();e["default"]=s},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(e,"__esModule",{value:!0});var o=n(38),i=r(o),a=n(41),u=r(a),s=n(40),c=r(s);e["default"]={CanvasRenderer:i["default"],SVGRenderer:u["default"],ObjectRenderer:c["default"]}},function(t,e){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(e,r,o){n(this,t),this.object=e,this.encodings=r,this.options=o}return t.prototype.render=function(){this.object.encodings=this.encodings},t}();e["default"]=r},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e,n){var r=document.createElementNS(l,"g");return r.setAttribute("transform","translate("+t+", "+e+")"),n.appendChild(r),r}function a(t,e){t.setAttribute("style","fill:"+e.lineColor+";")}function u(t,e,n,r,o){var i=document.createElementNS(l,"rect");return i.setAttribute("x",t),i.setAttribute("y",e),i.setAttribute("width",n),i.setAttribute("height",r),o.appendChild(i),i}Object.defineProperty(e,"__esModule",{value:!0});var s=n(3),c=r(s),f=n(9),l="http://www.w3.org/2000/svg",p=function(){function t(e,n,r){o(this,t),this.svg=e,this.encodings=n,this.options=r}return t.prototype.render=function(){var t=this.options.marginLeft;this.prepareSVG();for(var e=0;e0&&(u(a-e.width*i,r,e.width*i,e.height,t),i=0);i>0&&u(a-e.width*(i-1),r,e.width*i,e.height,t)},t.prototype.drawSVGText=function(t,e,n){var r=document.createElementNS(l,"text");if(e.displayValue){var o,i;r.setAttribute("style","font:"+e.fontOptions+" "+e.fontSize+"px "+e.font),i="top"==e.textPosition?e.fontSize-e.textMargin:e.height+e.textMargin+e.fontSize,"left"==e.textAlign||n.barcodePadding>0?(o=0,r.setAttribute("text-anchor","start")):"right"==e.textAlign?(o=n.width-1,r.setAttribute("text-anchor","end")):(o=n.width/2,r.setAttribute("text-anchor","middle")),r.setAttribute("x",o),r.setAttribute("y",i),r.appendChild(document.createTextNode(n.text)),t.appendChild(r)}},t.prototype.setSvgAttributes=function(t,e){var n=this.svg;n.setAttribute("width",t+"px"),n.setAttribute("height",e+"px"),n.setAttribute("x","0px"),n.setAttribute("y","0px"),n.setAttribute("viewBox","0 0 "+t+" "+e),n.setAttribute("xmlns",l),n.setAttribute("version","1.1"),n.style.transform="translate(0,0)"},t}();e["default"]=p},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){E.prototype[e]=E.prototype[e.toUpperCase()]=E.prototype[e.toLowerCase()]=function(n,r){var o=this;return o._errorHandler.wrapBarcodeCall(function(){r.text="undefined"==typeof r.text?void 0:""+r.text;var a=(0,l["default"])(o._options,r);a=(0,_["default"])(a);var u=t[e],s=i(n,u,a);return o._encodings.push(s),o})}}function i(t,e,n){t=""+t;var r=new e(t,n);if(!r.valid())throw new m.InvalidInputException(r.constructor.name,t);var o=r.encode();o=(0,h["default"])(o);for(var i=0;i + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/public/images/3x2 Label Logo2 BW.svg b/public/images/3x2 Label Logo2 BW.svg new file mode 100644 index 0000000..538306e --- /dev/null +++ b/public/images/3x2 Label Logo2 BW.svg @@ -0,0 +1,90 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/public/images/3x2 Label Logo3 BW.svg b/public/images/3x2 Label Logo3 BW.svg new file mode 100644 index 0000000..26db698 --- /dev/null +++ b/public/images/3x2 Label Logo3 BW.svg @@ -0,0 +1,66 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/public/images/Logo_0.8x0.73_300ppi.png b/public/images/Logo_0.8x0.73_300ppi.png new file mode 100644 index 0000000..8706429 Binary files /dev/null and b/public/images/Logo_0.8x0.73_300ppi.png differ diff --git a/public/images/Petit Teton Logo Only.png b/public/images/Petit Teton Logo Only.png new file mode 100644 index 0000000..53f6447 Binary files /dev/null and b/public/images/Petit Teton Logo Only.png differ diff --git a/public/jquery-3.4.1.min.js b/public/jquery-3.4.1.min.js new file mode 100644 index 0000000..a1c07fd --- /dev/null +++ b/public/jquery-3.4.1.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0