<commit_before>var http     = require('http'),
    fs       = require('fs'),
    path     = require('path'),
    spawn    = require('child_process').spawn,
    express  = require('express'),
    pod      = require('../lib/api'),
    app      = express()

// late def, wait until pod is ready
var conf

// middlewares
var reloadConf = function (req, res, next) {
    conf = pod.reloadConfig()
    next()
}

var auth = express.basicAuth(function (user, pass) {
    var u = conf.web.username || 'admin',
        p = conf.web.password || 'admin'
    return user === u && pass === p
})

app.configure(function(){
    app.set('views', __dirname + '/views')
    app.set('view engine', 'ejs')
    app.use(express.favicon())
    app.use(reloadConf)
    app.use(app.router)
    app.use(express.static(path.join(__dirname, 'static')))
})

app.get('/', auth, function (req, res) {
    pod.listApps(function (err, list) {
        if (err) return res.end(err)
        res.render('index', {
            apps: list
        })
    })
})

app.get('/json', auth, function (req, res) {
    pod.listApps(function (err, list) {
        if (err) return res.end(err)
        res.json(list)
    })
})

app.post('/hooks/:appid', express.bodyParser(), function (req, res) {
    var appid = req.params.appid,
        payload = req.body.payload,
        app = conf.apps[appid]

    try {
        payload = JSON.parse(payload)
    } catch (e) {
        return res.end(e.toString())
    }

    if (app && verify(req, app, payload)) {
        executeHook(appid, app, payload, function () {
            res.end()
        })
    } else {
        res.end()
    }
})

// listen when API is ready
pod.once('ready', function () {
    // load config first
    conf = pod.getConfig()
    // conditional open up jsonp based on config
    if (conf.web.jsonp === true) {
        app.get('/jsonp', function (req, res) {
            pod.listApps(function (err, list) {
                if (err) return res.end(err)
                res.jsonp(list)
            })
        })
    }
    app.listen(process.env.PORT || 19999)
})

// Helpers
function verify (req, app, payload) {
    // not even a remote app
    if (!app.remote) return
    // check repo match
    var repo = payload.repository
    console.log('\nreceived webhook request from: ' + repo.url)
    if (strip(repo.url) !== strip(app.remote)) {
        console.log('aborted.')
        return
    }
    // skip it with [pod skip] message
    var commit = payload.head_commit
    console.log('commit message: ' + commit.message)
    if (/\[pod skip\]/.test(commit.message)) {
        console.log('aborted.')
        return
    }
    // check branch match
    var branch = payload.ref.replace('refs/heads/', ''),
        expected = app.branch || 'master'
    console.log('expected branch: ' + expected + ', got branch: ' + branch)
    if (branch !== expected) {
        console.log('aborted.')
        return
    }
    return true
}

function executeHook (appid, app, payload, cb) {
    fs.readFile(path.resolve(__dirname, '../hooks/post-receive'), 'utf-8', function (err, template) {
        if (err) return cb(err)
        var hookPath = conf.root + '/temphook.sh',
            hook = template
                .replace(/\{\{pod_dir\}\}/g, conf.root)
                .replace(/\{\{app\}\}/g, appid)
        if (app.branch) {
            hook = hook.replace('origin/master', 'origin/' + app.branch)
        }
        fs.writeFile(hookPath, hook, function (err) {
            if (err) return cb(err)
            fs.chmod(hookPath, '0777', function (err) {
                if (err) return cb(err)
                console.log('excuting github webhook for ' + appid + '...')
                var child = spawn('bash', [hookPath])
                child.stdout.pipe(process.stdout)
                child.stderr.pipe(process.stderr)
                child.on('exit', function (code) {
                    fs.unlink(hookPath, cb)
                })
            })
        })
    })
}

function strip (url) {
    return url.replace(/(https?:\/\/|git@)github\.com(\/|:)|\.git/g, '')
}
<commit_msg>further fix web service strip()<commit_after>var http     = require('http'),
    fs       = require('fs'),
    path     = require('path'),
    spawn    = require('child_process').spawn,
    express  = require('express'),
    pod      = require('../lib/api'),
    app      = express()

// late def, wait until pod is ready
var conf

// middlewares
var reloadConf = function (req, res, next) {
    conf = pod.reloadConfig()
    next()
}

var auth = express.basicAuth(function (user, pass) {
    var u = conf.web.username || 'admin',
        p = conf.web.password || 'admin'
    return user === u && pass === p
})

app.configure(function(){
    app.set('views', __dirname + '/views')
    app.set('view engine', 'ejs')
    app.use(express.favicon())
    app.use(reloadConf)
    app.use(app.router)
    app.use(express.static(path.join(__dirname, 'static')))
})

app.get('/', auth, function (req, res) {
    pod.listApps(function (err, list) {
        if (err) return res.end(err)
        res.render('index', {
            apps: list
        })
    })
})

app.get('/json', auth, function (req, res) {
    pod.listApps(function (err, list) {
        if (err) return res.end(err)
        res.json(list)
    })
})

app.post('/hooks/:appid', express.bodyParser(), function (req, res) {
    var appid = req.params.appid,
        payload = req.body.payload,
        app = conf.apps[appid]

    try {
        payload = JSON.parse(payload)
    } catch (e) {
        return res.end(e.toString())
    }

    if (app && verify(req, app, payload)) {
        executeHook(appid, app, payload, function () {
            res.end()
        })
    } else {
        res.end()
    }
})

// listen when API is ready
pod.once('ready', function () {
    // load config first
    conf = pod.getConfig()
    // conditional open up jsonp based on config
    if (conf.web.jsonp === true) {
        app.get('/jsonp', function (req, res) {
            pod.listApps(function (err, list) {
                if (err) return res.end(err)
                res.jsonp(list)
            })
        })
    }
    app.listen(process.env.PORT || 19999)
})

// Helpers
function verify (req, app, payload) {
    // not even a remote app
    if (!app.remote) return
    // check repo match
    var repo = payload.repository
    console.log('\nreceived webhook request from: ' + repo.url)
    if (strip(repo.url) !== strip(app.remote)) {
        console.log('aborted.')
        return
    }
    // skip it with [pod skip] message
    var commit = payload.head_commit
    console.log('commit message: ' + commit.message)
    if (/\[pod skip\]/.test(commit.message)) {
        console.log('aborted.')
        return
    }
    // check branch match
    var branch = payload.ref.replace('refs/heads/', ''),
        expected = app.branch || 'master'
    console.log('expected branch: ' + expected + ', got branch: ' + branch)
    if (branch !== expected) {
        console.log('aborted.')
        return
    }
    return true
}

function executeHook (appid, app, payload, cb) {
    fs.readFile(path.resolve(__dirname, '../hooks/post-receive'), 'utf-8', function (err, template) {
        if (err) return cb(err)
        var hookPath = conf.root + '/temphook.sh',
            hook = template
                .replace(/\{\{pod_dir\}\}/g, conf.root)
                .replace(/\{\{app\}\}/g, appid)
        if (app.branch) {
            hook = hook.replace('origin/master', 'origin/' + app.branch)
        }
        fs.writeFile(hookPath, hook, function (err) {
            if (err) return cb(err)
            fs.chmod(hookPath, '0777', function (err) {
                if (err) return cb(err)
                console.log('excuting github webhook for ' + appid + '...')
                var child = spawn('bash', [hookPath])
                child.stdout.pipe(process.stdout)
                child.stderr.pipe(process.stderr)
                child.on('exit', function (code) {
                    fs.unlink(hookPath, cb)
                })
            })
        })
    })
}

function strip (url) {
    return url.replace(/^(https?:\/\/|git@)github\.com(\/|:)|\.git$/g, '')
}
<|endoftext|>


<commit_before>var bogart = require('bogart')
    ,pg = require('pg')
    ,viewEngine = bogart.viewEngine('jade')
    ,middleware = require('./lib/middleware')
    ,settings = require('../settings')
    ;

require('bogart-jade');

var client = new pg.Client(settings.connectionString);
client.connect();

var router = bogart.router();
router.get('/', function (req) {
    return bogart.promisify(client.query, client)(
        "SELECT hundred_block_location, description, COUNT(go_number) AS incident_count FROM crimes LEFT JOIN offense_descriptions ON crimes.offense_code = offense_descriptions.offense_code WHERE occurred_date > NOW() - INTERVAL '7 days 8 hours' AND NOT crimes.offense_code = 'X' GROUP BY hundred_block_location, crimes.offense_code, offense_descriptions.description ORDER By incident_count DESC, hundred_block_location"
        ).then(
        function (result) {
            return viewEngine.respond('index.jade',
            {
                locals: result
            });
        });
});
router.get('/major', function (req) {
    return bogart.promisify(client.query, client)(
        "SELECT DISTINCT hundred_block_location, description, occurred_date, go_number FROM crimes LEFT JOIN offense_descriptions ON crimes.offense_code = offense_descriptions.offense_code WHERE occurred_date > NOW() - INTERVAL '2 months' AND (crimes.offense_code LIKE '12__' OR crimes.offense_code LIKE '130_' OR crimes.offense_code LIKE '22__' OR crimes.offense_code LIKE '9__') ORDER BY occurred_date DESC").then(
        function (result) {
            return viewEngine.respond('major.jade',
            {
                locals: result
            });
        });
});
router.get('/drugs', function (req) {
    return bogart.promisify(client.query, client)(
        "SELECT DISTINCT hundred_block_location, description, occurred_date, go_number FROM crimes LEFT JOIN offense_descriptions ON crimes.offense_code = offense_descriptions.offense_code WHERE occurred_date > NOW() - INTERVAL '2 months' AND crimes.offense_code LIKE '35__' ORDER BY occurred_date DESC").then(
        function (result) {
            return viewEngine.respond('drugs.jade',
            {
                locals: result
            });
        });
});

var app = bogart.app();

app.use(middleware.batteries);
app.use(router);

var port = process.env['PORT'] || 6000;
app.start(port);
<commit_msg>Remove dups.<commit_after>var bogart = require('bogart')
    ,pg = require('pg')
    ,viewEngine = bogart.viewEngine('jade')
    ,middleware = require('./lib/middleware')
    ,settings = require('../settings')
    ;

require('bogart-jade');

var client = new pg.Client(settings.connectionString);
client.connect();

var router = bogart.router();
router.get('/', function (req) {
    return bogart.promisify(client.query, client)(
        "SELECT hundred_block_location, description, COUNT(DISTINCT go_number) AS incident_count FROM crimes LEFT JOIN offense_descriptions ON crimes.offense_code = offense_descriptions.offense_code WHERE occurred_date > NOW() - INTERVAL '7 days 8 hours' AND NOT crimes.offense_code = 'X' GROUP BY hundred_block_location, crimes.offense_code, offense_descriptions.description ORDER By incident_count DESC, hundred_block_location"
        ).then(
        function (result) {
            return viewEngine.respond('index.jade',
            {
                locals: result
            });
        });
});
router.get('/major', function (req) {
    return bogart.promisify(client.query, client)(
        "SELECT DISTINCT hundred_block_location, description, occurred_date, go_number FROM crimes LEFT JOIN offense_descriptions ON crimes.offense_code = offense_descriptions.offense_code WHERE occurred_date > NOW() - INTERVAL '2 months' AND (crimes.offense_code LIKE '12__' OR crimes.offense_code LIKE '130_' OR crimes.offense_code LIKE '22__' OR crimes.offense_code LIKE '9__') ORDER BY occurred_date DESC").then(
        function (result) {
            return viewEngine.respond('major.jade',
            {
                locals: result
            });
        });
});
router.get('/drugs', function (req) {
    return bogart.promisify(client.query, client)(
        "SELECT DISTINCT hundred_block_location, description, occurred_date, go_number FROM crimes LEFT JOIN offense_descriptions ON crimes.offense_code = offense_descriptions.offense_code WHERE occurred_date > NOW() - INTERVAL '2 months' AND crimes.offense_code LIKE '35__' ORDER BY occurred_date DESC").then(
        function (result) {
            return viewEngine.respond('drugs.jade',
            {
                locals: result
            });
        });
});

