<commit_before>'use babel'
/** @jsx etch.dom */

import { CompositeDisposable } from 'atom'
import { views } from '../ui'
import { client } from '../connection'

import workspace from './workspace'

let {nextline, stepin, finish, stepexpr, clearbps} =
  client.import(['nextline', 'stepin', 'finish', 'stepexpr', 'clearbps'])

let {togglebp, getbps, loadgallium} = client.import({rpc: ['togglebp', 'getbps', 'loadgallium']})

let ink, active, stepper, subs, BreakpointRegistry

export function activate() {
  subs = new CompositeDisposable()

  client.handle({
    debugmode: state => debugmode(state),
    stepto: (file, line, text) => stepto(file, line, text)
  })

  subs.add(client.onDetached(() => debugmode(false)))

  startListening()

  client.onDetached(() => clearall())
}

export function deactivate() {
  BreakpointRegistry.destroy()
  subs.dispose()
}

function activeError() {
  if (!active) {
    atom.notifications.addError('You need to be debugging to do that.', {
      detail: 'You can start debugging by setting a breakpoint,\nor by calling `@step f(args...)`.',
      dismissable: true
    })
    return true
  }
}

function requireDebugging(f) { activeError() || f() }

function debugmode(a) {
  active = a
  if (!active) {
    stepper.destroy()
    workspace.update()
  }
}

function stepto(file, line, text) {
  stepper.goto(file, line-1)
  stepper.setText(views.render(text))
  workspace.update()
}

export function nextline() { requireDebugging(() => nextline()) }
export function stepin()   { requireDebugging(() => stepin()) }
export function finish()   { requireDebugging(() => finish()) }
export function stepexpr() { requireDebugging(() => stepexpr()) }

let breakpoints = []
let odcm

// logic for activating breakpoints for saved files and deactivating when
// they are modified
function startListening() {
  subs.add(atom.workspace.observeTextEditors(ed => {
    subs.add(ed.observeGrammar(g => {
      if (g.scopeName === 'source.julia') {
        let buffer = ed.getBuffer()
        buffer.onDidChangeModified(m => {
          let file = buffer.getPath()
          let bp
          // unsaved changes in buffer -> deactivate all breakpoints
          if (m === true) {
            forBPinFile(file, bp => {
              // clear the breakpoints in gallium
              togglebp(bp.file, bp.line + 1).then(r => {
                if (r.msg !== 'bpremoved') {
                  console.error('julia-client: internal: tried to clear a ' +
                                'non-existant breakpoint:')
                  console.error(bp)
                }
                // and set them to inactive in atom
                bp.updateLineToMarkerPosition()
                bp.origStatus = bp.status
                bp.status = 'inactive'
              })
            })
          } else {
            forBPinFile(file, bp => {
              bp.updateLineToMarkerPosition()
              // set breakpoints in gallium
              togglebp(bp.file, bp.line + 1).then(r => {
                if (r.msg !== 'bpset') {
                  console.error('julia-client: internal: tried to set an ' +
                                'already existing breakpoint:')
                  console.error(bp)
                }
                // reset status
                if (bp.origStatus) bp.status = bp.origStatus
              })
            })
          }
        })
      }
    }))
  }))
}

function forBPinFile(file, f) {
  let bp
  for (bp of breakpoints) {
    if (bp.file === file) {
      f(bp)
    }
  }
}

function bufferForFile(file) {
  let ed
  for (ed of atom.workspace.getTextEditors()) {
    if (ed.getBuffer().getPath() === file) {
      return ed.getBuffer()
    }
  }
  return null
}

function bp(file, line) {
  loadgallium().then(() => {
    let i = breakpoints.findIndex(bp => bp.file === file && bp.line === line)
    let modified = bufferForFile(file).isModified()

    if (i > -1) {
      let bp = breakpoints[i]
      breakpoints.splice(i, 1)

      if (modified === false) {
        togglebp(file, line + 1).then(r => {
          if (r.msg !== 'bpremoved') {
            console.error('julia-client: internal: tried to clear a ' +
                          'non-existant breakpoint:')
            console.error(bp)
          }
          bp.destroy()
        })
      }
    } else {
      if (modified === false) {
        togglebp(file, line + 1).then(r => {
          if (r.msg !== 'bpset') {
            console.error('julia-client: internal: tried to set an ' +
                          'already existing breakpoint:')
            console.error(bp)
          }
          breakpoints.push(BreakpointRegistry.add(file, line, modified ? 'inactive' : 'active'))
        })
      }
    }
  })
}

export function clearall() {
  breakpoints.forEach((bp) => bp.destroy())
  clearbps()
}

export function getBPs() {
  console.log(getbps())
}

export function togglebp(ed = atom.workspace.getActiveTextEditor()) {
  if (!ed) return
  ed.getCursors().map((cursor) =>
    bp(ed.getPath(), cursor.getBufferPosition().row))
}

export function consumeInk(i) {
  ink = i
  stepper = new ink.Stepper({
    buttons: [
      {icon: 'link-external', command: 'julia-debug:finish-function'},
      {icon: 'triangle-right', command: 'julia-debug:step-to-next-expression'},
      {icon: 'sign-in', command: 'julia-debug:step-into-function'}
    ]
  })
  BreakpointRegistry = new ink.breakpoints('source.julia')
}
<commit_msg>fix clearall<commit_after>'use babel'
/** @jsx etch.dom */

import { CompositeDisposable } from 'atom'
import { views } from '../ui'
import { client } from '../connection'

import workspace from './workspace'

let {nextline, stepin, finish, stepexpr, clearbps} =
  client.import(['nextline', 'stepin', 'finish', 'stepexpr', 'clearbps'])

let {togglebp, getbps, loadgallium} = client.import({rpc: ['togglebp', 'getbps', 'loadgallium']})

let ink, active, stepper, subs, BreakpointRegistry

export function activate() {
  subs = new CompositeDisposable()

  client.handle({
    debugmode: state => debugmode(state),
    stepto: (file, line, text) => stepto(file, line, text)
  })

  subs.add(client.onDetached(() => debugmode(false)))

  startListening()

  client.onDetached(() => clearall())
}

export function deactivate() {
  BreakpointRegistry.destroy()
  subs.dispose()
}

function activeError() {
  if (!active) {
    atom.notifications.addError('You need to be debugging to do that.', {
      detail: 'You can start debugging by setting a breakpoint,\nor by calling `@step f(args...)`.',
      dismissable: true
    })
    return true
  }
}

function requireDebugging(f) { activeError() || f() }

function debugmode(a) {
  active = a
  if (!active) {
    stepper.destroy()
    workspace.update()
  }
}

function stepto(file, line, text) {
  stepper.goto(file, line - 1)
  stepper.setText(views.render(text))
  workspace.update()
}

export function nextline() { requireDebugging(() => nextline()) }
export function stepin()   { requireDebugging(() => stepin()) }
export function finish()   { requireDebugging(() => finish()) }
export function stepexpr() { requireDebugging(() => stepexpr()) }

let breakpoints = []

// logic for activating breakpoints for saved files and deactivating when
// they are modified
function startListening() {
  subs.add(atom.workspace.observeTextEditors(ed => {
    subs.add(ed.observeGrammar(g => {
      if (g.scopeName === 'source.julia') {
        let buffer = ed.getBuffer()
        buffer.onDidChangeModified(m => {
          let file = buffer.getPath()
          let bp
          // unsaved changes in buffer -> deactivate all breakpoints
          if (m === true) {
            forBPinFile(file, bp => {
              // clear the breakpoints in gallium
              togglebp(bp.file, bp.line + 1).then(r => {
                if (r.msg !== 'bpremoved') {
                  console.error('julia-client: internal: tried to clear a ' +
                                'non-existant breakpoint:')
                  console.error(bp)
                }
                // and set them to inactive in atom
                bp.updateLineToMarkerPosition()
                bp.origStatus = bp.status
                bp.status = 'inactive'
              })
            })
          } else {
            forBPinFile(file, bp => {
              bp.updateLineToMarkerPosition()
              // set breakpoints in gallium
              togglebp(bp.file, bp.line + 1).then(r => {
                if (r.msg !== 'bpset') {
                  console.error('julia-client: internal: tried to set an ' +
                                'already existing breakpoint:')
                  console.error(bp)
                }
                // reset status
                if (bp.origStatus) bp.status = bp.origStatus
              })
            })
          }
        })
      }
    }))
  }))
}

function forBPinFile(file, f) {
  let bp
  for (bp of breakpoints) {
    if (bp.file === file) {
      f(bp)
    }
  }
}

