<commit_before>var path = require('path');

var config = {
  entry: {
    'ng-hot-reload-core': path.join(__dirname, 'src', 'index.js'),
  },
  devtool: 'source-map',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].js',
    library: 'ng-hot-reload-core',
    libraryTarget: 'umd',
  },
  module: {
    loaders: [
      {
        test: /(\.jsx|\.js)$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
      },
      {
        test: /(\.jsx|\.js)$/,
        loader: 'eslint-loader',
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    modules: [
      path.join(__dirname, 'src'),
      'node_modules'
    ],
    extensions: ['.js'],
  },
};

module.exports = config;
<commit_msg>Minor cleanup in core/webpack-config<commit_after>/* eslint-env node */
const path = require('path');

const config = {
  entry: {
    'ng-hot-reload-core': path.join(__dirname, 'src', 'index.js'),
  },
  devtool: 'source-map',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].js',
    library: 'ng-hot-reload-core',
    libraryTarget: 'umd',
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.js$/,
        loader: 'eslint-loader',
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    modules: [
      path.join(__dirname, 'src'),
      'node_modules',
    ],
    extensions: ['.js'],
  },
};

module.exports = config;
<|endoftext|>


<commit_before>"use strict";
var gauges = [];

OutGauge.onRender(function(outgaugeData){
    document.getElementById('msg').innerHTML = JSON.stringify(outgaugeData,null,'  ')
        .replace(/\n/g,'
')
        .replace(/  /g,'    ');
    // update gauges
    gauges.forEach(function(gauge){
        gauge.gadget.setValue(outgaugeData[gauge.field]);
    });
});

// Generate and update gauges
var gaugeConfig = [
    {
        field: 'rpm',
        size: 300,
        units: 'rpm',
        max: 10000
    },
    {
        field: 'speedKPH',
        size: 300,
        units: 'km/h',
        max: 250
    },
    {
        field: 'clutch',
        size: 200,
        units: 'clutch',
        max: 1
    },
    {
        field: 'brake',
        size: 200,
        units: 'brake',
        max: 1
    },
    {
        field: 'throttle',
        size: 200,
        units: 'throttle',
        max: 1
    }
];

gaugeConfig.forEach(function(gauge){
    console.log(gauge);
    var ticks = [];
    var fixed = gauge.max > 1 ? 0 : 1;
    for(var i = 0; i <= 1; i += 0.2){
        ticks.push( (gauge.max * i).toFixed(fixed) );
    }
    var g = new Gauge({
        renderTo: gauge.field,
        width: gauge.size,
        height:gauge.size,
        maxValue: gauge.max,
        units: gauge.units,
        animation: false,
        highlights: false,
        glow: false,
        majorTicks: ticks,
        colors: {
            plate      : '#222',
            majorTicks : '#f5f5f5',
            minorTicks : '#ddd',
            title      : '#fff',
            units      : '#ccc',
            numbers    : '#eee',
            needle     : { start : 'rgba(240, 128, 128, 1)', end : 'rgba(255, 160, 122, .9)' }
        }
    });
    g.onready = function(){
        gauges.push({field: gauge.field, gadget: g});
    };
    g.draw();
});
<commit_msg>changed range of the speedometer<commit_after>"use strict";
var gauges = [];

OutGauge.onRender(function(outgaugeData){
    document.getElementById('msg').innerHTML = JSON.stringify(outgaugeData,null,'  ')
        .replace(/\n/g,'
')
        .replace(/  /g,'    ');
    // update gauges
    gauges.forEach(function(gauge){
        gauge.gadget.setValue(outgaugeData[gauge.field]);
    });
});

// Generate and update gauges
var gaugeConfig = [
    {
        field: 'rpm',
        size: 300,
        units: 'rpm',
        max: 10000
    },
    {
        field: 'speedKPH',
        size: 300,
        units: 'km/h',
        max: 300
    },
    {
        field: 'clutch',
        size: 200,
        units: 'clutch',
        max: 1
    },
    {
        field: 'brake',
        size: 200,
        units: 'brake',
        max: 1
    },
    {
        field: 'throttle',
        size: 200,
        units: 'throttle',
        max: 1
    }
];

gaugeConfig.forEach(function(gauge){
    console.log(gauge);
    var ticks = [];
    var fixed = gauge.max > 1 ? 0 : 1;
    for(var i = 0; i <= 1; i += 0.2){
        ticks.push( (gauge.max * i).toFixed(fixed) );
    }
    var g = new Gauge({
        renderTo: gauge.field,
        width: gauge.size,
        height:gauge.size,
        maxValue: gauge.max,
        units: gauge.units,
        animation: false,
        highlights: false,
        glow: false,
        majorTicks: ticks,
        colors: {
            plate      : '#222',
            majorTicks : '#f5f5f5',
            minorTicks : '#ddd',
            title      : '#fff',
            units      : '#ccc',
            numbers    : '#eee',
            needle     : { start : 'rgba(240, 128, 128, 1)', end : 'rgba(255, 160, 122, .9)' }
        }
    });
    g.onready = function(){
        gauges.push({field: gauge.field, gadget: g});
    };
    g.draw();
});
<|endoftext|>


<commit_before>import React from 'react';

import CoreCombatLogParser from 'Parser/Core/CombatLogParser';

import SuggestionsTab from 'Main/SuggestionsTab';
import Tab from 'Main/Tab';
import Talents from 'Main/Talents';

import PainChart from './Modules/PainChart/Pain';

import AlwaysBeCasting from './Modules/Features/AlwaysBeCasting';
import CastEfficiency from './Modules/Features/CastEfficiency';
import SpiritBomb from './Modules/Features/SpiritBomb';

import DamageDone from './Modules/Statistics/Core/DamageDone';
import DamageTaken from './Modules/Statistics/Core/DamageTaken';
import HealingDone from './Modules/Statistics/Core/HealingDone';

import SoulFragments from './Modules/Statistics/SoulFragments/SoulFragments';

import ImmolationAura from './Modules/Statistics/Spells/ImmolationAura';
import DemonSpikes from './Modules/Statistics/Spells/DemonSpikes';
import EmpowerWards from './Modules/Statistics/Spells/EmpowerWards';
import SigilOfFlame from './Modules/Statistics/Spells/SigilOfFlame';

class CombatLogParser extends CoreCombatLogParser {
  static specModules = {
    // Core Statistics
    damageDone: DamageDone,
    damageTaken: DamageTaken,
    healingDone: HealingDone,

    // Features
    alwaysBeCasting: AlwaysBeCasting,
    castEfficiency: CastEfficiency,
    spiritBomb: SpiritBomb,

    // Soul Fragments
    soulFragments: SoulFragments,

    // Spell Statistics
    immolationAura: ImmolationAura,
    demonSpikes: DemonSpikes,
    empowerWards: EmpowerWards,
    sigilOfFlame: SigilOfFlame,
  };

  generateResults() {
    const results = super.generateResults();

    results.tabs = [
      {
        title: 'Suggestions',
        url: 'suggestions',
        render: () => (
          <SuggestionsTab issues={results.issues} />
        ),
      },
      {
        title: 'Talents',
        url: 'talents',
        render: () => (
          <Tab title="Talents">
            <Talents combatant={this.modules.combatants.selected} />
          </Tab>
        ),
      },
      {
        title: 'Pain Chart',
        url: 'pain',
        render: () => (
          <Tab title="Pain" style={{ padding: '15px 22px' }}>
            <PainChart
              reportCode={this.report.code}
              actorId={this.playerId}
              start={this.fight.start_time}
              end={this.fight.end_time}
            />
          </Tab>
        ),
      },
      ...results.tabs,
    ];

    return results;
  }
}

export default CombatLogParser;
<commit_msg>Changed the import path of spirit bomb<commit_after>import React from 'react';

import CoreCombatLogParser from 'Parser/Core/CombatLogParser';

import SuggestionsTab from 'Main/SuggestionsTab';
import Tab from 'Main/Tab';
import Talents from 'Main/Talents';

import PainChart from './Modules/PainChart/Pain';

import AlwaysBeCasting from './Modules/Features/AlwaysBeCasting';
import CastEfficiency from './Modules/Features/CastEfficiency';

import DamageDone from './Modules/Statistics/Core/DamageDone';
import DamageTaken from './Modules/Statistics/Core/DamageTaken';
import HealingDone from './Modules/Statistics/Core/HealingDone';

import SoulFragments from './Modules/Statistics/SoulFragments/SoulFragments';
import SpiritBomb from './Modules/Statistics/SpiritBomb/SpiritBomb';

import ImmolationAura from './Modules/Statistics/Spells/ImmolationAura';
import DemonSpikes from './Modules/Statistics/Spells/DemonSpikes';
import EmpowerWards from './Modules/Statistics/Spells/EmpowerWards';
import SigilOfFlame from './Modules/Statistics/Spells/SigilOfFlame';

class CombatLogParser extends CoreCombatLogParser {
  static specModules = {
    // Core Statistics
    damageDone: DamageDone,
    damageTaken: DamageTaken,
    healingDone: HealingDone,

    // Features
    alwaysBeCasting: AlwaysBeCasting,
    castEfficiency: CastEfficiency,
    spiritBomb: SpiritBomb,

    // Soul Fragments
    soulFragments: SoulFragments,

    // Spell Statistics
    immolationAura: ImmolationAura,
    demonSpikes: DemonSpikes,
    empowerWards: EmpowerWards,
    sigilOfFlame: SigilOfFlame,
  };

  generateResults() {
    const results = super.generateResults();

    results.tabs = [
      {
        title: 'Suggestions',
        url: 'suggestions',
        render: () => (
          <SuggestionsTab issues={results.issues} />
        ),
      },
      {
        title: 'Talents',
        url: 'talents',
        render: () => (
          <Tab title="Talents">
            <Talents combatant={this.modules.combatants.selected} />
          </Tab>
        ),
      },
      {
        title: 'Pain Chart',
        url: 'pain',
        render: () => (
          <Tab title="Pain" style={{ padding: '15px 22px' }}>
            <PainChart
              reportCode={this.report.code}
              actorId={this.playerId}
              start={this.fight.start_time}
              end={this.fight.end_time}
            />
          </Tab>
        ),
      },
      ...results.tabs,
    ];

    return results;
  }
}

export default CombatLogParser;
<|endoftext|>


<commit_before>(function () {
    var app = angular.module('mainApp', ['ngRoute', 'config', 'ngScrollbars', 'services', 'directives', 'chart.js', 'angularFileUpload']);
    app.controller('mainCtrl', ['$scope', 'restful', '$location', '$route', '$routeParams', '$interval', 'FileUploader', '$http', '$document', function ($scope, restful, $location, $route, $routeParams, $interval, FileUploader, $http, $document) {

        /*Append loading page druing data fetching*/
        var loadingPage = {
            ready: function () {
                angular.element('.loading .text').innerHTML = 'Fetching data...';
                var interval = $interval(function () {
                    if ($http.pendingRequests < 1) {
                        angular.element('.loading').addClass('hidden');
                        $document.find('body').css('overflow', 'auto');
                        $interval.cancel(interval);
                    }
                }, 1000);
            }
        };
        /*Hide it when content is loaded*/
        $scope.$on('$viewContentLoaded', function () {
            loadingPage.ready();
        });

        /*Change route to dashboard*/
        $scope.redirectToDash = function () {
            $location.path('/dashboard');
        };

        /*Limits for lists*/
        $scope.limit = {
            users: 5,
            group: 3,
            log: 5,
            components: 5
        };

        /*Menu elements*/
        $scope.menu = {
            status: true,
            hide: function () {
                this.status = !this.status;
            },
            active: function(url){
                if (url.indexOf(':siteID')===-1){
                    var arr = angular.element('#navigation a').removeClass('active-li');
                    for(var i=0;i<arr.length;i++){
                        if(arr[i].href.indexOf(url) !== -1)
                            var active = arr[i];
                    }
                    active.className+=' active-li';
                }
            }
        };

        /*Filter apps by params in a route*/
        $scope.filterParams = {
            manage: function () {
                if ($routeParams.siteID)
                    return parseInt($routeParams.siteID);
                else return '';
            }
        };
        /*Get data model*/
        var update = {
            me: function () {
                restful.get('me/user').then(function (response) {
                    $scope.current_user = response['objects'][0];
                });
            },
            apps: function () {
                restful.get('app').then(function (response) {
                    $scope.apps = response['objects'];
                });
            },
            users: function () {
                restful.get('user').then(function (response) {
                    $scope.users = response['objects'];
                });
            },
            groups: function () {
                restful.get('group').then(function (response) {
                    $scope.groups = response['objects'];
                });
            },
            logs: function () {
                restful.get('log').then(function (response) {
                    $scope.logs = response['objects'];
                });
            },
            notes: function () {
                restful.get('note').then(function (response) {
                    $scope.notes = response['objects'];
                });
            },
            components: function () {
                restful.get('component').then(function (response) {
                    $scope.components = response['objects'];
                });
            },
            all: function () {
                this.me();
                this.apps();
                this.users();
                this.groups();
                this.logs();
                this.notes();
                this.components();
            }
        };
        update.all();
        /*Dashboard clock*/
        $scope.clockDate = {
            setup: new Date(),
            time: function () {
                if (this.setup.getMinutes() < 10)
                    return this.setup.getHours() > 9 ? this.setup.getHours() + ':0' + this.setup.getMinutes() : '0' + this.setup.getHours() + ':0' + this.setup.getMinutes();
                else
                    return this.setup.getHours() > 9 ? this.setup.getHours() + ':' + this.setup.getMinutes() : '0' + this.setup.getHours() + ':' + this.setup.getMinutes();
            },
            date: function () {
                return this.setup.getTime();
            },
            update: function () {
                this.setup = new Date();
            }
        };

        /*Refresh clock every 30s*/
        $interval(function () {
            $scope.clockDate.update()
        }, 30000)

        /*Applications methods*/
        $scope.newlink = {
            uploader: new FileUploader({
                url: 'api/upload',
                formData: []
            }),
            name: '',
            address: '',
            desc: '',
            img_link: '',
            order_id: '',
            beta: null,
            manageFill: function (name, link, desc, img_link, order_id, beta) {
                this.name = name;
                this.address = link;
                this.desc = desc;
                this.img_link = img_link;
                this.order_id = order_id;
                this.beta = beta;
            },
            add: function () {
                var img_link = $scope.clockDate.date();
                this.uploader.onBeforeUploadItem = function (item) {
                    item.formData.push({
                        filename: img_link
                    });
                }
                this.uploader.uploadItem(0);
                this.uploader.onSuccessItem = (item, response, status, headers)=> {
                    var post_object = {
                        name: this.name,
                        link: this.address,
                        desc: this.desc,
                        creator_id: $scope.current_user.id,
                        img_link: img_link,
                    }
                    restful.post('app', post_object).then(function () {
                        update.apps();
                    });
                    this.clear();
                    this.status = true;
                    this.uploader.clearQueue();
                };
                 this.uploader.onErrorItem = function(item, response, status, headers) {
                    console.log('Uplaoder: Error callback');
                    console.log(item);
                    console.log(response);
                    console.log(headers);
                };

                this.uploader.onCancelItem = function(item, response, status, headers) {
                    console.log('Uploader: Cancel callback');
                    console.log(item);
                    console.log(response);
                    console.log(headers);
                };

            },
            update: function (app_id) {
                if (this.uploader.queue.length > 0) {
                    this.img_link = $scope.clockDate.date();
                }
                var img_link = this.img_link;
                this.uploader.onBeforeUploadItem = function (item) {
                    item.formData.push({
                        filename: img_link
                    });
                }
                this.uploader.uploadItem(0);
                this.uploader.onSuccessItem = (item, response, status, headers)=> {
                    var post_object = {
                        name: this.name,
                        link: this.address,
                        desc: this.desc,
                        img_link: img_link,
                        order_id: this.order_id,
                        beta: this.beta,
                    }
                    restful.update('app', app_id, post_object).then(function () {
                        var log_object = {
                            content: 'A link #' + app_id + ' was updated',
                            author_id: $scope.current_user.id
                        }
                        update.apps();
                        restful.post('log', log_object).then(function(){
                            update.logs();
                        });
                    });
                    this.clear();
                    this.status = true;
                    this.uploader.clearQueue();
                    $location.path('/links').replace();
                };
                this.uploader.onErrorItem = function(item, response, status, headers) {
                    //Add information for img uplaod error in DOM (html)
                    console.log('Uplaoder: Error callback');
                    console.log(item);
                    console.log(response);
                    console.log(headers);
                };
                this.uploader.onCancelItem = function(item, response, status, headers) {
                    //Add information for img uplaod error in DOM (html)
                    console.log('Uploader: Cancel callback');
                    console.log(item);
                    console.log(response);
                    console.log(headers);
                };
            },
            hide: function (app_id, app_status) {
                var confirmResult = confirm("Do you want to change visibility of this app?");
                if (confirmResult) {
                    var hide = {
                        status: !app_status
                    }
                    restful.update('app', app_id, hide).then(function () {
                        var log_object = {
                            content: 'A link #' + app_id + ' was updated',
                            author_id: $scope.current_user.id
                        }
                        update.apps();
                        restful.post('log', log_object).then(function(){
                            update.logs();
                        });
                    });
                }
            },

            delete: function (app_id) {
                var confirmResult = confirm("Do you want to remove this app?");
                if (confirmResult) {
                    restful.delete("app", app_id).then(function () {
                        var log_object = {
                            content: 'A link #' + app_id + ' was removed',
                            author_id: $scope.current_user.id
                        }
                        update.apps();
                        restful.post('log', log_object).then(function(){
                            update.logs();
                        });
                    });
                }
            },
            clear: function () {
                this.name = '';
                this.address = '';
                this.desc = '';
            },
            status: false
        };

        $scope.note = {
            content: '',
            tag: '',
            add: function () {
                var post_note = {
                    content: this.content,
                    tag: this.tag,
                    owner_id: $scope.current_user.id,
                }
                restful.post('note', post_note).then(function () {
                    update.notes();
                });
                this.clear();
            },
            clear: function () {
                this.content = '';
                this.tag = '';
            }
        };

        $scope.orderArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
        /*
        If you use some variables in a couple places you probably
        want to reset them when you leave a page. That's why you should put
        those variables/functions below.
        */
        $scope.$on('$routeChangeStart', function (current, next) {
            $scope.newlink.clear();
            $scope.newlink.status = false;
            $scope.searchBy = '';
            $scope.menu.active(next.originalPath);

        });

        /*Popup model functions*/
        $scope.popup = {
            edit: {
                close: function () {
                    $location.path('/links').replace();
                }
            }
        };
        /*Some elements should change with resolution so it's nice to include them*/
        var bootstrap_resolution = {
            resl: document.body.innerWidth,
            onchange: function () {}
            //1200
            //768
            //480
            //320
        };

        /*Stats chart settings and data*/

        $scope.stats = {
            users: {
                labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
                series: ['Number of users'],
                data: [[3, 7, 2, 10, 6]]
            },
            invitations: {
                labels: ['Accepted', 'Unaccepted'],
                data: [17, 5]
            },
            apps: {
                labels: ['Yesterday', 'Today'],
                series: ['Registered', 'Beta'],
                data: [
                    [65, 59],
                    [28, 48]
                  ]
            },
            components: {
                labels: ['Usage'],
                series: ['Iframe', 'JSON', 'Polymer'],
                data: [
                    [17],
                    [3],
                    [7]
                  ]
            }
        }
        $scope.datasetOverride = [{
            yAxisID: 'y-axis-1'
        }, {
            yAxisID: 'y-axis-2'
            }];
        $scope.options = {
            scales: {
                yAxes: [
                    {
                        id: 'y-axis-1',
                        type: 'linear',
                        display: true,
                        position: 'left'
                    }
                        ]
            }
        };

        /*Custom Scrollbar Config*/
        $scope.config = {
            autoHideScrollbar: true,
            theme: 'minimal',
            advanced: {
                updateOnContentResize: true
            },
            scrollInertia: 0,
            axis: 'y'
        };
    }]);

}());
<commit_msg>Fix uploader<commit_after>(function () {
    var app = angular.module('mainApp', ['ngRoute', 'config', 'ngScrollbars', 'services', 'directives', 'chart.js', 'angularFileUpload']);
    app.controller('mainCtrl', ['$scope', 'restful', '$location', '$route', '$routeParams', '$interval', 'FileUploader', '$http', '$document', function ($scope, restful, $location, $route, $routeParams, $interval, FileUploader, $http, $document) {

        /*Append loading page druing data fetching*/
        var loadingPage = {
            ready: function () {
                angular.element('.loading .text').innerHTML = 'Fetching data...';
                var interval = $interval(function () {
                    if ($http.pendingRequests < 1) {
                        angular.element('.loading').addClass('hidden');
                        $document.find('body').css('overflow', 'auto');
                        $interval.cancel(interval);
                    }
                }, 1000);
            }
        };
        /*Hide it when content is loaded*/
        $scope.$on('$viewContentLoaded', function () {
            loadingPage.ready();
        });

        /*Change route to dashboard*/
        $scope.redirectToDash = function () {
            $location.path('/dashboard');
        };

        /*Limits for lists*/
        $scope.limit = {
            users: 5,
            group: 3,
            log: 5,
            components: 5
        };

        /*Menu elements*/
        $scope.menu = {
            status: true,
            hide: function () {
                this.status = !this.status;
            },
            active: function (url) {
                if (url.indexOf(':siteID') === -1) {
                    var arr = angular.element('#navigation a').removeClass('active-li');
                    for (var i = 0; i < arr.length; i++) {
                        if (arr[i].href.indexOf(url) !== -1)
                            var active = arr[i];
                    }
                    active.className += ' active-li';
                }
            }
        };

        /*Filter apps by params in a route*/
        $scope.filterParams = {
            manage: function () {
                if ($routeParams.siteID)
                    return parseInt($routeParams.siteID);
                else return '';
            }
        };
        /*Get data model*/
        var update = {
            me: function () {
                restful.get('me/user').then(function (response) {
                    $scope.current_user = response['objects'][0];
                });
            },
            apps: function () {
                restful.get('app').then(function (response) {
                    $scope.apps = response['objects'];
                });
            },
            users: function () {
                restful.get('user').then(function (response) {
                    $scope.users = response['objects'];
                });
            },
            groups: function () {
                restful.get('group').then(function (response) {
                    $scope.groups = response['objects'];
                });
            },
            logs: function () {
                restful.get('log').then(function (response) {
                    $scope.logs = response['objects'];
                });
            },
            notes: function () {
                restful.get('note').then(function (response) {
                    $scope.notes = response['objects'];
                });
            },
            components: function () {
                restful.get('component').then(function (response) {
                    $scope.components = response['objects'];
                });
            },
            all: function () {
                this.me();
                this.apps();
                this.users();
                this.groups();
                this.logs();
                this.notes();
                this.components();
            }
        };
        update.all();
        /*Dashboard clock*/
        $scope.clockDate = {
            setup: new Date(),
            time: function () {
                if (this.setup.getMinutes() < 10)
                    return this.setup.getHours() > 9 ? this.setup.getHours() + ':0' + this.setup.getMinutes() : '0' + this.setup.getHours() + ':0' + this.setup.getMinutes();
                else
                    return this.setup.getHours() > 9 ? this.setup.getHours() + ':' + this.setup.getMinutes() : '0' + this.setup.getHours() + ':' + this.setup.getMinutes();
            },
            date: function () {
                return this.setup.getTime();
            },
            update: function () {
                this.setup = new Date();
            }
        };

        /*Refresh clock every 30s*/
        $interval(function () {
            $scope.clockDate.update()
        }, 30000)

        /*Applications methods*/
        $scope.newlink = {
            uploader: new FileUploader({
                url: 'api/upload',
                formData: []
            }),
            name: '',
            address: '',
            desc: '',
            img_link: '',
            order_id: '',
            beta: null,
            manageFill: function (name, link, desc, img_link, order_id, beta) {
                this.name = name;
                this.address = link;
                this.desc = desc;
                this.img_link = img_link;
                this.order_id = order_id;
                this.beta = beta;
            },
            add: function () {
                var img_link = $scope.clockDate.date();
                this.uploader.onBeforeUploadItem = function (item) {
                    item.formData.push({
                        filename: img_link
                    });
                }
                this.uploader.uploadItem(0);
                this.uploader.onSuccessItem = (item, response, status, headers) => {
                    var post_object = {
                        name: this.name,
                        link: this.address,
                        desc: this.desc,
                        creator_id: $scope.current_user.id,
                        img_link: img_link,
                    }
                    restful.post('app', post_object).then(function () {
                        update.apps();
                    });
                    this.clear();
                    this.status = true;
                    this.uploader.clearQueue();
                };
                this.uploader.onErrorItem = function (item, response, status, headers) {
                    console.log('Uplaoder: Error callback');
                    console.log(item);
                    console.log(response);
                    console.log(headers);
                };

                this.uploader.onCancelItem = function (item, response, status, headers) {
                    console.log('Uploader: Cancel callback');
                    console.log(item);
                    console.log(response);
                    console.log(headers);
                };

            },
            update: function (app_id) {
                var img_link = this.img_link;
                if (this.uploader.queue.length > 0) {
                    img_link = this.img_link = $scope.clockDate.date();
                    this.uploader.onBeforeUploadItem = function (item) {
                        item.formData.push({
                            filename: img_link
                        });
                    }
                    this.uploader.uploadItem(0);
                    this.uploader.clearQueue();
                    this.uploader.onErrorItem = function (item, response, status, headers) {
                        //Add information for img uplaod error in DOM (html)
                        console.log('Uplaoder: Error callback');
                        console.log(item);
                        console.log(response);
                        console.log(headers);
                    };
                    this.uploader.onCancelItem = function (item, response, status, headers) {
                        //Add information for img uplaod error in DOM (html)
                        console.log('Uploader: Cancel callback');
                        console.log(item);
                        console.log(response);
                        console.log(headers);
                    };
                }
                var post_object = {
                    name: this.name,
                    link: this.address,
                    desc: this.desc,
                    img_link: img_link,
                    order_id: this.order_id,
                    beta: this.beta,
                }
                restful.update('app', app_id, post_object).then(function () {
                    var log_object = {
                        content: 'A link #' + app_id + ' was updated',
                        author_id: $scope.current_user.id
                    }
                    update.apps();
                    restful.post('log', log_object).then(function () {
                        update.logs();
                    });
                });
                this.clear();
                this.status = true;

                $location.path('/links').replace();
            },
            hide: function (app_id, app_status) {
                var confirmResult = confirm("Do you want to change visibility of this app?");
                if (confirmResult) {
                    var hide = {
                        status: !app_status
                    }
                    restful.update('app', app_id, hide).then(function () {
                        var log_object = {
                            content: 'A link #' + app_id + ' was updated',
                            author_id: $scope.current_user.id
                        }
                        update.apps();
                        restful.post('log', log_object).then(function () {
                            update.logs();
                        });
                    });
                }
            },

            delete: function (app_id) {
                var confirmResult = confirm("Do you want to remove this app?");
                if (confirmResult) {
                    restful.delete("app", app_id).then(function () {
                        var log_object = {
                            content: 'A link #' + app_id + ' was removed',
                            author_id: $scope.current_user.id
                        }
                        update.apps();
                        restful.post('log', log_object).then(function () {
                            update.logs();
                        });
                    });
                }
            },
            clear: function () {
                this.name = '';
                this.address = '';
                this.desc = '';
            },
            status: false
        };

        $scope.note = {
            content: '',
            tag: '',
            add: function () {
                var post_note = {
                    content: this.content,
                    tag: this.tag,
                    owner_id: $scope.current_user.id,
                }
                restful.post('note', post_note).then(function () {
                    update.notes();
                });
                this.clear();
            },
            clear: function () {
                this.content = '';
                this.tag = '';
            }
        };

        $scope.orderArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
        /*
        If you use some variables in a couple places you probably
        want to reset them when you leave a page. That's why you should put
        those variables/functions below.
        */
        $scope.$on('$routeChangeStart', function (current, next) {
            $scope.newlink.clear();
            $scope.newlink.status = false;
            $scope.searchBy = '';
            $scope.menu.active(next.originalPath);

        });

        /*Popup model functions*/
        $scope.popup = {
            edit: {
                close: function () {
                    $location.path('/links').replace();
                }
            }
        };
        /*Some elements should change with resolution so it's nice to include them*/
        var bootstrap_resolution = {
            resl: document.body.innerWidth,
            onchange: function () {}
            //1200
            //768
            //480
            //320
        };

        /*Stats chart settings and data*/

        $scope.stats = {
            users: {
                labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
                series: ['Number of users'],
                data: [[3, 7, 2, 10, 6]]
            },
            invitations: {
                labels: ['Accepted', 'Unaccepted'],
                data: [17, 5]
            },
            apps: {
                labels: ['Yesterday', 'Today'],
                series: ['Registered', 'Beta'],
                data: [
                    [65, 59],
                    [28, 48]
                  ]
            },
            components: {
                labels: ['Usage'],
                series: ['Iframe', 'JSON', 'Polymer'],
                data: [
                    [17],
                    [3],
                    [7]
                  ]
            }
        }
        $scope.datasetOverride = [{
            yAxisID: 'y-axis-1'
        }, {
            yAxisID: 'y-axis-2'
            }];
        $scope.options = {
            scales: {
                yAxes: [
                    {
                        id: 'y-axis-1',
                        type: 'linear',
                        display: true,
                        position: 'left'
                    }
                        ]
            }
        };

        /*Custom Scrollbar Config*/
        $scope.config = {
            autoHideScrollbar: true,
            theme: 'minimal',
            advanced: {
                updateOnContentResize: true
            },
            scrollInertia: 0,
            axis: 'y'
        };
    }]);

}());
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */
'use strict';
import {LitElement, html} from 'https://unpkg.com/@polymer/lit-element@0.6.2?module';

class ScreenSharing extends LitElement {
  constructor() {
    super();
    this.downloadUrl = null;
    this.enableStartCapture = true;
    this.enableStopCapture = false;
    this.enableDownloadRecording = false;
    this.stream = null;
    this.recording = [];
    this.mediaRecorder = null;
  }

  static get properties() {
    return {
      enableStartCapture: Boolean,
      enableStopCapture: Boolean,
      enableDownloadRecording: Boolean,
      stream: {
        type: {
          fromAttribute: input => input
        }
      }
    };
  }

  render() {
    return html`
<video playsinline autoplay muted .srcObject="${this.stream}"></video>

<button ?disabled="${!this.enableStartCapture}" @click="${e => this._startCapturing(e)}">Start screen capture</button>
<button ?disabled="${!this.enableStopCapture}" @click="${e => this._stopCapturing(e)}">Stop screen capture</button>
<button ?disabled="${!this.enableDownloadRecording}" @click="${e => this._downloadRecording(e)}">Download recording</button>

`;
  }

  static _startScreenCapture() {
    if (navigator.getDisplayMedia) {
      return navigator.getDisplayMedia({video: true});
    } else {
      return navigator.mediaDevices.getUserMedia({video: {mediaSource: 'screen'}});
    }
  }

  async _startCapturing(e) {
    console.log('Start capturing.');
    this.enableStartCapture = false;
    this.enableStopCapture = true;
    this.enableDownloadRecording = false;
    this.requestUpdate('buttons');

    if (this.downloadUrl) {
      window.URL.revokeObjectURL(this.downloadUrl);
    }

    this.recording = [];
    this.stream = await ScreenSharing._startScreenCapture();
    this.stream.addEventListener('inactive', e => {
      console.log('Capture stream inactive - stop recording!');
      this.enableStartCapture = false;
      this.enableStopCapture = false;
      this.enableDownloadRecording = true;

      this.mediaRecorder.stop();
      this.mediaRecorder = null;
      this.stream.getTracks().forEach(track => track.stop());
      this.stream = null;
    });
    this.mediaRecorder = new MediaRecorder(this.stream, {mimeType: 'video/webm'});
    this.mediaRecorder.addEventListener('dataavailable', event => {
      if (event.data && event.data.size > 0) {
        this.recording.push(event.data);
      }
    });
    this.mediaRecorder.start(10);
  }

  _stopCapturing(e) {
    console.log('Stop capturing.');
    this.enableStartCapture = false;
    this.enableStopCapture = false;
    this.enableDownloadRecording = true;

    this.mediaRecorder.stop();
    this.mediaRecorder = null;
    this.stream.getTracks().forEach(track => track.stop());
    this.stream = null;
  }

  _downloadRecording(e) {
    console.log('Download recording.');
    this.enableStartCapture = true;
    this.enableStopCapture = false;
    this.enableDownloadRecording = false;

    const blob = new Blob(this.recording, {type: 'video/webm'});
    this.downloadUrl = window.URL.createObjectURL(blob);
    const downloadLink = this.shadowRoot.querySelector('a#downloadLink');
    downloadLink.href = this.downloadUrl;
    downloadLink.download = 'screen-recording.webm';
    downloadLink.click();
  }
}

customElements.define('screen-sharing', ScreenSharing);
<commit_msg>Rename CSS var<commit_after>/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */
'use strict';
import {LitElement, html} from 'https://unpkg.com/@polymer/lit-element@0.6.2?module';

class ScreenSharing extends LitElement {
  constructor() {
    super();
    this.downloadUrl = null;
    this.enableStartCapture = true;
    this.enableStopCapture = false;
    this.enableDownloadRecording = false;
    this.stream = null;
    this.recording = [];
    this.mediaRecorder = null;
  }

  static get properties() {
    return {
      enableStartCapture: Boolean,
      enableStopCapture: Boolean,
      enableDownloadRecording: Boolean,
      stream: {
        type: {
          fromAttribute: input => input
        }
      }
    };
  }

  render() {
    return html`
<video playsinline autoplay muted .srcObject="${this.stream}"></video>

<button ?disabled="${!this.enableStartCapture}" @click="${e => this._startCapturing(e)}">Start screen capture</button>
<button ?disabled="${!this.enableStopCapture}" @click="${e => this._stopCapturing(e)}">Stop screen capture</button>
<button ?disabled="${!this.enableDownloadRecording}" @click="${e => this._downloadRecording(e)}">Download recording</button>

`;
  }

  static _startScreenCapture() {
    if (navigator.getDisplayMedia) {
      return navigator.getDisplayMedia({video: true});
    } else {
      return navigator.mediaDevices.getUserMedia({video: {mediaSource: 'screen'}});
    }
  }

  async _startCapturing(e) {
    console.log('Start capturing.');
    this.enableStartCapture = false;
    this.enableStopCapture = true;
    this.enableDownloadRecording = false;
    this.requestUpdate('buttons');

    if (this.downloadUrl) {
      window.URL.revokeObjectURL(this.downloadUrl);
    }

    this.recording = [];
    this.stream = await ScreenSharing._startScreenCapture();
    this.stream.addEventListener('inactive', e => {
      console.log('Capture stream inactive - stop recording!');
      this.enableStartCapture = false;
      this.enableStopCapture = false;
      this.enableDownloadRecording = true;

      this.mediaRecorder.stop();
      this.mediaRecorder = null;
      this.stream.getTracks().forEach(track => track.stop());
      this.stream = null;
    });
    this.mediaRecorder = new MediaRecorder(this.stream, {mimeType: 'video/webm'});
    this.mediaRecorder.addEventListener('dataavailable', event => {
      if (event.data && event.data.size > 0) {
        this.recording.push(event.data);
      }
    });
    this.mediaRecorder.start(10);
  }

  _stopCapturing(e) {
    console.log('Stop capturing.');
    this.enableStartCapture = false;
    this.enableStopCapture = false;
    this.enableDownloadRecording = true;

    this.mediaRecorder.stop();
    this.mediaRecorder = null;
    this.stream.getTracks().forEach(track => track.stop());
    this.stream = null;
  }

  _downloadRecording(e) {
    console.log('Download recording.');
    this.enableStartCapture = true;
    this.enableStopCapture = false;
    this.enableDownloadRecording = false;

    const blob = new Blob(this.recording, {type: 'video/webm'});
    this.downloadUrl = window.URL.createObjectURL(blob);
    const downloadLink = this.shadowRoot.querySelector('a#downloadLink');
    downloadLink.href = this.downloadUrl;
    downloadLink.download = 'screen-recording.webm';
    downloadLink.click();
  }
}

customElements.define('screen-sharing', ScreenSharing);
<|endoftext|>


<commit_before>import update from 'immutability-helper';

const initialState = {
  tool: null,

  mapType: 'T',
  center: {
    lat: 48.70714,
    lon: 19.4995
  },
  zoom: 8,
  overlays: []
};

export default function map(state = initialState, action) {
  switch (action.type) {
    case 'SET_TOOL':
      return update(state, { tool: { $set: action.tool === state.tool ? null : action.tool } } );
    case 'RESET_MAP':
      return update(state, {
        tool: { $set: initialState.tool },
        zoom: { $set: initialState.zoom },
        center: {
          lat : { $set: initialState.center.lat },
          lon : { $set: initialState.center.lon }
        },
      });
    case 'SET_MAP_BOUNDS':
      return update(state, { bounds: { $set: action.bounds } } );
    case 'SET_MAP_TYPE':
      return update(state, { mapType: { $set: action.mapType } } );
    case 'SET_MAP_OVERLAYS':
      return update(state, { overlays: { $set: action.overlays } } );
    case 'REFOCUS':
      return update(state, {
        zoom: { $set: action.zoom },
        center: {
          lat : { $set: action.lat },
          lon : { $set: action.lon }
        },
      });
    case 'RESTORE_FROM_URL_PARAMS': {
      const overlays = action.params.mapType && action.params.mapType.substring(1).split('') || [];
      return update(state, {
        mapType: { $set: action.params.mapType.charAt(0) },
        zoom: { $set: parseInt(action.params.zoom) },
        center: {
          lat : { $set: parseFloat(action.params.lat) },
          lon : { $set: parseFloat(action.params.lon) }
        },
        overlays: { $set: overlays }
      });
    }
    default:
      return state;
  }
}
<commit_msg>refactor: simplify reset map<commit_after>import update from 'immutability-helper';

const initialState = {
  tool: null,

  mapType: 'T',
  center: {
    lat: 48.70714,
    lon: 19.4995
  },
  zoom: 8,
  overlays: []
};

export default function map(state = initialState, action) {
  switch (action.type) {
    case 'SET_TOOL':
      return update(state, { tool: { $set: action.tool === state.tool ? null : action.tool } } );
    case 'RESET_MAP':
      return update(state, {
        tool: { $set: initialState.tool },
        zoom: { $set: initialState.zoom },
        center: { $set: initialState.center },
      });
    case 'SET_MAP_BOUNDS':
      return update(state, { bounds: { $set: action.bounds } } );
    case 'SET_MAP_TYPE':
      return update(state, { mapType: { $set: action.mapType } } );
    case 'SET_MAP_OVERLAYS':
      return update(state, { overlays: { $set: action.overlays } } );
    case 'REFOCUS':
      return update(state, {
        zoom: { $set: action.zoom },
        center: {
          lat : { $set: action.lat },
          lon : { $set: action.lon }
        },
      });
    case 'RESTORE_FROM_URL_PARAMS': {
      const overlays = action.params.mapType && action.params.mapType.substring(1).split('') || [];
      return update(state, {
        mapType: { $set: action.params.mapType.charAt(0) },
        zoom: { $set: parseInt(action.params.zoom) },
        center: {
          lat : { $set: parseFloat(action.params.lat) },
          lon : { $set: parseFloat(action.params.lon) }
        },
        overlays: { $set: overlays }
      });
    }
    default:
      return state;
  }
}
<|endoftext|>


<commit_before>(function ($) {
  "use strict";

  var getQueryParams, showErrorMessages, checkLoginStatus, checkSites, removeSite;

  getQueryParams = function () {
    var params = {};
    $.each(window.location.search.substr(1).split('&'), function (key, value) {
      value = value.split('=');
      params[value[0]] = value[1] || true;
    });
    return params;
  };

  showErrorMessages = function () {
    var queryParams = getQueryParams(),
      message,
      $error = $('#main .error');

    switch (queryParams['error']) {
      case 'login':
        message = 'Login failed';
        break;
      case 'sites':
        message = 'Failed to add domain';
        break;
    }

    if (message) {
      if (!$error.length) {
        $error = $('<div />').text(message).addClass('error').wrapInner('<p />').prepend($('<h2 />').text('Error')).prependTo('#main');
      }
      $error.text();
    } else {
      $error.remove();
    }
  };

  checkLoginStatus = function () {
    $.getJSON('/user/status', function (data) {
      if (data.version) {
        $('<span />').text('. ').prependTo('body > address');
        $('<a />').attr({
          href: 'https://github.com/voxpelli/webpage-webmentions/releases/tag/v' + encodeURIComponent(data.version),
          target: '_blank'
        }).text(data.version).prependTo('body > address');
        $('<span />').text('Version ').prependTo('body > address');
      }
      if (data.loggedin) {
        $('.receive li.first-step ul').replaceWith($('<p />').text('Done! ').append($('<a />', {
          href : '/user/logout',
          text : 'Log out?'
        })))
        checkSites();
      } else {
        if (data.accountsAvailable !== undefined) {
          $('<p />', {
            "class": "accounts-available",
            text : '(' + data.accountsAvailable + ' accounts left at the moment)'
          }).insertAfter('.receive li.first-step > ul');
        }
        $('.receive li.second-step form').remove();
        if (data.dev) {
          $('<a />', {
            href : '/user/auth/dummy',
            text : "Since you're in a dev environment you can bypass online sign ins here!"
          }).appendTo('.receive li.first-step ul').wrap('<li />');
        }
      }
    });
  };

  checkSites = function () {
    $.getJSON('/user/sites', function (data) {
      var $list = $('<ul />');
      $.each(data.sites, function (i, value) {
        var $listItem = $('<li />').text(value + ' ');
        $('<button />').attr('type', 'button').text('Remove').appendTo($listItem).click(function (e) {
          removeSite.call(this, value);
        });
        $listItem.appendTo($list);
      });
      $list.insertBefore('.receive li.second-step form');
    });
  };

  removeSite = function (site) {
    var $this = $(this).text('Removing...');
    $.post('/user/sites', {
      action : 'delete',
      hostname : site
    }, function () {
      $this.parent().slideUp(function () {
        $this.remove();
      });
    }, 'json');
  };

  showErrorMessages();
  checkLoginStatus();

  $('textarea').on('mouseup', function () {
      $(this).select();
  }).each(function () {
    var $this = $(this)
      , text = $this.val();
    text = text.replace('"http://example.com', '"' + window.location.protocol + '//' + window.location.host);
    text = text.replace('//example.com', '//' + window.location.host);
    $this.val(text);
  });
}($));
<commit_msg>Including mention count and link to export in list<commit_after>(function ($) {
  "use strict";

  var getQueryParams, showErrorMessages, checkLoginStatus, checkSites, removeSite;

  getQueryParams = function () {
    var params = {};
    $.each(window.location.search.substr(1).split('&'), function (key, value) {
      value = value.split('=');
      params[value[0]] = value[1] || true;
    });
    return params;
  };

  showErrorMessages = function () {
    var queryParams = getQueryParams(),
      message,
      $error = $('#main .error');

    switch (queryParams['error']) {
      case 'login':
        message = 'Login failed';
        break;
      case 'sites':
        message = 'Failed to add domain';
        break;
    }

    if (message) {
      if (!$error.length) {
        $error = $('<div />').text(message).addClass('error').wrapInner('<p />').prepend($('<h2 />').text('Error')).prependTo('#main');
      }
      $error.text();
    } else {
      $error.remove();
    }
  };

  checkLoginStatus = function () {
    $.getJSON('/user/status', function (data) {
      if (data.version) {
        $('<span />').text('. ').prependTo('body > address');
        $('<a />').attr({
          href: 'https://github.com/voxpelli/webpage-webmentions/releases/tag/v' + encodeURIComponent(data.version),
          target: '_blank'
        }).text(data.version).prependTo('body > address');
        $('<span />').text('Version ').prependTo('body > address');
      }
      if (data.loggedin) {
        $('.receive li.first-step ul').replaceWith($('<p />').text('Done! ').append($('<a />', {
          href : '/user/logout',
          text : 'Log out?'
        })))
        checkSites();
      } else {
        if (data.accountsAvailable !== undefined) {
          $('<p />', {
            "class": "accounts-available",
            text : '(' + data.accountsAvailable + ' accounts left at the moment)'
          }).insertAfter('.receive li.first-step > ul');
        }
        $('.receive li.second-step form').remove();
        if (data.dev) {
          $('<a />', {
            href : '/user/auth/dummy',
            text : "Since you're in a dev environment you can bypass online sign ins here!"
          }).appendTo('.receive li.first-step ul').wrap('<li />');
        }
      }
    });
  };

  checkSites = function () {
    $.getJSON('/user/sites', function (data) {
      var $list = $('<ul />');
      $.each(data.sites, function (i, value) {
        var $listItem = $('<li />').text(', mentioned ' + value.mentions + ' times. ').prepend($('<strong />').text(value.hostname));
        $('<a />').attr('href', '/user/sites/' + encodeURIComponent(value.hostname)).text('Export all mentions').appendTo($listItem);
        $listItem.append(' ');
        $('<button />').attr('type', 'button').text('Remove site').appendTo($listItem).click(function (e) {
          removeSite.call(this, value.hostname);
        });
        $listItem.appendTo($list);
      });
      $list.insertBefore('.receive li.second-step form');
    });
  };

  removeSite = function (site) {
    var $this = $(this).text('Removing...');
    $.post('/user/sites', {
      action : 'delete',
      hostname : site
    }, function () {
      $this.parent().slideUp(function () {
        $this.remove();
      });
    }, 'json');
  };

  showErrorMessages();
  checkLoginStatus();

  $('textarea').on('mouseup', function () {
      $(this).select();
  }).each(function () {
    var $this = $(this)
      , text = $this.val();
    text = text.replace('"http://example.com', '"' + window.location.protocol + '//' + window.location.host);
    text = text.replace('//example.com', '//' + window.location.host);
    $this.val(text);
  });
}($));
<|endoftext|>


<commit_before>import { List } from 'immutable';

const initialState = new List([null, null, null, null, null, null, null]);

export default function boardReducer(state = initialState, action) {
  return state;
}
<commit_msg>Add logic that adds cards to the board<commit_after>import { List } from 'immutable';
import { PLAY_CARD } from './hand';

const MAX_CARDS_ON_BOARD = 7;
const initialState = new List([null, null, null, null, null, null, null]);

// FIX ME: Ugly ass function...
function findPlaceToAddCard(list) {
  for (let i = 0; i < MAX_CARDS_ON_BOARD; i++) {
    if (list.get(i) === null) {
      return i;
    }
  }
  return undefined;
}

export default function boardReducer(state = initialState, action) {
  switch (action.type) {
    case PLAY_CARD:
      // FIX ME: Ugly ass way of doing this...
      const freeIndex = findPlaceToAddCard(state);
      if (freeIndex !== undefined) {
        return state.set(freeIndex, action.card);
      } else {
        return state;
      }
    default:
      return state;
  }
}
<|endoftext|>


<commit_before>// extra settings for Vue components

module.exports = {
  extends: [
    '@wearegenki/eslint-config',
  ],
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
  },
  env: {
    browser: true,
  },
};
<commit_msg>Minor comment change<commit_after>// extra settings for Marko components

module.exports = {
  extends: [
    '@wearegenki/eslint-config',
  ],
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
  },
  env: {
    browser: true,
  },
};
<|endoftext|>


