<commit_before>function (user, context, callback) {
  // AAI (AUTHENTICATOR ASSURANCE INDICATOR)
  // Sets the AAI for the user. This is later used by the AccessRules.js rule for example

  user.aai = [];
  if ((context.connection === 'github') && (user.two_factor_authentication === true)) {
    Array.prototype.push.apply(user.aai, ["2FA"]);
  } else if ((context.connection === 'firefoxaccounts') && (user.fxa_twoFactorAuthentication === true)) {
    Array.prototype.push.apply(user.aai, ["2FA"]);
  } else if ((context.connectionStrategy === 'ad') && (user.multifactor[0] === "duo")) {
    Array.prototype.push.apply(user.aai, ["2FA"]);
  } else if (context.connection === 'google-oauth2') {
    // We set Google to HIGH_ASSURANCE_IDP which is a special indicator, this is what it represents:
    // - has fraud detection
    // - will inform users when their account is used or logged through push notifications on their devices
    // - will actively block detected fraudulous logins even with correct credentials
    // - will fallback to phone 2FA in most cases (old accounts may still bypass that in some cases)
    // - will fallback to phone 2FA on all recent accounts
    // Note that this is not the same as "2FA" and other indicators, as we simply do not have a technically accurate
    // indicator of what the authenticator supports at this time for Google accounts
    Array.prototype.push.apply(user.aai, ["HIGH_ASSURANCE_IDP"]);
  } else {
    // Ensure all users have some AAI attribute, even if its empty
    user.aai = user.aai || [];
  }
  callback(null, user, context);
}
<commit_msg>if the multifactor context is set, it means the user will be required to duo-authenticate next if the multifactor user attribute is set, it means the user *has* authenticate with duo.<commit_after>function (user, context, callback) {
  // AAI (AUTHENTICATOR ASSURANCE INDICATOR)
  // Sets the AAI for the user. This is later used by the AccessRules.js rule for example

  user.aai = [];
  if ((context.connection === 'github') && (user.two_factor_authentication === true)) {
    Array.prototype.push.apply(user.aai, ["2FA"]);
  } else if ((context.connection === 'firefoxaccounts') && (user.fxa_twoFactorAuthentication === true)) {
    Array.prototype.push.apply(user.aai, ["2FA"]);
  } else if ((context.connectionStrategy === 'ad') && (context.multifactor || user.multifactor[0] === "duo")) {
    Array.prototype.push.apply(user.aai, ["2FA"]);
  } else if (context.connection === 'google-oauth2') {
    // We set Google to HIGH_ASSURANCE_IDP which is a special indicator, this is what it represents:
    // - has fraud detection
    // - will inform users when their account is used or logged through push notifications on their devices
    // - will actively block detected fraudulous logins even with correct credentials
    // - will fallback to phone 2FA in most cases (old accounts may still bypass that in some cases)
    // - will fallback to phone 2FA on all recent accounts
    // Note that this is not the same as "2FA" and other indicators, as we simply do not have a technically accurate
    // indicator of what the authenticator supports at this time for Google accounts
    Array.prototype.push.apply(user.aai, ["HIGH_ASSURANCE_IDP"]);
  } else {
    // Ensure all users have some AAI attribute, even if its empty
    user.aai = user.aai || [];
  }
  callback(null, user, context);
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
/**
 * Created by Kanthanarasimhaiah on 14/11/13.
 */

var binarytree = require('./binarytree'),
    rbt = require('./rbt.js');

// Run CFS algorithm
function runCFS(tasks, timeline) {
    // queue of tasks sorted in start_time order
    var time_queue = tasks.task_queue;
    // index into time_queue of the next nearest task to start
    var time_queue_idx = 0;

    // min_vruntime is set to the smallest vruntime of tasks on the
    // timeline
    var min_vruntime = 0;

    // current running task or null if no tasks are running.
    var running_task = null;

    // Initialize statistics gathering
    var results = {time_data: []};
    var start_ms = new Date().getTime();
    binarytree.RESET_STATS();

    // Loop from time/tick 0 through the total time/ticks specified
    for(var curTime=0; curTime < tasks.total_time; curTime++) {

        // Results data for this time unit/tick
        var tresults = {running_task: null,
                        completed_task: null};

        // Check tasks at the beginning of the task queue. Add any to
        // the timeline structure when the start_time for those tasks
        // has arrived.
        while (time_queue_idx < time_queue.length &&
               (curTime >= time_queue[time_queue_idx].start_time)) {
            var new_task = time_queue[time_queue_idx++];
            // new tasks get their vruntime set to the current
            // min_vruntime
            new_task.vruntime = min_vruntime;
            new_task.truntime = 0;
            new_task.actual_start_time = curTime;
            timeline.insert(new_task);
        }

        // If there is a task running and its vruntime exceeds
        // min_vruntime then add it back to the timeline. Since
        // vruntime is greater it won't change min_vruntime when it's
        // added back to the timeline.
        if (running_task && (running_task.vruntime > min_vruntime)) {
            timeline.insert(running_task);
            running_task = null;
        }

        // If there is no running task (which may happen right after
        // the running_task is added back to the timeline above), find
        // the task with the smallest vruntime on the timeline, remove
        // it and set it as the running_task and determine the new
        // min_vruntime.
        if (!running_task && timeline.size() > 0) {
            var min_node = timeline.min();
            running_task = min_node.val;
            timeline.remove(min_node);
            if (timeline.size() > 0) {
                min_vruntime = timeline.min().val.vruntime
            }
        }

        tresults.num_tasks = timeline.size() + (running_task ? 1 : 0);

        // Update the running_task (if any) by increasing the vruntime
        // and the truntime. If the running task has run for it's full
        // duration then report it as completed and set running_task
        // to null.
        if (running_task) {
            running_task.vruntime++;
            running_task.truntime++;
            tresults.running_task = running_task;
            //console.log(curTime + ": " + running_task.id);
            if (running_task.truntime >= running_task.duration) {
                running_task.completed_time = curTime;
                tresults.completed_task = running_task
                running_task = null;
                //console.log("Completed task:", running_task.id);
            }
        }

        results.time_data[curTime] = tresults;
    }

    //binarytree.RESET_STATS();
    results.node_stats = binarytree.GET_STATS();
    results.elapsed_ms = (new Date().getTime())-start_ms;

    return results;
}

function generate_report(tasks, results, detailed) {
    var reads = 0, writes = 0, total = 0, completed = 0;

    // General info on the original tasks
    console.log("Numer of Tasks:", tasks.num_of_tasks);
    console.log("Total Time:", tasks.total_time);

    if (detailed) {
        console.log("Task Queue:");
        console.log(tasks.task_queue);
    }

    // A chronological summary of the state at each time
    if (detailed) {
        console.log("\ntime [tasks]: running_task, completed?");
        for (var i=0; i < results.time_data.length; i++) {
            var t = results.time_data[i],
                msg = "  " + i + " [" + t.num_tasks + "]: ";
            if (t.running_task) {
                msg += t.running_task.id;
            }
            if (t.completed_task) {
                msg += ", Completed";
                completed++;
            }
            console.log(msg);
        }
    }

    // Sum all the reads and writes
    for (var r in results.node_stats.read) {
        reads += results.node_stats.read[r];
    }
    for (var r in results.node_stats.write) {
        writes += results.node_stats.write[r];
    }
    total = reads+writes;

    // Report summary statistics
    console.log("Wallclock elapsed time: " + results.elapsed_ms + "ms")
    console.log("Node operations reads  : " + reads);
    console.log("                writes : " + writes);
    console.log("                total  : " + total);
    console.log("Throughput:", (completed/results.elapsed_ms), "completed tasks/ms");
    console.log("           ", (completed/total), "completed tasks/operation");
    //console.log("Tasks per tick:", tasks_per_tick);
}

if (require.main === module) {
    // we are being run directly so load the task file specified on
    // the command line pass the data to runCFS using an RedBlackTree
    // for the timeline
    if (process.argv.length < 3) {
        console.log("cfs TASK_FILE");
        process.exit(2);
    }

    var tasksModule = require('./tasks');
    var fileName = process.argv[2];
    var tasks = tasksModule.readTasks(fileName);

    var timeline = new rbt.RBT(function (a, b) {
            return a.val.vruntime - b.val.vruntime; });

    // Run the CFS algorithm and generate a results report
    var results = runCFS(tasks, timeline);
    generate_report(tasks, results);

} else {
    // we are being required as a module so export the runCFS function
    exports.runCFS = runCFS;
}

<commit_msg>Fix non-detailed reporting.<commit_after>#!/usr/bin/env node
/**
 * Created by Kanthanarasimhaiah on 14/11/13.
 */

var binarytree = require('./binarytree'),
    rbt = require('./rbt.js');

// Run CFS algorithm
function runCFS(tasks, timeline) {
    // queue of tasks sorted in start_time order
    var time_queue = tasks.task_queue;
    // index into time_queue of the next nearest task to start
    var time_queue_idx = 0;

    // min_vruntime is set to the smallest vruntime of tasks on the
    // timeline
    var min_vruntime = 0;

    // current running task or null if no tasks are running.
    var running_task = null;

    // Initialize statistics gathering
    var results = {time_data: []};
    var start_ms = new Date().getTime();
    binarytree.RESET_STATS();

    // Loop from time/tick 0 through the total time/ticks specified
    for(var curTime=0; curTime < tasks.total_time; curTime++) {

        // Results data for this time unit/tick
        var tresults = {running_task: null,
                        completed_task: null};

        // Check tasks at the beginning of the task queue. Add any to
        // the timeline structure when the start_time for those tasks
        // has arrived.
        while (time_queue_idx < time_queue.length &&
               (curTime >= time_queue[time_queue_idx].start_time)) {
            var new_task = time_queue[time_queue_idx++];
            // new tasks get their vruntime set to the current
            // min_vruntime
            new_task.vruntime = min_vruntime;
            new_task.truntime = 0;
            new_task.actual_start_time = curTime;
            timeline.insert(new_task);
        }

        // If there is a task running and its vruntime exceeds
        // min_vruntime then add it back to the timeline. Since
        // vruntime is greater it won't change min_vruntime when it's
        // added back to the timeline.
        if (running_task && (running_task.vruntime > min_vruntime)) {
            timeline.insert(running_task);
            running_task = null;
        }

        // If there is no running task (which may happen right after
        // the running_task is added back to the timeline above), find
        // the task with the smallest vruntime on the timeline, remove
        // it and set it as the running_task and determine the new
        // min_vruntime.
        if (!running_task && timeline.size() > 0) {
            var min_node = timeline.min();
            running_task = min_node.val;
            timeline.remove(min_node);
            if (timeline.size() > 0) {
                min_vruntime = timeline.min().val.vruntime
            }
        }

        tresults.num_tasks = timeline.size() + (running_task ? 1 : 0);

        // Update the running_task (if any) by increasing the vruntime
        // and the truntime. If the running task has run for it's full
        // duration then report it as completed and set running_task
        // to null.
        if (running_task) {
            running_task.vruntime++;
            running_task.truntime++;
            tresults.running_task = running_task;
            //console.log(curTime + ": " + running_task.id);
            if (running_task.truntime >= running_task.duration) {
                running_task.completed_time = curTime;
                tresults.completed_task = running_task
                running_task = null;
                //console.log("Completed task:", running_task.id);
            }
        }

        results.time_data[curTime] = tresults;
    }

    //binarytree.RESET_STATS();
    results.node_stats = binarytree.GET_STATS();
    results.elapsed_ms = (new Date().getTime())-start_ms;

    return results;
}

function generate_report(tasks, results, detailed) {
    var reads = 0, writes = 0, total = 0, completed = 0;

    // General info on the original tasks
    if (detailed) {
        console.log("Task Queue:");
        console.log(tasks.task_queue);
    }

    // A chronological summary of the state at each time
    if (detailed) {
        console.log("\ntime [tasks]: running_task, completed?");
    }
    for (var i=0; i < results.time_data.length; i++) {
        var t = results.time_data[i],
            msg = "  " + i + " [" + t.num_tasks + "]: ";
        if (t.running_task) {
            msg += t.running_task.id;
        }
        if (t.completed_task) {
            msg += ", Completed";
            completed++;
        }
        if (detailed) {
            console.log(msg);
        }
    }

    // Sum all the reads and writes
    for (var r in results.node_stats.read) {
        reads += results.node_stats.read[r];
    }
    for (var r in results.node_stats.write) {
        writes += results.node_stats.write[r];
    }
    total = reads+writes;

    // Report summary statistics
    console.log("Total Tasks:", tasks.num_of_tasks);
    console.log("Completed Tasks:", completed);
    console.log("Total Time:", tasks.total_time);

    console.log("Wallclock elapsed time: " + results.elapsed_ms + "ms");
    console.log("Node operations reads  : " + reads);
    console.log("                writes : " + writes);
    console.log("                total  : " + total);
    console.log("Throughput:", (completed/results.elapsed_ms), "completed tasks/ms");
    console.log("           ", (completed/total), "completed tasks/operation");
    //console.log("Tasks per tick:", tasks_per_tick);
}

if (require.main === module) {
    // we are being run directly so load the task file specified on
    // the command line pass the data to runCFS using an RedBlackTree
    // for the timeline
    if (process.argv.length < 3) {
        console.log("cfs TASK_FILE");
        process.exit(2);
    }

    var tasksModule = require('./tasks');
    var fileName = process.argv[2];
    var tasks = tasksModule.readTasks(fileName);

    var timeline = new rbt.RBT(function (a, b) {
            return a.val.vruntime - b.val.vruntime; });

    // Run the CFS algorithm and generate a results report
    var results = runCFS(tasks, timeline);
    //generate_report(tasks, results, true);
    generate_report(tasks, results);

} else {
    // we are being required as a module so export the runCFS function
    exports.runCFS = runCFS;
}

<|endoftext|>


<commit_before>var fs               = require('fs'),
    util             = require('util'),
    utils            = require('./utils'),
    events           = require('events'),
    moment           = require('moment'),
    Playlist         = require('./api/Playlist'),
    Melted           = require('./api/Melted'),
    Media            = require('./api/Media'),
    ScheduledMedia   = require('./api/ScheduledMedia');

function scheduler( config ) {

    var self = this;

    self.mosto = config.mosto;
    self.fetcher = undefined;
    self.player = undefined;

    self.scheduled_clips = []; //here we must have the current playlist up to date...
    self.scheduled_clips_updated = false;

    scheduler.prototype.init = function() {

        self.fetcher = self.mosto.fetcher;
        if (self.fetcher) self.fetcher.on( 'fetch_downstream', self.convertPlaylistsToScheduledClips );

        self.synchronizer = self.mosto.synchronizer;
        if (self.synchronizer) self.synchronizer.on( 'sched_upstream', function() {
            console.log('mbc-mosto: [INFO] [SCHED] receiving sched_upstream event');
            self.upstreamCheck();
        });

        self.player = self.mosto.player;

    }

    scheduler.prototype.queueBlack = function( schedule_time, sch_duration, sch_expect_start, sch_expect_end ) {
        //Media(id, orig_order, actual_order, playlist_id, name, type, file, length, fps)
        var BlackMedia = new Media( 'black_id' /*id*/, '0' /*orig_order*/, '0'/*actual_order*/, '0' /*playlist_id*/, 'black' /*name*/, 'file' /*type*/, self.mosto.config.black, sch_duration/*length*/, ''/*fps*/ );
        console.log("mbc-mosto: [INFO] [SCHED] queueBlack > media:" + BlackMedia.file + " schedule_time:" + schedule_time + " sch_duration:" + sch_duration + " sch_expect_start:" + sch_expect_start + " sch_expect_end:" + sch_expect_end + " fps?:"+BlackMedia.fps );
        self.scheduled_clips.push( new ScheduledMedia( BlackMedia, schedule_time, sch_duration, sch_expect_start, sch_expect_end ) );

    }

    scheduler.prototype.upstreamCheck = function() {
        //Check if we need to make a checkout! (upstream syncro!! > sync_lock must be true )

        //UPSTREAM

            //if time_window advance for 1 hours (4 hours > 3 hours left ), we make a checkout...[FETCH]
            var rt_actual_window = self.fetcher.time_window_to.diff( moment() );
            var rt_min_window = moment.duration( { hours: 3 } ).asMilliseconds();

            console.log("mbc-mosto: [INFO] [SCHED] upstreamCheck > rt_actual_window:" + rt_actual_window + " rt_min_window:" + rt_min_window );
            console.log("mbc-mosto: [INFO] [SCHED] upstreamCheck > scheduled_clips:" + self.scheduled_clips.length );
            if (  rt_actual_window < rt_min_window || self.scheduled_clips.length==0 ) {
                //console.log("mbc-mosto: [INFO] [SCHED] window advanced at least one hour... calling [FETCH] checkoutPlaylists actual:" + rt_actual_window + " min:" + rt_min_window);
                //return  self.fetcher.checkoutPlaylists();//really updates time window too
                console.log("mbc-mosto: [INFO] [SCHED] emitting fetch_upstream");
                self.emit('fetch_upstream');
            } else {
                console.log("mbc-mosto: [INFO] [SCHED] timer unlock from upstreamCheck. No need to fetch upstream");
                self.player.timerUnlock();
            }

    }

    /** LOGIC SCHEDULER MODULE */
    //TODO: testing moment.js, converting time, test recursion

    /** convertPlaylistsToScheduledClips
     *
     * here we make all the necesarry calculations and update the current playlist
     * maybe create some warning messages
     * check coherence in scheduled playlists
     * add playlist_attribute= {} in Playlist.js
     *
     * case 0: no playlist available
     *       see modes: snap | fixed
     * case 1: next playlist is overlapped
     *       see modes: snap | fixed
     * case 2: next playlist start more than xx seconds after this one
     *       see modes: snap | fixed
     *
     *       We use a recursive function preparePlaylist
     */
    scheduler.prototype.convertPlaylistsToScheduledClips = function( playlists ) {

        console.log("mbc-mosto: [INFO] [SCHED] converting Playlists to scheduled clips : " + playlists );

        self.emit('converting', '[SCHED] Scheduler start' );

        //clean scheduled clips
        //if ( playlists_updated ) {
        self.scheduled_clips = [];
        if ( playlists.length>0 ) {
            console.log("mbc-mosto: [INFO] [SCHED] actually converting playlists ("+playlists.length+").");
            self.preparePlaylist( playlists, 0, -1 );
        }
        //playlists_updated = false;
        //}

        self.emit('converted', '[SCHED] Scheduler end' );

        //TODO: try to syncro immediatelly
        //or wait for timer synchronization
        console.log("mbc-mosto: [INFO] [SCHED] emitting sync_downstream");
        self.emit('sync_downstream', self.scheduled_clips );

    }

    /** preparePlaylist
     *       recursive convert for convertPlaylistsToScheduledClips
     *
     *       @see convertPlaylistsToScheduledClips
     */
    scheduler.prototype.preparePlaylist = function( playlists, next_playlist_id, lastTimeCode ) {

        var pl = playlists[next_playlist_id];
        var milis,sch_duration_m;
        var sch_duration, sch_time, sch_expect_start, sch_expect_end, schedule_time;
        var i = 0,is = 0;
        var pl_tc, last_tc, diff = 0;

        /*
          if (!self.validatePlaylist(pl)) {
          console.log("mbc-mosto: [ERROR] in preparePlaylist: " + pl.name );
          }
        */
        if (pl==undefined) return;

        pl_tc = moment( pl.startDate );

        if  ( lastTimeCode!=-1 ) {
            last_tc = moment( lastTimeCode,"DD/MM/YYYY HH:mm:ss.SSS");
            diff = last_tc.diff( pl_tc );
        } else last_tc = pl_tc;

        console.log("mbc-mosto: [INFO] [SCHED] preparePlaylist() : next_playlist_id : " + next_playlist_id + " startDate:" + pl_tc.format("DD/MM/YYYY HH:mm:ss") + " lastTimeCode:" +  lastTimeCode + " diff:" + diff );

        if ( lastTimeCode==-1
             || diff < 10000
           ) {

            if ( pl.mode == "snap") {
                // just add all clips with schedule: "now" if diff is less than 10 seconds, else push with own timecode (sch_time = sch_expect_start
                is = 0;
                sch_expect_end = moment( pl_tc, "DD/MM/YYYY HH:mm:ss").format("DD/MM/YYYY HH:mm:ss.SSS");
                for( i=0; i<pl.medias.length; i++) {
                    var sMedia = pl.medias[i];
                    milis = utils.convertFramesToMilliseconds( sMedia.length, sMedia.fps );
                    sch_duration_m = moment.duration( { milliseconds: milis } );

                    sch_time = moment( sch_expect_end, "DD/MM/YYYY HH:mm:ss.SSS").format("DD/MM/YYYY HH:mm:ss.SSS");
                    sch_duration = sch_duration_m.hours() + ":" + sch_duration_m.minutes() + ":" + sch_duration_m.seconds() + "." + sch_duration_m.milliseconds();
                    sch_expect_start = sch_time;
                    sch_expect_end = moment( sch_time ,"DD/MM/YYYY HH:mm:ss.SSS").add( sch_duration_m ).format("DD/MM/YYYY HH:mm:ss.SSS");

                    diff = last_tc.diff( moment( sch_time, "DD/MM/YYYY HH:mm:ss.SSS") );

                    //choose if queue or schedule...
                    if ( (i==0 && Math.abs(diff)<10000 && next_playlist_id>0 ) // first clip of queued playlists if diff <  10 seconds are queued
                         ||
                         ( i>0 && Math.abs(diff)<10000)  ) //clips >0 => all queued clips after first one
                        {
                            schedule_time = "now";
                        } else if (
                            (next_playlist_id==0 && i==0) // first playlist we have, it always need a schedule time
                                ||
                                (Math.abs(diff)>10000) ) // if diff > 10 seconds > use schedule time... (maybe a warning)
                        {
                            //check if we have unclosed playlists (without black end clip) before this new one...
                            var black_duration, black_duration_str;

                            if (next_playlist_id>0) {
                                black_duration = moment.duration({ milliseconds: Math.abs(diff) });
                                black_duration_str = utils.convertDurationToString(black_duration);
                                self.queueBlack( "now", black_duration_str, lastTimeCode, moment( lastTimeCode,"DD/MM/YYYY HH:mm:ss.SSS").add(black_duration).format('DD/MM/YYYY HH:mm:ss.SSS') );
                            } else if (next_playlist_id==0) {
                                //if this is the first and only playlist, check if an empty void is left before it...., so we can put our blackmedia...
                                var tnow = moment();
                                if (self.player) tnow = self.player.timer_clock;
                                if (self.player && !self.player.timer_clock) tnow = self.player.timer_clock = moment();
                                var sch_time_mom = moment(sch_time, "DD/MM/YYYY HH:mm:ss.SSS");
                                var sch_rightnow = moment(tnow).format("DD/MM/YYYY HH:mm:ss.SSS");
                                var diff_void_start = sch_time_mom.diff( tnow );
                                black_duration = moment.duration( sch_time_mom - tnow );
                                black_duration_str = utils.convertDurationToString(black_duration);
                                var sch_to_next_playlist = moment( sch_rightnow,"DD/MM/YYYY HH:mm:ss.SSS").add(black_duration).format('DD/MM/YYYY HH:mm:ss.SSS');
                                console.log("mbc-mosto: [INFO] [SCHED] preparePlaylist > empty space ? diff_void_start :" + diff_void_start );

                                if (diff_void_start>0) {
                                    self.queueBlack( sch_rightnow, black_duration_str, sch_rightnow, sch_to_next_playlist );
                                    sch_time = "now";
                                }

                            }

                            schedule_time = sch_time;
                        }
                    console.log("mbc-mosto: [INFO] [SCHED] adding scheduled clip: sched_time:" + schedule_time + " media.id:" + sMedia.id + " file:" + sMedia.file + " start:"+sch_expect_start+" end:"+sch_expect_end + " milis:" + milis );
                    self.scheduled_clips.push( new ScheduledMedia( sMedia, schedule_time, sch_duration, sch_expect_start, sch_expect_end ) );
                    lastTimeCode = sch_expect_end;
                    last_tc = moment( lastTimeCode,"DD/MM/YYYY HH:mm:ss.SSS");
                }

            } else if ( pl.mode == "fixed") {
                //just add these clips replacing and cutting others!!
            }
        }

        next_playlist_id++;

        //iteration ended because we have no more playlists !
        if ( playlists.length==next_playlist_id) {
            if (next_playlist_id > 0 && lastTimeCode!=-1 && pl.id!="black_id") {
                var black_duration, black_duration_str;
                black_duration = moment.duration( self.fetcher.time_window_to - last_tc );
                black_duration_str = utils.convertDurationToString(black_duration);
                //queue blackness to the end of the last playlist (no after a black media!) till last frame window
                self.queueBlack( "now", black_duration_str, lastTimeCode, moment( lastTimeCode,"DD/MM/YYYY HH:mm:ss.SSS").add(black_duration).format('DD/MM/YYYY HH:mm:ss.SSS') );
            }
            return;
        }

        return self.preparePlaylist( playlists, next_playlist_id, lastTimeCode );
    }

};

exports = module.exports = function(config) {
    util.inherits(scheduler, events.EventEmitter);
    var mosto_scheduler = new scheduler(config);
    return mosto_scheduler;
};

<commit_msg>Always fetch upstream: must optimize this.<commit_after>var fs               = require('fs'),
    util             = require('util'),
    utils            = require('./utils'),
    events           = require('events'),
    moment           = require('moment'),
    Playlist         = require('./api/Playlist'),
    Melted           = require('./api/Melted'),
    Media            = require('./api/Media'),
    ScheduledMedia   = require('./api/ScheduledMedia');

function scheduler( config ) {

    var self = this;

    self.mosto = config.mosto;
    self.fetcher = undefined;
    self.player = undefined;

    self.scheduled_clips = []; //here we must have the current playlist up to date...
    self.scheduled_clips_updated = false;

    scheduler.prototype.init = function() {

        self.fetcher = self.mosto.fetcher;
        if (self.fetcher) self.fetcher.on( 'fetch_downstream', self.convertPlaylistsToScheduledClips );

        self.synchronizer = self.mosto.synchronizer;
        if (self.synchronizer) self.synchronizer.on( 'sched_upstream', function() {
            console.log('mbc-mosto: [INFO] [SCHED] receiving sched_upstream event');
            self.upstreamCheck();
        });

        self.player = self.mosto.player;

    }

    scheduler.prototype.queueBlack = function( schedule_time, sch_duration, sch_expect_start, sch_expect_end ) {
        //Media(id, orig_order, actual_order, playlist_id, name, type, file, length, fps)
        var BlackMedia = new Media( 'black_id' /*id*/, '0' /*orig_order*/, '0'/*actual_order*/, '0' /*playlist_id*/, 'black' /*name*/, 'file' /*type*/, self.mosto.config.black, sch_duration/*length*/, ''/*fps*/ );
        console.log("mbc-mosto: [INFO] [SCHED] queueBlack > media:" + BlackMedia.file + " schedule_time:" + schedule_time + " sch_duration:" + sch_duration + " sch_expect_start:" + sch_expect_start + " sch_expect_end:" + sch_expect_end + " fps?:"+BlackMedia.fps );
        self.scheduled_clips.push( new ScheduledMedia( BlackMedia, schedule_time, sch_duration, sch_expect_start, sch_expect_end ) );

    }

    scheduler.prototype.upstreamCheck = function() {
        //Check if we need to make a checkout! (upstream syncro!! > sync_lock must be true )

        //UPSTREAM

            //if time_window advance for 1 hours (4 hours > 3 hours left ), we make a checkout...[FETCH]
            var rt_actual_window = self.fetcher.time_window_to.diff( moment() );
            var rt_min_window = moment.duration( { hours: 3 } ).asMilliseconds();

            console.log("mbc-mosto: [INFO] [SCHED] upstreamCheck > rt_actual_window:" + rt_actual_window + " rt_min_window:" + rt_min_window );
            console.log("mbc-mosto: [INFO] [SCHED] upstreamCheck > scheduled_clips:" + self.scheduled_clips.length );
            if (  rt_actual_window < rt_min_window || self.scheduled_clips.length==0 ) {
                //console.log("mbc-mosto: [INFO] [SCHED] window advanced at least one hour... calling [FETCH] checkoutPlaylists actual:" + rt_actual_window + " min:" + rt_min_window);
                //return  self.fetcher.checkoutPlaylists();//really updates time window too
                console.log("mbc-mosto: [INFO] [SCHED] emitting fetch_upstream");
                self.emit('fetch_upstream');
            } else {
                console.log("mbc-mosto: [INFO] [SCHED] timer unlock from upstreamCheck. No need to fetch upstream");
                //self.player.timerUnlock();
                self.emit('fetch_upstream');
            }

    }

    /** LOGIC SCHEDULER MODULE */
    //TODO: testing moment.js, converting time, test recursion

    /** convertPlaylistsToScheduledClips
     *
     * here we make all the necesarry calculations and update the current playlist
     * maybe create some warning messages
     * check coherence in scheduled playlists
     * add playlist_attribute= {} in Playlist.js
     *
     * case 0: no playlist available
     *       see modes: snap | fixed
     * case 1: next playlist is overlapped
     *       see modes: snap | fixed
     * case 2: next playlist start more than xx seconds after this one
     *       see modes: snap | fixed
     *
     *       We use a recursive function preparePlaylist
     */
    scheduler.prototype.convertPlaylistsToScheduledClips = function( playlists ) {

        console.log("mbc-mosto: [INFO] [SCHED] converting Playlists to scheduled clips : " + playlists );

        self.emit('converting', '[SCHED] Scheduler start' );

        //clean scheduled clips
        //if ( playlists_updated ) {
        self.scheduled_clips = [];
        if ( playlists.length>0 ) {
            console.log("mbc-mosto: [INFO] [SCHED] actually converting playlists ("+playlists.length+").");
            self.preparePlaylist( playlists, 0, -1 );
        }
        //playlists_updated = false;
        //}

        self.emit('converted', '[SCHED] Scheduler end' );

        //TODO: try to syncro immediatelly
        //or wait for timer synchronization
        console.log("mbc-mosto: [INFO] [SCHED] emitting sync_downstream");
        self.emit('sync_downstream', self.scheduled_clips );

    }

    /** preparePlaylist
     *       recursive convert for convertPlaylistsToScheduledClips
     *
     *       @see convertPlaylistsToScheduledClips
     */
    scheduler.prototype.preparePlaylist = function( playlists, next_playlist_id, lastTimeCode ) {

        var pl = playlists[next_playlist_id];
        var milis,sch_duration_m;
        var sch_duration, sch_time, sch_expect_start, sch_expect_end, schedule_time;
        var i = 0,is = 0;
        var pl_tc, last_tc, diff = 0;

        /*
          if (!self.validatePlaylist(pl)) {
          console.log("mbc-mosto: [ERROR] in preparePlaylist: " + pl.name );
          }
        */
        if (pl==undefined) return;

        pl_tc = moment( pl.startDate );

        if  ( lastTimeCode!=-1 ) {
            last_tc = moment( lastTimeCode,"DD/MM/YYYY HH:mm:ss.SSS");
            diff = last_tc.diff( pl_tc );
        } else last_tc = pl_tc;

        console.log("mbc-mosto: [INFO] [SCHED] preparePlaylist() : next_playlist_id : " + next_playlist_id + " startDate:" + pl_tc.format("DD/MM/YYYY HH:mm:ss") + " lastTimeCode:" +  lastTimeCode + " diff:" + diff );

        if ( lastTimeCode==-1
             || diff < 10000
           ) {

            if ( pl.mode == "snap") {
                // just add all clips with schedule: "now" if diff is less than 10 seconds, else push with own timecode (sch_time = sch_expect_start
                is = 0;
                sch_expect_end = moment( pl_tc, "DD/MM/YYYY HH:mm:ss").format("DD/MM/YYYY HH:mm:ss.SSS");
                for( i=0; i<pl.medias.length; i++) {
                    var sMedia = pl.medias[i];
                    milis = utils.convertFramesToMilliseconds( sMedia.length, sMedia.fps );
                    sch_duration_m = moment.duration( { milliseconds: milis } );

                    sch_time = moment( sch_expect_end, "DD/MM/YYYY HH:mm:ss.SSS").format("DD/MM/YYYY HH:mm:ss.SSS");
                    sch_duration = sch_duration_m.hours() + ":" + sch_duration_m.minutes() + ":" + sch_duration_m.seconds() + "." + sch_duration_m.milliseconds();
                    sch_expect_start = sch_time;
                    sch_expect_end = moment( sch_time ,"DD/MM/YYYY HH:mm:ss.SSS").add( sch_duration_m ).format("DD/MM/YYYY HH:mm:ss.SSS");

                    diff = last_tc.diff( moment( sch_time, "DD/MM/YYYY HH:mm:ss.SSS") );

                    //choose if queue or schedule...
                    if ( (i==0 && Math.abs(diff)<10000 && next_playlist_id>0 ) // first clip of queued playlists if diff <  10 seconds are queued
                         ||
                         ( i>0 && Math.abs(diff)<10000)  ) //clips >0 => all queued clips after first one
                        {
                            schedule_time = "now";
                        } else if (
                            (next_playlist_id==0 && i==0) // first playlist we have, it always need a schedule time
                                ||
                                (Math.abs(diff)>10000) ) // if diff > 10 seconds > use schedule time... (maybe a warning)
                        {
                            //check if we have unclosed playlists (without black end clip) before this new one...
                            var black_duration, black_duration_str;

                            if (next_playlist_id>0) {
                                black_duration = moment.duration({ milliseconds: Math.abs(diff) });
                                black_duration_str = utils.convertDurationToString(black_duration);
                                self.queueBlack( "now", black_duration_str, lastTimeCode, moment( lastTimeCode,"DD/MM/YYYY HH:mm:ss.SSS").add(black_duration).format('DD/MM/YYYY HH:mm:ss.SSS') );
                            } else if (next_playlist_id==0) {
                                //if this is the first and only playlist, check if an empty void is left before it...., so we can put our blackmedia...
                                var tnow = moment();
                                if (self.player) tnow = self.player.timer_clock;
                                if (self.player && !self.player.timer_clock) tnow = self.player.timer_clock = moment();
                                var sch_time_mom = moment(sch_time, "DD/MM/YYYY HH:mm:ss.SSS");
                                var sch_rightnow = moment(tnow).format("DD/MM/YYYY HH:mm:ss.SSS");
                                var diff_void_start = sch_time_mom.diff( tnow );
                                black_duration = moment.duration( sch_time_mom - tnow );
                                black_duration_str = utils.convertDurationToString(black_duration);
                                var sch_to_next_playlist = moment( sch_rightnow,"DD/MM/YYYY HH:mm:ss.SSS").add(black_duration).format('DD/MM/YYYY HH:mm:ss.SSS');
                                console.log("mbc-mosto: [INFO] [SCHED] preparePlaylist > empty space ? diff_void_start :" + diff_void_start );

                                if (diff_void_start>0) {
                                    self.queueBlack( sch_rightnow, black_duration_str, sch_rightnow, sch_to_next_playlist );
                                    sch_time = "now";
                                }

                            }

                            schedule_time = sch_time;
                        }
                    console.log("mbc-mosto: [INFO] [SCHED] adding scheduled clip: sched_time:" + schedule_time + " media.id:" + sMedia.id + " file:" + sMedia.file + " start:"+sch_expect_start+" end:"+sch_expect_end + " milis:" + milis );
                    self.scheduled_clips.push( new ScheduledMedia( sMedia, schedule_time, sch_duration, sch_expect_start, sch_expect_end ) );
                    lastTimeCode = sch_expect_end;
                    last_tc = moment( lastTimeCode,"DD/MM/YYYY HH:mm:ss.SSS");
                }

            } else if ( pl.mode == "fixed") {
                //just add these clips replacing and cutting others!!
            }
        }

        next_playlist_id++;

        //iteration ended because we have no more playlists !
        if ( playlists.length==next_playlist_id) {
            if (next_playlist_id > 0 && lastTimeCode!=-1 && pl.id!="black_id") {
                var black_duration, black_duration_str;
                black_duration = moment.duration( self.fetcher.time_window_to - last_tc );
                black_duration_str = utils.convertDurationToString(black_duration);
                //queue blackness to the end of the last playlist (no after a black media!) till last frame window
                self.queueBlack( "now", black_duration_str, lastTimeCode, moment( lastTimeCode,"DD/MM/YYYY HH:mm:ss.SSS").add(black_duration).format('DD/MM/YYYY HH:mm:ss.SSS') );
            }
            return;
        }

        return self.preparePlaylist( playlists, next_playlist_id, lastTimeCode );
    }

};

exports = module.exports = function(config) {
    util.inherits(scheduler, events.EventEmitter);
    var mosto_scheduler = new scheduler(config);
    return mosto_scheduler;
};

<|endoftext|>


<commit_before>global.Promise = require('bluebird');

const commando = require('discord.js-commando');
const Currency = require('./currency/Currency');
const Experience = require('./currency/Experience');
const oneLine = require('common-tags').oneLine;
const path = require('path');
const Raven = require('raven');
const winston = require('winston');

const Database = require('./postgreSQL/PostgreSQL');
const Redis = require('./redis/Redis');
const SequelizeProvider = require('./postgreSQL/SequelizeProvider');
const config = require('./settings');

const database = new Database();
const redis = new Redis();
const client = new commando.Client({
	owner: config.owner,
	commandPrefix: '?',
	unknownCommandResponse: false,
	disableEveryone: true
});

let earnedRecently = [];
let gainedXPRecently = [];

Raven.config(config.ravenKey);
Raven.install();

database.start();
redis.start();

client.setProvider(new SequelizeProvider(database.db));

client.dispatcher.addInhibitor(msg => {
	const blacklist = client.provider.get('global', 'userBlacklist', []);

	if (!blacklist.includes(msg.author.id)) return false;

	return `User ${msg.author.username}#${msg.author.discriminator} (${msg.author.id}) has been blacklisted.`;
});

client.on('error', winston.error)
	.on('warn', winston.warn)
	.on('ready', () => {
		winston.info(oneLine`
			Client ready... Logged in as ${client.user.username}#${client.user.discriminator} (${client.user.id})
		`);
		Currency.leaderboard();
	})
	.on('disconnect', () => { winston.warn('Disconnected!'); })
	.on('reconnect', () => { winston.warn('Reconnecting...'); })
	.on('commandRun', (cmd, promise, msg, args) => {
		winston.info(oneLine`${msg.author.username}#${msg.author.discriminator} (${msg.author.id})
			> ${msg.guild ? `${msg.guild.name} (${msg.guild.id})` : 'DM'}
			>> ${cmd.groupID}:${cmd.memberName}
			${Object.values(args)[0] !== '' ? `>>> ${Object.values(args)}` : ''}
		`);
	})
	.on('message', async (message) => {
		if (message.channel.type === 'dm') return;

		const channelLocks = client.provider.get(message.guild.id, 'locks', []);
		if (channelLocks.includes(message.channel.id)) return;
		if (message.author.bot) return;

		if (!earnedRecently.includes(message.author.id)) {
			const hasImageAttachment = message.attachments.some(attachment => {
				return attachment.url.match(/\.(png|jpg|jpeg|gif|webp)$/);
			});
			const moneyEarned = hasImageAttachment
				? Math.ceil(Math.random() * 7) + 1
				: Math.ceil(Math.random() * 7) + 5;

			Currency._changeBalance(message.author.id, moneyEarned);

			earnedRecently.push(message.author.id);
			setTimeout(() => {
				const index = earnedRecently.indexOf(message.author.id);
				earnedRecently.splice(index, 1);
			}, 8000);
		}

		if (!gainedXPRecently.includes(message.author.id)) {
			const xpEarned = Math.ceil(Math.random() * 9) + 3;
			const oldLevel = await Experience.getLevel(message.author.id);
			Experience.addExperience(message.author.id, xpEarned).then(async () => {
				const newLevel = await Experience.getLevel(message.author.id);

				if (newLevel > oldLevel) {
					Currency._changeBalance(message.author.id, 100 * newLevel);
				}
			}).catch(winston.error);

			gainedXPRecently.push(message.author.id);
			setTimeout(() => {
				const index = gainedXPRecently.indexOf(message.author.id);
				gainedXPRecently.splice(index, 1);
			}, 60 * 1000);
		}
	})
	.on('commandError', (cmd, err) => {
		if (err instanceof commando.FriendlyError) return;
		winston.error(`Error in command ${cmd.groupID}:${cmd.memberName}`, err);
	})
	.on('commandBlocked', (msg, reason) => {
		winston.info(oneLine`
			Command ${msg.command ? `${msg.command.groupID}:${msg.command.memberName}` : ''}
			blocked; User ${msg.author.username}#${msg.author.discriminator} (${msg.author.id}): ${reason}
		`);
	})
	.on('commandPrefixChange', (guild, prefix) => {
		winston.info(oneLine`
			Prefix changed to ${prefix || 'the default'}
			${guild ? `in guild ${guild.name} (${guild.id})` : 'globally'}.
		`);
	})
	.on('commandStatusChange', (guild, command, enabled) => {
		winston.info(oneLine`
			Command ${command.groupID}:${command.memberName}
			${enabled ? 'enabled' : 'disabled'}
			${guild ? `in guild ${guild.name} (${guild.id})` : 'globally'}.
		`);
	})
	.on('groupStatusChange', (guild, group, enabled) => {
		winston.info(oneLine`
			Group ${group.id}
			${enabled ? 'enabled' : 'disabled'}
			${guild ? `in guild ${guild.name} (${guild.id})` : 'globally'}.
		`);
	});

client.registry
	.registerGroups([
		['info', 'Info'],
		['economy', 'Economy'],
		['social', 'Social'],
		['games', 'Games'],
		['item', 'Item'],
		['weather', 'Weather'],
		['music', 'Music'],
		['tags', 'Tags']
	])
	.registerDefaults()
	.registerCommandsIn(path.join(__dirname, 'commands'));

client.login(config.token);
<commit_msg>register emoji type<commit_after>global.Promise = require('bluebird');

const commando = require('discord.js-commando');
const Currency = require('./currency/Currency');
const Experience = require('./currency/Experience');
const oneLine = require('common-tags').oneLine;
const path = require('path');
const Raven = require('raven');
const winston = require('winston');

const Database = require('./postgreSQL/PostgreSQL');
const Redis = require('./redis/Redis');
const SequelizeProvider = require('./postgreSQL/SequelizeProvider');
const config = require('./settings');

const database = new Database();
const redis = new Redis();
const client = new commando.Client({
	owner: config.owner,
	commandPrefix: '?',
	unknownCommandResponse: false,
	disableEveryone: true
});

let earnedRecently = [];
let gainedXPRecently = [];

Raven.config(config.ravenKey);
Raven.install();

database.start();
redis.start();

client.setProvider(new SequelizeProvider(database.db));

client.dispatcher.addInhibitor(msg => {
	const blacklist = client.provider.get('global', 'userBlacklist', []);

	if (!blacklist.includes(msg.author.id)) return false;

	return `User ${msg.author.username}#${msg.author.discriminator} (${msg.author.id}) has been blacklisted.`;
});

client.on('error', winston.error)
	.on('warn', winston.warn)
	.on('ready', () => {
		winston.info(oneLine`
			Client ready... Logged in as ${client.user.username}#${client.user.discriminator} (${client.user.id})
		`);
		Currency.leaderboard();
	})
	.on('disconnect', () => { winston.warn('Disconnected!'); })
	.on('reconnect', () => { winston.warn('Reconnecting...'); })
	.on('commandRun', (cmd, promise, msg, args) => {
		winston.info(oneLine`${msg.author.username}#${msg.author.discriminator} (${msg.author.id})
			> ${msg.guild ? `${msg.guild.name} (${msg.guild.id})` : 'DM'}
			>> ${cmd.groupID}:${cmd.memberName}
			${Object.values(args)[0] !== '' ? `>>> ${Object.values(args)}` : ''}
		`);
	})
	.on('message', async (message) => {
		if (message.channel.type === 'dm') return;

		const channelLocks = client.provider.get(message.guild.id, 'locks', []);
		if (channelLocks.includes(message.channel.id)) return;
		if (message.author.bot) return;

		if (!earnedRecently.includes(message.author.id)) {
			const hasImageAttachment = message.attachments.some(attachment => {
				return attachment.url.match(/\.(png|jpg|jpeg|gif|webp)$/);
			});
			const moneyEarned = hasImageAttachment
				? Math.ceil(Math.random() * 7) + 1
				: Math.ceil(Math.random() * 7) + 5;

			Currency._changeBalance(message.author.id, moneyEarned);

			earnedRecently.push(message.author.id);
			setTimeout(() => {
				const index = earnedRecently.indexOf(message.author.id);
				earnedRecently.splice(index, 1);
			}, 8000);
		}

		if (!gainedXPRecently.includes(message.author.id)) {
			const xpEarned = Math.ceil(Math.random() * 9) + 3;
			const oldLevel = await Experience.getLevel(message.author.id);
			Experience.addExperience(message.author.id, xpEarned).then(async () => {
				const newLevel = await Experience.getLevel(message.author.id);

				if (newLevel > oldLevel) {
					Currency._changeBalance(message.author.id, 100 * newLevel);
				}
			}).catch(winston.error);

			gainedXPRecently.push(message.author.id);
			setTimeout(() => {
				const index = gainedXPRecently.indexOf(message.author.id);
				gainedXPRecently.splice(index, 1);
			}, 60 * 1000);
		}
	})
	.on('commandError', (cmd, err) => {
		if (err instanceof commando.FriendlyError) return;
		winston.error(`Error in command ${cmd.groupID}:${cmd.memberName}`, err);
	})
	.on('commandBlocked', (msg, reason) => {
		winston.info(oneLine`
			Command ${msg.command ? `${msg.command.groupID}:${msg.command.memberName}` : ''}
			blocked; User ${msg.author.username}#${msg.author.discriminator} (${msg.author.id}): ${reason}
		`);
	})
	.on('commandPrefixChange', (guild, prefix) => {
		winston.info(oneLine`
			Prefix changed to ${prefix || 'the default'}
			${guild ? `in guild ${guild.name} (${guild.id})` : 'globally'}.
		`);
	})
	.on('commandStatusChange', (guild, command, enabled) => {
		winston.info(oneLine`
			Command ${command.groupID}:${command.memberName}
			${enabled ? 'enabled' : 'disabled'}
			${guild ? `in guild ${guild.name} (${guild.id})` : 'globally'}.
		`);
	})
	.on('groupStatusChange', (guild, group, enabled) => {
		winston.info(oneLine`
			Group ${group.id}
			${enabled ? 'enabled' : 'disabled'}
			${guild ? `in guild ${guild.name} (${guild.id})` : 'globally'}.
		`);
	});

client.registry
	.registerGroups([
		['info', 'Info'],
		['economy', 'Economy'],
		['social', 'Social'],
		['games', 'Games'],
		['item', 'Item'],
		['weather', 'Weather'],
		['music', 'Music'],
		['tags', 'Tags']
	])
	.registerDefaults()
	.registerTypesIn(path.join(__dirname, 'types'))
	.registerCommandsIn(path.join(__dirname, 'commands'));

client.login(config.token);
<|endoftext|>


<commit_before>/** Cz Selection Library
 * @author		Jan Pecha <janpecha@email.cz>, 2013
 * @license		New BSD License
 * @version		2013-02-25-5
 */

var Cz = Cz || {};
Cz.Selection = Cz.Selection || {};

Cz.Selection.getText = function (textarea) {
	return textarea.value.substring(this.getStartPos(textarea), this.getEndPos(textarea));
};

Cz.Selection.getLines = function (textarea) {
	var selEndPos = this.getEndPos(textarea);
	var startPos = textarea.value.substring(0, this.getStartPos(textarea)).lastIndexOf("\n");
	var endPos = selEndPos + textarea.value.substring(selEndPos).indexOf("\n");

	return textarea.value.substring(startPos + 1, endPos).replace("\r", '').split("\n");
};

Cz.Selection.insert = function (textarea, pos, text) {
	textarea.value = textarea.value.substring(0, pos) +
		text +
		textarea.value.substring(pos);
};

Cz.Selection.getStartPos = function (textarea) {
	return textarea.selectionStart;
};

Cz.Selection.getEndPos = function (textarea) {
	return textarea.selectionEnd;
};

Cz.Selection.getLength = function (textarea) {
	return this.getEndPos(textarea) - this.getStartPos(textarea);
};

<commit_msg>added method wrap()<commit_after>/** Cz Selection Library
 * @author		Jan Pecha <janpecha@email.cz>, 2013
 * @license		New BSD License
 * @version		2013-02-25-6
 */

var Cz = Cz || {};
Cz.Selection = Cz.Selection || {};

Cz.Selection.getText = function (textarea) {
	return textarea.value.substring(this.getStartPos(textarea), this.getEndPos(textarea));
};

Cz.Selection.getLines = function (textarea) {
	var selEndPos = this.getEndPos(textarea);
	var startPos = textarea.value.substring(0, this.getStartPos(textarea)).lastIndexOf("\n");
	var endPos = selEndPos + textarea.value.substring(selEndPos).indexOf("\n");

	return textarea.value.substring(startPos + 1, endPos).replace("\r", '').split("\n");
};

Cz.Selection.insert = function (textarea, pos, text) {
	textarea.value = textarea.value.substring(0, pos) +
		text +
		textarea.value.substring(pos);
};

Cz.Selection.wrap = function (textarea, prefix, suffix) {
	var start = this.getStartPos(textarea);
	var end = this.getEndPos(textarea);

	textarea.value = textarea.value.substring(0, start) +
		prefix +
		textarea.value.substring(start, end)
		+ suffix
		+ textarea.value.substring(end);

	// TODO: aby zustal vybran jen uzivatelem vybrany text a ne i prefix|suffix
	// TODO: nastaveni pozice kurzoru
};

Cz.Selection.getStartPos = function (textarea) {
	return textarea.selectionStart;
};

Cz.Selection.getEndPos = function (textarea) {
	return textarea.selectionEnd;
};

Cz.Selection.getLength = function (textarea) {
	return this.getEndPos(textarea) - this.getStartPos(textarea);
};

<|endoftext|>


<commit_before>define([
	"dojo/_base/array", // array.forEach array.map
	"dojo/aspect",
	"dojo/_base/declare"
], function(array, aspect, declare){

// module:
//		dijit/Destroyable
// summary:
//		Mixin to track handles and release them when instance is destroyed.

return declare("dijit.Destroyable", null, {
	// summary:
	//		Mixin to track handles and release them when instance is destroyed.
	// description:
	//		Call this.own(...) on list of handles (returned from dojo/aspect, dojo/on,
	//		dojo/Stateful::watch, or any class (including widgets) with a destroyRecursive() or destroy() method.
	//		Then call destroy() later to destroy this instance and release the resources.

	destroy: function(/*Boolean*/ preserveDom){
		// summary:
		//		Destroy this class, releasing any resources registered via own().
		this._destroyed = true;
	},

	own: function(){
		// summary:
		//		Track specified handles and remove/destroy them when this instance is destroyed, unless they were
		//		already removed/destroyed manually.
		// tags:
		//		protected
		// returns:
		//		The array of specified handles, so you can do for example:
		//	|		var handle = this.own(on(...))[0];

		array.forEach(arguments, function(handle){
			var destroyMethodName =
				"destroyRecursive" in handle ? "destroyRecursive" :	// remove "destroyRecursive" for 2.0
				"destroy" in handle ? "destroy" :
				"remove" in handle ? "remove" :
				"unwatch";		// avoid ("unwatch" in handle) since that's true for all objects in modern browsers

			// When this is destroyed, destroy handle.  Since I'm using aspect.before(),
			// the handle will be destroyed before a subclass's destroy() method starts running, before it calls
			// this.inherited() or even if it doesn't call this.inherited() at all.  If that's an issue, make an
			//  onDestroy() method and connect to that instead.
			handle._odh = aspect.before(this, "destroy", function(preserveDom){
				handle._odh.remove();
				handle[destroyMethodName](preserveDom);
			});

			// If handle is destroyed manually before this is destroyed, then remove the listener set directly above.
			aspect.after(handle, destroyMethodName, function(){
				handle._odh.remove();
			});
		}, this);

		return arguments;		// handle
	}
});

});
<commit_msg>Call remove() rather than unwatch(), since remove() has been added to the handles returned from watch(), refs #15364 !strict.<commit_after>define([
	"dojo/_base/array", // array.forEach array.map
	"dojo/aspect",
	"dojo/_base/declare"
], function(array, aspect, declare){

// module:
//		dijit/Destroyable
// summary:
//		Mixin to track handles and release them when instance is destroyed.

return declare("dijit.Destroyable", null, {
	// summary:
	//		Mixin to track handles and release them when instance is destroyed.
	// description:
	//		Call this.own(...) on list of handles (returned from dojo/aspect, dojo/on,
	//		dojo/Stateful::watch, or any class (including widgets) with a destroyRecursive() or destroy() method.
	//		Then call destroy() later to destroy this instance and release the resources.

	destroy: function(/*Boolean*/ preserveDom){
		// summary:
		//		Destroy this class, releasing any resources registered via own().
		this._destroyed = true;
	},

	own: function(){
		// summary:
		//		Track specified handles and remove/destroy them when this instance is destroyed, unless they were
		//		already removed/destroyed manually.
		// tags:
		//		protected
		// returns:
		//		The array of specified handles, so you can do for example:
		//	|		var handle = this.own(on(...))[0];

		array.forEach(arguments, function(handle){
			var destroyMethodName =
				"destroyRecursive" in handle ? "destroyRecursive" :	// remove "destroyRecursive" for 2.0
				"destroy" in handle ? "destroy" :
				"remove";

			// When this is destroyed, destroy handle.  Since I'm using aspect.before(),
			// the handle will be destroyed before a subclass's destroy() method starts running, before it calls
			// this.inherited() or even if it doesn't call this.inherited() at all.  If that's an issue, make an
			//  onDestroy() method and connect to that instead.
			handle._odh = aspect.before(this, "destroy", function(preserveDom){
				handle._odh.remove();
				handle[destroyMethodName](preserveDom);
			});

			// If handle is destroyed manually before this is destroyed, then remove the listener set directly above.
			aspect.after(handle, destroyMethodName, function(){
				handle._odh.remove();
			});
		}, this);

		return arguments;		// handle
	}
});

});
<|endoftext|>