function bufferForFile(file) {
  let ed
  for (ed of atom.workspace.getTextEditors()) {
    if (ed.getBuffer().getPath() === file) {
      return ed.getBuffer()
    }
  }
  return null
}

function bp(file, line) {
  loadgallium().then(() => {
    let i = breakpoints.findIndex(bp => bp.file === file && bp.line === line)
    let modified = bufferForFile(file).isModified()

    if (i > -1) {
      let bp = breakpoints[i]
      breakpoints.splice(i, 1)

      if (modified === false) {
        togglebp(file, line + 1).then(r => {
          if (r.msg !== 'bpremoved') {
            console.error('julia-client: internal: tried to clear a ' +
                          'non-existant breakpoint:')
            console.error(bp)
          }
          bp.destroy()
        })
      }
    } else {
      if (modified === false) {
        togglebp(file, line + 1).then(r => {
          if (r.msg !== 'bpset') {
            console.error('julia-client: internal: tried to set an ' +
                          'already existing breakpoint:')
            console.error(bp)
          }
          breakpoints.push(BreakpointRegistry.add(file, line, modified ? 'inactive' : 'active'))
        })
      }
    }
  })
}

export function clearall() {
  breakpoints.forEach((bp) => bp.destroy())
  breakpoints = []
  clearbps()
}

export function getBPs() {
  console.log(getbps())
}

export function togglebp(ed = atom.workspace.getActiveTextEditor()) {
  if (!ed) return
  ed.getCursors().map((cursor) =>
    bp(ed.getPath(), cursor.getBufferPosition().row))
}

export function consumeInk(i) {
  ink = i
  stepper = new ink.Stepper({
    buttons: [
      {icon: 'link-external', command: 'julia-debug:finish-function'},
      {icon: 'triangle-right', command: 'julia-debug:step-to-next-expression'},
      {icon: 'sign-in', command: 'julia-debug:step-into-function'}
    ]
  })
  BreakpointRegistry = new ink.breakpoints('source.julia')
}
<|endoftext|>


<commit_before>'use strict';

app.config(['$routeProvider', function ($routeProvider) {
    $routeProvider.when('/workflow', {
        templateUrl: getPath('js/partials/workflow.html'),
        controller: 'workflowCtrl'
    });
}]).controller('workflowCtrl', [
    '$scope',
    '$http',
    '$httpParamSerializer',
    'namespace',
    'workflow',
    '$mdDialog',
    '$mdToast',
    '$location',
    '$interval',
    '$anchorScroll',
    '$websocket',
    function ($scope, $http, $httpParamSerializer, namespace, workflow, $mdDialog, $mdToast, $location, $interval, $anchorScroll, $websocket) {
        if (namespace.get() === '') {
            $location.path('namespace');
            return ;
        }

        if (workflow.get() === '') {
            $location.path('workflows');
            return ;
        }

        $scope.layersData = {};
        $scope.workflow = workflow.get();

        $scope.testbutton = function () {
            $websocket.send(0, 'cool', {});
        };

        var typesList = {};
        var allFiltersList = [];

        $http.get('/ws/filters/types')
             .then(function (response) {
                 angular.forEach(response.data, function (type) {
                     typesList[type.slug] = type;
                 });
                 $scope.types = typesList;
             });

        $scope.getParameterForConfig = function (target, parameters) {
            for (var i in parameters) {
                if (parameters[i].key == target)
                    return parameters[i];
            }
            return null;
        };

        var updateLayersList = function () {
            $scope.layersData = {};
            allFiltersList = [];
            $http.get('/ws/layers/list/' + workflow.get().uuid)
                 .then(function (response) {
                     angular.forEach(response.data, function (value) {
                         $scope.layersData[value.uuid] = {
                             layer: value,
                             filters: []
                         };
                         $http.get('/ws/filters/list/' + value.uuid)
                              .then(function (filters) {
                                  $scope.layersData[value.uuid].filters = filters.data;
                                  allFiltersList = allFiltersList.concat(filters.data);
                              });
                     });
                 });
        };

        $scope.addLayer = function (ev) {
            var confirm = $mdDialog.prompt()
                                   .title('Nom du calque')
                                   .textContent('Choisissez un nom pour le nouveau calque')
                                   .placeholder('Nom')
                                   .ariaLabel('Nom')
                                   .targetEvent(ev)
                                   .ok('Créer')
                                   .cancel('Annuler');
            $mdDialog.show(confirm).then(function (result) {
                $http({
                    method: 'POST',
                    url: '/ws/layers/create/' + workflow.get().uuid,
                    data: $httpParamSerializer({name: result}),
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                    }
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Calque créé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                });
            });
        };

        $scope.deleteLayer = function (ev, uuid) {
            var confirm = $mdDialog.confirm()
                                   .title('Voulez-vous vraiment supprimer ce calque ?')
                                   .textContent('Cette opération ne peut pas être annulée.')
                                   .ariaLabel('Supprimer un calque')
                                   .targetEvent(ev)
                                   .ok('Supprimer')
                                   .cancel('Annuler');

            $mdDialog.show(confirm).then(function () {
                $http({
                    method: 'DELETE',
                    url: '/ws/layers/delete/' + uuid
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Calque supprimé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                });
            });
        };

        $scope.moveLayer = function (uuid, direction) {
            $http({
                method: 'POST',
                url: '/ws/layers/move/' + uuid,
                data: $httpParamSerializer({direction: direction}),
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                }
            }).then(function (result) {
                if (result.data.success) {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Calque déplacé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                }
            });
        };

        var currentLayer;

        function addFilterCtrl($scope, $mdDialog) {
            $scope.types = typesList;

            $scope.cancel = function () {
                $mdDialog.cancel();
            };

            $scope.create = function () {
                $http({
                    method: 'POST',
                    url: '/ws/filters/create/' + currentLayer,
                    data: $httpParamSerializer({
                        name: $scope.name,
                        target: $scope.target.slug
                    }),
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                    }
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Filtre ajouté')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                    $mdDialog.hide();
                });
            };
        };

        $scope.addFilter = function (ev, layer) {
            currentLayer = layer;

            $mdDialog.show({
                controller: ['$scope', '$mdDialog', addFilterCtrl],
                templateUrl: getPath('js/partials/dialogs/addFilter.html'),
                parent: angular.element(document.body),
                targetEvent: ev,
                clickOutsideToClose: true
            });
        };

        var targetConfig = {};
        var targetFilter = '';

        function addConfigCtrl($scope, $mdDialog, namespace) {
            $http.get('/ws/variables/all/' + namespace.get())
                 .then(function (response) {
                     $scope.list = [];
                     angular.forEach(response.data, function (variable) {
                         if (variable['type_slug'] == targetConfig['type'])
                            $scope.list.push(variable)
                     });
                 });

            $scope.cancel = function () {
                $mdDialog.cancel();
            };

            $scope.choose = function () {
                $http({
                    method: 'POST',
                    url: '/ws/filters/configure',
                    data: $httpParamSerializer({
                        filter: targetFilter.uuid,
                        variable: $scope.target,
                        key: targetConfig['key']
                    }),
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                    }
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Filtre configuré')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                    $mdDialog.hide();
                });
            };
        };

        $scope.selectVariable = function (ev, filter, config) {
            targetConfig = config;
            targetFilter = filter;

            $mdDialog.show({
                controller: ['$scope', '$mdDialog', 'namespace', addConfigCtrl],
                templateUrl: getPath('js/partials/dialogs/addConfig.html'),
                parent: angular.element(document.body),
                targetEvent: ev,
                clickOutsideToClose: true
            });
        }

        $scope.deleteFilter = function (ev, uuid) {
            var confirm = $mdDialog.confirm()
                                   .title('Voulez-vous vraiment supprimer ce filtre ?')
                                   .textContent('Cette opération ne peut pas être annulée.')
                                   .ariaLabel('Supprimer un filtre')
                                   .targetEvent(ev)
                                   .ok('Supprimer')
                                   .cancel('Annuler');

            $mdDialog.show(confirm).then(function () {
                $http({
                    method: 'DELETE',
                    url: '/ws/filters/delete/' + uuid
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Filtre supprimé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                });
            });
        };

        $scope.moveFilter = function (uuid, direction) {
            $http({
                method: 'POST',
                url: '/ws/filters/move/' + uuid,
                data: $httpParamSerializer({direction: direction}),
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                }
            }).then(function (result) {
                if (result.data.success) {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Filtre déplacé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                }
            });
        };

        function addLinkCtrl($scope, $mdDialog, namespace) {
            $scope.types = typesList;
            $scope.currentFilter = targetFilter;

            $scope.possibleFilters = allFiltersList;

            $scope.cancel = function () {
                $mdDialog.cancel();
            };

            $scope.link = function () {
                $http({
                    method: 'POST',
                    url: '/ws/filters/link',
                    data: $httpParamSerializer({
                        origin_filter: targetFilter.uuid,
                        target_filter: $scope.targetFilter.uuid,
                        origin_node: $scope.origin,
                        target_node: $scope.targetNode
                    }),
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                    }
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Lien créé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                    $mdDialog.hide();
                });
            };
        };

        $scope.addLink = function (ev, filter) {
            targetFilter = filter;

            $mdDialog.show({
                controller: ['$scope', '$mdDialog', 'namespace', addLinkCtrl],
                templateUrl: getPath('js/partials/dialogs/addLink.html'),
                parent: angular.element(document.body),
                targetEvent: ev,
                clickOutsideToClose: true
            });
        }

        $scope.deleteLink = function (ev, uuid) {
            var confirm = $mdDialog.confirm()
                                   .title('Voulez-vous vraiment supprimer ce lien ?')
                                   .textContent('Cette opération ne peut pas être annulée.')
                                   .ariaLabel('Supprimer un lien')
                                   .targetEvent(ev)
                                   .ok('Supprimer')
                                   .cancel('Annuler');

            $mdDialog.show(confirm).then(function () {
                $http({
                    method: 'DELETE',
                    url: '/ws/filters/unlink/' + uuid
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Lien supprimé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                });
            });
        };

        $scope.playing = false;
        $scope.stepping = false;
        $scope.status = '';
        $scope.currentlyRunning = '22eb5a0f-56f5-41f8-8275-02ea2f551401';

        var watchId;

        function _runWorkFlow (cmd) {
            $scope.playing = true;
            $scope.status = 'En attente';

            $websocket.hook('started', function (data) {
                $scope.status = 'Démarré';
                watchId = data['id'];
            })

            $websocket.hook('status', function (data) {
                if (data.status !== 'Unchanged') {
                    $scope.status = data.status;

                    if ($scope.status === "Running") {
                        $scope.currentlyRunning = data.filter;
                    }
                }
                if (data.status === 'Done' || data.status === 'Error') {
                    $scope.playing = false;
                    $scope.stepping = false;
                    $scope.currentlyRunning = '';
                }
                $scope.$apply();
            });

            $websocket.send(workflow.get().uuid, cmd)
        };

        $scope.playWorkflow = function () {
            _runWorkFlow("play");
        };

        $scope.startWorkflow = function () {
            $scope.stepping = true;
            _runWorkFlow("start");
        };

        $scope.stepWorkflow = function () {
            $websocket.send(watchId, "step");
        };

        $scope.runWorkflow = function () {
            $websocket.send(watchId, "run");
        };

        $scope.quitWorkflow = function () {
            $websocket.send(watchId, "quit");
        };

        $scope.log = function (ev) {
            $http.get('/ws/workflows/log/' + workflow.get().uuid)
                 .then(function (response) {
                     $mdDialog.show(
                        $mdDialog.alert()
                            .clickOutsideToClose(true)
                            .title('Journal d\'exécution')
                            .htmlContent('<pre>' + response.data['log'] + '</pre>')
                            .ariaLabel('Journal d\'exécution')
                            .ok('Fermer')
                            .targetEvent(ev)
                        );
                 });
        };

        $scope.goto = function (where) {
            $anchorScroll(where);
        }
        $anchorScroll.yOffset = 100;

        updateLayersList();
    }
]);<commit_msg>Remove test pre-filter<commit_after>'use strict';

