<commit_before>(function() {
    'use strict';

    function TimeChartFact(BaseChart, Utils) {

        function TimeChart($scope) {
            BaseChart.apply(this, [$scope]);
            var _this = this;
            var opt = {
                options: {
                    tooltip: {
                        formatter: defaultTimechartTooltipFormatter
                    },
                    navigator: {
                        enabled: true
                    },
                    rangeSelector: {
                        inputEnabled: true,
                        buttons: [{
                            type: 'hour',
                            count: 1,
                            text: '1h'
                        }, {
                            type: 'day',
                            count: 1,
                            text: '1D'
                        }, {
                            type: 'all',
                            count: 1,
                            text: 'All'
                        }],
                        selected: 1
                    },
                    scrollbar: {
                        enabled: false
                    },
                    xAxis: {
                        type: 'datetime',
                        title: {
                            text: ''
                        }
                    },
                    yAxis: {
                        min: 0,
                        title: {
                            text: ''
                        }
                    },
                    plotOptions: {
                        series: {
                            lineWidth: 3,
                            marker: {
                                enabled: false
                            }
                        }
                    },
                    legend: {
                        enabled: true
                    }
                },
                title: {
                    text: ''
                },

                series: [],
                useHighStocks: true,
                loading: true
            };

            Utils.merge($scope.chartConfig, opt);

            this.parseData = function(data) {
                $scope.chartConfig.yAxis.min = _this.getMinValue(data.Data);
                //config.yAxis.max = ChartBase.getMaxValue(data.Data);
                $scope.chartConfig.series = [];
                $scope.chartConfig.xAxis.categories = [];
                var tempData = [];
                var minDate = Number.POSITIVE_INFINITY;
                var maxDate = Number.NEGATIVE_INFINITY;
                var da;
                var i;

                if (data.Cols[0].tuples[0].children) {
                    var k = 0;
                    for(var t = 0; t < data.Cols[0].tuples.length; t++) {
                        for (var c = 0; c < data.Cols[0].tuples[t].children.length; c++) {
                            tempData = [];
                            minDate = Number.POSITIVE_INFINITY;
                            maxDate = Number.NEGATIVE_INFINITY;
                            for (var d = 0; d < data.Cols[1].tuples.length; d++) {
                                da = convertDateFromCache(extractValue(data.Cols[1].tuples[i].path));//this.getDate(data.Cols[1].tuples[i].caption);
                                tempData.push([
                                    da,
                                    data.Data[data.Cols[0].tuples.length * data.Cols[0].tuples[t].children.length * d + t * data.Cols[0].tuples[t].children.length + c] || 0
                                ]);
                                if (tempData[tempData.length - 1][1] === "") tempData[tempData.length - 1][1] = null;
                                k++;
                            }
                            _this.addSeries({
                                data: tempData,
                                name: data.Cols[0].tuples[t].caption + "/" + data.Cols[0].tuples[t].children[c].caption,
                                format: data.Cols[0].tuples[t].format
                            });
                        }
                    }
                } else {
                    for(var j = 0; j < data.Cols[0].tuples.length; j++) {
                        tempData = [];
                        minDate = Number.POSITIVE_INFINITY;
                        maxDate = Number.NEGATIVE_INFINITY;
                        for (i = 0; i < data.Cols[1].tuples.length; i++) {
                            da = convertDateFromCache(extractValue(data.Cols[1].tuples[i].path));//this.getDate(data.Cols[1].tuples[i].caption);
                            tempData.push(
                                [da, data.Data[i * data.Cols[0].tuples.length + j] || 0]
                            );
                        }
                        _this.addSeries({
                            data: tempData,
                            name: data.Cols[0].tuples[j].caption,
                            format: data.Cols[0].tuples[j].format
                        });
                    }
                }

                minDate = +Infinity;
                maxDate = -Infinity;
                var minValue;
                var maxValue;
                for (i = 0; i <  $scope.chartConfig.series.length; i++) {
                    minValue = $scope.chartConfig.series[i].data[0][0];
                    maxValue = $scope.chartConfig.series[i].data[$scope.chartConfig.series[i].data.length - 1][0];

                    if (minValue < minDate) minDate = minValue;
                    if (maxValue > maxDate) maxDate = maxValue;
                }
                var days = daysBetween(new Date(minValue), new Date(maxValue));
                if (days <= 2) {
                    $scope.chartConfig.options.rangeSelector.buttons =
                        [{
                            type : 'minute',
                            count : 1,
                            text : '1m'
                        }, {
                            type : 'hour',
                            count : 1,
                            text : '1h'
                        }, {
                            type : 'all',
                            count : 1,
                            text : 'All'
                        }];
                } else if (days <= 30) {
                    $scope.chartConfig.options.rangeSelector.buttons =
                        [{
                            type : 'hour',
                            count : 1,
                            text : '1h'
                        }, {
                            type : 'day',
                            count : 1,
                            text : '1D'
                        }, {
                            type : 'all',
                            count : 1,
                            text : 'All'
                        }];
                } else if (days <= 360) {
                    $scope.chartConfig.options.rangeSelector.buttons =
                        [{
                            type : 'day',
                            count : 1,
                            text : '1D'
                        }, {
                            type : 'month',
                            count : 1,
                            text : '1M'
                        }, {
                            type : 'all',
                            count : 1,
                            text : 'All'
                        }];

                } else {
                    $scope.chartConfig.options.rangeSelector.buttons =
                        [{
                            type : 'day',
                            count : 1,
                            text : '1D'
                        }, {
                            type : 'month',
                            count : 1,
                            text : '1M'
                        }, {
                            type : 'year',
                            count : 1,
                            text : '1Y'
                        }, {
                            type : 'all',
                            count : 1,
                            text : 'All'
                        }];
                    $scope.chartConfig.options.rangeSelector.selected = 3;
                }
            };

            function defaultTimechartTooltipFormatter() {
                var a;
                var fmt;
                var val;
                /* jshint ignore:start */
                var t = this;
                /* jshint ignore:end */
                if (t.series) {
                    fmt = t.series.options.format;
                    val = t.y;
                    if (fmt) val = numeral(val).format(fmt);
                    a = '\u25CF' + t.series.name + ': ' + val;
                    return a;
                } else {
                    a = "";
                    for (var i = t.points.length - 1; i > -1; i--) {
                        fmt = t.points[i].series.options.format;
                        val = t.points[i].y;
                        if (fmt) val = numeral(val).format(fmt);
                        a += '\u25CF' + t.points[i].series.name + ': ' + val + '
';
                    }
                    return a;
                }
            }

            function addDays(date, days) {
                var result = new Date(date);
                result.setDate(date.getDate() + days);
                return result;
            }

            function extractValue(path) {
                var idx = path.indexOf("&[");
                if (idx == -1) return "";
                return path.substring(idx + 2, path.length - 1);
            }

            function getDate(str) {
                var months = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];

                var d = Date.parse(str);
                if (!isNaN(d)) return d;
                if (str.split("-").length == 2) {
                    var parts = str.split("-");
                    var idx = months.indexOf(parts[0].toLowerCase());
                    if (idx != -1) {
                        return Date.parse((idx+1).toString() + "/01/" + parts[1]);
                    }
                } else
                if (str.split(" ").length == 2) {
                    //like 2015-01-07 05
                    str += ":00";
                    d = Date.parse(str.replace(/-/g, "/"));
                    if (!isNaN(d)) return d;
                }
                return 0;
            }

            function convertDateFromCache(s) {
                if (s === "" && s === undefined || s === null) return null;
                var str = s.toString();
                if (str.length == 4) return getDate(s);
                if (str.indexOf("-") != -1) return getDate(s);
                if (str.indexOf(" ") != -1) return getDate(s);
                if (str.length == 6) {
                    var y = str.substr(0, 4);
                    var m = str.substr(4, 2);
                    return Date.parse(new Date(parseInt(y), parseInt(m)-1, 1));
                }
                if (str.length == 5 && !isNaN(parseInt(str))) {
                    var base = new Date(1840, 11, 31);
                    var p = str.toString().split(",");
                    var d = parseInt(p[0]);
                    var t = null;
                    if (p.length > 1) t = parseInt(p[1]);
                    base = addDays(base, parseInt(d));
                    if (t) base.setSeconds(t);
                    return Date.parse(base);
                } else return getDate(s);
            }

            function daysBetween(first, second) {
                var one = new Date(first.getFullYear(), first.getMonth(), first.getDate());
                var two = new Date(second.getFullYear(), second.getMonth(), second.getDate());
                var millisecondsPerDay = 1000 * 60 * 60 * 24;
                var millisBetween = two.getTime() - one.getTime();
                var days = millisBetween / millisecondsPerDay;
                return Math.floor(days);
            }

            this.requestData();
        }

        return TimeChart;
    }

    angular.module('widgets')
        .factory('TimeChart', ['BaseChart', 'Utils', TimeChartFact]);

})();<commit_msg>fixes<commit_after>(function() {
    'use strict';

    function TimeChartFact(BaseChart, Utils, $timeout) {

        function TimeChart($scope) {
            BaseChart.apply(this, [$scope]);
            var _this = this;

            var opt = {
                options: {
                    chart: {
                        zoomType: 'x'
                    },
                    tooltip: {
                        formatter: defaultTimechartTooltipFormatter
                    },
                    navigator: {
                        enabled: true
                    },
                    //rangeSelector: {
                        /*inputEnabled: true,
                        buttons: [{
                            type: 'hour',
                            count: 1,
                            text: '1h'
                        }, {
                            type: 'day',
                            count: 1,
                            text: '1D'
                        }, {
                            type: 'all',
                            count: 1,
                            text: 'All'
                        }],*/
                        //selected: 5
                    //},
                    scrollbar: {
                        enabled: false
                    }
                    /* yAxis: {
                        min: 0,
                        title: {
                            text: ''
                        }
                    },*/
                    /*plotOptions: {
                        series: {
                            lineWidth: 3,
                            marker: {
                                enabled: false
                            }
                        }
                    },
                    legend: {
                        enabled: true
                    }*/
                },
               /* title: {
                    text: ''
                },*/

                series: [],
                useHighStocks: true,
                loading: true
            };

            Utils.merge($scope.chartConfig, opt);

            function customFormatter() {
                /* jshint ignore:start */
                var t = this;
                /* jshint ignore:end */
                if (!_this.chart) return t.value;
                var from = Math.floor(_this.chart.xAxis[0].getExtremes().min);
                var to = Math.ceil(_this.chart.xAxis[0].getExtremes().max);
                var days = daysBetween(new Date(from), new Date(to));
                if (days <= 1) return Highcharts.dateFormat('%H:%M', t.value);
                if (days < 5) return Highcharts.dateFormat('%e %b %H:%M', t.value);
                if (days < 30) return Highcharts.dateFormat('%e %b', t.value);
                if (days < 360 * 2) return Highcharts.dateFormat('%b %Y', t.value);
                return Highcharts.dateFormat('%Y', t.value);
            }

            this.parseData = function(data) {
                //if (_this.chart) _this.chart.xAxis[0].setExtremes(null, null, null, null, null);
                //if (_this.chart) _this.chart.xAxis[1].setExtremes(null, null, null, null, null);
                $scope.chartConfig.yAxis.min = _this.getMinValue(data.Data);
                //config.yAxis.max = ChartBase.getMaxValue(data.Data);
                $scope.chartConfig.series = [];
                var tempData = [];
                var minDate = Number.POSITIVE_INFINITY;
                var maxDate = Number.NEGATIVE_INFINITY;
                var da;
                var i;

                if (data.Cols[0].tuples[0].children) {
                    var k = 0;
                    for(var t = 0; t < data.Cols[0].tuples.length; t++) {
                        for (var c = 0; c < data.Cols[0].tuples[t].children.length; c++) {
                            tempData = [];
                            for (var d = 0; d < data.Cols[1].tuples.length; d++) {
                                da = convertDateFromCache(extractValue(data.Cols[1].tuples[i].path));//this.getDate(data.Cols[1].tuples[i].caption);
                                tempData.push([
                                    da,
                                    data.Data[data.Cols[0].tuples.length * data.Cols[0].tuples[t].children.length * d + t * data.Cols[0].tuples[t].children.length + c] || 0
                                ]);
                                if (tempData[tempData.length - 1][1] === "") tempData[tempData.length - 1][1] = null;
                                k++;
                            }
                            _this.addSeries({
                                data: tempData,
                                name: data.Cols[0].tuples[t].caption + "/" + data.Cols[0].tuples[t].children[c].caption,
                                format: data.Cols[0].tuples[t].format
                            });
                        }
                    }
                } else {
                    for(var j = 0; j < data.Cols[0].tuples.length; j++) {
                        tempData = [];
                        for (i = 0; i < data.Cols[1].tuples.length; i++) {
                            da = convertDateFromCache(extractValue(data.Cols[1].tuples[i].path));//this.getDate(data.Cols[1].tuples[i].caption);
                            var value = data.Data[i * data.Cols[0].tuples.length + j];
                            if (value !== "") tempData.push([da, value || 0]);
                        }

                        _this.addSeries({
                            data: tempData,
                            name: data.Cols[0].tuples[j].caption,
                            format: data.Cols[0].tuples[j].format
                        });
                    }
                }

                // Due bug in timechart we need manually update navigator and axis extremes after data refresh
                if ((_this.chart) && ($scope.chartConfig.series.length !== 0)) {
                    for (i = 0; i < _this.chart.xAxis.length; i++) _this.chart.xAxis[i].setExtremes();
                    var nav = _this.chart.get('highcharts-navigator-series');
                    if (nav) nav.setData($scope.chartConfig.series[0].data);
                }
                /*var minValue;
                var maxValue;
                for (i = 0; i <  $scope.chartConfig.series.length; i++) {
                    //var k = 0;
                    //while ($scope.chartConfig.series[i].data[k][1])
                    minValue = $scope.chartConfig.series[i].data[0][0];
                    maxValue = $scope.chartConfig.series[i].data[$scope.chartConfig.series[i].data.length - 1][0];

                    if (minValue < minDate) minDate = minValue;
                    if (maxValue > maxDate) maxDate = maxValue;
                }
                var days = daysBetween(new Date(minValue), new Date(maxValue));*/
                /*if (days <= 2) {
                    $scope.chartConfig.options.rangeSelector.buttons =
                        [{
                            type : 'minute',
                            count : 1,
                            text : '1m'
                        }, {
                            type : 'hour',
                            count : 1,
                            text : '1h'
                        }, {
                            type : 'all',
                            count : 1,
                            text : 'All'
                        }];
                } else if (days <= 30) {
                    $scope.chartConfig.options.rangeSelector.buttons =
                        [{
                            type : 'hour',
                            count : 1,
                            text : '1h'
                        }, {
                            type : 'day',
                            count : 1,
                            text : '1D'
                        }, {
                            type : 'all',
                            count : 1,
                            text : 'All'
                        }];
                } else if (days <= 360) {
                    $scope.chartConfig.options.rangeSelector.buttons =
                        [{
                            type : 'day',
                            count : 1,
                            text : '1D'
                        }, {
                            type : 'month',
                            count : 1,
                            text : '1M'
                        }, {
                            type : 'all',
                            count : 1,
                            text : 'All'
                        }];

                } else {
                    $scope.chartConfig.options.rangeSelector.buttons =
                        [{
                            type : 'day',
                            count : 1,
                            text : '1D'
                        }, {
                            type : 'month',
                            count : 1,
                            text : '1M'
                        }, {
                            type : 'year',
                            count : 1,
                            text : '1Y'
                        }, {
                            type : 'all',
                            count : 1,
                            text : 'All'
                        }];
                    $scope.chartConfig.options.rangeSelector.selected = 3;
                }*/
            };

            function defaultTimechartTooltipFormatter() {
                var a;
                var fmt;
                var val;
                /* jshint ignore:start */
                var t = this;
                /* jshint ignore:end */
                if (t.series) {
                    fmt = t.series.options.format;
                    val = t.y;
                    if (fmt) val = numeral(val).format(fmt);
                    a = '\u25CF' + t.series.name + ': ' + val;
                    return a;
                } else {
                    a = "";
                    for (var i = t.points.length - 1; i > -1; i--) {
                        fmt = t.points[i].series.options.format;
                        val = t.points[i].y;
                        if (fmt) val = numeral(val).format(fmt);
                        a += '\u25CF' + t.points[i].series.name + ': ' + val + '
';
                    }
                    return a;
                }
            }

            function addDays(date, days) {
                var result = new Date(date);
                result.setDate(date.getDate() + days);
                return result;
            }

            function extractValue(path) {
                var idx = path.indexOf("&[");
                if (idx == -1) return "";
                return path.substring(idx + 2, path.length - 1);
            }

            function getDate(str) {
                var months = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];

                var d = Date.parse(str);
                if (!isNaN(d)) return d;
                if (str.split("-").length == 2) {
                    var parts = str.split("-");
                    var idx = months.indexOf(parts[0].toLowerCase());
                    if (idx != -1) {
                        return Date.parse((idx+1).toString() + "/01/" + parts[1]);
                    }
                } else
                if (str.split(" ").length == 2) {
                    //like 2015-01-07 05
                    var timeParts = str.split(" ")[1].split(":").length;
                     if (timeParts === 0) str += ":00";
                    d = Date.parse(str.replace(/-/g, "/"));
                    if (!isNaN(d)) return d;
                }
                return 0;
            }

            function convertDateFromCache(s) {
                if (s === "" && s === undefined || s === null) return null;
                var str = s.toString();
                if (str.length == 4) return getDate(s);
                if (str.indexOf("-") != -1) return getDate(s);
                if (str.indexOf(" ") != -1) return getDate(s);
                if (str.length == 6) {
                    var y = str.substr(0, 4);
                    var m = str.substr(4, 2);
                    return Date.parse(new Date(parseInt(y), parseInt(m)-1, 1));
                }
                if (str.length == 5 && !isNaN(parseInt(str))) {
                    var base = new Date(1840, 11, 31);
                    var p = str.toString().split(",");
                    var d = parseInt(p[0]);
                    var t = null;
                    if (p.length > 1) t = parseInt(p[1]);
                    base = addDays(base, parseInt(d));
                    if (t) base.setSeconds(t);
                    return Date.parse(base);
                } else return getDate(s);
            }

            function daysBetween(first, second) {
                var one = new Date(first.getFullYear(), first.getMonth(), first.getDate());
                var two = new Date(second.getFullYear(), second.getMonth(), second.getDate());
                var millisecondsPerDay = 1000 * 60 * 60 * 24;
                var millisBetween = two.getTime() - one.getTime();
                var days = millisBetween / millisecondsPerDay;
                return Math.floor(days);
            }

            this.requestData();
        }

        return TimeChart;
    }

    angular.module('widgets')
        .factory('TimeChart', ['BaseChart', 'Utils', '$timeout', TimeChartFact]);

})();<|endoftext|>