<commit_before>var childProcess = require('child_process');
var fs = require('fs-extra');
var glob = require('glob');
var path = require('path');
var sortPackageJson = require('sort-package-json');

/**
 * Update the dependencies of the package.
 */
function updateDependencies(data) {
  // Handle all of the packages.
  var basePath = path.resolve('..');
  var files = glob.sync(path.join(basePath, 'packages/*'));
  for (var j = 0; j < files.length; j++) {
    handlePackage(files[j], data);
  }
}

/**
 * Handle an individual package on the path - get its dependencies.
 */
function handlePackage(packagePath, data) {
  // Read in the package.json.
  var packagePath = path.join(packagePath, 'package.json');
  try {
    var package = require(packagePath);
  } catch (e) {
    console.log('Skipping package ' + packagePath);
    return;
  }

  var deps = package.dependencies || [];
  for (let dep in deps) {
    data.dependencies[dep] = deps[dep];
  }
}

// Get the current version of JupyterLab
var cwd = path.resolve('..');
var version = childProcess.execSync('python setup.py --version', { cwd: cwd });
version = version.toString().trim();

// Update our package.json files.
var data = require('./package.json');
data['jupyterlab']['version'] = version;

// Update our package.json files.
updateDependencies(data);
var text = JSON.stringify(sortPackageJson(data), null, 2) + '\n';
fs.writeFileSync('./package.json', text);
fs.writeFileSync('./package.app.json', text);