var app = bogart.app();

app.use(middleware.batteries);
app.use(router);

var port = process.env['PORT'] || 6000;
app.start(port);
<|endoftext|>


<commit_before>var SparkMD5 = require('spark-md5');
var base64 = require('base64-arraybuffer').encode;
angular.module('angular.file', [])
    .factory('fileOperator', ['$window', '$q', function ($window, $q) {
        function FileOperator (file, maxChunkSize) {
            this.file = file;
            this.fileSize = (file && file.size) || 0;
            this.messages = [];
            // this property will only affect MD5 calculation
            this.maxChunkSize = maxChunkSize || 1048576;
        }
        FileOperator.prototype.read = function (start, end) {
            var that = this;
            var fileReader = new $window.FileReader();
            return $q(function (resolve, reject) {
                var fileChunk;
                if(!that.file) {
                    return reject(new Error('read','invalid file instance'));
                }
                // bind onloadend handler
                fileReader.onloadend = function (msg) {
                    resolve(fileReader.result);
                };
                fileReader.onerror = function (msg) {
                    reject(new Error('read', msg));
                };
                fileReader.onabort = function (msg) {
                    reject(msg);
                };

                // use slice.appy to handle three situation:
                // - both `start` and `end` are not given
                // - only `start` is given
                // - both `start` and `end` are given
                fileChunk = $window.File.prototype.slice.apply(
                    that.file,
                    [start, end]
                );

                fileReader.readAsArrayBuffer(fileChunk);
            });
        };
        FileOperator.prototype.abort = function () {
            fileReader.abort();
        };
        FileOperator.prototype.getArrayBuffer = function (start, length) {
            var params = this.correctRange(start, length);
            start = params.start;
            length = params.length;
            return this.read(start, start + length);
        };
        FileOperator.prototype.getUint8Array = function (start, length) {
            return this.getArrayBuffer(start, length).then(function (array) {
                return new Uint8Array(array);
            });
        };
        FileOperator.prototype.getBase64 = function (start, length) {
            return this.getArrayBuffer(start, length).then(function (array) {
                return base64(array);
            });
        };
        FileOperator.prototype.getMd5 = function (start, length) {
            var params = this.correctRange(start, length);
            start = params.start;
            length = params.length;

            // if require length is acceptable, get MD5 directly
            if(length < this.maxChunkSize) {
                return $q.when(
                    SparkMD5.ArrayBuffer.hash(
                        this.getUint8Array(start, length)
                    )
                );
            }
            // otherwise calculate MD5 incrementally
            return this.incMd5(start, length);
        };
        FileOperator.prototype.incMd5 = function (start, length) {
            var that = this;
            var chunkSize = that.maxChunkSize;
            var fileSize = that.fileSize;
            var spark = new SparkMD5.ArrayBuffer();

            var deferred = $q.defer();

            calculate(start, function (err, result) {
                if (err) {
                    return deferred.reject(err);
                }
                return deferred.resolve(result);
            });

            function calculate (now, done) {
                deferred.notify(now/fileSize);
                if(now > fileSize) {
                    return done(null, spark.end());
                }
                // get arraybuffer
                that.getArrayBuffer(now, chunkSize).then(function (array) {
                    spark.append(array);
                    return calculate(now + chunkSize, done);
                }, function (msg) {
                    return done(msg);
                });
            }

            return deferred.promise;

        };
        FileOperator.prototype.correctRange = function (start, length) {
            var fileSize = this.fileSize;
            start = (start && (start > 0)) ? start : 0;
            length = (length && (start + length < fileSize)) ? length : fileSize - start;
            return {
                start: start,
                length: length
            };
        };

        return function ServiceConstructor(file, maxChunkSize) {
            // When invoke this service, it will return a function,
            // service user can use it as a file loader, which will
            // return a file operator instance
            return new FileOperator(file, maxChunkSize);
        };

    }]);
<commit_msg>Fix MD5 generate bug<commit_after>var SparkMD5 = require('spark-md5');
var base64 = require('base64-arraybuffer').encode;
angular.module('angular.file', [])
    .factory('fileOperator', ['$window', '$q', function ($window, $q) {
        function FileOperator (file, maxChunkSize) {
            this.file = file;
            this.fileSize = (file && file.size) || 0;
            this.messages = [];
            // this property will only affect MD5 calculation
            this.maxChunkSize = maxChunkSize || 1048576;
        }
        FileOperator.prototype.read = function (start, end) {
            var that = this;
            var fileReader = new $window.FileReader();
            return $q(function (resolve, reject) {
                var fileChunk;
                if(!that.file) {
                    return reject(new Error('read','invalid file instance'));
                }
                // bind onloadend handler
                fileReader.onloadend = function (msg) {
                    resolve(fileReader.result);
                };
                fileReader.onerror = function (msg) {
                    reject(new Error('read', msg));
                };
                fileReader.onabort = function (msg) {
                    reject(msg);
                };

                // use slice.appy to handle three situation:
                // - both `start` and `end` are not given
                // - only `start` is given
                // - both `start` and `end` are given
                fileChunk = $window.File.prototype.slice.apply(
                    that.file,
                    [start, end]
                );

                fileReader.readAsArrayBuffer(fileChunk);
            });
        };
        FileOperator.prototype.abort = function () {
            fileReader.abort();
        };
        FileOperator.prototype.getArrayBuffer = function (start, length) {
            var params = this.correctRange(start, length);
            start = params.start;
            length = params.length;
            return this.read(start, start + length);
        };
        FileOperator.prototype.getUint8Array = function (start, length) {
            return this.getArrayBuffer(start, length).then(function (array) {
                return new Uint8Array(array);
            });
        };
        FileOperator.prototype.getBase64 = function (start, length) {
            return this.getArrayBuffer(start, length).then(function (array) {
                return base64(array);
            });
        };
        FileOperator.prototype.getMd5 = function (start, length) {
            var params = this.correctRange(start, length);
            start = params.start;
            length = params.length;

            // if require length is acceptable, get MD5 directly
            if(length < this.maxChunkSize) {
                return this.getArrayBuffer(start, length).then(function (data) {
                    return $q.when(SparkMD5.ArrayBuffer.hash(data));
                });
            }
            // otherwise calculate MD5 incrementally
            return this.incMd5(start, length);
        };
        FileOperator.prototype.incMd5 = function (start, length) {
            var that = this;
            var chunkSize = that.maxChunkSize;
            var fileSize = that.fileSize;
            var spark = new SparkMD5.ArrayBuffer();

            var deferred = $q.defer();

            calculate(start, function (err, result) {
                if (err) {
                    return deferred.reject(err);
                }
                return deferred.resolve(result);
            });

            function calculate (now, done) {
                deferred.notify(now/fileSize);
                if(now > fileSize) {
                    return done(null, spark.end());
                }
                // get arraybuffer
                that.getArrayBuffer(now, chunkSize).then(function (array) {
                    spark.append(array);
                    return calculate(now + chunkSize, done);
                }, function (msg) {
                    return done(msg);
                });
            }

            return deferred.promise;

        };
        FileOperator.prototype.correctRange = function (start, length) {
            var fileSize = this.fileSize;
            start = (start && (start > 0)) ? start : 0;
            length = (length && (start + length < fileSize)) ? length : fileSize - start;
            return {
                start: start,
                length: length
            };
        };

        return function ServiceConstructor(file, maxChunkSize) {
            // When invoke this service, it will return a function,
            // service user can use it as a file loader, which will
            // return a file operator instance
            return new FileOperator(file, maxChunkSize);
        };

    }]);
<|endoftext|>


<commit_before>// ==UserScript==
// @name        impartial-youtube
// @namespace   yt
// @include     https://www.youtube.com*
// @version     0.0.1
// @grant       none
// ==/UserScript==

'use strict';

const location = window.location; // for semistandard's sake
document.onreadystatechange = () => {
  if (document.readyState === 'complete') window.setInterval(impartial, 1000);
};

function impartial () {
  // hide views counts on home page, search page, trending page
  // and subscription page
  if (location.pathname !== '/watch') {
    Array.prototype.forEach.call(
      document.querySelectorAll('.yt-lockup-meta-info'),
      (v) => {
        if (
          location.pathname === '/' ||
          location.pathname === '/feed/subscriptions'
        ) {
          v.childNodes[0].style.display = 'none';
        }
        else if (
          location.pathname === '/results' ||
          location.pathname === '/feed/trending' ||
          location.pathname === '/feed/history'
        ) {
          if (v.childNodes.length === 1) {
            v.childNodes[0].style.display = 'none';
          } else {
            v.childNodes[1].style.display = 'none';
          }
        }
      });
  }
  // tweaks on video page
  else if (location.pathname === '/watch') {
    // hide views counts in recommendations
    Array.prototype.forEach.call(
      document.querySelectorAll('.view-count'),
      (v) => v.style.display = 'none');

    // hide video's views and likes/dislikes bar and count
    document.querySelector('#watch8-sentiment-actions').style.display = 'none';

    // hide video's uploader's subscribers count
    document.querySelector('.yt-subscriber-count').style.display = 'none';

    // hide comments and count
    let commentsHeader = document.querySelector('h2.comment-section-header-renderer');
    let sortMenu = document.querySelector('.comment-section-sort-menu');
    let comments = document.querySelector('#comment-section-renderer-items');
    let loadMoreBtn = document.querySelector('.comment-section-renderer-paginator');

    const commentsHeaderOriginalInnerHTML = commentsHeader.innerHTML;
    commentsHeader.innerHTML = 'Commentaires';
    sortMenu.style.display = 'none';
    comments.style.display = 'none';
    loadMoreBtn.style.display = 'none';

    // add a button to display comments
    let showCommentsBtn = document.createElement('button');
    showCommentsBtn.innerHTML = 'Show comments';
    showCommentsBtn.className = loadMoreBtn.className;
    showCommentsBtn.style.display = 'block';
    showCommentsBtn.onclick = () => {
      commentsHeader.innerHTML = commentsHeaderOriginalInnerHTML;
      sortMenu.style.display = '';
      comments.style.display = '';
      loadMoreBtn.style.display = '';
      showCommentsBtn.style.display = 'none';
    };
    document.querySelector('#comment-section-renderer')
      .insertBefore(showCommentsBtn, loadMoreBtn);
  }
  // hide views counts and subscribers count on user's page, user's videos page
  // and channels page
  else if (location.pathname.slice(0, 5) === '/user') {
    document.querySelector('.count').style.display = 'none';

    Array.prototype.forEach.call(
      document.querySelectorAll('.yt-lockup-meta-info'),
      (v) => {
        if (/\/user\/.*\/videos/.test(location.pathname)) {
          v.childNodes[0].style.display = 'none';
        } else {
          v.childNodes[0].style.display = 'none';
        }
      });

    document.querySelector('.subscribed').style.display = 'none';

    if (/\/user\/.*\/channels/.test(location.pathname)) {
      Array.prototype.forEach.call(
        document.querySelectorAll('.yt-subscription-button-subscriber-count-unbranded-horizontal'),
        (v) => v.style.display = 'none');
    }
  }

  // TODO: hide subscribers count when hovering an username
  Array.prototype.forEach.call(
    document.querySelectorAll('.subscribed'),
    (v) => v.style.display = 'none'
  );
}
<commit_msg>Fix show comments button<commit_after>// ==UserScript==
// @name        impartial-youtube
// @namespace   yt
// @include     https://www.youtube.com*
// @version     0.0.1
// @grant       none
// ==/UserScript==