<commit_before>import path from 'path';
import passport from 'passport';
import express from 'express';

require('dotenv').config();
// console.log(process.env.GOOGLE_CLIENT_ID,
//   process.env.GOOGLE_CLIENT_SECRET,
//   process.env.CALLBACK_URL);
const session = require('express-session');
// import bodyParser from 'body-parser';

const GoogleStrategy = require('passport-google-oauth20').Strategy;

const port = process.env.PORT || 5000;
const app = express();
app.use(passport.initialize());
app.use(passport.session());
app.use(session({
  secret: 'keyboard cat',
  key: 'user_sid',
  resave: false,
  saveUninitialized: false,
  cookie: { expires: 600000 },
}));
app.use(express.static('public'));
// app.use(bodyParser.urlencoded({ extended: true }));
// app.use(bodyParser.json());
passport.serializeUser((user, done) => {
  done(null, user);
});

passport.deserializeUser((obj, done) => {
  done(null, obj);
});

passport.use(new GoogleStrategy({
  clientID: process.env.GOOGLE_CLIENT_ID,
  clientSecret: process.env.GOOGLE_CLIENT_SECRET,
  callbackURL: process.env.CALLBACK_URL,
},
  (accessToken, refreshToken, profile, cb) =>
    // User.findOrCreate({ googleId: profile.id }, function (err, user) {
      // process.nextTick(function () {
     cb(null, profile)
    // });
    // return cb(null, profile);
    // });
  ,
));