// Update our app index file.
fs.copySync('./index.js', './index.app.js')

// Run a standard build.
childProcess.execSync('npm run build');

// Add  the release metadata.
var release_data = { version: version };
text = JSON.stringify(release_data, null, 2) + '\n';
fs.writeFileSync('./build/release_data.json', text);
<commit_msg>change a let to a var<commit_after>var childProcess = require('child_process');
var fs = require('fs-extra');
var glob = require('glob');
var path = require('path');
var sortPackageJson = require('sort-package-json');

/**
 * Update the dependencies of the package.
 */
function updateDependencies(data) {
  // Handle all of the packages.
  var basePath = path.resolve('..');
  var files = glob.sync(path.join(basePath, 'packages/*'));
  for (var j = 0; j < files.length; j++) {
    handlePackage(files[j], data);
  }
}

/**
 * Handle an individual package on the path - get its dependencies.
 */
function handlePackage(packagePath, data) {
  // Read in the package.json.
  var packagePath = path.join(packagePath, 'package.json');
  try {
    var package = require(packagePath);
  } catch (e) {
    console.log('Skipping package ' + packagePath);
    return;
  }

  var deps = package.dependencies || [];
  for (var dep in deps) {
    data.dependencies[dep] = deps[dep];
  }
}

// Get the current version of JupyterLab
var cwd = path.resolve('..');
var version = childProcess.execSync('python setup.py --version', { cwd: cwd });
version = version.toString().trim();