'use strict';
const location = window.location; // for semistandard's sake
document.onreadystatechange = () => {
  //if (document.readyState === 'complete') impartial();
};
impartial();

function impartial () {
  if (location.pathname !== '/watch') {
    // hide views counts on home page, search page, trending page
    // and subscription page
    impartialNav();
  }
  else if (location.pathname === '/watch') {
    // tweaks on video page
    impartialWatch();
  }
  else if (location.pathname.slice(0, 5) === '/user') {
    // hide views counts and subscribers count on user's page, user's videos
    // page and channels page
    impartialUsers();
  }

  // TODO: hide subscribers count when hovering an username
  Array.prototype.forEach.call(
    document.querySelectorAll('.subscribed'),
    (v) => v.style.display = 'none'
  );
}

function impartialNav () {
  Array.prototype.forEach.call(
    document.querySelectorAll('.yt-lockup-meta-info'),
    (v) => {
      if (
        location.pathname === '/' ||
        location.pathname === '/feed/subscriptions'
      ) {
        v.childNodes[0].style.display = 'none';
      }
      else if (
        location.pathname === '/results' ||
        location.pathname === '/feed/trending' ||
        location.pathname === '/feed/history'
      ) {
        if (v.childNodes.length === 1) {
          v.childNodes[0].style.display = 'none';
        } else {
          v.childNodes[1].style.display = 'none';
        }
      }
    });
}

function impartialWatch () {
  // hide views counts in recommendations
  Array.prototype.forEach.call(
    document.querySelectorAll('.view-count'),
    (v) => v.style.display = 'none');

  // hide video's views and likes/dislikes bar and count
  document.querySelector('#watch8-sentiment-actions').style.display = 'none';

  // hide video's uploader's subscribers count
  document.querySelector('.yt-subscriber-count').style.display = 'none';

  const interval = window.setInterval(() => {
    if (impartialWatchComments()) clearInterval(interval);
  }, 100);
}

function impartialWatchComments () {
  if (document.querySelectorAll('.action-panel-loading').length === 4) {
    // hide comments and count
    let commentsHeader = document.querySelector('h2.comment-section-header-renderer');
    let sortMenu = document.querySelector('.comment-section-sort-menu');
    let comments = document.querySelector('#comment-section-renderer-items');
    let loadMoreBtn = document.querySelector('.comment-section-renderer-paginator');

    const commentsHeaderOriginalInnerHTML = commentsHeader.innerHTML;
    commentsHeader.innerHTML = 'Commentaires';
    sortMenu.style.display = 'none';
    comments.style.display = 'none';
    loadMoreBtn.style.display = 'none';

    // add a button to display comments
    let showCommentsBtn = document.createElement('button');
    showCommentsBtn.innerHTML = 'Show comments';
    showCommentsBtn.className = 'yt-uix-button yt-uix-button-size-default yt-uix-button-default load-more-button yt-uix-load-more yt-uix-sessionlink comment-section-renderer-paginator';
    showCommentsBtn.style.display = 'block';
    showCommentsBtn.onclick = () => {
      commentsHeader.innerHTML = commentsHeaderOriginalInnerHTML;
      sortMenu.style.display = '';
      comments.style.display = '';
      loadMoreBtn.style.display = '';
      showCommentsBtn.style.display = 'none';
    };
    document.querySelector('#comment-section-renderer')
      .insertBefore(showCommentsBtn, loadMoreBtn);

    return true;
  } else {
    return false;
  }
}

function impartialUsers () {
  document.querySelector('.count').style.display = 'none';

  Array.prototype.forEach.call(
    document.querySelectorAll('.yt-lockup-meta-info'),
    (v) => {
      if (/\/user\/.*\/videos/.test(location.pathname)) {
        v.childNodes[0].style.display = 'none';
      } else {
        v.childNodes[0].style.display = 'none';
      }
    });

  document.querySelector('.subscribed').style.display = 'none';

  if (/\/user\/.*\/channels/.test(location.pathname)) {
    Array.prototype.forEach.call(
      document.querySelectorAll('.yt-subscription-button-subscriber-count-unbranded-horizontal'),
      (v) => v.style.display = 'none');
  }
}
<|endoftext|>


<commit_before>var fs = Npm.require('fs');
var Future = Npm.require('fibers/future');

// used for sync io
var Fiber = Npm.require('fibers');
// used to launch tsc execuable
var exec = Npm.require('child_process').exec;
// provides file pattern match
var glob = Npm.require('glob');
var path = Npm.require('path');
// provides temp folder access
var temp = Npm.require('temp');
// provides rm -rf
var rimraf = Npm.require('rimraf');
// html5 localStorage for node
var storage = Npm.require('node-persist');

var fsStat = Future.wrap(fs.stat);

// create the code cache
storage.initSync({
	dir: 'typescript-cache'
});

this.archs = this.archs || {};
function initArch(archName) {
	var arch = archs[archName] = {name: archName};
	arch.modTimes = {};
	arch.cachedErrorReplays = [];
	resetCompilationScopedArch(arch);
}

// regex to parse errors
var TS_ERROR_REGEX = /(.*[.]ts)\((\d+),(\d)+\): (.+)/;

// filename used to trigger the missing meteor batch compilation
var PLACEHOLDER_FILENAME = "zzz.ts-compiler.ts";

var CORDOVA_PLATFORMS_FILENAME = ".meteor/cordova-platforms";

// find the TSC path
var tscPath = function() {
	var bins = glob.sync("~/.meteor/packages/*:tsc/*/plugin.compileTsc.os/npm/compileTsc/node_modules/typescript/bin/tsc").concat(
		glob.sync("packages/*:tsc/.npm/plugin/compileTsc/node_modules/typescript/bin/tsc"),
		glob.sync("C:/Program Files (x86)/Microsoft SDKs/TypeScript/**/tsc.exe"),
		glob.sync("/usr/local/bin/tsc"),
    glob.sync(process.env.PWD + "/**/node_modules/typescript/bin/tsc", {dot:true})
    );
	if (bins.length === 0) {
		console.error("Could not find tsc binary, defaulting to 'tsc'.")
		return "tsc";
	} else {
		return bins[0];
	}
}();

// create place holder file
checkForPlaceholderFile();

// that's the plugin code itself
Plugin.registerSourceHandler("ts", function(compileStep) {
	if (typeof(archs[compileStep.arch]) === 'undefined') {
		if (compileStep.arch === 'web.cordova' && !fs.existsSync(CORDOVA_PLATFORMS_FILENAME)) {
			// Don't bother compiling for cordova if the 'cordova-platforms' file does not exist
			return;
		}

		initArch(compileStep.arch);
	}

	handleSourceFile(compileStep);

	if (compileStep.inputPath !== PLACEHOLDER_FILENAME) {
		// Note that we compile the placeholder as well so tsc uses its dirname as the base for all relative paths it produces
		return;
	}

	// Typically, Meteor hands us all of the files pertaining to an arch in clumps (i.e. all files for browser, then all files for os), so most compiles are only two phases (client and server).
	for (var archName in archs) {
		var arch = archs[archName];
		if (arch.compileSteps.length === 0)
			continue;

		var hadMod = checkAgainstModTime(arch);
		compile(arch, compileStep, hadMod);
		resetCompilationScopedArch(arch);
	}
});

// Save the file input path, and return back to Meteor
function handleSourceFile(compileStep) {
	var arch = archs[compileStep.arch];

	checkForPlaceholderFile(compileStep);

	if (arch.fullInputPaths.indexOf(compileStep.fullInputPath) != -1) {
		return;
	}

	arch.fullInputPaths.push(compileStep.fullInputPath);
	arch.compileSteps.push(compileStep);
	arch.fullPathToCompileSteps[compileStep._fullInputPath] = compileStep;
}

function checkAgainstModTime(arch) {
	var hadModifications = false;
	arch.fullInputPaths.forEach(function(path) {
		var stats = fsStat(path).wait();
		if (typeof(arch.modTimes[path]) === 'undefined' || arch.modTimes[path].toString() !== stats.mtime.toString()) {
			hadModifications = true;
		}

		arch.modTimes[path] = stats.mtime;
	});

	return hadModifications;
}

function compile(arch, placeholderCompileStep, hadModifications) {
	if (!hadModifications) {
		// Short-circuit via cache
		addJavaScriptFromCacheInOrder(arch);

		// Replay errors
		arch.cachedErrorReplays.forEach(function(errReplay) {
			recordError(errReplay.err, placeholderCompileStep, errReplay.errorNumber, arch, true);
		});

		return;
	}

	// Typically just the arch name, unless a local package uses TypeScript in which case it will be appended
	var variantName = arch.name;
	if (placeholderCompileStep.rootOutputPath != '/') {
		variantName += " (" + placeholderCompileStep.rootOutputPath.substr(1) + ")";
	}
	console.log("\nCompiling TypeScript " + variantName + " files...");

	// Clear cached errors since we're about to re-compile
	arch.cachedErrorReplays = [];
	var errorCount = 0;
	var compileOptions = {
		'target': (arch.name === 'browser' ? 'ES3' : 'ES5'),
		'skipWrite': true
	};

	// This is synchronous (and our callback will get called multiple times if there are errors)
	tscCompile(arch.fullInputPaths, path.dirname(placeholderCompileStep.fullInputPath), compileOptions, function(err, results) {
		if (err) {
			recordError(err, placeholderCompileStep, ++errorCount, arch, false);
			if (typeof(results) === 'undefined') {
				return;
			}
		}

		results.forEach(function(result) {

			// result.name is the theoretically-generated js filename
			var tsFullPath = result.name.substr(0, result.name.length - 2) + "ts";
			var compileStep = arch.fullPathToCompileSteps[tsFullPath];
			if (compileStep) {
				var src = processGenSource(result.src || "");
				var map = result.map || "";
				// store in file cache
				storage.setItem(b64encode(compileStep.fullInputPath), [src, map]);
			}
		});
	});

	//console.log("\nDone");
	addJavaScriptFromCacheInOrder(arch);
}

// Generally matches the signature of the previous ts.compile
function tscCompile(fullInputPaths, placeholderDirPath, compileOptions, cb) {
	var out = temp.mkdirSync('tsc-out');
	var args = '"' + [tscPath, '--sourceMap', '--removeComments', '--outDir', out, '--target', compileOptions.target || 'ES5'].concat(fullInputPaths).join('" "') + '"';

	var fiber = Fiber.current;
	var execErr, execStdout, execStderr;
	exec(args, function(err, stdout, stderr) {
		execErr = err;
		execStdout = stdout;
		execStderr = stderr;
		fiber.run();
	});
	Fiber.yield();

	if (execStderr) {
		cb("\n" + execStderr);
		return;
	}

	if (execStdout) {
		cb("\n" + execStdout);
		return;
	}

	var res = glob.sync(path.join(out, '**', '*.js')).map(function(f) {

		return {
			name: path.join(placeholderDirPath, f.substr(out.length + 1)),
			src: fs.readFileSync(f, {encoding: 'utf8'}),
			map: fs.readFileSync(f + ".map", {encoding: 'utf8'})
		};
	});

	rimraf.sync(out);
	cb(undefined, res);
}