app.get('/auth/google',
  passport.authenticate('google', { scope: ['profile'] }));

app.get('/auth/google/callback',
  passport.authenticate('google', { failureRedirect: '/' }),
  (req, res) => {
    console.log('userinfo', req.user);
    // Successful authentication, redirect home.
    res.redirect('/home');
  });

app.get('/logout', (req, res) => {
  req.logOut();
  res.clearCookie('user_sid');
  res.redirect('/');
});

app.get('/loggedin', (req, res) => {
  console.log('check login', req.user);
  res.end();
});

app.get('*', (req, res) => {
  res.sendFile(path.resolve(__dirname, 'public', 'index.html'));
});

app.listen(port, () => {
  console.log('Express server is up on port 5000');
});
<commit_msg>remove console logs<commit_after>import path from 'path';
import passport from 'passport';
import express from 'express';

require('dotenv').config();

const session = require('express-session');

const GoogleStrategy = require('passport-google-oauth20').Strategy;

const port = process.env.PORT || 5000;
const app = express();
app.use(passport.initialize());
app.use(passport.session());
app.use(session({
  secret: 'keyboard cat',
  key: 'user_sid',
  resave: false,
  saveUninitialized: false,
  cookie: { expires: 600000 },
}));
app.use(express.static('public'));
// app.use(bodyParser.urlencoded({ extended: true }));
// app.use(bodyParser.json());
passport.serializeUser((user, done) => {
  done(null, user);
});

passport.deserializeUser((obj, done) => {
  done(null, obj);
});

passport.use(new GoogleStrategy({
  clientID: process.env.GOOGLE_CLIENT_ID,
  clientSecret: process.env.GOOGLE_CLIENT_SECRET,
  callbackURL: process.env.CALLBACK_URL,
},
  (accessToken, refreshToken, profile, cb) =>
    // User.findOrCreate({ googleId: profile.id }, function (err, user) {
      // process.nextTick(function () {
     cb(null, profile)
    // });
    // return cb(null, profile);
    // });
  ,
));

app.get('/auth/google',
  passport.authenticate('google', { scope: ['profile'] }));

app.get('/auth/google/callback',
  passport.authenticate('google', { failureRedirect: '/' }),
  (req, res) => {
    console.log('userinfo', req.user);
    // Successful authentication, redirect home.
    res.redirect('/home');
  });

app.get('/logout', (req, res) => {
  req.logOut();
  res.clearCookie('user_sid');
  res.redirect('/');
});

app.get('/loggedin', (req, res) => {
  console.log('check login', req.user);
  res.end();
});

app.get('*', (req, res) => {
  res.sendFile(path.resolve(__dirname, 'public', 'index.html'));
});

app.listen(port, () => {
  console.log('Express server is up on port 5000');
});
<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
import PropTypes from 'prop-types';

import React from 'react';
import {DeleteModal} from './modals';
import {ReplicationTable} from './common-table';
import {ReplicationHeader} from './common-activity';

export default class Activity extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      modalVisible: false,
      unconfirmedDeleteDocId: null
    };
  }

  closeModal () {
    this.setState({
      modalVisible: false,
      unconfirmedDeleteDocId: null
    });
  }

  showModal (doc) {
    this.setState({
      modalVisible: true,
      unconfirmedDeleteDocId: doc
    });
  }

  confirmDeleteDocs () {
    let docs = [];
    if (this.state.unconfirmedDeleteDocId) {
      const doc = this.props.docs.find(doc => doc._id === this.state.unconfirmedDeleteDocId);
      docs.push(doc);
    } else {
      docs = this.props.docs.filter(doc => doc.selected);
    }

    this.props.deleteDocs(docs);
    this.closeModal();
  }

  numDocsSelected () {
    return this.props.docs.filter(doc => doc.selected).length;
  }

  render () {
    const {
      onFilterChange,
      activitySort,
      changeActivitySort,
      docs,
      filter,
      selectAllDocs,
      someDocsSelected,
      allDocsSelected,
      selectDoc
    } = this.props;

    const {modalVisible} = this.state;
    return (

          Replications must have a replication document to display in the following table.

        <ReplicationHeader
          filter={filter}
          onFilterChange={onFilterChange}
        />
        <ReplicationTable
          someDocsSelected={someDocsSelected}
          allDocsSelected={allDocsSelected}
          selectAllDocs={selectAllDocs}
          docs={docs}
          selectDoc={selectDoc}
          deleteDocs={this.showModal.bind(this)}
          descending={activitySort.descending}
          column={activitySort.column}
          changeSort={changeActivitySort}
        />
        <DeleteModal
          isReplicationDB={true}
          multipleDocs={this.numDocsSelected()}
          visible={modalVisible}
          onClose={this.closeModal.bind(this)}
          onClick={this.confirmDeleteDocs.bind(this)}
        />

    );
  }
}