// Update our package.json files.
var data = require('./package.json');
data['jupyterlab']['version'] = version;

// Update our package.json files.
updateDependencies(data);
var text = JSON.stringify(sortPackageJson(data), null, 2) + '\n';
fs.writeFileSync('./package.json', text);
fs.writeFileSync('./package.app.json', text);

// Update our app index file.
fs.copySync('./index.js', './index.app.js')

// Run a standard build.
childProcess.execSync('npm run build');

// Add  the release metadata.
var release_data = { version: version };
text = JSON.stringify(release_data, null, 2) + '\n';
fs.writeFileSync('./build/release_data.json', text);
<|endoftext|>


<commit_before>var request = require('request')
	, fs = require('fs-extra')
	, turf = require('turf')
	, xyzTileWorker = require('./xyzTileWorker')
	, geojsonvt = require('geojson-vt')
	, path = require('path')
	, CacheModel = require('../models/cache')
	, Readable = require('stream').Readable
 	, config = require('../config.json');

Math.radians = function(degrees) {
  return degrees * Math.PI / 180;
};

// Converts from radians to degrees.
Math.degrees = function(radians) {
  return radians * 180 / Math.PI;
};

function tile2lon(x,z) {
  return (x/Math.pow(2,z)*360-180);
}

function tile2lat(y,z) {
  var n=Math.PI-2*Math.PI*y/Math.pow(2,z);
  return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
}