function processGenSource(src) {
	var lines = src.split("\n");
	for (var i = 0 ; i < lines.length ; i++) {
		var line = lines[i];
		var p = i + 1;
		if (line.toLowerCase().trim() == "//tsc export" && p < lines.length) {
			// Removes "var" for var, function and class definitions
			lines[p] = lines[p].replace(/\s?var\s/, "     ");
			// Replaces the original "var xyz;" (before the above line executed) with a "if (typeof xyz == 'undefined') { xyz = {}; }" for modules
			lines[p] = lines[p].replace(/^\s*([$A-Z_][0-9A-Z_$]*);$/i, "if (typeof $1 == 'undefined') { $1 = {}; }");
			i++;
		}
	}

	return lines.join("\n");
}

function addJavaScriptFromCacheInOrder(arch) {
	arch.compileSteps.forEach(function(compileStep) {

		var item = storage.getItem(b64encode(compileStep.fullInputPath));
		if(item) {

			compileStep.addJavaScript({
				path: compileStep.inputPath + ".js",
				sourcePath: compileStep.inputPath,
				data: item[0] || "",
				sourceMap: item[1] || ""
			})
		}
	});
}

function recordError(err, placeholderCompileStep, errorNumber, arch, isFromCache) {
	if (!isFromCache)
		arch.cachedErrorReplays.push({err: err, errNumber: errorNumber});

	var match = TS_ERROR_REGEX.exec(err.toString());
	if (match) {
		var compileStep = arch.fullPathToCompileSteps[match[1]];
		if (compileStep) {
			compileStep.error({
				message: match[4],
				sourcePath: match[1],
				line: match[2],
				column: match[3]
			});
			return;
		}
	}

	placeholderCompileStep.error({
		message: err.toString(),
		sourcePath: placeholderCompileStep.fullInputPath,
		line: errorNumber,
		column: 1
	});
}

function resetCompilationScopedArch(arch) {
	arch.fullInputPaths = [];
	arch.compileSteps = [];
	arch.fullPathToCompileSteps = {};
}

// ensures the place holder file is in place
function checkForPlaceholderFile(compileStep) {
	// Either curPath should be e.g. zzz.ts-compiler.ts or packages/myPkg/zzz.ts-compiler.ts
	var curPath = (!compileStep || compileStep.rootOutputPath == '/') ? PLACEHOLDER_FILENAME : compileStep.rootOutputPath.substr(1) + "/" + PLACEHOLDER_FILENAME;

	// Check and see if we are trying to create the placeholder file in the root directory, if we are, then switch over to the fullInputPath that we
	// receive from the compileStep object.
	if (compileStep && curPath === '/zzz.ts-compiler.ts') curPath = compileStep.fullInputPath;

	if (!fs.existsSync(curPath)) {
		fs.writeFileSync(curPath, "// please add this file to .gitignore - it is used internally by typescript-compiler and must be the last file to compile\n// This needs some real logic so that tsc will use this dir as the starting path for all produced output\nif (true) {}\n");
		var errorMsg = "typescript-compiler:The file \"" + curPath + "\" has been created to help batch compilation of typescript assets. Please ignore it from your source control.";
		if (typeof(compileStep) !== 'undefined') {
			compileStep.error({message: errorMsg});
		} else {
			console.error(errorMsg);
		}
	}
}

function b64encode(s) {
	return new Buffer(s).toString('base64');
}
<commit_msg>Send --jsx react option to compiler<commit_after>var fs = Npm.require('fs');
var Future = Npm.require('fibers/future');

// used for sync io
var Fiber = Npm.require('fibers');
// used to launch tsc execuable
var exec = Npm.require('child_process').exec;
// provides file pattern match
var glob = Npm.require('glob');
var path = Npm.require('path');
// provides temp folder access
var temp = Npm.require('temp');
// provides rm -rf
var rimraf = Npm.require('rimraf');
// html5 localStorage for node
var storage = Npm.require('node-persist');

var fsStat = Future.wrap(fs.stat);

// create the code cache
storage.initSync({
	dir: 'typescript-cache'
});

this.archs = this.archs || {};
function initArch(archName) {
	var arch = archs[archName] = {name: archName};
	arch.modTimes = {};
	arch.cachedErrorReplays = [];
	resetCompilationScopedArch(arch);
}

// regex to parse errors
var TS_ERROR_REGEX = /(.*[.]ts)\((\d+),(\d)+\): (.+)/;

// filename used to trigger the missing meteor batch compilation
var PLACEHOLDER_FILENAME = "zzz.ts-compiler.ts";

var CORDOVA_PLATFORMS_FILENAME = ".meteor/cordova-platforms";

// find the TSC path
var tscPath = function() {
	var bins = glob.sync("~/.meteor/packages/*:tsc/*/plugin.compileTsc.os/npm/compileTsc/node_modules/typescript/bin/tsc").concat(
		glob.sync("packages/*:tsc/.npm/plugin/compileTsc/node_modules/typescript/bin/tsc"),
		glob.sync("C:/Program Files (x86)/Microsoft SDKs/TypeScript/**/tsc.exe"),
		glob.sync("/usr/local/bin/tsc"),
    glob.sync(process.env.PWD + "/**/node_modules/typescript/bin/tsc", {dot:true})
    );
	if (bins.length === 0) {
		console.error("Could not find tsc binary, defaulting to 'tsc'.")
		return "tsc";
	} else {
		return bins[0];
	}
}();

// create place holder file
checkForPlaceholderFile();

// that's the plugin code itself
Plugin.registerSourceHandler("ts", function(compileStep) {
	if (typeof(archs[compileStep.arch]) === 'undefined') {
		if (compileStep.arch === 'web.cordova' && !fs.existsSync(CORDOVA_PLATFORMS_FILENAME)) {
			// Don't bother compiling for cordova if the 'cordova-platforms' file does not exist
			return;
		}

		initArch(compileStep.arch);
	}

	handleSourceFile(compileStep);

	if (compileStep.inputPath !== PLACEHOLDER_FILENAME) {
		// Note that we compile the placeholder as well so tsc uses its dirname as the base for all relative paths it produces
		return;
	}

	// Typically, Meteor hands us all of the files pertaining to an arch in clumps (i.e. all files for browser, then all files for os), so most compiles are only two phases (client and server).
	for (var archName in archs) {
		var arch = archs[archName];
		if (arch.compileSteps.length === 0)
			continue;

		var hadMod = checkAgainstModTime(arch);
		compile(arch, compileStep, hadMod);
		resetCompilationScopedArch(arch);
	}
});

// Save the file input path, and return back to Meteor
function handleSourceFile(compileStep) {
	var arch = archs[compileStep.arch];

	checkForPlaceholderFile(compileStep);

	if (arch.fullInputPaths.indexOf(compileStep.fullInputPath) != -1) {
		return;
	}

	arch.fullInputPaths.push(compileStep.fullInputPath);
	arch.compileSteps.push(compileStep);
	arch.fullPathToCompileSteps[compileStep._fullInputPath] = compileStep;
}

function checkAgainstModTime(arch) {
	var hadModifications = false;
	arch.fullInputPaths.forEach(function(path) {
		var stats = fsStat(path).wait();
		if (typeof(arch.modTimes[path]) === 'undefined' || arch.modTimes[path].toString() !== stats.mtime.toString()) {
			hadModifications = true;
		}

		arch.modTimes[path] = stats.mtime;
	});

	return hadModifications;
}

function compile(arch, placeholderCompileStep, hadModifications) {
	if (!hadModifications) {
		// Short-circuit via cache
		addJavaScriptFromCacheInOrder(arch);

		// Replay errors
		arch.cachedErrorReplays.forEach(function(errReplay) {
			recordError(errReplay.err, placeholderCompileStep, errReplay.errorNumber, arch, true);
		});

		return;
	}

	// Typically just the arch name, unless a local package uses TypeScript in which case it will be appended
	var variantName = arch.name;
	if (placeholderCompileStep.rootOutputPath != '/') {
		variantName += " (" + placeholderCompileStep.rootOutputPath.substr(1) + ")";
	}
	console.log("\nCompiling TypeScript " + variantName + " files...");

	// Clear cached errors since we're about to re-compile
	arch.cachedErrorReplays = [];
	var errorCount = 0;
	var compileOptions = {
		'target': (arch.name === 'browser' ? 'ES3' : 'ES5'),
		'skipWrite': true
	};

	// This is synchronous (and our callback will get called multiple times if there are errors)
	tscCompile(arch.fullInputPaths, path.dirname(placeholderCompileStep.fullInputPath), compileOptions, function(err, results) {
		if (err) {
			recordError(err, placeholderCompileStep, ++errorCount, arch, false);
			if (typeof(results) === 'undefined') {
				return;
			}
		}

		results.forEach(function(result) {

			// result.name is the theoretically-generated js filename
			var tsFullPath = result.name.substr(0, result.name.length - 2) + "ts";
			var compileStep = arch.fullPathToCompileSteps[tsFullPath];
			if (compileStep) {
				var src = processGenSource(result.src || "");
				var map = result.map || "";
				// store in file cache
				storage.setItem(b64encode(compileStep.fullInputPath), [src, map]);
			}
		});
	});

	//console.log("\nDone");
	addJavaScriptFromCacheInOrder(arch);
}

// Generally matches the signature of the previous ts.compile
function tscCompile(fullInputPaths, placeholderDirPath, compileOptions, cb) {
	var out = temp.mkdirSync('tsc-out');
	var args = '"' + [tscPath, '--sourceMap', '--jsx', 'react', '--removeComments', '--outDir', out, '--target', compileOptions.target || 'ES5'].concat(fullInputPaths).join('" "') + '"';

	var fiber = Fiber.current;
	var execErr, execStdout, execStderr;
	exec(args, function(err, stdout, stderr) {
		execErr = err;
		execStdout = stdout;
		execStderr = stderr;
		fiber.run();
	});
	Fiber.yield();

	if (execStderr) {
		cb("\n" + execStderr);
		return;
	}

	if (execStdout) {
		cb("\n" + execStdout);
		return;
	}

	var res = glob.sync(path.join(out, '**', '*.js')).map(function(f) {

		return {
			name: path.join(placeholderDirPath, f.substr(out.length + 1)),
			src: fs.readFileSync(f, {encoding: 'utf8'}),
			map: fs.readFileSync(f + ".map", {encoding: 'utf8'})
		};
	});

	rimraf.sync(out);
	cb(undefined, res);
}

function processGenSource(src) {
	var lines = src.split("\n");
	for (var i = 0 ; i < lines.length ; i++) {
		var line = lines[i];
		var p = i + 1;
		if (line.toLowerCase().trim() == "//tsc export" && p < lines.length) {
			// Removes "var" for var, function and class definitions
			lines[p] = lines[p].replace(/\s?var\s/, "     ");
			// Replaces the original "var xyz;" (before the above line executed) with a "if (typeof xyz == 'undefined') { xyz = {}; }" for modules
			lines[p] = lines[p].replace(/^\s*([$A-Z_][0-9A-Z_$]*);$/i, "if (typeof $1 == 'undefined') { $1 = {}; }");
			i++;
		}
	}

	return lines.join("\n");
}

function addJavaScriptFromCacheInOrder(arch) {
	arch.compileSteps.forEach(function(compileStep) {

		var item = storage.getItem(b64encode(compileStep.fullInputPath));
		if(item) {

			compileStep.addJavaScript({
				path: compileStep.inputPath + ".js",
				sourcePath: compileStep.inputPath,
				data: item[0] || "",
				sourceMap: item[1] || ""
			})
		}
	});
}

