From 7a642a45f41b20bc5491a3fd1117e1c02b91cdf4 Mon Sep 17 00:00:00 2001 From: adriy Date: Wed, 12 Dec 2018 16:25:12 +0100 Subject: [PATCH] commit avant reprise --- _index_.js | 73 + _test.js | 0 bdd.js | 18 + config.json.sample | 7 + controllers/login-controller.js | 41 + controllers/register-controller.js | 23 + controllers/securepw.js | 7 + document.json | 16 + fonction.js | 22 + index.js | 112 + jsProcess | 1 + old.jd | 157 + package-lock.json | 835 ++ package.json | 15 + static/Icons/H1.png | Bin 0 -> 12615 bytes static/Icons/h0.png | Bin 0 -> 1052037 bytes static/Js/index.js | 60 + static/Js/map.js | 1 + static/Leaflet.Editable.js | 1946 ++++ static/Shapes/circle-shape.svg | 1 + static/Shapes/circles-shape.svg | 1 + static/Shapes/curve1-shape.svg | 1 + static/Shapes/curve2-shape.svg | 1 + static/Shapes/triangle-shape.svg | 1 + static/Shapes/water-shape.svg | 1 + static/css/style.css | 92 + static/old/503 Service Unavailable.htm | 13 + .../global-new.css | 116 + .../universal.css | 31 + static/old/font/summernote.eot | Bin 0 -> 16570 bytes static/old/font/summernote.ttf | Bin 0 -> 16384 bytes static/old/font/summernote.woff | Bin 0 -> 10184 bytes static/old/lang/summernote-ar-AR.js | 155 + static/old/lang/summernote-bg-BG.js | 155 + static/old/lang/summernote-ca-ES.js | 155 + static/old/lang/summernote-cs-CZ.js | 149 + static/old/lang/summernote-da-DK.js | 155 + static/old/lang/summernote-de-DE.js | 154 + static/old/lang/summernote-el-GR.js | 155 + static/old/lang/summernote-es-ES.js | 155 + static/old/lang/summernote-es-EU.js | 154 + static/old/lang/summernote-fa-IR.js | 155 + static/old/lang/summernote-fi-FI.js | 153 + static/old/lang/summernote-fr-FR.js | 155 + static/old/lang/summernote-gl-ES.js | 155 + static/old/lang/summernote-he-IL.js | 155 + static/old/lang/summernote-hr-HR.js | 155 + static/old/lang/summernote-hu-HU.js | 155 + static/old/lang/summernote-id-ID.js | 155 + static/old/lang/summernote-it-IT.js | 155 + static/old/lang/summernote-ja-JP.js | 155 + static/old/lang/summernote-ko-KR.js | 155 + static/old/lang/summernote-lt-LT.js | 155 + static/old/lang/summernote-lt-LV.js | 155 + static/old/lang/summernote-mn-MN.js | 157 + static/old/lang/summernote-nb-NO.js | 154 + static/old/lang/summernote-nl-NL.js | 155 + static/old/lang/summernote-pl-PL.js | 155 + static/old/lang/summernote-pt-BR.js | 155 + static/old/lang/summernote-pt-PT.js | 154 + static/old/lang/summernote-ro-RO.js | 155 + static/old/lang/summernote-ru-RU.js | 155 + static/old/lang/summernote-sk-SK.js | 153 + static/old/lang/summernote-sl-SI.js | 155 + static/old/lang/summernote-sr-RS-Latin.js | 155 + static/old/lang/summernote-sr-RS.js | 155 + static/old/lang/summernote-sv-SE.js | 155 + static/old/lang/summernote-ta-IN.js | 155 + static/old/lang/summernote-th-TH.js | 155 + static/old/lang/summernote-tr-TR.js | 155 + static/old/lang/summernote-uk-UA.js | 155 + static/old/lang/summernote-vi-VN.js | 155 + static/old/lang/summernote-zh-CN.js | 155 + static/old/lang/summernote-zh-TW.js | 155 + .../databasic/summernote-ext-databasic.css | 16 + .../databasic/summernote-ext-databasic.js | 292 + .../old/plugin/hello/summernote-ext-hello.js | 81 + .../summernote-ext-specialchars.js | 312 + static/old/summernote-bs4.css | 1 + static/old/summernote-bs4.js | 7285 +++++++++++++++ static/old/summernote-bs4.min.js | 3 + static/old/summernote-lite.css | 1 + static/old/summernote-lite.js | 7798 +++++++++++++++++ static/old/summernote.css | 1 + static/old/summernote.js | 7278 +++++++++++++++ static/old/summernote.min.js | 3 + static/script.js | 24 + sync.ffs_db | Bin 0 -> 9479 bytes views/TV.ejs | 117 + views/TV_old.ejs | 97 + views/_index2.ejs | 59 + views/_mapsTest.ejs | 95 + views/index.ejs | 123 + views/login.ejs | 142 + views/map.ejs | 139 + 95 files changed, 33957 insertions(+) create mode 100755 _index_.js create mode 100755 _test.js create mode 100644 bdd.js create mode 100644 config.json.sample create mode 100644 controllers/login-controller.js create mode 100644 controllers/register-controller.js create mode 100644 controllers/securepw.js create mode 100755 document.json create mode 100644 fonction.js create mode 100644 index.js create mode 100755 jsProcess create mode 100755 old.jd create mode 100755 package-lock.json create mode 100755 package.json create mode 100644 static/Icons/H1.png create mode 100644 static/Icons/h0.png create mode 100644 static/Js/index.js create mode 100644 static/Js/map.js create mode 100755 static/Leaflet.Editable.js create mode 100644 static/Shapes/circle-shape.svg create mode 100644 static/Shapes/circles-shape.svg create mode 100644 static/Shapes/curve1-shape.svg create mode 100644 static/Shapes/curve2-shape.svg create mode 100644 static/Shapes/triangle-shape.svg create mode 100644 static/Shapes/water-shape.svg create mode 100644 static/css/style.css create mode 100755 static/old/503 Service Unavailable.htm create mode 100755 static/old/503 Service Unavailable_fichiers/global-new.css create mode 100755 static/old/503 Service Unavailable_fichiers/universal.css create mode 100755 static/old/font/summernote.eot create mode 100755 static/old/font/summernote.ttf create mode 100755 static/old/font/summernote.woff create mode 100755 static/old/lang/summernote-ar-AR.js create mode 100755 static/old/lang/summernote-bg-BG.js create mode 100755 static/old/lang/summernote-ca-ES.js create mode 100755 static/old/lang/summernote-cs-CZ.js create mode 100755 static/old/lang/summernote-da-DK.js create mode 100755 static/old/lang/summernote-de-DE.js create mode 100755 static/old/lang/summernote-el-GR.js create mode 100755 static/old/lang/summernote-es-ES.js create mode 100755 static/old/lang/summernote-es-EU.js create mode 100755 static/old/lang/summernote-fa-IR.js create mode 100755 static/old/lang/summernote-fi-FI.js create mode 100755 static/old/lang/summernote-fr-FR.js create mode 100755 static/old/lang/summernote-gl-ES.js create mode 100755 static/old/lang/summernote-he-IL.js create mode 100755 static/old/lang/summernote-hr-HR.js create mode 100755 static/old/lang/summernote-hu-HU.js create mode 100755 static/old/lang/summernote-id-ID.js create mode 100755 static/old/lang/summernote-it-IT.js create mode 100755 static/old/lang/summernote-ja-JP.js create mode 100755 static/old/lang/summernote-ko-KR.js create mode 100755 static/old/lang/summernote-lt-LT.js create mode 100755 static/old/lang/summernote-lt-LV.js create mode 100755 static/old/lang/summernote-mn-MN.js create mode 100755 static/old/lang/summernote-nb-NO.js create mode 100755 static/old/lang/summernote-nl-NL.js create mode 100755 static/old/lang/summernote-pl-PL.js create mode 100755 static/old/lang/summernote-pt-BR.js create mode 100755 static/old/lang/summernote-pt-PT.js create mode 100755 static/old/lang/summernote-ro-RO.js create mode 100755 static/old/lang/summernote-ru-RU.js create mode 100755 static/old/lang/summernote-sk-SK.js create mode 100755 static/old/lang/summernote-sl-SI.js create mode 100755 static/old/lang/summernote-sr-RS-Latin.js create mode 100755 static/old/lang/summernote-sr-RS.js create mode 100755 static/old/lang/summernote-sv-SE.js create mode 100755 static/old/lang/summernote-ta-IN.js create mode 100755 static/old/lang/summernote-th-TH.js create mode 100755 static/old/lang/summernote-tr-TR.js create mode 100755 static/old/lang/summernote-uk-UA.js create mode 100755 static/old/lang/summernote-vi-VN.js create mode 100755 static/old/lang/summernote-zh-CN.js create mode 100755 static/old/lang/summernote-zh-TW.js create mode 100755 static/old/plugin/databasic/summernote-ext-databasic.css create mode 100755 static/old/plugin/databasic/summernote-ext-databasic.js create mode 100755 static/old/plugin/hello/summernote-ext-hello.js create mode 100755 static/old/plugin/specialchars/summernote-ext-specialchars.js create mode 100755 static/old/summernote-bs4.css create mode 100755 static/old/summernote-bs4.js create mode 100755 static/old/summernote-bs4.min.js create mode 100755 static/old/summernote-lite.css create mode 100755 static/old/summernote-lite.js create mode 100755 static/old/summernote.css create mode 100755 static/old/summernote.js create mode 100755 static/old/summernote.min.js create mode 100755 static/script.js create mode 100755 sync.ffs_db create mode 100755 views/TV.ejs create mode 100644 views/TV_old.ejs create mode 100644 views/_index2.ejs create mode 100755 views/_mapsTest.ejs create mode 100644 views/index.ejs create mode 100644 views/login.ejs create mode 100644 views/map.ejs diff --git a/_index_.js b/_index_.js new file mode 100755 index 0000000..a073e24 --- /dev/null +++ b/_index_.js @@ -0,0 +1,73 @@ +var express = require('express'); +var app = express(); +var http = require('http').Server(app); +var io = require('socket.io')(http); +var mysql = require('mysql'); +const util = require('util') +var bodyParser = require('body-parser'); +app.use(bodyParser.json()); // support json encoded bodies +app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies + +const config = require('./config.json'); +//console.debug(config.bdd.user) +var con = mysql.createConnection({ + host: "localhost", + user: config.bdd.user, + password: config.bdd.pw, + database : config.bdd.dbname +}); + + +app.set('view engine', 'ejs'); +app.use('/static', express.static('static')); + + +app.get('/', function(req, res){ + res.render('index'); +}).get('/TV', function(req, res){ + res.render('TV'); +}).get('/mapsTest', function(req, res){ + con.query('SELECT * FROM zone', function (err, result, fields) { + if (err) throw err; + var data = JSON.stringify(result); + data = JSON.parse(data); + res.render('mapsTest', {data:data}); + }); +}).post('/addZone' , function(req, res){ + + var nord = req.body.N; + var sud = req.body.S; + var est = req.body.E; + var ouest = req.body.O; + var name = req.body.Name; + + + con.query('CALL add_zone(?,?,?,?,?,?)', [true, name,nord,sud,ouest,est], function(err, result){ + + }); + }); + +io.on('connection', function(socket){ + socket.on('JoinZone', function(zone){ + console.log("Join "+zone) + socket.join(zone); + }); + socket.on('Communication', function(CommunicationJSON){ + var data = JSON.parse(CommunicationJSON); + console.log("JSON : "+CommunicationJSON); + console.log("ZONE "+data.zone); + io.sockets.in(data.zone).emit('Communication', CommunicationJSON); + }); +}); + + + + + + + + + +http.listen(1234, function(){ + console.log('listening on *:1234'); +}); diff --git a/_test.js b/_test.js new file mode 100755 index 0000000..e69de29 diff --git a/bdd.js b/bdd.js new file mode 100644 index 0000000..1e7ec09 --- /dev/null +++ b/bdd.js @@ -0,0 +1,18 @@ +const config = require('./config.json'); + +var mysql = require('mysql'); + +var connection = mysql.createConnection({ + host: "localhost", + user: config.bdd.user, + password: config.bdd.pw, + database : config.bdd.dbname +}); +connection.connect(function(err){ +if(!err) { + console.log("Database is connected"); +} else { + console.log("Error while connecting with database"); +} +}); +module.exports = connection; diff --git a/config.json.sample b/config.json.sample new file mode 100644 index 0000000..996af94 --- /dev/null +++ b/config.json.sample @@ -0,0 +1,7 @@ +{ + "bdd" : { + "user" : "UserBDD", + "pw" : "BDDPW", + "dbname" : "DataBaseName" + } +} diff --git a/controllers/login-controller.js b/controllers/login-controller.js new file mode 100644 index 0000000..6c62b59 --- /dev/null +++ b/controllers/login-controller.js @@ -0,0 +1,41 @@ +//http://www.expertphp.in/article/user-login-and-registration-using-nodejs-and-mysql-with-example +var connection = require('./../bdd'); +var passwordProtection = require('./securepw'); + +module.exports=function(req,res,next){ + var name=req.body.username; + var password=passwordProtection(req.body.password); + connection.query('SELECT * FROM user WHERE name = ? AND actif = 1',[name], function (error, results, fields) { + if (error) { + req.session.auth.json({ + status:false, + message:'there are some error with query' + }) + next(); + }else{ + if(results.length >0){ + if(password==results[0].pw){ + + req.session.authStatus=true; + req.session.authMessage='successfully authenticated'; + + next(); + }else{ + + req.session.authStatus=false, + req.session.authMessage="Email and password does not match"; + + next(); + } + + } + else{ + + req.session.authStatus=false; + req.session.authMessage="Email does not exits"; + + next(); + } + } + }); +} diff --git a/controllers/register-controller.js b/controllers/register-controller.js new file mode 100644 index 0000000..a2414f0 --- /dev/null +++ b/controllers/register-controller.js @@ -0,0 +1,23 @@ +// /http://www.expertphp.in/article/user-login-and-registration-using-nodejs-and-mysql-with-example +var connection = require('./../bdd'); +var passwordProtection = require('./securepw'); + +module.exports=function(req,res, next){ + var today = new Date(); + var users={ + "name":req.body.username, + "pw": passwordProtection(req.body.password) + } + connection.query('INSERT INTO user SET ?',users, function (error, results, fields) { + if (error) { + //res.local.stat = 0; + res.locals.message='there are some error with query'+error; + next(); + }else{ + //res.loacal.stat = 1; + res.locals.data = results; + res.locals.message = 'user registered sucessfully'; + next(); + } + }); +} diff --git a/controllers/securepw.js b/controllers/securepw.js new file mode 100644 index 0000000..4b13eec --- /dev/null +++ b/controllers/securepw.js @@ -0,0 +1,7 @@ +//https://lollyrock.com/articles/nodejs-encryption/ +var crypto = require('crypto'), + algorithm = 'sha-256'; + +module.exports = function(text){ + return crypto.createHash('sha256').update(text).digest('base64'); +} diff --git a/document.json b/document.json new file mode 100755 index 0000000..23cb1d0 --- /dev/null +++ b/document.json @@ -0,0 +1,16 @@ +{ + "zone" : "Liege", + "cmd" : "ping", + "ListeCom": [ + {"IDPub" : 1, + "CMD" : "add/dell", + "html" : "Hello", + "level" : 1 + }, + {"IDPub" : 2, + "CMD" : "add/dell", + "html" : "Hello", + "level" : 2 + } + ] +} \ No newline at end of file diff --git a/fonction.js b/fonction.js new file mode 100644 index 0000000..f11b7c7 --- /dev/null +++ b/fonction.js @@ -0,0 +1,22 @@ +exports.choixZone = function(zones){ + var zone = zones[0]; + var aireMin = (zones[0].Nord-zones[0].Sud)*(zones[0].Est-zones[0].Ouest) + for(var i = 1;i'+req.session.authMessage+'
HOME'); +}).post('/register', registerController, function(req, res){ + res.send(''+res.locals.message+'
HOME'); +}).post('/addZone' , function(req, res){ + + var nord = req.body.N; + var sud = req.body.S; + var est = req.body.E; + var ouest = req.body.O; + var name = req.body.Name; + + + + con.query('CALL add_zone(?,?,?,?,?,?)', [true, name,nord,sud,ouest,est], function(err, result){ + + }); + }); + +io.on('connection', function(socket){ + socket.on('JoinZone', function(zone){ + console.log("Join "+zone) + socket.join(zone); + }); + socket.on('Communication', function(CommunicationJSON){ + var data = JSON.parse(CommunicationJSON); + console.log("JSON : "+CommunicationJSON); + console.log("ZONE "+data.zone); + io.sockets.in(data.zone).emit('Communication', CommunicationJSON); + }); +}); + + + + + + + + + +http.listen(1234, function(){ + console.log('listening on *:1234'); +}); diff --git a/jsProcess b/jsProcess new file mode 100755 index 0000000..1f61070 --- /dev/null +++ b/jsProcess @@ -0,0 +1 @@ +1696 diff --git a/old.jd b/old.jd new file mode 100755 index 0000000..1e276e3 --- /dev/null +++ b/old.jd @@ -0,0 +1,157 @@ + + // Initialise the FeatureGroup to store editable layers + L.EditControl = L.Control.extend({ + + options: { + position: 'topleft', + callback: null, + kind: '', + html: '' + }, + + onAdd: function (map) { + var container = L.DomUtil.create('div', 'leaflet-control leaflet-bar'), + link = L.DomUtil.create('a', '', container); + + link.href = '#'; + link.title = 'Create a new ' + this.options.kind; + link.innerHTML = this.options.html; + L.DomEvent.on(link, 'click', L.DomEvent.stop) + .on(link, 'click', function () { + window.LAYER = this.options.callback.call(map.editTools); + }, this); + + return container; + } + + }); + + L.NewLineControl = L.EditControl.extend({ + + options: { + position: 'topleft', + callback: map.editTools.startPolyline, + kind: 'line', + html: '\\/\\' + } + + }); + + L.NewPolygonControl = L.EditControl.extend({ + + options: { + position: 'topleft', + callback: map.editTools.startPolygon, + kind: 'polygon', + html: '▰' + } + + }); + + L.NewMarkerControl = L.EditControl.extend({ + + options: { + position: 'topleft', + callback: map.editTools.startMarker, + kind: 'marker', + html: '🖈' + } + + }); + + L.NewRectangleControl = L.EditControl.extend({ + + options: { + position: 'topleft', + callback: map.editTools.startRectangle, + kind: 'rectangle', + html: '⬛' + } + + }); + + L.NewCircleControl = L.EditControl.extend({ + + options: { + position: 'topleft', + callback: map.editTools.startCircle, + kind: 'circle', + html: '⬤' + } + + }); + + map.addControl(new L.NewMarkerControl()); + map.addControl(new L.NewLineControl()); + map.addControl(new L.NewPolygonControl()); + map.addControl(new L.NewRectangleControl()); + map.addControl(new L.NewCircleControl()); + + var line = L.polyline([ + [43.1292, 1.256], + [43.1295, 1.259], + [43.1291, 1.261] + ]).addTo(map); + line.enableEdit(); + line.on('dblclick', L.DomEvent.stop).on('dblclick', line.toggleEdit); + + + var multi = L.polygon([ + [ + [ + [43.1239, 1.244], + [43.123, 1.253], + [43.1252, 1.255], + [43.1250, 1.251], + [43.1239, 1.244] + ], + [ + [43.124, 1.246], + [43.1236, 1.248], + [43.12475, 1.250] + ], + [ + [43.124, 1.251], + [43.1236, 1.253], + [43.12475, 1.254] + ] + ], + [ + [ + [43.1269, 1.246], + [43.126, 1.252], + [43.1282, 1.255], + [43.1280, 1.245] + ] + ] + ]).addTo(map); + multi.enableEdit(); + multi.on('dblclick', L.DomEvent.stop).on('dblclick', multi.toggleEdit); + multi.bindPopup('hi!'); + + var poly = L.polygon([ + [ + [43.1239, 1.259], + [43.123, 1.263], + [43.1252, 1.265], + [43.1250, 1.261] + ], + [ + [43.124, 1.263], + [43.1236, 1.261], + [43.12475, 1.262] + ] + ]).addTo(map); + poly.enableEdit(); + poly.on('dblclick', L.DomEvent.stop).on('dblclick', poly.toggleEdit); + + var rec = L.rectangle([ + [43.1235, 1.255], + [43.1215, 1.259] + ]).addTo(map); + rec.enableEdit(); + rec.on('dblclick', L.DomEvent.stop).on('dblclick', rec.toggleEdit); + + var circle = L.circle([43.1220, 1.250], {radius: 100}).addTo(map); + circle.enableEdit(); + circle.on('dblclick', L.DomEvent.stop).on('dblclick', circle.toggleEdit); diff --git a/package-lock.json b/package-lock.json new file mode 100755 index 0000000..9f78ec9 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,835 @@ +{ + "name": "TVPublicitaire", + "version": "0.0.1", + "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=" + }, + "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==" + }, + "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==" + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, + "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=" + }, + "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" + } + }, + "bignumber.js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz", + "integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==" + }, + "blob": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", + "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=" + }, + "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" + }, + "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==" + } + } + }, + "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=" + }, + "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=" + }, + "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=" + }, + "crc": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz", + "integrity": "sha1-naHpgOO9RPxck79as9ozeNheRms=" + }, + "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" + } + }, + "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=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "ejs": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", + "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "engine.io": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.0.tgz", + "integrity": "sha512-mRbgmAtQ4GAlKwuPnnAvXXwdPhEx+jkc0OBCLrXuD/CRvwNK3AxRSnqK4FSqmAMRRHryVJP8TopOvmEaA64fKw==", + "requires": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~3.3.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" + } + } + } + }, + "engine.io-client": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", + "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": "~3.3.1", + "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.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", + "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.4", + "has-binary2": "~1.0.2" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.16.3", + "resolved": "http://registry.npmjs.org/express/-/express-4.16.3.tgz", + "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "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.3", + "qs": "6.5.1", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.1", + "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": { + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.1", + "http-errors": "~1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "~2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "~1.6.15" + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": ">= 1.3.1 < 2" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + } + } + } + } + }, + "express-session": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.6.tgz", + "integrity": "sha512-r0nrHTCYtAMrFwZ0kBzZEXa1vtPVrw0dKvGSrKP4dahwBQ1BJpF2/y1Pp4sCD/0kvxV4zZeclyvfmw0B4RMJQA==", + "requires": { + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "crc": "3.4.4", + "debug": "2.6.9", + "depd": "~1.1.1", + "on-headers": "~1.0.1", + "parseurl": "~1.3.2", + "uid-safe": "~2.1.5", + "utils-merge": "1.0.1" + } + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://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" + } + }, + "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=" + }, + "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" + } + }, + "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=" + }, + "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" + } + }, + "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" + } + }, + "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=" + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mysql": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.16.0.tgz", + "integrity": "sha512-dPbN2LHonQp7D5ja5DJXNbCLe/HRdu+f3v61aguzNRQIrmZLOeRoymBYyeThrR6ug+FqzDL95Gc9maqZUJS+Gw==", + "requires": { + "bignumber.js": "4.1.0", + "readable-stream": "2.3.6", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "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=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "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" + } + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" + }, + "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": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + } + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "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.1.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", + "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", + "requires": { + "debug": "~3.1.0", + "engine.io": "~3.2.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.1.1", + "socket.io-parser": "~3.2.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" + } + } + } + }, + "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.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", + "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.2.0", + "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.2.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.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", + "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" + } + } + } + }, + "sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "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=" + }, + "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" + } + }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "~1.0.0" + } + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "util": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.0.tgz", + "integrity": "sha512-5n12uMzKCjvB2HPFHnbQSjaqAa98L5iIXmHrZCLavuZVe0qe/SJGbDGWlpaHk5lnBkWRDO+dRu1/PgmUYKPPTw==", + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.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 100755 index 0000000..c15114d --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "TVPublicitaire", + "version": "0.0.1", + "description": "Application pour TV publicitaire ou d'information à 3 niveau (Haut, moyen, bas) géolocalisé", + "dependencies": { + "body-parser": "^1.18.3", + "cookie-parser": "^1.4.3", + "ejs": "^2.6.1", + "express": "^4.16.3", + "express-session": "^1.15.6", + "mysql": "^2.16.0", + "socket.io": "^2.1.1", + "util": "^0.11.0" + } +} diff --git a/static/Icons/H1.png b/static/Icons/H1.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d85eec027495f56f8472ba538d64ee0eb37d9b GIT binary patch literal 12615 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 literal 0 HcmV?d00001 diff --git a/static/Icons/h0.png b/static/Icons/h0.png new file mode 100644 index 0000000000000000000000000000000000000000..fe9b8e7890bb8909d7fb9c24b91e7d41e4cc7bd0 GIT binary patch literal 1052037 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�uk^zU#Joat#7zx@oJVa( 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 F{{v4Sw{ZXf literal 0 HcmV?d00001 diff --git a/static/Js/index.js b/static/Js/index.js new file mode 100644 index 0000000..3aec663 --- /dev/null +++ b/static/Js/index.js @@ -0,0 +1,60 @@ + + // jus fot testing :) + console.log("Ok"); + + //Materialize js component initialization + $(document).ready(function(){ + $('select').formSelect(); + + + + + + var socket = io(); + $('#send').click(function(e){ + e.preventDefault(); + var data = {zone:$("#zone").val(), + ListeCom : new Array()}; + data.ListeCom.push({ + IDPub:-1, + html: $('#summernote').summernote('code'), + level:$("#level").val() + }); + + socket.emit('Communication', JSON.stringify(data)); + //$('#m').val(''); + return false; + }); + + $("#SendAll").click(function(){ + var data = {zone:$("#zone").val(), + ListeCom : new Array()}; + + for(var i=0;i<3;i++) + { + var f = $($("form").get(i)); + console.log(f) + data.ListeCom.push({ + IDPub:-1, + html:f.children(".com")[0].value, + level:f.children(".lvl")[0].value + }); + } + socket.emit('Communication', JSON.stringify(data)); + }) + + + socket.on('chat message', function(msg){ + //$('#messages').append($('
  • ').text(msg)); + }); + + + + }); + + //Summer note initialization + $('#summernote').summernote({ + placeholder: 'nothing', + tabsize: 2, + height: 100 + }); diff --git a/static/Js/map.js b/static/Js/map.js new file mode 100644 index 0000000..08f5795 --- /dev/null +++ b/static/Js/map.js @@ -0,0 +1 @@ + //Javascript leafletjs initialization diff --git a/static/Leaflet.Editable.js b/static/Leaflet.Editable.js new file mode 100755 index 0000000..c41b496 --- /dev/null +++ b/static/Leaflet.Editable.js @@ -0,0 +1,1946 @@ +'use strict'; +(function (factory, window) { + /*globals define, module, require*/ + + // define an AMD module that relies on 'leaflet' + if (typeof define === 'function' && define.amd) { + define(['leaflet'], factory); + + + // define a Common JS module that relies on 'leaflet' + } else if (typeof exports === 'object') { + module.exports = factory(require('leaflet')); + } + + // attach your plugin to the global 'L' variable + if(typeof window !== 'undefined' && window.L){ + factory(window.L); + } + +}(function (L) { + // 🍂miniclass CancelableEvent (Event objects) + // 🍂method cancel() + // Cancel any subsequent action. + + // 🍂miniclass VertexEvent (Event objects) + // 🍂property vertex: VertexMarker + // The vertex that fires the event. + + // 🍂miniclass ShapeEvent (Event objects) + // 🍂property shape: Array + // The shape (LatLngs array) subject of the action. + + // 🍂miniclass CancelableVertexEvent (Event objects) + // 🍂inherits VertexEvent + // 🍂inherits CancelableEvent + + // 🍂miniclass CancelableShapeEvent (Event objects) + // 🍂inherits ShapeEvent + // 🍂inherits CancelableEvent + + // 🍂miniclass LayerEvent (Event objects) + // 🍂property layer: object + // The Layer (Marker, Polyline…) subject of the action. + + // 🍂namespace Editable; 🍂class Editable; 🍂aka L.Editable + // Main edition handler. By default, it is attached to the map + // as `map.editTools` property. + // Leaflet.Editable is made to be fully extendable. You have three ways to customize + // the behaviour: using options, listening to events, or extending. + L.Editable = L.Evented.extend({ + + statics: { + FORWARD: 1, + BACKWARD: -1 + }, + + options: { + + // You can pass them when creating a map using the `editOptions` key. + // 🍂option zIndex: int = 1000 + // The default zIndex of the editing tools. + zIndex: 1000, + + // 🍂option polygonClass: class = L.Polygon + // Class to be used when creating a new Polygon. + polygonClass: L.Polygon, + + // 🍂option polylineClass: class = L.Polyline + // Class to be used when creating a new Polyline. + polylineClass: L.Polyline, + + // 🍂option markerClass: class = L.Marker + // Class to be used when creating a new Marker. + markerClass: L.Marker, + + // 🍂option rectangleClass: class = L.Rectangle + // Class to be used when creating a new Rectangle. + rectangleClass: L.Rectangle, + + // 🍂option circleClass: class = L.Circle + // Class to be used when creating a new Circle. + circleClass: L.Circle, + + // 🍂option drawingCSSClass: string = 'leaflet-editable-drawing' + // CSS class to be added to the map container while drawing. + drawingCSSClass: 'leaflet-editable-drawing', + + // 🍂option drawingCursor: const = 'crosshair' + // Cursor mode set to the map while drawing. + drawingCursor: 'crosshair', + + // 🍂option editLayer: Layer = new L.LayerGroup() + // Layer used to store edit tools (vertex, line guide…). + editLayer: undefined, + + // 🍂option featuresLayer: Layer = new L.LayerGroup() + // Default layer used to store drawn features (Marker, Polyline…). + featuresLayer: undefined, + + // 🍂option polylineEditorClass: class = PolylineEditor + // Class to be used as Polyline editor. + polylineEditorClass: undefined, + + // 🍂option polygonEditorClass: class = PolygonEditor + // Class to be used as Polygon editor. + polygonEditorClass: undefined, + + // 🍂option markerEditorClass: class = MarkerEditor + // Class to be used as Marker editor. + markerEditorClass: undefined, + + // 🍂option rectangleEditorClass: class = RectangleEditor + // Class to be used as Rectangle editor. + rectangleEditorClass: undefined, + + // 🍂option circleEditorClass: class = CircleEditor + // Class to be used as Circle editor. + circleEditorClass: undefined, + + // 🍂option lineGuideOptions: hash = {} + // Options to be passed to the line guides. + lineGuideOptions: {}, + + // 🍂option skipMiddleMarkers: boolean = false + // Set this to true if you don't want middle markers. + skipMiddleMarkers: false + + }, + + initialize: function (map, options) { + L.setOptions(this, options); + this._lastZIndex = this.options.zIndex; + this.map = map; + this.editLayer = this.createEditLayer(); + this.featuresLayer = this.createFeaturesLayer(); + this.forwardLineGuide = this.createLineGuide(); + this.backwardLineGuide = this.createLineGuide(); + }, + + fireAndForward: function (type, e) { + e = e || {}; + e.editTools = this; + this.fire(type, e); + this.map.fire(type, e); + }, + + createLineGuide: function () { + var options = L.extend({dashArray: '5,10', weight: 1, interactive: false}, this.options.lineGuideOptions); + return L.polyline([], options); + }, + + createVertexIcon: function (options) { + return L.Browser.mobile && L.Browser.touch ? new L.Editable.TouchVertexIcon(options) : new L.Editable.VertexIcon(options); + }, + + createEditLayer: function () { + return this.options.editLayer || new L.LayerGroup().addTo(this.map); + }, + + createFeaturesLayer: function () { + return this.options.featuresLayer || new L.LayerGroup().addTo(this.map); + }, + + moveForwardLineGuide: function (latlng) { + if (this.forwardLineGuide._latlngs.length) { + this.forwardLineGuide._latlngs[1] = latlng; + this.forwardLineGuide._bounds.extend(latlng); + this.forwardLineGuide.redraw(); + } + }, + + moveBackwardLineGuide: function (latlng) { + if (this.backwardLineGuide._latlngs.length) { + this.backwardLineGuide._latlngs[1] = latlng; + this.backwardLineGuide._bounds.extend(latlng); + this.backwardLineGuide.redraw(); + } + }, + + anchorForwardLineGuide: function (latlng) { + this.forwardLineGuide._latlngs[0] = latlng; + this.forwardLineGuide._bounds.extend(latlng); + this.forwardLineGuide.redraw(); + }, + + anchorBackwardLineGuide: function (latlng) { + this.backwardLineGuide._latlngs[0] = latlng; + this.backwardLineGuide._bounds.extend(latlng); + this.backwardLineGuide.redraw(); + }, + + attachForwardLineGuide: function () { + this.editLayer.addLayer(this.forwardLineGuide); + }, + + attachBackwardLineGuide: function () { + this.editLayer.addLayer(this.backwardLineGuide); + }, + + detachForwardLineGuide: function () { + this.forwardLineGuide.setLatLngs([]); + this.editLayer.removeLayer(this.forwardLineGuide); + }, + + detachBackwardLineGuide: function () { + this.backwardLineGuide.setLatLngs([]); + this.editLayer.removeLayer(this.backwardLineGuide); + }, + + blockEvents: function () { + // Hack: force map not to listen to other layers events while drawing. + if (!this._oldTargets) { + this._oldTargets = this.map._targets; + this.map._targets = {}; + } + }, + + unblockEvents: function () { + if (this._oldTargets) { + // Reset, but keep targets created while drawing. + this.map._targets = L.extend(this.map._targets, this._oldTargets); + delete this._oldTargets; + } + }, + + registerForDrawing: function (editor) { + if (this._drawingEditor) this.unregisterForDrawing(this._drawingEditor); + this.blockEvents(); + editor.reset(); // Make sure editor tools still receive events. + this._drawingEditor = editor; + this.map.on('mousemove touchmove', editor.onDrawingMouseMove, editor); + this.map.on('mousedown', this.onMousedown, this); + this.map.on('mouseup', this.onMouseup, this); + L.DomUtil.addClass(this.map._container, this.options.drawingCSSClass); + this.defaultMapCursor = this.map._container.style.cursor; + this.map._container.style.cursor = this.options.drawingCursor; + }, + + unregisterForDrawing: function (editor) { + this.unblockEvents(); + L.DomUtil.removeClass(this.map._container, this.options.drawingCSSClass); + this.map._container.style.cursor = this.defaultMapCursor; + editor = editor || this._drawingEditor; + if (!editor) return; + this.map.off('mousemove touchmove', editor.onDrawingMouseMove, editor); + this.map.off('mousedown', this.onMousedown, this); + this.map.off('mouseup', this.onMouseup, this); + if (editor !== this._drawingEditor) return; + delete this._drawingEditor; + if (editor._drawing) editor.cancelDrawing(); + }, + + onMousedown: function (e) { + if (e.originalEvent.which != 1) return; + this._mouseDown = e; + this._drawingEditor.onDrawingMouseDown(e); + }, + + onMouseup: function (e) { + if (this._mouseDown) { + var editor = this._drawingEditor, + mouseDown = this._mouseDown; + this._mouseDown = null; + editor.onDrawingMouseUp(e); + if (this._drawingEditor !== editor) return; // onDrawingMouseUp may call unregisterFromDrawing. + var origin = L.point(mouseDown.originalEvent.clientX, mouseDown.originalEvent.clientY); + var distance = L.point(e.originalEvent.clientX, e.originalEvent.clientY).distanceTo(origin); + if (Math.abs(distance) < 9 * (window.devicePixelRatio || 1)) this._drawingEditor.onDrawingClick(e); + } + }, + + // 🍂section Public methods + // You will generally access them by the `map.editTools` + // instance: + // + // `map.editTools.startPolyline();` + + // 🍂method drawing(): boolean + // Return true if any drawing action is ongoing. + drawing: function () { + return this._drawingEditor && this._drawingEditor.drawing(); + }, + + // 🍂method stopDrawing() + // When you need to stop any ongoing drawing, without needing to know which editor is active. + stopDrawing: function () { + this.unregisterForDrawing(); + }, + + // 🍂method commitDrawing() + // When you need to commit any ongoing drawing, without needing to know which editor is active. + commitDrawing: function (e) { + if (!this._drawingEditor) return; + this._drawingEditor.commitDrawing(e); + }, + + connectCreatedToMap: function (layer) { + return this.featuresLayer.addLayer(layer); + }, + + // 🍂method startPolyline(latlng: L.LatLng, options: hash): L.Polyline + // Start drawing a Polyline. If `latlng` is given, a first point will be added. In any case, continuing on user click. + // If `options` is given, it will be passed to the Polyline class constructor. + startPolyline: function (latlng, options) { + var line = this.createPolyline([], options); + line.enableEdit(this.map).newShape(latlng); + return line; + }, + + // 🍂method startPolygon(latlng: L.LatLng, options: hash): L.Polygon + // Start drawing a Polygon. If `latlng` is given, a first point will be added. In any case, continuing on user click. + // If `options` is given, it will be passed to the Polygon class constructor. + startPolygon: function (latlng, options) { + var polygon = this.createPolygon([], options); + polygon.enableEdit(this.map).newShape(latlng); + return polygon; + }, + + // 🍂method startMarker(latlng: L.LatLng, options: hash): L.Marker + // Start adding a Marker. If `latlng` is given, the Marker will be shown first at this point. + // In any case, it will follow the user mouse, and will have a final `latlng` on next click (or touch). + // If `options` is given, it will be passed to the Marker class constructor. + startMarker: function (latlng, options) { + latlng = latlng || this.map.getCenter().clone(); + var marker = this.createMarker(latlng, options); + marker.enableEdit(this.map).startDrawing(); + return marker; + }, + + // 🍂method startRectangle(latlng: L.LatLng, options: hash): L.Rectangle + // Start drawing a Rectangle. If `latlng` is given, the Rectangle anchor will be added. In any case, continuing on user drag. + // If `options` is given, it will be passed to the Rectangle class constructor. + startRectangle: function(latlng, options) { + var corner = latlng || L.latLng([0, 0]); + var bounds = new L.LatLngBounds(corner, corner); + var rectangle = this.createRectangle(bounds, options); + rectangle.enableEdit(this.map).startDrawing(); + return rectangle; + }, + + // 🍂method startCircle(latlng: L.LatLng, options: hash): L.Circle + // Start drawing a Circle. If `latlng` is given, the Circle anchor will be added. In any case, continuing on user drag. + // If `options` is given, it will be passed to the Circle class constructor. + startCircle: function (latlng, options) { + latlng = latlng || this.map.getCenter().clone(); + var circle = this.createCircle(latlng, options); + circle.enableEdit(this.map).startDrawing(); + return circle; + }, + + startHole: function (editor, latlng) { + editor.newHole(latlng); + }, + + createLayer: function (klass, latlngs, options) { + options = L.Util.extend({editOptions: {editTools: this}}, options); + var layer = new klass(latlngs, options); + // 🍂namespace Editable + // 🍂event editable:created: LayerEvent + // Fired when a new feature (Marker, Polyline…) is created. + this.fireAndForward('editable:created', {layer: layer}); + return layer; + }, + + createPolyline: function (latlngs, options) { + return this.createLayer(options && options.polylineClass || this.options.polylineClass, latlngs, options); + }, + + createPolygon: function (latlngs, options) { + return this.createLayer(options && options.polygonClass || this.options.polygonClass, latlngs, options); + }, + + createMarker: function (latlng, options) { + return this.createLayer(options && options.markerClass || this.options.markerClass, latlng, options); + }, + + createRectangle: function (bounds, options) { + return this.createLayer(options && options.rectangleClass || this.options.rectangleClass, bounds, options); + }, + + createCircle: function (latlng, options) { + return this.createLayer(options && options.circleClass || this.options.circleClass, latlng, options); + } + + }); + + L.extend(L.Editable, { + + makeCancellable: function (e) { + e.cancel = function () { + e._cancelled = true; + }; + } + + }); + + // 🍂namespace Map; 🍂class Map + // Leaflet.Editable add options and events to the `L.Map` object. + // See `Editable` events for the list of events fired on the Map. + // 🍂example + // + // ```js + // var map = L.map('map', { + // editable: true, + // editOptions: { + // … + // } + // }); + // ``` + // 🍂section Editable Map Options + L.Map.mergeOptions({ + + // 🍂namespace Map + // 🍂section Map Options + // 🍂option editToolsClass: class = L.Editable + // Class to be used as vertex, for path editing. + editToolsClass: L.Editable, + + // 🍂option editable: boolean = false + // Whether to create a L.Editable instance at map init. + editable: false, + + // 🍂option editOptions: hash = {} + // Options to pass to L.Editable when instantiating. + editOptions: {} + + }); + + L.Map.addInitHook(function () { + + this.whenReady(function () { + if (this.options.editable) { + this.editTools = new this.options.editToolsClass(this, this.options.editOptions); + } + }); + + }); + + L.Editable.VertexIcon = L.DivIcon.extend({ + + options: { + iconSize: new L.Point(8, 8) + } + + }); + + L.Editable.TouchVertexIcon = L.Editable.VertexIcon.extend({ + + options: { + iconSize: new L.Point(20, 20) + } + + }); + + + // 🍂namespace Editable; 🍂class VertexMarker; Handler for dragging path vertices. + L.Editable.VertexMarker = L.Marker.extend({ + + options: { + draggable: true, + className: 'leaflet-div-icon leaflet-vertex-icon' + }, + + + // 🍂section Public methods + // The marker used to handle path vertex. You will usually interact with a `VertexMarker` + // instance when listening for events like `editable:vertex:ctrlclick`. + + initialize: function (latlng, latlngs, editor, options) { + // We don't use this._latlng, because on drag Leaflet replace it while + // we want to keep reference. + this.latlng = latlng; + this.latlngs = latlngs; + this.editor = editor; + L.Marker.prototype.initialize.call(this, latlng, options); + this.options.icon = this.editor.tools.createVertexIcon({className: this.options.className}); + this.latlng.__vertex = this; + this.editor.editLayer.addLayer(this); + this.setZIndexOffset(editor.tools._lastZIndex + 1); + }, + + onAdd: function (map) { + L.Marker.prototype.onAdd.call(this, map); + this.on('drag', this.onDrag); + this.on('dragstart', this.onDragStart); + this.on('dragend', this.onDragEnd); + this.on('mouseup', this.onMouseup); + this.on('click', this.onClick); + this.on('contextmenu', this.onContextMenu); + this.on('mousedown touchstart', this.onMouseDown); + this.on('mouseover', this.onMouseOver); + this.on('mouseout', this.onMouseOut); + this.addMiddleMarkers(); + }, + + onRemove: function (map) { + if (this.middleMarker) this.middleMarker.delete(); + delete this.latlng.__vertex; + this.off('drag', this.onDrag); + this.off('dragstart', this.onDragStart); + this.off('dragend', this.onDragEnd); + this.off('mouseup', this.onMouseup); + this.off('click', this.onClick); + this.off('contextmenu', this.onContextMenu); + this.off('mousedown touchstart', this.onMouseDown); + this.off('mouseover', this.onMouseOver); + this.off('mouseout', this.onMouseOut); + L.Marker.prototype.onRemove.call(this, map); + }, + + onDrag: function (e) { + e.vertex = this; + this.editor.onVertexMarkerDrag(e); + var iconPos = L.DomUtil.getPosition(this._icon), + latlng = this._map.layerPointToLatLng(iconPos); + this.latlng.update(latlng); + this._latlng = this.latlng; // Push back to Leaflet our reference. + this.editor.refresh(); + if (this.middleMarker) this.middleMarker.updateLatLng(); + var next = this.getNext(); + if (next && next.middleMarker) next.middleMarker.updateLatLng(); + }, + + onDragStart: function (e) { + e.vertex = this; + this.editor.onVertexMarkerDragStart(e); + }, + + onDragEnd: function (e) { + e.vertex = this; + this.editor.onVertexMarkerDragEnd(e); + }, + + onClick: function (e) { + e.vertex = this; + this.editor.onVertexMarkerClick(e); + }, + + onMouseup: function (e) { + L.DomEvent.stop(e); + e.vertex = this; + this.editor.map.fire('mouseup', e); + }, + + onContextMenu: function (e) { + e.vertex = this; + this.editor.onVertexMarkerContextMenu(e); + }, + + onMouseDown: function (e) { + e.vertex = this; + this.editor.onVertexMarkerMouseDown(e); + }, + + onMouseOver: function (e) { + e.vertex = this; + this.editor.onVertexMarkerMouseOver(e); + }, + + onMouseOut: function (e) { + e.vertex = this; + this.editor.onVertexMarkerMouseOut(e); + }, + + // 🍂method delete() + // Delete a vertex and the related LatLng. + delete: function () { + var next = this.getNext(); // Compute before changing latlng + this.latlngs.splice(this.getIndex(), 1); + this.editor.editLayer.removeLayer(this); + this.editor.onVertexDeleted({latlng: this.latlng, vertex: this}); + if (!this.latlngs.length) this.editor.deleteShape(this.latlngs); + if (next) next.resetMiddleMarker(); + this.editor.refresh(); + }, + + // 🍂method getIndex(): int + // Get the index of the current vertex among others of the same LatLngs group. + getIndex: function () { + return this.latlngs.indexOf(this.latlng); + }, + + // 🍂method getLastIndex(): int + // Get last vertex index of the LatLngs group of the current vertex. + getLastIndex: function () { + return this.latlngs.length - 1; + }, + + // 🍂method getPrevious(): VertexMarker + // Get the previous VertexMarker in the same LatLngs group. + getPrevious: function () { + if (this.latlngs.length < 2) return; + var index = this.getIndex(), + previousIndex = index - 1; + if (index === 0 && this.editor.CLOSED) previousIndex = this.getLastIndex(); + var previous = this.latlngs[previousIndex]; + if (previous) return previous.__vertex; + }, + + // 🍂method getNext(): VertexMarker + // Get the next VertexMarker in the same LatLngs group. + getNext: function () { + if (this.latlngs.length < 2) return; + var index = this.getIndex(), + nextIndex = index + 1; + if (index === this.getLastIndex() && this.editor.CLOSED) nextIndex = 0; + var next = this.latlngs[nextIndex]; + if (next) return next.__vertex; + }, + + addMiddleMarker: function (previous) { + if (!this.editor.hasMiddleMarkers()) return; + previous = previous || this.getPrevious(); + if (previous && !this.middleMarker) this.middleMarker = this.editor.addMiddleMarker(previous, this, this.latlngs, this.editor); + }, + + addMiddleMarkers: function () { + if (!this.editor.hasMiddleMarkers()) return; + var previous = this.getPrevious(); + if (previous) this.addMiddleMarker(previous); + var next = this.getNext(); + if (next) next.resetMiddleMarker(); + }, + + resetMiddleMarker: function () { + if (this.middleMarker) this.middleMarker.delete(); + this.addMiddleMarker(); + }, + + // 🍂method split() + // Split the vertex LatLngs group at its index, if possible. + split: function () { + if (!this.editor.splitShape) return; // Only for PolylineEditor + this.editor.splitShape(this.latlngs, this.getIndex()); + }, + + // 🍂method continue() + // Continue the vertex LatLngs from this vertex. Only active for first and last vertices of a Polyline. + continue: function () { + if (!this.editor.continueBackward) return; // Only for PolylineEditor + var index = this.getIndex(); + if (index === 0) this.editor.continueBackward(this.latlngs); + else if (index === this.getLastIndex()) this.editor.continueForward(this.latlngs); + } + + }); + + L.Editable.mergeOptions({ + + // 🍂namespace Editable + // 🍂option vertexMarkerClass: class = VertexMarker + // Class to be used as vertex, for path editing. + vertexMarkerClass: L.Editable.VertexMarker + + }); + + L.Editable.MiddleMarker = L.Marker.extend({ + + options: { + opacity: 0.5, + className: 'leaflet-div-icon leaflet-middle-icon', + draggable: true + }, + + initialize: function (left, right, latlngs, editor, options) { + this.left = left; + this.right = right; + this.editor = editor; + this.latlngs = latlngs; + L.Marker.prototype.initialize.call(this, this.computeLatLng(), options); + this._opacity = this.options.opacity; + this.options.icon = this.editor.tools.createVertexIcon({className: this.options.className}); + this.editor.editLayer.addLayer(this); + this.setVisibility(); + }, + + setVisibility: function () { + var leftPoint = this._map.latLngToContainerPoint(this.left.latlng), + rightPoint = this._map.latLngToContainerPoint(this.right.latlng), + size = L.point(this.options.icon.options.iconSize); + if (leftPoint.distanceTo(rightPoint) < size.x * 3) this.hide(); + else this.show(); + }, + + show: function () { + this.setOpacity(this._opacity); + }, + + hide: function () { + this.setOpacity(0); + }, + + updateLatLng: function () { + this.setLatLng(this.computeLatLng()); + this.setVisibility(); + }, + + computeLatLng: function () { + var leftPoint = this.editor.map.latLngToContainerPoint(this.left.latlng), + rightPoint = this.editor.map.latLngToContainerPoint(this.right.latlng), + y = (leftPoint.y + rightPoint.y) / 2, + x = (leftPoint.x + rightPoint.x) / 2; + return this.editor.map.containerPointToLatLng([x, y]); + }, + + onAdd: function (map) { + L.Marker.prototype.onAdd.call(this, map); + L.DomEvent.on(this._icon, 'mousedown touchstart', this.onMouseDown, this); + map.on('zoomend', this.setVisibility, this); + }, + + onRemove: function (map) { + delete this.right.middleMarker; + L.DomEvent.off(this._icon, 'mousedown touchstart', this.onMouseDown, this); + map.off('zoomend', this.setVisibility, this); + L.Marker.prototype.onRemove.call(this, map); + }, + + onMouseDown: function (e) { + var iconPos = L.DomUtil.getPosition(this._icon), + latlng = this.editor.map.layerPointToLatLng(iconPos); + e = { + originalEvent: e, + latlng: latlng + }; + if (this.options.opacity === 0) return; + L.Editable.makeCancellable(e); + this.editor.onMiddleMarkerMouseDown(e); + if (e._cancelled) return; + this.latlngs.splice(this.index(), 0, e.latlng); + this.editor.refresh(); + var icon = this._icon; + var marker = this.editor.addVertexMarker(e.latlng, this.latlngs); + this.editor.onNewVertex(marker); + /* Hack to workaround browser not firing touchend when element is no more on DOM */ + var parent = marker._icon.parentNode; + parent.removeChild(marker._icon); + marker._icon = icon; + parent.appendChild(marker._icon); + marker._initIcon(); + marker._initInteraction(); + marker.setOpacity(1); + /* End hack */ + // Transfer ongoing dragging to real marker + L.Draggable._dragging = false; + marker.dragging._draggable._onDown(e.originalEvent); + this.delete(); + }, + + delete: function () { + this.editor.editLayer.removeLayer(this); + }, + + index: function () { + return this.latlngs.indexOf(this.right.latlng); + } + + }); + + L.Editable.mergeOptions({ + + // 🍂namespace Editable + // 🍂option middleMarkerClass: class = VertexMarker + // Class to be used as middle vertex, pulled by the user to create a new point in the middle of a path. + middleMarkerClass: L.Editable.MiddleMarker + + }); + + // 🍂namespace Editable; 🍂class BaseEditor; 🍂aka L.Editable.BaseEditor + // When editing a feature (Marker, Polyline…), an editor is attached to it. This + // editor basically knows how to handle the edition. + L.Editable.BaseEditor = L.Handler.extend({ + + initialize: function (map, feature, options) { + L.setOptions(this, options); + this.map = map; + this.feature = feature; + this.feature.editor = this; + this.editLayer = new L.LayerGroup(); + this.tools = this.options.editTools || map.editTools; + }, + + // 🍂method enable(): this + // Set up the drawing tools for the feature to be editable. + addHooks: function () { + if (this.isConnected()) this.onFeatureAdd(); + else this.feature.once('add', this.onFeatureAdd, this); + this.onEnable(); + this.feature.on(this._getEvents(), this); + }, + + // 🍂method disable(): this + // Remove the drawing tools for the feature. + removeHooks: function () { + this.feature.off(this._getEvents(), this); + if (this.feature.dragging) this.feature.dragging.disable(); + this.editLayer.clearLayers(); + this.tools.editLayer.removeLayer(this.editLayer); + this.onDisable(); + if (this._drawing) this.cancelDrawing(); + }, + + // 🍂method drawing(): boolean + // Return true if any drawing action is ongoing with this editor. + drawing: function () { + return !!this._drawing; + }, + + reset: function () {}, + + onFeatureAdd: function () { + this.tools.editLayer.addLayer(this.editLayer); + if (this.feature.dragging) this.feature.dragging.enable(); + }, + + hasMiddleMarkers: function () { + return !this.options.skipMiddleMarkers && !this.tools.options.skipMiddleMarkers; + }, + + fireAndForward: function (type, e) { + e = e || {}; + e.layer = this.feature; + this.feature.fire(type, e); + this.tools.fireAndForward(type, e); + }, + + onEnable: function () { + // 🍂namespace Editable + // 🍂event editable:enable: Event + // Fired when an existing feature is ready to be edited. + this.fireAndForward('editable:enable'); + }, + + onDisable: function () { + // 🍂namespace Editable + // 🍂event editable:disable: Event + // Fired when an existing feature is not ready anymore to be edited. + this.fireAndForward('editable:disable'); + }, + + onEditing: function () { + // 🍂namespace Editable + // 🍂event editable:editing: Event + // Fired as soon as any change is made to the feature geometry. + this.fireAndForward('editable:editing'); + }, + + onStartDrawing: function () { + // 🍂namespace Editable + // 🍂section Drawing events + // 🍂event editable:drawing:start: Event + // Fired when a feature is to be drawn. + this.fireAndForward('editable:drawing:start'); + }, + + onEndDrawing: function () { + // 🍂namespace Editable + // 🍂section Drawing events + // 🍂event editable:drawing:end: Event + // Fired when a feature is not drawn anymore. + this.fireAndForward('editable:drawing:end'); + }, + + onCancelDrawing: function () { + // 🍂namespace Editable + // 🍂section Drawing events + // 🍂event editable:drawing:cancel: Event + // Fired when user cancel drawing while a feature is being drawn. + this.fireAndForward('editable:drawing:cancel'); + }, + + onCommitDrawing: function (e) { + // 🍂namespace Editable + // 🍂section Drawing events + // 🍂event editable:drawing:commit: Event + // Fired when user finish drawing a feature. + this.fireAndForward('editable:drawing:commit', e); + }, + + onDrawingMouseDown: function (e) { + // 🍂namespace Editable + // 🍂section Drawing events + // 🍂event editable:drawing:mousedown: Event + // Fired when user `mousedown` while drawing. + this.fireAndForward('editable:drawing:mousedown', e); + }, + + onDrawingMouseUp: function (e) { + // 🍂namespace Editable + // 🍂section Drawing events + // 🍂event editable:drawing:mouseup: Event + // Fired when user `mouseup` while drawing. + this.fireAndForward('editable:drawing:mouseup', e); + }, + + startDrawing: function () { + if (!this._drawing) this._drawing = L.Editable.FORWARD; + this.tools.registerForDrawing(this); + this.onStartDrawing(); + }, + + commitDrawing: function (e) { + this.onCommitDrawing(e); + this.endDrawing(); + }, + + cancelDrawing: function () { + // If called during a vertex drag, the vertex will be removed before + // the mouseup fires on it. This is a workaround. Maybe better fix is + // To have L.Draggable reset it's status on disable (Leaflet side). + L.Draggable._dragging = false; + this.onCancelDrawing(); + this.endDrawing(); + }, + + endDrawing: function () { + this._drawing = false; + this.tools.unregisterForDrawing(this); + this.onEndDrawing(); + }, + + onDrawingClick: function (e) { + if (!this.drawing()) return; + L.Editable.makeCancellable(e); + // 🍂namespace Editable + // 🍂section Drawing events + // 🍂event editable:drawing:click: CancelableEvent + // Fired when user `click` while drawing, before any internal action is being processed. + this.fireAndForward('editable:drawing:click', e); + if (e._cancelled) return; + if (!this.isConnected()) this.connect(e); + this.processDrawingClick(e); + }, + + isConnected: function () { + return this.map.hasLayer(this.feature); + }, + + connect: function () { + this.tools.connectCreatedToMap(this.feature); + this.tools.editLayer.addLayer(this.editLayer); + }, + + onMove: function (e) { + // 🍂namespace Editable + // 🍂section Drawing events + // 🍂event editable:drawing:move: Event + // Fired when `move` mouse while drawing, while dragging a marker, and while dragging a vertex. + this.fireAndForward('editable:drawing:move', e); + }, + + onDrawingMouseMove: function (e) { + this.onMove(e); + }, + + _getEvents: function () { + return { + dragstart: this.onDragStart, + drag: this.onDrag, + dragend: this.onDragEnd, + remove: this.disable + }; + }, + + onDragStart: function (e) { + this.onEditing(); + // 🍂namespace Editable + // 🍂event editable:dragstart: Event + // Fired before a path feature is dragged. + this.fireAndForward('editable:dragstart', e); + }, + + onDrag: function (e) { + this.onMove(e); + // 🍂namespace Editable + // 🍂event editable:drag: Event + // Fired when a path feature is being dragged. + this.fireAndForward('editable:drag', e); + }, + + onDragEnd: function (e) { + // 🍂namespace Editable + // 🍂event editable:dragend: Event + // Fired after a path feature has been dragged. + this.fireAndForward('editable:dragend', e); + } + + }); + + // 🍂namespace Editable; 🍂class MarkerEditor; 🍂aka L.Editable.MarkerEditor + // 🍂inherits BaseEditor + // Editor for Marker. + L.Editable.MarkerEditor = L.Editable.BaseEditor.extend({ + + onDrawingMouseMove: function (e) { + L.Editable.BaseEditor.prototype.onDrawingMouseMove.call(this, e); + if (this._drawing) this.feature.setLatLng(e.latlng); + }, + + processDrawingClick: function (e) { + // 🍂namespace Editable + // 🍂section Drawing events + // 🍂event editable:drawing:clicked: Event + // Fired when user `click` while drawing, after all internal actions. + this.fireAndForward('editable:drawing:clicked', e); + this.commitDrawing(e); + }, + + connect: function (e) { + // On touch, the latlng has not been updated because there is + // no mousemove. + if (e) this.feature._latlng = e.latlng; + L.Editable.BaseEditor.prototype.connect.call(this, e); + } + + }); + + // 🍂namespace Editable; 🍂class PathEditor; 🍂aka L.Editable.PathEditor + // 🍂inherits BaseEditor + // Base class for all path editors. + L.Editable.PathEditor = L.Editable.BaseEditor.extend({ + + CLOSED: false, + MIN_VERTEX: 2, + + addHooks: function () { + L.Editable.BaseEditor.prototype.addHooks.call(this); + if (this.feature) this.initVertexMarkers(); + return this; + }, + + initVertexMarkers: function (latlngs) { + if (!this.enabled()) return; + latlngs = latlngs || this.getLatLngs(); + if (isFlat(latlngs)) this.addVertexMarkers(latlngs); + else for (var i = 0; i < latlngs.length; i++) this.initVertexMarkers(latlngs[i]); + }, + + getLatLngs: function () { + return this.feature.getLatLngs(); + }, + + // 🍂method reset() + // Rebuild edit elements (Vertex, MiddleMarker, etc.). + reset: function () { + this.editLayer.clearLayers(); + this.initVertexMarkers(); + }, + + addVertexMarker: function (latlng, latlngs) { + return new this.tools.options.vertexMarkerClass(latlng, latlngs, this); + }, + + onNewVertex: function (vertex) { + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:new: VertexEvent + // Fired when a new vertex is created. + this.fireAndForward('editable:vertex:new', {latlng: vertex.latlng, vertex: vertex}); + }, + + addVertexMarkers: function (latlngs) { + for (var i = 0; i < latlngs.length; i++) { + this.addVertexMarker(latlngs[i], latlngs); + } + }, + + refreshVertexMarkers: function (latlngs) { + latlngs = latlngs || this.getDefaultLatLngs(); + for (var i = 0; i < latlngs.length; i++) { + latlngs[i].__vertex.update(); + } + }, + + addMiddleMarker: function (left, right, latlngs) { + return new this.tools.options.middleMarkerClass(left, right, latlngs, this); + }, + + onVertexMarkerClick: function (e) { + L.Editable.makeCancellable(e); + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:click: CancelableVertexEvent + // Fired when a `click` is issued on a vertex, before any internal action is being processed. + this.fireAndForward('editable:vertex:click', e); + if (e._cancelled) return; + if (this.tools.drawing() && this.tools._drawingEditor !== this) return; + var index = e.vertex.getIndex(), commit; + if (e.originalEvent.ctrlKey) { + this.onVertexMarkerCtrlClick(e); + } else if (e.originalEvent.altKey) { + this.onVertexMarkerAltClick(e); + } else if (e.originalEvent.shiftKey) { + this.onVertexMarkerShiftClick(e); + } else if (e.originalEvent.metaKey) { + this.onVertexMarkerMetaKeyClick(e); + } else if (index === e.vertex.getLastIndex() && this._drawing === L.Editable.FORWARD) { + if (index >= this.MIN_VERTEX - 1) commit = true; + } else if (index === 0 && this._drawing === L.Editable.BACKWARD && this._drawnLatLngs.length >= this.MIN_VERTEX) { + commit = true; + } else if (index === 0 && this._drawing === L.Editable.FORWARD && this._drawnLatLngs.length >= this.MIN_VERTEX && this.CLOSED) { + commit = true; // Allow to close on first point also for polygons + } else { + this.onVertexRawMarkerClick(e); + } + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:clicked: VertexEvent + // Fired when a `click` is issued on a vertex, after all internal actions. + this.fireAndForward('editable:vertex:clicked', e); + if (commit) this.commitDrawing(e); + }, + + onVertexRawMarkerClick: function (e) { + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:rawclick: CancelableVertexEvent + // Fired when a `click` is issued on a vertex without any special key and without being in drawing mode. + this.fireAndForward('editable:vertex:rawclick', e); + if (e._cancelled) return; + if (!this.vertexCanBeDeleted(e.vertex)) return; + e.vertex.delete(); + }, + + vertexCanBeDeleted: function (vertex) { + return vertex.latlngs.length > this.MIN_VERTEX; + }, + + onVertexDeleted: function (e) { + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:deleted: VertexEvent + // Fired after a vertex has been deleted by user. + this.fireAndForward('editable:vertex:deleted', e); + }, + + onVertexMarkerCtrlClick: function (e) { + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:ctrlclick: VertexEvent + // Fired when a `click` with `ctrlKey` is issued on a vertex. + this.fireAndForward('editable:vertex:ctrlclick', e); + }, + + onVertexMarkerShiftClick: function (e) { + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:shiftclick: VertexEvent + // Fired when a `click` with `shiftKey` is issued on a vertex. + this.fireAndForward('editable:vertex:shiftclick', e); + }, + + onVertexMarkerMetaKeyClick: function (e) { + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:metakeyclick: VertexEvent + // Fired when a `click` with `metaKey` is issued on a vertex. + this.fireAndForward('editable:vertex:metakeyclick', e); + }, + + onVertexMarkerAltClick: function (e) { + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:altclick: VertexEvent + // Fired when a `click` with `altKey` is issued on a vertex. + this.fireAndForward('editable:vertex:altclick', e); + }, + + onVertexMarkerContextMenu: function (e) { + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:contextmenu: VertexEvent + // Fired when a `contextmenu` is issued on a vertex. + this.fireAndForward('editable:vertex:contextmenu', e); + }, + + onVertexMarkerMouseDown: function (e) { + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:mousedown: VertexEvent + // Fired when user `mousedown` a vertex. + this.fireAndForward('editable:vertex:mousedown', e); + }, + + onVertexMarkerMouseOver: function (e) { + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:mouseover: VertexEvent + // Fired when a user's mouse enters the vertex + this.fireAndForward('editable:vertex:mouseover', e); + }, + + onVertexMarkerMouseOut: function (e) { + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:mouseout: VertexEvent + // Fired when a user's mouse leaves the vertex + this.fireAndForward('editable:vertex:mouseout', e); + }, + + onMiddleMarkerMouseDown: function (e) { + // 🍂namespace Editable + // 🍂section MiddleMarker events + // 🍂event editable:middlemarker:mousedown: VertexEvent + // Fired when user `mousedown` a middle marker. + this.fireAndForward('editable:middlemarker:mousedown', e); + }, + + onVertexMarkerDrag: function (e) { + this.onMove(e); + if (this.feature._bounds) this.extendBounds(e); + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:drag: VertexEvent + // Fired when a vertex is dragged by user. + this.fireAndForward('editable:vertex:drag', e); + }, + + onVertexMarkerDragStart: function (e) { + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:dragstart: VertexEvent + // Fired before a vertex is dragged by user. + this.fireAndForward('editable:vertex:dragstart', e); + }, + + onVertexMarkerDragEnd: function (e) { + // 🍂namespace Editable + // 🍂section Vertex events + // 🍂event editable:vertex:dragend: VertexEvent + // Fired after a vertex is dragged by user. + this.fireAndForward('editable:vertex:dragend', e); + }, + + setDrawnLatLngs: function (latlngs) { + this._drawnLatLngs = latlngs || this.getDefaultLatLngs(); + }, + + startDrawing: function () { + if (!this._drawnLatLngs) this.setDrawnLatLngs(); + L.Editable.BaseEditor.prototype.startDrawing.call(this); + }, + + startDrawingForward: function () { + this.startDrawing(); + }, + + endDrawing: function () { + this.tools.detachForwardLineGuide(); + this.tools.detachBackwardLineGuide(); + if (this._drawnLatLngs && this._drawnLatLngs.length < this.MIN_VERTEX) this.deleteShape(this._drawnLatLngs); + L.Editable.BaseEditor.prototype.endDrawing.call(this); + delete this._drawnLatLngs; + }, + + addLatLng: function (latlng) { + if (this._drawing === L.Editable.FORWARD) this._drawnLatLngs.push(latlng); + else this._drawnLatLngs.unshift(latlng); + this.feature._bounds.extend(latlng); + var vertex = this.addVertexMarker(latlng, this._drawnLatLngs); + this.onNewVertex(vertex); + this.refresh(); + }, + + newPointForward: function (latlng) { + this.addLatLng(latlng); + this.tools.attachForwardLineGuide(); + this.tools.anchorForwardLineGuide(latlng); + }, + + newPointBackward: function (latlng) { + this.addLatLng(latlng); + this.tools.anchorBackwardLineGuide(latlng); + }, + + // 🍂namespace PathEditor + // 🍂method push() + // Programmatically add a point while drawing. + push: function (latlng) { + if (!latlng) return console.error('L.Editable.PathEditor.push expect a valid latlng as parameter'); + if (this._drawing === L.Editable.FORWARD) this.newPointForward(latlng); + else this.newPointBackward(latlng); + }, + + removeLatLng: function (latlng) { + latlng.__vertex.delete(); + this.refresh(); + }, + + // 🍂method pop(): L.LatLng or null + // Programmatically remove last point (if any) while drawing. + pop: function () { + if (this._drawnLatLngs.length <= 1) return; + var latlng; + if (this._drawing === L.Editable.FORWARD) latlng = this._drawnLatLngs[this._drawnLatLngs.length - 1]; + else latlng = this._drawnLatLngs[0]; + this.removeLatLng(latlng); + if (this._drawing === L.Editable.FORWARD) this.tools.anchorForwardLineGuide(this._drawnLatLngs[this._drawnLatLngs.length - 1]); + else this.tools.anchorForwardLineGuide(this._drawnLatLngs[0]); + return latlng; + }, + + processDrawingClick: function (e) { + if (e.vertex && e.vertex.editor === this) return; + if (this._drawing === L.Editable.FORWARD) this.newPointForward(e.latlng); + else this.newPointBackward(e.latlng); + this.fireAndForward('editable:drawing:clicked', e); + }, + + onDrawingMouseMove: function (e) { + L.Editable.BaseEditor.prototype.onDrawingMouseMove.call(this, e); + if (this._drawing) { + this.tools.moveForwardLineGuide(e.latlng); + this.tools.moveBackwardLineGuide(e.latlng); + } + }, + + refresh: function () { + this.feature.redraw(); + this.onEditing(); + }, + + // 🍂namespace PathEditor + // 🍂method newShape(latlng?: L.LatLng) + // Add a new shape (Polyline, Polygon) in a multi, and setup up drawing tools to draw it; + // if optional `latlng` is given, start a path at this point. + newShape: function (latlng) { + var shape = this.addNewEmptyShape(); + if (!shape) return; + this.setDrawnLatLngs(shape[0] || shape); // Polygon or polyline + this.startDrawingForward(); + // 🍂namespace Editable + // 🍂section Shape events + // 🍂event editable:shape:new: ShapeEvent + // Fired when a new shape is created in a multi (Polygon or Polyline). + this.fireAndForward('editable:shape:new', {shape: shape}); + if (latlng) this.newPointForward(latlng); + }, + + deleteShape: function (shape, latlngs) { + var e = {shape: shape}; + L.Editable.makeCancellable(e); + // 🍂namespace Editable + // 🍂section Shape events + // 🍂event editable:shape:delete: CancelableShapeEvent + // Fired before a new shape is deleted in a multi (Polygon or Polyline). + this.fireAndForward('editable:shape:delete', e); + if (e._cancelled) return; + shape = this._deleteShape(shape, latlngs); + if (this.ensureNotFlat) this.ensureNotFlat(); // Polygon. + this.feature.setLatLngs(this.getLatLngs()); // Force bounds reset. + this.refresh(); + this.reset(); + // 🍂namespace Editable + // 🍂section Shape events + // 🍂event editable:shape:deleted: ShapeEvent + // Fired after a new shape is deleted in a multi (Polygon or Polyline). + this.fireAndForward('editable:shape:deleted', {shape: shape}); + return shape; + }, + + _deleteShape: function (shape, latlngs) { + latlngs = latlngs || this.getLatLngs(); + if (!latlngs.length) return; + var self = this, + inplaceDelete = function (latlngs, shape) { + // Called when deleting a flat latlngs + shape = latlngs.splice(0, Number.MAX_VALUE); + return shape; + }, + spliceDelete = function (latlngs, shape) { + // Called when removing a latlngs inside an array + latlngs.splice(latlngs.indexOf(shape), 1); + if (!latlngs.length) self._deleteShape(latlngs); + return shape; + }; + if (latlngs === shape) return inplaceDelete(latlngs, shape); + for (var i = 0; i < latlngs.length; i++) { + if (latlngs[i] === shape) return spliceDelete(latlngs, shape); + else if (latlngs[i].indexOf(shape) !== -1) return spliceDelete(latlngs[i], shape); + } + }, + + // 🍂namespace PathEditor + // 🍂method deleteShapeAt(latlng: L.LatLng): Array + // Remove a path shape at the given `latlng`. + deleteShapeAt: function (latlng) { + var shape = this.feature.shapeAt(latlng); + if (shape) return this.deleteShape(shape); + }, + + // 🍂method appendShape(shape: Array) + // Append a new shape to the Polygon or Polyline. + appendShape: function (shape) { + this.insertShape(shape); + }, + + // 🍂method prependShape(shape: Array) + // Prepend a new shape to the Polygon or Polyline. + prependShape: function (shape) { + this.insertShape(shape, 0); + }, + + // 🍂method insertShape(shape: Array, index: int) + // Insert a new shape to the Polygon or Polyline at given index (default is to append). + insertShape: function (shape, index) { + this.ensureMulti(); + shape = this.formatShape(shape); + if (typeof index === 'undefined') index = this.feature._latlngs.length; + this.feature._latlngs.splice(index, 0, shape); + this.feature.redraw(); + if (this._enabled) this.reset(); + }, + + extendBounds: function (e) { + this.feature._bounds.extend(e.vertex.latlng); + }, + + onDragStart: function (e) { + this.editLayer.clearLayers(); + L.Editable.BaseEditor.prototype.onDragStart.call(this, e); + }, + + onDragEnd: function (e) { + this.initVertexMarkers(); + L.Editable.BaseEditor.prototype.onDragEnd.call(this, e); + } + + }); + + // 🍂namespace Editable; 🍂class PolylineEditor; 🍂aka L.Editable.PolylineEditor + // 🍂inherits PathEditor + L.Editable.PolylineEditor = L.Editable.PathEditor.extend({ + + startDrawingBackward: function () { + this._drawing = L.Editable.BACKWARD; + this.startDrawing(); + }, + + // 🍂method continueBackward(latlngs?: Array) + // Set up drawing tools to continue the line backward. + continueBackward: function (latlngs) { + if (this.drawing()) return; + latlngs = latlngs || this.getDefaultLatLngs(); + this.setDrawnLatLngs(latlngs); + if (latlngs.length > 0) { + this.tools.attachBackwardLineGuide(); + this.tools.anchorBackwardLineGuide(latlngs[0]); + } + this.startDrawingBackward(); + }, + + // 🍂method continueForward(latlngs?: Array) + // Set up drawing tools to continue the line forward. + continueForward: function (latlngs) { + if (this.drawing()) return; + latlngs = latlngs || this.getDefaultLatLngs(); + this.setDrawnLatLngs(latlngs); + if (latlngs.length > 0) { + this.tools.attachForwardLineGuide(); + this.tools.anchorForwardLineGuide(latlngs[latlngs.length - 1]); + } + this.startDrawingForward(); + }, + + getDefaultLatLngs: function (latlngs) { + latlngs = latlngs || this.feature._latlngs; + if (!latlngs.length || latlngs[0] instanceof L.LatLng) return latlngs; + else return this.getDefaultLatLngs(latlngs[0]); + }, + + ensureMulti: function () { + if (this.feature._latlngs.length && isFlat(this.feature._latlngs)) { + this.feature._latlngs = [this.feature._latlngs]; + } + }, + + addNewEmptyShape: function () { + if (this.feature._latlngs.length) { + var shape = []; + this.appendShape(shape); + return shape; + } else { + return this.feature._latlngs; + } + }, + + formatShape: function (shape) { + if (isFlat(shape)) return shape; + else if (shape[0]) return this.formatShape(shape[0]); + }, + + // 🍂method splitShape(latlngs?: Array, index: int) + // Split the given `latlngs` shape at index `index` and integrate new shape in instance `latlngs`. + splitShape: function (shape, index) { + if (!index || index >= shape.length - 1) return; + this.ensureMulti(); + var shapeIndex = this.feature._latlngs.indexOf(shape); + if (shapeIndex === -1) return; + var first = shape.slice(0, index + 1), + second = shape.slice(index); + // We deal with reference, we don't want twice the same latlng around. + second[0] = L.latLng(second[0].lat, second[0].lng, second[0].alt); + this.feature._latlngs.splice(shapeIndex, 1, first, second); + this.refresh(); + this.reset(); + } + + }); + + // 🍂namespace Editable; 🍂class PolygonEditor; 🍂aka L.Editable.PolygonEditor + // 🍂inherits PathEditor + L.Editable.PolygonEditor = L.Editable.PathEditor.extend({ + + CLOSED: true, + MIN_VERTEX: 3, + + newPointForward: function (latlng) { + L.Editable.PathEditor.prototype.newPointForward.call(this, latlng); + if (!this.tools.backwardLineGuide._latlngs.length) this.tools.anchorBackwardLineGuide(latlng); + if (this._drawnLatLngs.length === 2) this.tools.attachBackwardLineGuide(); + }, + + addNewEmptyHole: function (latlng) { + this.ensureNotFlat(); + var latlngs = this.feature.shapeAt(latlng); + if (!latlngs) return; + var holes = []; + latlngs.push(holes); + return holes; + }, + + // 🍂method newHole(latlng?: L.LatLng, index: int) + // Set up drawing tools for creating a new hole on the Polygon. If the `latlng` param is given, a first point is created. + newHole: function (latlng) { + var holes = this.addNewEmptyHole(latlng); + if (!holes) return; + this.setDrawnLatLngs(holes); + this.startDrawingForward(); + if (latlng) this.newPointForward(latlng); + }, + + addNewEmptyShape: function () { + if (this.feature._latlngs.length && this.feature._latlngs[0].length) { + var shape = []; + this.appendShape(shape); + return shape; + } else { + return this.feature._latlngs; + } + }, + + ensureMulti: function () { + if (this.feature._latlngs.length && isFlat(this.feature._latlngs[0])) { + this.feature._latlngs = [this.feature._latlngs]; + } + }, + + ensureNotFlat: function () { + if (!this.feature._latlngs.length || isFlat(this.feature._latlngs)) this.feature._latlngs = [this.feature._latlngs]; + }, + + vertexCanBeDeleted: function (vertex) { + var parent = this.feature.parentShape(vertex.latlngs), + idx = L.Util.indexOf(parent, vertex.latlngs); + if (idx > 0) return true; // Holes can be totally deleted without removing the layer itself. + return L.Editable.PathEditor.prototype.vertexCanBeDeleted.call(this, vertex); + }, + + getDefaultLatLngs: function () { + if (!this.feature._latlngs.length) this.feature._latlngs.push([]); + return this.feature._latlngs[0]; + }, + + formatShape: function (shape) { + // [[1, 2], [3, 4]] => must be nested + // [] => must be nested + // [[]] => is already nested + if (isFlat(shape) && (!shape[0] || shape[0].length !== 0)) return [shape]; + else return shape; + } + + }); + + // 🍂namespace Editable; 🍂class RectangleEditor; 🍂aka L.Editable.RectangleEditor + // 🍂inherits PathEditor + L.Editable.RectangleEditor = L.Editable.PathEditor.extend({ + + CLOSED: true, + MIN_VERTEX: 4, + + options: { + skipMiddleMarkers: true + }, + + extendBounds: function (e) { + var index = e.vertex.getIndex(), + next = e.vertex.getNext(), + previous = e.vertex.getPrevious(), + oppositeIndex = (index + 2) % 4, + opposite = e.vertex.latlngs[oppositeIndex], + bounds = new L.LatLngBounds(e.latlng, opposite); + // Update latlngs by hand to preserve order. + previous.latlng.update([e.latlng.lat, opposite.lng]); + next.latlng.update([opposite.lat, e.latlng.lng]); + this.updateBounds(bounds); + this.refreshVertexMarkers(); + }, + + onDrawingMouseDown: function (e) { + L.Editable.PathEditor.prototype.onDrawingMouseDown.call(this, e); + this.connect(); + var latlngs = this.getDefaultLatLngs(); + // L.Polygon._convertLatLngs removes last latlng if it equals first point, + // which is the case here as all latlngs are [0, 0] + if (latlngs.length === 3) latlngs.push(e.latlng); + var bounds = new L.LatLngBounds(e.latlng, e.latlng); + this.updateBounds(bounds); + this.updateLatLngs(bounds); + this.refresh(); + this.reset(); + // Stop dragging map. + // L.Draggable has two workflows: + // - mousedown => mousemove => mouseup + // - touchstart => touchmove => touchend + // Problem: L.Map.Tap does not allow us to listen to touchstart, so we only + // can deal with mousedown, but then when in a touch device, we are dealing with + // simulated events (actually simulated by L.Map.Tap), which are no more taken + // into account by L.Draggable. + // Ref.: https://github.com/Leaflet/Leaflet.Editable/issues/103 + e.originalEvent._simulated = false; + this.map.dragging._draggable._onUp(e.originalEvent); + // Now transfer ongoing drag action to the bottom right corner. + // Should we refine which corner will handle the drag according to + // drag direction? + latlngs[3].__vertex.dragging._draggable._onDown(e.originalEvent); + }, + + onDrawingMouseUp: function (e) { + this.commitDrawing(e); + e.originalEvent._simulated = false; + L.Editable.PathEditor.prototype.onDrawingMouseUp.call(this, e); + }, + + onDrawingMouseMove: function (e) { + e.originalEvent._simulated = false; + L.Editable.PathEditor.prototype.onDrawingMouseMove.call(this, e); + }, + + + getDefaultLatLngs: function (latlngs) { + return latlngs || this.feature._latlngs[0]; + }, + + updateBounds: function (bounds) { + this.feature._bounds = bounds; + }, + + updateLatLngs: function (bounds) { + var latlngs = this.getDefaultLatLngs(), + newLatlngs = this.feature._boundsToLatLngs(bounds); + // Keep references. + for (var i = 0; i < latlngs.length; i++) { + latlngs[i].update(newLatlngs[i]); + } + } + + }); + + // 🍂namespace Editable; 🍂class CircleEditor; 🍂aka L.Editable.CircleEditor + // 🍂inherits PathEditor + L.Editable.CircleEditor = L.Editable.PathEditor.extend({ + + MIN_VERTEX: 2, + + options: { + skipMiddleMarkers: true + }, + + initialize: function (map, feature, options) { + L.Editable.PathEditor.prototype.initialize.call(this, map, feature, options); + this._resizeLatLng = this.computeResizeLatLng(); + }, + + computeResizeLatLng: function () { + // While circle is not added to the map, _radius is not set. + var delta = (this.feature._radius || this.feature._mRadius) * Math.cos(Math.PI / 4), + point = this.map.project(this.feature._latlng); + return this.map.unproject([point.x + delta, point.y - delta]); + }, + + updateResizeLatLng: function () { + this._resizeLatLng.update(this.computeResizeLatLng()); + this._resizeLatLng.__vertex.update(); + }, + + getLatLngs: function () { + return [this.feature._latlng, this._resizeLatLng]; + }, + + getDefaultLatLngs: function () { + return this.getLatLngs(); + }, + + onVertexMarkerDrag: function (e) { + if (e.vertex.getIndex() === 1) this.resize(e); + else this.updateResizeLatLng(e); + L.Editable.PathEditor.prototype.onVertexMarkerDrag.call(this, e); + }, + + resize: function (e) { + var radius = this.feature._latlng.distanceTo(e.latlng); + this.feature.setRadius(radius); + }, + + onDrawingMouseDown: function (e) { + L.Editable.PathEditor.prototype.onDrawingMouseDown.call(this, e); + this._resizeLatLng.update(e.latlng); + this.feature._latlng.update(e.latlng); + this.connect(); + // Stop dragging map. + e.originalEvent._simulated = false; + this.map.dragging._draggable._onUp(e.originalEvent); + // Now transfer ongoing drag action to the radius handler. + this._resizeLatLng.__vertex.dragging._draggable._onDown(e.originalEvent); + }, + + onDrawingMouseUp: function (e) { + this.commitDrawing(e); + e.originalEvent._simulated = false; + L.Editable.PathEditor.prototype.onDrawingMouseUp.call(this, e); + }, + + onDrawingMouseMove: function (e) { + e.originalEvent._simulated = false; + L.Editable.PathEditor.prototype.onDrawingMouseMove.call(this, e); + }, + + onDrag: function (e) { + L.Editable.PathEditor.prototype.onDrag.call(this, e); + this.feature.dragging.updateLatLng(this._resizeLatLng); + } + + }); + + // 🍂namespace Editable; 🍂class EditableMixin + // `EditableMixin` is included to `L.Polyline`, `L.Polygon`, `L.Rectangle`, `L.Circle` + // and `L.Marker`. It adds some methods to them. + // *When editing is enabled, the editor is accessible on the instance with the + // `editor` property.* + var EditableMixin = { + + createEditor: function (map) { + map = map || this._map; + var tools = (this.options.editOptions || {}).editTools || map.editTools; + if (!tools) throw Error('Unable to detect Editable instance.'); + var Klass = this.options.editorClass || this.getEditorClass(tools); + return new Klass(map, this, this.options.editOptions); + }, + + // 🍂method enableEdit(map?: L.Map): this.editor + // Enable editing, by creating an editor if not existing, and then calling `enable` on it. + enableEdit: function (map) { + if (!this.editor) this.createEditor(map); + this.editor.enable(); + return this.editor; + }, + + // 🍂method editEnabled(): boolean + // Return true if current instance has an editor attached, and this editor is enabled. + editEnabled: function () { + return this.editor && this.editor.enabled(); + }, + + // 🍂method disableEdit() + // Disable editing, also remove the editor property reference. + disableEdit: function () { + if (this.editor) { + this.editor.disable(); + delete this.editor; + } + }, + + // 🍂method toggleEdit() + // Enable or disable editing, according to current status. + toggleEdit: function () { + if (this.editEnabled()) this.disableEdit(); + else this.enableEdit(); + }, + + _onEditableAdd: function () { + if (this.editor) this.enableEdit(); + } + + }; + + var PolylineMixin = { + + getEditorClass: function (tools) { + return (tools && tools.options.polylineEditorClass) ? tools.options.polylineEditorClass : L.Editable.PolylineEditor; + }, + + shapeAt: function (latlng, latlngs) { + // We can have those cases: + // - latlngs are just a flat array of latlngs, use this + // - latlngs is an array of arrays of latlngs, loop over + var shape = null; + latlngs = latlngs || this._latlngs; + if (!latlngs.length) return shape; + else if (isFlat(latlngs) && this.isInLatLngs(latlng, latlngs)) shape = latlngs; + else for (var i = 0; i < latlngs.length; i++) if (this.isInLatLngs(latlng, latlngs[i])) return latlngs[i]; + return shape; + }, + + isInLatLngs: function (l, latlngs) { + if (!latlngs) return false; + var i, k, len, part = [], p, + w = this._clickTolerance(); + this._projectLatlngs(latlngs, part, this._pxBounds); + part = part[0]; + p = this._map.latLngToLayerPoint(l); + + if (!this._pxBounds.contains(p)) { return false; } + for (i = 1, len = part.length, k = 0; i < len; k = i++) { + + if (L.LineUtil.pointToSegmentDistance(p, part[k], part[i]) <= w) { + return true; + } + } + return false; + } + + }; + + var PolygonMixin = { + + getEditorClass: function (tools) { + return (tools && tools.options.polygonEditorClass) ? tools.options.polygonEditorClass : L.Editable.PolygonEditor; + }, + + shapeAt: function (latlng, latlngs) { + // We can have those cases: + // - latlngs are just a flat array of latlngs, use this + // - latlngs is an array of arrays of latlngs, this is a simple polygon (maybe with holes), use the first + // - latlngs is an array of arrays of arrays, this is a multi, loop over + var shape = null; + latlngs = latlngs || this._latlngs; + if (!latlngs.length) return shape; + else if (isFlat(latlngs) && this.isInLatLngs(latlng, latlngs)) shape = latlngs; + else if (isFlat(latlngs[0]) && this.isInLatLngs(latlng, latlngs[0])) shape = latlngs; + else for (var i = 0; i < latlngs.length; i++) if (this.isInLatLngs(latlng, latlngs[i][0])) return latlngs[i]; + return shape; + }, + + isInLatLngs: function (l, latlngs) { + var inside = false, l1, l2, j, k, len2; + + for (j = 0, len2 = latlngs.length, k = len2 - 1; j < len2; k = j++) { + l1 = latlngs[j]; + l2 = latlngs[k]; + + if (((l1.lat > l.lat) !== (l2.lat > l.lat)) && + (l.lng < (l2.lng - l1.lng) * (l.lat - l1.lat) / (l2.lat - l1.lat) + l1.lng)) { + inside = !inside; + } + } + + return inside; + }, + + parentShape: function (shape, latlngs) { + latlngs = latlngs || this._latlngs; + if (!latlngs) return; + var idx = L.Util.indexOf(latlngs, shape); + if (idx !== -1) return latlngs; + for (var i = 0; i < latlngs.length; i++) { + idx = L.Util.indexOf(latlngs[i], shape); + if (idx !== -1) return latlngs[i]; + } + } + + }; + + + var MarkerMixin = { + + getEditorClass: function (tools) { + return (tools && tools.options.markerEditorClass) ? tools.options.markerEditorClass : L.Editable.MarkerEditor; + } + + }; + + var RectangleMixin = { + + getEditorClass: function (tools) { + return (tools && tools.options.rectangleEditorClass) ? tools.options.rectangleEditorClass : L.Editable.RectangleEditor; + } + + }; + + var CircleMixin = { + + getEditorClass: function (tools) { + return (tools && tools.options.circleEditorClass) ? tools.options.circleEditorClass : L.Editable.CircleEditor; + } + + }; + + var keepEditable = function () { + // Make sure you can remove/readd an editable layer. + this.on('add', this._onEditableAdd); + }; + + var isFlat = L.LineUtil.isFlat || L.LineUtil._flat || L.Polyline._flat; // <=> 1.1 compat. + + + if (L.Polyline) { + L.Polyline.include(EditableMixin); + L.Polyline.include(PolylineMixin); + L.Polyline.addInitHook(keepEditable); + } + if (L.Polygon) { + L.Polygon.include(EditableMixin); + L.Polygon.include(PolygonMixin); + } + if (L.Marker) { + L.Marker.include(EditableMixin); + L.Marker.include(MarkerMixin); + L.Marker.addInitHook(keepEditable); + } + if (L.Rectangle) { + L.Rectangle.include(EditableMixin); + L.Rectangle.include(RectangleMixin); + } + if (L.Circle) { + L.Circle.include(EditableMixin); + L.Circle.include(CircleMixin); + } + + L.LatLng.prototype.update = function (latlng) { + latlng = L.latLng(latlng); + this.lat = latlng.lat; + this.lng = latlng.lng; + } + +}, window)); diff --git a/static/Shapes/circle-shape.svg b/static/Shapes/circle-shape.svg new file mode 100644 index 0000000..ba09fa7 --- /dev/null +++ b/static/Shapes/circle-shape.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/Shapes/circles-shape.svg b/static/Shapes/circles-shape.svg new file mode 100644 index 0000000..ad17dfc --- /dev/null +++ b/static/Shapes/circles-shape.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/Shapes/curve1-shape.svg b/static/Shapes/curve1-shape.svg new file mode 100644 index 0000000..b05d2ee --- /dev/null +++ b/static/Shapes/curve1-shape.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/Shapes/curve2-shape.svg b/static/Shapes/curve2-shape.svg new file mode 100644 index 0000000..3296bdb --- /dev/null +++ b/static/Shapes/curve2-shape.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/Shapes/triangle-shape.svg b/static/Shapes/triangle-shape.svg new file mode 100644 index 0000000..2f6e767 --- /dev/null +++ b/static/Shapes/triangle-shape.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/Shapes/water-shape.svg b/static/Shapes/water-shape.svg new file mode 100644 index 0000000..2afabbc --- /dev/null +++ b/static/Shapes/water-shape.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000..3a1fae1 --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,92 @@ + + +@import url('https://fonts.googleapis.com/css?family=K2D:700|Nunito:400,700'); + +body{ + display: flex; + min-height: 100vh; + /*overflow-y: hidden;*/ + flex-direction: column; + background-color: #EDEDED; +} +*{ + font-family: sans-serif; +} + +nav{ + background-color: #EDEDED; + box-shadow: none; +} +nav.nav-wrapper{ + background-color: white; +} +a.brand-logo,ul li a{ + font-family: 'K2D',sans-serif; + color: #FEFEFE; + z-index: 100; +} +div#water-shape{ + position: fixed; + width: 600px; +} +div#circle-shape{ + position: fixed; + width: 100px; + margin-left: 700px; + margin-top: 100px; + text-align: center; +} +div#curve-shape{ + position: fixed; + width: 600px; + margin-left: 800px; +} +div#curve-two-shape{ + z-index: -1; + position: fixed; + width: 500px; + margin-top: 180px; + margin-left: -250px; +} +div#triangle-shape{ + position: fixed; + width: 150px; + margin-left: 650px; + margin-top: 500px; +} +div#body{ + margin-top: 100px; +} +h1.title{ + font-family: 'Nunito',sans-serif; + font-weight: 700; +} +p.sub-title{ + color: #686666; + font-family: 'Nunito',sans-serif; +} +a.bordered{ + border-radius: 30px; + text-decoration: none; + color: white; + font-family: 'Nunito',sans-serif; +} +.center-btn{ + text-align: center; +} + +footer img{ + margin-top: -120px +} +/*CSS for the map page*/ + +a.brand-logo-map{ +font-family: 'K2D',sans-serif; +font-size: 30px; + color: #FEFEFE; + z-index: 100; +} +div#mapid{ + height: 420px; +} + diff --git a/static/old/503 Service Unavailable.htm b/static/old/503 Service Unavailable.htm new file mode 100755 index 0000000..37774ad --- /dev/null +++ b/static/old/503 Service Unavailable.htm @@ -0,0 +1,13 @@ + + + +503 Service Unavailable + +

    Service Unavailable

    +

    The server is temporarily unable to service your +request due to maintenance downtime or capacity +problems. Please try again later.

    +
    +
    Apache/2.4.25 (Debian) Server at nodejs.adriy.be Port 80
    + + \ No newline at end of file diff --git a/static/old/503 Service Unavailable_fichiers/global-new.css b/static/old/503 Service Unavailable_fichiers/global-new.css new file mode 100755 index 0000000..001c3ee --- /dev/null +++ b/static/old/503 Service Unavailable_fichiers/global-new.css @@ -0,0 +1,116 @@ +html, html * { +color: rgb(183, 183, 183) !important;} +*{border-color:#a4afaf !important;} + +input[type="button"]:hover, input[type="submit"]:not(.color):hover, +input[type="reset"]:hover, button:hover, select:hover { + color: #e9e9e9 !important; + background-color: #303030 !important; +} + +html > body[class] a,html > body[class] a[class] { + color: #6091c1 !important; +} +a, a[class] { + color: #6091c1 !important; +} +html > body svg[class] { + fill: rgb(183, 183, 183); +} +html > body svg { + fill: rgb(183, 183, 183); +} +li { + color: #004db3 !important; +} + +tr { + color: #653d3d !important; +} + +cite { + color: #268 !important; +} + +input { + color: #257 !important; +} + +em { + color: #DEF !important; +} + +ul { + color: #650000 !important; +} + +nobr { + color: #4a0505 !important; +} + + +strong { + color: #9CC !important; +} + + +b { + color: #7AF !important; +} + +a:hover, a:hover *, a:visited:hover, a:visited:hover *, span[onclick]:hover, div[onclick]:hover, +[role="link"]:hover, [role="link"]:hover *, [role="button"]:hover *, [role="menuitem"]:hover, [role="menuitem"]:hover *, .link:hover, .link:hover * { + color: #2a3bb1 !important; + background-color: #0000009c !important; +} + +a:visited, a:visited * { + color: #607069 !important +} + +a.highlight, a.highlight *, a.active, a.active *, .selected, .selected *, [href="#"] { + color: #DDD !important; + font-weight: bold !important +} + +textarea, i, td { + color: #ACE !important; + /* text-shadow: -1px -1px #000, 1px -1px #000, -1px 1px #000, 1px 1px #000 !important; */ +} +/* Removed selection color + ::-moz-selection { + color: #0FF !important; + background-color: #333 !important; +} + + ::selection { + color: #0FF !important; + background-color: #333 !important; +} + + ::-webkit-selection { + color: #0FF !important; + background-color: #333 !important; +} +*/ + +abbr, progress, time, label, .date { + color: #CDEFC2 !important; +} + +mark, code, pre, blockquote, [class*="quote"], td[style*="inset"][class="alt2"] { + background-color: #00090F !important; +} + + /* Removed because dropdown icons were having black background unnecessarily. +nav, menu, html body [class*="open"], html body [id*="Dropdown"], html body [id*="dropdown"], html body [class*="Dropdown"], +html body [class*="dropdown"], html body [id*="menu"]:not(SELECT), html body [class*="menu"]:NOT(SELECT), html body [class*="tooltip"], +html body [class*="popup"], html body [id*="popup"], html body [class*="note"], html body [class*="detail"], html body [class*="description"] { + background-color: #232323 !important; +} + */ + + +[onclick]:hover, [ondblclick]:hover, [onmousedown]:hover { + color: #FEFF97 !important +} diff --git a/static/old/503 Service Unavailable_fichiers/universal.css b/static/old/503 Service Unavailable_fichiers/universal.css new file mode 100755 index 0000000..82b667f --- /dev/null +++ b/static/old/503 Service Unavailable_fichiers/universal.css @@ -0,0 +1,31 @@ +/*html { + background-color: #252525 !important; + background-image: none !important; +}*/ +::-webkit-scrollbar { + width: 7px; + height: 7px; +} +::-webkit-scrollbar-button { + width: 0px; + height: 0px; +} +::-webkit-scrollbar-thumb { + background: #525252; + border: 0px none #ffffff; + border-radius: 50px; +} +::-webkit-scrollbar-thumb:hover { + background: #4c4c4c; +} +::-webkit-scrollbar-thumb:active { + background: #404040; +} +::-webkit-scrollbar-track { + background: #272727; + border: 0px dashed #ffffff; + border-radius: 22px; +} +::-webkit-scrollbar-corner { + background: transparent; +} diff --git a/static/old/font/summernote.eot b/static/old/font/summernote.eot new file mode 100755 index 0000000000000000000000000000000000000000..4b6f0f6b9fc3bff341537ef50405922a81f8ab25 GIT binary patch literal 16570 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 literal 0 HcmV?d00001 diff --git a/static/old/font/summernote.ttf b/static/old/font/summernote.ttf new file mode 100755 index 0000000000000000000000000000000000000000..514099b602e4339a49a34293d2d845f2d905e092 GIT binary patch literal 16384 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', + tooltip: lang.image.resizeFull, + click: context.createInvokeHandler('editor.resize', '1') + }).render(); + }); + context.memo('button.databasicSize50', function() { + return ui.button({ + contents: '50%', + tooltip: lang.image.resizeHalf, + click: context.createInvokeHandler('editor.resize', '0.5') + }).render(); + }); + context.memo('button.databasicSize25', function() { + return ui.button({ + contents: '25%', + tooltip: lang.image.resizeQuarter, + click: context.createInvokeHandler('editor.resize', '0.25') + }).render(); + }); + + self.events = { + 'summernote.init': function(we, e) { + // update existing containers + $('data.ext-databasic', e.editable).each(function() { self.setContent($(this)); }); + // TODO: make this an undo snapshot... + }, + 'summernote.keyup summernote.mouseup summernote.change summernote.scroll': function() { + self.update(); + }, + 'summernote.dialog.shown': function() { + self.hidePopover(); + } + }; + + self.initialize = function() { + // create dialog markup + var $container = options.dialogsInBody ? $(document.body) : context.layoutInfo.editor; + + var body = '
    ' + + '' + + '' + + '
    '; + var footer = ''; + + self.$dialog = ui.dialog({ + title: lang.databasic.name, + fade: options.dialogsFade, + body: body, + footer: footer + }).render().appendTo($container); + + // create popover + self.$popover = ui.popover({ + className: 'ext-databasic-popover' + }).render().appendTo('body'); + var $content = self.$popover.find('.popover-content'); + + context.invoke('buttons.build', $content, options.popover.databasic); + }; + + self.destroy = function() { + self.$popover.remove(); + self.$popover = null; + self.$dialog.remove(); + self.$dialog = null; + }; + + self.update = function() { + // Prevent focusing on editable when invoke('code') is executed + if (!context.invoke('editor.hasFocus')) { + self.hidePopover(); + return; + } + + var rng = context.invoke('editor.createRange'); + var visible = false; + + if (rng.isOnData()) { + var $data = $(rng.sc).closest('data.ext-databasic'); + + if ($data.length) { + var pos = dom.posFromPlaceholder($data[0]); + + self.$popover.css({ + display: 'block', + left: pos.left, + top: pos.top + }); + + // save editor target to let size buttons resize the container + context.invoke('editor.saveTarget', $data[0]); + + visible = true; + } + } + + // hide if not visible + if (!visible) { + self.hidePopover(); + } + }; + + self.hidePopover = function() { + self.$popover.hide(); + }; + + // define plugin dialog + self.getInfo = function() { + var rng = context.invoke('editor.createRange'); + + if (rng.isOnData()) { + var $data = $(rng.sc).closest('data.ext-databasic'); + + if ($data.length) { + // Get the first node on range(for edit). + return { + node: $data, + test: $data.attr('data-test') + }; + } + } + + return {}; + }; + + self.setContent = function($node) { + $node.html('

    ' + self.icon + ' ' + lang.databasic.name + ': ' + + $node.attr('data-test') + '

    '); + }; + + self.updateNode = function(info) { + self.setContent(info.node + .attr('data-test', info.test)); + }; + + self.createNode = function(info) { + var $node = $(''); + + if ($node) { + // save node to info structure + info.node = $node; + // insert node into editor dom + context.invoke('editor.insertNode', $node[0]); + } + + return $node; + }; + + self.showDialog = function() { + var info = self.getInfo(); + var newNode = !info.node; + context.invoke('editor.saveRange'); + + self + .openDialog(info) + .then(function(dialogInfo) { + // [workaround] hide dialog before restore range for IE range focus + ui.hideDialog(self.$dialog); + context.invoke('editor.restoreRange'); + + // insert a new node + if (newNode) { + self.createNode(info); + } + + // update info with dialog info + $.extend(info, dialogInfo); + + self.updateNode(info); + }) + .fail(function() { + context.invoke('editor.restoreRange'); + }); + }; + + self.openDialog = function(info) { + return $.Deferred(function(deferred) { + var $inpTest = self.$dialog.find('.ext-databasic-test'); + var $saveBtn = self.$dialog.find('.ext-databasic-save'); + var onKeyup = function(event) { + if (event.keyCode === 13) { + $saveBtn.trigger('click'); + } + }; + + ui.onDialogShown(self.$dialog, function() { + context.triggerEvent('dialog.shown'); + + $inpTest.val(info.test).on('input', function() { + ui.toggleBtn($saveBtn, $inpTest.val()); + }).trigger('focus').on('keyup', onKeyup); + + $saveBtn + .text(info.node ? lang.databasic.edit : lang.databasic.insert) + .click(function(event) { + event.preventDefault(); + + deferred.resolve({ test: $inpTest.val() }); + }); + + // init save button + ui.toggleBtn($saveBtn, $inpTest.val()); + }); + + ui.onDialogHidden(self.$dialog, function() { + $inpTest.off('input keyup'); + $saveBtn.off('click'); + + if (deferred.state() === 'pending') { + deferred.reject(); + } + }); + + ui.showDialog(self.$dialog); + }); + }; + }; + + // Extends summernote + $.extend(true, $.summernote, { + plugins: { + databasic: DataBasicPlugin + }, + + options: { + popover: { + databasic: [ + ['databasic', ['databasicDialog', 'databasicSize100', 'databasicSize50', 'databasicSize25']] + ] + } + }, + + // add localization texts + lang: { + 'en-US': { + databasic: { + name: 'Basic Data Container', + insert: 'insert basic data container', + edit: 'edit basic data container', + testLabel: 'test input' + } + } + } + + }); +})); diff --git a/static/old/plugin/hello/summernote-ext-hello.js b/static/old/plugin/hello/summernote-ext-hello.js new file mode 100755 index 0000000..22e4f6a --- /dev/null +++ b/static/old/plugin/hello/summernote-ext-hello.js @@ -0,0 +1,81 @@ +(function(factory) { + /* global define */ + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof module === 'object' && module.exports) { + // Node/CommonJS + module.exports = factory(require('jquery')); + } else { + // Browser globals + factory(window.jQuery); + } +}(function($) { + // Extends plugins for adding hello. + // - plugin is external module for customizing. + $.extend($.summernote.plugins, { + /** + * @param {Object} context - context object has status of editor. + */ + 'hello': function(context) { + var self = this; + + // ui has renders to build ui elements. + // - you can create a button with `ui.button` + var ui = $.summernote.ui; + + // add hello button + context.memo('button.hello', function() { + // create button + var button = ui.button({ + contents: ' Hello', + tooltip: 'hello', + click: function() { + self.$panel.show(); + self.$panel.hide(500); + // invoke insertText method with 'hello' on editor module. + context.invoke('editor.insertText', 'hello'); + } + }); + + // create jQuery object from button instance. + var $hello = button.render(); + return $hello; + }); + + // This events will be attached when editor is initialized. + this.events = { + // This will be called after modules are initialized. + 'summernote.init': function(we, e) { + console.log('summernote initialized', we, e); + }, + // This will be called when user releases a key on editable. + 'summernote.keyup': function(we, e) { + console.log('summernote keyup', we, e); + } + }; + + // This method will be called when editor is initialized by $('..').summernote(); + // You can create elements for plugin + this.initialize = function() { + this.$panel = $('
    ').css({ + position: 'absolute', + width: 100, + height: 100, + left: '50%', + top: '50%', + background: 'red' + }).hide(); + + this.$panel.appendTo('body'); + }; + + // This methods will be called when editor is destroyed by $('..').summernote('destroy'); + // You should remove elements on `initialize`. + this.destroy = function() { + this.$panel.remove(); + this.$panel = null; + }; + } + }); +})); diff --git a/static/old/plugin/specialchars/summernote-ext-specialchars.js b/static/old/plugin/specialchars/summernote-ext-specialchars.js new file mode 100755 index 0000000..2ee4e51 --- /dev/null +++ b/static/old/plugin/specialchars/summernote-ext-specialchars.js @@ -0,0 +1,312 @@ +(function(factory) { + /* global define */ + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof module === 'object' && module.exports) { + // Node/CommonJS + module.exports = factory(require('jquery')); + } else { + // Browser globals + factory(window.jQuery); + } +}(function($) { + $.extend($.summernote.plugins, { + 'specialchars': function(context) { + var self = this; + var ui = $.summernote.ui; + + var $editor = context.layoutInfo.editor; + var options = context.options; + var lang = options.langInfo; + + var KEY = { + UP: 38, + DOWN: 40, + LEFT: 37, + RIGHT: 39, + ENTER: 13 + }; + var COLUMN_LENGTH = 15; + var COLUMN_WIDTH = 35; + + var currentColumn = 0; + var currentRow = 0; + var totalColumn = 0; + var totalRow = 0; + + // special characters data set + var specialCharDataSet = [ + '"', '&', '<', '>', '¡', '¢', + '£', '¤', '¥', '¦', '§', + '¨', '©', 'ª', '«', '¬', + '®', '¯', '°', '±', '²', + '³', '´', 'µ', '¶', '·', + '¸', '¹', 'º', '»', '¼', + '½', '¾', '¿', '×', '÷', + 'ƒ', 'ˆ', '˜', '–', '—', + '‘', '’', '‚', '“', '”', + '„', '†', '‡', '•', '…', + '‰', '′', '″', '‹', '›', + '‾', '⁄', '€', 'ℑ', '℘', + 'ℜ', '™', 'ℵ', '←', '↑', + '→', '↓', '↔', '↵', '⇐', + '⇑', '⇒', '⇓', '⇔', '∀', + '∂', '∃', '∅', '∇', '∈', + '∉', '∋', '∏', '∑', '−', + '∗', '√', '∝', '∞', '∠', + '∧', '∨', '∩', '∪', '∫', + '∴', '∼', '≅', '≈', '≠', + '≡', '≤', '≥', '⊂', '⊃', + '⊄', '⊆', '⊇', '⊕', '⊗', + '⊥', '⋅', '⌈', '⌉', '⌊', + '⌋', '◊', '♠', '♣', '♥', + '♦' + ]; + + context.memo('button.specialchars', function() { + return ui.button({ + contents: '', + tooltip: lang.specialChar.specialChar, + click: function() { + self.show(); + } + }).render(); + }); + + /** + * Make Special Characters Table + * + * @member plugin.specialChar + * @private + * @return {jQuery} + */ + this.makeSpecialCharSetTable = function() { + var $table = $(''); + $.each(specialCharDataSet, function(idx, text) { + var $td = $('') : $table.find('tr').last(); + + var $button = ui.button({ + callback: function($node) { + $node.html(text); + $node.attr('title', text); + $node.attr('data-value', encodeURIComponent(text)); + $node.css({ + width: COLUMN_WIDTH, + 'margin-right': '2px', + 'margin-bottom': '2px' + }); + } + }).render(); + + $td.append($button); + + $tr.append($td); + if (idx % COLUMN_LENGTH === 0) { + $table.append($tr); + } + }); + + totalRow = $table.find('tr').length; + totalColumn = COLUMN_LENGTH; + + return $table; + }; + + this.initialize = function() { + var $container = options.dialogsInBody ? $(document.body) : $editor; + + var body = '
    ' + this.makeSpecialCharSetTable()[0].outerHTML + '
    '; + + this.$dialog = ui.dialog({ + title: lang.specialChar.select, + body: body + }).render().appendTo($container); + }; + + this.show = function() { + var text = context.invoke('editor.getSelectedText'); + context.invoke('editor.saveRange'); + this.showSpecialCharDialog(text).then(function(selectChar) { + context.invoke('editor.restoreRange'); + + // build node + var $node = $('').html(selectChar)[0]; + + if ($node) { + // insert video node + context.invoke('editor.insertNode', $node); + } + }).fail(function() { + context.invoke('editor.restoreRange'); + }); + }; + + /** + * show image dialog + * + * @param {jQuery} $dialog + * @return {Promise} + */ + this.showSpecialCharDialog = function(text) { + return $.Deferred(function(deferred) { + var $specialCharDialog = self.$dialog; + var $specialCharNode = $specialCharDialog.find('.note-specialchar-node'); + var $selectedNode = null; + var ARROW_KEYS = [KEY.UP, KEY.DOWN, KEY.LEFT, KEY.RIGHT]; + var ENTER_KEY = KEY.ENTER; + + function addActiveClass($target) { + if (!$target) { + return; + } + $target.find('button').addClass('active'); + $selectedNode = $target; + } + + function removeActiveClass($target) { + $target.find('button').removeClass('active'); + $selectedNode = null; + } + + // find next node + function findNextNode(row, column) { + var findNode = null; + $.each($specialCharNode, function(idx, $node) { + var findRow = Math.ceil((idx + 1) / COLUMN_LENGTH); + var findColumn = ((idx + 1) % COLUMN_LENGTH === 0) ? COLUMN_LENGTH : (idx + 1) % COLUMN_LENGTH; + if (findRow === row && findColumn === column) { + findNode = $node; + return false; + } + }); + return $(findNode); + } + + function arrowKeyHandler(keyCode) { + // left, right, up, down key + var $nextNode; + var lastRowColumnLength = $specialCharNode.length % totalColumn; + + if (KEY.LEFT === keyCode) { + if (currentColumn > 1) { + currentColumn = currentColumn - 1; + } else if (currentRow === 1 && currentColumn === 1) { + currentColumn = lastRowColumnLength; + currentRow = totalRow; + } else { + currentColumn = totalColumn; + currentRow = currentRow - 1; + } + } else if (KEY.RIGHT === keyCode) { + if (currentRow === totalRow && lastRowColumnLength === currentColumn) { + currentColumn = 1; + currentRow = 1; + } else if (currentColumn < totalColumn) { + currentColumn = currentColumn + 1; + } else { + currentColumn = 1; + currentRow = currentRow + 1; + } + } else if (KEY.UP === keyCode) { + if (currentRow === 1 && lastRowColumnLength < currentColumn) { + currentRow = totalRow - 1; + } else { + currentRow = currentRow - 1; + } + } else if (KEY.DOWN === keyCode) { + currentRow = currentRow + 1; + } + + if (currentRow === totalRow && currentColumn > lastRowColumnLength) { + currentRow = 1; + } else if (currentRow > totalRow) { + currentRow = 1; + } else if (currentRow < 1) { + currentRow = totalRow; + } + + $nextNode = findNextNode(currentRow, currentColumn); + + if ($nextNode) { + removeActiveClass($selectedNode); + addActiveClass($nextNode); + } + } + + function enterKeyHandler() { + if (!$selectedNode) { + return; + } + + deferred.resolve(decodeURIComponent($selectedNode.find('button').attr('data-value'))); + $specialCharDialog.modal('hide'); + } + + function keyDownEventHandler(event) { + event.preventDefault(); + var keyCode = event.keyCode; + if (keyCode === undefined || keyCode === null) { + return; + } + // check arrowKeys match + if (ARROW_KEYS.indexOf(keyCode) > -1) { + if ($selectedNode === null) { + addActiveClass($specialCharNode.eq(0)); + currentColumn = 1; + currentRow = 1; + return; + } + arrowKeyHandler(keyCode); + } else if (keyCode === ENTER_KEY) { + enterKeyHandler(); + } + return false; + } + + // remove class + removeActiveClass($specialCharNode); + + // find selected node + if (text) { + for (var i = 0; i < $specialCharNode.length; i++) { + var $checkNode = $($specialCharNode[i]); + if ($checkNode.text() === text) { + addActiveClass($checkNode); + currentRow = Math.ceil((i + 1) / COLUMN_LENGTH); + currentColumn = (i + 1) % COLUMN_LENGTH; + } + } + } + + ui.onDialogShown(self.$dialog, function() { + $(document).on('keydown', keyDownEventHandler); + + self.$dialog.find('button').tooltip(); + + $specialCharNode.on('click', function(event) { + event.preventDefault(); + deferred.resolve(decodeURIComponent($(event.currentTarget).find('button').attr('data-value'))); + ui.hideDialog(self.$dialog); + }); + }); + + ui.onDialogHidden(self.$dialog, function() { + $specialCharNode.off('click'); + + self.$dialog.find('button').tooltip('destroy'); + + $(document).off('keydown', keyDownEventHandler); + + if (deferred.state() === 'pending') { + deferred.reject(); + } + }); + + ui.showDialog(self.$dialog); + }); + }; + } + }); +})); diff --git a/static/old/summernote-bs4.css b/static/old/summernote-bs4.css new file mode 100755 index 0000000..85492bd --- /dev/null +++ b/static/old/summernote-bs4.css @@ -0,0 +1 @@ +@font-face{font-family:"summernote";font-style:normal;font-weight:normal;src:url("./font/summernote.eot?e557617934c52ea068954af79ed7c221");src:url("./font/summernote.eot?#iefix") format("embedded-opentype"),url("./font/summernote.woff?e557617934c52ea068954af79ed7c221") format("woff"),url("./font/summernote.ttf?e557617934c52ea068954af79ed7c221") format("truetype")}[class^="note-icon-"]:before,[class*=" note-icon-"]:before{display:inline-block;font:normal normal normal 14px summernote;font-size:inherit;-webkit-font-smoothing:antialiased;text-decoration:inherit;text-rendering:auto;text-transform:none;vertical-align:middle;speak:none;-moz-osx-font-smoothing:grayscale}.note-icon-align-center:before,.note-icon-align-indent:before,.note-icon-align-justify:before,.note-icon-align-left:before,.note-icon-align-outdent:before,.note-icon-align-right:before,.note-icon-align:before,.note-icon-arrow-circle-down:before,.note-icon-arrow-circle-left:before,.note-icon-arrow-circle-right:before,.note-icon-arrow-circle-up:before,.note-icon-arrows-alt:before,.note-icon-arrows-h:before,.note-icon-arrows-v:before,.note-icon-bold:before,.note-icon-caret:before,.note-icon-chain-broken:before,.note-icon-circle:before,.note-icon-close:before,.note-icon-code:before,.note-icon-col-after:before,.note-icon-col-before:before,.note-icon-col-remove:before,.note-icon-eraser:before,.note-icon-font:before,.note-icon-frame:before,.note-icon-italic:before,.note-icon-link:before,.note-icon-magic:before,.note-icon-menu-check:before,.note-icon-minus:before,.note-icon-orderedlist:before,.note-icon-pencil:before,.note-icon-picture:before,.note-icon-question:before,.note-icon-redo:before,.note-icon-row-above:before,.note-icon-row-below:before,.note-icon-row-remove:before,.note-icon-special-character:before,.note-icon-square:before,.note-icon-strikethrough:before,.note-icon-subscript:before,.note-icon-summernote:before,.note-icon-superscript:before,.note-icon-table:before,.note-icon-text-height:before,.note-icon-trash:before,.note-icon-underline:before,.note-icon-undo:before,.note-icon-unorderedlist:before,.note-icon-video:before{display:inline-block;font-family:"summernote";font-style:normal;font-weight:normal;text-decoration:inherit}.note-icon-align-center:before{content:"\f101"}.note-icon-align-indent:before{content:"\f102"}.note-icon-align-justify:before{content:"\f103"}.note-icon-align-left:before{content:"\f104"}.note-icon-align-outdent:before{content:"\f105"}.note-icon-align-right:before{content:"\f106"}.note-icon-align:before{content:"\f107"}.note-icon-arrow-circle-down:before{content:"\f108"}.note-icon-arrow-circle-left:before{content:"\f109"}.note-icon-arrow-circle-right:before{content:"\f10a"}.note-icon-arrow-circle-up:before{content:"\f10b"}.note-icon-arrows-alt:before{content:"\f10c"}.note-icon-arrows-h:before{content:"\f10d"}.note-icon-arrows-v:before{content:"\f10e"}.note-icon-bold:before{content:"\f10f"}.note-icon-caret:before{content:"\f110"}.note-icon-chain-broken:before{content:"\f111"}.note-icon-circle:before{content:"\f112"}.note-icon-close:before{content:"\f113"}.note-icon-code:before{content:"\f114"}.note-icon-col-after:before{content:"\f115"}.note-icon-col-before:before{content:"\f116"}.note-icon-col-remove:before{content:"\f117"}.note-icon-eraser:before{content:"\f118"}.note-icon-font:before{content:"\f119"}.note-icon-frame:before{content:"\f11a"}.note-icon-italic:before{content:"\f11b"}.note-icon-link:before{content:"\f11c"}.note-icon-magic:before{content:"\f11d"}.note-icon-menu-check:before{content:"\f11e"}.note-icon-minus:before{content:"\f11f"}.note-icon-orderedlist:before{content:"\f120"}.note-icon-pencil:before{content:"\f121"}.note-icon-picture:before{content:"\f122"}.note-icon-question:before{content:"\f123"}.note-icon-redo:before{content:"\f124"}.note-icon-row-above:before{content:"\f125"}.note-icon-row-below:before{content:"\f126"}.note-icon-row-remove:before{content:"\f127"}.note-icon-special-character:before{content:"\f128"}.note-icon-square:before{content:"\f129"}.note-icon-strikethrough:before{content:"\f12a"}.note-icon-subscript:before{content:"\f12b"}.note-icon-summernote:before{content:"\f12c"}.note-icon-superscript:before{content:"\f12d"}.note-icon-table:before{content:"\f12e"}.note-icon-text-height:before{content:"\f12f"}.note-icon-trash:before{content:"\f130"}.note-icon-underline:before{content:"\f131"}.note-icon-undo:before{content:"\f132"}.note-icon-unorderedlist:before{content:"\f133"}.note-icon-video:before{content:"\f134"}.note-editor{position:relative}.note-editor .note-dropzone{position:absolute;z-index:100;display:none;color:#87cefa;background-color:white;opacity:.95}.note-editor .note-dropzone .note-dropzone-message{display:table-cell;font-size:28px;font-weight:bold;text-align:center;vertical-align:middle}.note-editor .note-dropzone.hover{color:#098ddf}.note-editor.dragover .note-dropzone{display:table}.note-editor .note-editing-area{position:relative}.note-editor .note-editing-area .note-editable{outline:0}.note-editor .note-editing-area .note-editable sup{vertical-align:super}.note-editor .note-editing-area .note-editable sub{vertical-align:sub}.note-editor .note-editing-area img.note-float-left{margin-right:10px}.note-editor .note-editing-area img.note-float-right{margin-left:10px}.note-editor.note-frame{border:1px solid #a9a9a9}.note-editor.note-frame.codeview .note-editing-area .note-editable{display:none}.note-editor.note-frame.codeview .note-editing-area .note-codable{display:block}.note-editor.note-frame .note-editing-area{overflow:hidden}.note-editor.note-frame .note-editing-area .note-editable{padding:10px;overflow:auto;color:#000;word-wrap:break-word;background-color:#fff}.note-editor.note-frame .note-editing-area .note-editable[contenteditable="false"]{background-color:#e5e5e5}.note-editor.note-frame .note-editing-area .note-codable{display:none;width:100%;padding:10px;margin-bottom:0;font-family:Menlo,Monaco,monospace,sans-serif;font-size:14px;color:#ccc;background-color:#222;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;box-shadow:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;resize:none}.note-editor.note-frame.fullscreen{position:fixed;top:0;left:0;z-index:1050;width:100%!important}.note-editor.note-frame.fullscreen .note-editable{background-color:white}.note-editor.note-frame.fullscreen .note-resizebar{display:none}.note-editor.note-frame .note-statusbar{background-color:#f5f5f5;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.note-editor.note-frame .note-statusbar .note-resizebar{width:100%;height:8px;padding-top:1px;cursor:ns-resize}.note-editor.note-frame .note-statusbar .note-resizebar .note-icon-bar{width:20px;margin:1px auto;border-top:1px solid #a9a9a9}.note-editor.note-frame .note-placeholder{padding:10px}.note-popover.popover{display:none;max-width:none}.note-popover.popover .popover-content a{display:inline-block;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle}.note-popover.popover .arrow{left:20px!important}.note-toolbar{position:relative;z-index:500}.note-popover .popover-content,.card-header.note-toolbar{padding:0 0 5px 5px;margin:0}.note-popover .popover-content>.btn-group,.card-header.note-toolbar>.btn-group{margin-top:5px;margin-right:5px;margin-left:0}.note-popover .popover-content .btn-group .note-table,.card-header.note-toolbar .btn-group .note-table{min-width:0;padding:5px}.note-popover .popover-content .btn-group .note-table .note-dimension-picker,.card-header.note-toolbar .btn-group .note-table .note-dimension-picker{font-size:18px}.note-popover .popover-content .btn-group .note-table .note-dimension-picker .note-dimension-picker-mousecatcher,.card-header.note-toolbar .btn-group .note-table .note-dimension-picker .note-dimension-picker-mousecatcher{position:absolute!important;z-index:3;width:10em;height:10em;cursor:pointer}.note-popover .popover-content .btn-group .note-table .note-dimension-picker .note-dimension-picker-unhighlighted,.card-header.note-toolbar .btn-group .note-table .note-dimension-picker .note-dimension-picker-unhighlighted{position:relative!important;z-index:1;width:5em;height:5em;background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIj4+Pjp6ekKlAqjAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKhmnaJzPAAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC') repeat}.note-popover .popover-content .btn-group .note-table .note-dimension-picker .note-dimension-picker-highlighted,.card-header.note-toolbar .btn-group .note-table .note-dimension-picker .note-dimension-picker-highlighted{position:absolute!important;z-index:2;width:1em;height:1em;background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIjd6vvD2f9LKLW+AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKwNDEVT0AAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC') repeat}.note-popover .popover-content .note-style .dropdown-style blockquote,.card-header.note-toolbar .note-style .dropdown-style blockquote,.note-popover .popover-content .note-style .dropdown-style pre,.card-header.note-toolbar .note-style .dropdown-style pre{padding:5px 10px;margin:0}.note-popover .popover-content .note-style .dropdown-style h1,.card-header.note-toolbar .note-style .dropdown-style h1,.note-popover .popover-content .note-style .dropdown-style h2,.card-header.note-toolbar .note-style .dropdown-style h2,.note-popover .popover-content .note-style .dropdown-style h3,.card-header.note-toolbar .note-style .dropdown-style h3,.note-popover .popover-content .note-style .dropdown-style h4,.card-header.note-toolbar .note-style .dropdown-style h4,.note-popover .popover-content .note-style .dropdown-style h5,.card-header.note-toolbar .note-style .dropdown-style h5,.note-popover .popover-content .note-style .dropdown-style h6,.card-header.note-toolbar .note-style .dropdown-style h6,.note-popover .popover-content .note-style .dropdown-style p,.card-header.note-toolbar .note-style .dropdown-style p{padding:0;margin:0}.note-popover .popover-content .note-color .dropdown-toggle,.card-header.note-toolbar .note-color .dropdown-toggle{width:20px;padding-left:5px}.note-popover .popover-content .note-color .dropdown-menu,.card-header.note-toolbar .note-color .dropdown-menu{min-width:337px}.note-popover .popover-content .note-color .dropdown-menu .note-palette,.card-header.note-toolbar .note-color .dropdown-menu .note-palette{display:inline-block;width:160px;margin:0}.note-popover .popover-content .note-color .dropdown-menu .note-palette:first-child,.card-header.note-toolbar .note-color .dropdown-menu .note-palette:first-child{margin:0 5px}.note-popover .popover-content .note-color .dropdown-menu .note-palette .note-palette-title,.card-header.note-toolbar .note-color .dropdown-menu .note-palette .note-palette-title{margin:2px 7px;font-size:12px;text-align:center;border-bottom:1px solid #eee}.note-popover .popover-content .note-color .dropdown-menu .note-palette .note-color-reset,.card-header.note-toolbar .note-color .dropdown-menu .note-palette .note-color-reset{width:100%;padding:0 3px;margin:3px;font-size:11px;cursor:pointer;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.note-popover .popover-content .note-color .dropdown-menu .note-palette .note-color-row,.card-header.note-toolbar .note-color .dropdown-menu .note-palette .note-color-row{height:20px}.note-popover .popover-content .note-color .dropdown-menu .note-palette .note-color-reset:hover,.card-header.note-toolbar .note-color .dropdown-menu .note-palette .note-color-reset:hover{background:#eee}.note-popover .popover-content .note-para .dropdown-menu,.card-header.note-toolbar .note-para .dropdown-menu{min-width:216px;padding:5px}.note-popover .popover-content .note-para .dropdown-menu>div:first-child,.card-header.note-toolbar .note-para .dropdown-menu>div:first-child{margin-right:5px}.note-popover .popover-content .dropdown-menu,.card-header.note-toolbar .dropdown-menu{min-width:90px}.note-popover .popover-content .dropdown-menu.right,.card-header.note-toolbar .dropdown-menu.right{right:0;left:auto}.note-popover .popover-content .dropdown-menu.right::before,.card-header.note-toolbar .dropdown-menu.right::before{right:9px;left:auto!important}.note-popover .popover-content .dropdown-menu.right::after,.card-header.note-toolbar .dropdown-menu.right::after{right:10px;left:auto!important}.note-popover .popover-content .dropdown-menu.note-check a i,.card-header.note-toolbar .dropdown-menu.note-check a i{color:deepskyblue;visibility:hidden}.note-popover .popover-content .dropdown-menu.note-check a.checked i,.card-header.note-toolbar .dropdown-menu.note-check a.checked i{visibility:visible}.note-popover .popover-content .note-fontsize-10,.card-header.note-toolbar .note-fontsize-10{font-size:10px}.note-popover .popover-content .note-color-palette,.card-header.note-toolbar .note-color-palette{line-height:1}.note-popover .popover-content .note-color-palette div .note-color-btn,.card-header.note-toolbar .note-color-palette div .note-color-btn{width:20px;height:20px;padding:0;margin:0;border:1px solid #fff}.note-popover .popover-content .note-color-palette div .note-color-btn:hover,.card-header.note-toolbar .note-color-palette div .note-color-btn:hover{border:1px solid #000}.note-dialog>div{display:none}.note-dialog .form-group{margin-right:0;margin-left:0}.note-dialog .note-modal-form{margin:0}.note-dialog .note-image-dialog .note-dropzone{min-height:100px;margin-bottom:10px;font-size:30px;line-height:4;color:lightgray;text-align:center;border:4px dashed lightgray}@-moz-document url-prefix(){.note-image-input{height:auto}}.note-placeholder{position:absolute;display:none;color:gray}.note-handle .note-control-selection{position:absolute;display:none;border:1px solid black}.note-handle .note-control-selection>div{position:absolute}.note-handle .note-control-selection .note-control-selection-bg{width:100%;height:100%;background-color:black;-webkit-opacity:.3;-khtml-opacity:.3;-moz-opacity:.3;opacity:.3;-ms-filter:alpha(opacity=30);filter:alpha(opacity=30)}.note-handle .note-control-selection .note-control-handle{width:7px;height:7px;border:1px solid black}.note-handle .note-control-selection .note-control-holder{width:7px;height:7px;border:1px solid black}.note-handle .note-control-selection .note-control-sizing{width:7px;height:7px;background-color:white;border:1px solid black}.note-handle .note-control-selection .note-control-nw{top:-5px;left:-5px;border-right:0;border-bottom:0}.note-handle .note-control-selection .note-control-ne{top:-5px;right:-5px;border-bottom:0;border-left:none}.note-handle .note-control-selection .note-control-sw{bottom:-5px;left:-5px;border-top:0;border-right:0}.note-handle .note-control-selection .note-control-se{right:-5px;bottom:-5px;cursor:se-resize}.note-handle .note-control-selection .note-control-se.note-control-holder{cursor:default;border-top:0;border-left:none}.note-handle .note-control-selection .note-control-selection-info{right:0;bottom:0;padding:5px;margin:5px;font-size:12px;color:white;background-color:black;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-opacity:.7;-khtml-opacity:.7;-moz-opacity:.7;opacity:.7;-ms-filter:alpha(opacity=70);filter:alpha(opacity=70)}.note-hint-popover{min-width:100px;padding:2px}.note-hint-popover .popover-content{max-height:150px;padding:3px;overflow:auto}.note-hint-popover .popover-content .note-hint-group .note-hint-item{display:block!important;padding:3px}.note-hint-popover .popover-content .note-hint-group .note-hint-item.active,.note-hint-popover .popover-content .note-hint-group .note-hint-item:hover{display:block;clear:both;font-weight:400;line-height:1.4;color:white;text-decoration:none;white-space:nowrap;cursor:pointer;background-color:#428bca;outline:0} \ No newline at end of file diff --git a/static/old/summernote-bs4.js b/static/old/summernote-bs4.js new file mode 100755 index 0000000..163c574 --- /dev/null +++ b/static/old/summernote-bs4.js @@ -0,0 +1,7285 @@ +/** + * Super simple wysiwyg editor v0.8.9 + * https://summernote.org + * + * Copyright 2013- Alan Hong. and other contributors + * summernote may be freely distributed under the MIT license. + * + * Date: 2017-12-25T06:39Z + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) : + typeof define === 'function' && define.amd ? define(['jquery'], factory) : + (factory(global.jQuery)); +}(this, (function ($$1) { 'use strict'; + +$$1 = $$1 && $$1.hasOwnProperty('default') ? $$1['default'] : $$1; + +var Renderer = /** @class */ (function () { + function Renderer(markup, children, options, callback) { + this.markup = markup; + this.children = children; + this.options = options; + this.callback = callback; + } + Renderer.prototype.render = function ($parent) { + var $node = $$1(this.markup); + if (this.options && this.options.contents) { + $node.html(this.options.contents); + } + if (this.options && this.options.className) { + $node.addClass(this.options.className); + } + if (this.options && this.options.data) { + $$1.each(this.options.data, function (k, v) { + $node.attr('data-' + k, v); + }); + } + if (this.options && this.options.click) { + $node.on('click', this.options.click); + } + if (this.children) { + var $container_1 = $node.find('.note-children-container'); + this.children.forEach(function (child) { + child.render($container_1.length ? $container_1 : $node); + }); + } + if (this.callback) { + this.callback($node, this.options); + } + if (this.options && this.options.callback) { + this.options.callback($node); + } + if ($parent) { + $parent.append($node); + } + return $node; + }; + return Renderer; +}()); +var renderer = { + create: function (markup, callback) { + return function () { + var options = typeof arguments[1] === 'object' ? arguments[1] : arguments[0]; + var children = $$1.isArray(arguments[0]) ? arguments[0] : []; + if (options && options.children) { + children = options.children; + } + return new Renderer(markup, children, options, callback); + }; + } +}; + +var editor = renderer.create('
    '); +var toolbar = renderer.create('
    '); +var editingArea = renderer.create('
    '); +var codable = renderer.create(' + +
    + + Lvl 2: + +
    + + Lvl 3: + +
    + + + + + + + + + diff --git a/views/_mapsTest.ejs b/views/_mapsTest.ejs new file mode 100755 index 0000000..ee4b10c --- /dev/null +++ b/views/_mapsTest.ejs @@ -0,0 +1,95 @@ + + + + + User-Editable Shapes + + + + + + + + + + +
    ').addClass('note-specialchar-node'); + var $tr = (idx % COLUMN_LENGTH === 0) ? $('
    +
    +

    Zone :

    + + <% for(var i = 0;i + + <% } %> +
    NomCoo
    <%= data[i].Nom %>#N<%=data[i].Nord %>#S<%=data[i].Sud %>#O<%=data[i].Ouest %>#E<%=data[i].Est %>
    + Nom Zone : + +
    + + + diff --git a/views/index.ejs b/views/index.ejs new file mode 100644 index 0000000..cf07dc3 --- /dev/null +++ b/views/index.ejs @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    + + + +
    + +
    + + + + +
    +
    +
    +
    + +
    + + +
    +
    + + +
    + +
    + + + +
    +
    + +
    Write your publication here!
    + +
    +
    +
    +
    + + Upload + +
    +
    +
    +
    +
    + + + + +
    +
    + + + + + + + + + + + + + + diff --git a/views/login.ejs b/views/login.ejs new file mode 100644 index 0000000..512612b --- /dev/null +++ b/views/login.ejs @@ -0,0 +1,142 @@ + + + + + + + + + + + + + diff --git a/views/map.ejs b/views/map.ejs new file mode 100644 index 0000000..26ba152 --- /dev/null +++ b/views/map.ejs @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + +
    + +
    +
    + +
    +
    + +
    +
    + +
    + + + + +
    + +
    + + + +
    +
    +
    + +
    + +
    +
    +
    + +
    + + + Add +
    + + + + +
    +
    + + + + + + + + + + + + + + +