app.config(['$routeProvider', function ($routeProvider) {
    $routeProvider.when('/workflow', {
        templateUrl: getPath('js/partials/workflow.html'),
        controller: 'workflowCtrl'
    });
}]).controller('workflowCtrl', [
    '$scope',
    '$http',
    '$httpParamSerializer',
    'namespace',
    'workflow',
    '$mdDialog',
    '$mdToast',
    '$location',
    '$interval',
    '$anchorScroll',
    '$websocket',
    function ($scope, $http, $httpParamSerializer, namespace, workflow, $mdDialog, $mdToast, $location, $interval, $anchorScroll, $websocket) {
        if (namespace.get() === '') {
            $location.path('namespace');
            return ;
        }

        if (workflow.get() === '') {
            $location.path('workflows');
            return ;
        }

        $scope.layersData = {};
        $scope.workflow = workflow.get();

        $scope.testbutton = function () {
            $websocket.send(0, 'cool', {});
        };

        var typesList = {};
        var allFiltersList = [];

        $http.get('/ws/filters/types')
             .then(function (response) {
                 angular.forEach(response.data, function (type) {
                     typesList[type.slug] = type;
                 });
                 $scope.types = typesList;
             });

        $scope.getParameterForConfig = function (target, parameters) {
            for (var i in parameters) {
                if (parameters[i].key == target)
                    return parameters[i];
            }
            return null;
        };

        var updateLayersList = function () {
            $scope.layersData = {};
            allFiltersList = [];
            $http.get('/ws/layers/list/' + workflow.get().uuid)
                 .then(function (response) {
                     angular.forEach(response.data, function (value) {
                         $scope.layersData[value.uuid] = {
                             layer: value,
                             filters: []
                         };
                         $http.get('/ws/filters/list/' + value.uuid)
                              .then(function (filters) {
                                  $scope.layersData[value.uuid].filters = filters.data;
                                  allFiltersList = allFiltersList.concat(filters.data);
                              });
                     });
                 });
        };

        $scope.addLayer = function (ev) {
            var confirm = $mdDialog.prompt()
                                   .title('Nom du calque')
                                   .textContent('Choisissez un nom pour le nouveau calque')
                                   .placeholder('Nom')
                                   .ariaLabel('Nom')
                                   .targetEvent(ev)
                                   .ok('Créer')
                                   .cancel('Annuler');
            $mdDialog.show(confirm).then(function (result) {
                $http({
                    method: 'POST',
                    url: '/ws/layers/create/' + workflow.get().uuid,
                    data: $httpParamSerializer({name: result}),
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                    }
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Calque créé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                });
            });
        };

        $scope.deleteLayer = function (ev, uuid) {
            var confirm = $mdDialog.confirm()
                                   .title('Voulez-vous vraiment supprimer ce calque ?')
                                   .textContent('Cette opération ne peut pas être annulée.')
                                   .ariaLabel('Supprimer un calque')
                                   .targetEvent(ev)
                                   .ok('Supprimer')
                                   .cancel('Annuler');

            $mdDialog.show(confirm).then(function () {
                $http({
                    method: 'DELETE',
                    url: '/ws/layers/delete/' + uuid
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Calque supprimé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                });
            });
        };

        $scope.moveLayer = function (uuid, direction) {
            $http({
                method: 'POST',
                url: '/ws/layers/move/' + uuid,
                data: $httpParamSerializer({direction: direction}),
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                }
            }).then(function (result) {
                if (result.data.success) {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Calque déplacé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                }
            });
        };

        var currentLayer;

        function addFilterCtrl($scope, $mdDialog) {
            $scope.types = typesList;

            $scope.cancel = function () {
                $mdDialog.cancel();
            };

            $scope.create = function () {
                $http({
                    method: 'POST',
                    url: '/ws/filters/create/' + currentLayer,
                    data: $httpParamSerializer({
                        name: $scope.name,
                        target: $scope.target.slug
                    }),
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                    }
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Filtre ajouté')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                    $mdDialog.hide();
                });
            };
        };

        $scope.addFilter = function (ev, layer) {
            currentLayer = layer;

            $mdDialog.show({
                controller: ['$scope', '$mdDialog', addFilterCtrl],
                templateUrl: getPath('js/partials/dialogs/addFilter.html'),
                parent: angular.element(document.body),
                targetEvent: ev,
                clickOutsideToClose: true
            });
        };

        var targetConfig = {};
        var targetFilter = '';

        function addConfigCtrl($scope, $mdDialog, namespace) {
            $http.get('/ws/variables/all/' + namespace.get())
                 .then(function (response) {
                     $scope.list = [];
                     angular.forEach(response.data, function (variable) {
                         if (variable['type_slug'] == targetConfig['type'])
                            $scope.list.push(variable)
                     });
                 });

            $scope.cancel = function () {
                $mdDialog.cancel();
            };

            $scope.choose = function () {
                $http({
                    method: 'POST',
                    url: '/ws/filters/configure',
                    data: $httpParamSerializer({
                        filter: targetFilter.uuid,
                        variable: $scope.target,
                        key: targetConfig['key']
                    }),
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                    }
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Filtre configuré')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                    $mdDialog.hide();
                });
            };
        };

        $scope.selectVariable = function (ev, filter, config) {
            targetConfig = config;
            targetFilter = filter;

            $mdDialog.show({
                controller: ['$scope', '$mdDialog', 'namespace', addConfigCtrl],
                templateUrl: getPath('js/partials/dialogs/addConfig.html'),
                parent: angular.element(document.body),
                targetEvent: ev,
                clickOutsideToClose: true
            });
        }

        $scope.deleteFilter = function (ev, uuid) {
            var confirm = $mdDialog.confirm()
                                   .title('Voulez-vous vraiment supprimer ce filtre ?')
                                   .textContent('Cette opération ne peut pas être annulée.')
                                   .ariaLabel('Supprimer un filtre')
                                   .targetEvent(ev)
                                   .ok('Supprimer')
                                   .cancel('Annuler');

            $mdDialog.show(confirm).then(function () {
                $http({
                    method: 'DELETE',
                    url: '/ws/filters/delete/' + uuid
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Filtre supprimé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                });
            });
        };

        $scope.moveFilter = function (uuid, direction) {
            $http({
                method: 'POST',
                url: '/ws/filters/move/' + uuid,
                data: $httpParamSerializer({direction: direction}),
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                }
            }).then(function (result) {
                if (result.data.success) {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Filtre déplacé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                }
            });
        };

        function addLinkCtrl($scope, $mdDialog, namespace) {
            $scope.types = typesList;
            $scope.currentFilter = targetFilter;

            $scope.possibleFilters = allFiltersList;

            $scope.cancel = function () {
                $mdDialog.cancel();
            };

            $scope.link = function () {
                $http({
                    method: 'POST',
                    url: '/ws/filters/link',
                    data: $httpParamSerializer({
                        origin_filter: targetFilter.uuid,
                        target_filter: $scope.targetFilter.uuid,
                        origin_node: $scope.origin,
                        target_node: $scope.targetNode
                    }),
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                    }
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Lien créé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                    $mdDialog.hide();
                });
            };
        };

        $scope.addLink = function (ev, filter) {
            targetFilter = filter;

            $mdDialog.show({
                controller: ['$scope', '$mdDialog', 'namespace', addLinkCtrl],
                templateUrl: getPath('js/partials/dialogs/addLink.html'),
                parent: angular.element(document.body),
                targetEvent: ev,
                clickOutsideToClose: true
            });
        }

        $scope.deleteLink = function (ev, uuid) {
            var confirm = $mdDialog.confirm()
                                   .title('Voulez-vous vraiment supprimer ce lien ?')
                                   .textContent('Cette opération ne peut pas être annulée.')
                                   .ariaLabel('Supprimer un lien')
                                   .targetEvent(ev)
                                   .ok('Supprimer')
                                   .cancel('Annuler');

            $mdDialog.show(confirm).then(function () {
                $http({
                    method: 'DELETE',
                    url: '/ws/filters/unlink/' + uuid
                }).then(function () {
                    $mdToast.show(
                        $mdToast.simple()
                                .textContent('Lien supprimé')
                                .position('bottom right')
                                .hideDelay(3000)
                    );
                    updateLayersList();
                });
            });
        };

        $scope.playing = false;
        $scope.stepping = false;
        $scope.status = '';
        $scope.currentlyRunning = '';

        var watchId;

        function _runWorkFlow (cmd) {
            $scope.playing = true;
            $scope.status = 'En attente';

            $websocket.hook('started', function (data) {
                $scope.status = 'Démarré';
                watchId = data['id'];
            })

            $websocket.hook('status', function (data) {
                if (data.status !== 'Unchanged') {
                    $scope.status = data.status;

                    if ($scope.status === "Running") {
                        $scope.currentlyRunning = data.filter;
                    }
                }
                if (data.status === 'Done' || data.status === 'Error') {
                    $scope.playing = false;
                    $scope.stepping = false;
                    $scope.currentlyRunning = '';
                }
                $scope.$apply();
            });

            $websocket.send(workflow.get().uuid, cmd)
        };

        $scope.playWorkflow = function () {
            _runWorkFlow("play");
        };

        $scope.startWorkflow = function () {
            $scope.stepping = true;
            _runWorkFlow("start");
        };

        $scope.stepWorkflow = function () {
            $websocket.send(watchId, "step");
        };

        $scope.runWorkflow = function () {
            $websocket.send(watchId, "run");
        };

        $scope.quitWorkflow = function () {
            $websocket.send(watchId, "quit");
        };

        $scope.log = function (ev) {
            $http.get('/ws/workflows/log/' + workflow.get().uuid)
                 .then(function (response) {
                     $mdDialog.show(
                        $mdDialog.alert()
                            .clickOutsideToClose(true)
                            .title('Journal d\'exécution')
                            .htmlContent('<pre>' + response.data['log'] + '</pre>')
                            .ariaLabel('Journal d\'exécution')
                            .ok('Fermer')
                            .targetEvent(ev)
                        );
                 });
        };

        $scope.goto = function (where) {
            $anchorScroll(where);
        }
        $anchorScroll.yOffset = 100;

        updateLayersList();
    }
]);<|endoftext|>