<commit_before>//consice methods and properties
var z = 5, w = 10;

var o = {
  x: function() {
    console.log('regular method');
  },

  y() {
    console.log('consice method');
  },

  z: z, //regular property
  w //consice property

}

//computed property names
var prefix = 'something';
var o = {
  [prefix + 's']: function() {
    console.log('look at that');
  },
  [prefix + 'x']() {
    console.log('consice');
  }
}
o.somethings(); //"look at that"
o.somethingx(); //"consice"

//TODO Object.assign
//TODO generators
<commit_msg>Update objects.js<commit_after>//consice methods and properties
var z = 5, w = 10;

var o = {
  x: function() {
    console.log('regular method');
  },

  y() {
    console.log('consice method');
  },

  z: z, //regular property
  w //consice property

}

//computed property names
var prefix = 'something';
var o = {
  [prefix + 's']: function() {
    console.log('look at that');
  },
  [prefix + 'x']() {
    console.log('consice');
  }
}
o.somethings(); //"look at that"
o.somethingx(); //"consice"

//TODO Object.assign
<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 */

var EventTarget = function () {

	var listeners = {};

	this.addEventListener = function ( type, listener ) {

		if ( listeners[ type ] === undefined ) {

			listeners[ type ] = [];

		}

		if ( listeners[ type ].indexOf( listener ) === - 1 ) {

			listeners[ type ].push( listener );

		}

	};

	this.dispatchEvent = function ( event ) {

		var listenerArray = listeners[ event.type ];

		if ( listenerArray !== undefined ) {

			for ( var i = 0, l = listenerArray.length; i < l; i ++ ) {

				listenerArray[ i ].call( this, event );

			}

		}

	};

	this.removeEventListener = function ( type, listener ) {

		var index = listeners[ type ].indexOf( listener );

		if ( index !== - 1 ) {

			listeners[ type ].splice( index, 1 );

		}

	};

};
<commit_msg>Code clean-up<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 * @author Jesús Leganés Combarro "Piranna" <piranna@gmail.com>
 */