exports.tileBboxCalculator = function(x, y, z) {
  console.log('tile box calculator for ' + x + ' ' + y + ' ' + z);
  x = Number(x);
  y = Number(y);
  var tileBounds = {
    north: tile2lat(y, z),
    east: tile2lon(x+1, z),
    south: tile2lat(y+1, z),
    west: tile2lon(x, z)
  };

  return tileBounds;
}

exports.xCalculator = function(bbox,z) {
	var x = [];
	var x1 = exports.getX(Number(bbox[0]), z);
	var x2 = exports.getX(Number(bbox[2]), z);
	x.max = Math.max(x1, x2);
	x.min = Math.min(x1, x2);
	if (z == 0){
		x.current = Math.min(x1, x2);
	}
	return x;
}

exports.yCalculator = function(bbox,z) {
	var y = [];
	var y1 = exports.getY(Number(bbox[1]), z);
	var y2 = exports.getY(Number(bbox[3]), z);
	y.max = Math.max(y1, y2);
	y.min = Math.min(y1, y2);
	y.current = Math.min(y1, y2);
	return y;
}

exports.getX = function(lon, zoom) {
	var xtile = Math.floor((lon + 180) / 360 * (1 << zoom));
	return xtile;
}

exports.getY = function(lat, zoom) {
	var ytile = Math.floor((1 - Math.log(Math.tan(Math.radians(parseFloat(lat))) + 1 / Math.cos(Math.radians(parseFloat(lat)))) / Math.PI) /2 * (1 << zoom));
	return ytile;
}