<commit_before>
import Moment from "moment";

const Later = ({ date, onClick }) => (

      Sounds Great!

      We will remind you about your contributions on
      {Moment(date).format("dddd, MMMM Do")}
      !
      If you would like to reset your schedules before then, please contact our Finance Team at 864-965-9990 or contact us

    <button className="one-whole btn push-ends" onClick={onClick}>
      Close
    </button>

);

export default Later;
<commit_msg>lint recover schedules later<commit_after>/* eslint-disable max-len */
import { PropTypes } from "react";

import moment from "moment";

const Later = ({ date, onClick }) => (

      Sounds Great!

      We will remind you about your contributions on
      {moment(date).format("dddd, MMMM Do")}
      !
      If you would like to reset your schedules before then, please contact our Finance Team at 864-965-9990 or contact us

    <button className="one-whole btn push-ends" onClick={onClick}>
      Close
    </button>

);

Later.propTypes = {
  date: PropTypes.string.isRequired,
  onClick: PropTypes.func.isRequired,
};

export default Later;
<|endoftext|>


<commit_before>/*globals d3*/
isic.views.ImagesViewSubViews = isic.views.ImagesViewSubViews || {};

/*
var ICONS = {
    check: girder.staticRoot + '/built/plugins/isic_archive/extra/img/check.svg',
    ex: girder.staticRoot + '/built/plugins/isic_archive/extra/img/ex.svg',
    dash: girder.staticRoot + '/built/plugins/isic_archive/extra/img/dash.svg'
};
*/