function recordError(err, placeholderCompileStep, errorNumber, arch, isFromCache) {
	if (!isFromCache)
		arch.cachedErrorReplays.push({err: err, errNumber: errorNumber});

	var match = TS_ERROR_REGEX.exec(err.toString());
	if (match) {
		var compileStep = arch.fullPathToCompileSteps[match[1]];
		if (compileStep) {
			compileStep.error({
				message: match[4],
				sourcePath: match[1],
				line: match[2],
				column: match[3]
			});
			return;
		}
	}

	placeholderCompileStep.error({
		message: err.toString(),
		sourcePath: placeholderCompileStep.fullInputPath,
		line: errorNumber,
		column: 1
	});
}

function resetCompilationScopedArch(arch) {
	arch.fullInputPaths = [];
	arch.compileSteps = [];
	arch.fullPathToCompileSteps = {};
}

// ensures the place holder file is in place
function checkForPlaceholderFile(compileStep) {
	// Either curPath should be e.g. zzz.ts-compiler.ts or packages/myPkg/zzz.ts-compiler.ts
	var curPath = (!compileStep || compileStep.rootOutputPath == '/') ? PLACEHOLDER_FILENAME : compileStep.rootOutputPath.substr(1) + "/" + PLACEHOLDER_FILENAME;

	// Check and see if we are trying to create the placeholder file in the root directory, if we are, then switch over to the fullInputPath that we
	// receive from the compileStep object.
	if (compileStep && curPath === '/zzz.ts-compiler.ts') curPath = compileStep.fullInputPath;

	if (!fs.existsSync(curPath)) {
		fs.writeFileSync(curPath, "// please add this file to .gitignore - it is used internally by typescript-compiler and must be the last file to compile\n// This needs some real logic so that tsc will use this dir as the starting path for all produced output\nif (true) {}\n");
		var errorMsg = "typescript-compiler:The file \"" + curPath + "\" has been created to help batch compilation of typescript assets. Please ignore it from your source control.";
		if (typeof(compileStep) !== 'undefined') {
			compileStep.error({message: errorMsg});
		} else {
			console.error(errorMsg);
		}
	}
}

function b64encode(s) {
	return new Buffer(s).toString('base64');
}
<|endoftext|>


<commit_before>define(["dijit/_WidgetBase","dijit/_Container","dijit/_Contained","./PageIndicator","./SwapView"], function(WidgetBase,Container,Contained,PageIndicator,SwapView){
	// module:
	//		dojox/mobile/Carousel
	// summary:
	//		TODOC

	dojo.experimental("dojox.mobile.Carousel");

	return dojo.declare("dojox.mobile.Carousel", [dijit._WidgetBase, dijit._Container, dijit._Contained], {
		numVisible: 3, // the number of visible items
		title: "",
		pageIndicator: true,
		navButton: false,
		height: "300px",
		store: null,
		query: null,
		queryOptions: null,

		buildRendering: function(){
			this.inherited(arguments);
			this.domNode.className = "mblCarousel";
			var h;
			if(this.height === "inherit"){
				if(this.domNode.offsetParent){
					h = this.domNode.offsetParent.offsetHeight + "px";
				}
			}else if(this.height){
				h = this.height;
			}
			this.domNode.style.height = h;
			dojo.setSelectable(this.domNode, false);
			this.headerNode = dojo.create("DIV", {className:"mblCarouselHeaderBar"}, this.domNode);

			if(this.navButton){
				this.btnContainerNode = dojo.create("DIV", {
					className: "mblCarouselBtnContainer"
				}, this.headerNode);
				this.prevBtnNode = dojo.create("BUTTON", {
					className: "mblCarouselBtn",
					title: "Previous",
					innerHTML: "<"
				}, this.btnContainerNode);
				this.nextBtnNode = dojo.create("BUTTON", {
					className: "mblCarouselBtn",
					title: "Next",
					innerHTML: ">"
				}, this.btnContainerNode);
				this.connect(this.prevBtnNode, "onclick", "onPrevBtnClick");
				this.connect(this.nextBtnNode, "onclick", "onNextBtnClick");
			}

			if(this.pageIndicator){
				if(!this.title){
					this.title = " ";
				}
				this.piw = new dojox.mobile.PageIndicator();
				this.headerNode.appendChild(this.piw.domNode);
			}

			this.titleNode = dojo.create("DIV", {
				className: "mblCarouselTitle"
			}, this.headerNode);

			this.containerNode = dojo.create("DIV", {className:"mblCarouselPages"}, this.domNode);
			dojo.subscribe("/dojox/mobile/viewChanged", this, "handleViewChanged");
		},

		startup: function(){
			if(this._started){ return; }
			if(this.store){
				var store = this.store;
				this.store = null;
				this.setStore(store, this.query, this.queryOptions);
			}
			this.inherited(arguments);
		},

		setStore: function(store, query, queryOptions){
			if(store === this.store){ return; }
			this.store = store;
			this.query = query;
			this.queryOptions = queryOptions;
			this.refresh();
		},

		refresh: function(){
			if(!this.store){ return; }
			this.store.fetch({
				query: this.query,
				queryOptions: this.queryOptions,
				onComplete: dojo.hitch(this, "generate"),
				onError: dojo.hitch(this, "onError")
			});
		},

		generate: function(/*Array*/items, /*Object*/ dataObject){
			dojo.forEach(this.getChildren(), function(child){
				if(child instanceof dojox.mobile.SwapView){
					child.destroyRecursive();
				}
			});
			this.items = items;
			this.swapViews = [];
			this.images = [];
			var nPages = Math.ceil(items.length / this.numVisible);
			var h = this.domNode.offsetHeight - this.headerNode.offsetHeight;
			for(var i = 0; i < nPages; i++){
				var w = new dojox.mobile.SwapView({height:h+"px"});
				this.addChild(w);
				this.swapViews.push(w);
				w._carouselImages = [];
				if(i === 0 && this.piw){
					this.piw.refId = w.id;
				}
				for(var j = 0; j < this.numVisible; j++){
					var idx = i * this.numVisible + j;
					var item = idx < items.length ? items[idx] :
						{src:dojo.moduleUrl("dojo", "resources/blank.gif"), height:"1px"};
					var disp = w.domNode.style.display;
					w.domNode.style.display = ""; // need to be visible during the size calculation
					var box = this.createBox(item, h);
					w.containerNode.appendChild(box);
					box.appendChild(this.createHeaderText(item));
					var img = this.createContent(item, idx);
					box.appendChild(img);
					box.appendChild(this.createFooterText(item));
					this.resizeContent(item, box, img);
					w.domNode.style.display = disp;

					if(item.height !== "1px"){
						this.images.push(img);
						w._carouselImages.push(img);
					}
				}
			}
			if(this.swapViews[0]){
				this.loadImages(this.swapViews[0]);
			}
			if(this.swapViews[1]){
				this.loadImages(this.swapViews[1]); // pre-fetch the next view images
			}
			this.currentView = this.swapViews[0];
			if(this.piw){
				this.piw.reset();
			}
		},

		createBox: function(item, h){
			var width = item.width || (90/this.numVisible + "%");
			var height = item.height || h + "px";
			var m = dojo.isIE ? 5/this.numVisible-1 : 5/this.numVisible
			var margin = item.margin || (m + "%");
			var box = dojo.create("DIV", {
				className: "mblCarouselBox"
			});
			dojo.style(box, {
				margin: "0px " + margin,
				width: width,
				height: height
			});
			return box;
		},

		createHeaderText: function(item){
			this.headerTextNode = dojo.create("DIV", {
				className: "mblCarouselImgHeaderText",
				innerHTML: item.headerText ? item.headerText : " "
			});
			return this.headerTextNode;
		},

		createContent: function(item, idx){
			var props = {
				alt: item.alt || "",
				tabIndex: "0", // for keyboard navigation on a desktop browser
				className: "mblCarouselImg"
			};
			var img = dojo.create("IMG", props);
			img._idx = idx;
			if(item.height !== "1px"){
				this.connect(img, "onclick", "onClick");
				this.connect(img, "onkeydown", "onClick");
				dojo.connect(img, "ondragstart", dojo.stopEvent);
			}else{
				img.style.visibility = "hidden";
			}
			return img;
		},

		createFooterText: function(item){
			this.footerTextNode = dojo.create("DIV", {
				className: "mblCarouselImgFooterText",
				innerHTML: item.footerText ? item.footerText : " "
			});
			return this.footerTextNode;
		},

		resizeContent: function(item, box, img){
			if(item.height !== "1px"){
				img.style.height = (box.offsetHeight  - this.headerTextNode.offsetHeight - this.footerTextNode.offsetHeight) + "px";
			}
		},

		onError: function(errText){
		},

		onPrevBtnClick: function(e){
			if(this.currentView){
				this.currentView.goTo(-1);
			}
		},

		onNextBtnClick: function(e){
			if(this.currentView){
				this.currentView.goTo(1);
			}
		},

		onClick: function(e){
			if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
			var img = e.currentTarget;
			for(var i = 0; i < this.images.length; i++){
				if(this.images[i] === img){
					dojo.addClass(img, "mblCarouselImgSelected");
				}else{
					dojo.removeClass(this.images[i], "mblCarouselImgSelected");
				}
			}
			this.setOpacity(img, 0.4);
			var _this = this;
			setTimeout(function(){
				_this.setOpacity(img, 1);
			}, 1000);
			dojo.publish("/dojox/mobile/carouselSelect", [this, img, this.items[img._idx], img._idx]);
		},

		setOpacity: function(node, val){
			// dojo._setOpacity unfortunately requires dojo.query...
			node.style.opacity = val;
			node.style.mozOpacity = val;
			node.style.khtmlOpacity = val;
			node.style.webkitOpacity = val;
		},

		loadImages: function(view){
			if(!view){ return; }
			var imgs = view._carouselImages;
			dojo.forEach(imgs, function(img){
				if(!img.src){
					var item = this.items[img._idx];
					img.src = item.src;
				}
			}, this);
		},

		handleViewChanged: function(view){
			if(view.getParent() !== this){ return; }
			this.currentView = view;
			// lazy-load images in the next view
			this.loadImages(view.nextView(view.domNode));
		},

		_setTitleAttr: function(/*String*/title){
			this.title = title;
			this.titleNode.innerHTML = title;
		}
	});
});
<commit_msg>Refs #12911 !strict Workaround for webkit rendering problem <commit_after>define(["dijit/_WidgetBase","dijit/_Container","dijit/_Contained","./PageIndicator","./SwapView"], function(WidgetBase,Container,Contained,PageIndicator,SwapView){
	// module:
	//		dojox/mobile/Carousel
	// summary:
	//		TODOC

	dojo.experimental("dojox.mobile.Carousel");

	return dojo.declare("dojox.mobile.Carousel", [dijit._WidgetBase, dijit._Container, dijit._Contained], {
		numVisible: 3, // the number of visible items
		title: "",
		pageIndicator: true,
		navButton: false,
		height: "300px",
		store: null,
		query: null,
		queryOptions: null,

		buildRendering: function(){
			this.inherited(arguments);
			this.domNode.className = "mblCarousel";
			var h;
			if(this.height === "inherit"){
				if(this.domNode.offsetParent){
					h = this.domNode.offsetParent.offsetHeight + "px";
				}
			}else if(this.height){
				h = this.height;
			}
			this.domNode.style.height = h;
			dojo.setSelectable(this.domNode, false);
			this.headerNode = dojo.create("DIV", {className:"mblCarouselHeaderBar"}, this.domNode);

			if(this.navButton){
				this.btnContainerNode = dojo.create("DIV", {
					className: "mblCarouselBtnContainer"
				}, this.headerNode);
				dojo.style(this.btnContainerNode, "float", "right"); // workaround for webkit rendering problem
				this.prevBtnNode = dojo.create("BUTTON", {
					className: "mblCarouselBtn",
					title: "Previous",
					innerHTML: "<"
				}, this.btnContainerNode);
				this.nextBtnNode = dojo.create("BUTTON", {
					className: "mblCarouselBtn",
					title: "Next",
					innerHTML: ">"
				}, this.btnContainerNode);
				this.connect(this.prevBtnNode, "onclick", "onPrevBtnClick");
				this.connect(this.nextBtnNode, "onclick", "onNextBtnClick");
			}

			if(this.pageIndicator){
				if(!this.title){
					this.title = " ";
				}
				this.piw = new dojox.mobile.PageIndicator();
				dojo.style(this.piw, "float", "right"); // workaround for webkit rendering problem
				this.headerNode.appendChild(this.piw.domNode);
			}

			this.titleNode = dojo.create("DIV", {
				className: "mblCarouselTitle"
			}, this.headerNode);

			this.containerNode = dojo.create("DIV", {className:"mblCarouselPages"}, this.domNode);
			dojo.subscribe("/dojox/mobile/viewChanged", this, "handleViewChanged");
		},

		startup: function(){
			if(this._started){ return; }
			if(this.store){
				var store = this.store;
				this.store = null;
				this.setStore(store, this.query, this.queryOptions);
			}
			this.inherited(arguments);
		},

		setStore: function(store, query, queryOptions){
			if(store === this.store){ return; }
			this.store = store;
			this.query = query;
			this.queryOptions = queryOptions;
			this.refresh();
		},

		refresh: function(){
			if(!this.store){ return; }
			this.store.fetch({
				query: this.query,
				queryOptions: this.queryOptions,
				onComplete: dojo.hitch(this, "generate"),
				onError: dojo.hitch(this, "onError")
			});
		},

		generate: function(/*Array*/items, /*Object*/ dataObject){
			dojo.forEach(this.getChildren(), function(child){
				if(child instanceof dojox.mobile.SwapView){
					child.destroyRecursive();
				}
			});
			this.items = items;
			this.swapViews = [];
			this.images = [];
			var nPages = Math.ceil(items.length / this.numVisible);
			var h = this.domNode.offsetHeight - this.headerNode.offsetHeight;
			for(var i = 0; i < nPages; i++){
				var w = new dojox.mobile.SwapView({height:h+"px"});
				this.addChild(w);
				this.swapViews.push(w);
				w._carouselImages = [];
				if(i === 0 && this.piw){
					this.piw.refId = w.id;
				}
				for(var j = 0; j < this.numVisible; j++){
					var idx = i * this.numVisible + j;
					var item = idx < items.length ? items[idx] :
						{src:dojo.moduleUrl("dojo", "resources/blank.gif"), height:"1px"};
					var disp = w.domNode.style.display;
					w.domNode.style.display = ""; // need to be visible during the size calculation
					var box = this.createBox(item, h);
					w.containerNode.appendChild(box);
					box.appendChild(this.createHeaderText(item));
					var img = this.createContent(item, idx);
					box.appendChild(img);
					box.appendChild(this.createFooterText(item));
					this.resizeContent(item, box, img);
					w.domNode.style.display = disp;

					if(item.height !== "1px"){
						this.images.push(img);
						w._carouselImages.push(img);
					}
				}
			}
			if(this.swapViews[0]){
				this.loadImages(this.swapViews[0]);
			}
			if(this.swapViews[1]){
				this.loadImages(this.swapViews[1]); // pre-fetch the next view images
			}
			this.currentView = this.swapViews[0];
			if(this.piw){
				this.piw.reset();
			}
		},

		createBox: function(item, h){
			var width = item.width || (90/this.numVisible + "%");
			var height = item.height || h + "px";
			var m = dojo.isIE ? 5/this.numVisible-1 : 5/this.numVisible;
			var margin = item.margin || (m + "%");
			var box = dojo.create("DIV", {
				className: "mblCarouselBox"
			});
			dojo.style(box, {
				margin: "0px " + margin,
				width: width,
				height: height
			});
			return box;
		},

		createHeaderText: function(item){
			this.headerTextNode = dojo.create("DIV", {
				className: "mblCarouselImgHeaderText",
				innerHTML: item.headerText ? item.headerText : " "
			});
			return this.headerTextNode;
		},

		createContent: function(item, idx){
			var props = {
				alt: item.alt || "",
				tabIndex: "0", // for keyboard navigation on a desktop browser
				className: "mblCarouselImg"
			};
			var img = dojo.create("IMG", props);
			img._idx = idx;
			if(item.height !== "1px"){
				this.connect(img, "onclick", "onClick");
				this.connect(img, "onkeydown", "onClick");
				dojo.connect(img, "ondragstart", dojo.stopEvent);
			}else{
				img.style.visibility = "hidden";
			}
			return img;
		},

		createFooterText: function(item){
			this.footerTextNode = dojo.create("DIV", {
				className: "mblCarouselImgFooterText",
				innerHTML: item.footerText ? item.footerText : " "
			});
			return this.footerTextNode;
		},

		resizeContent: function(item, box, img){
			if(item.height !== "1px"){
				img.style.height = (box.offsetHeight  - this.headerTextNode.offsetHeight - this.footerTextNode.offsetHeight) + "px";
			}
		},

		onError: function(errText){
		},

		onPrevBtnClick: function(e){
			if(this.currentView){
				this.currentView.goTo(-1);
			}
		},

		onNextBtnClick: function(e){
			if(this.currentView){
				this.currentView.goTo(1);
			}
		},

		onClick: function(e){
			if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
			var img = e.currentTarget;
			for(var i = 0; i < this.images.length; i++){
				if(this.images[i] === img){
					dojo.addClass(img, "mblCarouselImgSelected");
				}else{
					dojo.removeClass(this.images[i], "mblCarouselImgSelected");
				}
			}
			this.setOpacity(img, 0.4);
			var _this = this;
			setTimeout(function(){
				_this.setOpacity(img, 1);
			}, 1000);
			dojo.publish("/dojox/mobile/carouselSelect", [this, img, this.items[img._idx], img._idx]);
		},

		setOpacity: function(node, val){
			// dojo._setOpacity unfortunately requires dojo.query...
			node.style.opacity = val;
			node.style.mozOpacity = val;
			node.style.khtmlOpacity = val;
			node.style.webkitOpacity = val;
		},

		loadImages: function(view){
			if(!view){ return; }
			var imgs = view._carouselImages;
			dojo.forEach(imgs, function(img){
				if(!img.src){
					var item = this.items[img._idx];
					img.src = item.src;
				}
			}, this);
		},

		handleViewChanged: function(view){
			if(view.getParent() !== this){ return; }
			this.currentView = view;
			// lazy-load images in the next view
			this.loadImages(view.nextView(view.domNode));
		},

		_setTitleAttr: function(/*String*/title){
			this.title = title;
			this.titleNode.innerHTML = title;
		}
	});
});
<|endoftext|>