exports.generateMetadataTiles = function(source, file, callback) {
	source.status.message = "Generating metadata tiles";
	console.log('wrote the file');
	fs.readFile(file, function(err, fileData) {
	var gjData = JSON.parse(fileData);
		var geometry = turf.envelope(gjData);
		source.geometry = geometry;
		source.properties = [];
		var allProperties = {};
		for (var i = 0; i < gjData.features.length; i++) {
			var feature = gjData.features[i];
			for (var property in feature.properties) {
				allProperties[property] = allProperties[property] || {key: property, values:[]};
				if (allProperties[property].values.indexOf(feature.properties[property]) == -1) {
					allProperties[property].values.push(feature.properties[property]);
				}
			}
		}
		for (var property in allProperties) {
			source.properties.push(allProperties[property]);
		}

		source.style = {
			defaultStyle: {
				style: {
					'fill': "#000000",
					'fill-opacity': 0.5,
					'stroke': "#0000FF",
					'stroke-opacity': 1.0,
					'stroke-width': 1
				}
			},
			styles: []
		};
		source.save(function(err) {

			var tileIndex = geojsonvt(gjData, {
				indexMaxZoom: 0,
				maxZoom: 18
			});

			xyzTileWorker.createXYZTiles(source, 0, 3, function(tileInfo, tileDone) {
				console.log('get the shapefile tile %d, %d, %d', tileInfo.z, tileInfo.x, tileInfo.y);
				var dir = path.join(config.server.sourceDirectory.path, source.id.toString(), 'tiles', tileInfo.z.toString(), tileInfo.x.toString());
			  var file = path.join(dir, tileInfo.y.toString()+'.json');

			  if (!fs.existsSync(file)) {
					var tile = tileIndex.getTile(Number(tileInfo.z), Number(tileInfo.x), Number(tileInfo.y));
					if (tile) {
						exports.writeVectorTile(tile, source, tileInfo.z, tileInfo.x, tileInfo.y, function() {

							return tileDone();
						});
					} else {
						return tileDone();
					}
				} else {
					console.log('tile exists');
					return tileDone();
				}
			}, function(source, continueCallback) {
				continueCallback(null, true);
			}, function(source, zoom, zoomDoneCallback) {
				source.status.message="Processing " + ((zoom/6)*100) + "% complete";
				source.save(function() {
					zoomDoneCallback();
				});
			}, function(err, cache) {
				source.status.complete = true;
				source.status.message = "Complete";
				source.save(function() {
					callback(null, source);
				});
			});
		});
	});
}

exports.writeVectorTile = function(tile, source, z, x, y, callback) {
  var dir = path.join(config.server.sourceDirectory.path, source.id.toString(), 'tiles', z.toString(), x.toString());
  var file = path.join(dir, y.toString()+'.json');

  if (!fs.existsSync(file)) {
    fs.mkdirsSync(dir, function(err){
       if (err) console.log(err);
     });
    var outStream = fs.createWriteStream(file);
    outStream.on('finish',function(status){
      console.log('wrote the file');
      callback(null);
    });
    var s = new Readable();
    s.push(JSON.stringify(tile));
    s.push(null);
    s.pipe(outStream);
  } else {
    callback(null);
  }
}
<commit_msg>tweaking<commit_after>var request = require('request')
	, fs = require('fs-extra')
	, turf = require('turf')
	, xyzTileWorker = require('./xyzTileWorker')
	, geojsonvt = require('geojson-vt')
	, path = require('path')
	, CacheModel = require('../models/cache')
	, Readable = require('stream').Readable
 	, config = require('../config.json');

Math.radians = function(degrees) {
  return degrees * Math.PI / 180;
};

// Converts from radians to degrees.
Math.degrees = function(radians) {
  return radians * 180 / Math.PI;
};

function tile2lon(x,z) {
  return (x/Math.pow(2,z)*360-180);
}

function tile2lat(y,z) {
  var n=Math.PI-2*Math.PI*y/Math.pow(2,z);
  return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
}

exports.tileBboxCalculator = function(x, y, z) {
  console.log('tile box calculator for ' + x + ' ' + y + ' ' + z);
  x = Number(x);
  y = Number(y);
  var tileBounds = {
    north: tile2lat(y, z),
    east: tile2lon(x+1, z),
    south: tile2lat(y+1, z),
    west: tile2lon(x, z)
  };

  return tileBounds;
}

exports.xCalculator = function(bbox,z) {
	var x = [];
	var x1 = exports.getX(Number(bbox[0]), z);
	var x2 = exports.getX(Number(bbox[2]), z);
	x.max = Math.max(x1, x2);
	x.min = Math.min(x1, x2);
	if (z == 0){
		x.current = Math.min(x1, x2);
	}
	return x;
}

exports.yCalculator = function(bbox,z) {
	var y = [];
	var y1 = exports.getY(Number(bbox[1]), z);
	var y2 = exports.getY(Number(bbox[3]), z);
	y.max = Math.max(y1, y2);
	y.min = Math.min(y1, y2);
	y.current = Math.min(y1, y2);
	return y;
}

exports.getX = function(lon, zoom) {
	var xtile = Math.floor((lon + 180) / 360 * (1 << zoom));
	return xtile;
}

exports.getY = function(lat, zoom) {
	var ytile = Math.floor((1 - Math.log(Math.tan(Math.radians(parseFloat(lat))) + 1 / Math.cos(Math.radians(parseFloat(lat)))) / Math.PI) /2 * (1 << zoom));
	return ytile;
}

exports.generateMetadataTiles = function(source, file, callback) {
	source.status.message = "Generating metadata tiles";
	console.log('wrote the file');
	fs.readFile(file, function(err, fileData) {
	var gjData = JSON.parse(fileData);
		var geometry = turf.envelope(gjData);
		source.geometry = geometry;
		source.properties = [];
		var allProperties = {};
		for (var i = 0; i < gjData.features.length; i++) {
			var feature = gjData.features[i];
			for (var property in feature.properties) {
				allProperties[property] = allProperties[property] || {key: property, values:[]};
				if (allProperties[property].values.indexOf(feature.properties[property]) == -1) {
					allProperties[property].values.push(feature.properties[property]);
				}
			}
		}
		for (var property in allProperties) {
			source.properties.push(allProperties[property]);
		}

		source.style = {
			defaultStyle: {
				style: {
					'fill': "#000000",
					'fill-opacity': 0.5,
					'stroke': "#0000FF",
					'stroke-opacity': 1.0,
					'stroke-width': 1
				}
			},
			styles: []
		};
		source.save(function(err) {

			var tileIndex = geojsonvt(gjData, {
				indexMaxZoom: 14,
				maxZoom: 18
			});

			xyzTileWorker.createXYZTiles(source, 0, 5, function(tileInfo, tileDone) {
				console.log('get the shapefile tile %d, %d, %d', tileInfo.z, tileInfo.x, tileInfo.y);
				var dir = path.join(config.server.sourceDirectory.path, source.id.toString(), 'tiles', tileInfo.z.toString(), tileInfo.x.toString());
			  var file = path.join(dir, tileInfo.y.toString()+'.json');

			  if (!fs.existsSync(file)) {
					var tile = tileIndex.getTile(Number(tileInfo.z), Number(tileInfo.x), Number(tileInfo.y));
					if (tile) {
						exports.writeVectorTile(tile, source, tileInfo.z, tileInfo.x, tileInfo.y, function() {
							delete tileIndex.tiles[(((1 << tileInfo.z) * tileInfo.y + tileInfo.x) * 32) + tileInfo.z];
							return tileDone();
						});
					} else {
						return tileDone();
					}
				} else {
					console.log('tile exists');
					return tileDone();
				}
			}, function(source, continueCallback) {
				continueCallback(null, true);
			}, function(source, zoom, zoomDoneCallback) {
				source.status.message="Processing " + ((zoom/6)*100) + "% complete";
				source.save(function() {
					zoomDoneCallback();
				});
			}, function(err, cache) {
				source.status.complete = true;
				source.status.message = "Complete";
				source.save(function() {
					callback(null, source);
				});
			});
		});
	});
}

exports.writeVectorTile = function(tile, source, z, x, y, callback) {
  var dir = path.join(config.server.sourceDirectory.path, source.id.toString(), 'tiles', z.toString(), x.toString());
  var file = path.join(dir, y.toString()+'.json');

  if (!fs.existsSync(file)) {
    fs.mkdirsSync(dir, function(err){
       if (err) console.log(err);
     });
    var outStream = fs.createWriteStream(file);
    outStream.on('finish',function(status){
      console.log('wrote the file');
      callback(null);
    });
    var s = new Readable();
    s.push(JSON.stringify(tile));
    s.push(null);
    s.pipe(outStream);
  } else {
    callback(null);
  }
}
<|endoftext|>


<commit_before>// Copyright 2016 Volker Sorge
//
// 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.
//
// Supported by the Mozilla Foundation.

/**
 * @fileoverview A data structure to maintain grammatical context.
 * @author volker.sorge@gmail.com (Volker Sorge)
 */

goog.provide('sre.Grammar');