isic.views.ImagesViewSubViews.IndividualHistogram = Backbone.View.extend({
    initialize: function (parameters) {
        var self = this;
        self.attrName = parameters.attributeName;
        self.scale = new isic.views.ImagesViewSubViews
            .HistogramScale(self.attrName);
    },
    render: function () {
        var self = this;
        var parentWidth = this.el.parentNode.getBoundingClientRect().width;
        var emSize = parseFloat(self.$el.css('font-size'));
        self.scale.update(self.model, emSize, parentWidth);

        var svg = d3.select(self.el);
        var width = self.scale.width;
        var topPadding = 0.5 * emSize;
        var height = self.scale.height + topPadding;

        if (!self.addedTemplate) {
            svg.html(isic.templates.imagesPageHistogram({
                staticRoot: girder.staticRoot
            }));
            self.addedTemplate = true;
        }

        // Draw the y axis
        var yScale = d3.scale.linear()
            .domain([0, self.scale.yMax])
            .range([height, topPadding]);
        var yAxis = d3.svg.axis()
            .scale(yScale)
            .orient('left')
            .ticks(Math.min(4, self.scale.yMax))
            .tickFormat(d3.format('s'));
        var yAxisObj = svg.select('.yAxis')
            .attr('transform', 'translate(' + self.scale.leftAxisPadding + ',0)')
            .call(yAxis);

        // Move the special buttons into place and attach their events
        this.$el.find('.selectAllBins').hide();
        /*
        svg.select('.selectAllBins')
            .attr('transform', 'translate(' +
                (self.scale.leftAxisPadding - 0.5 * emSize) + ',' +
                (height + emSize) + ')');
        svg.select('.selectAll')
            .on('click', function () {
                self.model.clearFilters(self.attrName);
            });
        */

        // Draw the bin groups
        var labels = self.scale.overviewHistogram.map(function (d) {
            return d.label;
        });
        var bins = svg.select('.bins').selectAll('.bin')
            .data(labels, function (d) {
                return d;
            });
        var binsEnter = bins.enter().append('g')
            .attr('class', 'bin');
        bins.exit().remove();

        // Move the bins horizontally
        bins.attr('transform', function (d) {
            var binNo = self.scale.labelToBin(d, 'overview');
            return 'translate(' + self.scale.binToPosition(binNo) + ',' + topPadding + ')';
        });

        // Draw one bar for each bin
        binsEnter.append('rect')
            .attr('class', 'overview');
        binsEnter.append('rect')
            .attr('class', 'filteredSet');
        // Comment out this line to hide the page histogram (1/2):
        binsEnter.append('rect')
            .attr('class', 'page');

        // Update each bar
        function drawBars() {
            bins.select('rect.overview')
                .each(function (d) {
                    // this refers to the DOM element
                    d3.select(this).attr(self.scale.getBinRect(d, 'overview'));
                });
            bins.select('rect.filteredSet')
                .each(function (d) {
                    // this refers to the DOM element
                    d3.select(this).attr(self.scale.getBinRect(d, 'filteredSet'));
                });
            // Comment out these lines to hide the page histogram (2/2):
            bins.select('rect.page')
                .each(function (d) {
                    // this refers to the DOM element
                    d3.select(this).attr(self.scale.getBinRect(d, 'page'));
                });
        }
        drawBars();

        // Add the scale adjustment knob (needs a distinct scale instance)
        var knobScale = yScale.copy();
        var knob = svg.select('.yAxisKnob')
            .attr('transform', 'translate(' +
                self.scale.leftAxisPadding + ',' +
                knobScale(self.scale.yMax) + ')');
        knob.call(d3.behavior.drag()
            .origin(function () {
                return { x: 0, y: knobScale(self.scale.yMax) };
            }).on('drag', function () {
                // the yMax setter automagically prevents bad values...
                self.scale.yMax = knobScale.invert(d3.event.y);

                // update everything that cares about the y self.scale:
                // the knob
                knob.attr('transform', 'translate(' +
                    self.scale.leftAxisPadding + ',' +
                    knobScale(self.scale.yMax) + ')');
                // the axis
                yScale.domain([0, self.scale.yMax]);
                yAxis.scale(yScale).ticks(Math.min(4, self.scale.yMax));
                yAxisObj.call(yAxis);
                // and the bars
                drawBars();
            }).on('dragstart', function () {
                svg.style('cursor', 'ns-resize');
            }).on('dragend', function () {
                svg.style('cursor', null);
            }));

        // Add an include / exclude button for each bin
        /*
        binsEnter.append('image')
            .attr('class', 'button')
            .attr({
                x: -0.5 * emSize,
                y: height + 0.5 * emSize,
                width: emSize,
                height: emSize
            });
        bins.select('image.button').each(function (d) {
            // this refers to the DOM element
            var bin = self.scale.labelToBin(d, 'overview');
            bin = self.model.get('overviewHistogram')[self.attrName][bin];
            var status = self.model.getBinStatus(self.attrName, bin);

            // To add / remove ranges, we might need to provide a comparison
            // function (undefined will just do default comparisons)
            var comparator;
            if (self.model.getAttributeType(self.attrName) === 'string') {
                comparator = function (a, b) {
                    return a.localeCompare(b);
                };
            }

            d3.select(this)
                .attr('xlink:href', function () {
                    if (status === window.ENUMS.BIN_STATES.INCLUDED) {
                        return ICONS.check;
                    } else if (status === window.ENUMS.BIN_STATES.EXCLUDED) {
                        return ICONS.ex;
                    } else {
                        return ICONS.dash;
                    }
                }).on('click', function (d) {
                    if (status === window.ENUMS.BIN_STATES.INCLUDED) {
                        // Remove this bin
                        if (bin.hasOwnProperty('lowBound') &&
                                bin.hasOwnProperty('highBound')) {
                            self.model.removeRange(self.attrName,
                                bin.lowBound, bin.highBound, comparator);
                        } else {
                            self.model.removeValue(self.attrName, bin.label);
                        }
                    } else {
                        // Add this bin
                        if (bin.hasOwnProperty('lowBound') &&
                                bin.hasOwnProperty('highBound')) {
                            self.model.includeRange(self.attrName,
                                bin.lowBound, bin.highBound, comparator);
                        } else {
                            self.model.includeValue(self.attrName, bin.label);
                        }
                    }
                });
        });
        height += 2 * emSize;
        */

        // Add each bin label, and compute the total needed height
        var offsetY = 0.25 * emSize;
        var transformHeight = height + offsetY;
        var transformAngle = -45;
        var transformAngleRadians = transformAngle * (Math.PI / 180);
        var maxBoxHeight = svg.select('.selectAllBins').select('text')
            .node().getComputedTextLength();
        binsEnter.append('text');
        bins.select('text')
            .text(function (d) {
                return d;
            })
            .attr('text-anchor', 'end')
            .attr('transform', 'translate(0 ' + transformHeight + ') rotate(' + transformAngle + ')')
            .each(function () {
                // this refers to the DOM element
                var boxHeight = Math.abs(this.getComputedTextLength() * Math.sin(transformAngleRadians));
                maxBoxHeight = Math.max(boxHeight, maxBoxHeight);
            });
        height += maxBoxHeight + topPadding + offsetY;

        svg.attr({
            width: width + 'px',
            height: height + 'px'
        });
        return this;
    }
});
<commit_msg>Hide page indication on histograms<commit_after>/*globals d3*/
isic.views.ImagesViewSubViews = isic.views.ImagesViewSubViews || {};

/*
var ICONS = {
    check: girder.staticRoot + '/built/plugins/isic_archive/extra/img/check.svg',
    ex: girder.staticRoot + '/built/plugins/isic_archive/extra/img/ex.svg',
    dash: girder.staticRoot + '/built/plugins/isic_archive/extra/img/dash.svg'
};
*/

