<commit_before>OV.FeatureSet =
{
    SetDefaultColor : false
};

OV.ShowMessageDialog = function (title, message, subMessage)
{
    let dialog = new OV.ButtonDialog ();
    let contentDiv = dialog.Init (title, [
        {
            name : 'OK',
            onClick () {
                dialog.Hide ();
            }
        }
    ]);
    $('
').addClass ('ov_dialog_message').html (message).appendTo (contentDiv);
    if (subMessage !== null) {
        $('
').addClass ('ov_dialog_submessage').html ('' + subMessage + '').appendTo (contentDiv);
    }
    dialog.Show ();
    return dialog;
};

OV.ShowOpenUrlDialog = function (onOk)
{
    function CorrectFileHostUrls (urls)
    {
        for (let i = 0; i < urls.length; i++) {
            let url = urls[i];
            if (url.search (/www\.dropbox\.com/u) !== -1) {
                url = url.replace ('www.dropbox.com', 'dl.dropbox.com');
                let separatorPos = url.indexOf ('?');
                if (separatorPos !== -1) {
                    url = url.substr (0, separatorPos);
                }
                urls[i] = url;
            } else if (url.search (/github\.com/u) !== -1) {
                url = url.replace ('github.com', 'raw.githubusercontent.com');
                url = url.replace ('/blob', '');
                let separatorPos = url.indexOf ('?');
                if (separatorPos !== -1) {
                    url = url.substr (0, separatorPos);
                }
                urls[i] = url;
            }
        }
    }

    let dialog = new OV.ButtonDialog ();
    let urlsTextArea = $('<textarea>').addClass ('ov_dialog_textarea');
    let contentDiv = dialog.Init ('Open Model from Url', [
        {
            name : 'Cancel',
            subClass : 'outline',
            onClick () {
                dialog.Hide ();
            }
        },
        {
            name : 'OK',
            onClick () {
                let urls = [];
                OV.ReadLines (urlsTextArea.val (), function (line) {
                    urls.push (line);
                });
                dialog.Hide ();
                CorrectFileHostUrls (urls);
                onOk (urls);
            }
        }
    ]);
    let text = 'Here you can load models based on their urls. You can add more lines if your model builds up from multiple files.';
    $('
').html (text).addClass ('ov_dialog_section').appendTo (contentDiv);
    urlsTextArea.appendTo (contentDiv);
    dialog.Show ();
    return dialog;
};

OV.ShowSharingDialog = function (importer, importSettings, camera)
{
    function AddCheckboxLine (parentDiv, text, id, onChange)
    {
        let line = $('
').addClass ('ov_dialog_table_row').appendTo (parentDiv);
        let check = $('<input>').attr ('type', 'checkbox').attr ('checked', 'true').addClass ('ov_dialog_checkradio').attr ('id', id).appendTo (line);
        $('').attr ('for', id).html (text).appendTo (line);
        check.change (function () {
            onChange (check.prop ('checked'));
        });
    }

    function GetSharingLink (params)
    {
        let builder = OV.CreateUrlBuilder ();
        builder.AddModelUrls (params.files);
        builder.AddColor (params.color);
        let hashParameters = builder.GetParameterList ();
        return 'https://3dviewer.net#' + hashParameters;
    }

    function GetEmbeddingCode (params)
    {
        let builder = OV.CreateUrlBuilder ();
        builder.AddModelUrls (params.files);
        builder.AddCamera (params.camera);
        builder.AddColor (params.color);
        let hashParameters = builder.GetParameterList ();

        let embeddingCode = '';
        embeddingCode += '';
        embeddingCode += '';
        return embeddingCode;
    }

    function AddCopyableTextInput (parentDiv, getText)
    {
        let copyText = 'copy';
        let copiedText = 'copied';
        let container = $('
').addClass ('ov_dialog_copyable_input').appendTo (parentDiv);
        let input = $('<input>').prop ('readonly', true).appendTo (container);
        let button = $('
').addClass ('button').html (copyText).appendTo (container);
        button.click (function () {
            OV.CopyToClipboard (getText ());
            button.fadeOut (200, function () {
                button.html (copiedText).fadeIn (200);
                setTimeout (function () {
                    button.fadeOut (200, function () {
                        button.html (copyText).fadeIn (200);
                    });
                }, 2000);
            });
        });
        return input;
    }

    function AddSharingLinkTab (parentDiv, sharingLinkParams)
    {
        let section = $('
').addClass ('ov_dialog_section').appendTo (parentDiv);
        $('
').html ('Sharing Link').addClass ('ov_dialog_inner_title').appendTo (section);
        let optionsSection = null;
        if (OV.FeatureSet.SetDefaultColor) {
            optionsSection = $('
').addClass ('ov_dialog_section').appendTo (section);
        }
        let sharingLinkInput = AddCopyableTextInput (section, function () {
            return GetSharingLink (sharingLinkParams);
        });
        if (OV.FeatureSet.SetDefaultColor) {
            AddCheckboxLine (optionsSection, 'Use overridden default color', 'share_color', function (checked) {
                sharingLinkParams.color = checked ? importSettings.defaultColor : null;
                sharingLinkInput.val (GetSharingLink (sharingLinkParams));
            });
            sharingLinkParams.color = importSettings.defaultColor;
        }
        sharingLinkInput.val (GetSharingLink (sharingLinkParams));
    }

    function AddEmbeddingCodeTab (parentDiv, embeddingCodeParams)
    {
        let section = $('
').addClass ('ov_dialog_section').css ('margin-top', '20px').appendTo (parentDiv);
        $('
').html ('Embedding Code').addClass ('ov_dialog_inner_title').appendTo (section);
        let optionsSection = $('
').addClass ('ov_dialog_section').appendTo (section);
        let embeddingCodeInput = AddCopyableTextInput (section, function () {
            return GetEmbeddingCode (embeddingCodeParams);
        });
        AddCheckboxLine (optionsSection, 'Use current camera position', 'embed_camera', function (checked) {
            embeddingCodeParams.camera = checked ? camera : null;
            embeddingCodeInput.val (GetEmbeddingCode (embeddingCodeParams));
        });
        if (OV.FeatureSet.SetDefaultColor) {
            AddCheckboxLine (optionsSection, 'Use overridden default color', 'embed_color', function (checked) {
                embeddingCodeParams.color = checked ? importSettings.defaultColor : null;
                embeddingCodeInput.val (GetEmbeddingCode (embeddingCodeParams));
            });
            embeddingCodeParams.color = importSettings.defaultColor;
        }
        embeddingCodeInput.val (GetEmbeddingCode (embeddingCodeParams));
    }

    if (!importer.IsOnlyFileSource (OV.FileSource.Url)) {
        return OV.ShowMessageDialog (
            'Embedding Failed',
            'Embedding works only if you load files by url. Please upload your model files to a web server, open them by url, and try embedding again.',
            null
        );
    }

    let files = importer.GetFileList ().GetFiles ();
    let modelFiles = [];
    for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {
        let file = files[fileIndex];
        modelFiles.push (file.fileUrl);
    }

    let sharingLinkParams = {
        files : modelFiles,
        color : null
    };

    let embeddingCodeParams = {
        files : modelFiles,
        camera : camera,
        color : null
    };

    let dialog = new OV.ButtonDialog ();
    let contentDiv = dialog.Init ('Share', [
        {
            name : 'Close',
            onClick () {
                dialog.Hide ();
            }
        }
    ]);

    AddSharingLinkTab (contentDiv, sharingLinkParams);
    AddEmbeddingCodeTab (contentDiv, embeddingCodeParams);

    dialog.Show ();
    return dialog;
};

OV.ShowSettingsDialog = function (importSettings, onOk)
{
    let dialogSettings = {
        defaultColor : importSettings.defaultColor
    };
    let dialog = new OV.ButtonDialog ();
    let contentDiv = dialog.Init ('Settings', [
        {
            name : 'Cancel',
            subClass : 'outline',
            onClick () {
                dialog.Hide ();
            }
        },
        {
            name : 'OK',
            onClick () {
                dialog.Hide ();
                onOk (dialogSettings);
            }
        }
    ]);

    let colorRow = $('
').addClass ('ov_dialog_table_row').appendTo (contentDiv);
    $('
').html ('Default Color').addClass ('ov_dialog_table_row_name').appendTo (colorRow);
    let valueColumn = $('
').addClass ('ov_dialog_table_row_value').appendTo (colorRow);
    let colorInput = $('<input>').attr ('type', 'color').addClass ('ov_dialog_color').appendTo (valueColumn);
    $('').addClass ('ov_dialog_table_row_comment').html ('(For surfaces with no material)').appendTo (valueColumn);
    colorInput.val ('#' + OV.ColorToHexString (dialogSettings.defaultColor));
    colorInput.change (function () {
        let colorStr = colorInput.val ().substr (1);
        dialogSettings.defaultColor = OV.HexStringToColor (colorStr);
    });
    dialog.Show ();
    return dialog;
};

OV.ShowListPopup = function (button, items, callbacks)
{
    let popup = new OV.ListPopup ();
    popup.SetCustomResizeHandler (function (modalDiv) {
        let offset = button.offset ();
        let left = offset.left + button.outerWidth (true);
        let bottom = offset.top + button.outerHeight (true);
        modalDiv.offset ({
            left : left,
            top : bottom - modalDiv.outerHeight (true)
        });
    });
    popup.Init ();
    for (let i = 0; i < items.length; i++) {
        let item = items[i];
        popup.AddListItem (item, {
            onHoverStart : function () {
                if (callbacks.onHoverStart) {
                    callbacks.onHoverStart (i);
                }
            },
            onHoverStop : function () {
                if (callbacks.onHoverStop) {
                    callbacks.onHoverStop (i);
                }
            },
            onClick : function () {
                popup.Hide ();
                callbacks.onClick (i);
            }
        });
    }
    popup.Show ();
    return popup;
};
<commit_msg>Focus text area automatically when showing the open url dialog.<commit_after>OV.FeatureSet =
{
    SetDefaultColor : false
};

OV.ShowMessageDialog = function (title, message, subMessage)
{
    let dialog = new OV.ButtonDialog ();
    let contentDiv = dialog.Init (title, [
        {
            name : 'OK',
            onClick () {
                dialog.Hide ();
            }
        }
    ]);
    $('
').addClass ('ov_dialog_message').html (message).appendTo (contentDiv);
    if (subMessage !== null) {
        $('
').addClass ('ov_dialog_submessage').html ('' + subMessage + '').appendTo (contentDiv);
    }
    dialog.Show ();
    return dialog;
};

OV.ShowOpenUrlDialog = function (onOk)
{
    function CorrectFileHostUrls (urls)
    {
        for (let i = 0; i < urls.length; i++) {
            let url = urls[i];
            if (url.search (/www\.dropbox\.com/u) !== -1) {
                url = url.replace ('www.dropbox.com', 'dl.dropbox.com');
                let separatorPos = url.indexOf ('?');
                if (separatorPos !== -1) {
                    url = url.substr (0, separatorPos);
                }
                urls[i] = url;
            } else if (url.search (/github\.com/u) !== -1) {
                url = url.replace ('github.com', 'raw.githubusercontent.com');
                url = url.replace ('/blob', '');
                let separatorPos = url.indexOf ('?');
                if (separatorPos !== -1) {
                    url = url.substr (0, separatorPos);
                }
                urls[i] = url;
            }
        }
    }

    let dialog = new OV.ButtonDialog ();
    let urlsTextArea = $('<textarea>').addClass ('ov_dialog_textarea');
    let contentDiv = dialog.Init ('Open Model from Url', [
        {
            name : 'Cancel',
            subClass : 'outline',
            onClick () {
                dialog.Hide ();
            }
        },
        {
            name : 'OK',
            onClick () {
                let urls = [];
                OV.ReadLines (urlsTextArea.val (), function (line) {
                    urls.push (line);
                });
                dialog.Hide ();
                CorrectFileHostUrls (urls);
                onOk (urls);
            }
        }
    ]);
    let text = 'Here you can load models based on their urls. You can add more lines if your model builds up from multiple files.';
    $('
').html (text).addClass ('ov_dialog_section').appendTo (contentDiv);
    urlsTextArea.appendTo (contentDiv);
    dialog.Show ();
    urlsTextArea.focus ();
    return dialog;
};

OV.ShowSharingDialog = function (importer, importSettings, camera)
{
    function AddCheckboxLine (parentDiv, text, id, onChange)
    {
        let line = $('
').addClass ('ov_dialog_table_row').appendTo (parentDiv);
        let check = $('<input>').attr ('type', 'checkbox').attr ('checked', 'true').addClass ('ov_dialog_checkradio').attr ('id', id).appendTo (line);
        $('').attr ('for', id).html (text).appendTo (line);
        check.change (function () {
            onChange (check.prop ('checked'));
        });
    }

    function GetSharingLink (params)
    {
        let builder = OV.CreateUrlBuilder ();
        builder.AddModelUrls (params.files);
        builder.AddColor (params.color);
        let hashParameters = builder.GetParameterList ();
        return 'https://3dviewer.net#' + hashParameters;
    }

    function GetEmbeddingCode (params)
    {
        let builder = OV.CreateUrlBuilder ();
        builder.AddModelUrls (params.files);
        builder.AddCamera (params.camera);
        builder.AddColor (params.color);
        let hashParameters = builder.GetParameterList ();

        let embeddingCode = '';
        embeddingCode += '';
        embeddingCode += '';
        return embeddingCode;
    }

    function AddCopyableTextInput (parentDiv, getText)
    {
        let copyText = 'copy';
        let copiedText = 'copied';
        let container = $('
').addClass ('ov_dialog_copyable_input').appendTo (parentDiv);
        let input = $('<input>').prop ('readonly', true).appendTo (container);
        let button = $('
').addClass ('button').html (copyText).appendTo (container);
        button.click (function () {
            OV.CopyToClipboard (getText ());
            button.fadeOut (200, function () {
                button.html (copiedText).fadeIn (200);
                setTimeout (function () {
                    button.fadeOut (200, function () {
                        button.html (copyText).fadeIn (200);
                    });
                }, 2000);
            });
        });
        return input;
    }

    function AddSharingLinkTab (parentDiv, sharingLinkParams)
    {
        let section = $('
').addClass ('ov_dialog_section').appendTo (parentDiv);
        $('
').html ('Sharing Link').addClass ('ov_dialog_inner_title').appendTo (section);
        let optionsSection = null;
        if (OV.FeatureSet.SetDefaultColor) {
            optionsSection = $('
').addClass ('ov_dialog_section').appendTo (section);
        }
        let sharingLinkInput = AddCopyableTextInput (section, function () {
            return GetSharingLink (sharingLinkParams);
        });
        if (OV.FeatureSet.SetDefaultColor) {
            AddCheckboxLine (optionsSection, 'Use overridden default color', 'share_color', function (checked) {
                sharingLinkParams.color = checked ? importSettings.defaultColor : null;
                sharingLinkInput.val (GetSharingLink (sharingLinkParams));
            });
            sharingLinkParams.color = importSettings.defaultColor;
        }
        sharingLinkInput.val (GetSharingLink (sharingLinkParams));
    }

    function AddEmbeddingCodeTab (parentDiv, embeddingCodeParams)
    {
        let section = $('
').addClass ('ov_dialog_section').css ('margin-top', '20px').appendTo (parentDiv);
        $('
').html ('Embedding Code').addClass ('ov_dialog_inner_title').appendTo (section);
        let optionsSection = $('
').addClass ('ov_dialog_section').appendTo (section);
        let embeddingCodeInput = AddCopyableTextInput (section, function () {
            return GetEmbeddingCode (embeddingCodeParams);
        });
        AddCheckboxLine (optionsSection, 'Use current camera position', 'embed_camera', function (checked) {
            embeddingCodeParams.camera = checked ? camera : null;
            embeddingCodeInput.val (GetEmbeddingCode (embeddingCodeParams));
        });
        if (OV.FeatureSet.SetDefaultColor) {
            AddCheckboxLine (optionsSection, 'Use overridden default color', 'embed_color', function (checked) {
                embeddingCodeParams.color = checked ? importSettings.defaultColor : null;
                embeddingCodeInput.val (GetEmbeddingCode (embeddingCodeParams));
            });
            embeddingCodeParams.color = importSettings.defaultColor;
        }
        embeddingCodeInput.val (GetEmbeddingCode (embeddingCodeParams));
    }

    if (!importer.IsOnlyFileSource (OV.FileSource.Url)) {
        return OV.ShowMessageDialog (
            'Embedding Failed',
            'Embedding works only if you load files by url. Please upload your model files to a web server, open them by url, and try embedding again.',
            null
        );
    }

    let files = importer.GetFileList ().GetFiles ();
    let modelFiles = [];
    for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {
        let file = files[fileIndex];
        modelFiles.push (file.fileUrl);
    }

    let sharingLinkParams = {
        files : modelFiles,
        color : null
    };

    let embeddingCodeParams = {
        files : modelFiles,
        camera : camera,
        color : null
    };

    let dialog = new OV.ButtonDialog ();
    let contentDiv = dialog.Init ('Share', [
        {
            name : 'Close',
            onClick () {
                dialog.Hide ();
            }
        }
    ]);

    AddSharingLinkTab (contentDiv, sharingLinkParams);
    AddEmbeddingCodeTab (contentDiv, embeddingCodeParams);

    dialog.Show ();
    return dialog;
};

OV.ShowSettingsDialog = function (importSettings, onOk)
{
    let dialogSettings = {
        defaultColor : importSettings.defaultColor
    };
    let dialog = new OV.ButtonDialog ();
    let contentDiv = dialog.Init ('Settings', [
        {
            name : 'Cancel',
            subClass : 'outline',
            onClick () {
                dialog.Hide ();
            }
        },
        {
            name : 'OK',
            onClick () {
                dialog.Hide ();
                onOk (dialogSettings);
            }
        }
    ]);

    let colorRow = $('
').addClass ('ov_dialog_table_row').appendTo (contentDiv);
    $('
').html ('Default Color').addClass ('ov_dialog_table_row_name').appendTo (colorRow);
    let valueColumn = $('
').addClass ('ov_dialog_table_row_value').appendTo (colorRow);
    let colorInput = $('<input>').attr ('type', 'color').addClass ('ov_dialog_color').appendTo (valueColumn);
    $('').addClass ('ov_dialog_table_row_comment').html ('(For surfaces with no material)').appendTo (valueColumn);
    colorInput.val ('#' + OV.ColorToHexString (dialogSettings.defaultColor));
    colorInput.change (function () {
        let colorStr = colorInput.val ().substr (1);
        dialogSettings.defaultColor = OV.HexStringToColor (colorStr);
    });
    dialog.Show ();
    return dialog;
};

OV.ShowListPopup = function (button, items, callbacks)
{
    let popup = new OV.ListPopup ();
    popup.SetCustomResizeHandler (function (modalDiv) {
        let offset = button.offset ();
        let left = offset.left + button.outerWidth (true);
        let bottom = offset.top + button.outerHeight (true);
        modalDiv.offset ({
            left : left,
            top : bottom - modalDiv.outerHeight (true)
        });
    });
    popup.Init ();
    for (let i = 0; i < items.length; i++) {
        let item = items[i];
        popup.AddListItem (item, {
            onHoverStart : function () {
                if (callbacks.onHoverStart) {
                    callbacks.onHoverStart (i);
                }
            },
            onHoverStop : function () {
                if (callbacks.onHoverStop) {
                    callbacks.onHoverStop (i);
                }
            },
            onClick : function () {
                popup.Hide ();
                callbacks.onClick (i);
            }
        });
    }
    popup.Show ();
    return popup;
};
<|endoftext|>


<commit_before>
var dal = require('./dal');
var usersDal = require('../../server/api/users/dal');
var async = require('async');

exports.run = function (callback) {

  usersDal.getAll(function (err, users) {
    if (err) {
      return callback(err);
    }

    async.eachSeries(users, function iteratee(u, cb) {
      dal.computePointsAndStore(u.name, cb);
    }, function (err2) {
      if (err2) {
        return callback(err2);
      }

      var msg = 'points: Points of users (' + users.length + ') ' +
                'computed and stored.';
      console.log(msg);
      return callback();
    });
  });

};
<commit_msg>Rename async to asyn<commit_after>
var dal = require('./dal');
var usersDal = require('../../server/api/users/dal');
var asyn = require('async');

exports.run = function (callback) {

  usersDal.getAll(function (err, users) {
    if (err) {
      return callback(err);
    }

    asyn.eachSeries(users, function iteratee(u, cb) {
      dal.computePointsAndStore(u.name, cb);
    }, function (err2) {
      if (err2) {
        return callback(err2);
      }

      var msg = 'points: Points of users (' + users.length + ') ' +
                'computed and stored.';
      console.log(msg);
      return callback();
    });
  });

};
<|endoftext|>


<commit_before>import Vue from 'vue'
import Router from 'vue-router'

// Library for changing body classes
import vbclass from 'vue-body-class'

// Authentication library
import auth from 'lib/auth'

// Aptomi pages
import Login from 'pages/auth/Login.vue'
import ShowObjects from 'pages/objects/ShowObjects.vue'
import BrowsePolicy from 'pages/objects/BrowsePolicy.vue'
import ShowServices from 'pages/objects/ShowServices.vue'
import ShowContracts from 'pages/objects/ShowContracts.vue'
import ShowClusters from 'pages/objects/ShowClusters.vue'
import ShowRules from 'pages/objects/ShowRules.vue'
import ShowDependencies from 'pages/objects/ShowDependencies.vue'
import ShowUserRoles from 'pages/objects/ShowUserRoles.vue'
import ShowAuditLog from 'pages/objects/ShowAuditLog.vue'

Vue.use(Router)

const Passthrough = {
  template: '<router-view></router-view>'
}

const router = new Router({
  mode: 'hash',
  routes: [
    {
      path: '/',
      name: 'Home',
      redirect: '/objects/objects'
    },
    {
      path: '/objects',
      name: 'Objects',
      component: Passthrough,
      children: [
        {
          path: 'services',
          name: 'ShowServices',
          component: ShowServices
        },
        {
          path: 'contracts',
          name: 'ShowContracts',
          component: ShowContracts
        },
        {
          path: 'dependencies',
          name: 'ShowDependencies',
          component: ShowDependencies
        },
        {
          path: 'rules',
          name: 'ShowRules',
          component: ShowRules
        },
        {
          path: 'clusters',
          name: 'ShowClusters',
          component: ShowClusters
        },
        {
          path: 'users',
          name: 'ShowUserRoles',
          component: ShowUserRoles
        }
      ]
    },
    {
      path: '/deployment',
      name: 'Deployment',
      component: Passthrough,
      children: [
        {
          path: 'audit',
          name: 'ShowAuditLog',
          component: ShowAuditLog
        }
      ]
    },
    {
      path: '/debug',
      name: 'Debug',
      component: Passthrough,
      children: [
        {
          path: 'objects',
          name: 'ShowObjects',
          component: ShowObjects
        },
        {
          path: 'browse',
          name: 'BrowsePolicy',
          component: BrowsePolicy,
          props: true
        }
      ]
    },
    {
      path: '/help',
      name: 'Help',
      component: Passthrough,
      children: [
        {
          path: 'website',
          name: 'Website',
          beforeEnter (to, from, next) {
            window.location.href = 'http://aptomi.io'
          }
        },
        {
          path: 'documentation',
          name: 'Documentation',
          beforeEnter (to, from, next) {
            window.location.href = 'https://godoc.org/github.com/Aptomi/aptomi'
          }
        },
        {
          path: 'slack',
          name: 'Slack',
          beforeEnter (to, from, next) {
            window.location.href = 'http://slack.aptomi.io'
          }
        },
        {
          path: 'github',
          name: 'Github',
          beforeEnter (to, from, next) {
            window.location.href = 'https://github.com/Aptomi/aptomi'
          }
        }
      ]
    },
    {
      path: '/login',
      component: Login,
      meta: { bodyClass: 'hold-transition login-page' }
    },
    {
      path: '/logout',
      beforeEnter (to, from, next) {
        auth.logout()
        window.location.href = '/'
      }
    }
  ],
  linkActiveClass: 'active'
})

// change body classes for certain pages (such as /login)
Vue.use(vbclass, router)

// enforce authentication
router.beforeEach((to, from, next) => {
  if (to.path === '/login' || to.path === '/logout') {
    // we are on login or logout pages
    next()
  } else {
    if (!auth.loggedIn()) {
      next('/login')
    } else {
      next()
    }
  }
})

export default router
<commit_msg>fixed initial redirect<commit_after>import Vue from 'vue'
import Router from 'vue-router'

// Library for changing body classes
import vbclass from 'vue-body-class'

// Authentication library
import auth from 'lib/auth'

// Aptomi pages
import Login from 'pages/auth/Login.vue'
import ShowObjects from 'pages/objects/ShowObjects.vue'
import BrowsePolicy from 'pages/objects/BrowsePolicy.vue'
import ShowServices from 'pages/objects/ShowServices.vue'
import ShowContracts from 'pages/objects/ShowContracts.vue'
import ShowClusters from 'pages/objects/ShowClusters.vue'
import ShowRules from 'pages/objects/ShowRules.vue'
import ShowDependencies from 'pages/objects/ShowDependencies.vue'
import ShowUserRoles from 'pages/objects/ShowUserRoles.vue'
import ShowAuditLog from 'pages/objects/ShowAuditLog.vue'

Vue.use(Router)

const Passthrough = {
  template: '<router-view></router-view>'
}

const router = new Router({
  mode: 'hash',
  routes: [
    {
      path: '/',
      name: 'Home',
      redirect: '/objects/services'
    },
    {
      path: '/objects',
      name: 'Objects',
      component: Passthrough,
      children: [
        {
          path: 'services',
          name: 'ShowServices',
          component: ShowServices
        },
        {
          path: 'contracts',
          name: 'ShowContracts',
          component: ShowContracts
        },
        {
          path: 'dependencies',
          name: 'ShowDependencies',
          component: ShowDependencies
        },
        {
          path: 'rules',
          name: 'ShowRules',
          component: ShowRules
        },
        {
          path: 'clusters',
          name: 'ShowClusters',
          component: ShowClusters
        },
        {
          path: 'users',
          name: 'ShowUserRoles',
          component: ShowUserRoles
        }
      ]
    },
    {
      path: '/deployment',
      name: 'Deployment',
      component: Passthrough,
      children: [
        {
          path: 'audit',
          name: 'ShowAuditLog',
          component: ShowAuditLog
        }
      ]
    },
    {
      path: '/debug',
      name: 'Debug',
      component: Passthrough,
      children: [
        {
          path: 'objects',
          name: 'ShowObjects',
          component: ShowObjects
        },
        {
          path: 'browse',
          name: 'BrowsePolicy',
          component: BrowsePolicy,
          props: true
        }
      ]
    },
    {
      path: '/help',
      name: 'Help',
      component: Passthrough,
      children: [
        {
          path: 'website',
          name: 'Website',
          beforeEnter (to, from, next) {
            window.location.href = 'http://aptomi.io'
          }
        },
        {
          path: 'documentation',
          name: 'Documentation',
          beforeEnter (to, from, next) {
            window.location.href = 'https://godoc.org/github.com/Aptomi/aptomi'
          }
        },
        {
          path: 'slack',
          name: 'Slack',
          beforeEnter (to, from, next) {
            window.location.href = 'http://slack.aptomi.io'
          }
        },
        {
          path: 'github',
          name: 'Github',
          beforeEnter (to, from, next) {
            window.location.href = 'https://github.com/Aptomi/aptomi'
          }
        }
      ]
    },
    {
      path: '/login',
      component: Login,
      meta: { bodyClass: 'hold-transition login-page' }
    },
    {
      path: '/logout',
      beforeEnter (to, from, next) {
        auth.logout()
        window.location.href = '/'
      }
    }
  ],
  linkActiveClass: 'active'
})

// change body classes for certain pages (such as /login)
Vue.use(vbclass, router)

// enforce authentication
router.beforeEach((to, from, next) => {
  if (to.path === '/login' || to.path === '/logout') {
    // we are on login or logout pages
    next()
  } else {
    if (!auth.loggedIn()) {
      next('/login')
    } else {
      next()
    }
  }
})

export default router
<|endoftext|>


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

// Override logging to easily omit logs during tests
var logger = require('./logger');

var self = {

  /**
   * Counts the number of words in the line.
   */
  'worker': function(context, data) {

    // We expect the data argument to contain a 'line' property.
    var batch = data['batch'];

    // Batch should be an array.
    var count = 0;
    for (var i = 0; i < batch.length; i++) {
      var line = batch[i];
      // Just split to count words.
      count += line.split(/\s+/).length;
    }

    // Create a pubsub client to publish the result
    var pubsub = gcloud.pubsub({
      // We're using the API from the same project as the Cloud Function.
      projectId: process.env.GCP_PROJECT,
    });

    var outTopic = pubsub.topic(data['out-topic']);

    logger.log('Worker ' + data['worker'] + ' reporting total count of ' +
      count + ' in batch of size [' + batch.length + ']');

    outTopic.publish({
      data: {
        count: count,
        worker: data['worker']
      }
    }, function(err) {
      if (err) {
        context.failure(err);
        return;
      }
      context.success(count + '');
    });
  },

  /**
   * Reads the source file and fans out to the workers.
   */
  'master': function(context, data) {

    // Create a gcs client
    var gcs = gcloud.storage({
      // We're using the API from the same project as the Cloud Function.
      projectId: process.env.GCP_PROJECT,
    });

    // Create a pubsub client to publish the work and read the results of the workers.
    var pubsub = gcloud.pubsub({
      // We're using the API from the same project as the Cloud Function.
      projectId: process.env.GCP_PROJECT,
    });

    // Get the bucket containing our source file
    var bucket = gcs.bucket(data['bucket']);

    // The topic we are going to publish to
    var inTopic = pubsub.topic(data['in-topic']);

    var file = data['file'];

    var gcsFile = bucket.file(file);

    var batchSize = data['batch-size'] || 3;

    self._onProcessFile(gcsFile, inTopic, data['out-topic'], batchSize,
      function(err, count) {

        if (err) {
          logger.error(err);
          context.failure(err);
          return;
        }

        // The topic we are going to subscribe to
        var outTopic = pubsub.topic(data['out-topic']);

        // Subscribe to the out topic and wait for results
        self._receiveResults(outTopic, count, function(err, result) {

          if (err) {
            logger.error(err);
            context.failure(err);
            return;
          }

          context.success('The file ' + file + ' has ' + result +
            ' words');
        });
      });
  },

  /**
   * Processes the source file line-by-line.
   * @param gcsFile The name (path to) of the GCS File to be processed.
   * @param topic The pub/sub topic on to which messages will be published
   * @param strOutTopic The name of the topic to which the worker will ultimately publish.
   * @param batchSize The number of line per batch (default 3)
   * @param callback errback function to receive results in the form ()
   */
  '_onProcessFile': function(gcsFile, topic, strOutTopic, batchSize, callback) {

    const readLine = require('readline');

    // Load the master file using the stream API
    var inStream = gcsFile.createReadStream()
      .on('error', function(err) {
        callback(err);
        return;
      });

    // use the readLine module to read the stream line-by line
    var lineReader = readLine.createInterface({
      input: inStream
    });

    // Create an array to hold our request promises
    var promises = [];

    // We are going to batch the lines, we could use any number here
    var batch = [];

    // Group lines in to the file into batches and publish to the topic
    lineReader.on('line', function(line) {

      if (batch.length === batchSize) {
        // Send the batch.
        promises.push(self._publishBatch(topic, batch, strOutTopic,
          'worker' + promises.length)); // Give each worker an ID so we can handle duplicates
        batch = [];
      }

      batch.push(line.trim());
    });

    // Invoke the callback once the file has been completely read
    lineReader.on('close', function() {

      // We might have trailing lines in an incomplete batch.
      if (batch.length > 0) {
        promises.push(self._publishBatch(topic, batch, strOutTopic,
          'worker' + promises.length));
      }

      // Wait for all promises to return
      Promise.all(promises).then(
        function(result) {
          logger.log('All batches have been published');
          // The result will be an array of return values from the workers.
          callback(null, result.length);
        },
        function(err) {
          callback(err);
        });
    });
  },

  /**
   * Publishes a batch of file lines to the given topic.
   * @param topic The pub/sub topic to which messages will be published.
   * @param batch An array of Strings representing lines in the file.
   * @param strOutTopic The name of the topic to which the worker will ultimately publish.
   * @param workerId A (locally) unique ID for the worker so we can handle at-least-once duplicates from pubsub.
   * @return A Promise that resolves when the publish has completed.
   */
  '_publishBatch': function(topic, batch, strOutTopic, workerId) {
    return new Promise(function(resolve, reject) {
      logger.log('Sending batch of ' + batch.length +
        ' lines to worker worker' + workerId);

      topic.publish({
        data: {
          'batch': batch,
          'out-topic': strOutTopic,
          'worker': workerId
        }
      }, function(err) {
        if (err) {
          reject(err);
        } else {
          resolve();
        }
      });
    });
  },

  /**
   * Recieves results on the given topic.
   * @param topic The pub/sub topic in which messages will be received.
   * @param count The number of messages we expect in this batch.
   * @param callback errback function to receive results.
   */
  '_receiveResults': function(topic, count, callback) {

    // Subscribe to the out topic and wait for results
    var options = {
      autoAck: true,
      reuseExisting: true
    };

    // The subscription name can be anything, we're going to re-use it.
    topic.subscribe('mapr-pubsub-subscription', options,
      function(err, subscription) {

        if (err) {
          callback(err);
          return;
        }

        var words = 0;

        // Track returned workers to avoid duplicates
        var returned = {};

        var onError = function(err) {
          callback(err);
          return;
        };

        var onMessage = function(message) {

          var worker = message['data']['worker'];

          logger.log('Got count of ' + message['data']['count'] +
            ' from worker ' + worker);

          if (returned[worker] !== true) {
            count--;
            returned[worker] = true;
            words += parseInt(message['data']['count']);

            if (count === 0) {
              // Remove listeners to stop pulling for messages.
              subscription.removeListener('message', onMessage);
              subscription.removeListener('error', onError);
              callback(null, words);
            }
          } else {
            logger.log('Received duplicate result from worker ' +
              worker);
          }
        };

        // Register listeners to start pulling for messages.
        subscription.on('error', onError);
        subscription.on('message', onMessage);
      });
  },
};

module.exports = self;<commit_msg>Added logging of errors to pubsub master/worker sample<commit_after>var gcloud = require('gcloud');

// Override logging to easily omit logs during tests
var logger = require('./logger');

var self = {

  /**
   * Counts the number of words in the line.
   */
  'worker': function(context, data) {

    // We expect the data argument to contain a 'line' property.
    var batch = data['batch'];

    // Batch should be an array.
    var count = 0;
    for (var i = 0; i < batch.length; i++) {
      var line = batch[i];
      // Just split to count words.
      count += line.split(/\s+/).length;
    }

    // Create a pubsub client to publish the result
    var pubsub = gcloud.pubsub({
      // We're using the API from the same project as the Cloud Function.
      projectId: process.env.GCP_PROJECT,
    });

    var outTopic = pubsub.topic(data['out-topic']);

    logger.log('Worker ' + data['worker'] + ' reporting total count of ' +
      count + ' in batch of size [' + batch.length + ']');

    outTopic.publish({
      data: {
        count: count,
        worker: data['worker']
      }
    }, function(err) {
      if (err) {
        logger.error(err);
        context.failure(err);
        return;
      }
      context.success(count + '');
    });
  },

  /**
   * Reads the source file and fans out to the workers.
   */
  'master': function(context, data) {

    // Create a gcs client
    var gcs = gcloud.storage({
      // We're using the API from the same project as the Cloud Function.
      projectId: process.env.GCP_PROJECT,
    });

    // Create a pubsub client to publish the work and read the results of the workers.
    var pubsub = gcloud.pubsub({
      // We're using the API from the same project as the Cloud Function.
      projectId: process.env.GCP_PROJECT,
    });

    // Get the bucket containing our source file
    var bucket = gcs.bucket(data['bucket']);

    // The topic we are going to publish to
    var inTopic = pubsub.topic(data['in-topic']);

    var file = data['file'];

    var gcsFile = bucket.file(file);

    var batchSize = data['batch-size'] || 3;

    self._onProcessFile(gcsFile, inTopic, data['out-topic'], batchSize,
      function(err, count) {

        if (err) {
          logger.error(err);
          context.failure(err);
          return;
        }

        // The topic we are going to subscribe to
        var outTopic = pubsub.topic(data['out-topic']);

        // Subscribe to the out topic and wait for results
        self._receiveResults(outTopic, count, function(err, result) {

          if (err) {
            logger.error(err);
            context.failure(err);
            return;
          }

          context.success('The file ' + file + ' has ' + result +
            ' words');
        });
      });
  },

  /**
   * Processes the source file line-by-line.
   * @param gcsFile The name (path to) of the GCS File to be processed.
   * @param topic The pub/sub topic on to which messages will be published
   * @param strOutTopic The name of the topic to which the worker will ultimately publish.
   * @param batchSize The number of line per batch (default 3)
   * @param callback errback function to receive results in the form ()
   */
  '_onProcessFile': function(gcsFile, topic, strOutTopic, batchSize, callback) {

    const readLine = require('readline');

    // Load the master file using the stream API
    var inStream = gcsFile.createReadStream()
      .on('error', function(err) {
        logger.error(err);
        callback(err);
        return;
      });

    // use the readLine module to read the stream line-by line
    var lineReader = readLine.createInterface({
      input: inStream
    });

    // Create an array to hold our request promises
    var promises = [];

    // We are going to batch the lines, we could use any number here
    var batch = [];

    // Group lines in to the file into batches and publish to the topic
    lineReader.on('line', function(line) {

      if (batch.length === batchSize) {
        // Send the batch.
        promises.push(self._publishBatch(topic, batch, strOutTopic,
          'worker' + promises.length)); // Give each worker an ID so we can handle duplicates
        batch = [];
      }

      batch.push(line.trim());
    });

    // Invoke the callback once the file has been completely read
    lineReader.on('close', function() {

      // We might have trailing lines in an incomplete batch.
      if (batch.length > 0) {
        promises.push(self._publishBatch(topic, batch, strOutTopic,
          'worker' + promises.length));
      }

      // Wait for all promises to return
      Promise.all(promises).then(
        function(result) {
          logger.log('All batches [' + result.length +
            '] have been published');
          // The result will be an array of return values from the workers.
          callback(null, result.length);
        },
        function(err) {
          logger.error(err);
          callback(err);
        });
    });
  },

  /**
   * Publishes a batch of file lines to the given topic.
   * @param topic The pub/sub topic to which messages will be published.
   * @param batch An array of Strings representing lines in the file.
   * @param strOutTopic The name of the topic to which the worker will ultimately publish.
   * @param workerId A (locally) unique ID for the worker so we can handle at-least-once duplicates from pubsub.
   * @return A Promise that resolves when the publish has completed.
   */
  '_publishBatch': function(topic, batch, strOutTopic, workerId) {
    return new Promise(function(resolve, reject) {
      logger.log('Sending batch of ' + batch.length +
        ' lines to worker worker' + workerId);

      topic.publish({
        data: {
          'batch': batch,
          'out-topic': strOutTopic,
          'worker': workerId
        }
      }, function(err) {
        if (err) {
          reject(err);
        } else {
          resolve();
        }
      });
    });
  },

  /**
   * Recieves results on the given topic.
   * @param topic The pub/sub topic in which messages will be received.
   * @param count The number of messages we expect in this batch.
   * @param callback errback function to receive results.
   */
  '_receiveResults': function(topic, count, callback) {

    // Subscribe to the out topic and wait for results
    var options = {
      autoAck: true,
      reuseExisting: true
    };

    // The subscription name can be anything, we're going to re-use it.
    topic.subscribe('mapr-pubsub-subscription', options,
      function(err, subscription) {

        if (err) {
          callback(err);
          return;
        }

        var words = 0;

        // Track returned workers to avoid duplicates
        var returned = {};

        var onError = function(err) {
          logger.error(err);
          callback(err);
          return;
        };

        var onMessage = function(message) {

          var worker = message['data']['worker'];

          logger.log('Got count of ' + message['data']['count'] +
            ' from worker ' + worker);

          if (returned[worker] !== true) {
            count--;
            returned[worker] = true;
            words += parseInt(message['data']['count']);

            if (count === 0) {
              // Remove listeners to stop pulling for messages.
              subscription.removeListener('message', onMessage);
              subscription.removeListener('error', onError);
              callback(null, words);
            }
          } else {
            logger.log('Received duplicate result from worker ' +
              worker);
          }
        };

        // Register listeners to start pulling for messages.
        subscription.on('error', onError);
        subscription.on('message', onMessage);
      });
  },
};

module.exports = self;<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2019 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @fileoverview Non-editable, serializable text field. Behaves like a
 *    normal label but is serialized to XML. It may only be
 *    edited programmatically.
 */
'use strict';

goog.module('Blockly.FieldLabelSerializable');
goog.module.declareLegacyNamespace();

goog.require('Blockly.FieldLabel');
goog.require('Blockly.fieldRegistry');
goog.require('Blockly.utils');
goog.require('Blockly.utils.object');

/**
 * Class for a non-editable, serializable text field.
 * @param {*} opt_value The initial value of the field. Should cast to a
 *    string. Defaults to an empty string if null or undefined.
 * @param {string=} opt_class Optional CSS class for the field's text.
 * @param {Object=} opt_config A map of options used to configure the field.
 *    See the [field creation documentation]{@link https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/label-serializable#creation}
 *    for a list of properties this parameter supports.
 * @extends {Blockly.FieldLabel}
 * @constructor
 *
 */
const FieldLabelSerializable = function(opt_value, opt_class, opt_config) {
  FieldLabelSerializable.superClass_.constructor.call(
      this, opt_value, opt_class, opt_config);
};
Blockly.utils.object.inherits(FieldLabelSerializable,
    Blockly.FieldLabel);

/**
 * Construct a FieldLabelSerializable from a JSON arg object,
 * dereferencing any string table references.
 * @param {!Object} options A JSON object with options (text, and class).
 * @return {!FieldLabelSerializable} The new field instance.
 * @package
 * @nocollapse
 */
FieldLabelSerializable.fromJson = function(options) {
  const text = Blockly.utils.replaceMessageReferences(options['text']);
  // `this` might be a subclass of FieldLabelSerializable if that class doesn't
  // override the static fromJson method.
  return new this(text, undefined, options);
};

/**
 * Editable fields usually show some sort of UI indicating they are
 * editable. This field should not.
 * @type {boolean}
 */
FieldLabelSerializable.prototype.EDITABLE = false;

/**
 * Serializable fields are saved by the XML renderer, non-serializable fields
 * are not.  This field should be serialized, but only edited programmatically.
 * @type {boolean}
 */
FieldLabelSerializable.prototype.SERIALIZABLE = true;

Blockly.fieldRegistry.register(
    'field_label_serializable', FieldLabelSerializable);

exports = FieldLabelSerializable;
<commit_msg>Migrate core/field_label_serializable.js named requires<commit_after>/**
 * @license
 * Copyright 2019 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @fileoverview Non-editable, serializable text field. Behaves like a
 *    normal label but is serialized to XML. It may only be
 *    edited programmatically.
 */
'use strict';

goog.module('Blockly.FieldLabelSerializable');
goog.module.declareLegacyNamespace();

const FieldLabel = goog.require('Blockly.FieldLabel');
const fieldRegistry = goog.require('Blockly.fieldRegistry');
const {inherits} = goog.require('Blockly.utils.object');
const {replaceMessageReferences} = goog.require('Blockly.utils');

/**
 * Class for a non-editable, serializable text field.
 * @param {*} opt_value The initial value of the field. Should cast to a
 *    string. Defaults to an empty string if null or undefined.
 * @param {string=} opt_class Optional CSS class for the field's text.
 * @param {Object=} opt_config A map of options used to configure the field.
 *    See the [field creation documentation]{@link https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/label-serializable#creation}
 *    for a list of properties this parameter supports.
 * @extends {FieldLabel}
 * @constructor
 *
 */
const FieldLabelSerializable = function(opt_value, opt_class, opt_config) {
  FieldLabelSerializable.superClass_.constructor.call(
      this, opt_value, opt_class, opt_config);
};
inherits(FieldLabelSerializable,
    FieldLabel);

/**
 * Construct a FieldLabelSerializable from a JSON arg object,
 * dereferencing any string table references.
 * @param {!Object} options A JSON object with options (text, and class).
 * @return {!FieldLabelSerializable} The new field instance.
 * @package
 * @nocollapse
 */
FieldLabelSerializable.fromJson = function(options) {
  const text = replaceMessageReferences(options['text']);
  // `this` might be a subclass of FieldLabelSerializable if that class doesn't
  // override the static fromJson method.
  return new this(text, undefined, options);
};

/**
 * Editable fields usually show some sort of UI indicating they are
 * editable. This field should not.
 * @type {boolean}
 */
FieldLabelSerializable.prototype.EDITABLE = false;

/**
 * Serializable fields are saved by the XML renderer, non-serializable fields
 * are not.  This field should be serialized, but only edited programmatically.
 * @type {boolean}
 */
FieldLabelSerializable.prototype.SERIALIZABLE = true;

fieldRegistry.register(
    'field_label_serializable', FieldLabelSerializable);

exports = FieldLabelSerializable;
<|endoftext|>


<commit_before>var path = require('path');
var webpack = require('webpack');
var HtmlPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

function configCommon(cfg, opts)
{
    // Common configuration

    cfg.output.filename = 'bundle.js';

    cfg.entry.push('normalize.css');
    cfg.entry.push('event-source-polyfill');

    cfg.module.rules.push({
        test: /\.js$/,
        include: [
            opts.sourceDir,
            path.join(opts.rootDir, 'api')
        ],
        loader: 'babel-loader',
    });

    cfg.module.rules.push({
        test: /(\.svg|\.png)$/,
        loader: 'url-loader',
        options: {
            name: '[name].[ext]',
            limit: 1024
        }
    });
}

function configApp(cfg, opts)
{
    // App target configuration

    cfg.output.path = opts.outputDir;

    cfg.entry.push('./src/style.less');
    cfg.entry.push('./src/index.js');

    cfg.plugins.push(new HtmlPlugin({
        template: path.join(opts.sourceDir, 'index.html')
    }));
}

function configTests(cfg, opts)
{
    // Tests target configuration

    cfg.output.path = path.join(opts.outputDir, 'tests');

    cfg.entry.push('qunit/qunit/qunit.css');
    cfg.entry.push('./src/tests/index.js');

    cfg.plugins.push(new HtmlPlugin({
        template: path.join(opts.sourceDir, 'tests', 'index.html')
    }));
}

function configDebug(cfg)
{
    // Debug configuration

    cfg.devtool = 'source-map';

    cfg.plugins.push(new webpack.LoaderOptionsPlugin({
        debug: true
    }));

    cfg.module.rules.push({
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
    });

    cfg.module.rules.push({
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader']
    });
}

function configRelease(cfg)
{
    // Release configuration

    cfg.node.process = false;

    cfg.plugins.push(new webpack.LoaderOptionsPlugin({
        minimize: true
    }));

    cfg.plugins.push(new webpack.optimize.UglifyJsPlugin());

    cfg.plugins.push(new webpack.DefinePlugin({
        'process.env.NODE_ENV': '"production"'
    }));

    var styleExtractor = new ExtractTextPlugin({
        filename: 'bundle.css'
    });

    cfg.plugins.push(styleExtractor);

    cfg.module.rules.push({
        test: /\.css$/,
        use: styleExtractor.extract({
            use: 'css-loader',
            fallback: 'style-loader'
        })
    });

    cfg.module.rules.push({
        test: /\.less$/,
        use: styleExtractor.extract({
            use: ['css-loader', 'less-loader'],
            fallback: 'style-loader'
        })
    });
}

function makeBuildOpts(env)
{
    var buildType = env.release ? 'release' : 'debug';
    var enableTests = !!env.tests;

    var sourceDir = path.join(__dirname, 'src');
    var outputDir = path.join(__dirname, 'build', buildType);
    var rootDir = path.dirname(__dirname);

    return {
        buildType: buildType,
        enableTests: enableTests,
        rootDir: rootDir,
        sourceDir: sourceDir,
        outputDir: outputDir,
    };
}

function makeTarget(configTarget, opts)
{
    var cfg = {
        entry: [],
        output: {},
        plugins: [],
        module: { rules: [] },
        node: {}
    };

    configCommon(cfg, opts);
    configTarget(cfg, opts);

    (opts.buildType === 'release' ? configRelease : configDebug)(cfg, opts);

    return cfg;
}

module.exports = function(env)
{
    var opts = makeBuildOpts(env || {});
    var allTargets = [makeTarget(configApp, opts)];

    if (opts.enableTests)
        allTargets.push(makeTarget(configTests, opts));

    return allTargets;
};
<commit_msg>webpack.config.js: minor tweaks<commit_after>var path = require('path');
var webpack = require('webpack');
var HtmlPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

function configCommon(cfg, opts)
{
    // Common configuration

    cfg.output.filename = 'bundle.js';

    cfg.entry.push('normalize.css');
    cfg.entry.push('event-source-polyfill');

    cfg.module.rules.push({
        test: /\.js$/,
        include: [
            opts.sourceDir,
            path.join(opts.rootDir, 'api', 'client')
        ],
        loader: 'babel-loader',
    });

    cfg.module.rules.push({
        test: /(\.svg|\.png)$/,
        loader: 'url-loader',
        options: {
            name: '[name].[ext]',
            limit: 1024
        }
    });
}

function configApp(cfg, opts)
{
    // App target configuration

    cfg.output.path = opts.outputDir;

    cfg.entry.push('./src/style.less');
    cfg.entry.push('./src/index.js');

    cfg.plugins.push(new HtmlPlugin({
        template: path.join(opts.sourceDir, 'index.html')
    }));
}

function configTests(cfg, opts)
{
    // Tests target configuration

    cfg.output.path = path.join(opts.outputDir, 'tests');

    cfg.entry.push('qunit/qunit/qunit.css');
    cfg.entry.push('./src/tests/index.js');

    cfg.plugins.push(new HtmlPlugin({
        template: path.join(opts.sourceDir, 'tests', 'index.html')
    }));
}

function configDebug(cfg)
{
    // Debug configuration

    cfg.devtool = 'source-map';

    cfg.plugins.push(new webpack.LoaderOptionsPlugin({
        debug: true
    }));

    cfg.module.rules.push({
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
    });

    cfg.module.rules.push({
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader']
    });
}

function configRelease(cfg)
{
    // Release configuration

    cfg.node.process = false;

    cfg.plugins.push(new webpack.LoaderOptionsPlugin({
        minimize: true
    }));

    cfg.plugins.push(new webpack.optimize.UglifyJsPlugin());

    cfg.plugins.push(new webpack.DefinePlugin({
        'process.env.NODE_ENV': '"production"'
    }));

    var styleExtractor = new ExtractTextPlugin({
        filename: 'bundle.css'
    });

    cfg.plugins.push(styleExtractor);

    cfg.module.rules.push({
        test: /\.css$/,
        use: styleExtractor.extract({
            use: 'css-loader',
            fallback: 'style-loader'
        })
    });

    cfg.module.rules.push({
        test: /\.less$/,
        use: styleExtractor.extract({
            use: ['css-loader', 'less-loader'],
            fallback: 'style-loader'
        })
    });
}

function makeBuildOpts(env)
{
    const buildType = env.release ? 'release' : 'debug';
    const enableTests = !!env.tests;

    const sourceDir = path.join(__dirname, 'src');
    const outputDir = path.join(__dirname, 'build', buildType);
    const rootDir = path.dirname(__dirname);

    return {
        buildType,
        enableTests,
        rootDir,
        sourceDir,
        outputDir,
    };
}

function makeTarget(configTarget, opts)
{
    var cfg = {
        entry: [],
        output: {},
        plugins: [],
        module: { rules: [] },
        node: {}
    };

    configCommon(cfg, opts);
    configTarget(cfg, opts);

    (opts.buildType === 'release' ? configRelease : configDebug)(cfg, opts);

    return cfg;
}

module.exports = function(env)
{
    var opts = makeBuildOpts(env || {});
    var allTargets = [makeTarget(configApp, opts)];

    if (opts.enableTests)
        allTargets.push(makeTarget(configTests, opts));

    return allTargets;
};
<|endoftext|>


<commit_before>// @flow

import React from 'react';
import type { Node } from 'react';
import classNames from 'classnames';
import { inject, observer } from 'mobx-react';
import { type Store } from '../accordionStore/accordionStore';

const defaultProps = {
    className: 'accordion__body',
    hideBodyClassName: 'accordion__body--hidden',
};

type AccordionItemBodyProps = {
    children: Node,
    className: string,
    hideBodyClassName: string,
    accordionStore: Store,
    itemkey: string | number,
};

export const AccordionItemBody = (props: AccordionItemBodyProps) => {
    const { itemkey, children, className, hideBodyClassName } = props;
    const { items, accordion } = props.accordionStore;
    const foundItem = items.find(item => item.itemkey === itemkey);
    if (!foundItem) return null;

    const { itemUuid, expanded } = foundItem;
    const id = `accordion__body-${itemUuid}`;
    const role = accordion ? 'tabpanel' : null;

    const bodyClass = classNames(className, {
        [hideBodyClassName]: !expanded,
    });
    const ariaHidden = !expanded;
    return (
        <div
            id={id}
            className={bodyClass}
            aria-hidden={ariaHidden}
            aria-labelledby={id.replace(
                'accordion__body-',
                'accordion__title-',
            )}
            role={role}
        >
            {children}
        </div>
    );
};

AccordionItemBody.defaultProps = defaultProps;

export default inject('accordionStore', 'itemkey')(observer(AccordionItemBody));
<commit_msg>No named export in AccordionItemBody<commit_after>// @flow

import React from 'react';
import type { Node } from 'react';
import classNames from 'classnames';
import { inject, observer } from 'mobx-react';
import { type Store } from '../accordionStore/accordionStore';

const defaultProps = {
    className: 'accordion__body',
    hideBodyClassName: 'accordion__body--hidden',
};

type AccordionItemBodyProps = {
    children: Node,
    className: string,
    hideBodyClassName: string,
    accordionStore: Store,
    itemkey: string | number,
};

const AccordionItemBody = (props: AccordionItemBodyProps) => {
    const { itemkey, children, className, hideBodyClassName } = props;
    const { items, accordion } = props.accordionStore;
    const foundItem = items.find(item => item.itemkey === itemkey);
    if (!foundItem) return null;

    const { itemUuid, expanded } = foundItem;
    const id = `accordion__body-${itemUuid}`;
    const role = accordion ? 'tabpanel' : null;

    const bodyClass = classNames(className, {
        [hideBodyClassName]: !expanded,
    });
    const ariaHidden = !expanded;
    return (
        <div
            id={id}
            className={bodyClass}
            aria-hidden={ariaHidden}
            aria-labelledby={id.replace(
                'accordion__body-',
                'accordion__title-',
            )}
            role={role}
        >
            {children}
        </div>
    );
};

AccordionItemBody.defaultProps = defaultProps;

export default inject('accordionStore', 'itemkey')(observer(AccordionItemBody));
<|endoftext|>


<commit_before>// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';

global.parseIDLFileTest = function(data) {
  describe(data.description, function() {
    var execSync = require('child_process').execSync;
    var originalTimeout;
    var LocalGitRunner;
    var outputBox;
    var errorBox;

    afterAll(function() {
      execSync(`/bin/rm -rf "${data.localRepositoryPath}"`);
    });

    beforeEach(function() {
      global.defineAccumulatorBox();

      LocalGitRunner = foam.lookup('org.chromium.webidl.LocalGitRunner');
      var AccumulatorBox = foam.lookup('org.chromium.webidl.test.AccumulatorBox');
      outputBox = AccumulatorBox.create();
      errorBox = AccumulatorBox.create();

      data.GitilesIDLFile = foam.lookup('org.chromium.webidl.GitilesIDLFile');
      data.GithubIDLFile = foam.lookup('org.chromium.webidl.GithubIDLFile');
      data.Parser = foam.lookup(`org.chromium.webidl.${data.parser}`);
      data.IDLFileContents = foam.lookup('org.chromium.webidl.IDLFileContents');

      // Creating temporary directory for repo files.
      // execSync returns a Buffer with a new line character.
      data.localRepositoryPath = execSync('mktemp -d').toString().trim(-1);

      originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
      jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000000;
    });

    it('should fetch git repo and produce valid parse trees', function(done) {
      var onDone = function() {
        expect(outputBox.results.length > 0).toBe(true);
        expect(errorBox.results.length).toBe(0);

        var results = outputBox.results.map(function(result) {
          return result.idlFile;
        });
        var parser = data.Parser.create();

        results.forEach(function(result) {
          var idl = result.contents;
          var parse = parser.parseString(idl);
          expect(parse.pos).toBe(idl.length);
          expect(parse.value).toBeDefined();
        });
        done();
      }.bind(this);

      LocalGitRunner.create({
        repositoryURL: data.repositoryURL,
        sparsePath: data.sparsePath,
        localRepositoryPath: data.localRepositoryPath,
        findExcludePatterns: data.findExcludePatterns,
        idlFileContentsFactory: data.idlFileContentsFactory,
        extension: data.extension,
        fileOutputBox: outputBox,
        errorBox: errorBox,
        onDone: onDone,
      }).run();
    });
  });
};
<commit_msg>Adding extra field to fix manual test break due to addition of sources.<commit_after>// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';

global.parseIDLFileTest = function(data) {
  describe(data.description, function() {
    var execSync = require('child_process').execSync;
    var originalTimeout;
    var LocalGitRunner;
    var outputBox;
    var errorBox;

    afterAll(function() {
      execSync(`/bin/rm -rf "${data.localRepositoryPath}"`);
    });

    beforeEach(function() {
      global.defineAccumulatorBox();

      LocalGitRunner = foam.lookup('org.chromium.webidl.LocalGitRunner');
      var AccumulatorBox = foam.lookup('org.chromium.webidl.test.AccumulatorBox');
      outputBox = AccumulatorBox.create();
      errorBox = AccumulatorBox.create();

      data.GitilesIDLFile = foam.lookup('org.chromium.webidl.GitilesIDLFile');
      data.GithubIDLFile = foam.lookup('org.chromium.webidl.GithubIDLFile');
      data.Parser = foam.lookup(`org.chromium.webidl.${data.parser}`);
      data.IDLFileContents = foam.lookup('org.chromium.webidl.IDLFileContents');

      // Creating temporary directory for repo files.
      // execSync returns a Buffer with a new line character.
      data.localRepositoryPath = execSync('mktemp -d').toString().trim(-1);

      originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
      jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000000;
    });

    it('should fetch git repo and produce valid parse trees', function(done) {
      var onDone = function() {
        expect(outputBox.results.length > 0).toBe(true);
        expect(errorBox.results.length).toBe(0);

        var results = outputBox.results.map(function(result) {
          return result.idlFile;
        });
        var parser = data.Parser.create();

        results.forEach(function(result) {
          var idl = result.contents;
          var parse = parser.parseString(idl, 'Test');
          expect(parse.pos).toBe(idl.length);
          expect(parse.value).toBeDefined();
        });
        done();
      }.bind(this);

      LocalGitRunner.create({
        repositoryURL: data.repositoryURL,
        sparsePath: data.sparsePath,
        localRepositoryPath: data.localRepositoryPath,
        findExcludePatterns: data.findExcludePatterns,
        idlFileContentsFactory: data.idlFileContentsFactory,
        extension: data.extension,
        fileOutputBox: outputBox,
        errorBox: errorBox,
        onDone: onDone,
      }).run();
    });
  });
};
<|endoftext|>


<commit_before>"use strict";
/* global require, module */

var configurable = require('./util/configurable');
var eventLine = require('./eventLine');
var delimiter = require('./delimiter');

module.exports = function (d3) {

  var defaultConfig = {
    start: new Date(0),
    end: new Date(),
    width: 1000,
    margin: {
      top: 60,
      left: 200,
      bottom: 40,
      right: 50
    },
    locale: null,
    axisFormat: null,
    tickFormat: [
        [".%L", function(d) { return d.getMilliseconds(); }],
        [":%S", function(d) { return d.getSeconds(); }],
        ["%I:%M", function(d) { return d.getMinutes(); }],
        ["%I %p", function(d) { return d.getHours(); }],
        ["%a %d", function(d) { return d.getDay() && d.getDate() != 1; }],
        ["%b %d", function(d) { return d.getDate() != 1; }],
        ["%B", function(d) { return d.getMonth(); }],
        ["%Y", function() { return true; }]
    ],
    eventHover: null,
    hasDelimiter: true,
    hasTopAxis: true,
    hasBottomAxis: function (data) {
      return data.length >= 10;
    },
    eventColor: 'black'
  };

  return function eventDrops(config) {
    var xScale = d3.time.scale();
    var yScale = d3.scale.ordinal();
    config = config || {};
    for (var key in defaultConfig) {
      config[key] = config[key] || defaultConfig[key];
    }

    function eventDropGraph(selection) {
      selection.each(function (data) {
        var zoom = d3.behavior.zoom().center(null).on("zoom", updateZoom);

        if (config.hasDelimiter) {
          zoom.on("zoomend", redrawDelimiter);
        }
        var graphWidth = config.width - config.margin.right - config.margin.left;
        var graphHeight = data.length * 40;
        var height = graphHeight + config.margin.top + config.margin.bottom;

        d3.select(this).select('svg').remove();

        var svg = d3.select(this)
          .append('svg')
          .attr('width', config.width)
          .attr('height', height)
        ;

        var graph = svg.append('g')
          .attr('transform', 'translate(0, 25)');

        var yDomain = [];
        var yRange = [];

        data.forEach(function (event, index) {
          yDomain.push(event.name);
          yRange.push(index * 40);
        });

        yScale.domain(yDomain).range(yRange);

        var yAxisEl = graph.append('g')
          .classed('y-axis', true)
          .attr('transform', 'translate(0, 60)');

        var yTick = yAxisEl.append('g').selectAll('g').data(yDomain);

        yTick.enter()
          .append('g')
          .attr('transform', function(d) {
            return 'translate(0, ' + yScale(d) + ')';
          })
          .append('line')
          .classed('y-tick', true)
          .attr('x1', config.margin.left)
          .attr('x2', config.margin.left + graphWidth);

        yTick.exit().remove();

        var curx, cury;
        var zoomRect = svg
          .append('rect')
          .call(zoom)
          .classed('zoom', true)
          .attr('width', graphWidth)
          .attr('height', height )
          .attr('transform', 'translate(' + config.margin.left + ', 35)')
        ;

        if (typeof config.eventHover === 'function') {
          zoomRect.on('mousemove', function(d, e) {
            var event = d3.event;
            if (curx == event.clientX && cury == event.clientY) return;
            curx = event.clientX;
            cury = event.clientY;
            zoomRect.attr('display', 'none');
            var el = document.elementFromPoint(d3.event.clientX, d3.event.clientY);
            zoomRect.attr('display', 'block');
            if (el.tagName !== 'circle') return;
            config.eventHover(el);
          });
        }

        xScale.range([0, graphWidth]).domain([config.start, config.end]);

        zoom.x(xScale);

        function updateZoom() {
          if (d3.event.sourceEvent.toString() === '[object MouseEvent]') {
            zoom.translate([d3.event.translate[0], 0]);
          }

          if (d3.event.sourceEvent.toString() === '[object WheelEvent]') {
            zoom.scale(d3.event.scale);
          }

          redraw();
        }

        function redrawDelimiter() {
          svg.select('.delimiter').remove();
          var delimiterEl = svg
            .append('g')
            .classed('delimiter', true)
            .attr('width', graphWidth)
            .attr('height', 10)
            .attr('transform', 'translate(' + config.margin.left + ', ' + (config.margin.top - 45) + ')')
            .call(delimiter({
              xScale: xScale,
              dateFormat: config.locale ? config.locale.timeFormat("%d %B %Y") : d3.time.format("%d %B %Y")
            }))
          ;
        }

        function drawXAxis(where) {

          // copy config.tickFormat because d3 format.multi edit its given tickFormat data
          var tickFormatData = [];

          config.tickFormat.forEach(function (item) {
            var tick = item.slice(0);
            tickFormatData.push(tick);
          });

          var tickFormat = config.locale ? locale.timeFormat.multi(tickFormatData) : d3.time.format.multi(tickFormatData);
          var xAxis = d3.svg.axis()
            .scale(xScale)
            .orient(where)
            .tickFormat(tickFormat);
          ;

          if (typeof config.axisFormat === 'function') {
            config.axisFormat(xAxis);
          }

          var y = (where == 'bottom' ? parseInt(graphHeight) : 0) + config.margin.top - 40;

          graph.select('.x-axis.' + where).remove();
          var xAxisEl = graph
            .append('g')
            .classed('x-axis', true)
            .classed(where, true)
            .attr('transform', 'translate(' + config.margin.left + ', ' + y + ')')
            .call(xAxis)
          ;
        }

        function redraw() {

          var hasTopAxis = typeof config.hasTopAxis === 'function' ? config.hasTopAxis(data) : config.hasTopAxis;
          if (hasTopAxis) {
            drawXAxis('top');
          }

          var hasBottomAxis = typeof config.hasBottomAxis === 'function' ? config.hasBottomAxis(data) : config.hasBottomAxis;
          if (hasBottomAxis) {
            drawXAxis('bottom');
          }

          zoom.size([config.width, height]);

          graph.select('.graph-body').remove();
          var graphBody = graph
            .append('g')
            .classed('graph-body', true)
            .attr('transform', 'translate(' + config.margin.left + ', ' + (config.margin.top - 15) + ')');

          var lines = graphBody.selectAll('g').data(data);

          lines.enter()
            .append('g')
            .classed('line', true)
            .attr('transform', function(d) {
              return 'translate(0,' + yScale(d.name) + ')';
            })
            .style('fill', config.eventColor)
            .call(eventLine({ xScale: xScale }))
          ;

          lines.exit().remove();
        }

        redraw();
        if (config.hasDelimiter) {
          redrawDelimiter();
        }
      });
    }

    configurable(eventDropGraph, config);

    return eventDropGraph;
  };
};
<commit_msg>fix undefined locale<commit_after>"use strict";
/* global require, module */

var configurable = require('./util/configurable');
var eventLine = require('./eventLine');
var delimiter = require('./delimiter');

module.exports = function (d3) {

  var defaultConfig = {
    start: new Date(0),
    end: new Date(),
    width: 1000,
    margin: {
      top: 60,
      left: 200,
      bottom: 40,
      right: 50
    },
    locale: null,
    axisFormat: null,
    tickFormat: [
        [".%L", function(d) { return d.getMilliseconds(); }],
        [":%S", function(d) { return d.getSeconds(); }],
        ["%I:%M", function(d) { return d.getMinutes(); }],
        ["%I %p", function(d) { return d.getHours(); }],
        ["%a %d", function(d) { return d.getDay() && d.getDate() != 1; }],
        ["%b %d", function(d) { return d.getDate() != 1; }],
        ["%B", function(d) { return d.getMonth(); }],
        ["%Y", function() { return true; }]
    ],
    eventHover: null,
    hasDelimiter: true,
    hasTopAxis: true,
    hasBottomAxis: function (data) {
      return data.length >= 10;
    },
    eventColor: 'black'
  };

  return function eventDrops(config) {
    var xScale = d3.time.scale();
    var yScale = d3.scale.ordinal();
    config = config || {};
    for (var key in defaultConfig) {
      config[key] = config[key] || defaultConfig[key];
    }

    function eventDropGraph(selection) {
      selection.each(function (data) {
        var zoom = d3.behavior.zoom().center(null).on("zoom", updateZoom);

        if (config.hasDelimiter) {
          zoom.on("zoomend", redrawDelimiter);
        }
        var graphWidth = config.width - config.margin.right - config.margin.left;
        var graphHeight = data.length * 40;
        var height = graphHeight + config.margin.top + config.margin.bottom;

        d3.select(this).select('svg').remove();

        var svg = d3.select(this)
          .append('svg')
          .attr('width', config.width)
          .attr('height', height)
        ;

        var graph = svg.append('g')
          .attr('transform', 'translate(0, 25)');

        var yDomain = [];
        var yRange = [];

        data.forEach(function (event, index) {
          yDomain.push(event.name);
          yRange.push(index * 40);
        });

        yScale.domain(yDomain).range(yRange);

        var yAxisEl = graph.append('g')
          .classed('y-axis', true)
          .attr('transform', 'translate(0, 60)');

        var yTick = yAxisEl.append('g').selectAll('g').data(yDomain);

        yTick.enter()
          .append('g')
          .attr('transform', function(d) {
            return 'translate(0, ' + yScale(d) + ')';
          })
          .append('line')
          .classed('y-tick', true)
          .attr('x1', config.margin.left)
          .attr('x2', config.margin.left + graphWidth);

        yTick.exit().remove();

        var curx, cury;
        var zoomRect = svg
          .append('rect')
          .call(zoom)
          .classed('zoom', true)
          .attr('width', graphWidth)
          .attr('height', height )
          .attr('transform', 'translate(' + config.margin.left + ', 35)')
        ;

        if (typeof config.eventHover === 'function') {
          zoomRect.on('mousemove', function(d, e) {
            var event = d3.event;
            if (curx == event.clientX && cury == event.clientY) return;
            curx = event.clientX;
            cury = event.clientY;
            zoomRect.attr('display', 'none');
            var el = document.elementFromPoint(d3.event.clientX, d3.event.clientY);
            zoomRect.attr('display', 'block');
            if (el.tagName !== 'circle') return;
            config.eventHover(el);
          });
        }

        xScale.range([0, graphWidth]).domain([config.start, config.end]);

        zoom.x(xScale);

        function updateZoom() {
          if (d3.event.sourceEvent.toString() === '[object MouseEvent]') {
            zoom.translate([d3.event.translate[0], 0]);
          }

          if (d3.event.sourceEvent.toString() === '[object WheelEvent]') {
            zoom.scale(d3.event.scale);
          }

          redraw();
        }

        function redrawDelimiter() {
          svg.select('.delimiter').remove();
          var delimiterEl = svg
            .append('g')
            .classed('delimiter', true)
            .attr('width', graphWidth)
            .attr('height', 10)
            .attr('transform', 'translate(' + config.margin.left + ', ' + (config.margin.top - 45) + ')')
            .call(delimiter({
              xScale: xScale,
              dateFormat: config.locale ? config.locale.timeFormat("%d %B %Y") : d3.time.format("%d %B %Y")
            }))
          ;
        }

        function drawXAxis(where) {

          // copy config.tickFormat because d3 format.multi edit its given tickFormat data
          var tickFormatData = [];

          config.tickFormat.forEach(function (item) {
            var tick = item.slice(0);
            tickFormatData.push(tick);
          });

          var tickFormat = config.locale ? config.locale.timeFormat.multi(tickFormatData) : d3.time.format.multi(tickFormatData);
          var xAxis = d3.svg.axis()
            .scale(xScale)
            .orient(where)
            .tickFormat(tickFormat);
          ;

          if (typeof config.axisFormat === 'function') {
            config.axisFormat(xAxis);
          }

          var y = (where == 'bottom' ? parseInt(graphHeight) : 0) + config.margin.top - 40;

          graph.select('.x-axis.' + where).remove();
          var xAxisEl = graph
            .append('g')
            .classed('x-axis', true)
            .classed(where, true)
            .attr('transform', 'translate(' + config.margin.left + ', ' + y + ')')
            .call(xAxis)
          ;
        }

        function redraw() {

          var hasTopAxis = typeof config.hasTopAxis === 'function' ? config.hasTopAxis(data) : config.hasTopAxis;
          if (hasTopAxis) {
            drawXAxis('top');
          }

          var hasBottomAxis = typeof config.hasBottomAxis === 'function' ? config.hasBottomAxis(data) : config.hasBottomAxis;
          if (hasBottomAxis) {
            drawXAxis('bottom');
          }

          zoom.size([config.width, height]);

          graph.select('.graph-body').remove();
          var graphBody = graph
            .append('g')
            .classed('graph-body', true)
            .attr('transform', 'translate(' + config.margin.left + ', ' + (config.margin.top - 15) + ')');

          var lines = graphBody.selectAll('g').data(data);

          lines.enter()
            .append('g')
            .classed('line', true)
            .attr('transform', function(d) {
              return 'translate(0,' + yScale(d.name) + ')';
            })
            .style('fill', config.eventColor)
            .call(eventLine({ xScale: xScale }))
          ;

          lines.exit().remove();
        }

        redraw();
        if (config.hasDelimiter) {
          redrawDelimiter();
        }
      });
    }

    configurable(eventDropGraph, config);

    return eventDropGraph;
  };
};
<|endoftext|>


<commit_before>import Vue from 'vue'
import VueHighlightJS from 'vue-highlightjs'

Vue.use(VueHighlightJS)

export default
{
    name: 'viewer',

    components:
    {
    },

    computed:
    {
        version()
        {
            return this.$store.state.files.currentVersion
        },

        linesCount()
        {
            return (this.$store.state.files.currentVersion.content.match(/\n/g) || []).length + 1
        }
    },

    methods:
    {
        onCodeKeyDown(event)
        {
            if(!event.metaKey && !event.ctrlKey)
            {
                event.preventDefault()
            }
            else
            {
                if(event.keyCode === 88 || event.keyCode === 86)
                {
                    event.preventDefault()
                }
            }
        }
    }
}<commit_msg>:bug: Site > Viewer > Enable arrows<commit_after>import Vue from 'vue'
import VueHighlightJS from 'vue-highlightjs'

Vue.use(VueHighlightJS)

export default
{
    name: 'viewer',

    components:
    {
    },

    computed:
    {
        version()
        {
            return this.$store.state.files.currentVersion
        },

        linesCount()
        {
            return (this.$store.state.files.currentVersion.content.match(/\n/g) || []).length + 1
        }
    },

    methods:
    {
        onCodeKeyDown(event)
        {
            // Not arrow keys
            if(
                event.keyCode !== 38 &&
                event.keyCode !== 39 &&
                event.keyCode !== 30 &&
                event.keyCode !== 37
            )
            {
                // Not meta keys
                if(!event.metaKey && !event.ctrlKey)
                {
                    event.preventDefault()
                }

                // Meta keys
                else
                {
                    // Cut (meta + x) or past (meta + v) keys
                    if(event.keyCode === 88 || event.keyCode === 86)
                    {
                        event.preventDefault()
                    }
                }
            }
        }
    }
}<|endoftext|>


<commit_before>// ezservices.js
"use strict";

var exec, util, events, clc, fs, path, tilde;
exec   = require('child_process').exec;
util   = require('util');
events = require('events');
clc    = require('cli-color');
fs     = require('fs');
path   = require('path');
tilde  = require('tilde-expansion');

// +-----------------------+
// |    EzService class    |
// +-----------------------+
//
// Each LaunchAgents found on the Mac will be instancied as an EzService
// Methods availables:
//    start | stop | restart
//

function EzService(path) {
  EzService.prototype.__proto__ = events.EventEmitter.prototype;
  this.path = path;
}

EzService.prototype = {
  start: function (alias) {
    var self = this;
    this.method = 'load';
    exec('launchctl load ' + this.path, function (err, stdout, stderr) {
      self.parseLogs(alias, err, stdout, stderr);
    });
  },
  stop: function (alias) {
    var self = this;
    this.method = 'unload';
    exec('launchctl unload ' + this.path, function (err, stdout, stderr) {
      self.parseLogs(alias, err, stdout, stderr);
    });
  },
  restart: function (alias) {
    var self = this;
    this.on(alias+':unloaded', function () {
      self.start(alias);
    });
    this.stop(alias);
  },
  status: function (alias) {
    exec('launchctl list | grep ' + alias, function (err, stdout, stderr) {
      var regex = new RegExp('\\b' + alias + '\\b');
      if (regex.test(stdout)) return console.log(clc.green(alias + ' is running.'));
      return console.log(clc.red(alias + ' is not running.'));
    });
  },
  edit: function (alias) {
    var editor = 'open -t'
    if (process.env.EDITOR) editor = process.env.EDITOR
    exec(editor + ' ' + this.path, function (err, stdout, stderr) {
      if (err) return console.log(clc.red('Error with opening ' + alias + ' LaunchAgent plist.'));
      if (stderr == '' && stdout == '') return console.log(clc.green(alias + 'LaunchAgent plist opened.'));
    });
  },
  parseLogs: function (service, err, stdout, stderr) {
    if (err) {
      console.log(clc.red('Error with service : \'' + service + '\''));
      console.log(clc.red(stderr));
    } else {
      if ((stdout == '') && (stderr == '')) {
        // console.log(stdout);
        if (this.method == 'load') console.log(clc.green(service + ' correctly started.'));
        if (this.method == 'unload') console.log(clc.green(service + ' correctly stopped.'));
      }
      if (stderr) {
        // console.log(stderr);
        if (this.method == 'load') console.log(clc.blue(service + ' already started.'));
        if (this.method == 'unload') console.log(clc.blue(service + ' aleady stopped.'));
      }
      var event = service + ':' + this.method + 'ed';
      // console.log(event);
      this.emit(event);
    }
  }
}

// +--------------------+
// |  EzServices Class  |
// +--------------------+
//
// This is the class binded to the CLI 'ezservices'
// It will at start find all the availables LaunchAgents on the Mac
// and it will create EzService for each LaunchAgents found.
//
// It has an array of EzService, easy to call methods on them.
//
// Events:
//    - 'services:listed' is fired whend the services are found, kinda equivalent as a ready event.
//

function EzServices() {
  EzServices.prototype.__proto__ = events.EventEmitter.prototype;
  this.agentsDirectories = ['/Library/LaunchAgents/', '~/Library/LaunchAgents/'];
  this.services = [];

  // Get an array of all services
  var count    = 0;
  var services = [];
  var self     = this;
  var callback = function (path, error, stdout, stderr) {
    count++;
    if (stdout) {
      for (var i = 0; i < stdout.split('\n').length; i++) {
        if (stdout.split('\n')[i] != '') services.push(path + stdout.split('\n')[i]);
      };
    }
    if (count  === self.agentsDirectories.length) {
      self.emit('services:listed', services);
    }
  }
  for (var i = 0; i < self.agentsDirectories.length; i++) {
    (function () {
      var path = self.agentsDirectories[i];
      exec('ls ' + self.agentsDirectories[i], function (error, stdout, stderr) {
        callback(path, error, stdout, stderr);
      });
    })();
  };

  // When we have the list of all services instance the EzService class for each
  this.on('services:listed', function (services) {
    for (var i = 0; i < services.length; i++) {
      self.services.push(new EzService(services[i]));
    };
  });
}

EzServices.prototype = {
  showService: function (servicesAsked) {
    if (servicesAsked[0] == 'all') return this.listServices();
    this.on('services:listed', function (services) {
      for (var i = 0; i < servicesAsked.length; i++) {
        var regex = new RegExp('\\b'+ servicesAsked[i] + '\\b');
        for (var _i = 0; _i < services.length; _i++) {
          if (regex.test(services[_i])) { console.log(clc.yellow(services[_i])) }
        };
      };
    });
  },
  listServices: function () {
    this.on('services:listed', function (services) {
      for (var i = 0; i < services.length; i++) { console.log(clc.yellow(services[i])) };
    });
  },
  execOperation: function (method, servicesAsked) {
    var self = this;
    this.on('services:listed', function () {
      if (servicesAsked[0] == 'all') {
        for (var i = 0; i < self.services.length; i++) {
          self.services[i][method](self.services[i].path);
        };
      } else {
        for (var i = 0; i < self.services.length; i++) {
          for (var _i = 0; _i < servicesAsked.length; _i++) {
            var serviceName = servicesAsked[_i];
            var regex = new RegExp('\\b' + serviceName + '\\b');
            if (regex.test(self.services[i].path)) {
              self.services[i][method](servicesAsked[_i]);
            }
          };
        };
      }
    });
  },
  removeService: function (service) {
    var self  = this;
    var count = 0;
    var found = false;
    var regex = new RegExp('\\b' + service + '\\b');
    this.on('services:listed', function (services) {
      for (var i = 0; i < services.length; i++) {
        count++;
        if (regex.test(services[i])) {
          found = true;
          tilde(services[i], function (filePath) {
            fs.unlink(filePath, function (err) {
              if (err) return console.log(clc.red('Error with removing the service\n', err));
              console.log(clc.green('Service correctly removed!'));
            });
          });
        }
        if (count === services.length && !found) return console.log(clc.red('Service not found.'));
      };
    })
  },
  installService: function (filePath) {
    var self     = this;
    var nbOfDir  = this.agentsDirectories.length;
    var filename = path.basename(filePath);
    var results  = [];
    fs.exists(filePath, function (exists){
      if (!exists) return console.log(clc.red('plist you want to install doesn\'t exists.'));
      for (var i = 0; i < self.agentsDirectories.length; i++) {
        tilde(self.agentsDirectories[i]+filename, function (newFilePath) {
          fs.exists(newFilePath, function (exists) {
            results.push(exists);
            if (results.length === nbOfDir) {
              if (results[0] || results[1]) return console.log(clc.blue("plist arlready installed."));
              var cmd = 'cp ' + filePath + ' ' + self.agentsDirectories[1];
              // console.log(cmd);
              exec(cmd, function(err, stdout, stderr) {
                if (err) return console.log(clc.red('Error with copying the file\n', stderr));
                if (stdout == '' && stderr == '') return console.log(clc.green('Your plist was correctly installed!'));
              });
            }
          });
        });
      };
    });
  }
}

module.exports = new EzServices();
<commit_msg>fix some linting errors<commit_after>// ezservices.js
"use strict";

var exec, util, events, clc, fs, path, tilde;
exec   = require('child_process').exec;
util   = require('util');
events = require('events');
clc    = require('cli-color');
fs     = require('fs');
path   = require('path');
tilde  = require('tilde-expansion');

// +-----------------------+
// |    EzService class    |
// +-----------------------+
//
// Each LaunchAgents found on the Mac will be instancied as an EzService
// Methods availables:
//    start | stop | restart
//

function EzService(path) {
  EzService.prototype.__proto__ = events.EventEmitter.prototype;
  this.path = path;
}

EzService.prototype = {
  start: function (alias) {
    var self = this;
    this.method = 'load';
    exec('launchctl load ' + this.path, function (err, stdout, stderr) {
      self.parseLogs(alias, err, stdout, stderr);
    });
  },
  stop: function (alias) {
    var self = this;
    this.method = 'unload';
    exec('launchctl unload ' + this.path, function (err, stdout, stderr) {
      self.parseLogs(alias, err, stdout, stderr);
    });
  },
  restart: function (alias) {
    var self = this;
    this.on(alias+':unloaded', function () {
      self.start(alias);
    });
    this.stop(alias);
  },
  status: function (alias) {
    exec('launchctl list | grep ' + alias, function (err, stdout, stderr) {
      var regex = new RegExp('\\b' + alias + '\\b');
      if (regex.test(stdout)) return console.log(clc.green(alias + ' is running.'));
      return console.log(clc.red(alias + ' is not running.'));
    });
  },
  edit: function (alias) {
    var editor = 'open -t';
    if (process.env.EDITOR) editor = process.env.EDITOR;
    exec(editor + ' ' + this.path, function (err, stdout, stderr) {
      if (err) return console.log(clc.red('Error with opening ' + alias + ' LaunchAgent plist.'));
      if (stderr === '' && stdout === '') return console.log(clc.green(alias + 'LaunchAgent plist opened.'));
    });
  },
  parseLogs: function (service, err, stdout, stderr) {
    if (err) {
      console.log(clc.red('Error with service : \'' + service + '\''));
      console.log(clc.red(stderr));
    } else {
      if ((stdout === '') && (stderr === '')) {
        // console.log(stdout);
        if (this.method === 'load') console.log(clc.green(service + ' correctly started.'));
        if (this.method === 'unload') console.log(clc.green(service + ' correctly stopped.'));
      }
      if (stderr) {
        // console.log(stderr);
        if (this.method === 'load') console.log(clc.blue(service + ' already started.'));
        if (this.method === 'unload') console.log(clc.blue(service + ' aleady stopped.'));
      }
      var event = service + ':' + this.method + 'ed';
      // console.log(event);
      this.emit(event);
    }
  }
};

// +--------------------+
// |  EzServices Class  |
// +--------------------+
//
// This is the class binded to the CLI 'ezservices'
// It will at start find all the availables LaunchAgents on the Mac
// and it will create EzService for each LaunchAgents found.
//
// It has an array of EzService, easy to call methods on them.
//
// Events:
//    - 'services:listed' is fired whend the services are found, kinda equivalent as a ready event.
//

function EzServices() {
  EzServices.prototype.__proto__ = events.EventEmitter.prototype;
  this.agentsDirectories = ['/Library/LaunchAgents/', '~/Library/LaunchAgents/'];
  this.services = [];

  // Get an array of all services
  var count    = 0;
  var services = [];
  var self     = this;
  var callback = function (path, error, stdout, stderr) {
    count++;
    if (stdout) {
      for (var i = 0; i < stdout.split('\n').length; i++) {
        if (stdout.split('\n')[i] !== '') services.push(path + stdout.split('\n')[i]);
      }
    }
    if (count  === self.agentsDirectories.length) {
      self.emit('services:listed', services);
    }
  };
  for (var i = 0; i < self.agentsDirectories.length; i++) {
    (function () {
      var path = self.agentsDirectories[i];
      exec('ls ' + self.agentsDirectories[i], function (error, stdout, stderr) {
        callback(path, error, stdout, stderr);
      });
    })();
  }

  // When we have the list of all services instance the EzService class for each
  this.on('services:listed', function (services) {
    for (var i = 0; i < services.length; i++) {
      self.services.push(new EzService(services[i]));
    }
  });
}

EzServices.prototype = {
  showService: function (servicesAsked) {
    if (servicesAsked[0] === 'all') return this.listServices();
    this.on('services:listed', function (services) {
      for (var i = 0; i < servicesAsked.length; i++) {
        var regex = new RegExp('\\b'+ servicesAsked[i] + '\\b');
        for (var _i = 0; _i < services.length; _i++) {
          if (regex.test(services[_i])) { console.log(clc.yellow(services[_i])) }
        }
      }
    });
  },
  listServices: function () {
    this.on('services:listed', function (services) {
      for (var i = 0; i < services.length; i++) { console.log(clc.yellow(services[i])) };
    });
  },
  execOperation: function (method, servicesAsked) {
    var self = this;
    this.on('services:listed', function () {
      var i = 0;
      if (servicesAsked[0] === 'all') {
        for (i; i < self.services.length; i++) {
          self.services[i][method](self.services[i].path);
        }
      } else {
        for (i; i < self.services.length; i++) {
          for (var _i = 0; _i < servicesAsked.length; _i++) {
            var serviceName = servicesAsked[_i];
            var regex = new RegExp('\\b' + serviceName + '\\b');
            if (regex.test(self.services[i].path)) {
              self.services[i][method](servicesAsked[_i]);
            }
          }
        }
      }
    });
  },
  removeService: function (service) {
    var self  = this;
    var count = 0;
    var found = false;
    var regex = new RegExp('\\b' + service + '\\b');
    this.on('services:listed', function (services) {
      for (var i = 0; i < services.length; i++) {
        count++;
        if (regex.test(services[i])) {
          found = true;
          tilde(services[i], function (filePath) {
            fs.unlink(filePath, function (err) {
              if (err) return console.log(clc.red('Error with removing the service\n', err));
              console.log(clc.green('Service correctly removed!'));
            });
          });
        }
        if (count === services.length && !found) return console.log(clc.red('Service not found.'));
      }
    });
  },
  installService: function (filePath) {
    var self     = this;
    var nbOfDir  = this.agentsDirectories.length;
    var filename = path.basename(filePath);
    var results  = [];
    fs.exists(filePath, function (exists){
      if (!exists) return console.log(clc.red('plist you want to install doesn\'t exists.'));
      for (var i = 0; i < self.agentsDirectories.length; i++) {
        tilde(self.agentsDirectories[i]+filename, function (newFilePath) {
          fs.exists(newFilePath, function (exists) {
            results.push(exists);
            if (results.length === nbOfDir) {
              if (results[0] || results[1]) return console.log(clc.blue("plist arlready installed."));
              var cmd = 'cp ' + filePath + ' ' + self.agentsDirectories[1];
              // console.log(cmd);
              exec(cmd, function(err, stdout, stderr) {
                if (err) return console.log(clc.red('Error with copying the file\n', stderr));
                if (stdout === '' && stderr === '') return console.log(clc.green('Your plist was correctly installed!'));
              });
            }
          });
        });
      }
    });
  }
};

module.exports = new EzServices();<|endoftext|>