From a02d085d0c2badd0486ad4b3af4390bce4a95eae Mon Sep 17 00:00:00 2001 From: Reaby Date: Thu, 17 Jan 2019 01:35:47 +0200 Subject: [PATCH] import --- .dockerignore | 3 + .github/ISSUE_TEMPLATE/bug_report.md | 14 + .github/ISSUE_TEMPLATE/feature_request.md | 9 + .gitignore | 66 + Dockerfile | 19 + README.md | 53 + app.js | 75 + bin/www | 94 + config-default.js | 12 + data/default/backgrounds/bg.jpg | Bin 0 -> 43937 bytes data/default/bundle.json | 18 + data/default/images/.gitkeep | 0 .../03191688-bb93-4376-a3ab-53ed790b2155.png | Bin 0 -> 24563 bytes .../39e5205f-9ace-4597-9873-f9ea5846dff0.png | Bin 0 -> 38863 bytes .../6a298b8c-9246-411f-b364-2d73c7e292d0.png | Bin 0 -> 31791 bytes data/default/slides.json | 26 + .../03191688-bb93-4376-a3ab-53ed790b2155 | 1 + .../39e5205f-9ace-4597-9873-f9ea5846dff0 | 1 + .../6a298b8c-9246-411f-b364-2d73c7e292d0 | 1 + data/meta.json | 30 + data/set1/backgrounds/bg.jpg | Bin 0 -> 43937 bytes data/set1/bundle.json | 18 + data/set1/images/.gitkeep | 0 .../21f0451b-52ca-4da2-bdbb-dce3b8092c3e.png | Bin 0 -> 68017 bytes .../cfc55645-fd10-4f4d-b6f0-3dd34b68192e.png | Bin 0 -> 34282 bytes data/set1/slides.json | 18 + .../21f0451b-52ca-4da2-bdbb-dce3b8092c3e | 1 + .../cfc55645-fd10-4f4d-b6f0-3dd34b68192e | 1 + modules/admin.js | 450 +++++ modules/auth.js | 28 + modules/bundle.js | 152 ++ modules/bundleManager.js | 45 + modules/cli.js | 48 + modules/display.js | 215 ++ modules/websocket.js | 84 + package-lock.json | 1362 +++++++++++++ package.json | 23 + public/js/dashboard.js | 280 +++ public/js/display.js | 382 ++++ public/js/displayLite.js | 255 +++ public/js/edit.js | 435 ++++ public/js/filereader.js | 432 ++++ public/js/flux.js | 1763 +++++++++++++++++ public/js/preview.js | 175 ++ public/js/upload.js | 150 ++ public/stylesheets/style.css | 150 ++ routes/admin.js | 66 + routes/index.js | 100 + templates/bundle/backgrounds/bg.jpg | Bin 0 -> 43937 bytes templates/bundle/bundle.json | 18 + templates/bundle/images/.gitkeep | 0 templates/bundle/render/.gitkeep | 0 templates/bundle/slides.json | 1 + templates/bundle/slides/.gitkeep | 0 tmp/.gitkeep | 0 views/admin/dashboard.twig | 130 ++ views/admin/edit.twig | 109 + views/admin/editBundle.twig | 9 + views/admin/listBundle.twig | 30 + views/ajax/bundleImageList.twig | 15 + views/display.twig | 36 + views/error.twig | 12 + views/index.twig | 62 + views/layout/admin.twig | 21 + views/layout/edit.twig | 24 + views/layout/view.twig | 24 + views/liteDisplay.twig | 35 + views/preview.twig | 34 + 68 files changed, 7615 insertions(+) create mode 100644 .dockerignore create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 app.js create mode 100644 bin/www create mode 100644 config-default.js create mode 100644 data/default/backgrounds/bg.jpg create mode 100644 data/default/bundle.json create mode 100644 data/default/images/.gitkeep create mode 100644 data/default/render/03191688-bb93-4376-a3ab-53ed790b2155.png create mode 100644 data/default/render/39e5205f-9ace-4597-9873-f9ea5846dff0.png create mode 100644 data/default/render/6a298b8c-9246-411f-b364-2d73c7e292d0.png create mode 100644 data/default/slides.json create mode 100644 data/default/slides/03191688-bb93-4376-a3ab-53ed790b2155 create mode 100644 data/default/slides/39e5205f-9ace-4597-9873-f9ea5846dff0 create mode 100644 data/default/slides/6a298b8c-9246-411f-b364-2d73c7e292d0 create mode 100644 data/meta.json create mode 100644 data/set1/backgrounds/bg.jpg create mode 100644 data/set1/bundle.json create mode 100644 data/set1/images/.gitkeep create mode 100644 data/set1/render/21f0451b-52ca-4da2-bdbb-dce3b8092c3e.png create mode 100644 data/set1/render/cfc55645-fd10-4f4d-b6f0-3dd34b68192e.png create mode 100644 data/set1/slides.json create mode 100644 data/set1/slides/21f0451b-52ca-4da2-bdbb-dce3b8092c3e create mode 100644 data/set1/slides/cfc55645-fd10-4f4d-b6f0-3dd34b68192e create mode 100644 modules/admin.js create mode 100644 modules/auth.js create mode 100644 modules/bundle.js create mode 100644 modules/bundleManager.js create mode 100644 modules/cli.js create mode 100644 modules/display.js create mode 100644 modules/websocket.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/js/dashboard.js create mode 100644 public/js/display.js create mode 100644 public/js/displayLite.js create mode 100644 public/js/edit.js create mode 100644 public/js/filereader.js create mode 100644 public/js/flux.js create mode 100644 public/js/preview.js create mode 100644 public/js/upload.js create mode 100644 public/stylesheets/style.css create mode 100644 routes/admin.js create mode 100644 routes/index.js create mode 100644 templates/bundle/backgrounds/bg.jpg create mode 100644 templates/bundle/bundle.json create mode 100644 templates/bundle/images/.gitkeep create mode 100644 templates/bundle/render/.gitkeep create mode 100644 templates/bundle/slides.json create mode 100644 templates/bundle/slides/.gitkeep create mode 100644 tmp/.gitkeep create mode 100644 views/admin/dashboard.twig create mode 100644 views/admin/edit.twig create mode 100644 views/admin/editBundle.twig create mode 100644 views/admin/listBundle.twig create mode 100644 views/ajax/bundleImageList.twig create mode 100644 views/display.twig create mode 100644 views/error.twig create mode 100644 views/index.twig create mode 100644 views/layout/admin.twig create mode 100644 views/layout/edit.twig create mode 100644 views/layout/view.twig create mode 100644 views/liteDisplay.twig create mode 100644 views/preview.twig diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..7a34581 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +node_modules +.idea +.github diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..a88e819 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,14 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + + +**Desktop (please complete the following information):** + - OS: [Windows/Linux/Mac] + - Browser: [Firefox, opera, chrome] + - Infoscreen Version: [1.0] diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..3f5eeb9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,9 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. +(Add any other context or screenshots about the feature request) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f026f2d --- /dev/null +++ b/.gitignore @@ -0,0 +1,66 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# next.js build output +.next + +# own additions +.idea +config.js +tmp/*.png diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..260d991 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +# Nice fresh and new base +FROM node:10-alpine + +# Create directory for our app +WORKDIR /usr/src/infoscreen + +# Install app dependencies +COPY package*.json ./ +RUN npm install + +# Bundle app source +COPY . . +COPY config-default.js config.js + +# Port will be 8000 by default unless run wih ex. -e PORT=8080 +EXPOSE 8000 8001 1935 + +# Let's GO! +CMD [ "npm", "start" ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..cd30711 --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +# Info screen3 + +is useful tool when you need displaying same content to multiple locations or need to remotely control a slide show display. + +Usage is very easy after you have setup the server at local network. The viewer is simply a web page so you need just computer with a browser to setup your displays. + +# Setup +1. npm install +2. copy `config-default.js` to `config.js` +3. check config settings and if you don't need local rtmp media server, set `mediaServer` to `false` +4. (edit `/data/meta.json`, add, remove or rename the displays you need or use the defaults) +5. npm start + +# Default usage +Viewer is located at: http://localhost:8000
+Admin interface is located at: http://localhost:8000/admin
+Defaults to user: `admin`, pass: `admin`
+It's highly encouraged to change the defaults to something else! + +# Lite viewer +Lite viewer is located at each display post fixed with `/lite`
+Example: http://localhost:8000/display/0/lite
+ +> notice: Lite viewer supports only .png images on slides! +> backgrounds can be only jpg. + +# Local stream support for OBS +> Works only when config has `mediaServer` set to `true` + +Go to: `Settings` -> `Stream`
+set following options:
+ +|Setting|Value| +|:---|:---| +|Stream Type:| Custom Streaming Server| +|URL:| `rtmp://localhost/live`| +|Stream key:|`STREAM_NAME`| + +Later it is possible to define other stream names/keys too, but for now only this one is supported. + +# Environment variables +|ENV|default|Usage| +|:---|:---|:---| +|PORT|8000|Server listen port| +|HOST|localhost|Host or ip from where to server is externally accessible| +|ADMIN_USER|admin|Username to access admin interface| +|ADMIN_PASS|admin|Password for the admin interface| + +# Dockerfile +Dockerfile is provided for building a docker container. Docker container accepts the same ENV variables as the standard setup (see them above). + +`docker build -t reaby/infoscreen .`
+`docker run -p 8000:8000 -e HOST=infoscreen.lan -e PORT=8000 -e ADMIN_USER=admin -e ADMIN_PASS=secret --name infoscreen reaby/infoscreen`
diff --git a/app.js b/app.js new file mode 100644 index 0000000..7567064 --- /dev/null +++ b/app.js @@ -0,0 +1,75 @@ +let express = require('express'); +let createError = require('http-errors'); +let path = require('path'); +let cookieParser = require('cookie-parser'); +let logger = require('morgan'); +let lessMiddleware = require('less-middleware'); +const EventEmitter = require('events'); +let config = require("./config.js"); + +class Dispatcher extends EventEmitter { +} + +const eventDispatcher = new Dispatcher(); + +let app = express(); +let server = require('http').Server(app); +let io = require('socket.io')(server); + +if (config.mediaServer) { + const {NodeMediaServer} = require('node-media-server'); + + const nodeServerConfig = { + rtmp: { + port: 1935, + chunk_size: 60000, + gop_cache: true, + ping: 60, + ping_timeout: 30 + }, + http: { + port: (parseInt(config.serverListenPort) + 1), + allow_origin: '*' + } + }; + + let nms = new NodeMediaServer(nodeServerConfig); + nms.run(); +} + +// view engine setup +app.set('port', parseInt(config.serverListenPort)); +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'twig'); +app.use(logger('dev')); +app.use(express.json()); +app.use(express.urlencoded({extended: false})); +app.use(cookieParser()); +app.use(lessMiddleware(path.join(__dirname, 'public'))); + +app.use(express.static(path.join(__dirname, 'public'))); + +let displays = require("./modules/websocket")(server, app, io, eventDispatcher); +let indexRouter = require('./routes/index.js')(displays); +let adminRouter = require('./routes/admin.js')(displays); + +app.use('/', indexRouter); +app.use('/admin', adminRouter); + +// catch 404 and forward to error handler +app.use(function (req, res, next) { + next(createError(404)); +}); + +// error handler +app.use(function (err, req, res, next) { + // set locals, only providing error in development + res.locals.message = err.message; + res.locals.error = req.app.get('env') === 'development' ? err : {}; + + // render the error page + res.status(err.status || 500); + res.render('error'); +}); + +module.exports = {app: app, server: server, io: io, eventDispatcher: eventDispatcher}; diff --git a/bin/www b/bin/www new file mode 100644 index 0000000..7cdfeb9 --- /dev/null +++ b/bin/www @@ -0,0 +1,94 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ +let cli = require('../modules/cli'); +let chalk = require('chalk'); +let debug = require('debug')('screen-info:server'); +let config = require('../config.js'); +let app = require('../app').app; + + +/** + * Get port from environment and store in Express. + */ + +let port = normalizePort(config.serverListenPort || '8000'); +app.set('port', port); + +/** + * Create HTTP server. + */ + +let server = require("../app").server; + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + let port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + let bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + let addr = server.address(); + let bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + + cli.info('Infoscreen is now accessible at ' + chalk.bold.white(config.serverUrl + ":" + config.serverListenPort)); + console.log(chalk.green(">>") + chalk.default("Start complete.") + chalk.green("<<")); +} diff --git a/config-default.js b/config-default.js new file mode 100644 index 0000000..83eabd9 --- /dev/null +++ b/config-default.js @@ -0,0 +1,12 @@ +module.exports = { + "serverListenPort": process.env.PORT || 8000, + "serverHost": process.env.HOST || "localhost", + "serverUrl": "http://" + (process.env.HOST || "localhost"), + "admins": [ + { + "name": process.env.ADMIN_USER || "admin", + "pass": process.env.ADMIN_PASS || "admin" + } + ], + "mediaServer": false +}; diff --git a/data/default/backgrounds/bg.jpg b/data/default/backgrounds/bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f3cc0474a2c3ef042cb0c4a2dfd48326e3cc3867 GIT binary patch literal 43937 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 E0I+v%ssI20 literal 0 HcmV?d00001 diff --git a/data/default/bundle.json b/data/default/bundle.json new file mode 100644 index 0000000..6551bc5 --- /dev/null +++ b/data/default/bundle.json @@ -0,0 +1,18 @@ +{ + "bundleName": "default", + "background": "bg.jpg", + "duration": 20, + "useWebFonts": false, + "styleHeader": { + "fill": "#f90", + "fontSize": 56, + "fontWeight": 900, + "fontFamily": "Arial Black" + }, + "styleText": { + "fill": "#fff", + "fontSize": 32, + "fontWeight": 900, + "fontFamily": "Arial Black" + } +} \ No newline at end of file diff --git a/data/default/images/.gitkeep b/data/default/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/data/default/render/03191688-bb93-4376-a3ab-53ed790b2155.png b/data/default/render/03191688-bb93-4376-a3ab-53ed790b2155.png new file mode 100644 index 0000000000000000000000000000000000000000..54033462061fb93028c1107e5f6fa01339f5c3fe GIT binary patch literal 24563 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 O^~%l5Wfz_Q`2PS6u3@wQ literal 0 HcmV?d00001 diff --git a/data/default/slides.json b/data/default/slides.json new file mode 100644 index 0000000..ad4b588 --- /dev/null +++ b/data/default/slides.json @@ -0,0 +1,26 @@ +[ + { + "file": "39e5205f-9ace-4597-9873-f9ea5846dff0", + "name": "header", + "duration": null, + "enabled": true, + "displayTime": true, + "index": 0 + }, + { + "file": "6a298b8c-9246-411f-b364-2d73c7e292d0", + "name": "header 3", + "duration": null, + "enabled": true, + "displayTime": true, + "index": 1 + }, + { + "file": "03191688-bb93-4376-a3ab-53ed790b2155", + "name": "2 header", + "duration": null, + "enabled": true, + "displayTime": true, + "index": 2 + } +] \ No newline at end of file diff --git a/data/default/slides/03191688-bb93-4376-a3ab-53ed790b2155 b/data/default/slides/03191688-bb93-4376-a3ab-53ed790b2155 new file mode 100644 index 0000000..7fd13ac --- /dev/null +++ b/data/default/slides/03191688-bb93-4376-a3ab-53ed790b2155 @@ -0,0 +1 @@ +{"version":"2.4.0","objects":[{"type":"i-text","version":"2.4.0","left":150,"top":40,"width":206.85,"height":63.28,"fill":"#f90","shadow":{"color":"rgba(0,0,0,0.8)","blur":5,"offsetX":2,"offsetY":2,"affectStroke":false},"text":"2 header","fontSize":56,"fontWeight":900,"fontFamily":"Arial Black","id":"header","styles":{}},{"type":"i-text","version":"2.4.0","left":150,"top":113.28,"width":164.85,"height":63.28,"fill":"#f90","shadow":{"color":"rgba(0,0,0,0.8)","blur":5,"offsetX":2,"offsetY":2,"affectStroke":false},"text":"header","fontSize":56,"fontWeight":900,"fontFamily":"Arial Black","id":"header","styles":{}}]} \ No newline at end of file diff --git a/data/default/slides/39e5205f-9ace-4597-9873-f9ea5846dff0 b/data/default/slides/39e5205f-9ace-4597-9873-f9ea5846dff0 new file mode 100644 index 0000000..15d83e3 --- /dev/null +++ b/data/default/slides/39e5205f-9ace-4597-9873-f9ea5846dff0 @@ -0,0 +1 @@ +{"version":"2.4.0","objects":[{"type":"i-text","version":"2.4.0","left":150,"top":40,"width":225.39,"height":63.28,"fill":"#f90","shadow":{"color":"rgba(0,0,0,0.8)","blur":5,"offsetX":2,"offsetY":2,"affectStroke":false},"text":"header","fontSize":56,"fontWeight":900,"fontFamily":"Audiowide","id":"header","styles":{}},{"type":"i-text","version":"2.4.0","left":250,"top":113.28,"width":225.86,"height":36.16,"fill":"#fff","shadow":{"color":"rgba(0,0,0,0.8)","blur":5,"offsetX":2,"offsetY":2,"affectStroke":false},"text":"paragraph text","fontSize":32,"fontWeight":900,"fontFamily":"Exo 2","id":"normal","styles":{}},{"type":"i-text","version":"2.4.0","left":250,"top":159.44,"width":225.86,"height":36.16,"fill":"#fff","shadow":{"color":"rgba(0,0,0,0.8)","blur":5,"offsetX":2,"offsetY":2,"affectStroke":false},"text":"paragraph text","fontSize":32,"fontWeight":900,"fontFamily":"Exo 2","id":"normal","styles":{}}]} \ No newline at end of file diff --git a/data/default/slides/6a298b8c-9246-411f-b364-2d73c7e292d0 b/data/default/slides/6a298b8c-9246-411f-b364-2d73c7e292d0 new file mode 100644 index 0000000..b13d40b --- /dev/null +++ b/data/default/slides/6a298b8c-9246-411f-b364-2d73c7e292d0 @@ -0,0 +1 @@ +{"version":"2.4.0","objects":[{"type":"i-text","version":"2.4.0","left":151,"top":40,"width":267.64,"height":63.28,"fill":"#f90","shadow":{"color":"rgba(0,0,0,0.8)","blur":5,"offsetX":2,"offsetY":2,"affectStroke":false},"text":"header 3","fontSize":56,"fontWeight":900,"fontFamily":"Arial Black","id":"header","styles":{}}]} \ No newline at end of file diff --git a/data/meta.json b/data/meta.json new file mode 100644 index 0000000..160cebb --- /dev/null +++ b/data/meta.json @@ -0,0 +1,30 @@ +{ + "bundleNames": [ + { + "dir": "default", + "name": "default" + } + ], + "displays": [ + { + "name": "main screen", + "bundle": "default" + }, + { + "name": "2nd screen", + "bundle": "set1" + }, + { + "name": "3rd screen", + "bundle": "default" + }, + { + "name": "4th screen", + "bundle": "set1" + }, + { + "name": "5th screen", + "bundle": "default" + } + ] +} \ No newline at end of file diff --git a/data/set1/backgrounds/bg.jpg b/data/set1/backgrounds/bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f3cc0474a2c3ef042cb0c4a2dfd48326e3cc3867 GIT binary patch literal 43937 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 E0I+v%ssI20 literal 0 HcmV?d00001 diff --git a/data/set1/bundle.json b/data/set1/bundle.json new file mode 100644 index 0000000..417cc07 --- /dev/null +++ b/data/set1/bundle.json @@ -0,0 +1,18 @@ +{ + "bundleName": "set1", + "background": "bg.jpg", + "useWebFonts": false, + "duration": 20, + "styleHeader": { + "fill": "#f90", + "fontSize": 56, + "fontWeight": 900, + "fontFamily": "Arial Black" + }, + "styleText": { + "fill": "#fff", + "fontFamily": "Arial Black", + "fontSize": 42, + "fontWeight": 900 + } +} \ No newline at end of file diff --git a/data/set1/images/.gitkeep b/data/set1/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/data/set1/render/21f0451b-52ca-4da2-bdbb-dce3b8092c3e.png b/data/set1/render/21f0451b-52ca-4da2-bdbb-dce3b8092c3e.png new file mode 100644 index 0000000000000000000000000000000000000000..cd4105486df008ba615e15bae518364af44a63c9 GIT binary patch literal 68017 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 literal 0 HcmV?d00001 diff --git a/data/set1/slides.json b/data/set1/slides.json new file mode 100644 index 0000000..cdf2bd1 --- /dev/null +++ b/data/set1/slides.json @@ -0,0 +1,18 @@ +[ + { + "file": "cfc55645-fd10-4f4d-b6f0-3dd34b68192e", + "name": "bundle2", + "duration": null, + "enabled": true, + "displayTime": true, + "index": 0 + }, + { + "file": "21f0451b-52ca-4da2-bdbb-dce3b8092c3e", + "name": "dia 3", + "duration": null, + "enabled": true, + "displayTime": true, + "index": 1 + } +] \ No newline at end of file diff --git a/data/set1/slides/21f0451b-52ca-4da2-bdbb-dce3b8092c3e b/data/set1/slides/21f0451b-52ca-4da2-bdbb-dce3b8092c3e new file mode 100644 index 0000000..67bb21f --- /dev/null +++ b/data/set1/slides/21f0451b-52ca-4da2-bdbb-dce3b8092c3e @@ -0,0 +1 @@ +{"version":"2.4.0","objects":[{"type":"i-text","version":"2.4.0","left":150,"top":40,"width":149.38,"height":63.28,"fill":"#f90","shadow":{"color":"rgba(0,0,0,0.8)","blur":5,"offsetX":2,"offsetY":2,"affectStroke":false},"text":"dia 3","fontSize":56,"fontWeight":900,"fontFamily":"Arial Black","id":"header","styles":{}},{"type":"i-text","version":"2.4.0","left":250,"top":113.28,"width":342.89,"height":47.46,"fill":"#fff","shadow":{"color":"rgba(0,0,0,0.8)","blur":5,"offsetX":2,"offsetY":2,"affectStroke":false},"text":"paragraph text","fontSize":42,"fontWeight":900,"fontFamily":"Arial Black","id":"normal","styles":{}},{"type":"i-text","version":"2.4.0","left":250,"top":170.74,"width":342.89,"height":47.46,"fill":"#fff","shadow":{"color":"rgba(0,0,0,0.8)","blur":5,"offsetX":2,"offsetY":2,"affectStroke":false},"text":"paragraph text","fontSize":42,"fontWeight":900,"fontFamily":"Arial Black","id":"normal","styles":{}}]} \ No newline at end of file diff --git a/data/set1/slides/cfc55645-fd10-4f4d-b6f0-3dd34b68192e b/data/set1/slides/cfc55645-fd10-4f4d-b6f0-3dd34b68192e new file mode 100644 index 0000000..31ed41c --- /dev/null +++ b/data/set1/slides/cfc55645-fd10-4f4d-b6f0-3dd34b68192e @@ -0,0 +1 @@ +{"version":"2.4.0","objects":[{"type":"i-text","version":"2.4.0","left":150,"top":36,"width":242.76,"height":63.28,"fill":"#f90","shadow":{"color":"rgba(0,0,0,0.8)","blur":5,"offsetX":2,"offsetY":2,"affectStroke":false},"text":"bundle2","fontSize":56,"fontWeight":900,"fontFamily":"Arial Black","styles":{}},{"type":"i-text","version":"2.4.0","left":250,"top":113.28,"width":342.89,"height":47.46,"fill":"#fff","shadow":{"color":"rgba(0,0,0,0.8)","blur":5,"offsetX":2,"offsetY":2,"affectStroke":false},"text":"paragraph text","fontSize":42,"fontWeight":900,"fontFamily":"Arial Black","styles":{}}]} \ No newline at end of file diff --git a/modules/admin.js b/modules/admin.js new file mode 100644 index 0000000..e9e8ca1 --- /dev/null +++ b/modules/admin.js @@ -0,0 +1,450 @@ +let fs = require("fs"); +let config = require("../config.js"); +let cli = require('./cli.js'); + +/** + * @module infoscreen3/admin + * @class + */ +class admin { + + /** + * + * @param sharedIO + * @param dispatcher + * @param screenViews + * @param bundleManager + */ + constructor(sharedIO, dispatcher, screenViews, bundleManager) { + cli.info("Starting admin socket interface"); + + /** + * @typedef {object} previewInstance + * @property {string} adminId is string from admin socket.Id + * @property {object} preview, pure previews socket + * + * @type {previewInstance[]} + */ + let previewInstances = []; + let io = sharedIO.of("/admin"); + this.io = io; + this.dispatcher = dispatcher; + + this.bundleManager = bundleManager; + let self = this; + // helper callback for global announce + dispatcher.on("announce", function (obj) { + if (obj.screens == null) { + io.emit(obj.event, obj.data); + } else { + for (let screen of obj.screens) { + if (screen === "admin") { + io.emit(obj.event, obj.data); + } + } + } + }); + + /** helper function to call announce easier **/ + function announce(screens, event, data) { + self.dispatcher.emit("announce", {screens: screens, event: event, data: data}); + } + + io.on("connection", function (socket) { + cli.success("WS " + socket.conn.remoteAddress + " connect with id:" + socket.id); + + + socket.on('error', function (error) { + cli.error(error, "WS error on socket id:" + socket.id); + for (let i in previewInstances) { + if (previewInstances[i].adminId === socket.id || previewInstances[i].preview === socket) { + delete previewInstances[i]; + break; + } + } + }); + + socket.on('disconnect', function (reason) { + for (let i in previewInstances) { + if (previewInstances[i].adminId === socket.id || previewInstances[i].preview === socket) { + delete previewInstances[i]; + break; + } + } + cli.success("WS " + reason + " " + socket.conn.remoteAddress + " socket id:" + socket.id); + }); + + socket.on('sync.preview', function (socketId) { + for (let i in previewInstances) { + if (previewInstances[i].adminId === decodeURIComponent(socketId)) { + previewInstances[i].preview = socket; + } + } + }); + + socket.on('admin.reload', function (data) { + announce([data.displayId], "callback.reload", {}); + }); + + // toggle time + socket.on('controls.time.toggle', function (data) { + let view = getView(data.displayId); + view.serverOptions.timeDisplay = !view.serverOptions.timeDisplay; + view.io.emit("callback.time", view.serverOptions.timeDisplay); + updateDashboard(io, data.displayId); + }); + + socket.on('controls.previous', function (data) { + let view = getView(data.displayId); + view.serverOptions.loopIndex -= 2; + view.mainLoop(); + }); + + socket.on('controls.play', function (data) { + getServerOptions(data.displayId).loop = true; + getView(data.displayId).mainLoop(); + updateDashboard(io, data.displayId); + }); + + socket.on('controls.startStream', function (data) { + let view = getView(data.displayId); + let serverOptions = getServerOptions(data.displayId); + + if (serverOptions.isStreaming === false) { + serverOptions.loop = false; + serverOptions.streamSource = "http://" + config.serverHost + ":" + (config.serverListenPort + 1) + "/live/" + data.streamName + ".flv"; + serverOptions.isStreaming = true; + cli.success("start stream"); + } else { + + serverOptions.loop = true; + serverOptions.isStreaming = false; + serverOptions.streamSource = ""; + cli.success("stop stream"); + } + view.io.emit("callbackLoad", view.getSlideData()); + updateDashboard(io, data.displayId); + }); + + + socket.on('controls.pause', function (data) { + let view = getView(data.displayId); + view.clearTimers(); + getServerOptions(data.displayId).loop = false; + updateDashboard(io, data.displayId); + }); + + socket.on('controls.next', function (data) { + getView(data.displayId).mainLoop(); + }); + + socket.on('controls.blackout', function (data) { + let view = getView(data.displayId); + view.serverOptions.blackout = view.serverOptions.blackout === false; + + view.io.emit("callback.blackout", {serverOptions: view.serverOptions}); + updateDashboard(io, data.displayId); + }); + + socket.on("controls.preview", function (data) { + let bundle = self.bundleManager.getBundle(data.bundle); + let json = "{}"; + if (data.fileName) { + json = bundle.getSlideJsonFile(data.fileName); + } + + try { + getPreview(socket).preview.emit("callback.preview", + { + bundleData: bundle.getBundleData(), + json: json, + displayId: data.displayId + } + ); + } catch (err) { + cli.error("preview instance not found"); + } + + }); + + socket.on("controls.skipTo", function (data) { + let bundleSettings = getView(data.displayId).getBundle(); + let slides = bundleSettings.enabledSlides; + + let idx = slides.indexOf(data.fileName); + if (idx >= 0) { + getServerOptions(data.displayId).loopIndex = idx; + } + getView(data.displayId).mainLoop(); + }); + + socket.on('controls.toggle', function (data) { + let fileName = data.fileName; + let bundleSettings = getView(data.displayId).getBundle(); + let idx = bundleSettings.disabledSlides.indexOf(fileName); + + if (idx > -1) { + bundleSettings.setSlideStatus(fileName, true); + } else { + bundleSettings.setSlideStatus(fileName, false); + } + + updateDashboard(socket, data.displayId); + }); + + // override + socket.on('admin.override', function (data) { + let view = getView(parseInt(data.displayId)); + view.overrideSlide(data.json, data.png); + view.displayCurrentSlide(); + }); + + socket.on('admin.setBundle', function (data) { + let view = getView(data.displayId); + view.changeBundle(data.bundle); + view.displayCurrentSlide(); + updateDashboard(io, data.displayId); + }); + + socket.on('admin.dashboard.sync', function (data) { + syncDashboard(socket, 0); + updateDashboard(socket, data.displayId); + }); + + socket.on('admin.setDisplay', function (data) { + syncDashboard(socket, data.display); + updateDashboard(socket, data.display); + }); + + socket.on('admin.listSlides', function (data) { + updateDashboard(socket, data.displayId); + }); + + socket.on('admin.listBundles', function (data) { + updateDashboard(socket, data.displayId); + }); + + + socket.on('admin.reorderSlides', function (data) { + let view = getView(data.displayId); + let serverOptions = view.serverOptions; + let bundle = view.getBundle(); + + let i = 0; + console.log(data.sortedIDs); + + for (let uuid of data.sortedIDs) { + bundle.setIndex(uuid, i); + i += 1; + } + + for (let slide of bundle.allSlides) { + // calculate new index for next slide; + if (slide.file === serverOptions.currentFile) { + serverOptions.loopIndex = slide.index + 1; + } + } + + bundle.save(); + updateDashboard(io, data.displayId); + }); + + /** remove slide **/ + socket.on('admin.removeSlide', function (data) { + let view = getView(data.displayId); + let bundle = view.getBundle(); + bundle.removeUuid(data.uuid); + updateSlides(io, bundle.getBundleData().bundleName, bundle); + }); + + /** edit **/ + socket.on('admin.editSlide', function (data) { + let bundle = self.bundleManager.getBundle(data.bundleName); + let bundleData = bundle.getBundleData(); + let json = "{}"; + if (data.fileName) { + json = bundle.getSlideJsonFile(data.fileName); + } + socket.emit("callbackEdit", {bundleData: bundleData, json: json}); + }); + + /** rename **/ + socket.on('admin.renameSlide', function (data) { + getView(data.displayId).getBundle().setName(data.uuid, data.name); + updateDashboard(io, data.displayId); + }); + /** change transition **/ + socket.on('admin.setTransition', function (data) { + getServerOptions(data.displayId).transition = data.transition; + updateDashboard(io, data.displayId); + }); + + socket.on('edit.save', function (data) { + + let filename = data.fileName.replace(".json", ""); + if (filename === "") { + filename = uuidv4(); + } + + try { + fs.writeFileSync("./data/" + data.bundleName + "/render/" + filename + ".png", data.png.replace(/^data:image\/png;base64,/, ""), "base64"); + fs.writeFileSync("./data/" + data.bundleName + "/slides/" + filename, JSON.stringify(data.json)); + + let bundle = self.bundleManager.getBundle(data.bundleName); + + let template = { + file: filename, + name: data.name, + duration: null, + enabled: true, + displayTime: true, + index: bundle.allSlides.length, + }; + + let obj = bundle.findSlideByUuid(filename); + if (Object.keys(obj).length === 0 && obj.constructor === Object) { + bundle.allSlides.push(template); + } + + bundle.save(); + + cli.success("save new slide data"); + socket.emit("callback.save", {}); + announce([parseInt(data.displayId)], "callback.reloadImage", { + bundle: data.bundleName, + file: filename + }); + updateSlides(io, data.bundleName, bundle); + + } catch (err) { + cli.error(err, "save new slide date"); + socket.emit("callback.save", {error: err}); + } + }); + + socket.on('edit.uploadImage', function (data) { + + let filename = data.name.replace(/\.[^/.]+$/, ""); + let ext = "." + data.type.replace("image/", ""); + if (filename === "") { + filename = uuidv4(); + } + try { + let replace = "^data:" + data.type + ";base64,"; + let re = new RegExp(replace, "g"); + + fs.writeFileSync("./data/" + data.bundleName + "/images/" + filename + ext, data.imageData.replace(re, ""), "base64"); + cli.success("upload of " + filename + ext); + socket.emit("callback.edit.updateFileList", {}); + } catch (err) { + cli.error("upload of " + filename + ext); + cli.error(err); + socket.emit("callback.edit.updateFileList", {error: err}); + } + }); + + socket.on('edit.deleteImage', function (data) { + try { + fs.unlinkSync("./data/" + data.bundleName + "/images/" + data.name); + cli.success("delete " + data.name); + socket.emit("callback.edit.updateFileList", {}); + } catch (err) { + cli.error(err, "delete image"); + socket.emit("callback.edit.updateFileList", {error: err}); + } + }); + + }); // io + + + /** helper functions */ + + /** + * @param {object} socket + * @param {number} displayId + */ + function updateDashboard(socket, displayId) { + let view = getView(displayId); + let serverOptions = view.serverOptions; + let bundleSettings = view.getBundle(); + + socket.emit("callback.dashboard.update", { + bundleSettings: bundleSettings, + allSlides: bundleSettings.allSlides, + serverOptions: serverOptions, + displayId: displayId + }); + } + + function updateSlides(socket, bundlename, bundle) { + socket.emit("callback.dashboard.updateSlides", { + bundleName: bundlename, + bundleSettings: bundle + }); + } + + function syncDashboard(socket, displayId) { + + previewInstances.push({adminId: socket.id, preview: {}, currentView: {}}); + let serverOptions = getView(displayId).serverOptions; + let bundleDirs = getDirectories("./data"); + let meta = JSON.parse(fs.readFileSync("./data/meta.json").toString()); + + socket.emit("callback.dashboard.sync", { + displayId: displayId, + bundleDirs: bundleDirs, + serverOptions: serverOptions, + displays: meta.displays + }); + } + + function getDirectories(path) { + return fs.readdirSync(path).filter(function (file) { + return fs.statSync(path + '/' + file).isDirectory(); + }); + } + + function getPreview(socket) { + for (let i in previewInstances) { + if (previewInstances[i].adminId === socket.id) { + return previewInstances[i]; + } + } + + throw "error"; + } + + /** Generate an uuid + * @url https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript#2117523 **/ + function uuidv4() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + let r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + } + + /** + * @param {number} displayId + */ + function getServerOptions(displayId) { + return getView(displayId).serverOptions; + + } + + /** + * + * @param displayId + */ + function getView(displayId) { + try { + return screenViews[parseInt(displayId)]; + } catch (err) { + throw "display not found"; + } + } + } + +} // admin + + +module.exports = admin; \ No newline at end of file diff --git a/modules/auth.js b/modules/auth.js new file mode 100644 index 0000000..be973a3 --- /dev/null +++ b/modules/auth.js @@ -0,0 +1,28 @@ + +let basicAuth = require("basic-auth"); +let config = require("../config.js"); + +module.exports = function (req, res, next) { + function unauthorized(res) { + res.set("WWW-Authenticate", "Basic realm=Authorization Required"); + return res.sendStatus(401); + } + + let user = basicAuth(req); + + if (!user || !user.name || !user.pass) { + return unauthorized(res); + } + + for (let i in config.admins) { + let admin = config.admins[i]; + if (user.name === admin.name && user.pass === admin.pass) { + return next('route'); + } + } + + return unauthorized(res); +}; + + + diff --git a/modules/bundle.js b/modules/bundle.js new file mode 100644 index 0000000..46f2ba8 --- /dev/null +++ b/modules/bundle.js @@ -0,0 +1,152 @@ +let cli = require("./cli.js"); +let fs = require("fs"); + +class bundleClass { + + constructor(name, data, slides) { + this.name = name; + this.bundleData = data; + this.allSlides = slides; + this.enabledSlides = []; + this.disabledSlides = []; + this.sync(); + } + + getBundleData() { + return this.bundleData; + } + + getSlideJsonFile(fileName) { + try { + return fs.readFileSync("./data/" + this.name + "/slides/" + fileName).toString(); + } catch (err) { + return "{}"; + } + } + + findSlideByUuid(uuid) { + for (let slide of this.allSlides) { + if (slide.file === uuid) { + return slide; + } + } + return {}; + } + + removeUuid(uuid) { + // delete files from fs + let newList = []; + let x = 0; + for (let slide of this.allSlides) { + if (slide.file !== uuid) { + let ent = slide; + ent.index = x; + newList.push(ent); + x++; + } + if (slide.file === uuid) { + let path = "./data/" + this.name; + + try { + if (fs.existsSync(path + "/render/" + uuid + ".png")) { + fs.unlinkSync(path + "/render/" + uuid + ".png"); + cli.success("removing file:" + path + "/render/" + uuid + ".png"); + } + if (fs.existsSync(path + "/slides/" + uuid)) { + fs.unlinkSync(path + "/slides/" + uuid); + cli.success("removing file:" + path + "/slides/" + uuid); + } + } catch (err) { + cli.error("error while deleting file:" + uuid, err); + } + } + } + this.allSlides = newList; + this.save(); + } + + setSlideStatus(uuid, status) { + for (let i in this.allSlides) { + if (this.allSlides[i].file === uuid) { + this.allSlides[i].enabled = status; + this.sync(); + break; + } + } + } + + setIndex(uuid, index) { + for (let i in this.allSlides) { + if (this.allSlides[i].file === uuid) { + this.allSlides[i].index = index; + this.sync(); + return; + } + } + } + + setName(uuid, name) { + for (let i in this.allSlides) { + if (this.allSlides[i].file === uuid) { + this.allSlides[i].name = name; + this.save(); + return; + } + } + } + + sync() { + this.enabledSlides = []; + this.disabledSlides = []; + this.allSlides.sort(sortByProperty('index')); + for (let slide of this.allSlides) { + if (slide.enabled) { + this.enabledSlides.push(slide.file.replace(".json", "")); + } else { + this.disabledSlides.push(slide.file.replace(".json", "")); + } + } + } + + toJson() { + this.sync(); + return JSON.stringify(this.allSlides, null, "\t"); + } + + save() { + try { + fs.writeFileSync("./data/" + this.name + "/slides.json", this.toJson()); + } catch (e) { + cli.error("error while saving file:", e); + } + } + +} + +/** + * helper function to clone object + * @returns {*} + */ +function clone(object) { + return JSON.parse(JSON.stringify(object)); +} + + +/** + * helper function to sort object by property. + * @param property + * @returns {function(*, *): number} + */ +function sortByProperty(property) { + let sortOrder = 1; + if (property[0] === "-") { + sortOrder = -1; + property = property.substr(1); + } + return function (a, b) { + let result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0; + return result * sortOrder; + } +} + +module.exports = bundleClass; \ No newline at end of file diff --git a/modules/bundleManager.js b/modules/bundleManager.js new file mode 100644 index 0000000..66fd216 --- /dev/null +++ b/modules/bundleManager.js @@ -0,0 +1,45 @@ +"use strict"; + +const bundle = require('./bundle.js'); +let fs = require("fs"); + +/** + * @module infoscreen3/bundleManager + */ +class bundleManager { + + constructor() { + this.bundles = {}; + let dirs = getDirectories("./data"); + + for (let name of dirs) { + let data = getJson("./data/" + name + "/bundle.json"); + let slides = getJson("./data/" + name + "/slides.json"); + + this.bundles[name] = new bundle(name, data, slides); + } + } + + /** + * + * @param {string} name + * @returns {bundle} + */ + getBundle(name) { + return this.bundles[name]; + } + +} + +function getDirectories(path) { + return fs.readdirSync(path).filter(function (file) { + return fs.statSync(path + '/' + file).isDirectory(); + }); +} + + +function getJson(file) { + return JSON.parse(fs.readFileSync(file).toString()); +} + +module.exports = bundleManager; \ No newline at end of file diff --git a/modules/cli.js b/modules/cli.js new file mode 100644 index 0000000..66cd475 --- /dev/null +++ b/modules/cli.js @@ -0,0 +1,48 @@ +let chalk = require('chalk'); + +module.exports = { + error: function (error, title) { + if (title == null) { + title = ""; + } + this.log(chalk.bold.red("[Error]" + title) + " " + error); + }, + + info: function (string) { + this.log(chalk.cyan("[Info] ") + string); + }, + + success: function (string) { + this.log(string + chalk.green(" [Success]")); + }, + + log: function (string) { + + console.log(getDateTime() + " " + string); + } +}; + +function getDateTime() { + + var date = new Date(); + + var hour = date.getHours(); + hour = (hour < 10 ? "0" : "") + hour; + + var min = date.getMinutes(); + min = (min < 10 ? "0" : "") + min; + + var sec = date.getSeconds(); + sec = (sec < 10 ? "0" : "") + sec; + + var year = date.getFullYear(); + + var month = date.getMonth() + 1; + month = (month < 10 ? "0" : "") + month; + + var day = date.getDate(); + day = (day < 10 ? "0" : "") + day; + + return year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec; + +} \ No newline at end of file diff --git a/modules/display.js b/modules/display.js new file mode 100644 index 0000000..1d784e9 --- /dev/null +++ b/modules/display.js @@ -0,0 +1,215 @@ +let fs = require("fs"); +let path = require("path"); +let cli = require("./cli.js"); +let bundleManager = require('./bundleManager.js'); + +/** + * handles one instance of display + * @module infoscreen3/display + */ +class display { + + /** + * @param {object} sharedIO - socketIO + * @param {object} dispatcher - dispatcher + * @param {object} meta - reads from ./data/meta.json --> as display[displayId] + * @param {number} displayId - this display instances id + * @param {object} bundleManager + */ + constructor(sharedIO, dispatcher, meta, displayId, bundleManager) { + cli.info("Starting display" + displayId + ": " + meta.name + "..."); + + /** @property {Array} timeoutId - holds setTimeout id's for mainLoop */ + this.timeoutId = []; + this.bundleManager = bundleManager; + let self = this; + + /** + * @property {number} displayId - this display id + * @property {number} currentId - index number @see getBundle() + * @property {string} currentBundle - current bundle directory name at ./data/ + * @property {string} currentFile - current filename at bundle + * @property {string} currentJSON - current slides json data + * @property {boolean} loop - runs main loop + * @property {number} loopIndex - index number used to calculate slide at enabledSlides @see getBundle() + * @property {boolean} blackout - should the blackout be enabled + * @property {boolean} isStreaming - is media server stream enabled at client + * @property {string} streamSource - URL for FLV media stream + * @property {string} transition values supported: bars,blinds,blinds3d,zip,blocks,blocks2,concentric,warp,cube,tiles3d,tiles3dprev,slide,swipe,dissolve + */ + this.serverOptions = { + displayId: displayId, + currentId: -1, + currentBundle: "default", + currentFile: null, + slideDuration: 10, + loop: true, + loopIndex: 0, + blackout: false, + isStreaming: false, + streamSource: "", + isAnnounce: false, + transition: "tiles3d", + displayTime: true + }; + + let io = sharedIO.of("/display-" + displayId.toString()); + this.io = io; + this.name = meta.name; + this.dispatcher = dispatcher; + this.id = displayId; + + /** + * helper callback for global announce + /** + * @listens event:announce + * + */ + dispatcher.on("announce", function (obj) { + // if global announce, ie screens is null + if (obj.screens == null) { + io.emit(obj.event, obj.data); + } else { + // screens is array + for (let screen of obj.screens) { + // so if match, emit data from here + if (screen === displayId) { + io.emit(obj.event, obj.data); + } + } + } + }); + + io.on("connection", + /** + * @param socket + */ + function (socket) { + console.log("WS display" + displayId + ":" + socket.conn.remoteAddress + " connect"); + + socket.on('error', function (error) { + console.log("WS display" + displayId + ": error"); + console.log(error); + }); + + socket.on('disconnect', function (reason) { + console.log("WS display" + displayId + ": disconnect " + reason + " " + socket.conn.remoteAddress); + }); + + socket.on('sync', function () { + cli.info("request sync " + self.name); + socket.emit("callbackLoad", self.getSlideData()); + }); + + }); // io + + this.init(meta); + cli.info("done."); + } // display + + + init(meta) { + this.changeBundle(meta.bundle); + this.mainLoop(); + } + + /** + * change displayed bundle + * @param {string} bundleName + */ + changeBundle(bundleName) { + let bundle = this.getBundle(); + this.serverOptions.currentBundle = bundleName; + this.serverOptions.loopIndex = 0; + this.serverOptions.currentFile = bundle.enabledSlides[0] || ""; + this.serverOptions.slideDuration = bundle.findSlideByUuid(bundle.enabledSlides[0]).duration || bundle.getBundleData().duration; + this.serverOptions.currentId = bundle.enabledSlides.indexOf(this.serverOptions.currentFile); + } + + getSlideData() { + let bundle = this.getBundle(); + return {bundleData: bundle.getBundleData(), slides: bundle.allSlides, serverOptions: this.serverOptions}; + } + + /** + * clears timers + */ + clearTimers() { + for (let i in this.timeoutId) { + clearTimeout(this.timeoutId[i]); + delete this.timeoutId[i]; + } + } + + /** + * @returns {bundle} + */ + getBundle() { + return this.bundleManager.getBundle(this.serverOptions.currentBundle); + } + + + /** + * emits custom event for screens + * @fires event:announce + * @param screens list of screenId's use "admin" for admin interface + * @param event string event to io.emit on the selected screens + * @param data object object to send + */ + announce(screens, event, data) { + /** + * @event event:announce + */ + this.dispatcher.emit("announce", {screens: screens, event: event, data: data}); + } + + /** + * display main loop, which updates the display periodically + */ + mainLoop() { + if (this.serverOptions.loop) { + this.clearTimers(); + } + this.serverOptions.isAnnounce = false; + + let bundle = this.getBundle(); + let slides = bundle.enabledSlides; + + if (slides.length >= 0) { + let lIndex = this.serverOptions.loopIndex; + if (lIndex < 0) lIndex = slides.length - Math.abs(lIndex); // negative values should shift from end + let idx = (lIndex % slides.length); // make sure id is normalized to slide count + this.serverOptions.loopIndex = idx; + this.serverOptions.currentFile = slides[idx]; + this.serverOptions.slideDuration = bundle.findSlideByUuid(slides[idx]).duration || bundle.getBundleData().duration; + this.serverOptions.currentId = bundle.enabledSlides.indexOf(this.serverOptions.currentFile); + } + + this.displayCurrentSlide(); + + + this.serverOptions.loopIndex += 1; + + if (this.serverOptions.loop) { + let that = this; + this.timeoutId.push( + setTimeout(function () { + that.mainLoop(); + }, this.serverOptions.slideDuration * 1000)); + } + } + + overrideSlide(json, pngData) { + this.clearTimers(); + this.serverOptions.loop = false; + this.serverOptions.isAnnounce = true; + // save temporarily png data... + fs.writeFileSync("./tmp/display_" + this.serverOptions.displayId + ".png", pngData.replace(/^data:image\/png;base64,/, ""), "base64"); + } + + displayCurrentSlide() { + this.announce([this.serverOptions.displayId, "admin"], "callback.update", this.getSlideData()); + } +} + +module.exports = display; \ No newline at end of file diff --git a/modules/websocket.js b/modules/websocket.js new file mode 100644 index 0000000..009375b --- /dev/null +++ b/modules/websocket.js @@ -0,0 +1,84 @@ +let meta = require("../data/meta.json"); +let display = require("./display.js"); +let admin = require("./admin.js"); +let cli = require('./cli.js'); +let bundleManager = require('./bundleManager.js'); +let chalk = require('chalk'); +let fs = require('fs'); + +/** + * + * @type {module:infoscreen3/display[]} + */ +let screenView = []; + +/** + * @exports infoscreen3/websocket + */ +module.exports = function (server, app, io, dispatcher) { + console.log(chalk.green(">> ") + "InfoScreen3" + chalk.green("<<")); + cli.log("Checking for write permissions..."); + + try { + fs.accessSync("./data", fs.W_OK); + cli.success("data directory (./data) is writable"); + } catch (err) { + cli.error("data directory (./data) is not writable", err); + process.exit(1); + } + + try { + fs.accessSync("./tmp", fs.W_OK); + cli.success("temp directory (./tmp) is writable "); + let tempFiles = fs.readdirSync("./tmp/", { + dotfiles: false + }); + cli.info("removing temp-files..."); + for (let file of tempFiles) { + if (file !== ".gitkeep") { + fs.unlinkSync("./tmp/" + file); + } + } + cli.info("done."); + + } catch (err) { + cli.error("temp directory (./tmp) is not writable", err); + process.exit(1); + } + + cli.info("Starting bundle manager..."); + + let bundler = new bundleManager(); + + cli.info("Starting websocket backends..."); + + let screenId = 0; + for (let metadata of meta.displays) { + screenView.push(new display(io, dispatcher, metadata, screenId, bundler)); + screenId += 1; + } + + let adminView = new admin(io, dispatcher, screenView, bundler); + + io.of("/lobby").on("connection", function (socket) { + cli.info("WS/" + socket.conn.remoteAddress + " connect"); + + socket.on('error', function (error) { + cli.error(error, "WS/ error"); + }); + + socket.on('disconnect', function (reason) { + cli.info("WS/ " + reason + " " + socket.conn.remoteAddress); + }); + + socket.on('displays', function () { + let previewImages = []; + for (let display of screenView) { + previewImages.push("/render/" + display.serverOptions.currentBundle + "/" + display.serverOptions.currentFile + ".png"); + } + socket.emit("callback.displays", {displays: meta.displays, previewImages: previewImages}); + }); + }); + + return screenView; +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..6f7c3a0 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1362 @@ +{ + "name": "infoscreen3", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "optional": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "optional": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "optional": true, + "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.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "optional": true + }, + "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=", + "optional": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "optional": true + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, + "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=" + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + }, + "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==" + } + } + }, + "basic-auth-connect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz", + "integrity": "sha1-/bC0OWLKe0BFanwrtI/hc9otISI=" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "requires": { + "callsite": "1.0.0" + } + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + } + }, + "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" + } + }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + } + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "optional": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "optional": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "optional": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "connect-busboy": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/connect-busboy/-/connect-busboy-0.0.2.tgz", + "integrity": "sha1-rFyclmchcYheV2xmsr/ZXTuxEJc=", + "requires": { + "busboy": "*" + } + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz", + "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=", + "requires": { + "cookie": "0.3.1", + "cookie-signature": "1.0.6" + } + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "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=" + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==" + }, + "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" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "optional": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "engine.io": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.3.2.tgz", + "integrity": "sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w==", + "requires": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~6.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "engine.io-client": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.1.tgz", + "integrity": "sha512-q66JBFuQcy7CSlfAz9L3jH+v7DTT3i6ZEadYcVj2pOs8/0uJHLxKX3WBkGTvULJMdz0tUCyJag0aKT/dpXL9BQ==", + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "optional": true, + "requires": { + "prr": "~1.0.1" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.3", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.2", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "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==" + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "optional": true + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "optional": true + }, + "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=", + "optional": true + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + } + }, + "foreachasync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz", + "integrity": "sha1-VQKYfchxS+M5IJfzLgBxyd7gfPY=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "optional": true + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + }, + "dependencies": { + "combined-stream": { + "version": "1.0.6", + "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "optional": true, + "requires": { + "delayed-stream": "~1.0.0" + } + } + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "optional": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "optional": true + }, + "har-validator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", + "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", + "optional": true, + "requires": { + "ajv": "^5.3.0", + "har-schema": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "http-errors": { + "version": "1.6.3", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "optional": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", + "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" + }, + "is": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz", + "integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "optional": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "optional": true + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "optional": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "optional": true + }, + "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=", + "optional": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "less": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/less/-/less-3.0.4.tgz", + "integrity": "sha512-q3SyEnPKbk9zh4l36PGeW2fgynKu+FpbhiUNx/yaiBUQ3V0CbACCgb9FzYWcRgI2DJlP6eI4jc8XPrCTi55YcQ==", + "requires": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "mime": "^1.4.1", + "mkdirp": "^0.5.0", + "promise": "^7.1.1", + "request": "^2.83.0", + "source-map": "~0.6.0" + } + }, + "less-middleware": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/less-middleware/-/less-middleware-3.0.1.tgz", + "integrity": "sha512-FCG4zGd7c/lKMWGDzzkfU9Lcndfjc4TcSnuRwUtJ4E+NxPMuDGe7lJA1rOn+SI9x2lak+s4b6sQkcPa45eqKiw==", + "requires": { + "less": "~3.0.4", + "mkdirp": "~0.5.1", + "node.extend": "~2.0.0" + } + }, + "locutus": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/locutus/-/locutus-2.0.10.tgz", + "integrity": "sha512-AZg2kCqrquMJ5FehDsBidV0qHl98NrsYtseUClzjAQ3HFnsDBJTCwGVplSQ82t9/QfgahqvTjaKcZqZkHmS0wQ==" + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "mime-db": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", + "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==" + }, + "mime-types": { + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", + "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", + "requires": { + "mime-db": "~1.36.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": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "node-media-server": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/node-media-server/-/node-media-server-1.4.9.tgz", + "integrity": "sha512-lqWtbJDaL9DEJrRAdyMcwvsaJ1SFn23vDu6gItk0t6x1Y4GTVDRXl3R/VHqV6mpSFioi3qeacPkxCJIorbN83g==", + "requires": { + "basic-auth-connect": "^1.0.0", + "chalk": "^2.4.1", + "dateformat": "^3.0.3", + "express": "^4.16.3", + "lodash": "^4.17.10", + "mkdirp": "^0.5.1", + "ws": "^5.1.1" + }, + "dependencies": { + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "node.extend": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-2.0.0.tgz", + "integrity": "sha1-dSWih1Z36lNHhKXhCseJVhOWFN8=", + "requires": { + "is": "^3.2.1" + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "optional": true + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "optional": true, + "requires": { + "asap": "~2.0.3" + } + }, + "proxy-addr": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", + "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.8.0" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "optional": true + }, + "psl": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", + "optional": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "optional": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "optional": true, + "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": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "optional": true + }, + "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==", + "optional": true + } + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "socket.io": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.2.0.tgz", + "integrity": "sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==", + "requires": { + "debug": "~4.1.0", + "engine.io": "~3.3.1", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.2.0", + "socket.io-parser": "~3.3.0" + }, + "dependencies": { + "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" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=" + }, + "socket.io-client": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", + "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==", + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.3.1", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, + "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.14.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", + "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "optional": true, + "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" + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + }, + "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==", + "optional": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "optional": true, + "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=", + "optional": true + }, + "twig": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/twig/-/twig-0.10.3.tgz", + "integrity": "sha1-Z2BOCOGSDr8vr4CpAeJWGJyKPGc=", + "requires": { + "locutus": "^2.0.5", + "minimatch": "3.0.x", + "walk": "2.3.x" + } + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "optional": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "walk": { + "version": "2.3.14", + "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.14.tgz", + "integrity": "sha512-5skcWAUmySj6hkBdH6B6+3ddMjVQYH5Qy9QGbPmN8kVmLteXk+yVXg+yfk1nbX30EYakahLrr8iPcCxJQSCBeg==", + "requires": { + "foreachasync": "^3.0.0" + } + }, + "ws": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.2.tgz", + "integrity": "sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..dcdc177 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "infoscreen3", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node --expose-gc ./bin/www" + }, + "dependencies": { + "basic-auth": "^2.0.1", + "chalk": "^2.4.2", + "connect-busboy": "0.0.2", + "cookie-parser": "~1.4.3", + "cors": "^2.8.5", + "debug": "~2.6.9", + "express": "^4.16.4", + "http-errors": "~1.6.2", + "less-middleware": "^3.0.1", + "morgan": "~1.9.0", + "node-media-server": "~1.4.9", + "socket.io": "^2.2.0", + "twig": "~0.10.3" + } +} diff --git a/public/js/dashboard.js b/public/js/dashboard.js new file mode 100644 index 0000000..1a1c6e3 --- /dev/null +++ b/public/js/dashboard.js @@ -0,0 +1,280 @@ +var serverOptions; +var bundleSettings; +var bundleDirs; +var displayId = 0; +var displayList; + + +socket.on('connect', function () { + canvas = new fabric.Canvas('edit'); + canvas.includeDefaultValues = false; + emit('admin.dashboard.sync'); +}); + +socket.on("callback.update", function (data) { + // filter out other displays updates than the current one + if (data.serverOptions.displayId === displayId) { + serverOptions = data.serverOptions; + $('#bundleSlides').children().css("border", "1px solid black"); + $('#' + serverOptions.currentFile).css("border", "1px solid #1ebc30"); + } + updateControls(data.serverOptions); +}); + + +socket.on("callback.dashboard.sync", function (data) { + displayId = parseInt(data.displayId); + serverOptions = data.serverOptions; + bundleDirs = data.bundleDirs; + displayList = data.displays; + updateControls(data.serverOptions); + + // update dropdown at menu with bundles + var valueArray = []; + for (var dir of bundleDirs) { + valueArray.push({name: dir, value: dir}); + } + + $('#bundles') + .dropdown({ + direction: "upward", + values: valueArray, + action: function (text, value) { + $('#bundles') + .dropdown("hide"); + emit("admin.setBundle", {bundle: value}); + } + }).dropdown("set selected", {bundle: serverOptions.currentBundle}); + $('#currentBundle').text(serverOptions.currentBundle); + + // update dropdown at menu with bundles + valueArray = []; + var x = 0; + for (var display of data.displays) { + valueArray.push({name: display.name, value: x}); + x++; + } + + $('#displays') + .dropdown({ + direction: "upward", + values: valueArray, + action: function (text, value) { + $('#displays') + .dropdown("hide"); + + displayId = parseInt(value); + emit("admin.setDisplay", {display: value}); + var program = document.getElementById('program'); + program.src = "/display/" + value; + } + }).dropdown("set selected", displayId); + + $('.currentDisplay').text(displayList[displayId].name); + + var transitionArray = []; + var values = ["bars", "blinds", "blinds3d", "zip", "blocks", "blocks2", "concentric", "warp", "cube", "tiles3d", "tiles3dprev", "slide", "swipe", "dissolve"]; + + for (var i in values) { + transitionArray.push({name: values[i], value: values[i]}); + } + + $('#transitions') + .dropdown({ + direction: "upward", + values: transitionArray, + action: function (text, value) { + $('#displays') + .dropdown("hide"); + + emit("admin.setTransition", {transition: value}); + $('.currentTransition').text(value); + + } + }).dropdown("set selected", serverOptions.transition); + + $('#currentTransition').text(serverOptions.transition); + + var preview = document.getElementById('preview'); + preview.src = "/admin/preview?displayId=" + displayId + "&socket=" + encodeURIComponent(socket.id); + + + let output = ""; + for (var i in data.bundleDirs) { + let bundle = data.bundleDirs[i]; + output += '
' + + '
' + + '' + + '' + + '
' + + '
' + + '
' + bundle + '
' + + '
' + + '
'; + } + + $('#allBundles').html(output); + + +}); + +socket.on("callback.dashboard.updateSlides", function (data) { + + console.log("update"); + if (serverOptions.currentBundle === data.bundleName) { + bundleSettings = data.bundleSettings; + console.log("slides"); + updateSlides(data.bundleSettings); + } +}); + + + +socket.on("callback.dashboard.update", function (data) { + if (data.serverOptions.displayId !== displayId) + return; + + displayId = parseInt(data.displayId); + bundleSettings = data.bundleSettings; + serverOptions = data.serverOptions; + updateControls(data.serverOptions); + updateSlides(bundleSettings); + + $('#allBundles').children().css("border", "1px solid black"); + $('#bundle_' + serverOptions.currentBundle).css("border", "1px solid #1ebc30"); + $('#currentBundle').text(serverOptions.currentBundle); + $('#currentDisplay').text(displayList[displayId].name); + $('#transitions').dropdown("set selected", serverOptions.transition); + $('#currentTransition').text(serverOptions.transition); + + $('.editable').editable(function (value, settings) { + var uuid = $(this).parent().parent().attr("id"); + emit("admin.renameSlide", {uuid: uuid, name: value, bundleName: serverOptions.currentBundle}); + return (value); + }, { + submit: 'rename', + tooltip: "Doubleclick to edit...", + event: "dblclick", + cssclass: 'ui mini nopadded form', + cancelcssclass: 'ui tiny basic negative button', + submitcssclass: 'ui tiny basic positive button', + }); +}); + +$(function () { + fixPreview(); + $(".sortable").sortable({ + beforeStop: function (event, element) { + var sortedIDs = $(".sortable").sortable("toArray"); + emit("admin.reorderSlides", {sortedIDs: sortedIDs}); + } + }).disableSelection(); +}); + +function fixPreview() { + var con = $("#programContainer"), + aspect = (0.9 / 1.6), + width = con.innerWidth(), + height = Math.floor(width * aspect); + $("#program").css("width", width + "px").css("height", height + "px"); + $("#preview").css("width", width + "px").css("height", height + "px"); +} + +$(window).bind("resize", function () { + fixPreview(); +}); + +function createNew() { + editSlide(""); +} + +function editSlide(name) { + window.open("/admin/edit/slide?bundle=" + serverOptions.currentBundle + "&file=" + name + "&displayId=" + displayId, '_blank', 'location=no,height=800,width=1304,scrollbars=no,status=no'); +} + +function emit(callback, data) { + if (data === undefined || data === null) { + data = {}; + } + Object.assign(data, {displayId: parseInt(displayId)}); + socket.emit(callback, data); +} + +/** + * + * @param {display~serverOptions} serverOptions + */ +function updateControls() { + if (serverOptions.blackout) { + $('#blackout').removeClass('basic'); + } else { + $('#blackout').addClass('basic'); + } + if (serverOptions.isStreaming) { + $('#stream').removeClass('basic'); + } else { + $('#stream').addClass('basic'); + } + + if (serverOptions.loop) { + $('#play').addClass('green'); + $('#pause').removeClass('orange'); + + } else { + $('#play').removeClass('green'); + $('#pause').addClass('orange'); + } + +} + +function updateSlides(settings) { + var slides = settings.allSlides; + + var output = ""; + var index = 0; + var currentIndex = 0; + for (slide of slides) { + var status = "on"; + var color = "green"; + if (!slide.enabled) { + status = "off"; + color = "red"; + } + var iconStatus = "play"; + if (serverOptions.currentFile === slide.file) { + iconStatus = "play"; + currentIndex = index; + } + + output += '
' + + '
' + + '' + + '' + + '' + + '' + + '
' + + '
' + + '' + + '
' + slide.name.replace(".json", "") + '
' + + '
' + + '
'; + + index += 1; + } + + $("#bundleSlides").html(output); + $('#bundleSlides').children().css("border", "1px solid black"); + $('#' + serverOptions.currentFile).css("border", "1px solid #1ebc30"); +} + + +function remove(obj) { + if (confirm("Really delete slide?")) { + emit('admin.removeSlide', obj); + } +} +function forceReload() { + if (confirm("Really reload all connected display clients ?")) { + emit('admin.reload'); + } +} \ No newline at end of file diff --git a/public/js/display.js b/public/js/display.js new file mode 100644 index 0000000..5aadfcf --- /dev/null +++ b/public/js/display.js @@ -0,0 +1,382 @@ +function symmetricDifference(a1, a2) { + var result = []; + for (var i = 0; i < a1.length; i++) { + if (a2.indexOf(a1[i]) === -1) { + result.push(a1[i]); + } + } + for (i = 0; i < a2.length; i++) { + if (a1.indexOf(a2[i]) === -1) { + result.push(a2[i]); + } + } + return result; +} + +var connectionTimeoutId; + +$(function () { + if (!flux.browser.supportsTransitions) + alert("Flux Slider requires a browser that supports CSS3 transitions"); + + window.f = new flux.slider('#slider', { + controls: false, + captions: false, + autoplay: false, + pagination: false, + width: $(window).width(), + height: $(window).height(), + }); + + $(window).resize(function () { + if (this.resizeTO) clearTimeout(this.resizeTO); + this.resizeTO = setTimeout(function () { + $(this).trigger('windowResize'); + }, 250); + }); + + $(window).on('windowResize', function () { + window.f.setSize($(window).width(), $(window).height()); + }); + + updateTimeout(); +}); + +var layer = 0; + +/** bundleData + * @see data/default/bundle.json + * + **/ +var bundleData; +var serverOptions; +var streamStarted = false; +bundleData = { + background: "", + duration: 10, + styleHeader: {}, + styleText: {}, + useWebFonts: false +}; + +/*************************** + * window load, init + * **************************/ + +$(function () { + fixImageSizes(); + displayTime(); + setInterval(displayTime, 1000); +}); + +$(window).bind("resize", function () { + fixImageSizes(); +}); + + +function getLayer(offset) { + if (offset === undefined) offset = 0; + return "layer" + (layer + offset) % 2; +} + + +// socketio callbacks +/** when connected **/ +socket.on('connect', function () { + socket.emit("sync"); +}); + +socket.on('callback.blackout', function (data) { + serverOptions = data.serverOptions; + checkBlackout(); +}); + +socket.on('error', function () { + $("#networkstatus").css("opacity", 1); +}); + +socket.on('disconnect', function () { + $("#networkstatus").css("opacity", 1); +}); + +socket.on('pong', function () { + updateTimeout(); +}); + +socket.on('callback.time', function (data) { + + if ($('#time').hasClass('flipOutX')) { + $('#time').removeClass('flipOutX').addClass("flipInX"); + } else { + $('#time').addClass('flipOutX').removeClass("flipInX"); + } + +}); + +/** callback Load **/ +socket.on('callbackLoad', function (data) { + serverOptions = data.serverOptions; + bundleData = data.bundleData; + preloadImages(data.slides); + checkBlackout(); + setBackground(data.bundleData.background); + if (checkStream(serverOptions) === false) { + nextSlide(data); + } +}); + + +/** callback Update **/ +socket.on('callback.update', function (data) { + serverOptions = data.serverOptions; + bundleData = data.bundleData; + checkBlackout(); + if (checkStream(serverOptions) === false) { + nextSlide(data); + } +}); + +socket.on('callback.reload', function () { + location.reload(true); +}); + +socket.on('callback.reloadImage', function (data) { + reloadImage(data); +}); + +socket.on('callback.announce', function (data) { + checkBlackout(); + nextSlide(data); +}); + +socket.on('callback.forceSlide', function (data) { + checkBlackout(); + nextSlide(data); +}); + +/** + * Displays the local time for bottom of screen + * hh:mm + **/ +function displayTime() { + var date = new Date(); + var min = date.getMinutes(); + if (min < 10) min = "0" + min; + var time = date.getHours() + ":" + min; + $('#time').html(time); +} + +/** resize canvas to max width keeping aspect ratio 16:9**/ +function fixImageSizes() { + var con = $(window), + aspect = (0.9 / 1.6), + width = con.innerWidth(), + height = Math.floor(width * aspect); + + + $("#layer0").css("width", width + "px").css("height", height + "px"); + $("#layer1").css("width", width + "px").css("height", height + "px"); +} + + +function checkBlackout() { + updateTimeout(); + if (serverOptions.blackout) { + $("#blackoutLayer").css("opacity", 1); + } else { + $("#blackoutLayer").css("opacity", 0); + } +} + +function nextSlide(data) { + serverOptions = data.serverOptions; + bundleData = data.bundleData; + checkImages(data.slides); + + if (serverOptions.isAnnounce) { + try { + var randomId = uuidv4(); + var image = new Image(); + image.src = "/tmp/" + serverOptions.displayId + "/?randomId=" + randomId; + image.id = randomId; + image.class = "temp"; + window.f.images.push(image); + window.f.showTempImage(randomId); + } catch (err) { + console.log(err); + } + } else { + window.f.showImageById(serverOptions.currentFile, serverOptions.transition); + } + setBackground(bundleData.background); +} + +function setBackground(background) { + background = "/background/" + bundleData.bundleName + "/" + background; + if (serverOptions.isStreaming) return; + + var video = document.getElementById("bgvid"); + var bg = $("#bg"); + var bgImage = document.getElementById("bgimg"); + if (background.indexOf(".mp4") !== -1) { + + if (parseUrl(video.src) !== background) { + bg.hide(); + $(video).show(); + video.src = background; + video.play(); + } + } else { + if (parseUrl(bgImage.src) !== background) { + bgImage.src = background; + bg.show(); + $(video).hide(); + video.src = null; + video.pause(); + } + } +} + +function parseUrl(url) { + return '/background' + url.split('background')[1] +} + +function showBackgroundOnly() { + $("#" + getLayer(1)).css("opacity", 0); + $("#" + getLayer()).css("opacity", 0); +} + +function checkStream(serverOptions) { + + if (serverOptions.isStreaming && streamStarted === false) { + console.log("start stream!"); + if (flvjs.isSupported()) { + var videoElement = document.getElementById('bgvid'); + flvPlayer = flvjs.createPlayer({ + type: 'flv', + url: serverOptions.streamSource + }); + try { + flvPlayer.attachMediaElement(videoElement); + flvPlayer.load(); + flvPlayer.play(); + showBackgroundOnly(); + streamStarted = true; + return true; + + } catch (err) { + console.log(err); + streamStarted = false; + return false; + } + } + } else if (serverOptions.isStreaming === false) { + if (typeof flvPlayer !== "undefined") { + if (flvPlayer != null) { + flvPlayer.pause(); + flvPlayer.unload(); + flvPlayer.detachMediaElement(); + flvPlayer.destroy(); + flvPlayer = null; + streamStarted = false; + } + } + return false; + } + return false; +} + +/** + * preload images + * @param allSlides + */ +function preloadImages(allSlides) { + window.f.clearImages(); + + for (var i in allSlides) { + try { + var image = new Image(); + image.src = "/render/" + serverOptions.currentBundle + "/" + allSlides[i].file + ".png"; + image.id = allSlides[i].file; + window.f.images.push(image); + } catch (err) { + console.log(err); + } + } + window.f.setupImages(); +} + +function reloadImage(data) { + console.log("reloadImage"); + console.log(data); + + window.f.clearImageById(data.file); + window.f.setupImages(); + + var image = new Image(); + image.src = "/render/" + data.bundle + "/" + data.file + ".png?" + uuidv4(); + image.id = data.file; + window.f.images.push(image); + + +} + +function checkImages(allSlides) { + var fluxIds = []; + var allIds = []; + + var fImages = window.f.images; + for (var j in fImages) { + fluxIds.push(fImages[j].id); + } + for (var k in allSlides) { + allIds.push(allSlides[k].file); + } + + // new slides count is less than slides in rotation + // remove slides + if (allSlides.length < fluxIds.length) { + console.log("less"); + var diffIds = symmetricDifference(fluxIds, allIds); + for (var l in diffIds) { + window.f.clearImageById(diffIds[l]); + } + } else + // else count is greater, so add slides + { + for (var i in allSlides) { + try { + if (fluxIds.indexOf(allSlides[i].file) < 0) { + console.log("adding"); + var image = new Image(); + image.src = "/render/" + serverOptions.currentBundle + "/" + allSlides[i].file + ".png"; + image.id = allSlides[i].file; + window.f.images.push(image); + } + } catch (err) { + console.log(err); + } + } + } + + +} + +/** Generate an uuid + * @url https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript#2117523 **/ +function uuidv4() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + let r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); +} + +function updateTimeout() { + clearTimeout(connectionTimeoutId); + $("#networkstatus").css("opacity", 0); + connectionTimeoutId = setTimeout(function () { + $("#networkstatus").css("opacity", 1); + }, 30000) +} + + diff --git a/public/js/displayLite.js b/public/js/displayLite.js new file mode 100644 index 0000000..6d0632e --- /dev/null +++ b/public/js/displayLite.js @@ -0,0 +1,255 @@ +var layer = 0; + +/** bundleData + * @see data/default/bundle.json + * + **/ +var connectionTimeoutId; +var bundleData; +var serverOptions; +var streamStarted = false; +bundleData = { + background: "", + duration: 10, + styleHeader: {}, + styleText: {}, + useWebFonts: false +}; + + +/*************************** + * window load, init + * **************************/ + +$(function () { + + fixImageSizes(); + displayTime(); + setInterval(displayTime, 1000); +}); + +$(window).bind("resize", function () { + fixImageSizes(); +}); + + +function getLayer(offset) { + if (offset === undefined) offset = 0; + return "layer" + (layer + offset) % 2; +} + + +// socketio callbacks +/** when connected **/ +socket.on('connect', function () { + console.log("connect, calling sync!"); + socket.emit("sync"); +}); + +socket.on('error', function () { + $("#networkstatus").css("opacity", 1); +}); + +socket.on('disconnect', function () { + $("#networkstatus").css("opacity", 1); +}); + +socket.on('pong', function () { + updateTimeout(); +}); + +socket.on('callback.blackout', function (data) { + serverOptions = data.serverOptions; + checkBlackout(); +}); + +socket.on('callback.time', function (data) { + + if ($('#time').hasClass('flipOutX')) { + $('#time').removeClass('flipOutX').addClass("flipInX"); + } else { + $('#time').addClass('flipOutX').removeClass("flipInX"); + } + +}); + +/** callback Load **/ +socket.on('callbackLoad', function (data) { + serverOptions = data.serverOptions; + bundleData = data.bundleData; + checkBlackout(); + nextSlide(data); +}); + + +/** callback Update **/ +socket.on('callback.update', function (data) { + serverOptions = data.serverOptions; + bundleData = data.bundleData; + checkBlackout(); + nextSlide(data); +}); + +socket.on('callback.reload', function () { + location.reload(true); +}); + +socket.on('callback.announce', function (data) { + checkBlackout(); + nextSlide(data); +}); + +socket.on('callback.forceSlide', function (data) { + checkBlackout(); + nextSlide(data); +}); + + +/** + * Displays the local time for bottom of screen + * hh:mm + **/ +function displayTime() { + var date = new Date(); + var min = date.getMinutes(); + if (min < 10) min = "0" + min; + var time = date.getHours() + ":" + min; + $('#time').html(time); +} + +/** resize canvas to max width keeping aspect ratio 16:9**/ +function fixImageSizes() { + var con = $(window), + aspect = (0.9 / 1.6), + width = con.innerWidth(), + height = Math.floor(width * aspect); + + + $("#layer0").css("width", width + "px").css("height", height + "px"); + $("#layer1").css("width", width + "px").css("height", height + "px"); +} + + +function checkBlackout() { + updateTimeout(); + if (serverOptions.blackout) { + $("#blackoutLayer").css("opacity", 1); + } else { + $("#blackoutLayer").css("opacity", 0); + } +} + +function nextSlide(data) { + serverOptions = data.serverOptions; + bundleData = data.bundleData; + + var elem = document.getElementById("img" + layer); + if (serverOptions.isAnnounce) { + try { + var randomId = uuidv4(); + elem.src = "/tmp/" + serverOptions.displayId + "/?randomId=" + randomId; + } catch (err) { + console.log(err); + } + } else { + elem.src = "/render/" + serverOptions.currentBundle + "/" + serverOptions.currentFile + ".png"; + } + + setBackground(bundleData.background); + $("#" + getLayer(1)).css("opacity", 0); + $("#" + getLayer()).css("opacity", 1); + + layer++; + if (layer > 1) { + layer = 0; + } + +} + +function setBackground(background) { + background = "/background/" + bundleData.bundleName + "/" + background; + + var video = document.getElementById("bgvid"); + var bg = $("#bg"); + var bgImage = document.getElementById("bgimg"); + if (background.indexOf(".mp4") !== -1) { + if (parseUrl(video.src) !== background) { + bg.hide(); + $(video).show(); + video.src = background; + video.play(); + } + } else { + if (parseUrl(bgImage.src) !== background) { + bgImage.src = background; + bg.show(); + $(video).hide(); + video.src = ""; + video.pause(); + } + } +} + +function parseUrl(url) { + return '/background' + url.split('background')[1] +} + +function showBackgroundOnly() { + $("#" + getLayer(1)).css("opacity", 0); + $("#" + getLayer()).css("opacity", 0); +} + +function checkStream(serverOptions) { + + if (serverOptions.isStreaming && streamStarted === false) { + if (flvjs.isSupported()) { + var videoElement = document.getElementById('bgvid'); + flvPlayer = flvjs.createPlayer({ + type: 'flv', + url: serverOptions.streamSource + }); + try { + flvPlayer.attachMediaElement(videoElement); + flvPlayer.load(); + flvPlayer.play(); + showBackgroundOnly(); + streamStarted = true; + return true; + } catch (err) { + console.log(err); + streamStarted = false; + return false; + } + } + } else if (serverOptions.isStreaming === false) { + if (typeof flvPlayer !== "undefined") { + if (flvPlayer != null) { + flvPlayer.pause(); + flvPlayer.unload(); + flvPlayer.detachMediaElement(); + flvPlayer.destroy(); + flvPlayer = null; + streamStarted = false; + } + } + return false; + } + return false; +} + +function updateTimeout() { + clearTimeout(connectionTimeoutId); + $("#networkstatus").css("opacity", 0); + connectionTimeoutId = setTimeout(function () { + $("#networkstatus").css("opacity", 1); + }, 30000) +} + +/** Generate an uuid + * @url https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript#2117523 **/ +function uuidv4() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + let r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); +} diff --git a/public/js/edit.js b/public/js/edit.js new file mode 100644 index 0000000..ac35153 --- /dev/null +++ b/public/js/edit.js @@ -0,0 +1,435 @@ +let canvas; +let bundleData; + +let _clipboard = null; + +bundleData = { + background: "", + duration: 10, + styleHeader: {}, + styleText: {}, + useWebFonts: false +}; + +$(function () { + + $('html').keyup(function (e) { + if (e.keyCode === 46) { + obj = canvas.getActiveObject(); + if (!obj.isEditing) { + removeSelectedObjects(); + } + } + }); + + $('#order') + .dropdown({ + action: 'hide', + onChange: function (value, text, $selectedItem) { + setZindex(value); + } + }); + + + $('#contextmenu .dropdown').dropdown({ + on: 'hover', + }); + + displayTime(); + setInterval(displayTime, 1000); +}); + + +// Trigger action when the contexmenu is about to be shown +$(document).bind("contextmenu", function (event) { + + // Avoid the real one + event.preventDefault(); + + var objects = canvas.getActiveObjects(); + + if (objects.length > 0) { + // Show contextmenu + $("#contextmenu").finish().toggle(100).// In the right position (the mouse) + css({ + top: event.pageY + "px", + left: event.pageX + "px" + }); + } + +}); + + +// If the document is clicked somewhere +$(document).bind("mousedown", function (e) { + + // If the clicked element is not the menu + if (!$(e.target).parents("#contextmenu").length > 0) { + if (!$(e.target).attr("data-action")) { + // Hide it + $("#contextmenu").hide(100); + } + } +}); + + +// If the menu element is clicked +$("#contextmenu .item").click(function () { + + // This is the triggered action name + switch ($(this).attr("data-action")) { + + // A case for each action. Your actions here + case "copy": + copyObject(); + break; + case "paste": + pasteObject(); + break; + case "delete": + removeSelectedObjects(); + break; + case "bringToFront": + setZindex("bringToFront"); + break; + case "sendToBack": + setZindex("sendToBack"); + break; + case "bringForward": + setZindex("bringForward"); + break; + case "sendBackwards": + setZindex("sendBackwards"); + break; + } + + // Hide it AFTER the action was triggered + $("#contextmenu").hide(100); +}); + +/** + * Displays the local time for bottom of screen + * hh:mm + **/ +function displayTime() { + var date = new Date(); + var min = date.getMinutes(); + if (min < 10) min = "0" + min; + var time = date.getHours() + ":" + min; + $('#time2').html(time); +} + + +function setZindex(value) { + switch (value) { + case "sendToBack": + canvas.sendToBack(canvas.getActiveObject()); + break; + case "bringToFront": + canvas.bringToFront(canvas.getActiveObject()); + break; + case "bringForward": + canvas.bringForward(canvas.getActiveObject()); + break; + case "sendBackwards": + canvas.sendBackwards(canvas.getActiveObject()); + break; + } + canvas.renderAll(); +} + +// socketio +fabric.Image.prototype.toObject = (function (toObject) { + return function () { + return fabric.util.object.extend(toObject.call(this), { + src: '/images' + this.getSrc().split('images')[1] + }); + } +})(fabric.Image.prototype.toObject); + + +socket.on('connect', function () { + canvas = new fabric.Canvas('edit'); + canvas.includeDefaultValues = false; + socket.emit('admin.editSlide', {bundleName: bundle, fileName: file}); +}); + +socket.on('callback.save', function (data) { + if (data.error) { + alert(data.error); + } else { + window.close(); + } +}); + +socket.on('callback.edit.updateFileList', function (data) { + if (data.error) { + console.log(data); + alert(data.error); + } else { + openImageBrowser(); + } +}); + +socket.on('callbackEdit', function (data) { + canvas.clear(); + if (data.bundleData.useWebFonts) { + if (data.bundleData.styleHeader.fontFamily !== bundleData.styleHeader.fontFamily || data.bundleData.styleText.fontFamily !== bundleData.styleText.fontFamily) { + WebFont.load({ + google: { + families: [data.bundleData.styleHeader.fontFamily, data.bundleData.styleText.fontFamily] + }, + timeout: 2000, + active: function () { + nextSlide(data, true); + }, + inactive: function () { + nextSlide(data, true); + } + }); + } else { + nextSlide(data, true); + } + } else { + nextSlide(data, true); + } + + bundleData = data.bundleData; + setBackground(bundleData.background); +}); + +function setBackground(background) { + background = "/background/" + bundleData.bundleName + "/" + background; + + var video = document.getElementById("bgvid2"); + var bg = $("#bg"); + var bgImage = document.getElementById("bgimg"); + if (background.indexOf(".mp4") !== -1) { + if (parseUrl(video.src) !== background) { + bg.hide(); + $(video).show(); + video.src = background; + video.play(); + } + } else { + if (parseUrl(bgImage.src) !== background) { + bgImage.src = background; + bg.show(); + $(video).hide(); + video.src = null; + video.pause(); + } + } +} + +function parseUrl(url) { + return '/background' + url.split('background')[1] +} + +function nextSlide(data) { + canvas.loadFromJSON(data.json, function () { + canvas.renderAll(); + }, function (o, object) { + + if (object.type === "i-text") { + object.setOptions(bundleData.styleText); + + if (object.id === "header") { + object.setOptions(bundleData.styleHeader); + } + object.setShadow({color: "#000", blur: 3, offsetX: 0, offsetY: 0}); + + object.lockRotation = true; + object.hasControls = false; + object.hasRotatingPoint = false; + } + + object.lockUniScaling = true; + }); +} + + +function copyObject() { + // clone what are you copying since you + // may want copy and paste on different moment. + // and you do not want the changes happened + // later to reflect on the copy. + canvas.getActiveObject().clone(function (cloned) { + _clipboard = cloned; + }); +} + +function pasteObject() { + if (_clipboard === null) return; + // clone again, so you can do multiple copies. + _clipboard.clone(function (clonedObj) { + canvas.discardActiveObject(); + clonedObj.set({ + left: clonedObj.left + 10, + top: clonedObj.top + 10, + evented: true, + }); + if (clonedObj.type === 'activeSelection') { + // active selection needs a reference to the canvas. + clonedObj.canvas = canvas; + clonedObj.forEachObject(function (obj) { + canvas.add(obj); + }); + // this should solve the unselectability + clonedObj.setCoords(); + } else { + canvas.add(clonedObj); + } + _clipboard.top += 10; + _clipboard.left += 10; + canvas.setActiveObject(clonedObj); + canvas.requestRenderAll(); + }); +} + +function addText(content, isHeader) { + let text = new fabric.IText(content, { + id: "normal", + }); + + let y = 0; + var objects = canvas.getObjects('i-text'); + for (let i in objects) { + if (objects[i].top > y) { + y = objects[i].top + objects[i].height; + } + } + + if (y === 0) { + y = 30; + } + text.setOptions(bundleData.styleText); + text.setOptions({top: y + 10, left: 250}); + + if (isHeader) { + text.id = "header"; + text.setOptions(bundleData.styleHeader); + text.setOptions({top: y + 10, left: 150}); + } + + text.lockRotation = true; + text.hasControls = false; + text.lockUniScaling = true; + text.hasRotatingPoint = false; + + text.setShadow({color: "rgba(0,0,0,0.8)", blur: 5, offsetX: 2, offsetY: 2}); + + canvas.add(text); +} + +function addImage(imageUrl, isFullSized) { + + fabric.Image.fromURL(imageUrl, function (bgImage) { + + var canvasAspect = canvas.width / canvas.height; + var imgAspect = bgImage.width / bgImage.height; + var left, top, scaleFactor; + + if (canvasAspect >= imgAspect) { + scaleFactor = canvas.width / bgImage.width; + left = 0; + top = -((bgImage.height * scaleFactor) - canvas.height) / 2; + } else { + scaleFactor = canvas.height / bgImage.height; + top = 0; + left = -((bgImage.width * scaleFactor) - canvas.width) / 2; + } + + if (isFullSized) { + bgImage.set({ + top: top, + left: left, + originX: 'left', + originY: 'top', + scaleX: scaleFactor, + scaleY: scaleFactor + }); + } else { + bgImage.set({ + scaleY: 0.5, + scaleX: 0.5, + }); + } + + bgImage.lockUniScaling = true; + canvas.add(bgImage); + }); + + $("#imageLayer").modal("hide"); + +} + +function addHeader(content) { + addText(content, true); +} + +function removeSelectedObjects() { + let obj = canvas.getActiveObjects(); + for (var i in obj) { + canvas.remove(obj[i]); + } + canvas.discardActiveObject(); + canvas.requestRenderAll(); + +} + +function cueSlide() { + if (confirm('Pause show and force display of the current slide?')) { + let obj = {json: canvas.toJSON(['id']), png: canvas.toDataURL('png'), displayId: displayId}; + socket.emit("admin.override", obj); + } +} + + +function save() { + canvas.setBackgroundImage(null, null, null); + var name = "untitled"; + var texts = canvas.getObjects('i-text'); + for (let i in texts) { + if (texts[i].id == "header") { + name = texts[i].text; + break; + } + } + socket.emit("edit.save", { + bundleName: bundle, + name: name, + fileName: file, + json: canvas.toJSON(['id']), + png: canvas.toDataURL('png'), + displayId: displayId + }); +} + + +function deleteImage(name) { + if (confirm("Really delete image?")) { + socket.emit("edit.deleteImage", { + bundleName: bundle, + name: name, + }); + } +} + + +function openImageBrowser() { + $("#imageList").load("/admin/ajax/imagelist?bundle=" + bundle + "&nocache=" + uuidv4(), null, function () { + addImagesFromUploadQueue(); + $('#imageLayer').modal('show'); + }); +} + +/** Generate an uuid + * @url https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript#2117523 **/ +function uuidv4() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + let r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); +} + diff --git a/public/js/filereader.js b/public/js/filereader.js new file mode 100644 index 0000000..ddeb815 --- /dev/null +++ b/public/js/filereader.js @@ -0,0 +1,432 @@ +/*! +FileReader.js - v0.99 +A lightweight wrapper for common FileReader usage. +Copyright 2014 Brian Grinstead - MIT License. +See http://github.com/bgrins/filereader.js for documentation. +*/ + +(function(window, document) { + + var FileReader = window.FileReader; + var FileReaderSyncSupport = false; + var workerScript = "self.addEventListener('message', function(e) { var data=e.data; try { var reader = new FileReaderSync; postMessage({ result: reader[data.readAs](data.file), extra: data.extra, file: data.file})} catch(e){ postMessage({ result:'error', extra:data.extra, file:data.file}); } }, false);"; + var syncDetectionScript = "onmessage = function(e) { postMessage(!!FileReaderSync); };"; + var fileReaderEvents = ['loadstart', 'progress', 'load', 'abort', 'error', 'loadend']; + var sync = false; + var FileReaderJS = window.FileReaderJS = { + enabled: false, + setupInput: setupInput, + setupDrop: setupDrop, + setupClipboard: setupClipboard, + setSync: function (value) { + sync = value; + + if (sync && !FileReaderSyncSupport) { + checkFileReaderSyncSupport(); + } + }, + getSync: function() { + return sync && FileReaderSyncSupport; + }, + output: [], + opts: { + dragClass: "drag", + accept: false, + readAsDefault: 'DataURL', + readAsMap: { + }, + on: { + loadstart: noop, + progress: noop, + load: noop, + abort: noop, + error: noop, + loadend: noop, + skip: noop, + groupstart: noop, + groupend: noop, + beforestart: noop + } + } + }; + + // Setup jQuery plugin (if available) + if (typeof(jQuery) !== "undefined") { + jQuery.fn.fileReaderJS = function(opts) { + return this.each(function() { + if (jQuery(this).is("input")) { + setupInput(this, opts); + } + else { + setupDrop(this, opts); + } + }); + }; + + jQuery.fn.fileClipboard = function(opts) { + return this.each(function() { + setupClipboard(this, opts); + }); + }; + } + + // Not all browsers support the FileReader interface. Return with the enabled bit = false. + if (!FileReader) { + return; + } + + + // makeWorker is a little wrapper for generating web workers from strings + function makeWorker(script) { + var URL = window.URL || window.webkitURL; + var Blob = window.Blob; + var Worker = window.Worker; + + if (!URL || !Blob || !Worker || !script) { + return null; + } + + var blob = new Blob([script]); + var worker = new Worker(URL.createObjectURL(blob)); + return worker; + } + + // setupClipboard: bind to clipboard events (intended for document.body) + function setupClipboard(element, opts) { + + if (!FileReaderJS.enabled) { + return; + } + var instanceOptions = extend(extend({}, FileReaderJS.opts), opts); + + element.addEventListener("paste", onpaste, false); + + function onpaste(e) { + var files = []; + var clipboardData = e.clipboardData || {}; + var items = clipboardData.items || []; + + for (var i = 0; i < items.length; i++) { + var file = items[i].getAsFile(); + + if (file) { + + // Create a fake file name for images from clipboard, since this data doesn't get sent + var matches = new RegExp("/\(.*\)").exec(file.type); + if (!file.name && matches) { + var extension = matches[1]; + file.name = "clipboard" + i + "." + extension; + } + + files.push(file); + } + } + + if (files.length) { + processFileList(e, files, instanceOptions); + e.preventDefault(); + e.stopPropagation(); + } + } + } + + // setupInput: bind the 'change' event to an input[type=file] + function setupInput(input, opts) { + + if (!FileReaderJS.enabled) { + return; + } + var instanceOptions = extend(extend({}, FileReaderJS.opts), opts); + + input.addEventListener("change", inputChange, false); + input.addEventListener("drop", inputDrop, false); + + function inputChange(e) { + processFileList(e, input.files, instanceOptions); + } + + function inputDrop(e) { + e.stopPropagation(); + e.preventDefault(); + processFileList(e, e.dataTransfer.files, instanceOptions); + } + } + + // setupDrop: bind the 'drop' event for a DOM element + function setupDrop(dropbox, opts) { + + if (!FileReaderJS.enabled) { + return; + } + var instanceOptions = extend(extend({}, FileReaderJS.opts), opts); + var dragClass = instanceOptions.dragClass; + var initializedOnBody = false; + + // Bind drag events to the dropbox to add the class while dragging, and accept the drop data transfer. + dropbox.addEventListener("dragenter", onlyWithFiles(dragenter), false); + dropbox.addEventListener("dragleave", onlyWithFiles(dragleave), false); + dropbox.addEventListener("dragover", onlyWithFiles(dragover), false); + dropbox.addEventListener("drop", onlyWithFiles(drop), false); + + // Bind to body to prevent the dropbox events from firing when it was initialized on the page. + document.body.addEventListener("dragstart", bodydragstart, true); + document.body.addEventListener("dragend", bodydragend, true); + document.body.addEventListener("drop", bodydrop, false); + + function bodydragend(e) { + initializedOnBody = false; + } + + function bodydragstart(e) { + initializedOnBody = true; + } + + function bodydrop(e) { + if (e.dataTransfer.files && e.dataTransfer.files.length ){ + e.stopPropagation(); + e.preventDefault(); + } + } + + function onlyWithFiles(fn) { + return function() { + if (!initializedOnBody) { + fn.apply(this, arguments); + } + }; + } + + function drop(e) { + e.stopPropagation(); + e.preventDefault(); + if (dragClass) { + removeClass(dropbox, dragClass); + } + processFileList(e, e.dataTransfer.files, instanceOptions); + } + + function dragenter(e) { + e.stopPropagation(); + e.preventDefault(); + if (dragClass) { + addClass(dropbox, dragClass); + } + } + + function dragleave(e) { + if (dragClass) { + removeClass(dropbox, dragClass); + } + } + + function dragover(e) { + e.stopPropagation(); + e.preventDefault(); + if (dragClass) { + addClass(dropbox, dragClass); + } + } + } + + // setupCustomFileProperties: modify the file object with extra properties + function setupCustomFileProperties(files, groupID) { + for (var i = 0; i < files.length; i++) { + var file = files[i]; + file.extra = { + nameNoExtension: file.name.substring(0, file.name.lastIndexOf('.')), + extension: file.name.substring(file.name.lastIndexOf('.') + 1), + fileID: i, + uniqueID: getUniqueID(), + groupID: groupID, + prettySize: prettySize(file.size) + }; + } + } + + // getReadAsMethod: return method name for 'readAs*' - http://www.w3.org/TR/FileAPI/#reading-a-file + function getReadAsMethod(type, readAsMap, readAsDefault) { + for (var r in readAsMap) { + if (type.match(new RegExp(r))) { + return 'readAs' + readAsMap[r]; + } + } + return 'readAs' + readAsDefault; + } + + // processFileList: read the files with FileReader, send off custom events. + function processFileList(e, files, opts) { + + var filesLeft = files.length; + var group = { + groupID: getGroupID(), + files: files, + started: new Date() + }; + + function groupEnd() { + group.ended = new Date(); + opts.on.groupend(group); + } + + function groupFileDone() { + if (--filesLeft === 0) { + groupEnd(); + } + } + + FileReaderJS.output.push(group); + setupCustomFileProperties(files, group.groupID); + + opts.on.groupstart(group); + + // No files in group - end immediately + if (!files.length) { + groupEnd(); + return; + } + + var supportsSync = sync && FileReaderSyncSupport; + var syncWorker; + + // Only initialize the synchronous worker if the option is enabled - to prevent the overhead + if (supportsSync) { + syncWorker = makeWorker(workerScript); + syncWorker.onmessage = function(e) { + var file = e.data.file; + var result = e.data.result; + + // Workers seem to lose the custom property on the file object. + if (!file.extra) { + file.extra = e.data.extra; + } + + file.extra.ended = new Date(); + + // Call error or load event depending on success of the read from the worker. + opts.on[result === "error" ? "error" : "load"]({ target: { result: result } }, file); + groupFileDone(); + }; + } + + Array.prototype.forEach.call(files, function(file) { + + file.extra.started = new Date(); + + if (opts.accept && !file.type.match(new RegExp(opts.accept))) { + opts.on.skip(file); + groupFileDone(); + return; + } + + if (opts.on.beforestart(file) === false) { + opts.on.skip(file); + groupFileDone(); + return; + } + + var readAs = getReadAsMethod(file.type, opts.readAsMap, opts.readAsDefault); + + if (syncWorker) { + syncWorker.postMessage({ + file: file, + extra: file.extra, + readAs: readAs + }); + } + else { + + var reader = new FileReader(); + reader.originalEvent = e; + + fileReaderEvents.forEach(function(eventName) { + reader['on' + eventName] = function(e) { + if (eventName == 'load' || eventName == 'error') { + file.extra.ended = new Date(); + } + opts.on[eventName](e, file); + if (eventName == 'loadend') { + groupFileDone(); + } + }; + }); + reader[readAs](file); + } + }); + } + + // checkFileReaderSyncSupport: Create a temporary worker and see if FileReaderSync exists + function checkFileReaderSyncSupport() { + var worker = makeWorker(syncDetectionScript); + if (worker) { + worker.onmessage =function(e) { + FileReaderSyncSupport = e.data; + }; + worker.postMessage({}); + } + } + + // noop: do nothing + function noop() { + + } + + // extend: used to make deep copies of options object + function extend(destination, source) { + for (var property in source) { + if (source[property] && source[property].constructor && + source[property].constructor === Object) { + destination[property] = destination[property] || {}; + arguments.callee(destination[property], source[property]); + } + else { + destination[property] = source[property]; + } + } + return destination; + } + + // hasClass: does an element have the css class? + function hasClass(el, name) { + return new RegExp("(?:^|\\s+)" + name + "(?:\\s+|$)").test(el.className); + } + + // addClass: add the css class for the element. + function addClass(el, name) { + if (!hasClass(el, name)) { + el.className = el.className ? [el.className, name].join(' ') : name; + } + } + + // removeClass: remove the css class from the element. + function removeClass(el, name) { + if (hasClass(el, name)) { + var c = el.className; + el.className = c.replace(new RegExp("(?:^|\\s+)" + name + "(?:\\s+|$)", "g"), " ").replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + } + } + + // prettySize: convert bytes to a more readable string. + function prettySize(bytes) { + var s = ['bytes', 'kb', 'MB', 'GB', 'TB', 'PB']; + var e = Math.floor(Math.log(bytes)/Math.log(1024)); + return (bytes/Math.pow(1024, Math.floor(e))).toFixed(2)+" "+s[e]; + } + + // getGroupID: generate a unique int ID for groups. + var getGroupID = (function(id) { + return function() { + return id++; + }; + })(0); + + // getUniqueID: generate a unique int ID for files + var getUniqueID = (function(id) { + return function() { + return id++; + }; + })(0); + + // The interface is supported, bind the FileReaderJS callbacks + FileReaderJS.enabled = true; + +})(this, document); \ No newline at end of file diff --git a/public/js/flux.js b/public/js/flux.js new file mode 100644 index 0000000..2f81a00 --- /dev/null +++ b/public/js/flux.js @@ -0,0 +1,1763 @@ +/** + * @preserve Flux Slider v1.4.4 + * http://www.joelambert.co.uk/flux + * + * Copyright 2011, Joe Lambert. + * Free to use under the MIT license. + * http://www.opensource.org/licenses/mit-license.php + */ + +/** + * Contains additional changes for infoScreen3 + * Free to use under the MIT license. + * http://www.opensource.org/licenses/mit-license.php + */ + +// Flux namespace +window.flux = { + version: '1.4.4' +}; + +(function ($) { + flux.slider = function (elem, opts) { + // Setup the flux.browser singleton to perform feature detection + flux.browser.init(); + + if (!flux.browser.supportsTransitions) { + if (window.console && window.console.error) + console.error("Flux Slider requires a browser that supports CSS3 transitions"); + } + + var _this = this; + + this.element = $(elem); + + // Make a list of all available transitions + this.transitions = []; + for (var fx in flux.transitions) + this.transitions.push(fx); + + this.options = $.extend({ + autoplay: true, + transitions: this.transitions, + delay: 4000, + pagination: true, + controls: false, + captions: false, + width: null, + height: null, + onTransitionEnd: null + }, opts); + + // Set the height/width if given [EXPERIMENTAL!] + this.height = this.options.height ? this.options.height : null; + this.width = this.options.width ? this.options.width : null; + + // Filter out non compatible transitions + var newTrans = []; + $(this.options.transitions).each(function (index, tran) { + var t = new flux.transitions[tran](this), + compatible = true; + + if (t.options.requires3d && !flux.browser.supports3d) + compatible = false; + + if (t.options.compatibilityCheck) + compatible = t.options.compatibilityCheck(); + + if (compatible) + newTrans.push(tran); + }); + + this.options.transitions = newTrans; + + this.images = []; + this.imageLoadedCount = 0; + this.currentImageIndex = 0; + this.nextImageIndex = 1; + this.playing = false; + this.isTransition = false; + + this.container = $('
').appendTo(this.element); + + this.surface = $('
').appendTo(this.container); + + // Listen for click events as we may want to follow a link + this.container.bind('click', function (event) { + if ($(event.target).hasClass('hasLink')) + window.location = $(event.target).data('href'); + }); + + this.imageContainer = $('
').css({ + 'position': 'relative', + 'overflow': 'hidden', + 'min-height': '100px', + 'background-repeat': 'no-repeat', + }).appendTo(this.surface); + + // If the height/width is already set then resize the container + if (this.width && this.height) { + this.imageContainer.css({ + width: this.width + 'px', + height: this.height + 'px' + }); + } + + // Create the placeholders for the current and next image + this.image1 = $('
').appendTo(this.imageContainer); + this.image2 = $('
').appendTo(this.imageContainer); + + $(this.image1).add(this.image2).css({ + 'position': 'absolute', + 'top': '0px', + 'left': '0px' + }); + + // Get a list of the images to use + this.element.find('img, a img').each(function (index, found_img) { + var imgClone = found_img.cloneNode(false), + link = $(found_img).parent(); + + // If this img is directly inside a link then save the link for later use + if (link.is('a')) + $(imgClone).data('href', link.attr('href')); + + _this.images.push(imgClone); + + // Remove the images from the DOM + $(found_img).remove(); + }); + + // Load the images afterwards as IE seems to load images synchronously + for (var i = 0; i < this.images.length; i++) { + var image = new Image(); + image.onload = function () { + _this.imageLoadedCount++; + + _this.width = _this.width ? _this.width : this.width; + _this.height = _this.height ? _this.height : this.height; + + if (_this.imageLoadedCount >= _this.images.length) { + _this.finishedLoading(); + _this.setupImages(); + } + }; + + // Load the image to ensure its cached by the browser + image.src = this.images[i].src; + } + + // Catch when a transition has finished + this.element.bind('fluxTransitionEnd', function (event, data) { + // If the slider is currently playing then set the timeout for the next transition + // if(_this.isPlaying()) + // _this.start(); + + // Are we using a callback instead of events for notifying about transition ends? + if (_this.options.onTransitionEnd) { + event.preventDefault(); + + _this.options.onTransitionEnd(data); + } + }); + + // Should we auto start the slider? + if (this.options.autoplay) + this.start(); + + // Handle swipes + /* this.element.bind('swipeLeft', function(event){ + _this.next(null, {direction: 'left'}); + }).bind('swipeRight', function(event){ + _this.prev(null, {direction: 'right'}); + }); */ + + // Under FF7 autoplay breaks when the current tab loses focus + setTimeout(function () { + $(window).focus(function () { + if (_this.isPlaying()) + _this.next(); + }); + }, 100); + }; + + flux.slider.prototype = { + constructor: flux.slider, + playing: false, + start: function () { + var _this = this; + this.playing = true; + this.interval = setInterval(function () { + _this.transition(); + }, this.options.delay); + }, + stop: function () { + this.playing = false; + clearInterval(this.interval); + this.interval = null; + }, + isPlaying: function () { + return this.playing; + //return this.interval != null; + }, + setSize(w, h) { + this.width = w; + this.height = h; + this.options.width = w; + this.options.height = h; + this.container.css({"width": w + "px", "height": h + "px"}); + this.imageContainer.css({"width": w + "px", "height": h + "px"}); + this.image1.css({"width": w + "px", "height": h + "px"}); + this.image2.css({"width": w + "px", "height": h + "px"}); + this.setupImages(); + }, + next: function (trans, opts) { + opts = opts || {}; + opts.direction = 'left'; + this.showImage(this.currentImageIndex + 1, trans, opts); + }, + + prev: function (trans, opts) { + opts = opts || {}; + opts.direction = 'right'; + this.showImage(this.currentImageIndex - 1, trans, opts); + }, + transitionPlaying: function () { + return this.isTransition; + }, + showImage: function (index, trans, opts) { + this.setNextIndex(index); + + // Temporarily stop the transition interval + //clearInterval(this.interval); + //this.interval = null; + + this.setupImages(); + this.transition(trans, opts); + }, + showImageById: function (id, trans, opts) { + let i = 0; + for (var img of this.images) { + if (img.id === id) { + this.showImage(i, trans, opts); + break; + } + i++; + } + this.clearTempImages(); + }, + showTempImage: function (id, trans, opts) { + let i = 0; + for (var img of this.images) { + if (img.class === "temp" && img.id === id) { + this.showImage(i, trans, opts); + break; + } + i++; + } + }, + clearImages: function () { + this.images = []; + }, + clearTempImages: function () { + let newImages = []; + for (var i in this.images) { + if (this.images[i].class !== "temp") { + newImages.push(this.images[i]); + } else { + delete this.images[i]; + console.log("cleared temp"); + } + } + this.images = newImages; + }, + clearImageById: function (id) { + let newImages = []; + for (var i in this.images) { + if (this.images[i].id !== id) { + newImages.push(this.images[i]); + } else { + console.log("cleared image by id: " + id); + delete this.images[i]; + } + } + this.images = newImages; + }, + finishedLoading: function () { + var _this = this; + + this.container.css({ + width: this.width + 'px', + height: this.height + 'px' + }); + + this.imageContainer.removeClass('loading'); + + // Should we setup a pagination view? + if (this.options.pagination) { + // TODO: Attach to touch events if appropriate + this.pagination = $('
    ').css({ + margin: '0px', + padding: '0px', + 'text-align': 'center' + }); + + this.pagination.bind('click', function (event) { + event.preventDefault(); + _this.showImage($(event.target).data('index')); + }); + + $(this.images).each(function (index, image) { + var li = $('
  • ' + (index + 1) + '
  • ').css({ + display: 'inline-block', + 'margin-left': '0.5em', + 'cursor': 'pointer' + }).appendTo(_this.pagination); + + if (index == 0) + li.css('margin-left', 0).addClass('current'); + }); + + this.container.append(this.pagination); + } + + // Resize + $(this.imageContainer).css({ + width: this.width + 'px', + height: this.height + 'px' + }); + + $(this.image1).css({ + width: this.width + 'px', + height: this.height + 'px' + }); + + $(this.image2).css({ + width: this.width + 'px', + height: this.height + 'px' + }); + + this.container.css({ + width: this.width + 'px', + height: this.height + (this.options.pagination ? this.pagination.height() : 0) + 'px' + }); + + // Should we add prev/next controls? + if (this.options.controls) { + var css = { + padding: '4px 10px 10px', + 'font-size': '60px', + 'font-family': 'arial, sans-serif', + 'line-height': '1em', + 'font-weight': 'bold', + color: '#FFF', + 'text-decoration': 'none', + background: 'rgba(0,0,0,0.5)', + position: 'absolute', + 'z-index': 2000 + }; + + this.nextButton = $('»').css(css).css3({ + 'border-radius': '4px' + }).appendTo(this.surface).bind('click', function (event) { + event.preventDefault(); + _this.next(); + }); + + this.prevButton = $('«').css(css).css3({ + 'border-radius': '4px' + }).appendTo(this.surface).bind('click', function (event) { + event.preventDefault(); + _this.prev(); + }); + + var top = (this.height - this.nextButton.height()) / 2; + this.nextButton.css({ + top: top + 'px', + right: '10px' + }); + + this.prevButton.css({ + top: top + 'px', + left: '10px' + }); + } + + // Should we use captions? + if (this.options.captions) { + this.captionBar = $('
    ').css({ + background: 'rgba(0,0,0,0.6)', + color: '#FFF', + 'font-size': '16px', + 'font-family': 'helvetica, arial, sans-serif', + 'text-decoration': 'none', + 'font-weight': 'bold', + padding: '1.5em 1em', + opacity: 0, + position: 'absolute', + 'z-index': 110, + width: '100%', + bottom: 0 + }).css3({ + 'transition-property': 'opacity', + 'transition-duration': '800ms', + 'box-sizing': 'border-box' + }).prependTo(this.surface); + } + + this.updateCaption(); + }, + setupImages: function () { + var img1 = this.getImage(this.currentImageIndex); + css1 = { + 'background-image': 'url("' + img1.src + '")', + 'z-index': 101, + 'cursor': 'auto', + 'background-repeat': 'no-repeat', + 'background-size': this.options.width + "px " + this.options.height + "px" + }; + + // Does this image have an associated link? + if ($(img1).data('href')) { + css1.cursor = 'pointer'; + this.image1.addClass('hasLink'); + this.image1.data('href', $(img1).data('href')); + } + else { + this.image1.removeClass('hasLink'); + this.image1.data('href', null); + } + + this.image1.css(css1).children().remove(); + + this.image2.css({ + 'background-image': 'url("' + this.getImage(this.nextImageIndex).src + '")', + 'z-index': 100, + 'background-repeat': 'no-repeat', + 'background-size': this.options.width + "px " + this.options.height + "px", + }).hide(); + + if (this.options.pagination && this.pagination) { + this.pagination.find('li.current').removeClass('current'); + $(this.pagination.find('li')[this.currentImageIndex]).addClass('current'); + } + }, + transition: function (transition, opts) { + // Allow a transition to be picked from ALL available transitions (not just the reduced set) + if (transition == undefined || !flux.transitions[transition]) { + // Pick a transition at random from the (possibly reduced set of) transitions + var index = Math.floor(Math.random() * (this.options.transitions.length)); + transition = this.options.transitions[index]; + } + + var tran = null; + + try { + tran = new flux.transitions[transition](this, $.extend(this.options[transition] ? this.options[transition] : {}, opts)); + } + catch (e) { + // If an invalid transition has been provided then use the fallback (default is to just switch the image) + tran = new flux.transition(this, {fallback: true}); + } + this.isTransition = true; + tran.run(); + + this.currentImageIndex = this.nextImageIndex; + this.setNextIndex(this.currentImageIndex + 1); + this.updateCaption(); + }, + updateCaption: function () { + var str = $(this.getImage(this.currentImageIndex)).attr('title'); + if (this.options.captions && this.captionBar) { + if (str !== "") + this.captionBar.html(str); + + this.captionBar.css('opacity', str === "" ? 0 : 1); + } + }, + getImage: function (index) { + index = index % this.images.length; + + return this.images[index]; + }, + setNextIndex: function (nextIndex) { + if (nextIndex == undefined) + nextIndex = this.currentImageIndex + 1; + + this.nextImageIndex = nextIndex; + + if (this.nextImageIndex > this.images.length - 1) + this.nextImageIndex = 0; + + if (this.nextImageIndex < 0) + this.nextImageIndex = this.images.length - 1; + }, + increment: function () { + this.currentImageIndex++; + if (this.currentImageIndex > this.images.length - 1) + this.currentImageIndex = 0; + } + }; +})(window.jQuery || window.Zepto); + +/** + * Helper object to determine support for various CSS3 functions + * @author Joe Lambert + */ + +(function ($) { + flux.browser = { + init: function () { + // Have we already been initialised? + if (flux.browser.supportsTransitions !== undefined) + return; + + var div = document.createElement('div'), + prefixes = ['-webkit', '-moz', '-o', '-ms'], + domPrefixes = ['Webkit', 'Moz', 'O', 'Ms']; + + // Does the current browser support CSS Transitions? + if (window.Modernizr && Modernizr.csstransitions !== undefined) + flux.browser.supportsTransitions = Modernizr.csstransitions; + else { + flux.browser.supportsTransitions = this.supportsCSSProperty('Transition'); + } + + // Does the current browser support 3D CSS Transforms? + if (window.Modernizr && Modernizr.csstransforms3d !== undefined) + flux.browser.supports3d = Modernizr.csstransforms3d; + else { + // Custom detection when Modernizr isn't available + flux.browser.supports3d = this.supportsCSSProperty("Perspective"); + + if (flux.browser.supports3d && 'webkitPerspective' in $('body').get(0).style) { + // Double check with a media query (similar to how Modernizr does this) + var div3D = $('
    '); + var mq = $(''); + + $('body').append(div3D); + $('head').append(mq); + + flux.browser.supports3d = div3D.get(0).offsetLeft == 9; + + div3D.remove(); + mq.remove(); + } + } + + }, + supportsCSSProperty: function (prop) { + var div = document.createElement('div'), + prefixes = ['', '-webkit', '-moz', '-o', '-ms'], + domPrefixes = ['', 'Webkit', 'Moz', 'O', 'Ms']; + + var support = false; + for (var i = 0; i < domPrefixes.length; i++) { + if (domPrefixes[i] + prop in div.style) + support = support || true; + } + + return support; + }, + translate: function (x, y, z) { + x = (x != undefined) ? x : 0; + y = (y != undefined) ? y : 0; + z = (z != undefined) ? z : 0; + + return 'translate' + (flux.browser.supports3d ? '3d(' : '(') + x + 'px,' + y + (flux.browser.supports3d ? 'px,' + z + 'px)' : 'px)'); + }, + + rotateX: function (deg) { + return flux.browser.rotate('x', deg); + }, + + rotateY: function (deg) { + return flux.browser.rotate('y', deg); + }, + + rotateZ: function (deg) { + return flux.browser.rotate('z', deg); + }, + + rotate: function (axis, deg) { + if (!axis in {'x': '', 'y': '', 'z': ''}) + axis = 'z'; + + deg = (deg != undefined) ? deg : 0; + + if (flux.browser.supports3d) + return 'rotate3d(' + (axis == 'x' ? '1' : '0') + ', ' + (axis == 'y' ? '1' : '0') + ', ' + (axis == 'z' ? '1' : '0') + ', ' + deg + 'deg)'; + else { + if (axis == 'z') + return 'rotate(' + deg + 'deg)'; + else + return ''; + } + } + }; + + $(function () { + // To continue to work with legacy code, ensure that flux.browser is initialised on document ready at the latest + flux.browser.init(); + }); +})(window.jQuery || window.Zepto); + +(function ($) { + /** + * Helper function for cross-browser CSS3 support, prepends all possible prefixes to all properties passed in + * @param {Object} props Ker/value pairs of CSS3 properties + */ + $.fn.css3 = function (props) { + var css = {}; + var prefixes = ['webkit', 'moz', 'ms', 'o']; + + for (var prop in props) { + // Add the vendor specific versions + for (var i = 0; i < prefixes.length; i++) + css['-' + prefixes[i] + '-' + prop] = props[prop]; + + // Add the actual version + css[prop] = props[prop]; + } + + this.css(css); + return this; + }; + + /** + * Helper function to bind to the correct transition end event + * @param {function} callback The function to call when the event fires + */ + $.fn.transitionEnd = function (callback) { + var _this = this; + + var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd']; + + for (var i = 0; i < events.length; i++) { + this.bind(events[i], function (event) { + // Automatically stop listening for the event + for (var j = 0; j < events.length; j++) + $(this).unbind(events[j]); + + // Perform the callback function + if (callback) + callback.call(this, event); + }); + } + + return this; + }; + + flux.transition = function (fluxslider, opts) { + this.options = $.extend({ + requires3d: false, + after: function () { + // Default callback for after the transition has completed + } + }, opts); + + this.slider = fluxslider; + + // We need to ensure transitions degrade gracefully if the transition is unsupported or not loaded + if ((this.options.requires3d && !flux.browser.supports3d) || !flux.browser.supportsTransitions || this.options.fallback === true) { + var _this = this; + + this.options.after = undefined; + + this.options.setup = function () { + //console.error("Fallback setup()"); + _this.fallbackSetup(); + }; + + this.options.execute = function () { + //console.error("Fallback execute()"); + _this.fallbackExecute(); + }; + } + }; + + flux.transition.prototype = { + constructor: flux.transition, + hasFinished: false, // This is a lock to ensure that the fluxTransitionEnd event is only fired once per tansition + run: function () { + var _this = this; + flux.slider.isTransition = true; + + // do something + if (this.options.setup !== undefined) + this.options.setup.call(this); + + // Remove the background image from the top image + this.slider.image1.css({ + 'background-image': 'none', + + }); + + this.slider.imageContainer.css('overflow', this.options.requires3d ? 'visible' : 'hidden'); + + // For some of the 3D effects using Zepto we need to delay the transitions for some reason + setTimeout(function () { + if (_this.options.execute !== undefined) + _this.options.execute.call(_this); + }, 5); + }, + finished: function () { + if (this.hasFinished) + return; + + this.hasFinished = true; + this.slider.isTransition = false; + if (this.options.after) + this.options.after.call(this); + + this.slider.imageContainer.css('overflow', 'hidden'); + + this.slider.setupImages(); + + // Trigger an event to signal the end of a transition + this.slider.element.trigger('fluxTransitionEnd', { + currentImage: this.slider.getImage(this.slider.currentImageIndex) + }); + }, + fallbackSetup: function () { + + }, + fallbackExecute: function () { + this.finished(); + } + }; + + flux.transitions = {}; + + // Flux grid transition + + flux.transition_grid = function (fluxslider, opts) { + return new flux.transition(fluxslider, $.extend({ + columns: 6, + rows: 6, + forceSquare: false, + setup: function () { + var imgWidth = this.slider.options.width, + imgHeight = this.slider.options.height; + + var colWidth = Math.floor(imgWidth / this.options.columns), + rowHeight = Math.floor(imgHeight / this.options.rows); + + if (this.options.forceSquare) { + rowHeight = colWidth; + this.options.rows = Math.floor(imgHeight / rowHeight); + } + + // Work out how much space remains with the adjusted barWidth + var colRemainder = imgWidth - (this.options.columns * colWidth), + colAddPerLoop = Math.floor(colRemainder / this.options.columns), + + rowRemainder = imgHeight - (this.options.rows * rowHeight), + rowAddPerLoop = Math.floor(rowRemainder / this.options.rows), + + delayBetweenBars = 150, + height = this.slider.options.height; + totalLeft = 0, + totalTop = 0, + fragment = document.createDocumentFragment(); + + for (var i = 0; i < this.options.columns; i++) { + var thisColWidth = colWidth, + totalTop = 0; + + if (colRemainder > 0) { + var add = colRemainder >= colAddPerLoop ? colAddPerLoop : colRemainder; + thisColWidth += add; + colRemainder -= add; + } + + for (var j = 0; j < this.options.rows; j++) { + var thisRowHeight = rowHeight, + thisRowRemainder = rowRemainder; + + if (thisRowRemainder > 0) { + var add = thisRowRemainder >= rowAddPerLoop ? rowAddPerLoop : thisRowRemainder; + thisRowHeight += add; + thisRowRemainder -= add; + } + + var tile = $('
    ').css({ + width: thisColWidth + 'px', + height: thisRowHeight + 'px', + position: 'absolute', + top: totalTop + 'px', + left: totalLeft + 'px' + }); + + this.options.renderTile.call(this, tile, i, j, thisColWidth, thisRowHeight, totalLeft, totalTop); + + fragment.appendChild(tile.get(0)); + + totalTop += thisRowHeight; + } + + totalLeft += thisColWidth; + } + + // Append the fragement to the surface + this.slider.image1.get(0).appendChild(fragment); + }, + execute: function () { + var _this = this, + height = this.slider.options.height, + bars = this.slider.image1.find('div.barcontainer'); + + this.slider.image2.hide(); + + // Get notified when the last transition has completed + bars.last().transitionEnd(function (event) { + _this.slider.image2.show(); + + _this.finished(); + }); + + bars.css3({ + 'transform': flux.browser.rotateX(-90) + ' ' + flux.browser.translate(0, height / 2, height / 2) + }); + }, + renderTile: function (elem, colIndex, rowIndex, colWidth, rowHeight, leftOffset, topOffset) { + + } + }, opts)); + }; +})(window.jQuery || window.Zepto); + +(function ($) { + flux.transitions.bars = function (fluxslider, opts) { + return new flux.transition_grid(fluxslider, $.extend({ + columns: 10, + rows: 1, + delayBetweenBars: 40, + renderTile: function (elem, colIndex, rowIndex, colWidth, rowHeight, leftOffset, topOffset) { + $(elem).css({ + 'background-image': this.slider.image1.css('background-image'), + 'background-position': '-' + leftOffset + 'px 0px', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px", + }).css3({ + 'transition-duration': '400ms', + 'transition-timing-function': 'ease-in', + 'transition-property': 'all', + 'transition-delay': (colIndex * this.options.delayBetweenBars) + 'ms' + }); + }, + execute: function () { + var _this = this; + + var height = this.slider.options.height; + + var bars = this.slider.image1.find('div.tile'); + + // Get notified when the last transition has completed + $(bars[bars.length - 1]).transitionEnd(function () { + _this.finished(); + }); + + setTimeout(function () { + bars.css({ + 'opacity': '0.5' + }).css3({ + 'transform': flux.browser.translate(0, height) + }); + }, 50); + + } + }, opts)); + }; +})(window.jQuery || window.Zepto); +/* +(function ($) { + flux.transitions.bars3d = function (fluxslider, opts) { + return new flux.transition_grid(fluxslider, $.extend({ + requires3d: true, + columns: 7, + rows: 1, + delayBetweenBars: 150, + perspective: 1000, + renderTile: function (elem, colIndex, rowIndex, colWidth, rowHeight, leftOffset, topOffset) { + var bar = $('
    ').css({ + width: colWidth + 'px', + height: this.slider.options.height + "px", + position: 'absolute', + top: '0px', + left: '0px', + 'z-index': 200, + 'background-image': this.slider.image1.css('background-image'), + 'background-position': '-' + leftOffset + 'px 0px', + 'background-repeat': 'no-repeat', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px ", + }).css3({ + 'backface-visibility': 'hidden' + }), + + bar2 = $(bar.get(0).cloneNode(false)).css({ + 'background-image': this.slider.image2.css('background-image'), + 'background-repeat': 'no-repeat', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px ", + }).css3({ + 'transform': flux.browser.rotateX(90) + ' ' + flux.browser.translate(0, -rowHeight / 2, rowHeight / 2) + }), + + left = $('
    ').css({ + width: rowHeight + 'px', + height: rowHeight + 'px', + position: 'absolute', + top: '0px', + left: '0px', + background: '#222', + 'z-index': 190 + }).css3({ + 'transform': flux.browser.rotateY(90) + ' ' + flux.browser.translate(rowHeight / 2, 0, -rowHeight / 2) + ' ' + flux.browser.rotateY(180), + 'backface-visibility': 'hidden' + }), + + right = $(left.get(0).cloneNode(false)).css3({ + 'transform': flux.browser.rotateY(90) + ' ' + flux.browser.translate(rowHeight / 2, 0, colWidth - rowHeight / 2) + }); + + $(elem).css({ + width: colWidth + 'px', + height: this.slider.options.height + "px", + position: 'absolute', + top: '0px', + left: leftOffset + 'px', + 'z-index': colIndex > this.options.columns / 2 ? 1000 - colIndex : 1000 // Fix for Chrome to ensure that the z-index layering is correct! + }).css3({ + 'transition-duration': '800ms', + 'transition-timing-function': 'linear', + 'transition-property': 'all', + 'transition-delay': (colIndex * this.options.delayBetweenBars) + 'ms', + 'transform-style': 'preserve-3d' + }).append(bar).append(bar2).append(left).append(right); + }, + execute: function () { + this.slider.image1.css3({ + 'perspective': this.options.perspective, + 'perspective-origin': '50% 50%' + }).css({ + '-moz-transform': 'perspective(' + this.options.perspective + 'px)', + '-moz-perspective': 'none', + '-moz-transform-style': 'preserve-3d' + }); + + var _this = this, + height = this.slider.options.height, + bars = this.slider.image1.find('div.tile'); + + this.slider.image2.hide(); + + // Get notified when the last transition has completed + bars.last().transitionEnd(function (event) { + _this.slider.image1.css3({ + 'transform-style': 'flat' + }); + + _this.slider.image2.show(); + + _this.finished(); + }); + + setTimeout(function () { + bars.css3({ + 'transform': flux.browser.rotateX(-90) + ' ' + flux.browser.translate(0, height / 2, height / 2) + }); + }, 50); + } + }, opts)); + }; +})(window.jQuery || window.Zepto); +*/ + +(function ($) { + flux.transitions.blinds = function (fluxslider, opts) { + return new flux.transitions.bars(fluxslider, $.extend({ + execute: function () { + var _this = this; + + var height = this.slider.options.height; + + var bars = this.slider.image1.find('div.tile'); + + // Get notified when the last transition has completed + $(bars[bars.length - 1]).transitionEnd(function () { + _this.finished(); + }); + + setTimeout(function () { + bars.css({ + 'opacity': '0.5' + }).css3({ + 'transform': 'scalex(0.0001)' + }); + }, 50); + } + }, opts)); + } +})(window.jQuery || window.Zepto); + +(function ($) { + flux.transitions.blinds3d = function (fluxslider, opts) { + return new flux.transitions.tiles3d(fluxslider, $.extend({ + forceSquare: false, + rows: 1, + columns: 6 + }, opts)); + }; +})(window.jQuery || window.Zepto); + +(function ($) { + flux.transitions.zip = function (fluxslider, opts) { + return new flux.transitions.bars(fluxslider, $.extend({ + execute: function () { + var _this = this; + + var height = this.slider.options.height; + + var bars = this.slider.image1.find('div.tile'); + + // Get notified when the last transition has completed + $(bars[bars.length - 1]).transitionEnd(function () { + _this.finished(); + }); + + setTimeout(function () { + bars.each(function (index, bar) { + $(bar).css({ + 'opacity': '0.3' + }).css3({ + 'transform': flux.browser.translate(0, (index % 2 ? '-' + (2 * height) : height)) + }); + }); + }, 20); + } + }, opts)); + }; +})(window.jQuery || window.Zepto); + +(function ($) { + flux.transitions.blocks = function (fluxslider, opts) { + return new flux.transition_grid(fluxslider, $.extend({ + forceSquare: true, + delayBetweenBars: 100, + renderTile: function (elem, colIndex, rowIndex, colWidth, rowHeight, leftOffset, topOffset) { + var delay = Math.floor(Math.random() * 10 * this.options.delayBetweenBars); + + $(elem).css({ + 'background-image': this.slider.image1.css('background-image'), + 'background-position': '-' + leftOffset + 'px -' + topOffset + 'px', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px" + }).css3({ + 'transition-duration': '350ms', + 'transition-timing-function': 'ease-in', + 'transition-property': 'all', + 'transition-delay': delay + 'ms' + }); + + // Keep track of the last elem to fire + if (this.maxDelay === undefined) + this.maxDelay = 0; + + if (delay > this.maxDelay) { + this.maxDelay = delay; + this.maxDelayTile = elem; + } + }, + execute: function () { + var _this = this; + + var blocks = this.slider.image1.find('div.tile'); + + // Get notified when the last transition has completed + this.maxDelayTile.transitionEnd(function () { + _this.finished(); + }); + + setTimeout(function () { + blocks.each(function (index, block) { + $(block).css({ + 'opacity': '0' + }).css3({ + 'transform': 'scale(0.8)' + }); + }); + }, 50); + } + }, opts)); + }; +})(window.jQuery || window.Zepto); + +(function ($) { + flux.transitions.blocks2 = function (fluxslider, opts) { + return new flux.transition_grid(fluxslider, $.extend({ + cols: 12, + forceSquare: true, + delayBetweenDiagnols: 150, + renderTile: function (elem, colIndex, rowIndex, colWidth, rowHeight, leftOffset, topOffset) { + var delay = Math.floor(Math.random() * 10 * this.options.delayBetweenBars); + + $(elem).css({ + 'background-image': this.slider.image1.css('background-image'), + 'background-position': '-' + leftOffset + 'px -' + topOffset + 'px', + 'background-repeat': 'no-repeat', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px", + }).css3({ + 'transition-duration': '350ms', + 'transition-timing-function': 'ease-in', + 'transition-property': 'all', + 'transition-delay': (colIndex + rowIndex) * this.options.delayBetweenDiagnols + 'ms', + 'backface-visibility': 'hidden' // trigger hardware acceleration + }); + }, + execute: function () { + var _this = this; + + var blocks = this.slider.image1.find('div.tile'); + + // Get notified when the last transition has completed + blocks.last().transitionEnd(function () { + _this.finished(); + }); + + setTimeout(function () { + blocks.each(function (index, block) { + $(block).css({ + 'opacity': '0' + }).css3({ + 'transform': 'scale(0.8)' + }); + }); + }, 50); + } + }, opts)); + }; +})(window.jQuery || window.Zepto); + +(function ($) { + flux.transitions.concentric = function (fluxslider, opts) { + return new flux.transition(fluxslider, $.extend({ + blockSize: 60, + delay: 150, + alternate: false, + setup: function () { + var w = this.slider.options.width, + h = this.slider.options.height, + largestLength = Math.sqrt(w * w + h * h), // Largest length is the diagonal + + // How many blocks do we need? + blockCount = Math.ceil(((largestLength - this.options.blockSize) / 2) / this.options.blockSize) + 1, // 1 extra to account for the round border + fragment = document.createDocumentFragment(); + + for (var i = 0; i < blockCount; i++) { + var thisBlockSize = (2 * i * this.options.blockSize) + this.options.blockSize; + + var block = $('
    ').attr('class', 'block block-' + i).css({ + width: thisBlockSize + 'px', + height: thisBlockSize + 'px', + position: 'absolute', + top: ((h - thisBlockSize) / 2) + 'px', + left: ((w - thisBlockSize) / 2) + 'px', + 'z-index': 100 + (blockCount - i), + 'background-image': this.slider.image1.css('background-image'), + 'background-position': 'center center', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px ", + }).css3({ + 'border-radius': thisBlockSize + 'px', + 'transition-duration': '800ms', + 'transition-timing-function': 'linear', + 'transition-property': 'all', + 'transition-delay': ((blockCount - i) * this.options.delay) + 'ms' + }); + + fragment.appendChild(block.get(0)); + } + + //this.slider.image1.append($(fragment)); + this.slider.image1.get(0).appendChild(fragment); + }, + execute: function () { + var _this = this; + + var blocks = this.slider.image1.find('div.block'); + + // Get notified when the last transition has completed + $(blocks[0]).transitionEnd(function () { + _this.finished(); + }); + + setTimeout(function () { + blocks.each(function (index, block) { + $(block).css({ + 'opacity': '0' + }).css3({ + 'transform': flux.browser.rotateZ((!_this.options.alternate || index % 2 ? '' : '-') + '90') + }); + }); + }, 50); + } + }, opts)); + }; +})(window.jQuery || window.Zepto); + +(function ($) { + flux.transitions.warp = function (fluxslider, opts) { + return new flux.transitions.concentric(fluxslider, $.extend({ + delay: 30, + alternate: true + }, opts)); + }; +})(window.jQuery || window.Zepto); + +(function ($) { + flux.transitions.cube = function (fluxslider, opts) { + return new flux.transition(fluxslider, $.extend({ + requires3d: true, + barWidth: 100, + direction: 'left', + perspective: 1000, + setup: function () { + var width = this.slider.options.width; + var height = this.slider.options.height; + + // Setup the container to allow 3D perspective + + this.slider.image1.css3({ + 'perspective': this.options.perspective, + 'perspective-origin': '50% 50%' + }); + + this.cubeContainer = $('
    ').css({ + width: width + 'px', + height: height + 'px', + position: 'relative' + }).css3({ + 'transition-duration': '800ms', + 'transition-timing-function': 'linear', + 'transition-property': 'all', + 'transform-style': 'preserve-3d' + }); + + var css = { + height: this.slider.options.height + "px", + width: this.slider.options.width + "px", + position: 'absolute', + top: '0px', + left: '0px' + }; + + var currentFace = $('
    ').css($.extend(css, { + background: this.slider.image1.css('background-image'), + 'background-repeat': 'no-repeat', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px", + })).css3({ + 'backface-visibility': 'hidden' + }); + + this.cubeContainer.append(currentFace); + + var nextFace = $('').css($.extend(css, { + background: this.slider.image2.css('background-image'), + 'background-repeat': 'no-repeat', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px", + })).css3({ + 'transform': this.options.transitionStrings.call(this, this.options.direction, 'nextFace'), + 'backface-visibility': 'hidden' + }); + + this.cubeContainer.append(nextFace); + + this.slider.image1.append(this.cubeContainer); + }, + execute: function () { + var _this = this; + + var width = this.slider.options.width; + var height = this.slider.options.height; + + this.slider.image2.hide(); + this.cubeContainer.transitionEnd(function () { + _this.slider.image2.show(); + + _this.finished(); + }); + + setTimeout(function () { + _this.cubeContainer.css3({ + 'transform': _this.options.transitionStrings.call(_this, _this.options.direction, 'container') + }); + }, 50); + }, + transitionStrings: function (direction, elem) { + var width = this.slider.options.width; + var height = this.slider.options.height; + + // Define the various transforms that are required to perform various cube rotations + var t = { + 'up': { + 'nextFace': flux.browser.rotateX(-90) + ' ' + flux.browser.translate(0, height / 2, height / 2), + 'container': flux.browser.rotateX(90) + ' ' + flux.browser.translate(0, -height / 2, height / 2) + }, + 'down': { + 'nextFace': flux.browser.rotateX(90) + ' ' + flux.browser.translate(0, -height / 2, height / 2), + 'container': flux.browser.rotateX(-90) + ' ' + flux.browser.translate(0, height / 2, height / 2) + }, + 'left': { + 'nextFace': flux.browser.rotateY(90) + ' ' + flux.browser.translate(width / 2, 0, width / 2), + 'container': flux.browser.rotateY(-90) + ' ' + flux.browser.translate(-width / 2, 0, width / 2) + }, + 'right': { + 'nextFace': flux.browser.rotateY(-90) + ' ' + flux.browser.translate(-width / 2, 0, width / 2), + 'container': flux.browser.rotateY(90) + ' ' + flux.browser.translate(width / 2, 0, width / 2) + } + }; + + return (t[direction] && t[direction][elem]) ? t[direction][elem] : false; + } + }, opts)); + }; +})(window.jQuery || window.Zepto); + +(function ($) { + flux.transitions.tiles3d = function (fluxslider, opts) { + return new flux.transition_grid(fluxslider, $.extend({ + requires3d: true, + forceSquare: false, + columns: 6, + rows: 4, + perspective: 600, + delayBetweenBarsX: 200, + delayBetweenBarsY: 150, + renderTile: function (elem, colIndex, rowIndex, colWidth, rowHeight, leftOffset, topOffset) { + var tile = $('
    ').css({ + width: colWidth + 'px', + height: rowHeight + 'px', + position: 'absolute', + top: '0px', + left: '0px', + //'z-index': 200, // Removed to make compatible with FF10 (Chrome bug seems to have been fixed) + + 'background-image': this.slider.image1.css('background-image'), + 'background-position': '-' + leftOffset + 'px -' + topOffset + 'px', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px", + + + }).css3({ + 'backface-visibility': 'hidden' + }); + + var tile2 = $(tile.get(0).cloneNode(false)).css({ + 'background-image': this.slider.image2.css('background-image'), + + //'z-index': 190 // Removed to make compatible with FF10 (Chrome bug seems to have been fixed) + }).css3({ + + 'transform': flux.browser.rotateY(180), + 'backface-visibility': 'hidden' + }); + + $(elem).css({ + 'z-index': (colIndex > this.options.columns / 2 ? 500 - colIndex : 500) + (rowIndex > this.options.rows / 2 ? 500 - rowIndex : 500), // Fix for Chrome to ensure that the z-index layering is correct! + + }).css3({ + 'transition-duration': '800ms', + 'transition-timing-function': 'ease-out', + 'transition-property': 'all', + 'transition-delay': (colIndex * this.options.delayBetweenBarsX + rowIndex * this.options.delayBetweenBarsY) + 'ms', + 'transform-style': 'preserve-3d' + }).append(tile).append(tile2); + + }, + execute: function () { + this.slider.image1.css3({ + 'perspective': this.options.perspective, + 'perspective-origin': '50% 50%' + }); + + var _this = this; + + var tiles = this.slider.image1.find('div.tile'); + + this.slider.image2.hide(); + + // Get notified when the last transition has completed + tiles.last().transitionEnd(function (event) { + _this.slider.image2.show(); + _this.finished(); + }); + + setTimeout(function () { + tiles.css3({ + 'transform': flux.browser.rotateY(180) + }); + }, 50); + } + }, opts)); + }; +})(window.jQuery || window.Zepto); + +(function ($) { + flux.transitions.tiles3dprev = function (fluxslider, opts) { + return new flux.transition_grid(fluxslider, $.extend({ + requires3d: true, + forceSquare: false, + columns: 6, + rows: 4, + perspective: 600, + delayBetweenBarsX: 200, + delayBetweenBarsY: 150, + renderTile: function (elem, colIndex, rowIndex, colWidth, rowHeight, leftOffset, topOffset) { + var tile = $('
    ').css({ + width: colWidth + 'px', + height: rowHeight + 'px', + position: 'absolute', + top: '0px', + left: '0px', + //'z-index': 200, // Removed to make compatible with FF10 (Chrome bug seems to have been fixed) + + 'background-image': this.slider.image1.css('background-image'), + 'background-position': '-' + leftOffset + 'px -' + topOffset + 'px', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px", + + + }).css3({ + 'backface-visibility': 'hidden' + }); + + var tile2 = $(tile.get(0).cloneNode(false)).css({ + 'background-image': this.slider.image2.css('background-image'), + + //'z-index': 190 // Removed to make compatible with FF10 (Chrome bug seems to have been fixed) + }).css3({ + + 'transform': flux.browser.rotateY(180), + 'backface-visibility': 'hidden' + }); + + $(elem).css({ + 'z-index': (colIndex > this.options.columns / 2 ? 500 - colIndex : 500) + (rowIndex > this.options.rows / 2 ? 500 - rowIndex : 500), // Fix for Chrome to ensure that the z-index layering is correct! + + }).css3({ + 'transition-duration': '800ms', + 'transition-timing-function': 'ease-out', + 'transition-property': 'all', + 'transition-delay': ((this.options.columns - 1 - colIndex) * this.options.delayBetweenBarsX + (this.options.rows - 1 - rowIndex) * this.options.delayBetweenBarsY) + 'ms', + 'transform-style': 'preserve-3d' + }).append(tile).append(tile2); + }, + execute: function () { + this.slider.image1.css3({ + 'perspective': this.options.perspective, + 'perspective-origin': '50% 50%' + }); + + var _this = this; + + var tiles = this.slider.image1.find('div.tile'); + + this.slider.image2.hide(); + + // Get notified when the last transition has completed + tiles.first().transitionEnd(function (event) { + _this.slider.image2.show(); + _this.finished(); + }); + + setTimeout(function () { + tiles.css3({ + 'transform': flux.browser.rotateY(-180) + }); + }, 50); + } + }, opts)); + }; +})(window.jQuery || window.Zepto); +/* (function ($) { + flux.transitions.turn = function (fluxslider, opts) { + return new flux.transition(fluxslider, $.extend({ + requires3d: true, + perspective: 1300, + direction: 'left', + setup: function () { + var tab = $('
    ').css({ + width: '50%', + height: '100%', + position: 'absolute', + top: '0px', + left: this.options.direction == 'left' ? '50%' : '0%', + 'z-index': 101, + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px" + }).css3({ + 'transform-style': 'preserve-3d', + 'transition-duration': '1000ms', + 'transition-timing-function': 'ease-out', + 'transition-property': 'all', + 'transform-origin': this.options.direction == 'left' ? 'left center' : 'right center' + }), + + front = $('
    ').appendTo(tab).css({ + 'background-image': this.slider.image1.css('background-image'), + 'background-position': (this.options.direction == 'left' ? '-' + (this.slider.options.width / 2) : 0) + 'px 0', + width: "100%", + height: "100%", + position: 'absolute', + top: '0', + left: '0', + '-moz-transform': 'translateZ(1px)', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px", + + }).css3({ + 'backface-visibility': 'hidden' + }), + + back = $('
    ').appendTo(tab).css({ + 'background-image': this.slider.image2.css('background-image'), + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px", + 'background-position': (this.options.direction == 'left' ? 0 : '-' + (this.slider.options.width / 2)) + 'px 0', + width: '100%', + height: '100%', + position: 'absolute', + top: '0', + left: '0' + }).css3({ + transform: flux.browser.rotateY(180), + 'backface-visibility': 'hidden' + }), + + current = $('
    ').css({ + position: 'absolute', + top: '0', + left: this.options.direction == 'left' ? '0' : '50%', + width: '50%', + height: '100%', + 'background-image': this.slider.image1.css('background-image'), + 'background-position': (this.options.direction == 'left' ? 0 : '-' + (this.slider.options.width / 2)) + 'px 0', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px", + 'z-index': 100 + }), + + overlay = $('
    ').css({ + position: 'absolute', + top: '0', + left: this.options.direction == 'left' ? '50%' : '0', + width: '50%', + height: '100%', + background: '#000', + opacity: 1, + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px", + }).css3({ + 'transition-duration': '800ms', + 'transition-timing-function': 'linear', + 'transition-property': 'opacity' + }), + + container = $('
    ').css3({ + width: '100%', + height: '100%', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px", + }).css3({ + 'perspective': this.options.perspective, + 'perspective-origin': '50% 50%' + }).append(tab).append(current).append(overlay); + + this.slider.image1.append(container); + }, + execute: function () { + var _this = this; + + this.slider.image1.find('div.tab').first().transitionEnd(function () { + _this.finished(); + }); + + setTimeout(function () { + _this.slider.image1.find('div.tab').css3({ + // 179 not 180 so that the tab rotates the correct way in Firefox + transform: flux.browser.rotateY(_this.options.direction == 'left' ? -179 : 179) + }); + _this.slider.image1.find('div.overlay').css({ + opacity: 0 + }); + }, 50); + } + }, opts)); + }; +})(window.jQuery || window.Zepto); +*/ + +(function ($) { + flux.transitions.slide = function (fluxslider, opts) { + return new flux.transition(fluxslider, $.extend({ + direction: 'left', + setup: function () { + var width = this.slider.options.width, + height = this.slider.options.height, + + currentImage = $('
    ').css({ + height: height + 'px', + width: width + 'px', + position: 'absolute', + top: '0px', + left: '0px', + background: this.slider[this.options.direction == 'left' ? 'image1' : 'image2'].css('background-image'), + 'background-repeat': 'no-repeat', + 'background-size': 'cover' + }).css3({ + 'backface-visibility': 'hidden' + }), + + nextImage = $('').css({ + height: height + 'px', + width: width + 'px', + position: 'absolute', + top: '0px', + left: width + 'px', + background: this.slider[this.options.direction == 'left' ? 'image2' : 'image1'].css('background-image'), + 'background-repeat': 'no-repeat', + 'background-size': 'cover' + }).css3({ + 'backface-visibility': 'hidden' + }); + + this.slideContainer = $('
    ').css({ + width: (2 * width) + 'px', + height: height + 'px', + position: 'relative', + left: this.options.direction == 'left' ? '0px' : -width + 'px', + 'z-index': 101, + 'background-repeat': 'no-repeat' + }).css3({ + 'transition-duration': '600ms', + 'transition-timing-function': 'ease-in', + 'transition-property': 'all' + }); + + this.slideContainer.append(currentImage).append(nextImage); + + this.slider.image1.append(this.slideContainer); + }, + execute: function () { + var _this = this, + delta = this.slider.options.width; + + if (this.options.direction == 'left') + delta = -delta; + + this.slideContainer.transitionEnd(function () { + _this.finished(); + }); + + setTimeout(function () { + _this.slideContainer.css3({ + 'transform': flux.browser.translate(delta) + }); + }, 50); + } + }, opts)); + }; +})(window.jQuery || window.Zepto); + +(function ($) { + flux.transitions.swipe = function (fluxslider, opts) { + return new flux.transition(fluxslider, $.extend({ + setup: function () { + var svgmask = $('' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + ''); + var img = $('
    ').css({ + width: this.slider.options.width + "px ", + height: this.slider.options.height + "px ", + 'background-image': this.slider.image1.css('background-image'), + 'background-repeat': 'no-repeat', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px", + }).css3({ + 'transition-duration': '1600ms', + 'transition-timing-function': 'ease-in', + 'transition-property': 'all', + 'mask-image': '-webkit-linear-gradient(left, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 48%, rgba(0,0,0,1) 52%, rgba(0,0,0,1) 100%)', + 'mask-position': '70%', + 'mask-size': '400%' + }); + + this.slider.image1.append(img); + this.slider.image1.append(svgmask); + }, + execute: function () { + //return; + var _this = this, + img = this.slider.image1.find('div'); + + // Get notified when the last transition has completed + $(img).transitionEnd(function () { + _this.finished(); + }).get()[0].addEventListener('end', function () { + _this.finished(); + }, false); + + setTimeout(function () { + if (flux.browser.supportsCSSProperty('MaskImage')) { + $(img).css3({ + 'mask-position': '30%' + }); + } else if (flux.browser.supportsCSSProperty('mask')) { + $(img).css3({ + 'mask': 'url(#myMask)' + }); + } + }, 50); + }, + compatibilityCheck: function () { + return flux.browser.supportsCSSProperty('MaskImage') || + flux.browser.supportsCSSProperty('mask'); + } + }, opts)); + }; +})(window.jQuery || window.Zepto); + +(function ($) { + flux.transitions.dissolve = function (fluxslider, opts) { + return new flux.transition(fluxslider, $.extend({ + setup: function () { + var img = $('
    ').css({ + width: '100%', + height: '100%', + 'background-image': this.slider.image1.css('background-image'), + 'background-repeat': 'no-repeat', + 'background-size': this.slider.options.width + "px " + this.slider.options.height + "px", + }).css3({ + 'transition-duration': '600ms', + 'transition-timing-function': 'ease-in', + 'transition-property': 'opacity' + }); + + this.slider.image1.append(img); + }, + execute: function () { + var _this = this, + img = this.slider.image1.find('div.image'); + + // Get notified when the last transition has completed + $(img).transitionEnd(function () { + _this.finished(); + }); + + setTimeout(function () { + $(img).css({ + 'opacity': '0.0' + }); + }, 50); + } + }, opts)); + }; +})(window.jQuery || window.Zepto); + diff --git a/public/js/preview.js b/public/js/preview.js new file mode 100644 index 0000000..ae7f8a9 --- /dev/null +++ b/public/js/preview.js @@ -0,0 +1,175 @@ +/** fabric **/ +var canvas; +var displayId = 0; + +/** bundleData + * @see data/default/bundle.json + * + **/ +var bundleData; +bundleData = { + background: "", + duration: 10, + styleHeader: {}, + styleText: {}, + useWebFonts: false +}; +/** displayGroup + * contains displayed slide items + */ +var displayGroup; +displayGroup = []; + +/** background image **/ +var bgImage; + +/*************************** + * window load, init + * **************************/ +$(function () { + canvas = new fabric.StaticCanvas('c'); + canvas.backgroundColor = null; + canvas.backgroundImage = null; + canvas.renderAll(); + var ctx = canvas.getContext("2d"); + if (ctx) { + ctx.translate(0.5, 0.5); + } + fixCanvas(); + + /* $(document).mouseenter(function () { + $('.ui.basic.modal') + .modal('show') + ; + }); + + $(document).mouseleave(function () { + $('.ui.basic.modal') + .modal('hide') + ; + }); + */ + +}); + +$(window).bind("resize", function () { + fixCanvas(); +}); + +// socketio callbacks +/** when connected **/ +socket.on('connect', function () { + socket.emit("sync.preview", socketId); +}); + +/** callback Load **/ +socket.on('callback.preview', function (data) { + canvas.clear(); + displayId = data.displayId; + + if (data.bundleData.useWebFonts) { + if (bundleData.styleHeader.fontFamily != data.bundleData.styleHeader.fontFamily || bundleData.styleText.fontFamily != data.bundleData.styleText.fontFamily) { + WebFont.load({ + google: { + families: [data.bundleData.styleHeader.fontFamily, data.bundleData.styleText.fontFamily] + }, + timeout: 2000, + active: function () { + + nextSlide(data); + }, + inactive: function () { + + nextSlide(data); + } + }); + } else { + nextSlide(data); + } + } else { + nextSlide(data); + } + + bundleData = data.bundleData; + serverOptions = data.serverOptions; + + displayGroup = new fabric.Group(); + + setBackground(bundleData.background); +}); + + +function setBackground(background) { + background = "/background/" + bundleData.bundleName + "/" + background; + + var video = document.getElementById("bgvid"); + var bg = $("#bg"); + var bgImage = document.getElementById("bgimg"); + if (background.indexOf(".mp4") !== -1) { + if (parseUrl(video.src) !== background) { + bg.hide(); + $(video).show(); + video.src = background; + video.play(); + } + } else { + if (parseUrl(bgImage.src) !== background) { + bgImage.src = background; + bg.show(); + $(video).hide(); + video.pause(); + video.src = ""; + } + } +} + +function parseUrl(url) { + return '/background' + url.split('background')[1] +} + + +/** resize canvas to max width keeping aspect ratio 16:9**/ +function fixCanvas() { + var con = $(window), + aspect = (0.9 / 1.6), + width = con.innerWidth(), + height = Math.floor(width * aspect); + + canvas.setWidth(1280).setHeight(720); + $("#c").css("width", width + "px").css("height", height + "px"); + canvas.calcOffset(); +} + +function override() { + var obj = canvas.toJSON(['id']); + var video = document.getElementById("bgvid"); + var bg = ""; + if (video.src.indexOf(".mp4") !== -1) { + bg = video.src; + } else { + bg = video.poster; + } + + socket.emit("admin.override", {json: obj, displayId: displayId, background: bg}); +} + + +function nextSlide(data, updateOptions) { + serverOptions = data.serverOptions; + bundleData = data.bundleData; + + + setBackground(data.bundleData.background); + + canvas.loadFromJSON(data.json, function () { + + }, function (o, object) { + object.set(data.bundleData.styleText); + if (object.id === "header") { + object.set(data.bundleData.styleHeader); + } + + object.setShadow({color: "#000", blur: 3, offsetX: 0, offsetY: 0}); + + }); +} \ No newline at end of file diff --git a/public/js/upload.js b/public/js/upload.js new file mode 100644 index 0000000..4939508 --- /dev/null +++ b/public/js/upload.js @@ -0,0 +1,150 @@ +var images = {}; + +$(document).ready(function () { + var opts = { + dragClass: "active", + on: { + load: function (e, file) { + // check file type + var imageType = /image.(jpeg|png)/; + if (!file.type.match(imageType)) { + alert("File \"" + file.name + "\" is not a valid image file, only jpeg and png are supported"); + return false; + } + + // check file size + if (parseInt(file.size / 1024) > 2050) { + alert("File \"" + file.name + "\" is too big.Max allowed size is 2 MB."); + return false; + } + + createBox(e, file); + }, + } + }; + + FileReaderJS.setupDrop(document.getElementById('dropzone'), opts); + FileReaderJS.setupClipboard(document.body, opts); +}); + + +function createBox(e, file) { + var uid = uuidv4(); + var imgName = file.name; + + var src = e.target.result; + var tempCanvas = new fabric.StaticCanvas("tempCanvas", {width: 1280, height: 720}); + tempCanvas.backgroundColor = null; + tempCanvas.backgroundImage = null; + + fabric.Image.fromURL(src, function (bgImage) { + + var canvasAspect = tempCanvas.width / tempCanvas.height; + var imgAspect = bgImage.width / bgImage.height; + var left, top, scaleFactor; + + if (canvasAspect >= imgAspect) { + scaleFactor = tempCanvas.width / bgImage.width; + left = 0; + top = -((bgImage.height * scaleFactor) - tempCanvas.height) / 2; + } else { + scaleFactor = tempCanvas.height / bgImage.height; + top = 0; + left = -((bgImage.width * scaleFactor) - tempCanvas.width) / 2; + } + + bgImage.set({ + top: top, + left: left, + originX: 'left', + originY: 'top', + scaleX: scaleFactor, + scaleY: scaleFactor + }); + + bgImage.lockUniScaling = true; + tempCanvas.add(bgImage); + tempCanvas.renderAll(); + + images[uid] = {data: src, crop: tempCanvas.toDataURL(), name: imgName, type: file.type}; + + var template = `
    +
    + image +
    +
    +
    ${imgName}
    +
    +
    +
    Upload Original
    +
    Upload & Scale to 16:9
    +
    Cancel
    +
    +
    `; + $("#imageList").append(template); + }); + +} + + +function upload(uid, useOriginal) { + + if (images[uid] !== null) { + var busyTemplate = `
    +
    +
    Uploading
    +
    +
    `; + + $("#" + uid).html(busyTemplate); + let filename = images[uid].name.replace(/\.[^/.]+$/, ""); + + if (useOriginal) { + socket.emit("edit.uploadImage", { + bundleName: bundle, + name: filename, + imageData: images[uid].data, + type: images[uid].type, + displayId: displayId + }); + } else { + socket.emit("edit.uploadImage", { + bundleName: bundle, + name: filename + "_crop", + imageData: images[uid].crop, + type: "image/png", + displayId: displayId + }); + } + + delete (images[uid]); + + } +} + +function addImagesFromUploadQueue() { + + for (var i in images) { + var uid = i; + var image = images[i]; + var template = `
    +
    + image +
    +
    +
    ${image.name}
    +
    +
    +
    Upload Original
    +
    Upload & Scale to 16:9
    +
    Cancel
    +
    +
    `; + $("#imageList").append(template); + } +} + +function cancelUpload(uid) { + delete images[uid]; + $("#" + uid).remove(); +} \ No newline at end of file diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css new file mode 100644 index 0000000..54b9e8d --- /dev/null +++ b/public/stylesheets/style.css @@ -0,0 +1,150 @@ +body { + padding: 0; + margin: 0; + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; + height: 100%; + background: #1B1C1D; +} + +html { + min-height: 100%; +} + +iframe { + border: 1px solid black; +} + +#edit { + border: 1px solid #0f0f10; + padding: 0; + margin: 0; +} + +.noselect { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: default; +} + +#networkstatus { + position: absolute; + z-index: 10; + top: 1vw; + right: 1vw; + font-family: 'Open Sans', sans-serif; + font-weight: bolder; + color: white; + text-align: center; + opacity: 0; +} + +#time { + position: absolute; + z-index: 10; + bottom: 2vw; + right: 3vw; + font-family: 'Open Sans', sans-serif; + font-weight: bolder; + font-size: 5vw; + color: white; + text-shadow: 2px 2px 2px black; + text-align: right; +} + +#time2 { + position: absolute; + z-index: 10; + bottom: 2vw; + right: 3vw; + font-family: 'Open Sans', sans-serif; + font-weight: bolder; + font-size: 5vw; + color: white; + text-shadow: 2px 2px 2px black; + text-align: right; +} + +#bgvid, #bg, canvas, .fsimage { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +#bgvid, #bg { + z-index: 0; +} + +#bgvid2 { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 0; +} + +#matchsize { + position: absolute; +} + +#blackoutLayer { + position: fixed; + background: black; + opacity: 0; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; +} + +#bundleSlides .item, #allBundles .item { + padding: 0.5rem; + margin: 3px 0; + box-shadow: none; +} + +#bundleSlides .green, #allBundles .green { + background: #08200b; +} + +#bundleSlides .red { + background: #200c0c; +} + +.nopadded { + padding: 0 !important; + margin: 0 !important; +} + +#preview { + overflow: hidden; +} + +.indexIcon { + opacity: 0; +} + +.gpu { + -webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + -ms-transform: translateZ(0); + -o-transform: translateZ(0); + transform: translateZ(0); + + -moz-transition: opacity 2s !important; + -webkit-transition: opacity 2s !important; + -o-transition: opacity 2s !important; + transition: opacity 2s !important; +} + +#slider { + position: fixed; + z-index: 1; +} \ No newline at end of file diff --git a/routes/admin.js b/routes/admin.js new file mode 100644 index 0000000..3ff7e7f --- /dev/null +++ b/routes/admin.js @@ -0,0 +1,66 @@ +let express = require('express'); +let authMiddleWare = require('../modules/auth.js'); +let router = express.Router(); + +let fs = require('fs'); +let path = require('path'); +let config = require("../config.js"); + +module.exports = function (displays) { + + router.use(authMiddleWare); + + router.get('/', function (req, res, next) { + res.render('admin/dashboard', {config: config}); + }); + + router.get('/preview', function (req, res, next) { + let socketId = req.query['socket']; + let displayId = req.query['displayId'] || 0; + res.render('preview', {config: config, socketId: socketId, displayId: displayId}); + }); + + + router.get('/edit/slide', function (req, res, next) { + let bundle = req.query['bundle']; + let file = req.query['file']; + let displayId = req.query['displayId'] || 0; + res.render('admin/edit', {config: config, bundle: bundle, displayId: displayId, file: file}); + }); + + router.get('/bundle', function (req, res, next) { + let bundles = getDirectories("./data"); + res.render('admin/listBundle', {config: config, bundles: bundles}); + }); + + + router.get('/edit/bundle', function (req, res, next) { + let bundle = req.query['bundle']; + let file = req.query['file']; + let displayId = req.query['displayId'] || 0; + res.render('admin/editBundle', {config: config, bundle: bundle, displayId: displayId, file: file}); + }); + + router.get('/ajax/imagelist', function (req, res, next) { + let bundle = req.query['bundle']; + let bundleRoot = path.normalize("./data/" + bundle); + let bundleImages = fs.readdirSync(bundleRoot + "/images", { + dotfiles: false + }); + + let output = []; + for (let file of bundleImages) { + output.push({url: "/images/" + bundle + "/" + file, name: file}); + } + + res.render('ajax/bundleImageList', {bundleImages: output}); + }); + + function getDirectories(path) { + return fs.readdirSync(path).filter(function (file) { + return fs.statSync(path + '/' + file).isDirectory(); + }); + } + + return router; +}; diff --git a/routes/index.js b/routes/index.js new file mode 100644 index 0000000..7931154 --- /dev/null +++ b/routes/index.js @@ -0,0 +1,100 @@ +let express = require('express'); +let router = express.Router(); +let fs = require("fs"); +let config = require("../config.js"); +let displayMeta = require("../data/meta.json"); +const cli = require('../modules/cli.js'); + +module.exports = function (displays) { + + router.get('/', function (req, res, next) { + res.header('Access-Control-Allow-Origin', '*'); + res.render('index', {config: config}); + }); + + router.get('/display/:id/lite', function (req, res, next) { + res.header('Access-Control-Allow-Origin', '*'); + let idx = parseInt(req.params.id); + res.render('liteDisplay', {config: config, display: displayMeta.displays[idx], displayId: idx}); + }); + + router.get('/display/:id', function (req, res, next) { + res.header('Access-Control-Allow-Origin', '*'); + let idx = parseInt(req.params.id); + res.render('display', {config: config, display: displayMeta.displays[idx], displayId: idx}); + }); + + router.get('/images/:dir/:name', function (req, res, next) { + let options = { + root: './data/' + req.params.dir + '/images/', + dotfiles: 'deny', + headers: { + 'x-timestamp': Date.now(), + 'x-sent': true + } + }; + + res.sendFile(req.params.name, options, function (err) { + if (err) { + cli.error(err); + res.end(); + } + }); + }); + + router.get('/render/:dir/:name', function (req, res, next) { + let options = { + root: './data/' + req.params.dir + '/render/', + dotfiles: 'deny', + headers: { + 'x-timestamp': Date.now(), + 'x-sent': true + } + }; + + res.sendFile(req.params.name, options, function (err) { + if (err) { + cli.error(err); + res.end(); + } + }); + }); + + router.get('/tmp/:displayId', function (req, res, next) { + let options = { + root: './tmp', + dotfiles: 'deny', + headers: { + 'x-timestamp': Date.now(), + 'x-sent': true + } + }; + + res.sendFile("display_"+req.params.displayId+".png", options, function (err) { + if (err) { + cli.error(err); + res.end(); + } + }); + }); + + router.get('/background/:dir/:name', function (req, res, next) { + let options = { + root: './data/' + req.params.dir + '/backgrounds/', + dotfiles: 'deny', + headers: { + 'x-timestamp': Date.now(), + 'x-sent': true + } + }; + + res.sendFile(req.params.name, options, function (err) { + if (err) { + cli.error(err); + res.end(); + } + }); + }); + + return router; +}; \ No newline at end of file diff --git a/templates/bundle/backgrounds/bg.jpg b/templates/bundle/backgrounds/bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f3cc0474a2c3ef042cb0c4a2dfd48326e3cc3867 GIT binary patch literal 43937 zcmbTf4Rl-QdFOcn5)=uM4lP~D6m3mN+oW-o(iS6Fw&^+rselGSg2spBx>y~Dq8b)Z zqEwD7H=`cU0claS5y_z_SfU}(g&+W=oM?`{MW%Akc$QI2wUZfkNRZaJ8aHdZ6Sb1l z%yidoXEQse`+MGdK~j!qW_ObVgCc?Z@xIUJ|M@@9{m1wI@dK^i-`&%#*=#m#fd6a% z_@OrB{Z4#H(*gl)i>7JSTBWT~bMTXm*H>(JF8|zZb7>Xo_jdl+uJK>3o>xCF`QHF9 z`Hp%&uqXblXYc>k*Pm^2-`{?}Tl>fVpzY8q?G+Uj_DcR!$^RTRRSy2Qwz|5irfzLr zUESK++S}^&+i&~A`Y+Vhu4`Dge#6E)?zrQ&+c(|0X=9_l@s5ph5Sx6{;c!+}IX8Zx z_6r;TKmYF^XSCa^D<58ysIc9w*>AU1+;02FceF2Z?G9E&7RLIY&0bOIs9IB9<6O%J zeps*BZR+YBj><|t{XBoyDsOkJYi{qXS|8f8=I&?oFAtwMSA9>{n?KqRUii=VZX5je zNR4yj9SxfrTUzgP8C%>BZhz?EM>=+V)!Y5Jug4$Rx$DW_eCoHNdw=`uL%$P??>qSH zq33?@JOA|X3r9we{=thcCC5*uUO9Do;?;Ead@f&@n!fP*|N2M8AO4F!zVz0gT>kMp zvseD~&;IpKN{dVHUj6s){l&EpKl-cx__OPO{Wmvm{@wrae}3}m-~YpZ`M-WC_hr*6 z%-dSNv(Mbu?cA5Wva+Ibjog>b{(HPCZm)DSw^yy}46WJo%=){(JY21JojCXAk81AO z7XHs02EV=F+<341!{{(s%s@{O(B*EOxS!p7!R+^+qG_FsNGHpnig;l%klEwagZ5-iZcd+ZWs@HLrYmDlx^(SzSL?A- zuql6|#}}y3)5gYA3Fo1ve5RAnZ?!&^v7brv@pPazUes>7?2{g?A=f$*&&@Zrjwj>S zhld}TviTfsnw|+}PYpZt_e*oxEQP#$EgYHFW*fNt{!}Vg3fee%`K86UPA!|1*X>xw4|XS^&{Zmvb+bf07@Z#*9DD9u~fC7+SY;&X2mIP5)P zxe~A2k~PuTf<@x3pwFvYshEp$AU(5tR^tkxZiER ztF+*EY}JgLh8|hknRwm!WTErHrbpdZ_kE-Bc=|}<;De8QH+b}r-(`Eot2;GE+op5f zG270_QrLAt-2>MVdSteVTWd@&t?%(T^hhdL`AI4iek$aBz^`=#9aVdo>^Hr z7HKQ%Fy?USwqCxqeD}rLZ5}-`s#dkFtw}Fxk)~OK z)2PX$HkycqJl^Kq}NV9KfG|Jg&cK7mo86_jmRmf? z7HR8ylw6<|uKbl){)VTf^n(08Ro>f`cQQ^vH;@eLFhcDG@AQh`1{| zjqIX5{-yG7mDp)qu3i-38_=)S@HNATD{+)t@DH#ccP7Hq=e$aQnwLiyHUN0B; z7KS3TG3ghLF;zsVR_hrh7M2)?dXt*p6xiXd+2rnElYWU$f2-a5rBG7yZ0l$DKW)f# zO{4n7pXHikxw(59J+<-U{wwIUyOcEcafhdJ_Oa6S@d+$ZEN4pw4adVyZP!$CUoyPU z)3Deue`VrI+ViEx{rWB~)GMc4bFoeIGU2j$rlxbDCqg|4`ol<>-T( z9+?{0@Nx`?U@xir8Inbo*I9?A?847wpKhW)rm&46CZbMQ#O&E@!tgeI(W}30Y+N>z zZK!Bq?~ca(6}6USP@5Q@&N!o*wMLbCC}8U3KoJRZY)NY9UD7ywkiBsIgF7`-BT7*? z>Ax~QCQ|I!lpRY~ih-+8Y94e&!!cV&IMkEYqQ+N>MJ?2GRjlpZVpJ*@dos4;?sUUq z%+{03r1xuv5^)ZM{Zw)nXieB-%NthSINmdhhu_uSj>ob&R>7Xow)Ouqygu2tXj?jp zZAVZ=Ja%|$yt2qjIFae2>NyblL$NmDra=9JAd?CnVI z%5*Jw-RUts-4)*!*ef<7d~qu$ukSiH%9)$%O9QrN3^xm$Qc>7jpBJZ!6~<{xvPn1sOkx?KPdVS}m`BDN~uZpH^2Jj_(lv!QMapzEXqBt{Hv#>orp%D0#Ci3diirsZ^ps}%xL2*|v7miAlint# zUan1DUr@u#nPxBPa%)GFe_t`1xYATmY}q!SeJt%a5|IlX;Svkl6&EWjj$nej{3PSJ z;fv*REJ_3s9EqFjeZ#vszQpc7pdcwna-Yc-$MV7&6CMx2VJ)3=QhVa?p2<*lNFuUkU?7-qofo@?DoUKrm5Rp_9T|T z+eG}*UbsFck{Z#boL;KFMbj>o2xdo$)zP6R}~M zDA_Mk+N4oFa#vhDvicWh>~wxRYc$)YYqqi=L}Ko;X3Bd>-KOnw(%(04zeU=^jsC&S z>HT^{siUZ*dR%$jY^y));c!+SXggA=@ zR`#^wf?@4T!i62PpRGb5J)*={2(2XnFk<-%eTMZ&d-S0*Y2!V|$NkZPkDrM4t!Zm} z$So4ux7T;&%-KcHCNrugVQA5YUM}ABD8b&9Q(*-$(pf`X++f%I}KmR2QTMp+f@fk~R^Q`TT7bCWVgoFviF{4DnuL22mB-1v@$+IHSDh4_0*nYY- zu~Eev4%6yjSv>h{a?DAZk*HtrHb3Ywa~@NwHTD3Nu@9S(uM*>X8duK3H5>RStjube zGk@-MznYV4U-3uh$)rm4BFht(SKaH_U5nFYnHG1&?O?-t(v@wMrJ)nYQOaCi*NWB^ zA$7-)exY_Mv^2a{BTx7l(&yn#pasbuXyf{d$*?=wNU?` z8*k<2n!cE>DGVJey;0HVXmPzxRKW@FTIiScl2sO8n>4g+DkRp~m2rqQYSDC?w;ky`BPI1?`hO(RI*GqiCq%gWWA2e2Uh*YX>?{BL`Ca8 zHNGpSa4I5(a?$_&myw&Vm?nsN&bD-p?=6BU&bH;9JVpW7RwUJkP3PsoxMcbY#&csgDvNv4-aBYGUK5@@bd- zX!$~j_${Nf>OI_^FT7igj8y5N|Sq0o~QGh@#5uk=JnJ~OfoKuYvd&C-1mF>^=GxIpvykyRC!oeOa-P{ktk=#v(|$U zZZi!-cWiEZ;toPX*_%wL-#+$|E1Pn5XR@i<`KtH_LA$MA%xLkV71wM}rTv_Wz)|f& zc(1#t^v^W*9~gprh-)*|`qivN#AR($an|)@O~y`;skuI8nZrROOzb~d0RNFgk0;iB zu1sy~j;XsQlvH87oHlaFiDZMephbQyA`u14pkCcdq}4wrJyp0pWjBs{ssnmR9EfP3 z972+SX7?XUBCo=Dxvd#+bXW>&RHh&b5f`$y3J=?ni%!b*Nv@4K?N5nCVMXwr&Zr2akmpJaxH!QI%P+ zF_vE2(n^&jW|Bql1zKabDDfVCD^h*0vGnd#5Tl|*F+4;BzyD$Rclct{#>qf->^5#W z?$+Kq?@mc{hy}vFOv(PYnIV%>R)WtB@mOB34)vz}Te|%Y*QR`h`-Aq*j4Ll2geJbt z-k!!ug}nC!?ZHPR1X~vIWl_(PABy9!6O9REG^aLDHqm?q@~yJV+XY>dYp5z?GjaqB z2f5QK0V)5i(l(XpzLgzckstEoDoh)9nb^4cIC3l#LNP72{Y)qFy}x5@(bHlY8K2z@ zPt2&f?2nXiAwxtAzy;z1(R%qKnAy;0Pf)()&wJ0^qEnn()LTM6Q<_pirGjEgRSvmR zM2owxQO4BPr#TPVCrcw9LU!ULNlCC}9wYXZRGZd@k$P#Awd)i=nrAl^5~D?WGU?S= zSNXE?W^iQQ=*m8L$t*4>`vYyZ17t}r$~}8Hv}Y~Zkw~E5q1n$Cv0Dc5MAIGaSKUKn zLHh#XCxPEg(9tnQQXIZ6`^@cOsVpaS)0Oc!I>yIUo^fQ+elxjy@YL8+`X#S^C{rnE zn09o0ZLz21$s_K$n|v)|Pwa#Img+CpA? zLJu#jD6sMJkGy(lKmmi{!BffS1pL5M*vANtER)8&7MadRN$QEhH!0vIGU`?k>jB+0 zwKHLU=N>W)zwFO8@1xbEjm~J7Ga7Z-443=Ciu$xS6Ilv=`EQ%u54K2Xg@bBW@mQFU zw5G@ZPX#%vAKrrF8sLhJ-qUPS95~&ttWr-OP@fHsD zxPRaQ|9%yWl6~MuF>j@l;_ZVmTV2a%Ol;ZIn(yoTKM={o)Z{}u?Zf<1tgix65iW1j z#$$g)uwuN&nn|R*Vj+4-$}?3ICva`Ao_D{~raN7-skeP3SzDEUTa2u$JC<|5R69?; zselk$E_=#^#do%HaQkvxvA=4?YKxDS5{PnN4dMS<3NMZ8DWwTJgPcGjxh}pb_EPM0 z&eor)l|P4vCKFMkqqL|I1zpglBC*Vx^=3RV>9H?f*mw$IBOCLmsZ`%c`&Z zirGKu9wHix#OADBUJ-7ktE++!w49cYgk8C|f*~Lm^8u-pa8Zp$9j7N~ta=Qf75As?!Gljd0R+iC-z=%Bu6&Klk`|I4%Opx|WoMJX_|3*MySl+6y6kd=3 z;hA3FPX$D1FUurhgZLiA>9en~dEAq0g9p&H6U=;W*$$a5)si7Zpz4gDloXJLYmMj4 zC z$hjN+8o6CLR#5^TAWTO{#PHy*e&r>`NZ?a*2XDrvM3i>)smypP+}74A>3nCiFGjgE z)axr|h7vcoB)?sXT+oh$l2J2&@EY!G>LKD(*%Z$4=v1w`T-PfV+YCuNELoOiAQuK|35^dgp?I=3Wh&E;)e{f@W!6^&7= z5{W;5Ll*Qvrb2Grr5{Zocwx)+Wo5dWC0~Ae?6=&*v}I5 zdaDw*A8+AMJ&(7ZGJ}ONDoB=r5rZuOjfs@7nFCRB7&;O~=oAT7o24{(`H&WI-u z)uO+E1G6lqWF#t>rsj^FkdPYMK)WwaDPd2iJ3NTgFPCkV{28wL6!j6jO;<8H=seWY z)-IPcBCx2PLoAlB5O8ijUaaLz;8tae{VVShLs?#t*ssEU(=@Ic4r;af6E5J>{0A-w z5|0O4SQa|=PR!5ilE#F>q;R?xbWMR|6jR{_WI6DVyLub>Kxk)syMN=^?Bu_A<(+MM z@#lkQJR7IayWd~B)8;lqx#7`P%$(X^1nzU+QK<}Yd)en$##T`V%35taW9<=Kh}Hg& zgk)Wcj6`$4AGu%}ld6SYU^;3UA|?@!wMr{SXj@O(|C}&(`cSFP&ab2rV*0itcZMX* z%M!P;;wXuVe@$hV2-1P;Q(2A#I%AI3*mC+H(i2g~;%*ZzcO;(SBO+)jtO$maQE(M; z9(+*cTKo;ow3SY}kFM+u+FiRituS}O2X({)4H>OgF&j)#RJ#u_vtDm}5}%Mw`Uk-? zFakR%z`jUq)VC(QzQ(Yeu4;lM2pLr~rB3 z=D37Op`K;HzO$J)s1CdBuZr2kxDlj1;%Qb|+SjI|`ycTCnlL9? zwt`5esEfJun;!i`U{cZqkhtHpX?cVu?ddq_et#kTeQ_j@cq<(Gr%^pJbK#qv$=%^n z`-S?eg-H6K*w47-d9M+N6yr zDeWbMtcXp86u@pCH9&1~S;JW^QT{v1JFVn85~xzYWs%IJeQd3F`=k$IOrXV0QArCg zmJ_enkx&Rt^A$LvMwQnf4!?T!M9XeVWhA)54QREcw4thg30F293Gu0R%KIMQ-hfCr7N4seinL;iI?vZkG{t|6Xn2X$)*wNW2M1iqAIEBga508nzi*% zHzvu}i4e<0yu)qTok4>fN^Uz5f`=4&1LRwoI(6|rS-ddVhVkBWgt>zg@7PldJ-)8z zW7*_hD-0NRY>wqxa{~cUA^&4>P7(5MklZcT>BX`2g~3QQ{~@b5U0#&eE}I}FQ1>-~ z0llp@KZK%HMoXMjg&v+amJ(L}|C}q-KifO7{e^z18>Wtw){Az-*V+o<#+S{7!tV*A z;v0=)8z@HC6yCj8`={At{B`@gdg!;#h+7eMg~~0i5_}VAx9Qhhwxvk?ako}1n_r2{ zb!T)xLD~Y;B!sd796Qje04w94QCbN3V-`Y5parWWW-Axoy(z_#?K6F~2fQK>M z?JC$8xjLsS1KR{Zoy(d7!?R)9Zw-7*fsx;_PUam8zDQE0&9#|`#Vc~kg@Fn*Wd@1U zpkS&1`o3u8rhn)6|K1N9ruH1qzChkA`Qxy+P2YJ8`zIo5N>i{ZCNPe~WYwN)xnURe3XCs{FOYtjst~N0&NOaGDCZ!oH07cRjaBBa5!1yAkKrzt zE`P}1>KnlhP|*Gx5{QU<^es)yh@^skJG3oCDX;V0%?73v43pcT0z_~?R0eD8OuEW& z7XipQO|bc~(H8xAm-hEl3O0TvZX6^9v4iAzTORONA`rWY2m&w(D8Plf;2P}8L+5K& zgom43?i6apJ&j|H@7~#Xu+g7O?AI^hHMfTPVHdoX&A(Zl{X_Zt?U15G06FC@EfRmi zZS!o5p|St=y=`KeM6bwx3Da3kSy2r(5&(7*l8fUX@Ly~PY1`cWWj@1Lx~@gj2ZbC` z`S&Qr;h;Sn`cG;l09MJN!dhrPNA$hw9>}#KB;qXVNhNUhl5)yYO zOj%WixtUKXw?2a4b+Wm^AxrQ(1?D880yr0Ns8TJB8Nf_yuz|$lxezFCGXmtQf9*QO z-2|Xu)yA_9cVznB zT_%k%_?|O+D%t&@){Mz(FMRsCuM-?(SFKn*hcBBaSiWieKuC!_=ie_KdfhijEV4@r z|2_ct5g|N;JnP6LzqD;Yge-e(@gUZsZ0UG!Gq=q$S>|1rxd_@2wAB_!B;n^{zg+NC z#}LV`IP9&9TE$h#l@yismW?)X6)~(W_gz)wJQOP@FlAXlZatG3Gr80MOF}~G83-39 ze^hdf++HjTM>io*WKB@lnnGzoxMRv?S*I4RU4B+p93kh`q8B4J!&rKMXaW-Av*+`x z5n6n7Of20*cCyEV{3x2^v>myrJg*n!>PW&|g_BZRx#e1eHCe7)G&v*QkaLI!R|$z68O~gG(pUB*Nv$KizPDVbH@0~$4|}e2om73I z_KyZn=k-5~R(=uYu2+&NLGWO{Z(Oc~r`2I2TBdfPUoJtx=n`0JHt;aTo+D~?>8THW zC@qxJ%7p$i;P&YY-*jMBdrD(z$}PvB_5A}PCY15vzKcMm_OscOgB!fRk-yL1wNHcQ znfvv3@7;QzJ5_we!*$q!x^K!I_SNv87Y3~K{!Fjp`*D-2mav)Kya^A;A(BYp;-nCG z1g}?K;=Z@?AQZJKMV*AwrfOZv)dlTBfQR#O37(a2@PjM{HT3<4Y2O%@1MAQy;$HaL; zf?h5%BU?7Fy861x7deK@C9BIz{QB=k2k*G}fS-al_5|`wyLIQS`f<#IsKyq>6+TZVfxtg(10wB^%9wu0#F2TmgEtN@w#J?H%%2G>{0hO#))i=<1d)5 zx;l0x9^VPwcoHz}=T7ZgM&sG|Mb8n+>L6Rf$PV=!i%MuBzLx_~d)+#VmA$*s?-F{2 z@giPS%9Dr8O4W!gp(*iF`=^%pGyTXG8Uuvl|1X*lyvGr%hw9h&L1X@U*rUH4cXUk5 zL=xv{An2u#^p{5bVpzKZ#oM>%>d8C>5CT4lA;?(dMqim>6+Jx!XYrZ~+oj%2&@1&t zrKII-M>rX#lwt0);;SrvRLgyA)rCd%Tg#agS8Hzkqz|g26hq~Fj?FH(FC=cSk}3j1 zYg3BvCDbvaLGgi)OJpC0I@9N18SwZ^#{*jG=KlL*18tSi^fw|TNF5qz>-Dj4H3jX; zm=GV;;X4Ec>rtR@7(_JCdJIm-i>^GYF87C`1=p5NUev?3gG3JrOL{W0u{Bp|kC7Z8 zL*q;x1_U`UIRShM57?WmYEdiZDhPtm$0v8b2u@E9X?($5+@*of$KACOhujNYq{?N} zGNtslj4zKQ+j~o6f&i(yP-ZM6xC$$BKu-Ho(jOKurT6hSGF@u1%ZskwE$EmM@yJ(a z??)&v@fqibT-qJZ-;H)GCT4BVwD+K_M32$bQINk2Url!Qcdz%+2wn*Ot#Wa$FqRZ0WGwE_O7>9i~mBY`W-+X$3o#bWl; z1bnNOO_r~mqAFL0Agvcq6*OWEBd3!4?eCkihC3i_MK;>|v+RXC)CYLeqeuz@MYOYF zTfWL!-TbhlPi2gRKM&W+t(WV*8@vvE(xT0CR6+2ha8y~^RjW!s%>>7UbBejOysx4O z;@xb$3YGcNs44N7?|y#YoX<|w&FX)poNI1oht#(BB;`u0iRv{_dI?+X@tSkTADnI! z00g@m@@34sCM*#sYtR{|40D;a?(Cnna|t+^`>rPR!)A9DD@lT5`Znn*dyL2u-#M!P zY(v}01Hhe0PrE* zck+eB6>h{Ob&c02J#r{ID}tm`*k==YMK?!cHdUN3ijB8y;CBTT~#}#u@$1$z)8li+vU%ppY9Z+ZQKn=-2c5~ll6$KpIJo-JFtx9$z159XneJ?Rl?;l_C4}XUCj$tBvZvc%?~C z!NyLws#suLk+{k5M-w%@>2}YCrsc@WTn|<_@}@7Y{UkKk(za~?8_$y8Dqb$IvO_G* zoSg$%i%2L&MFRpw6a6MBvM|7CbEBIdCQ@6bHr_O`K9o-wkh`>EP!Z--=N}=XwU|Tn z`w>CP)>D^7h3Wh2kT6;-VpmN5V7^XDJXt2m-FlUuxoS7Hx>NYfKFl&5TwuLRST$A4 z>D$wpJuz)_VV@;6G^^8?C4k-J-g@$&%F+8VSG7j*?bs}x%Xps=xqy^2=qhMS*H-Cf zSx5iJ?>`p=JQ7btdh+|ULMu(y1k#g$_QQ~tbBn~ACJ2rv`{sY(TX ziAX})ytEYY!&SF-j0Ur(7Hcv&?%Khobasj#2QAdqHmuW+!al!juA1O;qJebLp`9XS zkPK3p@G#P|37OMmZ!KfTtwPeSUEpSh%sVTnQouYyBvnf@kR!LxEdEJ^Pz$pzen9%h zy0B6Gg~bbr3~1O~(_IwZM2@_hW@TY27fD~$63M?l^XiW07HtQ+<1YKeZE_p3f(n;U z6xUy)ObsUPBrWJJlN(K=M?9s>{B-4BaugNoH_blmWJf#QM@ryi z%DId1+;mBeH{=`3&9>>a)CauwOG4Pxuv}9V4rgg4q4CUiy!|*WwvHzEwL@Qw?!A+X zxWfJPHabZVA{Qu!?;ac%*)5z2$co|5cTcP8Z=VK-|n3+_9-;;fE1_wbuGH~^MxLAHCm}NUE$%L{=!z^ZfRXu zb{xx1GUDz*Lqnjdx$2kB=UX-m{YXA$lKyWMHtmoY8Alo8Wl!L@%%RxBf-anAt;%i_ z$6hu~DG~B&bboiK{{t3*Mm}gboK+fQD9|IF6_IEvy&wMp{l0Lr8(EXcWNPS4zb=yn zkhC??-MYCBL@Ju5!q1*}&qVu53Iz!^Nkh@RCd4?olH8cOL)I>0 zD+c2p==PK1;kXE!2(J}s3S_08|GIo(i}l2$)BbCEeXLN%JEK?kblTc24UU-sh}!=38;VukpfEF5@8kB zIRUj>y5(FqxK9PBNk3eSJqLp)Pf-rdOeR-F-)qeyt+rm<0Uup<%SMQG8G0d*{eW9j z#nwcqggIlC)uFd|x^q*F{jYdh@IjO=F0Lsln=(1WrhIi2nYo;V%T=q*JqllS%Ms$x z-Ql1;)NA1=B2?Ck51PWkLTb`%@kUJvoQoThEp=Uq$EF4l4zbP4-*HqW+R93g!gM2hqg+&A8mbxOVLj9cBY%ntDN8*)RCq4gSJk(3+{w%5)2k^?%$NzaiNgx&J3>aHpt7EJfKd&Y4Y~5wLOwY zld~2?YMPwwe#u;!Z7}7?|LG4a-`}q{s>1or9bJ0~ICl8M zGlL8dCnfT(Qr^(@X+fh3-t}emBuRB zM(f2{#8NH4SWeaRFTbJ1NybOGgfqHE7+K}7?U7^lZ#J@%SJO7!BvFb#GP_;btr6?c z8SAK+zmAEKbUZqKR4zrI!?4Rw z!Xbo?c1@Eb@X9#9wois&$hG)sotogxg=TMEk1{>f?lFd>xU!6wO$qIeo&PBy`p~#| zajX7%Pw>k4Nls;GT*0fI;+Jy&01Q?iE)9uxi95%0E`)(i!p}qR1|LyZmbZ_>*r;^= zu(h2*ICpoKNWQMRo9p%lGE@gL6uvezZAMCk-phR!sf*8W)~$C?U!5aNgL3CQK&2%w zGPGZ4cEZSTR&9ogJp3}B^eMm8XMcrW^0;I@Id*=7XM3`aAq{Y@+PzK9T(?y2zlY^B zwkb9DAaGdVezX}TQh86y@6-Zf zYBSBD8lDY1oGv#|ExIBfQEeI`bRx{JyJ)iquV6SqQXDxMz>0B_*jgNg!%ksiES;$* z6K~=(@;U28bsQU)D($L~?;$Hnnq#aDIIw)EH|cmrSUyYD05J50mh(vPN-=_$0D`1x z(V=Q5zg<502(1eFT$9O|mzW~UrAz-ySy^V~{1rR6&l7xy0R>p6Hv63vO79+#;Ic*_ z-4QJ9_(|p3Vb5V{Xc%e3ACH?)SdBw|Lv-E80RyYL)IV}Gi6fZmJnlP#EpGN^xx6L zs!m{)hm;pA3z@5)fY<+doePmaz{9QYP45qie2GjVxKQUlmFjb5P=TS?sy2mzRRko% ztt*RJZ|UXKp-iWgj_bqE=9vyez`g8%C&Ed;tNvyegA6PS54~J-G{c;?)3$d~ul2Y0 zOOOra^UltE;fIbIymV2S7iBQJX;7Y!{J6b048UwqS_nEeLMdp|cb_OC{LXa(Onka2 z6BtQ;huUYj`3)h?(dWCjZ|}9EZd+%Ut+)4k(Z2Ad%W$&|=Lgiclr8L5HI7=6iu;Y~ znEt7Lj%;-I0Bzy^6QdGas{~{QURq9sYlm0@<0(4$bTGYf;B-Yu=c4+H+9AxLx?Uoy z4NW_!fZqw>kc`}(TnR@^S?jra^5VmyZwB__<%_!O8+PC9mGwREz=qRD1r`&!f>G} zr#GMJ6Ri?~khRYs)yi8PfngePnO_rDo4L0ciacPZ>mT>;Zy)U#S77F{IW&_2OQrOi ze!q23s`8b0hac2hw!`$=W8TQ}RXVx!leGUk8^>zAOk>K?w+dA7!p_U=kywv!vifkA?A_N5V)JnIPtynl~hq_u}_SF z&3MM|xTo*5)Uiv}2D0kwJ(^BSCw?r@oV$xTMmGR_r zG}5f9%;1D!1j!_@SG>Po8*Y9RG$gh3%~*YV0rG-I9llK;M7(je*HQFiz?0E_SUqyT4qD76K4*a{Mq zF&d2?tB*@53ERkU88~3p*@5vWA8zPsLh6h=t(C+kvEb?WVN;wEc=0VB5q?Rz{j%oD z@2ykhG-|GyO3Q(D2{3UC1}}*1CdS8E{0sS~q-Cw(W-_QG;~b!AsXv2csmh&o(9ep& z=l`1q9-0=pb&_S22+1JEvG57Gzqdah3V7&vq1F=7>uSycrhj@65#d8nLab6-D9GV?~+ zrh;T1g2r4ZQS@&m*c8MFbVEp}vb5-hso-jb6rV^RqMAOl3}meAz^YRGAlT0mip_*V z82PufkElfy$D~-CyGx6=P>5Fg3>m61+J+)uhkXs-F%#fCYpX;c0yBj4MH{CV=Sz>rH4LP||~$SlGi zja3^r;fLFE6?*FC-o`5BeABV|!g#W4pXv!2AI%g012Z>L?mODVd{+Y1CPtApOeqL6 zvERLTeEW3fW3L`2uwUs~C;l`*+Vt~RX^XRu#D4vm9?ze}vdQib*+5(1V=U~9D_@o} z%X`VP3s{VO*&GwYAxPp9TSoyQ9oVW{l>+6E_*g{C2}Zjts2y~lX|5YH`CnHx;t@a$ z!G@nD)$D<`slRqv#vO%2p4;fd(9JURl*GySuNuxvo4H0-o0WQjBv551%R82w4~d+C z#)1c^?VvbeCccW`BA{M)Y!v){AUhoTNL~&UD7on}vk|XM8FW2ny|WaAY)pqbvE`77yb)$Y2;8FqR(MnCv8>RZdhj zsvK?3krIiKW-#CWhrdW_{?Y(`@PePp!-seI4 zlNni-CD}o?dOP-5d=pA1zX(GCf#)GALtFd(@kCLAMwqmw+bP?|J_Y+(9*&zmTP0JK znFsR`^AeQX)?6Z?gui8(m3QSjWwQr>-Mn;}rOK8z)RVZmVtNHX6tx%LEZdclX5t*| z1_a-9h;*dUPymb+9+F@rGHq+8DR^A62+1=EIHsqZRMyWqbf)`mZ5&S(n1YRS2&Szo0kFRvOP2@>Cq zLq*hHeO&dDvuxrLM{k!u2 z!BaQeJeA(>lY$vkUX3I9jmEL+C7H2&+?()k!|m>c>@j$nta*3%qm%@dB+Fvf;HYEw z?r-<~=6b!{#9Aw+pw{oY(d}xOK;Niw;J>x}pXPmazYK@dbbk+f$wc!xI(-}knj}&PKxJx8Swq#kZOI(w zw!TOG{#RPUl*~!MDq$wbSwm(~omHJ#Pi1x{ii-Cur8Tl* zIG+vcXbrc+W%m8@@fLD)NgKU4A+BEOd^k+sr{+O8$^L4Acx?F1tokYiav~c-dn76-o=2 zW@HDPEliL@TFOT7%ptA4UWeQRf^iAMM}^<Ji(_*8g<==E`E9B z)G3M9WCg4OVA$q+-iWvN&$P(5uC(Yk_cvW?6bR@Fkp_w}e(I!d3nz_dI_F!!_&j)n zt0H7&kytTeNj@!X4KTq_FFK$vQ_g@eTg9o0%-s6wmW&ghDtV{5h1OQakTyBA>D7rl zw)LJ3N<-Fb99<ElK zmR8$|Ak&V0U7uj`+ZA5raasfPD=@6FvJlV6jT(=;Q@=>v0wELf$ZT3H=o-Hiy<{0^ zt(Ul*d`-&z%F!sDh8Q3%fA9ji`G2((>_sGl5`9`9(I~4>_otT$462e!?+#yOX2A=u z7ego9fXo=i!+AJ~6fOn7|HKVnMIOE?G^5eEme%-_!%5VU+E%WU@p3~*Vr~2)t@tyb ze^+9&j+%awv74S&SO61Z#JY`ln_7)saS!ypU$h!^k6Zv=X_s|)sn^>8*^ZiR*!I{o z^$@d!@Bhwn(w&{5HBr~D8PV~P5o@6%-`7A ze3+(ay#BTxNE1k@+vXeKM5PJY|1n8xKch3EL&^>+5sLb$g$iswGNMX}CLebg8DMf- zDk$rquy3T*|5!{re{plHb;L`b9z~j0bNRc1_W1xL33U$h%0wFo4^;40?e{-jq&kZf zB3r}-gJ=08UVuUtofiIR%{P(b8cIr*X49Lg;5zP&j;Iq__78FT-!gKMKT{wwhxpP6 zCNaNf?I-zJCX_i;H|b<)?6yCL-M>DtH{E5A8y$N75!4|-gB@w-+@f+bEK6FuQfh5&+u?^M0Kb&>6Hn)S(5Hz38 zKfp62YN>ud*y@5{ss@*d@u8Elij%l77tdxoOUd^10lj+4t6w`gEv*(?H;#`dWw2Ly zr_J{lEPD6W4RoTB;8^(av54~I%7o4vHR%!wzZ!IRR;w2Zl8}{)+`q!G{Z>j1l`DoTM_IX+;cWG}MPo^I+yFz6pn)s`L(kr&i ztC!7SgHD@RzSuwX{4; zQ@9ZGXZ54oU&b(Jf?MsUP9+TLCsTuGd^8ZSFItK=e;S5w?yu-%MYg)Hfi~1~W$0h4 z08Us`qLbeNytr@RGfQPI8^ezz7rg{GOnO8QWSo+GGJH-yQaTwBaJ5}7n@r||h5jt0 zR@PMbVJos&mPxOkVz2=C^Y~FUFE|rX@GD2y-zHXO#pQjUSWF%tkX5a}Pyoz1*=9~$ z-g4xD3)zHCC%F{~v~q>@fr4+noU>mitWE4$J9K4m3r9dp345uK2sii*CCsZ(B_vrak7mtHxlHgQOGImnk) z`X@3d2D#b67~>^b)_0h)*Zn~Y-BBI$TQM%}YP^F$In=m9eV*b?$A)`HAJuK%M`d)? zZ2N9JPieTObSk-PQ_em;M*yqj{Hi-44-c?dSFSv0^01~$AKR**MxY==WYow_OTN3Jk#h#`{f271flkMW;G7bw?7Ei#Oj$7ut^DFuF6M0RiN3?~l zCHzg+%--jhUkA4&K%ta@={;asFC;ho-xU5dD_J}&De`w|!yzri-7__HKQr%32fd2T zVl79x8D8Td0N?FZnW@QCx4KjePX_2hg?}91N}e}y=4~RC%tW9Ltcot54M#OZPBo;^5{R$_?t_{s@%0X275R+Cmd!kog9iN*mFBP`Ki77HO=prK!8~n71$N&p}<{f(&40#$4u=!x_w@8HsQ=J zm=IfCA$>5?lM5al7q{h%x@IfZjl+lPy4_3vcaHIwKcOE)boT2Do$j5J!xn}oO3I7& zTt`E8xl4lI?8cu&U;rtL#?1I-9~GF>DjATp%<0igJsD4YVGpzmd@-C+JZwzOElwB- z^NBpJLg{@@b2uW&g8B-xpfDiWV`>!ek$GzlgxYM{beHFsHoF;Z)561>WREnU;+;0% z74jU}VXCdK#Ked$m+h>JDNE|I_=pI}s~onk_@LQ4X-Vo5rnXwoMI&IZL;~Xev;C`%5k)@`}ekU$@a#+p-FGkogV$? zVO4f>XptFlf2BnG<5zQ)g&%$?5+w$0rx9&RN*W|(&7<-loOo?CDmv}_b_v@06Zux6 zByI3}hod{@THCpG-<}=9ufAF+l_(7pB)&=7JLH<}AZR3|?e#XTJ9Sz=Z|%Bz&`RyU z#XxkvXSopW3ZVjM3qDe)z=QY@lqHQgvr`!P)Ys^dHJP<)Iw#;XHEjWA&MzZNN{B^} zvB-dopHK<=*vjI>YYtBE&;yyoOt-z5LM*J*`raqBczzme=R|zTGJj5KpC)mEs;mic zm)Oi;_n0y||GOV?f#=Mh#JLvi5)wq4_CUX{~+z*(LqZ`hhM@{l7VPe9VB!$>DurPGeRJfuyY@PmQ;@3M`_`0 zBk^obA~DY}ZOl&NgF%Ll*6Eh>g>2kB?3QRC@@638csliIp>#d*#WYV68CIRHxs1p7 zH$DA-D^DDXq{2MmY$j(vt-s_nmf6yHXTlBUOxbgq^EuaDp>(BwZJW2^_6ycvE#how zAjHF0-9yQ$?XP$n@_McK3(;u!0pC09X9mYLDN_0|^H0&v^yzv1DXBci>|-S7q%@b_ zr&%vqxk5zc$wQ@JJNgz1Z<)WN{cp0#fBUzlq2N^Y3u+HKEG*g@}V?y%ASb1^^&AlwSCzhr*>wBPx2?WnFoC3R~#tT&y;L(VrJed z*-+&&55hv$b^2nn98-=bbJ^>_SS+z5u^XPV6OIC5E58bSm+pHP^{}S6mu0W~?sqWv zQob#!APR7I*Rc1|d{FI_AV~#5vPD46i>fb~3}drLN+vjYNNchWL_I7MB~{#q=xw#f1ScQ?h3(hri^mJY-%amcj6V}5=QeX2j}D^_n;LfILO-4C z{Iwvs;Ip}0Q#R>(@s^azLn0rl7~C79y*Ch=Nh zN#y`-T0=hfOGvsE6atRjak1m&6zw_1o34gy#$j&h9URl{pxyaoK6iok4GV=iaa#AVgl){SBT6{G|T$K7aIbN@JL)`&A8jL9K>D>9ud0fisV^8_mvh!f|R+rZ2fg?3jWk;^9Nu+<(ddv21iH; zSJ&hOCvH+A(6QikBXto=Wk4&BavTa7CMz;B9fhcZ3zCAYJYGZMHZ^6n{Ef19$UAtm zSB#!{JVS72CYxC${pbMMj{FTtEg_*_gV&fQ$`Cg|Obg`+gZ|n19 zUvoGy6ZJNk@9>RAts66R4DDo0CxsQUSb&IW!9;}zt)RjjK=o16gkU9hZMd6f?Va%U z{F_{Kh?(z~q%MWTZhNj-YvPb_5r~;f4RyqM?n{ON713 zU)S$wgmo|IsyMQTuaW^T&RF^l(77T%NOCEHJZAfmjrRv}74ZQ#hOUg4pW z7c1U)>k~LUMboQ7=MMGbKW)v-1`rK-se7^+Z?cD(lkwTL79Dg^GVjxNbne$Kc-!o zD}?-y<$@=ohRzht@;Dhk(f}AnqW8KWDoUNydyX=grL&4zwOpo={))D(5{i&&q5Jd~ z#9f(R)8BTqP;Sw~i}l4wJa%c6)2m&e57sp`k8wvf7Z2{_fo5wCJKD4@#}=0&Po6EV zd)WDVe)xm5|6DohzRX~xM`T8a;u*IKrHiK8Ozq;E)WigonyybBi^ngqfM44e)!O?3 zz8>>dCWV;!Dts{-6&@w>>-0OC(S0V#RPUM!-{xxN83+%#!D1b3OR(ZXk;<#V8u))~ zSE1UMNA;fpJdk9w5w_CKQl?MrA*E3) z3Kb18Ze%jnNTX61F#{oQgJUq_N%t4QnLwTJL=}Iy&+q!d6CPF=R^J>DIcAN;0FK5< zH>r#959q;1VA0_6l%&dNZ@Xffj-?|3%Yc2xsL3ou@l;3;g0C@oDgG_2fCbht9`R9q zaQHY$V@ipnY%pzFsv#sgh;TrOVSp@r(yP zsiNtX+hw0#(o(8+qRvh^RLDrV)`<%0Sf;&n<=u3#=30k`Wu&c|e$T^Hl@QN2?PJ_m zyPS$$@qn*q7++@=HB=lSIyXSrX zce0yjeNMzvH>7C<)b*`~aFg?5H}nklb-+@{s=XU^BH2ovF0?&J=x!@L;qB^rYux0U-Vu;CPN>#K0Jv%oI z;I91kb1vH@hIr95sLYQF(fT0&6en*W6Mjd9WYu%cNJ4LtIRPvw8^()?Q2oWS;XHbZ z;wirm3N7nn!LkJ=RM~`jFQ$}LR%9NQ=-dwoz+Yf&>1L(e}a5$2(_%71IZ1)x-n)!rkI`&(#| zmc{{f7g7_hihV47j3yB?jMm#Paq06T%E~Y6>G|o2$R7pr(LvMtD-QsyLr6RFN-P9b zp2`@lCpc^RqArXJKqPYsxx{5KLSX^Z)a9^7;k7Rby|nP9QE7yJszLAl@EH|JN!4)Z|K={xS^a8E_b_2K$j9S zwfB+A?N(HSoGsv1BS+aQ_u_?irpcC{5g~h5P0c#DPsC9j*M9OwZ}%1t#Zc@hWQ=e! zqta;nv^&@?cc@qIzP=KJnx#~c{NAf$(u`)-nagQ{`Tl)uY?zcvRw5szW0{|ry7lBZ z#i?SWk$YF9R>C-O>?Rph9%=wQ$&7s{uQ~gt?xIs_IFIJ(>l8SwibKr`6JP@ITJ_{C zJF02(U``9yCv5Il&s{Jug=!VQ%yWDgpJkdm3H+q+wPjvRryP09;=ScDZKC?JG`vKG zsO`%0j~7J2y4A=|s9>JlRJcK*sl&`VJo#{@v9fIwT(^ZiSVO)xDPexmdcb0~OL{nN zN?c)gc1y?CHKt@5@uz-|K>dSu$=6jOM?Ix#^uT#H8wZn;K0_}-!q*P=_VDw+>5qEz zxnAkg=!&g%GG46NT`Occo|8o$%~%0Rj7gXCQ3is_)$?S)0X_A<(PG?CB!x{lV2iO+g@8E|S7(BF!e7_Ppsl#Eq z3zN!SOX{G2`AmH&7|Sr}s2FTtI+|2rnOHsRg+-L-j|(;}#iylJtxl_?4^$I_W~&1n z@YHzpLpUR4X?Ej0{RaxAi`5Q!@JJVTMc5MD@{)Af1vR5bd^^uJ=4@HTXd-@#y2=E3 zN)xk4LucmQYGI^79EF9_gsGv`6+T@-S_sVgxi5owjT21Y=&Q)fu1MpJPzcq?w`TV{ z5AZ~DMKvHi48Rpzxj|Lz0mgnhH8_kZV8QwC=?z`$(n~xqZ-hB^;Rae2ovK_TH!wC* z9vqZS%ABumbnGW^n)|?{HJ&6f+nmq2CGy~J{bhC+&;P|8hubri?huq0^vcGJv$zZj zOaV1f6~Fhn_`v|PbHWge)MShc3L%h*Kww}%Q7k^Rpc7?p;GkILV${mri>Got2h}b` z0VweD&^DIyfoRk_!ZeWd20IW4k8NewtZt-aCUQa>j^GqC&I4q@#i$p=@_)$5GjGq}q zvdQ258d+F08l#q^&I&y8A(MxQFGu1DrsiO=Fgg#1#hP1Y2Yu5J7&V+=K))7k@9T<8 zlgF>)A(=g%+i*D!`(~JNi3%>Rj&JeJ$m>Ux03AdBlnuK~hoSz?{X7U|1(?_|L5^DIko^)^?`0BoE~BUyEkFVj@t`9%H#qNg&& zBRoDnB3*d>s`{6VnV$3A4>~#TRhWG z%}Z)a(qIQz6Y9TWFr{Bj$Zo$(Ov4a(TIaN|@GZcz6JY3o-{@BaJjn+8l8Dkx*(da` zPkQy=eB^yGpO`>=IS(r(v`&O$kb|075yoa`7Q`amB5CU10rz!tG89jt`%70&^f2%s z+Rmf4?zpJdQPy(RYx_t{WH%EgKUwu_^^vgcV>M!L^`nff&k$P`1>Cb*|4H7IiKHke zWf-i}mLoFWMW%KYnld53afn{ulQa{nd>7uIJP_$^L!J;M8ypO56^^LcL(W42dSO_Y zkt<^}O3A3~sY${WtuW`7gwcY<^|Bniu&Q!pCafr7o{WocWz;>H0W6N7e2xuGJWbbKTapBZSqB)irE4;(g1Q0&1Js_6-t8r6 zU#Slfo5S9ncjaJTmm;IsQE%n2`x?=}R+-IUOYYFxJ;;kN+~~&gXTMvEOz~jlKz?tJ z@Bb<5{A1d@?>zq4#56b|qsfz&(58c=P(P$_&={Iz*P8<+XADk^A+$o##9+(etl2eV z>Ge9D&Jbu*7k4BvlsaT`92;oTRE_3L?Mc03Ss-dBBrq&%xoVeYSJcw3(&<*6wA1PC z_4z)Aw7Wkn5`%v{&-e5D^ZvX)odK83Vy zHj063J2&97mG2n+g7p%INXISVVtR5pf+#kFsf073!Ybv(|IBJVlv$l4!c2L|2o@aG zB{U=idw>)#^TG0yB{a^ccsevaV+2-AAVr-)oVr>ug*N~>qvUS&#U6tqR@qm#D68ge zhH4bgZXmlHfgOrx!^PRHdZQoc?t^lXqgx~bH4{)`RSbc{sf#K<*TDd#C;^g6#YD>n#Ug}%&$=Ux--jV~CbzBlPB z5Cg8s)%6CPT*Nj_e}>D_+q;Q2)wmpuAcQkRy)-Vxu*oC6tFaLrK)+_;)edj z;zD%MhP45QvyU2KY1%PfMzINj=m&I?6SL7mipc#2ASe;^S|c$_!#!73vD7il>}qzw zm9D*go4@n}m4U-jU+ZZz#J~zHLsCy!iE^ro8>u2Lgz0ooj>pDC-fYGBKwVj(O*r)6 zeA_dp)=I*!LCXFLiU{&9k?=)6s!#XF1au2|4rgzvY@i<%J5P49fZ^QL%qD2=BJ#{R zt~;PFJ|lnDsA!w^%!RU1zxsitPvX5l82N&9k4^^T5~ek8r=yn%ricweJq!;`dOXL* z=3U$bB}?E|W7+eZAq;qB)guU*VqX=%jOc%5n+&xFbTHDif0CE7>zpN1<{QWx_029s z@TwRd%mcR}D80+f2bkp&kpZuq)TATvSwrSuB6|x$i;uBW(nIfipkR&eV;=$H+cBbu zn}njG_ztfSW5H)hI4(;0+2?prtx~nyCG6oNM2@e?TQveLovD`l#wWj}a6a)7jz+%S z*B&|S^;0v;Qc4x99iY7+U;dFN#ag8UCrMa=f+(z#801)uWLA02{|sqd<_36D8>MDF zu9`}-G+Z3|^>svLTv)m?QNol111@w@FoPMys!$KDN((o^M9wU#bX;W_mhMI3aF>K` zKN12H)X&4EtZU%C3AExNOF!0g+Y;-gNqmO~x$xnic9RZf$<~Xk&4KrfOH%u*>8^Jr zilAOLZi(xp`9T`|Dh6^1>z5DLlCL6(=Io|h-SCUid%)@oHS@y1T^1B;S)saF#!k0) zYnSEPIq#?YWw@|D8q=f3UCxj7+;w$j*@M?(>!X#?Q}^n@kKY|TQ(JJf``ja!<)XMe_^FC za7@^arRLC7YeEtV$cIG)Jhzl=FPny8GIQL6NJ56*DJ%=N$On^*fzCyL7^u^}Nlttx z2BjeFpO?yU`*weGm>Rw+48sOqJ-~|RF(HQ&Kxub9rSC~jmVzAxAspToQwGgiw*)kZ zU&1*l2d4~CBlz-AJN{72E9mG|2!^f3 zI#FxlBeSduuHTX9bgxNBEc`V+5qt#j@N5CcvK#ZqBxPFJ9$7HSqO4c9q1Qn(Fg#4T zFYoiE(1GtZfJ}@C*K#k(oo?%A*pH@;ohOosqTHgSGwfa?r$26IYPMn=Dq(&-eVb{3 z)^jhjZ74cD^x6x*>*;YyO;mjTg{ndohiW zyCsNt6@IK}gBT?Fd@u)6{Dvlv6I?6N@>Lg+GnuElY?GaeBn(Fn*6WVp%z-Jd*NozN z5yx^}CZ7uhP$8Kk$wL!+=1Hm3(Ef{Jk^F123CeOUWD{SlK*KMmZW+O#KaDE{8Jds^ z?KH!gW|N(|PdTg3AdK|q%d}DIy4|cBqfEJqu$Gj-JI;I>-+W^k;i4egsM-GuRgmm2 z}1wPDHqj6*q_7i8E={B=zlq&upVs7#T(wo2qcUpm$vSMuk&7Nv8O z4h-asRT&VI?rliRR?M5UxPBJtqxj%0>Msch>C`u)2bZF$FU>2az>{E?v9-6K%o&=$ z`3Il-!8k%HT{kE)CWHjGYoeWJJPes@`curN%Yl-l+aTG zO={+Co)yog${RhEt-}Z#3F-_Nb*aItFXx$GiH4tq1g46}LIDM)$XI(wUUN4;-ftE^ zMJCllh*~M|PgO9XpE9|R#13Nr#O%(lLKjI_r5a8QrvwXL7xBi5%O0yIj$AA{BCKXW z!H)x=I+H9>!VnYZyXs6)kLMatkbVo5aSFh(M_0pAsnJ3BpwZL~}2I8K!V4>l)lNs&{h7xA{ynNX#+uK&B|f-TY-D~?nX5K&m{gp(B}=jv7Qg6o zyqRshm%2#Z576Vq*-HoFzq0S!mFx_Ke|ov{1jmI|k;{ACma*CCGrMCofTy?Rr7`y3 zt*X6;ZE(Bmib8a>Pk}|-%2Wx}ZNUKc_RmxgsXHDZ) zpXM`xG=uN!62L@cGAF*G5y;pb8lM$~=%R~S*Hq-O;h;B~Rr04H7m4$^yqnSo+MXRf zhsfY0Eah`^fFcM_g6JEtr6id9vNHX!aD+x!Q8ay;hM5MWVzrq-_%Ld#0A=xXMyn;& z?m?t~OyWA&?QvM%GZsR!K-P>I#K<@2HTM^ClNf-??y1C+-Bcjzl-#Pr(P{KO6Cf5b z0U&iV$gFc3WLNzrYNo^=nDW4?I?FJZub1*vbHBS+*sz`})9k7LNqyY*jKlhf@p@@( z;}Pxq#dOsc)kIU$Iv}O;j!^H zXSUr80-0!7cwT~(6$uf}2XV>!=ow1VrJXZY(Qam+T7JFQ)=1_&MWcKi$cc*Cl2bc^ zBgv^U5lgujC){f!;b4;NmSakF5eqp|5+>O}WC{tL%4U~N%Ly0(y*y=2C625U`6VsD z!vKk`^dLMQ+&oQWcu+oH9wU^SuSIFdWf2L&3Y<2lBMPZC)@9vuW(&?JryrLY zA9=w~HI=Uk$QeN@tIS0zI!5|U#bT(P;(>puw+46;{qOflkxc%FH-RoH-(gi($W`9A zU$wxyK2>crdM=^84Me02{W4gOun7_1psj7F_0&G&kIGR`OGmbHW_`Cy1nUYKxiUDc zL{r+DYAb~am)~9IUJG2pp8B#)tAju5V(RneH$PV~_H|qntF(%D&DX;i!+Hd>`-tPn znOZYnKcu#qnbo#TNTpF1k3Oi@BV0=zb%w*mD zM3uAt@jz>lC%Zd884vyYw|YU>()Sl2Ax_+_5m_7w)+&F-6Y`|s(bRyb>|8WWj`-|S zx`7cnnhx|7@f;qMEoe?_6}u?au%k$>dWfuvvs0#U`wC&OE;t?wZeKqH?5mRtgRvWQ$6n=AQ)YeD#y7=);x=^x73>h_j& z@${dS=z)#+Lu;V29iG@*FI`veYU=s&zfUHZueC~Hd6S}#m3NkCh!SN2>uzd4Ljx4B zKWfAVdmQ`=sT4X;xcALJ`0F+$m7+8)6qp6H?$}&N#RB+2kyC&-o}ael#7}r*LbPUr^iDLK za0wJQ*u3D^tfMwTqE3uAcY|VgBn~GIk8SL-JUO2~7xfHo(j&i553ZlhI@s->PHkJ5 zyKGxmaPZ`${+s;s(Vo#{e*D~_7rHt)R}O>yK;GgzXRid*y^u1;2mlbljvHz=wN;Ab z1zG@3p5HrTQi&p+<*B~3_;4i-X$gL0XDL#&;xpPaBKuV-b=x3S(Nt_D`vwUss8W^4 z7dn>??Sc9NR2n6enEkklIBeBJ;o{8eA)Ss7%qjCFC%;$xq+eQP$bdZlEAtPdm1Fbc|h<)e+<(}TS6icFiNw%!JQ3w zkCUR6z?MOI8atz&gJ_z(zd+aJdaZAouca^=A83AUEq320RBTNDHQGLtD!1_u6HwV$ zZTaI9=V2_LEv$R(U>ATeiiV^p1zP@XgtT?{7z`G$ft+A#31%f|LkcCV^K}V~03dmn zaO-K~JuVTkm-e?|&@XReeO7kAU?JO|QxhllzrD&*5EMkVB#}Iat0BB`yelDojlcB6Yn;W7lb_3JtwfwsgQWd&>miQ^;?_*4v@#`!0qI;Z zV`dE(Gefv@(Z!CWlHM*s^B6%UCgGZf`El0D*(w<|j_q?~sxnH9>3y$>51Xwx1d|X? zxet8$CNB_J1CsX;Rksc)(#y5bP(2m+HAYX~zADqh0W?lsm|=^c=tAaUY22$IEt&sf z!E>_}(=ha+5+48s>yq^asv=A<^LYo|GPML}IMlK64EnOJpIL?3!q24dphSnNGojxw z@*_xQ0q16QIWWH&l6`DZ2T{lj+_X=WC||O~($%QfmLGrLmJ3+LT+yLQt2W zS|C7K(oXk*j6eFY7_AQJ9kYNxYk<~Lu$uMm--K};1ym(iELBrzjH3|dbfL;A|*vmEL&dcrjzk4m5kmN zhZ}@2Ku2anYubjM(3Q;Q&u_U>TU~nBQ}g-XIy^Y)+s_W1tOr7lH+H_M_MW&NNy#Zlp}nd#6iCVKwFoV>GOpsHF6v3=AM%RrbR!6sU!Rb7F)@z~JUu0gjak zLYJo_skFrTe{pj#XW!0-o5Ml4DXEY4%^{#_$BHo2OHsvtwU_~Mk1;lp<>XVCkRxSX zDN*fW*k{j(J!J-Z?76W7D68$I7U(Og!+T!~8Ln83FR(B&_B@_ajWl3}vE${itwhZ0 zVXGc1#z0%q@wqcQGSWwKqPQmH7WUTATbi{9J1deVk3%>U6(56%-dMu^75WTLDjm{{ zN0b1{B9SmNk!AvXZt)e8?oS5OJxte_%w!JEiz}c>>@!fwM;^Bh)0o$`OCV@! zt*R0oI4C0#7tbn_<|iTrx+u}2L!T!D$nnA4i#nx9XBo$)4O(hx{m0F z2Xg=^`!6npQu?+s&!y1jW3|F)Ht>GN3UB?nd%xo$U4rn0)RM9u7^EX~_4+fC;xx*F z0=Jq06PKUKt$vrHne0$yD0x>|NKz$Pr^1DKQ5EUNgdl+bTFpWw@Dhe-On42@J0Hzu9H=u&=N^|S}9JyxFMBNmx7vW;QmotRw-j&1yU5s<;-e9%NBD4lvh5;yd_nh0LfAU-XPk?amvqnZ+;IMr#?ECrQ zp|j2p{dw;MsG06hWHD^L5N_;fzQQ~?h#thWJaCtDLtv7{F|rNuRGqf%@~$~=XMOM{ z_iJqEUT3hSO{m$I5kh9%Vnl7;;vIA%a*qVYt12ff3_CL3P=uV9j7$gb4zEqjpUSB! zePi)-Ult|(eFC%YeBjzp_)(lLbR2oq_R}rF$VK7lgG@LEWwh;v^W&|r1^+WN1k$O@ zb3vcFeeR!nP84)jI}T5|{t(UH@Im4seN(8Dpo!H%m>sDn5Uu|*9@;VZIR*Kq`k=oO zx%3c{{;X3Q=0${45osIVB@Z&L}UgCen@b z{p`e4dAb5K168QQctjMuL;*ie@j=O%W_>an0j=P4_@CDKeb)94w^AIQd+pR z0Y`=887~3?X2tnsuT%YXjfHVi6-~KxBBbLaDCj^``9AHA&mvKGkB;yve=je7JuFD+leeknTC3OUMim))GZB{!Sz zvB(rwt)-8p=2BcqaPF1ihr7JGzw`0;&eN=j5B@5D;=@02!-<#1-W5mHqRrQE1Mjlz ze~i<*k8hvd|DCI)qW~c8J#IY3E$Qn2S7+aCa8%RIpvVy51ovGN=SOVsg1P_4|NY?q E0I+v%ssI20 literal 0 HcmV?d00001 diff --git a/templates/bundle/bundle.json b/templates/bundle/bundle.json new file mode 100644 index 0000000..c3e04ae --- /dev/null +++ b/templates/bundle/bundle.json @@ -0,0 +1,18 @@ +{ + "bundleName": "bundle", + "background": "bg.jpg", + "duration": 20, + "useWebFonts": false, + "styleHeader": { + "fill": "#f90", + "fontSize": 56, + "fontWeight": 900, + "fontFamily": "Arial Black" + }, + "styleText": { + "fill": "#fff", + "fontFamily": "Arial Black", + "fontSize": 42, + "fontWeight": 900 + } +} \ No newline at end of file diff --git a/templates/bundle/images/.gitkeep b/templates/bundle/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/templates/bundle/render/.gitkeep b/templates/bundle/render/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/templates/bundle/slides.json b/templates/bundle/slides.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/templates/bundle/slides.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/templates/bundle/slides/.gitkeep b/templates/bundle/slides/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tmp/.gitkeep b/tmp/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/views/admin/dashboard.twig b/views/admin/dashboard.twig new file mode 100644 index 0000000..44d3d6a --- /dev/null +++ b/views/admin/dashboard.twig @@ -0,0 +1,130 @@ +{% extends 'layout/admin.twig' %} + +{% block header %} + + +{% endblock %} + +{% block body %} + + + + +
    +
    + +
    +
    +

    + Available Bundles +

    + +
    +
    +
    +
    + +
    +
    +

    + Slides in rotation +

    + + + +
    + +
    +
    +
    + +
    + +
    +
    +

    Preview

    + +
    +
    + +
    +
    +

    Program

    + +
    +
    + +
    +
    +
    + + + +{% endblock %} \ No newline at end of file diff --git a/views/admin/edit.twig b/views/admin/edit.twig new file mode 100644 index 0000000..6904413 --- /dev/null +++ b/views/admin/edit.twig @@ -0,0 +1,109 @@ +{% extends 'layout/edit.twig' %} + +{% block header %} + + + + +{% endblock %} + +{% block body %} + + + + +
    +
    + +
    + +
    + +
    00:00
    +
    +
    + + + + + + +{% endblock %} + diff --git a/views/admin/editBundle.twig b/views/admin/editBundle.twig new file mode 100644 index 0000000..f217b98 --- /dev/null +++ b/views/admin/editBundle.twig @@ -0,0 +1,9 @@ +{% extends 'layout/admin.twig' %} + +{% block header %} + +{% endblock %} + +{% block body %} + +{% endblock %} \ No newline at end of file diff --git a/views/admin/listBundle.twig b/views/admin/listBundle.twig new file mode 100644 index 0000000..d33ea31 --- /dev/null +++ b/views/admin/listBundle.twig @@ -0,0 +1,30 @@ +{% extends 'layout/admin.twig' %} + +{% block header %} + +{% endblock %} + +{% block body %} + + + +
    +
    +
    +

    Available Bundles

    + +
    +
    +
    + +{% endblock %} \ No newline at end of file diff --git a/views/ajax/bundleImageList.twig b/views/ajax/bundleImageList.twig new file mode 100644 index 0000000..6ea59e8 --- /dev/null +++ b/views/ajax/bundleImageList.twig @@ -0,0 +1,15 @@ +{% for image in bundleImages %} +
    +
    + image +
    +
    +
    {{ image.name }}
    +
    +
    +
    Insert
    +
    Fill
    +
    Delete
    +
    +
    +{% endfor %} \ No newline at end of file diff --git a/views/display.twig b/views/display.twig new file mode 100644 index 0000000..dc702cc --- /dev/null +++ b/views/display.twig @@ -0,0 +1,36 @@ +{% extends 'layout/view.twig' %} + +{% block header %} + + + + InfoScreen3 - {{ display.name }} +{% endblock %} + +{% block body %} +
    + +
    + +
    00:00
    +
    + + +
    + +
    + +
    + +
    + + + + + +{% endblock %} + diff --git a/views/error.twig b/views/error.twig new file mode 100644 index 0000000..143ff6a --- /dev/null +++ b/views/error.twig @@ -0,0 +1,12 @@ +{% extends 'layout/admin.twig' %} + +{% block body %} + +

    {{ message }}

    +

    {{ error.status }}

    +
    {{ error.stack }}
    +{% endblock %} diff --git a/views/index.twig b/views/index.twig new file mode 100644 index 0000000..202f7ab --- /dev/null +++ b/views/index.twig @@ -0,0 +1,62 @@ +{% extends 'layout/view.twig' %} + +{% block header %} + +{% endblock %} + +{% block body %} +
    +
    +

    + InfoScreen3 +

    +

    Available displays

    + +
    +
    +
    +
    + + +{% endblock %} diff --git a/views/layout/admin.twig b/views/layout/admin.twig new file mode 100644 index 0000000..e6213c2 --- /dev/null +++ b/views/layout/admin.twig @@ -0,0 +1,21 @@ + + + + InfoScreen + + + + + + + + + {% block header %}{% endblock %} + + +
    + {% block body %}{% endblock %} +
    +{% block afterbody %}{% endblock %} + + diff --git a/views/layout/edit.twig b/views/layout/edit.twig new file mode 100644 index 0000000..f32c793 --- /dev/null +++ b/views/layout/edit.twig @@ -0,0 +1,24 @@ + + + + InfoScreen + + + + + + + + + + + {% block header %}{% endblock %} + + +
    + {% block body %}{% endblock %} +
    + + + + diff --git a/views/layout/view.twig b/views/layout/view.twig new file mode 100644 index 0000000..fa30839 --- /dev/null +++ b/views/layout/view.twig @@ -0,0 +1,24 @@ + + + + + + + + + + + {% block header %}{% endblock %} + + +{% block body %}{% endblock %} + + diff --git a/views/liteDisplay.twig b/views/liteDisplay.twig new file mode 100644 index 0000000..a0319c7 --- /dev/null +++ b/views/liteDisplay.twig @@ -0,0 +1,35 @@ +{% extends 'layout/view.twig' %} + +{% block header %} + + + InfoScreen3 - {{ display.name }} +{% endblock %} + +{% block body %} + +
    + +
    + +
    +
    + +
    + +
    00:00
    +
    + +
    + +
    + + + + +{% endblock %} diff --git a/views/preview.twig b/views/preview.twig new file mode 100644 index 0000000..c379ea2 --- /dev/null +++ b/views/preview.twig @@ -0,0 +1,34 @@ +{% extends 'layout/admin.twig' %} + +{% block header %} + + +{% endblock %} + +{% block body %} + + + + + + + + +{% endblock %} + +{% block afterbody %} + +{% endblock %} \ No newline at end of file