isic.views.ImagesViewSubViews.IndividualHistogram = Backbone.View.extend({
    initialize: function (parameters) {
        var self = this;
        self.attrName = parameters.attributeName;
        self.scale = new isic.views.ImagesViewSubViews
            .HistogramScale(self.attrName);
    },
    render: function () {
        var self = this;
        var parentWidth = this.el.parentNode.getBoundingClientRect().width;
        var emSize = parseFloat(self.$el.css('font-size'));
        self.scale.update(self.model, emSize, parentWidth);

        var svg = d3.select(self.el);
        var width = self.scale.width;
        var topPadding = 0.5 * emSize;
        var height = self.scale.height + topPadding;

        if (!self.addedTemplate) {
            svg.html(isic.templates.imagesPageHistogram({
                staticRoot: girder.staticRoot
            }));
            self.addedTemplate = true;
        }

        // Draw the y axis
        var yScale = d3.scale.linear()
            .domain([0, self.scale.yMax])
            .range([height, topPadding]);
        var yAxis = d3.svg.axis()
            .scale(yScale)
            .orient('left')
            .ticks(Math.min(4, self.scale.yMax))
            .tickFormat(d3.format('s'));
        var yAxisObj = svg.select('.yAxis')
            .attr('transform', 'translate(' + self.scale.leftAxisPadding + ',0)')
            .call(yAxis);

        // Move the special buttons into place and attach their events
        this.$el.find('.selectAllBins').hide();
        /*
        svg.select('.selectAllBins')
            .attr('transform', 'translate(' +
                (self.scale.leftAxisPadding - 0.5 * emSize) + ',' +
                (height + emSize) + ')');
        svg.select('.selectAll')
            .on('click', function () {
                self.model.clearFilters(self.attrName);
            });
        */

        // Draw the bin groups
        var labels = self.scale.overviewHistogram.map(function (d) {
            return d.label;
        });
        var bins = svg.select('.bins').selectAll('.bin')
            .data(labels, function (d) {
                return d;
            });
        var binsEnter = bins.enter().append('g')
            .attr('class', 'bin');
        bins.exit().remove();

        // Move the bins horizontally
        bins.attr('transform', function (d) {
            var binNo = self.scale.labelToBin(d, 'overview');
            return 'translate(' + self.scale.binToPosition(binNo) + ',' + topPadding + ')';
        });

        // Draw one bar for each bin
        binsEnter.append('rect')
            .attr('class', 'overview');
        binsEnter.append('rect')
            .attr('class', 'filteredSet');
        // Comment out this line to hide the page histogram (1/2):
        // binsEnter.append('rect')
        //     .attr('class', 'page');

        // Update each bar
        function drawBars() {
            bins.select('rect.overview')
                .each(function (d) {
                    // this refers to the DOM element
                    d3.select(this).attr(self.scale.getBinRect(d, 'overview'));
                });
            bins.select('rect.filteredSet')
                .each(function (d) {
                    // this refers to the DOM element
                    d3.select(this).attr(self.scale.getBinRect(d, 'filteredSet'));
                });
            // Comment out these lines to hide the page histogram (2/2):
            // bins.select('rect.page')
            //     .each(function (d) {
            //         // this refers to the DOM element
            //         d3.select(this).attr(self.scale.getBinRect(d, 'page'));
            //     });
        }
        drawBars();

        // Add the scale adjustment knob (needs a distinct scale instance)
        var knobScale = yScale.copy();
        var knob = svg.select('.yAxisKnob')
            .attr('transform', 'translate(' +
                self.scale.leftAxisPadding + ',' +
                knobScale(self.scale.yMax) + ')');
        knob.call(d3.behavior.drag()
            .origin(function () {
                return { x: 0, y: knobScale(self.scale.yMax) };
            }).on('drag', function () {
                // the yMax setter automagically prevents bad values...
                self.scale.yMax = knobScale.invert(d3.event.y);

                // update everything that cares about the y self.scale:
                // the knob
                knob.attr('transform', 'translate(' +
                    self.scale.leftAxisPadding + ',' +
                    knobScale(self.scale.yMax) + ')');
                // the axis
                yScale.domain([0, self.scale.yMax]);
                yAxis.scale(yScale).ticks(Math.min(4, self.scale.yMax));
                yAxisObj.call(yAxis);
                // and the bars
                drawBars();
            }).on('dragstart', function () {
                svg.style('cursor', 'ns-resize');
            }).on('dragend', function () {
                svg.style('cursor', null);
            }));

        // Add an include / exclude button for each bin
        /*
        binsEnter.append('image')
            .attr('class', 'button')
            .attr({
                x: -0.5 * emSize,
                y: height + 0.5 * emSize,
                width: emSize,
                height: emSize
            });
        bins.select('image.button').each(function (d) {
            // this refers to the DOM element
            var bin = self.scale.labelToBin(d, 'overview');
            bin = self.model.get('overviewHistogram')[self.attrName][bin];
            var status = self.model.getBinStatus(self.attrName, bin);

            // To add / remove ranges, we might need to provide a comparison
            // function (undefined will just do default comparisons)
            var comparator;
            if (self.model.getAttributeType(self.attrName) === 'string') {
                comparator = function (a, b) {
                    return a.localeCompare(b);
                };
            }

            d3.select(this)
                .attr('xlink:href', function () {
                    if (status === window.ENUMS.BIN_STATES.INCLUDED) {
                        return ICONS.check;
                    } else if (status === window.ENUMS.BIN_STATES.EXCLUDED) {
                        return ICONS.ex;
                    } else {
                        return ICONS.dash;
                    }
                }).on('click', function (d) {
                    if (status === window.ENUMS.BIN_STATES.INCLUDED) {
                        // Remove this bin
                        if (bin.hasOwnProperty('lowBound') &&
                                bin.hasOwnProperty('highBound')) {
                            self.model.removeRange(self.attrName,
                                bin.lowBound, bin.highBound, comparator);
                        } else {
                            self.model.removeValue(self.attrName, bin.label);
                        }
                    } else {
                        // Add this bin
                        if (bin.hasOwnProperty('lowBound') &&
                                bin.hasOwnProperty('highBound')) {
                            self.model.includeRange(self.attrName,
                                bin.lowBound, bin.highBound, comparator);
                        } else {
                            self.model.includeValue(self.attrName, bin.label);
                        }
                    }
                });
        });
        height += 2 * emSize;
        */

        // Add each bin label, and compute the total needed height
        var offsetY = 0.25 * emSize;
        var transformHeight = height + offsetY;
        var transformAngle = -45;
        var transformAngleRadians = transformAngle * (Math.PI / 180);
        var maxBoxHeight = svg.select('.selectAllBins').select('text')
            .node().getComputedTextLength();
        binsEnter.append('text');
        bins.select('text')
            .text(function (d) {
                return d;
            })
            .attr('text-anchor', 'end')
            .attr('transform', 'translate(0 ' + transformHeight + ') rotate(' + transformAngle + ')')
            .each(function () {
                // this refers to the DOM element
                var boxHeight = Math.abs(this.getComputedTextLength() * Math.sin(transformAngleRadians));
                maxBoxHeight = Math.max(boxHeight, maxBoxHeight);
            });
        height += maxBoxHeight + topPadding + offsetY;

        svg.attr({
            width: width + 'px',
            height: height + 'px'
        });
        return this;
    }
});
<|endoftext|>


<commit_before>/* global moment */

import Ember from 'ember';
import TooltipEnabled from '../mixins/sl-tooltip-enabled';

/**
 * @module components
 * @class  sl-date-time
 */
export default Ember.Component.extend( TooltipEnabled, {

    // -------------------------------------------------------------------------
    // Dependencies

    // -------------------------------------------------------------------------
    // Attributes

    /**
     * The HTML tag type of the component's root element
     *
     * @property {Ember.String} tagName
     * @default  "time"
     */
    tagName: 'time',

    /**
     * Class names for the component's root element, <time>
     *
     * @property {Ember.Array} classNames
     */
    classNames: [ 'sl-datetime' ],

    // -------------------------------------------------------------------------
    // Actions

    // -------------------------------------------------------------------------
    // Events

    // -------------------------------------------------------------------------
    // Properties

    /**
     * Bindings for the date-time's attribute values
     *
     * @property {Ember.Array} attributeBindings
     */
    attributeBindings: [ 'datetime' ],

    /**
     * String name for the format to render inline; can be "date", "datetime",
     * or "relative"
     *
     * @property {Ember.String} format
     * @default  "datetime"
     */
    format: 'datetime',

    /**
     * String representing the full timezone name, as used by and interpreted by
     * Moment-timezone: http://momentjs.com/timezone/docs/#/using-timezones/
     *
     * @property {Ember.String} timezone
     * @default  null
     */
    timezone: null,

    // -------------------------------------------------------------------------
    // Observers

    // -------------------------------------------------------------------------
    // Methods

    /**
     * The date-time's value formatted as a datetime string
     *
     * @function datetime
     * @observes timezoneString, value
     * @returns  {string}
     */
    datetime: function() {
        return moment( this.get( 'value' )).format( 'YYYY-MM-DD HH:mm ' ) + this.get( 'timezoneString' );
    }.property( 'timezoneString', 'value' ),

    /**
     * Formatted string based on value and supplied format
     *
     * @function formattedValue
     * @observes format, momentValue
     * @returns  {string}
     */
    formattedValue: function() {
        var momentValue     = this.get( 'momentValue' ),
            formattedString = '';

        switch ( this.get( 'format' ) ) {
            case 'date':
                formattedString = momentValue.format( 'YYYY-MM-DD' );
                break;

            case 'relative':
                formattedString = momentValue.fromNow();
                break;

            default:
            case 'datetime':
                formattedString = momentValue.format( 'dddd, MMMM Do YYYY, h:mm A' ) + ' ' + this.get( 'timezoneString' );
        }

        return formattedString;
    }.property( 'format', 'momentValue' ),

    /**
     * The component's current value wrapped in moment
     *
     * @function momentValue
     * @observes value
     * @returns  {object}
     */
    momentValue: function() {
        return moment( this.get( 'value' ) );
    }.property( 'value' ),

    /**
     * Formatted timezone string based on component's timezone value
     *
     * @function timezoneString
     * @observes timezone, momentValue
     * @returns  {string}
     */
    timezoneString: function() {
        return this.get( 'momentValue' ).tz( this.get( 'timezone' ) ).format( 'z' );
    }.property( 'timezone', 'momentValue' ),

    /**
     * The text to use for the component's tooltip
     *
     * @function title
     * @observes datetime
     * @returns  {string}
     */
    title: function() {
        return this.get( 'datetime' );
    }.property( 'datetime' ),

    /**
     * The bound value of the component's date value
     *
     * @function value
     * @returns  {date}
     */
    value: function() {
        return new Date();
    }.property()

});
<commit_msg>Replace computed `value` with initialized value<commit_after>/* global moment */

import Ember from 'ember';
import TooltipEnabled from '../mixins/sl-tooltip-enabled';