var EventTarget = function()
{
	var listeners = {};

	this.addEventListener = function(type, listener)
	{
		if(listeners[type] === undefined)
			listeners[type] = [];

		if(listeners[type].indexOf(listener) === -1)
			listeners[type].push(listener);
	};

	this.dispatchEvent = function(event)
	{
		var listenerArray = listeners[event.type];

		if(listenerArray !== undefined)
			for(var i=0, l=listenerArray.length; i<l; i++)
				listenerArray[i].call(this, event);
	};

	this.removeEventListener = function(type, listener)
	{
		var index = listeners[type].indexOf(listener);

		if(index !== -1)
			listeners[type].splice(index, 1);
	};
};<|endoftext|>


<commit_before>Seed({
		name : "Mold.Lib.VDom.DomNode",
		dna : "static",
	},
	function(){

		return function DomNode(config){
			//°include Mold.Lib.VDom.ProtoNode

			this.type = DOM_NODE;
			this.attributes = config.attributes || {};
			this.domPointer = false;
			this.renderDom = this.vdom;

			this.onSetData = function(data, bind){

				//set children to false if no data is given
				for(var name in this.children){
					if(Mold.isArray(this.children[name])){
						var len = this.children[name].length, i = 0;
						for(; i < len; i++){
							var selected = this.children[name][i];
							if(selected.type === BLOCK_NODE){
								//if type is a blocknode add parent data
								if(data){
									selected.setData(data, bind);
								}else{
									selected.setData(false, bind);
								}
							}else{
								if(selected.hasParentValue && data[selected.parentName] &&  data[selected.parentName][selected.childName]){
									selected.setData(data[selected.parentName][selected.childName], bind);
								}else if(data[name]){
									selected.setData(data[name], bind);
								}else{
									selected.setData("", bind);
								}

							}
						}
					}else{

						if(this.children[name].type === BLOCK_NODE){
							//if type is a blocknode add parent data
							if(data){
								this.children[name].setData(data, bind);
							}else{
								this.children[name].setData(false, bind);
							}
						}else{
							var selected = this.children[name];
							if(selected.hasParentValue && data[selected.parentName] &&  data[selected.parentName][selected.childName]){
								selected.setData(data[selected.parentName][selected.childName], bind);
							}else if(data[name]){
								this.children[name].setData(data[name], bind);
							}else{
								this.children[name].setData("", bind);
							}
						}

					}
				}

			}

			this.clone = function(){

				var newNode =  new DomNode({
					name : this.name,
					data : this.data,
					services : this.services
				});

				var i = 0, len = this.vdom.length;

				for(; i < len; i++){
					var cloneNode = this.vdom[i].clone();
					newNode.addNode(cloneNode)
				}

				for(var name in this.attributes){
					var cloneNode = this.attributes[name].clone();
					newNode.addAttribute(cloneNode);

				}

				return newNode;
			}

			this.renderAttribute = function(name){
				var attr = this.attributes[name];
				if(attr){
					var attrValue = attr.render();
					this.domPointer.setAttribute(name, attrValue);
				}
			}

			this.render = function(){

				if(!this.domPointer){
					this.domPointer = _doc.createElement(this.name);
					this.domPointer.moldTemplate = this.services.template;
				}

				var i = 0, len = this.renderDom.length;
				for(; i < len; i++){
					this.domPointer.appendChild(this.renderDom[i].render());
				}

				for(var name in this.attributes){
					var attrValue = this.attributes[name].render();
					this.domPointer.setAttribute(name, attrValue);
				}

				return this.domPointer;
			}

			this.renderString = function(){
				var output = '<' + this.name;

				for(var name in this.attributes){
					var attrValue = this.attributes[name].renderString();
					output += ' ' + name + '="' + attrValue + '"';
				}

				output += '>';

				var i = 0, len = this.renderDom.length;
				for(; i < len; i++){
					output += this.renderDom[i].renderString();
				}

				output += '</' + this.name + '>';

				return output;
			}

		}

	}

)<commit_msg>reRender method added<commit_after>Seed({
		name : "Mold.Lib.VDom.DomNode",
		dna : "static",
	},
	function(){

		return function DomNode(config){
			//°include Mold.Lib.VDom.ProtoNode

			this.type = DOM_NODE;
			this.attributes = config.attributes || {};
			this.domPointer = false;
			this.renderDom = this.vdom;
			this.stopDirective = true;

			this.onSetData = function(data, bind){

				//set children to false if no data is given
				for(var name in this.children){
					if(Mold.isArray(this.children[name])){
						var len = this.children[name].length, i = 0;
						for(; i < len; i++){
							var selected = this.children[name][i];
							if(selected.type === BLOCK_NODE){
								//if type is a blocknode add parent data
								if(data){
									selected.setData(data, bind);
								}else{
									selected.setData(false, bind);
								}
							}else{
								if(selected.hasParentValue && data[selected.parentName] &&  data[selected.parentName][selected.childName]){
									selected.setData(data[selected.parentName][selected.childName], bind);
								}else if(data[name]){
									selected.setData(data[name], bind);
								}else{
									selected.setData("", bind);
								}

							}
						}
					}else{

						if(this.children[name].type === BLOCK_NODE){
							//if type is a blocknode add parent data
							if(data){
								this.children[name].setData(data, bind);
							}else{
								this.children[name].setData(false, bind);
							}
						}else{
							var selected = this.children[name];
							if(selected.hasParentValue && data[selected.parentName] &&  data[selected.parentName][selected.childName]){
								selected.setData(data[selected.parentName][selected.childName], bind);
							}else if(data[name]){
								this.children[name].setData(data[name], bind);
							}else{
								this.children[name].setData("", bind);
							}
						}

					}
				}

			}

			this.clone = function(){

				var newNode =  new DomNode({
					name : this.name,
					data : this.data,
					services : this.services
				});

				var i = 0, len = this.vdom.length;

				for(; i < len; i++){
					var cloneNode = this.vdom[i].clone();
					newNode.addNode(cloneNode)
				}

				for(var name in this.attributes){
					var cloneNode = this.attributes[name].clone();
					newNode.addAttribute(cloneNode);

				}

				return newNode;
			}

			this.renderAttribute = function(name){
				var attr = this.attributes[name];
				if(attr){
					var attrValue = attr.render();
					this.domPointer.setAttribute(name, attrValue);
				}
			}

			this.render = function(){
				var created = false;
				if(!this.domPointer){
					this.domPointer = _doc.createElement(this.name);
					this.domPointer.moldTemplate = this.services.template;
					created = true;
				}

				var i = 0, len = this.renderDom.length;
				for(; i < len; i++){
					this.renderDom[i].parentElement = this.domPointer;
					this.domPointer.appendChild(this.renderDom[i].render());
				}

				for(var name in this.attributes){
					var attrValue = this.attributes[name].render();
					this.domPointer.setAttribute(name, attrValue);
				}
				this.domPointer.stopDirective = this.stopDirective;
				if(created){
					Mold.Lib.Observer.publish('element.created', { element : this.domPointer });
				}
				return this.domPointer;
			}

			this.reRender = function(){
				var i = 0, len = this.renderDom.length;
				for(; i < len; i++){
					 this.renderDom[i].reRender();
				}
			}

			this.renderString = function(){
				var output = '<' + this.name;

				for(var name in this.attributes){
					var attrValue = this.attributes[name].renderString();
					output += ' ' + name + '="' + attrValue + '"';
				}

				output += '>';

				var i = 0, len = this.renderDom.length;
				for(; i < len; i++){
					output += this.renderDom[i].renderString();
				}

				output += '</' + this.name + '>';

				return output;
			}

		}

	}

)<|endoftext|>


<commit_before>import launchDarkly from '../services/launch-darkly';

export function initialize(application) {
  let serviceLookupName = `service:launchDarkly`;

  application.register(serviceLookupName, launchDarkly);
  application.inject(serviceLookupName, 'application', 'application:main');
}

export default {
  initialize
};
<commit_msg>fix(initializer): import service has bad path<commit_after>import launchDarkly from '@busy-web/ember-cli-launch-darkly/services/launch-darkly';

export function initialize(application) {
  let serviceLookupName = `service:launchDarkly`;

  application.register(serviceLookupName, launchDarkly);
  application.inject(serviceLookupName, 'application', 'application:main');
}

export default {
  initialize
};
<|endoftext|>