Activity.propTypes = {
  docs: PropTypes.array.isRequired,
  filter: PropTypes.string.isRequired,
  selectAllDocs: PropTypes.func.isRequired,
  allDocsSelected: PropTypes.bool.isRequired,
  someDocsSelected: PropTypes.bool.isRequired,
  selectDoc: PropTypes.func.isRequired,
  onFilterChange: PropTypes.func.isRequired,
  deleteDocs: PropTypes.func.isRequired,
  activitySort: PropTypes.object.isRequired,
  changeActivitySort: PropTypes.func.isRequired
};
<commit_msg>In Replication panel warn that not all replications may be displayed. (#1311)<commit_after>// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
import PropTypes from 'prop-types';

import React from 'react';
import {DeleteModal} from './modals';
import {ReplicationTable} from './common-table';
import {ReplicationHeader} from './common-activity';

export default class Activity extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      modalVisible: false,
      unconfirmedDeleteDocId: null
    };
  }

  closeModal () {
    this.setState({
      modalVisible: false,
      unconfirmedDeleteDocId: null
    });
  }

  showModal (doc) {
    this.setState({
      modalVisible: true,
      unconfirmedDeleteDocId: doc
    });
  }

  confirmDeleteDocs () {
    let docs = [];
    if (this.state.unconfirmedDeleteDocId) {
      const doc = this.props.docs.find(doc => doc._id === this.state.unconfirmedDeleteDocId);
      docs.push(doc);
    } else {
      docs = this.props.docs.filter(doc => doc.selected);
    }

    this.props.deleteDocs(docs);
    this.closeModal();
  }

  numDocsSelected () {
    return this.props.docs.filter(doc => doc.selected).length;
  }

  render () {
    const {
      onFilterChange,
      activitySort,
      changeActivitySort,
      docs,
      filter,
      selectAllDocs,
      someDocsSelected,
      allDocsSelected,
      selectDoc
    } = this.props;

    const {modalVisible} = this.state;
    return (

          Replications must have a replication document to display in the following table.
          Up to about 100 replications are displayed.

        <ReplicationHeader
          filter={filter}
          onFilterChange={onFilterChange}
        />
        <ReplicationTable
          someDocsSelected={someDocsSelected}
          allDocsSelected={allDocsSelected}
          selectAllDocs={selectAllDocs}
          docs={docs}
          selectDoc={selectDoc}
          deleteDocs={this.showModal.bind(this)}
          descending={activitySort.descending}
          column={activitySort.column}
          changeSort={changeActivitySort}
        />
        <DeleteModal
          isReplicationDB={true}
          multipleDocs={this.numDocsSelected()}
          visible={modalVisible}
          onClose={this.closeModal.bind(this)}
          onClick={this.confirmDeleteDocs.bind(this)}
        />

    );
  }
}

Activity.propTypes = {
  docs: PropTypes.array.isRequired,
  filter: PropTypes.string.isRequired,
  selectAllDocs: PropTypes.func.isRequired,
  allDocsSelected: PropTypes.bool.isRequired,
  someDocsSelected: PropTypes.bool.isRequired,
  selectDoc: PropTypes.func.isRequired,
  onFilterChange: PropTypes.func.isRequired,
  deleteDocs: PropTypes.func.isRequired,
  activitySort: PropTypes.object.isRequired,
  changeActivitySort: PropTypes.func.isRequired
};
<|endoftext|>


<commit_before>import {dialog} from 'electron';
import {isEmpty, first} from 'lodash';
import csv from 'fast-csv';
import fs from 'fs';
import {basename} from 'path';
import log from 'karmapa-log';
import sleep from 'sleep-promise';
import shortid from 'shortid';

import csvProcessor, {FIELD_PAGE_NUM} from './../../helpers/csvProcessor';
import pageNumToFloat from './../../helpers/pageNumToFloat';
import FRACTION_LENGTH from './../../constants/fractionLength';

const numberConcurrentWrite = 50000;
const dialogOptions = {
  properties: ['openFile'],
  filters: [
    {name: 'Csv Files', extensions: ['csv']}
  ]
};

export default async function addFolderByCsv(event, data) {

  const {models, importEmitter, db} = this.params;
  const {Folder} = models;
  const {broadcast, resolve, reject} = this;

  dialog.showOpenDialog(dialogOptions, handleDialogOpen);

  function processCsv(csvFilePath) {

    let cancelImporting = false;
    importEmitter.removeAllListeners();

    importEmitter.once('cancel-importing', () => {
      cancelImporting = true;
    });

    const filename = basename(csvFilePath);
    const stream = fs.createReadStream(csvFilePath);
    const timeStart = +new Date();

    let completedLines = 0;
    let hasColumnRow = false;
    let folder = null;
    let fields = [];
    let currentEntryDatum = null;
    let entryData = [];

    async function handleData(data) {

      if (cancelImporting) {
        return Promise.reject('User stopped importing');
      }

      if (isEmpty(folder) && csvProcessor.isColumnRow(data)) {
        const columnData = csvProcessor.getColumnData(data);
        folder = await Folder.create({
          name: `${filename} - ${shortid.generate()}`,
          data: columnData
        });
        broadcast('csv-folder-created', {folderId: folder.id});
        fields = csvProcessor.getFields(data);
        hasColumnRow = true;
      }
      else if (folder) {

        const rowData = csvProcessor.getRowDataByFields(data, fields);
        const {sourceEntry} = rowData;
        const pageNum = pageNumToFloat(rowData[FIELD_PAGE_NUM], FRACTION_LENGTH) || '';

        if (sourceEntry) {

          delete rowData.sourceEntry;
          delete rowData[FIELD_PAGE_NUM];

          currentEntryDatum = {
            folderId: folder.id,
            sourceEntry,
            pageNum,
            data: rowData
          };

          return currentEntryDatum;
        }

        if (currentEntryDatum) {
          currentEntryDatum.data = csvProcessor.appendData(data, currentEntryDatum.data, fields);
        }
      }
    }

    async function batchInsertIfNeeded(entryDatum) {

      if (entryDatum) {
        entryData.push(entryDatum);

        if (entryData.length > (numberConcurrentWrite + 1)) {

          const insertQuery = getEntryBatchInsertQuery(db, entryData.slice(0, entryData.length - 1));

          return db.raw(insertQuery)
            .then(() => {
              completedLines += entryData.length - 1;
              const seconds = parseInt((+new Date() - timeStart) / 1000, 10);
              const linesPerSecond = Math.floor(completedLines / seconds);
              broadcast('csv-processing-status', {completedLines, linesPerSecond});
              entryData = [entryData.pop()];
            });
        }
      }
    }

    function done() {
      broadcast('csv-processing-status', {completedLines});
      broadcast('csv-processing-done', {filename});
      resolve({message: 'done'});
    }

    csv.fromStream(stream)
      .validate((data, next) => {

        handleData(data)
          .then((entryDatum) => batchInsertIfNeeded(entryDatum))
          .then(() => next(null, true))
          .catch((err) => next(err));
      })
      .on('data', () => {})
      .on('error', (err) => {
        log.error(err);
        reject({message: `${err}`});
      })
      .on('end', () => {

        if (! hasColumnRow) {
          reject({messageId: 'no-column-row-detected', filename});
          return;
        }

        // finish the rest
        if (entryData.length > 0) {
          const insertQuery = getEntryBatchInsertQuery(db, entryData);
          db.raw(insertQuery)
            .then(done);
        }
        else {
          done();
        }
      });
  }

  function handleDialogOpen(paths) {

    if (isEmpty(paths)) {
      resolve({message: 'User did not choose csv file'});
      return;
    }
    broadcast('csv-processing-start');
    const csvFilePath = first(paths);
    processCsv(csvFilePath);
  }
}

function getEntryBatchInsertQuery(db, entryData) {
  const formattedData = entryData.map((row) => ({...row, data: JSON.stringify(row.data)}));
  return db.knex.batchInsert('Entry', formattedData, 200);
}
<commit_msg>use now to return current unix timestamp<commit_after>import {dialog} from 'electron';
import {isEmpty, first} from 'lodash';
import csv from 'fast-csv';
import fs from 'fs';
import {basename} from 'path';
import log from 'karmapa-log';
import sleep from 'sleep-promise';
import shortid from 'shortid';

import csvProcessor, {FIELD_PAGE_NUM} from './../../helpers/csvProcessor';
import pageNumToFloat from './../../helpers/pageNumToFloat';
import FRACTION_LENGTH from './../../constants/fractionLength';
import now from './../../helpers/now';

const numberConcurrentWrite = 50000;
const dialogOptions = {
  properties: ['openFile'],
  filters: [
    {name: 'Csv Files', extensions: ['csv']}
  ]
};