goog.require('sre.Engine');

/**
 * @constructor
 */
sre.Grammar = function() {

  /**
   * Grammatical annotations that need to be propagated.
   * @type {!sre.Grammar.State}
   * @private
   */
  this.parameters_ = {};

  /**
   * Maps grammatical annotations to correction functions.
   * @type {Object.<Function>}
   * @private
   */
  this.corrections_ = {};

  /**
   * Maps grammatical annotations to preprocessor functions.
   * @type {Object.<Function>}
   * @private
   */
  this.preprocessors_ = {};

  /**
   * @type {Array.<Object.<sre.Grammar.Value>>}
   * @private
   */
  this.stateStack_ = [];

  /**
   * Current processing flags of the grammar. This is only filled during
   * application of grammatical structures to an input text.
   * @type {{adjust: (undefined|boolean),
   *         preprocess: (undefined|boolean),
   *         correct: (undefined|boolean),
   *         translate: (undefined|boolean)}}
   */
  this.currentFlags = {};

};
goog.addSingletonGetter(sre.Grammar);

/**
 * @typedef {boolean|string}
 */
sre.Grammar.Value;

/**
 * Defines grammar attribute for a component of a speech rule.
 * @typedef {!Object.<sre.Grammar.Value>}
 */
sre.Grammar.State;

/**
 * @type {string}
 */
sre.Grammar.ATTRIBUTE = 'grammar';

/**
 * Clears the grammar object.
 */
sre.Grammar.prototype.clear = function() {
  this.parameters_ = {};
  this.stateStack_ = [];
};

/**
 * Sets a grammar parameter.
 * @param {string} parameter The parameter name.
 * @param {sre.Grammar.Value} value The parameter's value.
 * @return {sre.Grammar.Value} The old value if it existed.
 */
sre.Grammar.prototype.setParameter = function(parameter, value) {
  var oldValue = this.parameters_[parameter];
  value ? this.parameters_[parameter] = value :
      delete this.parameters_[parameter];
  return oldValue;
};

/**
 * Returns the value for a parameter.
 * @param {string} parameter The parameter name.
 * @return {sre.Grammar.Value} Value of a parameter if it exists.
 */
sre.Grammar.prototype.getParameter = function(parameter) {
  return this.parameters_[parameter];
};

/**
 * Sets a grammar correction.
 * @param {string} correction The correction name.
 * @param {Function} func The correction function.
 */
sre.Grammar.prototype.setCorrection = function(correction, func) {
  this.corrections_[correction] = func;
};

/**
 * Sets a grammar preprocessor.
 * @param {string} preprocessor The preprocessor name.
 * @param {Function} func The preprocessor function.
 */
sre.Grammar.prototype.setPreprocessor = function(preprocessor, func) {
  this.preprocessors_[preprocessor] = func;
};

/**
 * Returns a grammar correction function if it exists.
 * @param {string} correction The grammar annotation.
 * @return {Function} The correction function.
 */
sre.Grammar.prototype.getCorrection = function(correction) {
  return this.corrections_[correction];
};

/**
 * @return {string} A string version of the grammatical state.
 */
sre.Grammar.prototype.getState = function() {
  var pairs = [];
  for (var key in this.parameters_) {
    var value = this.parameters_[key];
    pairs.push(typeof value === 'string' ? key + ':' + value : key);
  }
  return pairs.join(' ');
};

/**
 * Saves the current state of the grammar object.
 * @param {Object.<sre.Grammar.Value>} assignment A list of key value
 *     pairs.
 */
sre.Grammar.prototype.pushState = function(assignment) {
  for (var key in assignment) {
    assignment[key] = this.setParameter(key, assignment[key]);
  }
  this.stateStack_.push(assignment);
};

/**
 * Saves the current state of the grammar object.
 */
sre.Grammar.prototype.popState = function() {
  var assignment = this.stateStack_.pop();
  for (var key in assignment) {
    this.setParameter(key, assignment[key]);
  }
};

/**
 * Adds the grammatical state as attributed to an XML node.
 * @param {Node} node Adds a grammar value to the node.
 */
sre.Grammar.prototype.setAttribute = function(node) {
  if (node && node.nodeType === sre.DomUtil.NodeType.ELEMENT_NODE) {
    var state = this.getState();
    if (state) {
      node.setAttribute(sre.Grammar.ATTRIBUTE, state);
    }
  }
};

/**
 * Applies a grammatical preprocessors to a given description text.
 * @param {string} text The original description text.
 * @return {string} The grammatically corrected string.
 */
sre.Grammar.prototype.preprocess = function(text) {
  return this.runProcessors_(text, this.preprocessors_);
};

/**
 * Applies a grammatical corrections to a given description text.
 * @param {string} text The original description text.
 * @return {string} The grammatically corrected string.
 */
sre.Grammar.prototype.correct = function(text) {
  return this.runProcessors_(text, this.corrections_);
};

/**
 * Applies a grammatical processors to a given description text.
 * @param {string} text The original description text.
 * @param {Object.<Function>} funcs Dictionary of processor functions.
 * @return {string} The grammatically corrected string.
 * @private
 */
sre.Grammar.prototype.runProcessors_ = function(text, funcs) {
  for (var key in this.parameters_) {
    var func = funcs[key];
    if (!func) {
      continue;
    }
    var value = this.parameters_[key];
    text = (value === true) ? func(text) : func(text, value);
  }
  return text;
};

/**
 * Process a math expression into a string suitable for a speech engine.
 * @param {string} text Text representing a math expression.
 * @return {string} The string with a spoken version of the math expression.
 * @private
 */
sre.Grammar.translateString_ = function(text) {
  var engine = sre.Engine.getInstance();
  var result = engine.evaluator(text, engine.dynamicCstr) || text;
  return sre.Grammar.cleanUnit_(result);
};

/**
 * Removes unit suffix in case no unit with this name was found.
 * @param {string} text The text.
 * @return {string} The cleaned text incase it contained the :unit suffix.
 */
sre.Grammar.cleanUnit_ =  function(text) {
  if (text.match(/:unit$/)) {
    sre.Grammar.getInstance().setParameter('plural', false);
    return text.replace(/:unit$/, '');
  }
  return text;
};

/**
 * Apply grammatical adjustments of the current state to a text string.
 * @param {string} text The text string to be processed.
 * @param {{adjust: (undefined|boolean),
 *          preprocess: (undefined|boolean),
 *          correct: (undefined|boolean),
 *          translate: (undefined|boolean)}=} opt_flags Flags indicating
 *     what adjustments should be carried out.
 *
 * Description of flags:
 * adjust: All grammar adjustments are performed.
 * preprocess: Only grammar preprocessing is performed.
 * correct: Only grammar corrections are performed.
 * translate: Text element is translated with math mappings.
 *
 * @return {string} The transformed text.
 */
sre.Grammar.prototype.apply = function(text, opt_flags) {
  this.currentFlags = opt_flags || {};
  text = (this.currentFlags.adjust || this.currentFlags.preprocess) ?
      sre.Grammar.getInstance().preprocess(text) :
      text;
  if (this.parameters_['translate'] || this.currentFlags.translate) {
    text = sre.Grammar.translateString_(text);
  }
  text = (this.currentFlags.adjust || this.currentFlags.correct) ?
      sre.Grammar.getInstance().correct(text) :
      text;
  this.currentFlags = {};
  return text;
};

/**
 * Parses a state string that can be passed to the grammar.
 * @param {string} stateStr The state string for the grammar.
 * @return {sre.Grammar.State} The grammar structure.
 */
sre.Grammar.parseState = function(stateStr) {
  var state = {};
  var corrections = stateStr.split(' ');
  for (var i = 0, l = corrections.length; i < l; i++) {
    var corr = corrections[i].split(':');
    var key = corr[0];
    var value = corr[1];
    state[key] = value ? value : true;
  }
  return state;
};

/**
 * Processes the grammar annotations of a rule.
 * @param {string} grammar The grammar annotations.
 * @return {sre.Grammar.State} The grammar structure.
 */
sre.Grammar.parseInput = function(grammar) {
  var attributes = {};
  var components = grammar.split(':');
  for (var i = 0, l = components.length; i < l; i++) {
    var comp = components[i].split('=');
    var key = comp[0].trim();
    if (comp[1]) {
      attributes[key] = comp[1].trim();
      continue;
    }
    key.match(/^!/) ? attributes[key.slice(1)] = false : attributes[key] = true;
  }
  return attributes;
};

// TODO: The following is temporary and needs a better place.
//
/**
 * Applies a corrective string to the given description text.
 * @param {string} text The original description text.
 * @param {string} correction The correction string to be applied.
 * @return {string} The cleaned up string.
 * @private
 */
sre.Grammar.correctFont_ = function(text, correction) {
  if (!correction || !text) {
    return text;
  }
  correction =
      sre.Messages.MS_FUNC.FONT_REGEXP(sre.Locale.localFont(correction));
  return text.replace(correction, '');
};

/**
 * Attaches an annotation to a description.
 * @param {string} text The original description text.
 * @param {string} annotation The annotation string to be applied.
 * @return {string} The cleaned up string.
 * @private
 */
sre.Grammar.addAnnotation_ = function(text, annotation) {
  return text + ':' + annotation;
};

// TODO: Check if that is still necessary!
/**
 * Method switches of translation of text elements if they match the regexp of
 * locale.
 * @param {string} text The text.
 * @return {string} The untranslated text.
 * @private
 */
sre.Grammar.noTranslateText_ = function(text) {
  if (text.match(new RegExp('^[' + sre.Messages.REGEXP.TEXT + ']+$'))) {
    sre.Grammar.getInstance().currentFlags['translate'] = false;
  }
  return text;
};

sre.Grammar.getInstance().setCorrection('ignoreFont',
                                        sre.Grammar.correctFont_);
sre.Grammar.getInstance().setPreprocessor('annotation',
                                          sre.Grammar.addAnnotation_);
sre.Grammar.getInstance().setPreprocessor('noTranslateText',
                                          sre.Grammar.noTranslateText_);
sre.Grammar.getInstance().setCorrection('ignoreCaps',
                                        sre.Grammar.correctFont_);
<commit_msg>Some preprocessing of unit expressions that contain whitespace.<commit_after>// Copyright 2016 Volker Sorge
//
// 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.
//
// Supported by the Mozilla Foundation.

/**
 * @fileoverview A data structure to maintain grammatical context.
 * @author volker.sorge@gmail.com (Volker Sorge)
 */

goog.provide('sre.Grammar');

goog.require('sre.Engine');