<commit_before>/*
 * FFT plugin for dancer.js
 *
 * Usage of frequencies being 2px with 1px spacing:
 *
 * var dancer = new Dancer('song.ogg'),
 *     canvas = document.getElementById('fftcanvas');
 * dancer.fft( canvas, 2, 1 );
 */

(function() {
  Dancer.addPlugin( 'fft', function( canvasEl, options ) {
    options = options || {};
    var
      ctx     = canvasEl.getContext( '2d' ),
      h       = canvasEl.height,
      w       = canvasEl.width,
      width   = options.width || 1,
      spacing = options.spacing || 0,
      count   = options.count || 512;

    ctx.fillStyle = options.fillStyle || "white";

    this.bind( 'update', function() {
      var spectrum = this.getSpectrum();
      ctx.clearRect( 0, 0, w, h );
      for ( var i = 0, l = spectrum.length; i < l && i < count; i++ ) {
        ctx.fillRect( i * ( spacing + width ), h, width, -spectrum[ i ] * h );
      }
    });

    return this;
  });
})();
<commit_msg>Fix example in fft plugin<commit_after>/*
 * FFT plugin for dancer.js
 *
 * Usage of frequencies being 2px with 1px spacing:
 *
 * var dancer = new Dancer('song.ogg'),
 *     canvas = document.getElementById('fftcanvas');
 * dancer.fft( canvas, { width: 2, spacing: 1 });
 */

(function() {
  Dancer.addPlugin( 'fft', function( canvasEl, options ) {
    options = options || {};
    var
      ctx     = canvasEl.getContext( '2d' ),
      h       = canvasEl.height,
      w       = canvasEl.width,
      width   = options.width || 1,
      spacing = options.spacing || 0,
      count   = options.count || 512;

    ctx.fillStyle = options.fillStyle || "white";

    this.bind( 'update', function() {
      var spectrum = this.getSpectrum();
      ctx.clearRect( 0, 0, w, h );
      for ( var i = 0, l = spectrum.length; i < l && i < count; i++ ) {
        ctx.fillRect( i * ( spacing + width ), h, width, -spectrum[ i ] * h );
      }
    });

    return this;
  });
})();
<|endoftext|>


<commit_before>/**
 Copyright 2014 Gordon Williams (gw@pur3.co.uk),
                Victor Nakoryakov (victor@amperka.ru)

 This Source Code is subject to the terms of the Mozilla Public
 License, v2.0. If a copy of the MPL was not distributed with this
 file, You can obtain one at http://mozilla.org/MPL/2.0/.

 ------------------------------------------------------------------
  Wrap whole code in `onInit` function before send and save() it
  after upload. Wrapping is necessary to avoid execution start
  before save() is executed
 ------------------------------------------------------------------
**/
"use strict";
(function(){

  function init() {
    Espruino.Core.Config.add("SAVE_ON_SEND", {
      section : "Communications",
      name : "Save on Send",
      description : "Save the code after sending so that it is executed again as is on board restart",
      type : "boolean",
      defaultValue : false
    });

    Espruino.addProcessor("transformForEspruino", function(code, callback) {
      wrap(code, callback);
    });
  }

  function wrap(code, callback) {
    if (!Espruino.Config.SAVE_ON_SEND) return callback(code);

    var newCode = [];
    newCode.push("function onInit() {");
    newCode.push(code);
    newCode.push("}");
    newCode.push("save();");
    newCode = newCode.join('');
    callback(newCode);
  }

  Espruino.Plugins.SaveOnSend = {
    init : init,
  };
}());
<commit_msg>update: use E.setBootCode behind save-on-send plugin implementation<commit_after>/**
 Copyright 2014 Gordon Williams (gw@pur3.co.uk),
                Victor Nakoryakov (victor@amperka.ru)

 This Source Code is subject to the terms of the Mozilla Public
 License, v2.0. If a copy of the MPL was not distributed with this
 file, You can obtain one at http://mozilla.org/MPL/2.0/.

 ------------------------------------------------------------------
  Wrap whole code in `onInit` function before send and save() it
  after upload. Wrapping is necessary to avoid execution start
  before save() is executed
 ------------------------------------------------------------------
**/
"use strict";
(function(){

  function init() {
    Espruino.Core.Config.add("SAVE_ON_SEND", {
      section : "Communications",
      name : "Save on Send",
      description : "Save the code after sending so that it is executed again as is on board restart",
      type : "boolean",
      defaultValue : false
    });

    Espruino.addProcessor("transformForEspruino", function(code, callback) {
      wrap(code, callback);
    });
  }

  function wrap(code, callback) {
    if (!Espruino.Config.SAVE_ON_SEND) return callback(code);

    var newCode = [];
    newCode.push("E.setBootCode(");
    newCode.push(JSON.stringify(code));
    newCode.push(");\n");
    newCode.push("reset();");
    newCode.push("load();");
    newCode = newCode.join('');

    console.log('Save on send transformed code to:', newCode);
    callback(newCode);
  }

  Espruino.Plugins.SaveOnSend = {
    init : init,
  };
}());
<|endoftext|>