export default async function addFolderByCsv(event, data) {

  const {models, importEmitter, db} = this.params;
  const {Folder} = models;
  const {broadcast, resolve, reject} = this;

  dialog.showOpenDialog(dialogOptions, handleDialogOpen);

  function processCsv(csvFilePath) {

    let cancelImporting = false;
    importEmitter.removeAllListeners();

    importEmitter.once('cancel-importing', () => {
      cancelImporting = true;
    });

    const filename = basename(csvFilePath);
    const stream = fs.createReadStream(csvFilePath);
    const timeStart = now();

    let completedLines = 0;
    let hasColumnRow = false;
    let folder = null;
    let fields = [];
    let currentEntryDatum = null;
    let entryData = [];

    async function handleData(data) {

      if (cancelImporting) {
        return Promise.reject('User stopped importing');
      }

      if (isEmpty(folder) && csvProcessor.isColumnRow(data)) {
        const columnData = csvProcessor.getColumnData(data);
        folder = await Folder.create({
          name: `${filename} - ${shortid.generate()}`,
          data: columnData
        });
        broadcast('csv-folder-created', {folderId: folder.id});
        fields = csvProcessor.getFields(data);
        hasColumnRow = true;
      }
      else if (folder) {

        const rowData = csvProcessor.getRowDataByFields(data, fields);
        const {sourceEntry} = rowData;
        const pageNum = pageNumToFloat(rowData[FIELD_PAGE_NUM], FRACTION_LENGTH) || '';

        if (sourceEntry) {

          delete rowData.sourceEntry;
          delete rowData[FIELD_PAGE_NUM];

          currentEntryDatum = {
            folderId: folder.id,
            sourceEntry,
            pageNum,
            data: rowData
          };

          return currentEntryDatum;
        }

        if (currentEntryDatum) {
          currentEntryDatum.data = csvProcessor.appendData(data, currentEntryDatum.data, fields);
        }
      }
    }

    async function batchInsertIfNeeded(entryDatum) {

      if (entryDatum) {
        entryData.push(entryDatum);

        if (entryData.length > (numberConcurrentWrite + 1)) {

          const insertQuery = getEntryBatchInsertQuery(db, entryData.slice(0, entryData.length - 1));

          return db.raw(insertQuery)
            .then(() => {
              completedLines += entryData.length - 1;
              const seconds = parseInt((+new Date() - timeStart) / 1000, 10);
              const linesPerSecond = Math.floor(completedLines / seconds);
              broadcast('csv-processing-status', {completedLines, linesPerSecond});
              entryData = [entryData.pop()];
            });
        }
      }
    }

    function done() {
      broadcast('csv-processing-status', {completedLines});
      broadcast('csv-processing-done', {filename});
      resolve({message: 'done'});
    }

    csv.fromStream(stream)
      .validate((data, next) => {

        handleData(data)
          .then((entryDatum) => batchInsertIfNeeded(entryDatum))
          .then(() => next(null, true))
          .catch((err) => next(err));
      })
      .on('data', () => {})
      .on('error', (err) => {
        log.error(err);
        reject({message: `${err}`});
      })
      .on('end', () => {

        if (! hasColumnRow) {
          reject({messageId: 'no-column-row-detected', filename});
          return;
        }

        // finish the rest
        if (entryData.length > 0) {
          const insertQuery = getEntryBatchInsertQuery(db, entryData);
          db.raw(insertQuery)
            .then(done);
        }
        else {
          done();
        }
      });
  }

  function handleDialogOpen(paths) {

    if (isEmpty(paths)) {
      resolve({message: 'User did not choose csv file'});
      return;
    }
    broadcast('csv-processing-start');
    const csvFilePath = first(paths);
    processCsv(csvFilePath);
  }
}

function getEntryBatchInsertQuery(db, entryData) {
  const formattedData = entryData.map((row) => ({...row, data: JSON.stringify(row.data)}));
  return db.knex.batchInsert('Entry', formattedData, 200);
}
<|endoftext|>


<commit_before>$(function() {

    // UI elements in colorScheme.html
    // these vars will not select anything if we are in a
    // different page
    var headerSelect = $("select[name=header]");
    var titleSelect = $("select[name=title]");
    var mainBodySelect = $("select[name=mainBody]");
    var sidebarSelect = $("select[name=sidebar]");
    var backgroundSelect = $("select[name=background]");
    var resetter = $("#resetButton");

    function ColorSet(headerHex, titleHex, mainHex, sideHex, bgHex) {
        // Constructor for an object that stores a set of the hexcodes
        // for a specified color scheme
        this.headerHex = headerHex;
        this.titleHex = titleHex;
        this.mainHex = mainHex;
        this.sideHex = sideHex;
        this.bgHex = bgHex;
    }

    function defaultColorSet() {
        return new ColorSet('#0099FF', '#FFCC00', '#FFFFFF',
                            '#808080', '#B0C4DE');
    }

    function changeColor(selector, color) {
        // changes the backgroudn-color of the elements covered
        // by selector to color
        $(selector).css("background-color", color);
    }

    function animateColor(selector, color) {
        // like changeColor, but does the change with an
        // animation, using jquery.colors.js
        // we only animate the initial change of color when the
        // user first picks the new color, all other changes of
        // the css value are done instantly with changeColor
        $(selector).animate({backgroundColor: color}, 'slow');
    }

    function save() {
        var newColors = new ColorSet(headerSelect.val(),
                                     titleSelect.val(),
                                     mainBodySelect.val(),
                                     sidebarSelect.val(),
                                     backgroundSelect.val());
        $.cookie("color", JSON.stringify(newColors),{expires: 7});
    }

    function selectChangeEvent(selector, color)
    {
        // event that is called when one of the selects changes.
        // The elements specified by selector animate a color
        // change to color, and the cookie is updated
        // accordingly
        animateColor(selector, color);
        save();
    }

    headerSelect.change(function() {
        selectChangeEvent("header", $(this).val());
    });

    titleSelect.change(function() {
        selectChangeEvent("h1", $(this).val());
    });

    mainBodySelect.change(function() {
        selectChangeEvent("#mainText", $(this).val());
    });

    sidebarSelect.change(function() {
        // In case the user highlighted nav li's via
        // highlightNav.js, change them too
        selectChangeEvent("nav, nav li", $(this).val());
    });

    backgroundSelect.change(function() {
        selectChangeEvent("body", $(this).val());
    });

    function set(colSet, shouldAnimate) {
        // sets the selects' names and the background colors as
        // specified by colSet, animates if shouldAnimate is
        // true, else just changes the colors
        colSet = $.extend(defaultColorSet(), colSet);//remove null values just in case

        headerSelect.val(colSet.headerHex);
        titleSelect.val(colSet.titleHex);
        mainBodySelect.val(colSet.mainHex);
        sidebarSelect.val(colSet.sideHex);
        backgroundSelect.val(colSet.bgHex);

        var colorFun = changeColor;
        if (shouldAnimate) {
            colorFun = animateColor;
        }

        colorFun("header", colSet.headerHex);
        colorFun("h1", colSet.titleHex);
        colorFun("#mainText", colSet.mainHex);
        colorFun("nav, nav li", colSet.sideHex);
        colorFun("body", colSet.bgHex);
        return true;
    }

    function resetCookie() {
        $.cookie("color", null);
    }

    resetter.click(function() {
        set(defaultColorSet(), true);
        resetCookie();
    });

    function setColorsFromCookie() {
        // reads color and sets the colors accordingly
        // does not animate the color change, as the page should
        // load with the changed colors, and the user should not
        // see the original ones (they have already seen an
        // animation)
        set(JSON.parse($.cookie("color")), false);
    }

    // only action when the document loads is to
    setColorsFromCookie();
});
<commit_msg>Fixed a typo in a comment in colors.js<commit_after>$(function() {

    // UI elements in colorScheme.html
    // these vars will not select anything if we are in a
    // different page
    var headerSelect = $("select[name=header]");
    var titleSelect = $("select[name=title]");
    var mainBodySelect = $("select[name=mainBody]");
    var sidebarSelect = $("select[name=sidebar]");
    var backgroundSelect = $("select[name=background]");
    var resetter = $("#resetButton");

    function ColorSet(headerHex, titleHex, mainHex, sideHex, bgHex) {
        // Constructor for an object that stores a set of the hexcodes
        // for a specified color scheme
        this.headerHex = headerHex;
        this.titleHex = titleHex;
        this.mainHex = mainHex;
        this.sideHex = sideHex;
        this.bgHex = bgHex;
    }

    function defaultColorSet() {
        return new ColorSet('#0099FF', '#FFCC00', '#FFFFFF',
                            '#808080', '#B0C4DE');
    }

    function changeColor(selector, color) {
        // changes the background-color of the elements covered
        // by selector to color
        $(selector).css("background-color", color);
    }

    function animateColor(selector, color) {
        // like changeColor, but does the change with an
        // animation, using jquery.colors.js
        // we only animate the initial change of color when the
        // user first picks the new color, all other changes of
        // the css value are done instantly with changeColor
        $(selector).animate({backgroundColor: color}, 'slow');
    }

    function save() {
        var newColors = new ColorSet(headerSelect.val(),
                                     titleSelect.val(),
                                     mainBodySelect.val(),
                                     sidebarSelect.val(),
                                     backgroundSelect.val());
        $.cookie("color", JSON.stringify(newColors),{expires: 7});
    }

    function selectChangeEvent(selector, color)
    {
        // event that is called when one of the selects changes.
        // The elements specified by selector animate a color
        // change to color, and the cookie is updated
        // accordingly
        animateColor(selector, color);
        save();
    }

    headerSelect.change(function() {
        selectChangeEvent("header", $(this).val());
    });

    titleSelect.change(function() {
        selectChangeEvent("h1", $(this).val());
    });

    mainBodySelect.change(function() {
        selectChangeEvent("#mainText", $(this).val());
    });

    sidebarSelect.change(function() {
        // In case the user highlighted nav li's via
        // highlightNav.js, change them too
        selectChangeEvent("nav, nav li", $(this).val());
    });

    backgroundSelect.change(function() {
        selectChangeEvent("body", $(this).val());
    });

    function set(colSet, shouldAnimate) {
        // sets the selects' names and the background colors as
        // specified by colSet, animates if shouldAnimate is
        // true, else just changes the colors
        colSet = $.extend(defaultColorSet(), colSet);//remove null values just in case

        headerSelect.val(colSet.headerHex);
        titleSelect.val(colSet.titleHex);
        mainBodySelect.val(colSet.mainHex);
        sidebarSelect.val(colSet.sideHex);
        backgroundSelect.val(colSet.bgHex);

        var colorFun = changeColor;
        if (shouldAnimate) {
            colorFun = animateColor;
        }

        colorFun("header", colSet.headerHex);
        colorFun("h1", colSet.titleHex);
        colorFun("#mainText", colSet.mainHex);
        colorFun("nav, nav li", colSet.sideHex);
        colorFun("body", colSet.bgHex);
        return true;
    }

    function resetCookie() {
        $.cookie("color", null);
    }

    resetter.click(function() {
        set(defaultColorSet(), true);
        resetCookie();
    });

    function setColorsFromCookie() {
        // reads color and sets the colors accordingly
        // does not animate the color change, as the page should
        // load with the changed colors, and the user should not
        // see the original ones (they have already seen an
        // animation)
        set(JSON.parse($.cookie("color")), false);
    }

    // only action when the document loads is to
    setColorsFromCookie();
});
<|endoftext|>