/**
 * @module components
 * @class  sl-date-time
 */
export default Ember.Component.extend( TooltipEnabled, {

    // -------------------------------------------------------------------------
    // Dependencies

    // -------------------------------------------------------------------------
    // Attributes

    /**
     * The HTML tag type of the component's root element
     *
     * @property {Ember.String} tagName
     * @default  "time"
     */
    tagName: 'time',

    /**
     * Class names for the component's root element, <time>
     *
     * @property {Ember.Array} classNames
     */
    classNames: [ 'sl-datetime' ],

    // -------------------------------------------------------------------------
    // Actions

    // -------------------------------------------------------------------------
    // Events

    // -------------------------------------------------------------------------
    // Properties

    /**
     * Bindings for the date-time's attribute values
     *
     * @property {Ember.Array} attributeBindings
     */
    attributeBindings: [ 'datetime' ],

    /**
     * String name for the format to render inline; can be "date", "datetime",
     * or "relative"
     *
     * @property {Ember.String} format
     * @default  "datetime"
     */
    format: 'datetime',

    /**
     * String representing the full timezone name, as used by and interpreted by
     * Moment-timezone: http://momentjs.com/timezone/docs/#/using-timezones/
     *
     * @property {Ember.String} timezone
     * @default  null
     */
    timezone: null,

    /**
     * The bound value of the component's date value
     *
     * @property {date} value
     * @default  null
     */
    value: null,

    // -------------------------------------------------------------------------
    // Observers

    /**
     * Set up initial internal value
     *
     * @function initializeValue
     * @returns  {void}
     */
    initializeValue: function() {
        if ( !this.get( 'value' ) ) {
            this.set( 'value', new Date() );
        }
    }.on( 'didInsertElement' ),

    // -------------------------------------------------------------------------
    // Methods

    /**
     * The date-time's value formatted as a datetime string
     *
     * @function datetime
     * @observes timezoneString, value
     * @returns  {string}
     */
    datetime: function() {
        return moment( this.get( 'value' )).format( 'YYYY-MM-DD HH:mm ' ) + this.get( 'timezoneString' );
    }.property( 'timezoneString', 'value' ),

    /**
     * Formatted string based on value and supplied format
     *
     * @function formattedValue
     * @observes format, momentValue
     * @returns  {string}
     */
    formattedValue: function() {
        var momentValue     = this.get( 'momentValue' ),
            formattedString = '';

        switch ( this.get( 'format' ) ) {
            case 'date':
                formattedString = momentValue.format( 'YYYY-MM-DD' );
                break;

            case 'relative':
                formattedString = momentValue.fromNow();
                break;

            default:
            case 'datetime':
                formattedString = momentValue.format( 'dddd, MMMM Do YYYY, h:mm A' ) + ' ' + this.get( 'timezoneString' );
        }

        return formattedString;
    }.property( 'format', 'momentValue' ),

    /**
     * The component's current value wrapped in moment
     *
     * @function momentValue
     * @observes value
     * @returns  {object}
     */
    momentValue: function() {
        return moment( this.get( 'value' ) );
    }.property( 'value' ),

    /**
     * Formatted timezone string based on component's timezone value
     *
     * @function timezoneString
     * @observes timezone, momentValue
     * @returns  {string}
     */
    timezoneString: function() {
        return this.get( 'momentValue' ).tz( this.get( 'timezone' ) ).format( 'z' );
    }.property( 'timezone', 'momentValue' ),

    /**
     * The text to use for the component's tooltip
     *
     * @function title
     * @observes datetime
     * @returns  {string}
     */
    title: function() {
        return this.get( 'datetime' );
    }.property( 'datetime' )

});
<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Component.extend({
  id: 'app-snackbar',
  classNames: ['mdl-js-snackbar', 'mdl-snackbar'],
  didInsertElement() {
    this._super(...arguments);
    componentHandler.upgradeElement(this.element);
    this.$('.mdl-tabs__panel').addClass('is-active');
  }
});
<commit_msg>fixed snackbar template issue<commit_after>import Ember from 'ember';
import layout from '../templates/components/smd-snackbar';

export default Ember.Component.extend({
  layout,
  id: 'app-snackbar',
  classNames: ['mdl-js-snackbar', 'mdl-snackbar'],
  didInsertElement() {
    this._super(...arguments);
    componentHandler.upgradeElement(this.element);
    this.$('.mdl-tabs__panel').addClass('is-active');
  }
});
<|endoftext|>


<commit_before>//
// Takes a screenshot of the given URL, uses named arguments passed in like so: phantomjs raster.js arg=value arg2=value2
//
// Arguments:
// - url                      - URL to screenshot
// - output                   - page to output (e.g. /tmp/output.png)
// - width         [optional] - default 1024 - viewport width
// - height        [optional] - viewport height (see note below on using height)
// - debug         [optional] - default false - whether to do some extra debugging
// - div           [optional] - a selector to use to screenshot to a specific element
// - resourceWait  [optional] - default 300 - the time to wait after the last resource has loaded in MS before taking the screenshot
// - maxRenderWait [optional] - default 10000 - the maximum time to wait before taking the screenshot, regardless of whether resources are waiting to be loaded
// - top, left, width, height [optional] - dimensions to use to screenshot a specific area of the screen
//
// == Important notice when providing height ==
//
// If you provide a height then we resize the html & body tags otherwise render() renders the entire page
// changing the viewport height does not affect this behaviour of render(), see https://github.com/ariya/phantomjs/issues/10619
//
var page           = new WebPage(),
    resourceWait   = 300,
    maxRenderWait  = 10000,
    cutoffWait     = null,
    args           = {},
    resourceCount  = 0,
    debug          = false,
    mask           = null,
    forcedRenderTimeout,
    renderTimeout,
    cutoffTimeout;

//
// Functions
//
function pickupNamedArguments() {
    var i, pair;
    for(i = 0; i < phantom.args.length; i++) {
        pair = phantom.args[i].split(/=(.*)/);
        args[pair[0]] = pair[1];
    }

    if(!args.width)        { args.width = 1024; }
    if(!args.dpi)          { args.dpi = 1; }
    if(args.url)           { args.url = decodeURIComponent(args.url); }
    if(args.debug)         { debug = true; }
    if(args.resourceWait)  { resourceWait = args.resourceWait; }
    if(args.maxRenderWait) { maxRenderWait = args.maxRenderWait; }
}

function setupMask() {
    // if given settings for an area to take create a mask for that
    if( args.top && args.left && args.width && args.height) {
        mask = {
            top:    args.top,
            left:   args.left,
            width:  args.width,
            height: args.height
        };
    }
}

function doRender() {
    clearTimeout(renderTimeout);
    clearTimeout(forcedRenderTimeout);
    clearTimeout(cutoffTimeout);
    page.render(args.output);
    phantom.exit();
}

// if the page is taking too long (set via cutoffWait) to load, just exit cleanly
function cutoff() {
  clearTimeout(renderTimeout);
  clearTimeout(forcedRenderTimeout);
  console.log("Process exceeded cutoff timeout, aborting.");
  phantom.exit();
}

function delayScreenshotForResources() {
    forcedRenderTimeout = setTimeout(doRender, maxRenderWait);
}

function cutoffExecution() {
  if(cutoffWait != null) {
    cutoffTimeout = setTimeout(cutoff, cutoffWait);
  }
}

function evaluateWithArgs(func) {
    var args = [].slice.call(arguments, 1);
    var fn =  "function() { return (" + func.toString() + ").apply(this, " + JSON.stringify(args) + "); }";
    return page.evaluate(fn);
}

function takeScreenshot() {
  cutoffExecution();
  console.log("before page open");
   page.open(args.url, function(status) {
     console.log("inside page open");
        if(status !== 'success') {
            console.log('Unable to load: ' + args.url);
            phantom.exit();
        } else {
            delayScreenshotForResources();

            page.includeJs(
                "https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js",
                function() {

                    var foundDiv = true;
                    page.evaluate(function(){ jQuery.noConflict(); });

                    if(args.div) {
                        var clip = evaluateWithArgs(withinPage_GetDivDimensions, args.div);
                        foundDiv = clip;
                        page.clipRect = clip;
                    } else if(mask) {
                        page.clipRect = mask;
                    } else if(args.height) {
                        // have a height resize the html & body to workaround https://github.com/ariya/phantomjs/issues/10619
                        evaluateWithArgs(
                            function(w,h) {
                                jQuery('body, html').css({
                                    width: w + 'px',
                                    height: h + 'px',
                                    overflow: 'hidden'
                               });
                            },
                            page.viewportSize.width,
                            page.viewportSize.height / args.dpi
                        );
                    }

                    if (args.dpi !== 1) {
                    evaluateWithArgs(
                        function(dpi) {
                            document.body.style.webkitTransform = "scale(" + dpi + ")";
                            document.body.style.webkitTransformOrigin = "0% 0%";
                            document.body.style.width = (100 / dpi) + "%";
                        },
                        args.dpi
                    );
                    }

                    if(!foundDiv) {
                        phantom.exit();
                    }
                }
            );
        }
    });
}