/**
 * @constructor
 */
sre.Grammar = function() {

  /**
   * Grammatical annotations that need to be propagated.
   * @type {!sre.Grammar.State}
   * @private
   */
  this.parameters_ = {};

  /**
   * Maps grammatical annotations to correction functions.
   * @type {Object.<Function>}
   * @private
   */
  this.corrections_ = {};

  /**
   * Maps grammatical annotations to preprocessor functions.
   * @type {Object.<Function>}
   * @private
   */
  this.preprocessors_ = {};

  /**
   * @type {Array.<Object.<sre.Grammar.Value>>}
   * @private
   */
  this.stateStack_ = [];

  /**
   * Current processing flags of the grammar. This is only filled during
   * application of grammatical structures to an input text.
   * @type {{adjust: (undefined|boolean),
   *         preprocess: (undefined|boolean),
   *         correct: (undefined|boolean),
   *         translate: (undefined|boolean)}}
   */
  this.currentFlags = {};

};
goog.addSingletonGetter(sre.Grammar);

/**
 * @typedef {boolean|string}
 */
sre.Grammar.Value;

/**
 * Defines grammar attribute for a component of a speech rule.
 * @typedef {!Object.<sre.Grammar.Value>}
 */
sre.Grammar.State;

/**
 * @type {string}
 */
sre.Grammar.ATTRIBUTE = 'grammar';

/**
 * Clears the grammar object.
 */
sre.Grammar.prototype.clear = function() {
  this.parameters_ = {};
  this.stateStack_ = [];
};

/**
 * Sets a grammar parameter.
 * @param {string} parameter The parameter name.
 * @param {sre.Grammar.Value} value The parameter's value.
 * @return {sre.Grammar.Value} The old value if it existed.
 */
sre.Grammar.prototype.setParameter = function(parameter, value) {
  var oldValue = this.parameters_[parameter];
  value ? this.parameters_[parameter] = value :
      delete this.parameters_[parameter];
  return oldValue;
};

/**
 * Returns the value for a parameter.
 * @param {string} parameter The parameter name.
 * @return {sre.Grammar.Value} Value of a parameter if it exists.
 */
sre.Grammar.prototype.getParameter = function(parameter) {
  return this.parameters_[parameter];
};

/**
 * Sets a grammar correction.
 * @param {string} correction The correction name.
 * @param {Function} func The correction function.
 */
sre.Grammar.prototype.setCorrection = function(correction, func) {
  this.corrections_[correction] = func;
};

/**
 * Sets a grammar preprocessor.
 * @param {string} preprocessor The preprocessor name.
 * @param {Function} func The preprocessor function.
 */
sre.Grammar.prototype.setPreprocessor = function(preprocessor, func) {
  this.preprocessors_[preprocessor] = func;
};

/**
 * Returns a grammar correction function if it exists.
 * @param {string} correction The grammar annotation.
 * @return {Function} The correction function.
 */
sre.Grammar.prototype.getCorrection = function(correction) {
  return this.corrections_[correction];
};

/**
 * @return {string} A string version of the grammatical state.
 */
sre.Grammar.prototype.getState = function() {
  var pairs = [];
  for (var key in this.parameters_) {
    var value = this.parameters_[key];
    pairs.push(typeof value === 'string' ? key + ':' + value : key);
  }
  return pairs.join(' ');
};

/**
 * Saves the current state of the grammar object.
 * @param {Object.<sre.Grammar.Value>} assignment A list of key value
 *     pairs.
 */
sre.Grammar.prototype.pushState = function(assignment) {
  for (var key in assignment) {
    assignment[key] = this.setParameter(key, assignment[key]);
  }
  this.stateStack_.push(assignment);
};

/**
 * Saves the current state of the grammar object.
 */
sre.Grammar.prototype.popState = function() {
  var assignment = this.stateStack_.pop();
  for (var key in assignment) {
    this.setParameter(key, assignment[key]);
  }
};

/**
 * Adds the grammatical state as attributed to an XML node.
 * @param {Node} node Adds a grammar value to the node.
 */
sre.Grammar.prototype.setAttribute = function(node) {
  if (node && node.nodeType === sre.DomUtil.NodeType.ELEMENT_NODE) {
    var state = this.getState();
    if (state) {
      node.setAttribute(sre.Grammar.ATTRIBUTE, state);
    }
  }
};

/**
 * Applies a grammatical preprocessors to a given description text.
 * @param {string} text The original description text.
 * @return {string} The grammatically corrected string.
 */
sre.Grammar.prototype.preprocess = function(text) {
  return this.runProcessors_(text, this.preprocessors_);
};

/**
 * Applies a grammatical corrections to a given description text.
 * @param {string} text The original description text.
 * @return {string} The grammatically corrected string.
 */
sre.Grammar.prototype.correct = function(text) {
  return this.runProcessors_(text, this.corrections_);
};

/**
 * Applies a grammatical processors to a given description text.
 * @param {string} text The original description text.
 * @param {Object.<Function>} funcs Dictionary of processor functions.
 * @return {string} The grammatically corrected string.
 * @private
 */
sre.Grammar.prototype.runProcessors_ = function(text, funcs) {
  for (var key in this.parameters_) {
    var func = funcs[key];
    if (!func) {
      continue;
    }
    var value = this.parameters_[key];
    text = (value === true) ? func(text) : func(text, value);
  }
  return text;
};

/**
 * Process a math expression into a string suitable for a speech engine.
 * @param {string} text Text representing a math expression.
 * @return {string} The string with a spoken version of the math expression.
 * @private
 */
sre.Grammar.translateString_ = function(text) {
  text = sre.Grammar.prepareUnit_(text);
  var engine = sre.Engine.getInstance();
  var result = engine.evaluator(text, engine.dynamicCstr) || text;
  return sre.Grammar.cleanUnit_(result);
};

/**
 * Prepares a unit expression for matching.
 * @param {string} text The text to test.
 * @return {string} The cleaned string.
 */
sre.Grammar.prepareUnit_ =  function(text) {
  var match = text.match(/:unit$/);
  return match ?
    text.slice(0, match.index).replace(/\s+/g, ' ') +
    text.slice(match.index) :
    text;
};

/**
 * Removes unit suffix in case no unit with this name was found.
 * @param {string} text The text.
 * @return {string} The cleaned text incase it contained the :unit suffix.
 */
sre.Grammar.cleanUnit_ =  function(text) {
  if (text.match(/:unit$/)) {
    sre.Grammar.getInstance().setParameter('plural', false);
    return text.replace(/:unit$/, '');
  }
  return text;
};

/**
 * Apply grammatical adjustments of the current state to a text string.
 * @param {string} text The text string to be processed.
 * @param {{adjust: (undefined|boolean),
 *          preprocess: (undefined|boolean),
 *          correct: (undefined|boolean),
 *          translate: (undefined|boolean)}=} opt_flags Flags indicating
 *     what adjustments should be carried out.
 *
 * Description of flags:
 * adjust: All grammar adjustments are performed.
 * preprocess: Only grammar preprocessing is performed.
 * correct: Only grammar corrections are performed.
 * translate: Text element is translated with math mappings.
 *
 * @return {string} The transformed text.
 */
sre.Grammar.prototype.apply = function(text, opt_flags) {
  this.currentFlags = opt_flags || {};
  text = (this.currentFlags.adjust || this.currentFlags.preprocess) ?
      sre.Grammar.getInstance().preprocess(text) :
      text;
  if (this.parameters_['translate'] || this.currentFlags.translate) {
    text = sre.Grammar.translateString_(text);
  }
  text = (this.currentFlags.adjust || this.currentFlags.correct) ?
      sre.Grammar.getInstance().correct(text) :
      text;
  this.currentFlags = {};
  return text;
};

/**
 * Parses a state string that can be passed to the grammar.
 * @param {string} stateStr The state string for the grammar.
 * @return {sre.Grammar.State} The grammar structure.
 */
sre.Grammar.parseState = function(stateStr) {
  var state = {};
  var corrections = stateStr.split(' ');
  for (var i = 0, l = corrections.length; i < l; i++) {
    var corr = corrections[i].split(':');
    var key = corr[0];
    var value = corr[1];
    state[key] = value ? value : true;
  }
  return state;
};

/**
 * Processes the grammar annotations of a rule.
 * @param {string} grammar The grammar annotations.
 * @return {sre.Grammar.State} The grammar structure.
 */
sre.Grammar.parseInput = function(grammar) {
  var attributes = {};
  var components = grammar.split(':');
  for (var i = 0, l = components.length; i < l; i++) {
    var comp = components[i].split('=');
    var key = comp[0].trim();
    if (comp[1]) {
      attributes[key] = comp[1].trim();
      continue;
    }
    key.match(/^!/) ? attributes[key.slice(1)] = false : attributes[key] = true;
  }
  return attributes;
};

// TODO: The following is temporary and needs a better place.
//
/**
 * Applies a corrective string to the given description text.
 * @param {string} text The original description text.
 * @param {string} correction The correction string to be applied.
 * @return {string} The cleaned up string.
 * @private
 */
sre.Grammar.correctFont_ = function(text, correction) {
  if (!correction || !text) {
    return text;
  }
  correction =
      sre.Messages.MS_FUNC.FONT_REGEXP(sre.Locale.localFont(correction));
  return text.replace(correction, '');
};

/**
 * Attaches an annotation to a description.
 * @param {string} text The original description text.
 * @param {string} annotation The annotation string to be applied.
 * @return {string} The cleaned up string.
 * @private
 */
sre.Grammar.addAnnotation_ = function(text, annotation) {
  return text + ':' + annotation;
};

// TODO: Check if that is still necessary!
/**
 * Method switches of translation of text elements if they match the regexp of
 * locale.
 * @param {string} text The text.
 * @return {string} The untranslated text.
 * @private
 */
sre.Grammar.noTranslateText_ = function(text) {
  if (text.match(new RegExp('^[' + sre.Messages.REGEXP.TEXT + ']+$'))) {
    sre.Grammar.getInstance().currentFlags['translate'] = false;
  }
  return text;
};

sre.Grammar.getInstance().setCorrection('ignoreFont',
                                        sre.Grammar.correctFont_);
sre.Grammar.getInstance().setPreprocessor('annotation',
                                          sre.Grammar.addAnnotation_);
sre.Grammar.getInstance().setPreprocessor('noTranslateText',
                                          sre.Grammar.noTranslateText_);
sre.Grammar.getInstance().setCorrection('ignoreCaps',
                                        sre.Grammar.correctFont_);
<|endoftext|>