<commit_before>// "use strict";

var Glyde = {
  // utilties class

  _checker_interval_id: null,
  _checker_timeout: 0,
  _run_app: "",

  startApp: function() {
    var args = Utils.getDocumentArgs();
    var fs = "fs.glyde";
    if( args && args["fs"] ) {
      fs = (args["fs"] + ".glyde");
    }
    var loadview = _.e( "loadview" );
    Glyde._verbose = (args && args["verbose"] && (Utils.isTrueString( args["verbose"] )));

    if( Glyde._verbose ) {
      _.rt( loadview, ("Loading from " + fs + "...") );
    } else {
      _.rt( loadview, "Loading..." );
    }

    // we look for a file called "fs.glyde" in this folder to load and parse
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = Glyde._startWithFS;
    xhr.open( "GET", fs, true );
    xhr.send();
  },

  _startWithFS: function() {
    // "this" points to the request since that sent the event
    if( this.readyState == 4 ) {    // OK
      if( this.status == 200 ) {
        var fs = Utils.parseSimpleConfig( this.responseText );
        // first, we'll load all the scripts we need for "platform.exec"
        Glyde._run_app = Dict.valueOf( fs, "run" );
        var root = Dict.valueOf( fs, "root", "" );
        var i, item, rows, path_src, path_dest, pi;
        var head = document.getElementsByTagName( "head" )[0];
        for( rows = Utils.split( Dict.valueOf( fs, "script" ), "\n" ), i = 0; i < rows.length; i++ ) {
          item = document.createElement( "script" );
	        item["glyde.exec_app_src"] = rows[i];
          item.src = (root + rows[i]);
          head.appendChild( item );
        }

        // next, we'll add the images
        var body = document.getElementsByTagName( "body" );
        for( rows = Utils.split( Dict.valueOf( fs, "image" ), "\n" ), i = 0; i < rows.length; i++ ) {
          var img = document.createElement( "img" );
          if( (pi = rows[i].indexOf( ">" )) > -1 ) {
            path_src = rows[i].substr( 0, pi ).trim();
            path_dest = rows[i].substr( (pi + 1) ).trim();
          } else {
            path_src = path_dest = rows[i];
          }
          if( path_src.indexOf( "://" ) == -1 ) {
            img.src = (root + path_src);
          } else {
            img.src = path_src;
          }
		      img["gluefilesystem.id"] = path_dest;
		      img.style["display"] = "none";
          document.getElementsByTagName( "body" )[0].appendChild( img );
        }

		    // and finally, the text files
        for( rows = Utils.split( Dict.valueOf( fs, "text" ), "\n" ), i = 0; i < rows.length; i++ ) {
          if( (pi = rows[i].indexOf( ">" )) > -1 ) {
            path_src = rows[i].substr( 0, pi ).trim();
            path_dest = rows[i].substr( (pi + 1) ).trim();
          } else {
            path_src = path_dest = rows[i];
          }
          var ta = document.createElement( "textarea" );
    		  ta["gluefilesystem.id"] = path_dest;
    		  ta["glyde.complete"] = false;
    		  ta.style["display"] = "none";
          document.getElementsByTagName( "body" )[0].appendChild( ta );
		      var xhr = new XMLHttpRequest();
          xhr["glyde.textarea"] = ta;
    			xhr.onreadystatechange = Glyde._setTextAreaFromXHR;
    			xhr.open( "GET", (root + path_src), true );
    			xhr.send();
        }
        if( Glyde._verbose ) {
          console.log( "Waiting for resources..." );
        }
        Glyde._checker_interval_id = window.setInterval( Glyde._checkLoaded, 250 );
      } else {
        _.rt( _.e( "loadview" ), "Failed to load filesystem definition" );
      }
    }
  },

  _setTextAreaFromXHR: function() {
	// "this" points to the request since that sent the event
    if( this.readyState == 4 ) {    // OK
      if( this.status == 200 ) {
        var ta = this["glyde.textarea"];
		    ta.value = this.responseText;
		    ta["glyde.complete"] = true;
      } else {
        window.clearInterval( Glyde._checker_interval_id );
        _.rt( _.e( "loadview" ), "Failed to load text resource" );
      }
    }
  },

  _checkLoaded: function() {
    // have we been going for 10 seconds?
    if( Glyde._checker_timeout++ == 40 ) {
      window.clearInterval( Glyde._checker_interval_id );
      _.rt( _.e( "loadview" ), "Loading is taking too long, try refreshing the page?" );
    }
	  // Check to see if text files have loaded
	  var i;
    var tas = document.getElementsByTagName( "textarea" );
    for( i = 0; i < tas.length; i++ ) {
      if( !tas[i]["glyde.complete"] ) {
        if( Glyde._verbose ) {
          _.rt( _.e( "loadview" ), ("Text resource " + i + " isn't complete yet") );
        }
        return;
      }
    }

   // check if the images are all loaded
    var imgs = document.getElementsByTagName( "img" );
    for( i = 0; i < imgs.length; i++ ) {
      if( !imgs[i].complete ) {
        if( Glyde._verbose ) {
          _.rt( _.e( "loadview" ), ("Image resource " + i + " isn't complete yet") );
        }
        return;
      }
    }

  	// check if the exec apps have registered
  	var scripts = document.getElementsByTagName( "script" );
  	for( i = 0; i < scripts.length; i++ ) {
  		if( scripts["glyde.exec_app_src"] ) {
  			if( !GluePlatform.isExecAppAvailable( scripts["glyde.exec_app_src"] ) ) {
          if( Glyde._verbose ) {
            _.rt( _.e( "loadview" ), ("Script resource " + i + " isn't complete yet") );
          }
  				return false;
  			}
  		}
  	}
    // everythings loaded!
    window.clearInterval( Glyde._checker_interval_id );
    if( Glyde._verbose ) {
      console.log( "Loaded everything, launching app: " + Glyde._run_app );
    }
    document.getElementById( "loadview" ).style["display"] = "none";
    GlydeRT.runApp( Glyde._run_app );
  },

  App: {
    create: function( s_file, s_src ) {
      if( !s_src ) {
        s_src = GlueFileManager.readText( s_file );
      }
      if( s_src === null ) {
        return null;
      }
			var e, s = 0;
			var key, value;
			var data = Dict.create(), vars = Dict.create();
			Dict.set( data, "_file", s_file );
			while( (e = s_src.indexOf( ";", s )) > -1 ) {
			  var line = s_src.substr( s, (e - s) ).trim();
			  s = (e + 1);
				e = line.indexOf( "=" );
				if( (e > -1) && (line.length > 0) && (line.charAt( 0 ) != "#") ) {
					key = line.substring( 0, e );
					value = line.substring( (e + 1) );
					if( key == "var" ) {
    				e = value.indexOf( "=" );
    				if( e > -1 ) {
    					Dict.set( vars, value.substring( 0, e ), value.substring( (e + 1) ) );
    				}
					} else {
					  if( Dict.containsKey( data, key ) ) {
					    value = (Dict.valueOf( data, key ) + "\n" + value);
					  }
					  Dict.set( data, key, value );
					}
				}
			}
			Dict.set( data, "var_dict", vars );
      return data;
    },

    getFile: function( d_app ) {
      return Dict.valueOf( d_app, "_file" );
    },

    getTitle: function( d_app ) {
      return Dict.valueOf( d_app, "title" );
    },

    getScriptFile: function( d_app ) {
      return Dict.valueOf( d_app, "script" );
    },

    getIconFile: function( d_app ) {
      return Dict.valueOf( d_app, "icon" );
    },

    getIncludeFiles: function( d_app ) {      // comma separated list? or multiple include keys makes an array/indexed dict?
      return Dict.valueOf( d_app, "include" );
    },

    getVarsMap: function( d_app ) {   // Dict
      return Dict.valueOf( d_app, "var_dict" );
    },

    getWindowDict: function( d_app ) {
      return Dict.createFromDictBranch( d_app, "window." );
    }
  }
};