<commit_before>// TODO Check the filesize https://stackoverflow.com/questions/3717793/javascript-file-upload-size-validation
//  and suggest they resize if using an appropriate tool https://www.google.com/search?q=compress+photo+online+to+200kb
//  for example https://www.img2go.com/compress-image or https://www.imgonline.com.ua/eng/compress-image-size.php
//  or https://sqooush.app

(function () {
    'use strict';

    var app = angular.module('uploadModule', [
        'blueimp.fileupload'
    ]);

    var getIdFromUrl = function (url) {
        var breakdown = /\/file\/(.+?)\/([0-9a-f]{24})/.exec(url);
        return breakdown[2];
    };

    app
        .controller('FngUploadAdditFieldsCtrl', ['$scope', '$timeout', function ($scope, $timeout) {
            $scope.record = {};

            $scope.$watch('record', function (newVal, oldVal) {
                if (newVal !== oldVal) {
                    $scope.uploadForm.formScope[$scope.uploadForm.formScope.topLevelFormName].$setDirty();
                    angular.extend($scope.uploadForm.dataField()[$scope.file], newVal);
                }
            }, true);

            function setUpAdditFields() {
                if ($scope.schema) {
                    $scope.schema.forEach(function (field) {
                        var objVal = $scope.uploadForm.dataField()[$scope.file];
                        $scope.record[field.name] = objVal ? objVal[field.name] : undefined;
                    });
                }
            }

            function doSetUp() {
                if (!$scope.formScope.newRecord) {
                    var watchDeregister = $scope.formScope.$watch('phase', function (newVal) {
                        if (newVal === 'ready') {
                            setUpAdditFields();
                            $scope.$on('fngCancel', function () {
                                setUpAdditFields();
                            });
                            watchDeregister();
                        }
                    });
                } else {
                    $scope.record = {};
                    // setUpWatch();
                }
            }

            $timeout(doSetUp);

        }])
        .directive('fngUploadAdditFields', function () {
            return {
                link: function (scope, element, attrs) {
                    scope.uploadForm = scope.$parent.$parent.$parent;
                    scope.formScope = scope.uploadForm.formScope;
                    scope.schema = scope.uploadForm.directiveOptions.additFields;
                    scope.file = parseInt(attrs.file);
                },
                scope: {},
                controller: 'FngUploadAdditFieldsCtrl',
                template: '<form-input formstyle="inline" schema="schema" model="record" forceform="true"></form-input>'
            };
        })
        .controller('fngJqUploadCtrl', ['$scope', function ($scope) {
            $scope.loadingFiles = false;
            $scope.formScope = $scope.$parent;

            $scope.dataField = function (initialise) {
                var retVal;
                if ($scope.info.name.indexOf('.') === -1) {
                    retVal = $scope.formScope.record[$scope.info.name];
                    if (!retVal && initialise) {
                        retVal = $scope.formScope.record[$scope.info.name] = [];
                    }
                } else if ($scope.options.subschema) {
                    var modelBase = $scope.formScope.record;
                    var compoundName = $scope.info.name;
                    var root = $scope.options.subschemaroot;
                    var lastPart = compoundName.slice(root.length + 1);

                    retVal = modelBase;
                    var rootParts = root.split('.');
                    for (var i = 0, l = rootParts.length; i < l; i++) {
                        retVal = retVal[rootParts[i]];
                    }

                    var index = $scope.options.index;
                    if (index === undefined) {
                        index = $scope.$parent.$index;  // Works for use case where file obj sits in an array
                    }
                    if (index !== undefined) {
                        if (!retVal[index][lastPart]) {
                            retVal[index][lastPart] = [];
                        }
                        retVal = retVal[index][lastPart];
                    } else {
                        if ($scope.options.subkey) {
                            var arrayIndex = $scope.formScope['$_arrayOffset_' + root.replace(/\./g, '_') + '_' + $scope.options.subkeyno];
                            if (arrayIndex != null && arrayIndex !== undefined && arrayIndex !== -1) {
                                retVal = retVal[arrayIndex][lastPart];
                            } else {
                                retVal = undefined;
                            }
                        } else {
                            console.log('No support for this yet');
                            //modelString += '[$index].' + lastPart;
                            //idString = null;
                            //nameString = compoundName.replace(/\./g, '-');
                        }
                    }
                } else {
                    console.log('No support for this yet either');
                }
                return retVal;
            };

            function setUpAttachments() {
                var storedData = $scope.dataField();
                if (storedData) {
                    for (var i = 0; i < storedData.length; i++) {
                        var storedElement = storedData[i];
                        var storedName = storedElement.filename;
                        var queueElement = {
                            'name': storedName,
                            'size': storedElement.size,
                            'url': '/api/file/' + $scope.formScope.modelName + '/' + storedElement._id,
                            'deleteUrl': '/api/file/' + $scope.formScope.modelName + '/' + storedElement._id,
                            'deleteType': 'DELETE'
                        };
                        if (storedName) {
                            switch (storedName.slice(storedName.length - 4, storedName.length).toLowerCase()) {     // extension
                                case '.gif':
                                case '.png':
                                case '.jpg':
                                case 'jpeg':
                                    queueElement.thumbnailUrl = '/api/file/' + $scope.formScope.modelName + '/thumbnail/' + storedElement._id;
                                    break;
                                default:
                                    queueElement.thumbnailUrl = 'https://upload.wikimedia.org/wikipedia/commons/7/77/Icon_New_File_256x256.png';
                            }
                        } else {
                            queueElement.thumbnailUrl = 'https://upload.wikimedia.org/wikipedia/commons/7/77/Icon_New_File_256x256.png';
                        }
                        $scope.$$childHead.queue.push(queueElement);
                    }
                }
            }

            if (!$scope.formScope.newRecord) {
                var watchDeregister = $scope.formScope.$watch('phase', function (newVal) {
                    if (newVal === 'ready') {
                        $scope.$$childHead.queue = $scope.$$childHead.queue || [];
                        setUpAttachments();
                        $scope.$on('fngCancel', function () {
                            $scope.$$childHead.queue = [];
                            setUpAttachments();
                        });

                        watchDeregister();
                    }
                });
            }

            $scope.$on('fileuploaddone', function (event, data) {
                var field = $scope.dataField(true);
                var fileDetails = data.result.files[0];
                field.push(
                    {
                        _id: getIdFromUrl(fileDetails.url),
                        filename: fileDetails.name,
                        size: fileDetails.size
                    });
                $scope.ngModel.$setDirty();
            });

        }])
        .directive('fngJqUploadForm', ['pluginHelper', function (pluginHelper) {
            return {
                link: function (scope, element, attrs, ngModel) {
                    angular.extend(scope, pluginHelper.extractFromAttr(attrs, 'fngJqUploadForm'));
                    // Pick up options from the mongoose schema
                    scope.passedParams = scope.formScope[attrs.schema];
                    angular.extend(scope.options, scope.passedParams.fngJqUploadForm);
                    if (scope.options.additFields) {
                        scope.directiveOptions.additFields = JSON.parse(scope.options.additFields);
                    }
                    scope.directiveOptions.url = '/api/file/upload/' + scope.formScope.modelName;
                    scope.directiveOptions.sizeLimit = scope.directiveOptions.sizelimit;
                    scope.directiveOptions.autoUpload = scope.directiveOptions.autoupload;
                    scope.name = scope.passedParams.name;
                    scope.ngModel = ngModel;
                },
                restrict: 'E',
                require: '?ngModel',
                templateUrl: 'templates/fileform.html',
                scope: {},
                controller: 'fngJqUploadCtrl'
            };
        }])
        .controller('FileDestroyController', ['$scope', '$http', function ($scope, $http) {
            var file = $scope.file,
                state;

            $scope.uploadScope = $scope.$parent.$parent.$parent;

            var removeFromRecord = function (file) {
                var id = getIdFromUrl(file.url);
                var array = $scope.uploadScope.dataField();
                for (var i = array.length - 1; i >= 0; i--) {
                    if (array[i]._id === id) {
                        array.splice(i, 1);
                    }
                }
                $scope.clear(file);
                $scope.ngModel.$setDirty();
            };

            if (file.url) {
                file.$state = function () {
                    return state;
                };
                file.$destroy = function ($event) {
                    if (!$event.target.className.includes('ng-hide')) {
                        $scope.$parent.$parent.mouseIn = false;
                        state = 'pending';
                        return $http({
                            url: file.deleteUrl,
                            method: file.deleteType
                        }).then(
                            function () {
                                state = 'resolved';
                                removeFromRecord(file);
                            },
                            function () {
                                state = 'rejected';
                                removeFromRecord(file);
                            }
                        );
                    }
                };
            } else if (!file.$cancel && !file._index) {
                file.$cancel = function () {
                    removeFromRecord(file);
                };
            }
        }
        ]);
})();
<commit_msg>Fix regression in 845af40e9e463aa6d43e6b1152c0cfe2dffa3e40 which prevented delete in mutliple file fields.<commit_after>// TODO Check the filesize https://stackoverflow.com/questions/3717793/javascript-file-upload-size-validation
//  and suggest they resize if using an appropriate tool https://www.google.com/search?q=compress+photo+online+to+200kb
//  for example https://www.img2go.com/compress-image or https://www.imgonline.com.ua/eng/compress-image-size.php
//  or https://sqooush.app