//
// Functions evaluated within the page context
//
function withinPage_GetDivDimensions(div){
    var $el = jQuery(div);

    if($el.length === 0){
        console.log(div + ' was not found. exiting');
        return false;
    }

    var dims    = $el.offset();
    dims.height = $el.height();
    dims.width  = $el.width();
    return dims;
}

//
// Event handlers
//
page.onConsoleMessage = function(msg) {
    console.log('from page: ' + msg);
};

page.onResourceRequested = function(req) {
    resourceCount += 1;
    if(debug) { console.log('> ' + req.id + ' - ' + req.url); }
    clearTimeout(renderTimeout);
};

page.onResourceReceived = function(res) {
    if(!res.stage || res.stage == 'end') {
        resourceCount -= 1;
        if(debug) {
            console.log(res.id + ' ' + res.status + ' - ' + res.url);
            console.log(resourceCount + ' resources remaining');
        }
        if(resourceCount === 0) {
            // Once all resources are loaded, we wait a small amount of time
            // (resourceWait) in case these resources load other resources.
            clearTimeout(forcedRenderTimeout);
            renderTimeout = setTimeout(doRender, resourceWait);
        }
    }
};

//
// Do the processing
//
pickupNamedArguments();
setupMask();

console.log(JSON.stringify(args));

if( !args.url || !args.output ) {
    console.log('Usage: raster.js url=URL output=filename width=width[optional] height=height[optional] debug=true/false[optional] (div=div[optional] OR top=top left=left width=width height=height)');
    phantom.exit();
}

page.viewportSize = { width: args.width, height: args.height || 1024 };

takeScreenshot();
<commit_msg>need to actually set the variable with the arg...<commit_after>//
// Takes a screenshot of the given URL, uses named arguments passed in like so: phantomjs raster.js arg=value arg2=value2
//
// Arguments:
// - url                      - URL to screenshot
// - output                   - page to output (e.g. /tmp/output.png)
// - width         [optional] - default 1024 - viewport width
// - height        [optional] - viewport height (see note below on using height)
// - debug         [optional] - default false - whether to do some extra debugging
// - div           [optional] - a selector to use to screenshot to a specific element
// - resourceWait  [optional] - default 300 - the time to wait after the last resource has loaded in MS before taking the screenshot
// - maxRenderWait [optional] - default 10000 - the maximum time to wait before taking the screenshot, regardless of whether resources are waiting to be loaded
// - top, left, width, height [optional] - dimensions to use to screenshot a specific area of the screen
//
// == Important notice when providing height ==
//
// If you provide a height then we resize the html & body tags otherwise render() renders the entire page
// changing the viewport height does not affect this behaviour of render(), see https://github.com/ariya/phantomjs/issues/10619
//
var page           = new WebPage(),
    resourceWait   = 300,
    maxRenderWait  = 10000,
    cutoffWait     = null,
    args           = {},
    resourceCount  = 0,
    debug          = false,
    mask           = null,
    forcedRenderTimeout,
    renderTimeout,
    cutoffTimeout;

//
// Functions
//
function pickupNamedArguments() {
    var i, pair;
    for(i = 0; i < phantom.args.length; i++) {
        pair = phantom.args[i].split(/=(.*)/);
        args[pair[0]] = pair[1];
    }

    if(!args.width)        { args.width = 1024; }
    if(!args.dpi)          { args.dpi = 1; }
    if(args.url)           { args.url = decodeURIComponent(args.url); }
    if(args.debug)         { debug = true; }
    if(args.resourceWait)  { resourceWait = args.resourceWait; }
    if(args.maxRenderWait) { maxRenderWait = args.maxRenderWait; }
    if(args.cutoffWait)    { cutoffWait = args.cutoffWait; }
}

function setupMask() {
    // if given settings for an area to take create a mask for that
    if( args.top && args.left && args.width && args.height) {
        mask = {
            top:    args.top,
            left:   args.left,
            width:  args.width,
            height: args.height
        };
    }
}

function doRender() {
    clearTimeout(renderTimeout);
    clearTimeout(forcedRenderTimeout);
    clearTimeout(cutoffTimeout);
    page.render(args.output);
    phantom.exit();
}

// if the page is taking too long (set via cutoffWait) to load, just exit cleanly
function cutoff() {
  clearTimeout(renderTimeout);
  clearTimeout(forcedRenderTimeout);
  console.log("Process exceeded cutoff timeout, aborting.");
  phantom.exit();
}

function delayScreenshotForResources() {
    forcedRenderTimeout = setTimeout(doRender, maxRenderWait);
}

function cutoffExecution() {
  if(cutoffWait != null) {
    cutoffTimeout = setTimeout(cutoff, cutoffWait);
  }
}

function evaluateWithArgs(func) {
    var args = [].slice.call(arguments, 1);
    var fn =  "function() { return (" + func.toString() + ").apply(this, " + JSON.stringify(args) + "); }";
    return page.evaluate(fn);
}

function takeScreenshot() {
  cutoffExecution();
  console.log("before page open");
   page.open(args.url, function(status) {
     console.log("inside page open");
        if(status !== 'success') {
            console.log('Unable to load: ' + args.url);
            phantom.exit();
        } else {
            delayScreenshotForResources();

            page.includeJs(
                "https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js",
                function() {

                    var foundDiv = true;
                    page.evaluate(function(){ jQuery.noConflict(); });

                    if(args.div) {
                        var clip = evaluateWithArgs(withinPage_GetDivDimensions, args.div);
                        foundDiv = clip;
                        page.clipRect = clip;
                    } else if(mask) {
                        page.clipRect = mask;
                    } else if(args.height) {
                        // have a height resize the html & body to workaround https://github.com/ariya/phantomjs/issues/10619
                        evaluateWithArgs(
                            function(w,h) {
                                jQuery('body, html').css({
                                    width: w + 'px',
                                    height: h + 'px',
                                    overflow: 'hidden'
                               });
                            },
                            page.viewportSize.width,
                            page.viewportSize.height / args.dpi
                        );
                    }

                    if (args.dpi !== 1) {
                    evaluateWithArgs(
                        function(dpi) {
                            document.body.style.webkitTransform = "scale(" + dpi + ")";
                            document.body.style.webkitTransformOrigin = "0% 0%";
                            document.body.style.width = (100 / dpi) + "%";
                        },
                        args.dpi
                    );
                    }

                    if(!foundDiv) {
                        phantom.exit();
                    }
                }
            );
        }
    });
}

//
// Functions evaluated within the page context
//
function withinPage_GetDivDimensions(div){
    var $el = jQuery(div);

    if($el.length === 0){
        console.log(div + ' was not found. exiting');
        return false;
    }

    var dims    = $el.offset();
    dims.height = $el.height();
    dims.width  = $el.width();
    return dims;
}

//
// Event handlers
//
page.onConsoleMessage = function(msg) {
    console.log('from page: ' + msg);
};

page.onResourceRequested = function(req) {
    resourceCount += 1;
    if(debug) { console.log('> ' + req.id + ' - ' + req.url); }
    clearTimeout(renderTimeout);
};

page.onResourceReceived = function(res) {
    if(!res.stage || res.stage == 'end') {
        resourceCount -= 1;
        if(debug) {
            console.log(res.id + ' ' + res.status + ' - ' + res.url);
            console.log(resourceCount + ' resources remaining');
        }
        if(resourceCount === 0) {
            // Once all resources are loaded, we wait a small amount of time
            // (resourceWait) in case these resources load other resources.
            clearTimeout(forcedRenderTimeout);
            renderTimeout = setTimeout(doRender, resourceWait);
        }
    }
};

//
// Do the processing
//
pickupNamedArguments();
setupMask();

console.log(JSON.stringify(args));

if( !args.url || !args.output ) {
    console.log('Usage: raster.js url=URL output=filename width=width[optional] height=height[optional] debug=true/false[optional] (div=div[optional] OR top=top left=left width=width height=height)');
    phantom.exit();
}

page.viewportSize = { width: args.width, height: args.height || 1024 };

takeScreenshot();
<|endoftext|>