var GlydeRT = {
		canvas: null,
		glue: {},

		init: function() { "use strict";
			Glue.init( GlydeRT.glue );
			window.addEventListener( "load", GlydeRT.start );

			return true;
		},

		start: function() { "use strict";
		  Glyde.startApp();
    },

	  runApp: function( s_appfile ) {
			GlydeRT.canvas = document.getElementById( "content" );
			GlydeRT.canvas.addEventListener( "click", GlydeRT._clickHandler, false );

			VecText.init();
			ExtGlyde.init( GlydeRT.canvas );

			Glue.attachPlugin( GlydeRT.glue, ExtGlyde );

      // reset the title of the runtime toolbar
			var tb_title = _.e( "tb_title" );
		  tb_title.removeChild( tb_title.childNodes[0] );
		  _.at( tb_title, "Glyde" );
	    var app = Glyde.App.create( s_appfile );
	    if( app ) {
  	    var script_files = Utils.split( Glyde.App.getScriptFile( app ), "\n" );
  	    var script_idx;
  	    var main_script = "", script;
  	    for( script_idx = 0; script_idx < script_files.length; script_idx++ ) {
  	      script = GlueFileManager.readText( script_files[script_idx] );
  	      if( script ) {
  	        main_script += (script + "\n");
  	      } else {
  	        // TODO: warn unable to load script
  	      }
  	    }
  	    if( main_script ) {
  	      var vars = Glyde.App.getVarsMap( app );   // already an object/map so no need to convert

  				Glue.load( GlydeRT.glue, main_script, vars );
  				GlydeRT._showRuntime();
  				Glue.run( GlydeRT.glue );
  	    } else {
  	      // TODO: warn of unable to load script
  	    }
	    } else {
	      // TODO: warn of unable to load app
	    }
	  },

  getRuntimeDiv: function() {
    return _.e( "runtimeview" );
  },

  _showRuntime: function() {
    _.se( "loadview", { "display": "none" } );
    _.se( "runtimeview", { "display": "block" } );
  },

  /** Event handling **/
	_clickHandler: function( e ) { "use strict";
		e = (e || window.event);

		var label = GlydeRT._getIdAtEventPoint( e );

    if( label ) {
      Glue.run( GlydeRT.glue, label );
    }
	},

  _getIdAtEventPoint: function( o_evt ) { "use strict";
		var rect = GlydeRT.canvas.getBoundingClientRect();
		var x = Math.round( ((o_evt.clientX - rect.left) / (rect.right - rect.left) * GlydeRT.canvas.width) );
		var y = Math.round( ((o_evt.clientY - rect.top) / (rect.bottom - rect.top ) * GlydeRT.canvas.height) );
		return ExtGlyde.getLabelForButtonAt( x, y );
  },

  _minimiseWindow: function() {
    chrome.app.window.current().minimize();
  },

  _closeWindow: function() {
    chrome.app.window.current().close();
  }
};

// Setup Core, Glue and the file system.  Attaches Glyde.start() to window.onload
// At this point ExtGlyde is NOT available - becomes available after start()
GlydeRT.init();

<commit_msg>Improved verbosity<commit_after>// "use strict";