(function () {
    'use strict';

    var app = angular.module('uploadModule', [
        'blueimp.fileupload'
    ]);

    var getIdFromUrl = function (url) {
        var breakdown = /\/file\/(.+?)\/([0-9a-f]{24})/.exec(url);
        return breakdown[2];
    };

    app
        .controller('FngUploadAdditFieldsCtrl', ['$scope', '$timeout', function ($scope, $timeout) {
            $scope.record = {};

            $scope.$watch('record', function (newVal, oldVal) {
                if (newVal !== oldVal) {
                    $scope.uploadForm.formScope[$scope.uploadForm.formScope.topLevelFormName].$setDirty();
                    angular.extend($scope.uploadForm.dataField()[$scope.file], newVal);
                }
            }, true);

            function setUpAdditFields() {
                if ($scope.schema) {
                    $scope.schema.forEach(function (field) {
                        var objVal = $scope.uploadForm.dataField()[$scope.file];
                        $scope.record[field.name] = objVal ? objVal[field.name] : undefined;
                    });
                }
            }

            function doSetUp() {
                if (!$scope.formScope.newRecord) {
                    var watchDeregister = $scope.formScope.$watch('phase', function (newVal) {
                        if (newVal === 'ready') {
                            setUpAdditFields();
                            $scope.$on('fngCancel', function () {
                                setUpAdditFields();
                            });
                            watchDeregister();
                        }
                    });
                } else {
                    $scope.record = {};
                    // setUpWatch();
                }
            }

            $timeout(doSetUp);

        }])
        .directive('fngUploadAdditFields', function () {
            return {
                link: function (scope, element, attrs) {
                    scope.uploadForm = scope.$parent.$parent.$parent;
                    scope.formScope = scope.uploadForm.formScope;
                    scope.schema = scope.uploadForm.directiveOptions.additFields;
                    scope.file = parseInt(attrs.file);
                },
                scope: {},
                controller: 'FngUploadAdditFieldsCtrl',
                template: '<form-input formstyle="inline" schema="schema" model="record" forceform="true"></form-input>'
            };
        })
        .controller('fngJqUploadCtrl', ['$scope', function ($scope) {
            $scope.loadingFiles = false;
            $scope.formScope = $scope.$parent;

            $scope.dataField = function (initialise) {
                var retVal;
                if ($scope.info.name.indexOf('.') === -1) {
                    retVal = $scope.formScope.record[$scope.info.name];
                    if (!retVal && initialise) {
                        retVal = $scope.formScope.record[$scope.info.name] = [];
                    }
                } else if ($scope.options.subschema) {
                    var modelBase = $scope.formScope.record;
                    var compoundName = $scope.info.name;
                    var root = $scope.options.subschemaroot;
                    var lastPart = compoundName.slice(root.length + 1);

                    retVal = modelBase;
                    var rootParts = root.split('.');
                    for (var i = 0, l = rootParts.length; i < l; i++) {
                        retVal = retVal[rootParts[i]];
                    }

                    var index = $scope.options.index;
                    if (index === undefined) {
                        index = $scope.$parent.$index;  // Works for use case where file obj sits in an array
                    }
                    if (index !== undefined) {
                        if (!retVal[index][lastPart]) {
                            retVal[index][lastPart] = [];
                        }
                        retVal = retVal[index][lastPart];
                    } else {
                        if ($scope.options.subkey) {
                            var arrayIndex = $scope.formScope['$_arrayOffset_' + root.replace(/\./g, '_') + '_' + $scope.options.subkeyno];
                            if (arrayIndex != null && arrayIndex !== undefined && arrayIndex !== -1) {
                                retVal = retVal[arrayIndex][lastPart];
                            } else {
                                retVal = undefined;
                            }
                        } else {
                            console.log('No support for this yet');
                            //modelString += '[$index].' + lastPart;
                            //idString = null;
                            //nameString = compoundName.replace(/\./g, '-');
                        }
                    }
                } else {
                    console.log('No support for this yet either');
                }
                return retVal;
            };

            function setUpAttachments() {
                var storedData = $scope.dataField();
                if (storedData) {
                    for (var i = 0; i < storedData.length; i++) {
                        var storedElement = storedData[i];
                        var storedName = storedElement.filename;
                        var queueElement = {
                            'name': storedName,
                            'size': storedElement.size,
                            'url': '/api/file/' + $scope.formScope.modelName + '/' + storedElement._id,
                            'deleteUrl': '/api/file/' + $scope.formScope.modelName + '/' + storedElement._id,
                            'deleteType': 'DELETE'
                        };
                        if (storedName) {
                            switch (storedName.slice(storedName.length - 4, storedName.length).toLowerCase()) {     // extension
                                case '.gif':
                                case '.png':
                                case '.jpg':
                                case 'jpeg':
                                    queueElement.thumbnailUrl = '/api/file/' + $scope.formScope.modelName + '/thumbnail/' + storedElement._id;
                                    break;
                                default:
                                    queueElement.thumbnailUrl = 'https://upload.wikimedia.org/wikipedia/commons/7/77/Icon_New_File_256x256.png';
                            }
                        } else {
                            queueElement.thumbnailUrl = 'https://upload.wikimedia.org/wikipedia/commons/7/77/Icon_New_File_256x256.png';
                        }
                        $scope.$$childHead.queue.push(queueElement);
                    }
                }
            }

            if (!$scope.formScope.newRecord) {
                var watchDeregister = $scope.formScope.$watch('phase', function (newVal) {
                    if (newVal === 'ready') {
                        $scope.$$childHead.queue = $scope.$$childHead.queue || [];
                        setUpAttachments();
                        $scope.$on('fngCancel', function () {
                            $scope.$$childHead.queue = [];
                            setUpAttachments();
                        });

                        watchDeregister();
                    }
                });
            }

            $scope.$on('fileuploaddone', function (event, data) {
                var field = $scope.dataField(true);
                var fileDetails = data.result.files[0];
                field.push(
                    {
                        _id: getIdFromUrl(fileDetails.url),
                        filename: fileDetails.name,
                        size: fileDetails.size
                    });
                $scope.ngModel.$setDirty();
            });

        }])
        .directive('fngJqUploadForm', ['pluginHelper', function (pluginHelper) {
            return {
                link: function (scope, element, attrs, ngModel) {
                    angular.extend(scope, pluginHelper.extractFromAttr(attrs, 'fngJqUploadForm'));
                    // Pick up options from the mongoose schema
                    scope.passedParams = scope.formScope[attrs.schema];
                    angular.extend(scope.options, scope.passedParams.fngJqUploadForm);
                    if (scope.options.additFields) {
                        scope.directiveOptions.additFields = JSON.parse(scope.options.additFields);
                    }
                    scope.directiveOptions.url = '/api/file/upload/' + scope.formScope.modelName;
                    scope.directiveOptions.sizeLimit = scope.directiveOptions.sizelimit;
                    scope.directiveOptions.autoUpload = scope.directiveOptions.autoupload;
                    scope.name = scope.passedParams.name;
                    scope.ngModel = ngModel;
                },
                restrict: 'E',
                require: '?ngModel',
                templateUrl: 'templates/fileform.html',
                scope: {},
                controller: 'fngJqUploadCtrl'
            };
        }])
        .controller('FileDestroyController', ['$scope', '$http', function ($scope, $http) {
            var file = $scope.file,
                state;

            $scope.uploadScope = $scope.$parent.$parent.$parent;

            var removeFromRecord = function (file) {
                var id = getIdFromUrl(file.url);
                var array = $scope.uploadScope.dataField();
                for (var i = array.length - 1; i >= 0; i--) {
                    if (array[i]._id === id) {
                        array.splice(i, 1);
                    }
                }
                $scope.clear(file);
                $scope.ngModel.$setDirty();
            };

            if (file.url) {
                file.$state = function () {
                    return state;
                };
                file.$destroy = function ($event) {
                    if (!$event || !$event.target.className.includes('ng-hide')) {
                        $scope.$parent.$parent.mouseIn = false;
                        state = 'pending';
                        return $http({
                            url: file.deleteUrl,
                            method: file.deleteType
                        }).then(
                            function () {
                                state = 'resolved';
                                removeFromRecord(file);
                            },
                            function () {
                                state = 'rejected';
                                removeFromRecord(file);
                            }
                        );
                    }
                };
            } else if (!file.$cancel && !file._index) {
                file.$cancel = function () {
                    removeFromRecord(file);
                };
            }
        }
        ]);
})();
<|endoftext|>


<commit_before>class Template {
  constructor (selector) {
    return Object.assign (
      this.factory (selector),
      { bind: this.bind }
    )
  }

  factory (selector) {
    return (
      document.querySelector (selector)
        || document.createElement ('template')
    ).cloneNode (true)
  }

  bind (state) {
    let html   = window.template = this.innerHTML
    let render = context => tag (html) (context)

    let tags = Array.isArray (state)
      ?  state.map (render)
      : [render (state)]

    this.innerHTML = tags.join ('')

    return this
  }
}

let record = { name: 'That Beast' }
var collection = [
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
]
console.group ('template')
console.time ('bind time')
window.template = new Template ('#items')

document.
  body.appendChild
  (
    (new Template ('#items'))
      .bind(record)
      .content
  )

let items = new Template ('#item')

items
  .bind (collection)

let ul = document.querySelector ('ul')

ul.appendChild (items.content)

console.timeEnd ('bind time')
console.groupEnd ('template')

console.group ('appendChild')
console.time ('append time')
for (let context of collection) {
  let li = document.createElement ('li')
  ul.appendChild (li)
  li.outerHTML = `<li style='background:red'>Hello ${context.name}!</li>`
}
console.timeEnd ('append time')
console.groupEnd ('appendChild')
<commit_msg>Refactor tags ternary operand<commit_after>class Template {
  constructor (selector) {
    return Object.assign (
      this.factory (selector),
      { bind: this.bind }
    )
  }

  factory (selector) {
    return (
      document.querySelector (selector)
        || document.createElement ('template')
    ).cloneNode (true)
  }

  bind (state) {
    let html   = window.template = this.innerHTML
      , render = context => tag (html) (context)

      , tags = Array.isArray (state)
          ?  state.map (render)
          : [render (state)]

    this.innerHTML = tags.join ('')

    return this
  }
}

let record = { name: 'That Beast' }
var collection = [
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
{name: 'foo'}, {name: 'bar'},
]
console.group ('template')
console.time ('bind time')
window.template = new Template ('#items')

document.
  body.appendChild
  (
    (new Template ('#items'))
      .bind(record)
      .content
  )

let items = new Template ('#item')

items
  .bind (collection)

let ul = document.querySelector ('ul')

ul.appendChild (items.content)

console.timeEnd ('bind time')
console.groupEnd ('template')

console.group ('appendChild')
console.time ('append time')
for (let context of collection) {
  let li = document.createElement ('li')
  ul.appendChild (li)
  li.outerHTML = `<li style='background:red'>Hello ${context.name}!</li>`
}
console.timeEnd ('append time')
console.groupEnd ('appendChild')
<|endoftext|>


<commit_before>import { injectGlobal } from 'styled-components';

/* eslint no-unused-expressions: 0 */
injectGlobal`
  html,
  body,
  #app {
    height: 100%;
    width: 100%;
    background-color: #4a4a4a;
  }

  body {
    font-family: 'Raleway', sans-serif;
    font-weight: bold;
  }

  h1,
  h1 {
    font-family: 'Lobster', cursive;
  }

  .cc-window {
    font-family: 'Raleway', sans-serif !important;
  }

  .cc-compliance a,
  .cc-compliance a:link,
  .cc-compliance a:visited,
  .cc-compliance a:hover,
  .cc-compliance a:active {
    transition: color 0.25s ease-in-out;
    cursor: pointer;
    color: #78c8b4;
    background-color: #95a3b3 !important;
  }

  .cc-link,
  .cc-link:link,
  .cc-link:visited {
    transition: color 0.25s ease-in-out;
    cursor: pointer;
    color: #95a3b3 !important;
  }

  .cc-link:hover,
  .cc-link:active {
    color: #78c8b4 !important;
  }
`;
<commit_msg>changing color of consent cookie button<commit_after>import { injectGlobal } from 'styled-components';

/* eslint no-unused-expressions: 0 */
injectGlobal`
  html,
  body,
  #app {
    height: 100%;
    width: 100%;
    background-color: #4a4a4a;
  }

  body {
    font-family: 'Raleway', sans-serif;
    font-weight: bold;
  }

  h1,
  h1 {
    font-family: 'Lobster', cursive;
  }

  .cc-window {
    font-family: 'Raleway', sans-serif !important;
  }

  .cc-compliance a,
  .cc-compliance a:link,
  .cc-compliance a:visited {
    transition: background-color 0.25s ease-in-out;
    color: #d3d3d3;
  }
  .cc-compliance a:hover,
  .cc-compliance a:active {
    cursor: pointer;
    background-color: #78c8b4 !important;
  }

  .cc-link,
  .cc-link:link,
  .cc-link:visited {
    transition: color 0.25s ease-in-out;
    cursor: pointer;
    color: #95a3b3 !important;
  }

  .cc-link:hover,
  .cc-link:active {
    color: #78c8b4 !important;
  }
`;
<|endoftext|>