var Glyde = {
  // utilties class

  _checker_interval_id: null,
  _checker_timeout: 0,
  _run_app: "",
  _verbose: false,

  startApp: function() {
    var args = Utils.getDocumentArgs();
    var fs = "fs.glyde";
    if( args && args["fs"] ) {
      fs = (args["fs"] + ".glyde");
    }
    var loadview = _.e( "loadview" );
    Glyde._verbose = (args && args["verbose"] && (Utils.isTrueString( args["verbose"] )));

    if( Glyde._verbose ) {
      _.rt( loadview, ("Loading from " + fs + "...") );
    } else {
      _.rt( loadview, "Loading..." );
    }

    // we look for a file called "fs.glyde" in this folder to load and parse
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = Glyde._startWithFS;
    xhr.open( "GET", fs, true );
    xhr.send();
  },

  _startWithFS: function() {
    // "this" points to the request since that sent the event
    if( this.readyState == 4 ) {    // OK
      if( this.status == 200 ) {
        var fs = Utils.parseSimpleConfig( this.responseText );
        // first, we'll load all the scripts we need for "platform.exec"
        Glyde._run_app = Dict.valueOf( fs, "run" );
        var root = Dict.valueOf( fs, "root", "" );
        var i, item, rows, path_src, path_dest, pi;
        var head = document.getElementsByTagName( "head" )[0];
        for( rows = Utils.split( Dict.valueOf( fs, "script" ), "\n" ), i = 0; i < rows.length; i++ ) {
          item = document.createElement( "script" );
	        item["glyde.exec_app_src"] = rows[i];
          item.src = (root + rows[i]);
          if( Glyde._verbose ) {
            console.log( ("[Glyde] Request script: " + item.src) );
          }
          head.appendChild( item );
        }

        // next, we'll add the images
        var body = document.getElementsByTagName( "body" );
        for( rows = Utils.split( Dict.valueOf( fs, "image" ), "\n" ), i = 0; i < rows.length; i++ ) {
          var img = document.createElement( "img" );
          if( (pi = rows[i].indexOf( ">" )) > -1 ) {
            path_src = rows[i].substr( 0, pi ).trim();
            path_dest = rows[i].substr( (pi + 1) ).trim();
          } else {
            path_src = path_dest = rows[i];
          }
          if( path_src.indexOf( "://" ) == -1 ) {
            img.src = (root + path_src);
          } else {
            img.src = path_src;
          }
          if( Glyde._verbose ) {
            console.log( ("[Glyde] Request image: " + img.src) );
          }
		      img["gluefilesystem.id"] = path_dest;
		      img.style["display"] = "none";
          document.getElementsByTagName( "body" )[0].appendChild( img );
        }

		    // and finally, the text files
        for( rows = Utils.split( Dict.valueOf( fs, "text" ), "\n" ), i = 0; i < rows.length; i++ ) {
          if( (pi = rows[i].indexOf( ">" )) > -1 ) {
            path_src = rows[i].substr( 0, pi ).trim();
            path_dest = rows[i].substr( (pi + 1) ).trim();
          } else {
            path_src = path_dest = rows[i];
          }
          var ta = document.createElement( "textarea" );
    		  ta["gluefilesystem.id"] = path_dest;
    		  ta["glyde.complete"] = false;
    		  ta.style["display"] = "none";
          document.getElementsByTagName( "body" )[0].appendChild( ta );
          if( Glyde._verbose ) {
            console.log( ("[Glyde] Request text: " + (root + path_src)) );
          }
		      var xhr = new XMLHttpRequest();
          xhr["glyde.textarea"] = ta;
    			xhr.onreadystatechange = Glyde._setTextAreaFromXHR;
    			xhr.open( "GET", (root + path_src), true );
    			xhr.send();
        }
        if( Glyde._verbose ) {
          console.log( "[Glyde] Waiting for resources..." );
        }
        Glyde._checker_interval_id = window.setInterval( Glyde._checkLoaded, 250 );
      } else {
        _.rt( _.e( "loadview" ), "Failed to load filesystem definition" );
      }
    }
  },

  _setTextAreaFromXHR: function() {
	// "this" points to the request since that sent the event
    if( this.readyState == 4 ) {    // OK
      if( this.status == 200 ) {
        var ta = this["glyde.textarea"];
		    ta.value = this.responseText;
		    ta["glyde.complete"] = true;
      } else {
        window.clearInterval( Glyde._checker_interval_id );
        _.rt( _.e( "loadview" ), "Failed to load text resource" );
      }
    }
  },

  _checkLoaded: function() {
    // have we been going for 10 seconds?
    if( Glyde._checker_timeout++ == 40 ) {
      window.clearInterval( Glyde._checker_interval_id );
      _.rt( _.e( "loadview" ), "Loading is taking too long, try refreshing the page?" );
    }
	  // Check to see if text files have loaded
	  var i;
    var tas = document.getElementsByTagName( "textarea" );
    for( i = 0; i < tas.length; i++ ) {
      if( !tas[i]["glyde.complete"] ) {
        if( Glyde._verbose ) {
          _.rt( _.e( "loadview" ), ("Text resource " + i + " isn't complete yet") );
        }
        return;
      }
    }

   // check if the images are all loaded
    var imgs = document.getElementsByTagName( "img" );
    for( i = 0; i < imgs.length; i++ ) {
      if( !imgs[i].complete ) {
        if( Glyde._verbose ) {
          _.rt( _.e( "loadview" ), ("Image resource " + i + " isn't complete yet") );
        }
        return;
      }
    }

  	// check if the exec apps have registered
  	var scripts = document.getElementsByTagName( "script" );
  	for( i = 0; i < scripts.length; i++ ) {
  		if( scripts["glyde.exec_app_src"] ) {
  			if( !GluePlatform.isExecAppAvailable( scripts["glyde.exec_app_src"] ) ) {
          if( Glyde._verbose ) {
            _.rt( _.e( "loadview" ), ("Script resource " + i + " isn't complete yet") );
          }
  				return false;
  			}
  		}
  	}
    // everythings loaded!
    window.clearInterval( Glyde._checker_interval_id );
    if( Glyde._verbose ) {
      console.log( "[Glyde] Loaded everything, launching app: " + Glyde._run_app );
    }
    document.getElementById( "loadview" ).style["display"] = "none";
    GlydeRT.runApp( Glyde._run_app );
  },

  App: {
    create: function( s_file, s_src ) {
      if( !s_src ) {
        s_src = GlueFileManager.readText( s_file );
      }
      if( s_src === null ) {
        return null;
      }
			var e, s = 0;
			var key, value;
			var data = Dict.create(), vars = Dict.create();
			Dict.set( data, "_file", s_file );
			while( (e = s_src.indexOf( ";", s )) > -1 ) {
			  var line = s_src.substr( s, (e - s) ).trim();
			  s = (e + 1);
				e = line.indexOf( "=" );
				if( (e > -1) && (line.length > 0) && (line.charAt( 0 ) != "#") ) {
					key = line.substring( 0, e );
					value = line.substring( (e + 1) );
					if( key == "var" ) {
    				e = value.indexOf( "=" );
    				if( e > -1 ) {
    					Dict.set( vars, value.substring( 0, e ), value.substring( (e + 1) ) );
    				}
					} else {
					  if( Dict.containsKey( data, key ) ) {
					    value = (Dict.valueOf( data, key ) + "\n" + value);
					  }
					  Dict.set( data, key, value );
					}
				}
			}
			Dict.set( data, "var_dict", vars );
      return data;
    },

    getFile: function( d_app ) {
      return Dict.valueOf( d_app, "_file" );
    },

    getTitle: function( d_app ) {
      return Dict.valueOf( d_app, "title" );
    },

    getScriptFile: function( d_app ) {
      return Dict.valueOf( d_app, "script" );
    },

    getIconFile: function( d_app ) {
      return Dict.valueOf( d_app, "icon" );
    },

    getIncludeFiles: function( d_app ) {      // comma separated list? or multiple include keys makes an array/indexed dict?
      return Dict.valueOf( d_app, "include" );
    },

    getVarsMap: function( d_app ) {   // Dict
      return Dict.valueOf( d_app, "var_dict" );
    },

    getWindowDict: function( d_app ) {
      return Dict.createFromDictBranch( d_app, "window." );
    }
  }
};

var GlydeRT = {
		canvas: null,
		glue: {},

		init: function() { "use strict";
			Glue.init( GlydeRT.glue );
			window.addEventListener( "load", GlydeRT.start );

			return true;
		},

		start: function() { "use strict";
		  Glyde.startApp();
    },

	  runApp: function( s_appfile ) {
			GlydeRT.canvas = document.getElementById( "content" );
			GlydeRT.canvas.addEventListener( "click", GlydeRT._clickHandler, false );

			VecText.init();
			ExtGlyde.init( GlydeRT.canvas );

			Glue.attachPlugin( GlydeRT.glue, ExtGlyde );

      // reset the title of the runtime toolbar
			var tb_title = _.e( "tb_title" );
		  tb_title.removeChild( tb_title.childNodes[0] );
		  _.at( tb_title, "Glyde" );
	    var app = Glyde.App.create( s_appfile );
	    if( app ) {
  	    var script_files = Utils.split( Glyde.App.getScriptFile( app ), "\n" );
  	    var script_idx;
  	    var main_script = "", script;
  	    for( script_idx = 0; script_idx < script_files.length; script_idx++ ) {
  	      script = GlueFileManager.readText( script_files[script_idx] );
  	      if( script ) {
  	        main_script += (script + "\n");
  	      } else {
  	        // TODO: warn unable to load script
  	      }
  	    }
  	    if( main_script ) {
  	      var vars = Glyde.App.getVarsMap( app );   // already an object/map so no need to convert

  				Glue.load( GlydeRT.glue, main_script, vars );
  				GlydeRT._showRuntime();
  				Glue.run( GlydeRT.glue );
  	    } else {
  	      // TODO: warn of unable to load script
  	    }
	    } else {
	      // TODO: warn of unable to load app
	    }
	  },

  getRuntimeDiv: function() {
    return _.e( "runtimeview" );
  },

  _showRuntime: function() {
    _.se( "loadview", { "display": "none" } );
    _.se( "runtimeview", { "display": "block" } );
  },

  /** Event handling **/
	_clickHandler: function( e ) { "use strict";
		e = (e || window.event);

		var label = GlydeRT._getIdAtEventPoint( e );

    if( label ) {
      Glue.run( GlydeRT.glue, label );
    }
	},

  _getIdAtEventPoint: function( o_evt ) { "use strict";
		var rect = GlydeRT.canvas.getBoundingClientRect();
		var x = Math.round( ((o_evt.clientX - rect.left) / (rect.right - rect.left) * GlydeRT.canvas.width) );
		var y = Math.round( ((o_evt.clientY - rect.top) / (rect.bottom - rect.top ) * GlydeRT.canvas.height) );
		return ExtGlyde.getLabelForButtonAt( x, y );
  },

  _minimiseWindow: function() {
    chrome.app.window.current().minimize();
  },

  _closeWindow: function() {
    chrome.app.window.current().close();
  }
};

// Setup Core, Glue and the file system.  Attaches Glyde.start() to window.onload
// At this point ExtGlyde is NOT available - becomes available after start()
GlydeRT.init();

<|endoftext|>