<commit_before>const Polyglot = require('node-polyglot');
const Locale = require('locale/index');

const ACTIVE_LOCALE = window.ACTIVE_LOCALE || 'en';
const polyglot = new Polyglot({
  locale: ACTIVE_LOCALE, // Needed for pluralize behaviour
  phrases: Locale[ACTIVE_LOCALE]
});
window._t = polyglot.t.bind(polyglot);

const $ = require('jquery');
const _ = require('underscore');
const Backbone = require('backbone');
const UserModel = require('dashboard/data/user-model');
const OrganizationModel = require('dashboard/data/organization-model');
const ConfigModel = require('dashboard/data/config-model');
const DashboardHeaderView = require('dashboard/components/dashboard-header-view');
const HeaderViewModel = require('./views/organization/header-view-model');
const LocalStorage = require('dashboard/helpers/local-storage');
const FlashMessageModel = require('dashboard/data/flash-message-model');
const FlashMessageView = require('dashboard/components/flash-message/flash-message-view');
const TipsyTooltipView = require('builder/components/tipsy-tooltip-view');
const OrganizationUsersView = require('dashboard/views/organization/organization-users/organization-users-view');
const OrganizationNotificationView = require('dashboard/views/organization/organization-notification/organization-notification-view');
const OrganizationUserQuota = require('dashboard/views/organization/organization-user-quota');
const AvatarSelector = require('dashboard/components/avatar-selector/avatar-selector-view');
const OrganizationUserForm = require('dashboard/views/organization/organization-user-form');
const RegenerateKeysDialog = require('dashboard/views/organization/regenerate-keys-dialog-view');
const ModalsServiceModel = require('builder/components/modals/modals-service-model');
const DeleteOrganization = require('dashboard/views/organization/delete-organization-view');
const IconPickerView = require('dashboard/views/organization/icon-picker/organization-icon-picker-view');
const DeleteOrganizationUser = require('dashboard/views/organization/delete-organization-user-view');
const GroupsRouter = require('dashboard/common/router-organization-groups');
const GroupsMainView = require('dashboard/views/organization/groups-admin/groups-main-view');
const OrganizationGroupsCollection = require('dashboard/data/organization-groups-collection');
const PasswordValidatedForm = require('dashboard/helpers/password-validated-form');
const getObjectValue = require('deep-insights/util/get-object-value');
require('dashboard/data/backbone/sync-options');

const ForbiddenAction = require('builder/data/backbone/network-interceptors/interceptors/forbidden-403');
const NetworkResponseInterceptor = require('builder/data/backbone/network-interceptors/interceptor');
NetworkResponseInterceptor.addURLPattern('api/v');
NetworkResponseInterceptor.addErrorInterceptor(ForbiddenAction());
NetworkResponseInterceptor.start();

const DOMAIN_REGEXP = /^[a-zA-Z0-9*][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,3})$/;
const configModel = new ConfigModel(
  _.defaults(
    {
      base_url: window.user_data.base_url,
      url_prefix: window.user_data.base_url
    },
    window.config
  )
);

if (window.trackJs) {
  window.trackJs.configure({
    userId: window.user_data.username
  });
}

/**
 *  Entry point for the new organization, bootstraps all
 *  dependency models and application.
 */

$(function () {
  let organizationUser;
  let organization;
  let organizationUsers;

  const modalsService = new ModalsServiceModel();

  const userModel = new UserModel(window.user_data, { configModel });

  if (window.user_data.organization) {
    organization = new OrganizationModel({
      ...window.user_data.organization,
      ...window.organization_data
    }, {
      userModel,
      configModel,
      currentUserId: window.user_data.id
    });
    organizationUsers = organization.users;
    organization.owner = new UserModel(getObjectValue(window.user_data, 'organization.owner'));
    userModel.setOrganization(organization);
  }

  if (window.organization_user_data) {
    organizationUser = new UserModel(window.organization_user_data, { configModel });

    if (organization) {
      organizationUser.setOrganization(organization);
      organizationUser.organization.set(
        'available_quota_for_user',
        window.organization_user_data.organization.available_quota_for_user
      )
    }
  }

  const headerView = new DashboardHeaderView({
    el: $('#header'), // pre-rendered in DOM by Rails app
    model: userModel,
    userModelUrl: userModel.viewUrl(),
    viewModel: new HeaderViewModel(),
    localStorage: new LocalStorage(),
    configModel
  });
  headerView.render();

  const flashMessageModel = new FlashMessageModel();
  const flashMessageView = new FlashMessageView({
    model: flashMessageModel
  });
  flashMessageView.render();
  flashMessageView.$el.insertAfter(headerView.$el);

  // Avatar
  if ($('.js-avatarSelector').length > 0) {
    const avatarSelector = new AvatarSelector({
      el: $('.js-avatarSelector'),
      renderModel: new Backbone.Model({
        inputName: $('.js-fileAvatar').attr('name'),
        name: userModel.organization.get('name'),
        avatar_url: userModel.organization.get('avatar_url'),
        id: userModel.get('id')
      }),
      avatarAcceptedExtensions: window.avatar_valid_extensions,
      configModel
    });

    avatarSelector.render();
  }

  // Tooltips
  $('[data-title]').each(function (i, el) {
    new TipsyTooltipView({ // eslint-disable-line
      el: el,
      title: function () {
        return $(this).attr('data-title');
      }
    });
  });

  // Icon picker
  if ($('.js-iconPicker').length > 0) {
    this.icon_picker_view = new IconPickerView({
      el: $('.js-iconPicker'),
      orgId: userModel.organization.get('id'),
      configModel
    });
  }

  // Domain whitelisting
  if ($('.js-domains').length > 0) {
    require('jquery-ui');
    require('tagit');

    $('.js-domainsList').tagit({
      allowSpaces: false,
      singleField: true,
      singleFieldNode: $('.js-whitelist'),
      fieldName: $('.js-whitelist').attr('name'),
      tagLimit: 10,
      readOnly: false,
      onBlur: function () {
        $('.js-domains').removeClass('is-focus');

        if ($('.tagit-choice').length > 0) {
          $('.js-placeholder').hide();
        } else {
          $('.js-placeholder').show();
        }

        if ($('.tagit-new').length > 0) {
          $('.tagit-new input').val('');
        }
      },
      onFocus: function () {
        $('.js-domains').addClass('is-focus');

        $('.js-placeholder').hide();
      },
      beforeTagAdded: function (ev, ui) {
        if (!DOMAIN_REGEXP.test(ui.tagLabel)) {
          return false;
        }

        if ($('.tagit-choice').length > 0) {
          $('.js-placeholder').hide();
        } else { $('.js-placeholder').show(); }
      },
      afterTagAdded: function (ev, ui) {
        if ($('.tagit-choice').length > 0) {
          $('.js-placeholder').hide();
        } else { $('.js-placeholder').show(); }
      }
    });
  }

  // Organization user form
  if (organizationUser) {
    this.organization_user_form = new OrganizationUserForm({
      el: $('.js-organizationUserForm'),
      model: organizationUser
    });
  }

  // User quota main view
  if (organizationUser) {
    this.organization_user_quota = new OrganizationUserQuota({
      el: $('.js-userQuota'),
      model: organizationUser
    });
  }

  // Organization users list
  if ($('.js-orgUsersList').length === 1) {
    this.organizationUsersView = new OrganizationUsersView({
      el: '.js-orgUsersList',
      organization,
      organizationUsers,
      userModel,
      configModel
    });

    this.organizationUsersView.render();
  }

  // User deletion
  const deleteAccountButton = $('.js-deleteAccount');
  if (deleteAccountButton.length > 0 && window.authenticity_token) {
    deleteAccountButton.click(function (ev) {
      if (ev) {
        ev.preventDefault();
      }

      modalsService.create(modalModel =>
        new DeleteOrganizationUser({
          modalModel,
          configModel,
          organizationUser,
          authenticityToken: window.authenticity_token,
          passwordNeeded: userModel.needsPasswordConfirmation()
        })
      );
    });
  }

  // Organization deletion
  if ($('.js-deleteOrganization').length > 0 && window.authenticity_token) {
    $('.js-deleteOrganization').click(function (event) {
      if (event) event.preventDefault();

      modalsService.create(modalModel => (
        new DeleteOrganization({
          authenticityToken: window.authenticity_token,
          userModel,
          modalModel
        })
      ));
    });
  }

  // Notifications
  if ($('.js-OrganizationNotification').length > 0) {
    const authenticityToken = $('[name=authenticity_token][value]').get(0).value;

    this.organization_notification_view = new OrganizationNotificationView({
      el: '.js-OrganizationNotification',
      authenticityToken,
      userModel
    });

    this.organization_notification_view.render();
  }

  // User quotas
  const toggleUserQuotas = function () {
    const viewer = $('.js-userViewerOption:checked').val();
    if (viewer === 'true') {
      $('.user-quotas').hide();
      $('.js-org-admin-row').hide();
      $('#org_admin').prop('checked', false);
    } else {
      $('.user-quotas').show();
      $('.js-org-admin-row').show();
    }
  };

  toggleUserQuotas();

  $('.js-userViewerOption').bind('change', function (ev) {
    toggleUserQuotas();
  });

  // API keys
  const regenerateApiKeyHandler = function (event, scope, form_action) {
    if (event) event.preventDefault();

    const authenticity_token = $('[name=authenticity_token][value]').get(0).value;

    modalsService.create(modalModel => (
      new RegenerateKeysDialog({
        type: 'api',
        scope,
        form_action,
        authenticity_token,
        modalModel,
        passwordNeeded: userModel.needsPasswordConfirmation()
      })
    ));
  };

  $('.js-regenerateOrgUsersApiKey').bind('click', function (event) {
    const current_username = $(this).attr('data-current_username');

    regenerateApiKeyHandler(event, 'organization', `/u/${current_username}/organization/regenerate_api_keys`);
  });

  $('.js-regenerateOrgUserApiKey').bind('click', function (ev) {
    const username = $(this).attr('data-username');
    const current_username = $(this).attr('data-current_username');

    regenerateApiKeyHandler(ev, 'organization_user', `/u/${current_username}/organization/users/${username}/regenerate_api_key`);
  });

  const $groups = $('.js-groups-content');
  if ($groups) {
    if (!userModel.isOrgAdmin()) {
      window.location = userModel.viewUrl().accountProfile();
      return false;
    }

    const groups = new OrganizationGroupsCollection([], {
      organization: userModel.organization,
      configModel
    });

    const router = new GroupsRouter({
      rootUrl: userModel.viewUrl().organization().groups(),
      flashMessageModel,
      groups,
      userModel,
      modals: modalsService
    });

    const groupsMainView = new GroupsMainView({
      el: $groups,
      groups,
      routerModel: router,
      user: userModel
    });
    groupsMainView.render();

    router.enableAfterMainView();
  }

  // Password Expiration
  const listenToExpirationSettingsChanges = function () {
    const expirationInput = $('#organization_password_expiration_in_d');
    const unlimitedExpirationInput = $('#unlimited_password_expiration');

    unlimitedExpirationInput.change(function () {
      const isChecked = this.checked;
      isChecked ? expirationInput.attr('disabled', 'disabled') : expirationInput.removeAttr('disabled');
      expirationInput.val(null);
    });
  };
  listenToExpirationSettingsChanges();

  // Form Validations
  PasswordValidatedForm.bindEventTo('.FormAccount-Content form', {
    modals: modalsService,
    passwordConfirmationNeeded: userModel.get('needs_password_confirmation')
  });
});
<commit_msg>Fix hound issues<commit_after>const Polyglot = require('node-polyglot');
const Locale = require('locale/index');

const ACTIVE_LOCALE = window.ACTIVE_LOCALE || 'en';
const polyglot = new Polyglot({
  locale: ACTIVE_LOCALE, // Needed for pluralize behaviour
  phrases: Locale[ACTIVE_LOCALE]
});
window._t = polyglot.t.bind(polyglot);

const $ = require('jquery');
const _ = require('underscore');
const Backbone = require('backbone');
const UserModel = require('dashboard/data/user-model');
const OrganizationModel = require('dashboard/data/organization-model');
const ConfigModel = require('dashboard/data/config-model');
const DashboardHeaderView = require('dashboard/components/dashboard-header-view');
const HeaderViewModel = require('./views/organization/header-view-model');
const LocalStorage = require('dashboard/helpers/local-storage');
const FlashMessageModel = require('dashboard/data/flash-message-model');
const FlashMessageView = require('dashboard/components/flash-message/flash-message-view');
const TipsyTooltipView = require('builder/components/tipsy-tooltip-view');
const OrganizationUsersView = require('dashboard/views/organization/organization-users/organization-users-view');
const OrganizationNotificationView = require('dashboard/views/organization/organization-notification/organization-notification-view');
const OrganizationUserQuota = require('dashboard/views/organization/organization-user-quota');
const AvatarSelector = require('dashboard/components/avatar-selector/avatar-selector-view');
const OrganizationUserForm = require('dashboard/views/organization/organization-user-form');
const RegenerateKeysDialog = require('dashboard/views/organization/regenerate-keys-dialog-view');
const ModalsServiceModel = require('builder/components/modals/modals-service-model');
const DeleteOrganization = require('dashboard/views/organization/delete-organization-view');
const IconPickerView = require('dashboard/views/organization/icon-picker/organization-icon-picker-view');
const DeleteOrganizationUser = require('dashboard/views/organization/delete-organization-user-view');
const GroupsRouter = require('dashboard/common/router-organization-groups');
const GroupsMainView = require('dashboard/views/organization/groups-admin/groups-main-view');
const OrganizationGroupsCollection = require('dashboard/data/organization-groups-collection');
const PasswordValidatedForm = require('dashboard/helpers/password-validated-form');
const getObjectValue = require('deep-insights/util/get-object-value');
require('dashboard/data/backbone/sync-options');

const ForbiddenAction = require('builder/data/backbone/network-interceptors/interceptors/forbidden-403');
const NetworkResponseInterceptor = require('builder/data/backbone/network-interceptors/interceptor');
NetworkResponseInterceptor.addURLPattern('api/v');
NetworkResponseInterceptor.addErrorInterceptor(ForbiddenAction());
NetworkResponseInterceptor.start();

const DOMAIN_REGEXP = /^[a-zA-Z0-9*][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,3})$/;
const configModel = new ConfigModel(
  _.defaults(
    {
      base_url: window.user_data.base_url,
      url_prefix: window.user_data.base_url
    },
    window.config
  )
);

if (window.trackJs) {
  window.trackJs.configure({
    userId: window.user_data.username
  });
}

/**
 *  Entry point for the new organization, bootstraps all
 *  dependency models and application.
 */

$(function () {
  let organizationUser;
  let organization;
  let organizationUsers;

  const modalsService = new ModalsServiceModel();

  const userModel = new UserModel(window.user_data, { configModel });

  if (window.user_data.organization) {
    organization = new OrganizationModel({
      ...window.user_data.organization,
      ...window.organization_data
    }, {
      userModel,
      configModel,
      currentUserId: window.user_data.id
    });
    organizationUsers = organization.users;
    organization.owner = new UserModel(getObjectValue(window.user_data, 'organization.owner'));
    userModel.setOrganization(organization);
  }

  if (window.organization_user_data) {
    organizationUser = new UserModel(window.organization_user_data, { configModel });

    if (organization) {
      organizationUser.setOrganization(organization);
      organizationUser.organization.set(
        'available_quota_for_user',
        window.organization_user_data.organization.available_quota_for_user
      );
    }
  }

  const headerView = new DashboardHeaderView({
    el: $('#header'), // pre-rendered in DOM by Rails app
    model: userModel,
    userModelUrl: userModel.viewUrl(),
    viewModel: new HeaderViewModel(),
    localStorage: new LocalStorage(),
    configModel
  });
  headerView.render();

  const flashMessageModel = new FlashMessageModel();
  const flashMessageView = new FlashMessageView({
    model: flashMessageModel
  });
  flashMessageView.render();
  flashMessageView.$el.insertAfter(headerView.$el);

  // Avatar
  if ($('.js-avatarSelector').length > 0) {
    const avatarSelector = new AvatarSelector({
      el: $('.js-avatarSelector'),
      renderModel: new Backbone.Model({
        inputName: $('.js-fileAvatar').attr('name'),
        name: userModel.organization.get('name'),
        avatar_url: userModel.organization.get('avatar_url'),
        id: userModel.get('id')
      }),
      avatarAcceptedExtensions: window.avatar_valid_extensions,
      configModel
    });

    avatarSelector.render();
  }

  // Tooltips
  $('[data-title]').each(function (i, el) {
    new TipsyTooltipView({ // eslint-disable-line
      el: el,
      title: function () {
        return $(this).attr('data-title');
      }
    });
  });

  // Icon picker
  if ($('.js-iconPicker').length > 0) {
    this.icon_picker_view = new IconPickerView({
      el: $('.js-iconPicker'),
      orgId: userModel.organization.get('id'),
      configModel
    });
  }

  // Domain whitelisting
  if ($('.js-domains').length > 0) {
    require('jquery-ui');
    require('tagit');

    $('.js-domainsList').tagit({
      allowSpaces: false,
      singleField: true,
      singleFieldNode: $('.js-whitelist'),
      fieldName: $('.js-whitelist').attr('name'),
      tagLimit: 10,
      readOnly: false,
      onBlur: function () {
        $('.js-domains').removeClass('is-focus');

        if ($('.tagit-choice').length > 0) {
          $('.js-placeholder').hide();
        } else {
          $('.js-placeholder').show();
        }

        if ($('.tagit-new').length > 0) {
          $('.tagit-new input').val('');
        }
      },
      onFocus: function () {
        $('.js-domains').addClass('is-focus');

        $('.js-placeholder').hide();
      },
      beforeTagAdded: function (ev, ui) {
        if (!DOMAIN_REGEXP.test(ui.tagLabel)) {
          return false;
        }

        if ($('.tagit-choice').length > 0) {
          $('.js-placeholder').hide();
        } else { $('.js-placeholder').show(); }
      },
      afterTagAdded: function (ev, ui) {
        if ($('.tagit-choice').length > 0) {
          $('.js-placeholder').hide();
        } else { $('.js-placeholder').show(); }
      }
    });
  }

  // Organization user form
  if (organizationUser) {
    this.organization_user_form = new OrganizationUserForm({
      el: $('.js-organizationUserForm'),
      model: organizationUser
    });
  }

  // User quota main view
  if (organizationUser) {
    this.organization_user_quota = new OrganizationUserQuota({
      el: $('.js-userQuota'),
      model: organizationUser
    });
  }

  // Organization users list
  if ($('.js-orgUsersList').length === 1) {
    this.organizationUsersView = new OrganizationUsersView({
      el: '.js-orgUsersList',
      organization,
      organizationUsers,
      userModel,
      configModel
    });

    this.organizationUsersView.render();
  }

  // User deletion
  const deleteAccountButton = $('.js-deleteAccount');
  if (deleteAccountButton.length > 0 && window.authenticity_token) {
    deleteAccountButton.click(function (ev) {
      if (ev) {
        ev.preventDefault();
      }

      modalsService.create(modalModel =>
        new DeleteOrganizationUser({
          modalModel,
          configModel,
          organizationUser,
          authenticityToken: window.authenticity_token,
          passwordNeeded: userModel.needsPasswordConfirmation()
        })
      );
    });
  }

  // Organization deletion
  if ($('.js-deleteOrganization').length > 0 && window.authenticity_token) {
    $('.js-deleteOrganization').click(function (event) {
      if (event) event.preventDefault();

      modalsService.create(modalModel => (
        new DeleteOrganization({
          authenticityToken: window.authenticity_token,
          userModel,
          modalModel
        })
      ));
    });
  }

  // Notifications
  if ($('.js-OrganizationNotification').length > 0) {
    const authenticityToken = $('[name=authenticity_token][value]').get(0).value;

    this.organization_notification_view = new OrganizationNotificationView({
      el: '.js-OrganizationNotification',
      authenticityToken,
      userModel
    });

    this.organization_notification_view.render();
  }

  // User quotas
  const toggleUserQuotas = function () {
    const viewer = $('.js-userViewerOption:checked').val();
    if (viewer === 'true') {
      $('.user-quotas').hide();
      $('.js-org-admin-row').hide();
      $('#org_admin').prop('checked', false);
    } else {
      $('.user-quotas').show();
      $('.js-org-admin-row').show();
    }
  };

  toggleUserQuotas();

  $('.js-userViewerOption').bind('change', function (ev) {
    toggleUserQuotas();
  });

  // API keys
  const regenerateApiKeyHandler = function (event, scope, form_action) {
    if (event) event.preventDefault();

    const authenticity_token = $('[name=authenticity_token][value]').get(0).value;

    modalsService.create(modalModel => (
      new RegenerateKeysDialog({
        type: 'api',
        scope,
        form_action,
        authenticity_token,
        modalModel,
        passwordNeeded: userModel.needsPasswordConfirmation()
      })
    ));
  };

  $('.js-regenerateOrgUsersApiKey').bind('click', function (event) {
    const current_username = $(this).attr('data-current_username');

    regenerateApiKeyHandler(event, 'organization', `/u/${current_username}/organization/regenerate_api_keys`);
  });

  $('.js-regenerateOrgUserApiKey').bind('click', function (ev) {
    const username = $(this).attr('data-username');
    const current_username = $(this).attr('data-current_username');

    regenerateApiKeyHandler(ev, 'organization_user', `/u/${current_username}/organization/users/${username}/regenerate_api_key`);
  });

  const $groups = $('.js-groups-content');
  if ($groups) {
    if (!userModel.isOrgAdmin()) {
      window.location = userModel.viewUrl().accountProfile();
      return false;
    }

    const groups = new OrganizationGroupsCollection([], {
      organization: userModel.organization,
      configModel
    });

    const router = new GroupsRouter({
      rootUrl: userModel.viewUrl().organization().groups(),
      flashMessageModel,
      groups,
      userModel,
      modals: modalsService
    });

    const groupsMainView = new GroupsMainView({
      el: $groups,
      groups,
      routerModel: router,
      user: userModel
    });
    groupsMainView.render();

    router.enableAfterMainView();
  }

  // Password Expiration
  const listenToExpirationSettingsChanges = function () {
    const expirationInput = $('#organization_password_expiration_in_d');
    const unlimitedExpirationInput = $('#unlimited_password_expiration');

    unlimitedExpirationInput.change(function () {
      const isChecked = this.checked;
      isChecked ? expirationInput.attr('disabled', 'disabled') : expirationInput.removeAttr('disabled');
      expirationInput.val(null);
    });
  };
  listenToExpirationSettingsChanges();

  // Form Validations
  PasswordValidatedForm.bindEventTo('.FormAccount-Content form', {
    modals: modalsService,
    passwordConfirmationNeeded: userModel.get('needs_password_confirmation')
  });
});
<|endoftext|>


<commit_before>// Object: javascript literal object
(function ($) {
    "use strict";

    if (!Object["eachAttrs"]) {
        $.defineProperty($.prototype, "eachAttrs", {
            value: function () {
                var
                    self = this,
                    attrs = Object.getOwnPropertyNames(self),
                    att,
                    callback = arguments[0],
                    obj;

                // o for...in é para se usar break;
                for (att in attrs) {
                    if (!isNaN(parseInt(attrs[att], 10))) {
                        callback(self[att], att);
                    } else {
                        break;
                    }
                }
            }
        });
    }

    if (!Object["isEqual"]) {
        $.defineProperty($.prototype, "isEqual", {
            value: function () {
                var
                    self = this;

                // self.eachAttrs
            }
        });
    }

    if (!Object["flatten"]) {
        $.defineProperty($.prototype, "flatten", {
            value: function () {
                var
                    flat = [],
                    self = this,
                    i,
                    type;

                for (i in self) {
                    if (self.hasOwnProperty(i)) {
                        type = Object.prototype.toString.call(self[i]).split(' ')
                            .pop().split(']').shift().toLowerCase();
                        if (type) {
                            flat = flat
                                .concat(/^(array|arguments|collection)$/
                                    .test(type) ? self.flatten
                                        .call(self[i]) : self[i]);
                        }
                    }
                }

                return flat;
            }
        });
    }

    if (!Object["eachNodes"]) {
        $.defineProperty($.prototype, "eachNodes", {
            value: function (callback, trail) {
                trail = trail || [];

                var
                    self = this,
                    value;

                //for (var key in self) {
                Object.getOwnPropertyNames(self).forEach(function (key) {
                // Object.keys(self).forEach(function (key) {
                    value = self[key];

                    if (Object.getPrototypeOf(value) === Object.prototype) {
                        // chamar uma função recursivamente não substitui os valores do atual loop, nem o interrompe (salvo quando a instrução return é chamada), apenas define um novo loop com um novo valor para ser executado
                        // eachNodes(callback, trail.concat(key));
                        value.eachNodes(callback, trail.concat(key));
                    } else {
                        callback({name: key, value: value, trail: trail});
                    }
                });
                // }
            }
        });
    }

    if (!Object["merge"]) {
        $.defineProperty($.prototype, "merge", {
            value: function () {
                var
                    self = this,
                    merged = {},
                    i,
                    arg;

                for (i in self) {
                    if (self.hasOwnProperty(i)) {
                        merged[i] = self[i];
                    }
                }

                for (arg in arguments) {
                    if (arguments.hasOwnProperty(arg)) {
                        if (arguments[arg] instanceof Object) {
                            for (i in arguments[arg]) {
                                if (arguments[arg].hasOwnProperty(i)) {
                                    merged[i] = arguments[arg][i];
                                }
                            }
                        }
                    }
                }

                return merged;
            }
        });
    }

    if (!Object["indexOfConstructor"]) {
        $.defineProperty($.prototype, "indexOfConstructor", {
            value: function () {
                var
                    self = this,
                    calleeArgs = self.callee.arguments,
                    arg = arguments[0],
                    i;

                for(i in calleeArgs) {
                    if (calleeArgs[i].constructor === arg) {
                        return parseFloat(i);
                    }
                }

                return false;
            }
        });
    }

}(Object));
<commit_msg>código final para testar se dois objetos são equivalentes<commit_after>// Object: javascript literal object
(function ($) {
    "use strict";

    if (!Object["eachAttrs"]) {
        $.defineProperty($.prototype, "eachAttrs", {
            value: function () {
                var
                    self = this,
                    attrs = Object.getOwnPropertyNames(self),
                    attr,
                    callback = arguments[0],
                    obj;

                // o for...in é para se usar break;
                for (attr in attrs) {
                    if (!isNaN(parseInt(attrs[attr], 10))) {
                        callback(self[attr], attr);
                    } else {
                        break;
                    }
                }
            }
        });
    }

    if (!Object["isEquivalent"]) {
        $.defineProperty($.prototype, "isEquivalent", {
            value: function () {
                var
                    self = this,
                    i;

                // usar break
                for (i in self) {
                    if (self[i] !== arguments[0][i]) {
                        return false;
                    }
                }

                return true;
            }
        });
    }

    if (!Object["flatten"]) {
        $.defineProperty($.prototype, "flatten", {
            value: function () {
                var
                    flat = [],
                    self = this,
                    i,
                    type;

                for (i in self) {
                    if (self.hasOwnProperty(i)) {
                        type = Object.prototype.toString.call(self[i]).split(' ')
                            .pop().split(']').shift().toLowerCase();
                        if (type) {
                            flat = flat
                                .concat(/^(array|arguments|collection)$/
                                    .test(type) ? self.flatten
                                        .call(self[i]) : self[i]);
                        }
                    }
                }

                return flat;
            }
        });
    }

    if (!Object["eachNodes"]) {
        $.defineProperty($.prototype, "eachNodes", {
            value: function (callback, trail) {
                trail = trail || [];

                var
                    self = this,
                    value;

                //for (var key in self) {
                Object.getOwnPropertyNames(self).forEach(function (key) {
                // Object.keys(self).forEach(function (key) {
                    value = self[key];

                    if (Object.getPrototypeOf(value) === Object.prototype) {
                        // chamar uma função recursivamente não substitui os valores do atual loop, nem o interrompe (salvo quando a instrução return é chamada), apenas define um novo loop com um novo valor para ser executado
                        // eachNodes(callback, trail.concat(key));
                        value.eachNodes(callback, trail.concat(key));
                    } else {
                        callback({name: key, value: value, trail: trail});
                    }
                });
                // }
            }
        });
    }

    if (!Object["merge"]) {
        $.defineProperty($.prototype, "merge", {
            value: function () {
                var
                    self = this,
                    merged = {},
                    i,
                    arg;

                for (i in self) {
                    if (self.hasOwnProperty(i)) {
                        merged[i] = self[i];
                    }
                }

                for (arg in arguments) {
                    if (arguments.hasOwnProperty(arg)) {
                        if (arguments[arg] instanceof Object) {
                            for (i in arguments[arg]) {
                                if (arguments[arg].hasOwnProperty(i)) {
                                    merged[i] = arguments[arg][i];
                                }
                            }
                        }
                    }
                }

                return merged;
            }
        });
    }

    if (!Object["indexOfConstructor"]) {
        $.defineProperty($.prototype, "indexOfConstructor", {
            value: function () {
                var
                    self = this,
                    calleeArgs = self.callee.arguments,
                    arg = arguments[0],
                    i;

                for(i in calleeArgs) {
                    if (calleeArgs[i].constructor === arg) {
                        return parseFloat(i);
                    }
                }

                return false;
            }
        });
    }

}(Object));
<|endoftext|>


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

    $.prototype.copyUntil = function (untilWord, start) {
        var
            self = this,
            searchIndex;

        searchIndex = self.search(untilWord);
        if (searchIndex !== -1) {
            if (start) {
                return self.substr(start, searchIndex -start);
            }
            return self.substr(0, searchIndex);
        } else {
            return false;
        }
    };

    // procura, na string, por palavras (separadas por espaço)
    // $ procura da direita para a esquerda
    $.prototype.allReplaced = function (find, change) {
        // /g -> modifier. Identifica em qualquer parte do contexto
        var pattern = eval.call(null, "/" + find + "/g");
        return this.replace(pattern, change);
    };

    $.prototype.allReplacedChar = function (find, change) {
        // procura qualquer caracter entre os colchetes
        var pattern = eval.call(null, "/[" + find + "]/g");
        return this.replace(pattern, change);
    };

    $.prototype.without = function (chars) {
        return this.allReplacedChar(chars, "");
    };

    $.prototype.empty = function () {
        if (this.length === 0) {
            return true;
        }
        return false;
    };

    $.prototype.capitalized = function () {
        var
            s = this.split(" "),
            str = "";

        s.map(function (s, i) {
            str += s.charAt(0).toUpperCase() + s.slice(1, s.length);
            if (i < s.length - 1) {
                str += " ";
            }
        });
        return str;
    };

})(String);
<commit_msg>fix bug in copyUntil method of String class<commit_after>(function ($) {
    "use strict";

    $.prototype.copyUntil = function (untilWord, start) {
        var
            self = this,
            searchIndex,
            substr;

        substr = self.substr(start, self.length);
        searchIndex = substr.search(untilWord);
        if (searchIndex !== -1 && start) {
            return substr.substr(0, searchIndex);
        } else {
            if (start) {
                return substr;
            }
            return self.substr(0, searchIndex);
        }
    };

    // procura, na string, por palavras (separadas por espaço)
    // $ procura da direita para a esquerda
    $.prototype.allReplaced = function (find, change) {
        // /g -> modifier. Identifica em qualquer parte do contexto
        var pattern = eval.call(null, "/" + find + "/g");
        return this.replace(pattern, change);
    };

    $.prototype.allReplacedChar = function (find, change) {
        // procura qualquer caracter entre os colchetes
        var pattern = eval.call(null, "/[" + find + "]/g");
        return this.replace(pattern, change);
    };

    $.prototype.without = function (chars) {
        return this.allReplacedChar(chars, "");
    };

    $.prototype.empty = function () {
        if (this.length === 0) {
            return true;
        }
        return false;
    };

    $.prototype.capitalized = function () {
        var
            s = this.split(" "),
            str = "";

        s.map(function (s, i) {
            str += s.charAt(0).toUpperCase() + s.slice(1, s.length);
            if (i < s.length - 1) {
                str += " ";
            }
        });
        return str;
    };

})(String);
<|endoftext|>


<commit_before>/* eslint-disable import/imports-first */

// FIXME: replace globals with central (non-global) config
global.__SERVER__ = true

const r = require('src/db/connect')
const getPlayerInfo = require('src/server/actions/getPlayerInfo')
const {buildProjects} = require('src/server/actions/formProjects')
const {finish} = require('./util')

const LOG_PREFIX = `[${__filename.split('js')[0]}]`

// TODO: accept as command line args
const CHAPTER_NAME = 'Oakland'
const CYCLE_NUMBER = 12

const startedAt = new Date()
console.log('startedAt:', startedAt)
run()
  .then(() => finish(null, {startedAt}))
  .catch(err => finish(err, {startedAt}))

async function run() {
  console.log(LOG_PREFIX, `Arranging projects for cyle ${CYCLE_NUMBER}`)

  const chapters = await r.table('chapters').filter({name: CHAPTER_NAME})
  const chapter = chapters[0]
  if (!chapter) {
    throw new Error(`Invalid chapter name ${CHAPTER_NAME}`)
  }

  const cycles = await r.table('cycles').filter({chapterId: chapter.id, cycleNumber: CYCLE_NUMBER})
  const cycle = cycles[0]
  if (!cycle) {
    throw new Error(`Invalid cycle number ${CYCLE_NUMBER} for chapter ${CHAPTER_NAME}`)
  }

  const previewProjects = await buildProjects(cycle.id)
  const {projects, players} = await _expandProjectData(previewProjects)

  console.log('\n\n\n::: PROJECTS BY TEAM :::\n\n')
  _logProjectsByTeam(projects)

  console.log('\n\n\n\n::: PROJECTS BY PLAYER :::\n\n')
  _logProjectsByPlayer(players)

  console.log(`TOTAL PLAYERS VOTED: ${players.length}`)
}

async function _expandProjectData(projects) {
  const allPlayers = new Map()
  const allProjects = await Promise.all(projects.map(async project => {
    const primaryCycle = project.cycleHistory[0]
    const players = await Promise.all(primaryCycle.playerIds.map(async playerId => {
      const [users, player] = await Promise.all([
        getPlayerInfo([playerId]),
        r.table('players').get(playerId),
      ])

      const mergedUser = {
        ...users[0],
        ...player,
        elo: ((player.stats || {}).elo || {}).rating || 0,
      }

      const playerProject = allPlayers.get(player.id) || {...mergedUser, projects: []}
      playerProject.projects.push(project)
      allPlayers.set(player.id, playerProject)

      return mergedUser
    }))

    return {...project, ...primaryCycle, players}
  }))

  return {projects: allProjects, players: Array.from(allPlayers.values())}
}

function _logProjectsByTeam(projects) {
  projects.forEach(project => {
    const goalTitle = ((project.goal || {}).githubIssue || {}).title
    console.log(`#${project.name} (${goalTitle})`)
    console.log('----------')
    project.players.forEach(player => console.log(`@${player.handle} (${player.name}) (${player.elo})`))
    console.log('\n\n')
  })
}

function _logProjectsByPlayer(players) {
  players.forEach(player => {
    console.log(`@${player.handle} (${player.name}) (${player.elo})`)
    console.log('----------')
    player.projects.forEach(project => console.log(`#${project.name} (${project.goalTitle})`))
    console.log('\n\n')
  })
}
<commit_msg>remove extra whitespace from script output<commit_after>/* eslint-disable import/imports-first */

// FIXME: replace globals with central (non-global) config
global.__SERVER__ = true

const r = require('src/db/connect')
const getPlayerInfo = require('src/server/actions/getPlayerInfo')
const {buildProjects} = require('src/server/actions/formProjects')
const {finish} = require('./util')

const LOG_PREFIX = `[${__filename.split('js')[0]}]`

// TODO: accept as command line args
const CHAPTER_NAME = 'Oakland'
const CYCLE_NUMBER = 12

const startedAt = new Date()
console.log('startedAt:', startedAt)
run()
  .then(() => finish(null, {startedAt}))
  .catch(err => finish(err, {startedAt}))

async function run() {
  console.log(LOG_PREFIX, `Arranging projects for cyle ${CYCLE_NUMBER}`)

  const chapters = await r.table('chapters').filter({name: CHAPTER_NAME})
  const chapter = chapters[0]
  if (!chapter) {
    throw new Error(`Invalid chapter name ${CHAPTER_NAME}`)
  }

  const cycles = await r.table('cycles').filter({chapterId: chapter.id, cycleNumber: CYCLE_NUMBER})
  const cycle = cycles[0]
  if (!cycle) {
    throw new Error(`Invalid cycle number ${CYCLE_NUMBER} for chapter ${CHAPTER_NAME}`)
  }

  const previewProjects = await buildProjects(cycle.id)
  const {projects, players} = await _expandProjectData(previewProjects)

  console.log('\n\n::: PROJECTS BY TEAM :::\n')
  _logProjectsByTeam(projects)

  console.log('\n\n::: PROJECTS BY PLAYER :::\n')
  _logProjectsByPlayer(players)

  console.log(`TOTAL PLAYERS VOTED: ${players.length}`)
}

async function _expandProjectData(projects) {
  const allPlayers = new Map()
  const allProjects = await Promise.all(projects.map(async project => {
    const primaryCycle = project.cycleHistory[0]
    const players = await Promise.all(primaryCycle.playerIds.map(async playerId => {
      const [users, player] = await Promise.all([
        getPlayerInfo([playerId]),
        r.table('players').get(playerId),
      ])

      const mergedUser = {
        ...users[0],
        ...player,
        elo: ((player.stats || {}).elo || {}).rating || 0,
      }

      const playerProject = allPlayers.get(player.id) || {...mergedUser, projects: []}
      playerProject.projects.push(project)
      allPlayers.set(player.id, playerProject)

      return mergedUser
    }))

    return {...project, ...primaryCycle, players}
  }))

  return {projects: allProjects, players: Array.from(allPlayers.values())}
}

function _logProjectsByTeam(projects) {
  projects.forEach(project => {
    const goalTitle = ((project.goal || {}).githubIssue || {}).title
    console.log(`#${project.name} (${goalTitle})`)
    console.log('----------')
    project.players.forEach(player => console.log(`@${player.handle} (${player.name}) (${player.elo})`))
    console.log('')
  })
}

function _logProjectsByPlayer(players) {
  players.forEach(player => {
    console.log(`@${player.handle} (${player.name}) (${player.elo})`)
    console.log('----------')
    player.projects.forEach(project => console.log(`#${project.name} (${project.goalTitle})`))
    console.log('')
  })
}
<|endoftext|>


<commit_before>/* Copyright 2011 Carlos Guerreiro
   All rights reserved */

'use strict';

var redis  = require('redis');

module.exports = function (queueName) {
  var that = this;
  var client = redis.createClient();

  client.on('error', function(err) {
    console.error(err);
  });

  var listKey = queueName+ '_a';

  console.log('listKey', listKey);

  var stopping = false;
  var busyCount = 0;

  function clientStop() {
    if(!client.connected) {
      // FIXME: this is to work around a bug in the redis client where it will keep retrying a reconnection just to send the QUIT request
      // FIXME: actually go and report bug
      client.closing = true;
    }
    client.quit();
  }

  function markDone() {
    --busyCount;
    if(busyCount === 0) {
      if(stopping) {
        clientStop();
      }
    }
  }

  that.add = function(id, when, cb) {
    ++busyCount;
    if(typeof when !== 'number' || Math.floor(when) !== when) {
      process.nextTick(function() { cb('when must be an integer'); markDone();});
    } else {
      client.rpush(listKey, JSON.stringify({id: id, when:when}), function(err, results) {
        markDone();
        cb(err, results);
      });
    }
  };

  that.stop = function() {
    if(busyCount === 0) {
      clientStop();
    } else {
      stopping = true;
    }
  };
};
<commit_msg>remove unnecessary log<commit_after>/* Copyright 2011 Carlos Guerreiro
   All rights reserved */

'use strict';

var redis  = require('redis');

module.exports = function (queueName) {
  var that = this;
  var client = redis.createClient();

  client.on('error', function(err) {
    console.error(err);
  });

  var listKey = queueName+ '_a';

  var stopping = false;
  var busyCount = 0;

  function clientStop() {
    if(!client.connected) {
      // FIXME: this is to work around a bug in the redis client where it will keep retrying a reconnection just to send the QUIT request
      // FIXME: actually go and report bug
      client.closing = true;
    }
    client.quit();
  }

  function markDone() {
    --busyCount;
    if(busyCount === 0) {
      if(stopping) {
        clientStop();
      }
    }
  }

  that.add = function(id, when, cb) {
    ++busyCount;
    if(typeof when !== 'number' || Math.floor(when) !== when) {
      process.nextTick(function() { cb('when must be an integer'); markDone();});
    } else {
      client.rpush(listKey, JSON.stringify({id: id, when:when}), function(err, results) {
        markDone();
        cb(err, results);
      });
    }
  };

  that.stop = function() {
    if(busyCount === 0) {
      clientStop();
    } else {
      stopping = true;
    }
  };
};
<|endoftext|>


<commit_before>'use strict';

var async = require('async'),
  events = require('events'),
  util = require('util'),
  Config = require('./Config'),
  DataStore = require('./ds/DataStore'),
  Tenant = require('./resource/Tenant');

/**
 * Creates a new Client.
 *
 * @class
 */
function Client(config) {
  var self = this;

  // Call the constructor of the EventEmitter class -- this, allows us to
  // initialize our Client object as an EventEmitter, and allows us to fire off
  // events later on.
  events.EventEmitter.call(self);

  // Bind the user-supplied config property to our class so it can be accessed
  // like an object.
  self.config = new Config(config);

  // For backwards compatibility reasons, if no API key is specified we'll try
  // to grab the API credentials out of our new format and shove it into the old
  // format.  This can go away once we cut a release and decide to no longer
  // support the old configuration formatting.
  if (!self.config.apiKey) {
    self.config.apiKey = self.config.client.apiKey;
  }

  self._dataStore = new DataStore(self.config);

  // We'll maintain this class variable as an in-memory singleton for caching
  // purposes.  We do this because Tenants never ever change once a Client has
  // been initialized, so it makes sense to cache the Tenant object so we don't
  // make unnecessary API requests if this object is looked up more than once.
  self._currentTenant = null;

  self.mergeRemoteConfig(function(err) {
    return err ? self.emit('error', err): self.emit('ready');
  });
}

// By inheriting from `events.EventEmitter`, we're making our Client object a
// true EventEmitter -- allowing us to fire off events.
util.inherits(Client, Object);
util.inherits(Client, events.EventEmitter);

Client.prototype.mergeRemoteConfig = function(callback) {
  var self = this;
  var config = self.config;
  var application = config.application;

  function findApplication(name, cb) {
    self.getApplications({ name: application.name }, function(err, applications) {
      if (err) {
        return cb(err);
      }

      applications.detect(function(app, cb) {
        cb(application.name === app.name);
      }, function(app) {
        if (app) {
          self.config.application.href = app.href;
          return cb(null, app);
        }

        return cb(new Error('Application not found: "' + application.name + '"'));
      });
    });
  }

  function findDefaultDirectoryHref(application, cb) {
    application.getAccountStoreMappings(function(err, mappings) {
      if (err) {
        return cb(err);
      }
      mappings.detect(function(mapping,cb){
        cb(mapping.isDefaultAccountStore);
      },function(defaultMapping){
        if(defaultMapping){
          var href = defaultMapping.accountStore.href;
          if(href.match(/group/)){
            self.getGroup(href,function(err,group){
              cb(err,group &&group.directory.href);
            });
          }else{
            cb(null,href);
          }
        }else{
          cb(null,null);
        }
      });
    });
  }

  function applyConfig(directoryHref, cb) {
    if(!directoryHref){
      callback(null);
    }else{
      self.getDirectory(
        directoryHref,
        {expand:'passwordPolicy,accountCreationPolicy'},
        function(err,directory){
          if(err){
            cb(err);
          }else{
            self.config.web.verifyEmail.enabled =
              directory.accountCreationPolicy.verificationEmailStatus === 'ENABLED';
            self.config.web.changePassword.enabled = self.config.web.forgotPassword.enabled =
              directory.passwordPolicy.resetEmailStatus === 'ENABLED';
            cb(null);
          }
        }
      );
    }
  }

  if (application && application.href) {
    async.waterfall([
      self.getApplication.bind(self, application.href),
      findDefaultDirectoryHref,
      applyConfig
    ], callback);
  } else if (application && application.name) {
    async.waterfall([
      findApplication(application.name),
      findDefaultDirectoryHref,
      applyConfig
    ], callback);
  } else {
    process.nextTick(callback);
  }

};

/**
 * @callback getCurrentTenantCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} tenant - The retrieved Tenant object.
 */

/**
 * Retrieves the current Tenant object.
 *
 * @method getCurrentTenant
 * @param {Object} [options] - Options.
 * @param {getCurrentTenantCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.getCurrentTenant = function() {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  // First, we'll check to see if we've already cached the current tenant (since
  // a Tenant never changes once a Client has been initialized).  This prevents
  // us from making unnecessary repeat API requests if this method is called
  // multiple times.
  if (self._currentTenant) {
    return callback(null, self._currentTenant);
  }

  self._dataStore.getResource('/tenants/current', options, Tenant, function(err, tenant) {
    if (err) {
      return callback(err);
    }

    self._currentTenant = tenant;
    return callback(null, tenant);
  });
};

/**
 * @callback getResourceCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} resource - The retrieved resource object.
 */

/**
 * Retrieves a resource object by href.
 *
 * @method getResource
 * @param {String} href - The URI of the resource.
 * @param {Object} [query] - Name / value pairs to use as query parameters.
 * @param {Function} [constructor] - The constructor function that will be
 *  invoked when the given resource is retrieved.  EG: Account, Directory,
 *  Group, etc.  Defaults to `InstanceResource`.  If a resource returned from
 *  the API is a collection (not a single resource object), then each returned
 *  object in the `items` array will be passed into this constructor function
 *  and initialized.
 * @param {getResourceCallback} callback - The callback that handles the
 *  resposne.
 */
Client.prototype.getResource = function() {
  return this._dataStore.getResource.apply(this._dataStore, arguments);
};

/**
 * Creates a new resource on the server as a child of the specified `parentHref` location.  `parentHref` must be a collection resource endpoint.
 *
 * @param {String} parentHref the URI of the parent collection under which the new resource will be created as a child - must always be the first argument.
 * @param {Object} query (optional, defaults to `undefined`) name/value pairs to use as query parameters to `parentHref`
 * @param {Object} data the resource (name/value pairs) to send to the server.
 * @param {Function} instanceCtor (optional, defaults to `InstanceResource`)  The Constructor function to invoke for any instance resource returned by the server.  If the request result is a single resource, this function is used to construct the resource.  If the request result is a collection, the `instanceCtor` is used to construct each resource in the collection's `items` field.
 * @param {Function} callback the callback function to invoke with the constructed Resource. The callback's first argument is an `Error` object, the second is the constructed resource. Must always be the last argument.
 * @return {void} result is provided to `callback`.
 * @method createResource
 * @version 0.1
 */
Client.prototype.createResource = function createResource(/* parentHref, [query,] data, [InstanceConstructor,] callback */) {
  this._dataStore.createResource.apply(this._dataStore, arguments);
};

/**
 * @callback getApplicationsCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} applications - The retrieved Application objects.
 */

/**
 * Retrieves all Application objects.
 *
 * @method
 * @param {Object} [options] - Options.
 * @param {getApplicationsCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.getApplications = function() {
  var args = Array.prototype.slice.call(arguments);
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  this.getCurrentTenant(function(err, tenant) {
    if (err) {
      return callback(err);
    }

    return tenant.getApplications(options, callback);
  });
};

/**
 * @callback createApplicationCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} application - The created Application object.
 */

/**
 * Creates a new Application object.
 *
 * @method createApplication
 * @param {Object} application - The Application object to create.
 * @param {Object} [options] - Options.
 * @param {createApplicationCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.createApplication = function() {
  var args = Array.prototype.slice.call(arguments);
  var app = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  this.getCurrentTenant(function(err, tenant) {
    if (err) {
      return callback(err);
    }

    return tenant.createApplication(app, options, callback);
  });
};

/**
 * @callback getAccountsCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} directories - The retrieved Account objects.
 */

/**
 * Retrieves all Account objects.
 *
 * @method
 * @param {Object} [options] - Options.
 * @param {getAccountsCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.getAccounts = function() {
  var args = Array.prototype.slice.call(arguments);
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  this.getCurrentTenant(function(err, tenant) {
    if (err) {
      return callback(err);
    }

    return tenant.getAccounts(options, callback);
  });
};

/**
 * @callback getGroupsCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} groups - The retrieved Group objects.
 */

/**
 * Retrieves all Group objects.
 *
 * @method
 * @param {Object} [options] - Options.
 * @param {getGroupsCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.getGroups = function() {
  var args = Array.prototype.slice.call(arguments);
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  this.getCurrentTenant(function(err, tenant) {
    if (err) {
      return callback(err);
    }

    return tenant.getGroups(options, callback);
  });
};

/**
 * @callback getDirectoriesCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} directories - The retrieved Directory objects.
 */

/**
 * Retrieves all Directory objects.
 *
 * @method
 * @param {Object} [options] - Options.
 * @param {getDirectoriesCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.getDirectories = function() {
  var args = Array.prototype.slice.call(arguments);
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  this.getCurrentTenant(function(err, tenant) {
    if (err) {
      return callback(err);
    }

    return tenant.getDirectories(options, callback);
  });
};

/**
 * @callback createDirectoryCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} directory - The created Directory object.
 */

/**
 * Creates a new Directory object.
 *
 * @method createDirectory
 * @param {Object} directory - The Directory object to create.
 * @param {Object} [options] - Options.
 * @param {createDirectoryCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.createDirectory = function() {
  var args = Array.prototype.slice.call(arguments);
  var dir = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  this.getCurrentTenant(function(err, tenant) {
    if (err) {
      return callback(err);
    }

    return tenant.createDirectory(dir, options, callback);
  });
};

// Individual resource type convenience methods:
Client.prototype.getAccount = function getClientAccount(/* href, [options,], callback */) {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var href = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  return self.getResource(href, options, require('./resource/Account'), callback);
};
Client.prototype.getApplication = function getClientApplication(/* href, [options,], callback */) {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var href = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  return self.getResource(href, options, require('./resource/Application'), callback);
};
Client.prototype.getDirectory = function getClientDirectory(/* href, [options,], callback */) {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var href = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  return self.getResource(href, options, require('./resource/Directory'), callback);
};
Client.prototype.getGroup = function getClientGroup(/* href, [options,], callback */) {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var href = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  return self.getResource(href, options, require('./resource/Group'), callback);
};
Client.prototype.getGroupMembership = function getClientGroupMembership(/* href, [options,], callback */) {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var href = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  return self.getResource(href, options, require('./resource/GroupMembership'), callback);
};

module.exports = Client;
<commit_msg>Refactoring Client.createResource().<commit_after>'use strict';

var async = require('async'),
  events = require('events'),
  util = require('util'),
  Config = require('./Config'),
  DataStore = require('./ds/DataStore'),
  Tenant = require('./resource/Tenant');

/**
 * Creates a new Client.
 *
 * @class
 */
function Client(config) {
  var self = this;

  // Call the constructor of the EventEmitter class -- this, allows us to
  // initialize our Client object as an EventEmitter, and allows us to fire off
  // events later on.
  events.EventEmitter.call(self);

  // Bind the user-supplied config property to our class so it can be accessed
  // like an object.
  self.config = new Config(config);

  // For backwards compatibility reasons, if no API key is specified we'll try
  // to grab the API credentials out of our new format and shove it into the old
  // format.  This can go away once we cut a release and decide to no longer
  // support the old configuration formatting.
  if (!self.config.apiKey) {
    self.config.apiKey = self.config.client.apiKey;
  }

  self._dataStore = new DataStore(self.config);

  // We'll maintain this class variable as an in-memory singleton for caching
  // purposes.  We do this because Tenants never ever change once a Client has
  // been initialized, so it makes sense to cache the Tenant object so we don't
  // make unnecessary API requests if this object is looked up more than once.
  self._currentTenant = null;

  self.mergeRemoteConfig(function(err) {
    return err ? self.emit('error', err): self.emit('ready');
  });
}

// By inheriting from `events.EventEmitter`, we're making our Client object a
// true EventEmitter -- allowing us to fire off events.
util.inherits(Client, Object);
util.inherits(Client, events.EventEmitter);

Client.prototype.mergeRemoteConfig = function(callback) {
  var self = this;
  var config = self.config;
  var application = config.application;

  function findApplication(name, cb) {
    self.getApplications({ name: application.name }, function(err, applications) {
      if (err) {
        return cb(err);
      }

      applications.detect(function(app, cb) {
        cb(application.name === app.name);
      }, function(app) {
        if (app) {
          self.config.application.href = app.href;
          return cb(null, app);
        }

        return cb(new Error('Application not found: "' + application.name + '"'));
      });
    });
  }

  function findDefaultDirectoryHref(application, cb) {
    application.getAccountStoreMappings(function(err, mappings) {
      if (err) {
        return cb(err);
      }
      mappings.detect(function(mapping,cb){
        cb(mapping.isDefaultAccountStore);
      },function(defaultMapping){
        if(defaultMapping){
          var href = defaultMapping.accountStore.href;
          if(href.match(/group/)){
            self.getGroup(href,function(err,group){
              cb(err,group &&group.directory.href);
            });
          }else{
            cb(null,href);
          }
        }else{
          cb(null,null);
        }
      });
    });
  }

  function applyConfig(directoryHref, cb) {
    if(!directoryHref){
      callback(null);
    }else{
      self.getDirectory(
        directoryHref,
        {expand:'passwordPolicy,accountCreationPolicy'},
        function(err,directory){
          if(err){
            cb(err);
          }else{
            self.config.web.verifyEmail.enabled =
              directory.accountCreationPolicy.verificationEmailStatus === 'ENABLED';
            self.config.web.changePassword.enabled = self.config.web.forgotPassword.enabled =
              directory.passwordPolicy.resetEmailStatus === 'ENABLED';
            cb(null);
          }
        }
      );
    }
  }

  if (application && application.href) {
    async.waterfall([
      self.getApplication.bind(self, application.href),
      findDefaultDirectoryHref,
      applyConfig
    ], callback);
  } else if (application && application.name) {
    async.waterfall([
      findApplication(application.name),
      findDefaultDirectoryHref,
      applyConfig
    ], callback);
  } else {
    process.nextTick(callback);
  }

};

/**
 * @callback getCurrentTenantCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} tenant - The retrieved Tenant object.
 */

/**
 * Retrieves the current Tenant object.
 *
 * @method getCurrentTenant
 * @param {Object} [options] - Options.
 * @param {getCurrentTenantCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.getCurrentTenant = function() {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  // First, we'll check to see if we've already cached the current tenant (since
  // a Tenant never changes once a Client has been initialized).  This prevents
  // us from making unnecessary repeat API requests if this method is called
  // multiple times.
  if (self._currentTenant) {
    return callback(null, self._currentTenant);
  }

  self._dataStore.getResource('/tenants/current', options, Tenant, function(err, tenant) {
    if (err) {
      return callback(err);
    }

    self._currentTenant = tenant;
    return callback(null, tenant);
  });
};

/**
 * @callback getResourceCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} resource - The retrieved resource object.
 */

/**
 * Retrieves a resource object by href.
 *
 * @method getResource
 * @param {String} href - The URI of the resource.
 * @param {Object} [query] - Name / value pairs to use as query parameters.
 * @param {Function} [constructor] - The constructor function that will be
 *  invoked when the given resource is retrieved.  EG: Account, Directory,
 *  Group, etc.  Defaults to `InstanceResource`.  If a resource returned from
 *  the API is a collection (not a single resource object), then each returned
 *  object in the `items` array will be passed into this constructor function
 *  and initialized.
 * @param {getResourceCallback} callback - The callback that handles the
 *  resposne.
 */
Client.prototype.getResource = function() {
  return this._dataStore.getResource.apply(this._dataStore, arguments);
};

/**
 * @callback createResourceCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} resource - The created resource object.
 */

/**
 * Creates a new resource object as a child of the specified parentHref
 * location.  parentHref must be a collection resource endpoint.  This is a
 * utility method we use internally to handle resource creation.
 *
 * @method createResource
 * @param {String} parentHref - The URI of the parent's collection resource.
 * @param {Object} [query] - Name / value pairs to use as query parameters.
 * @param {Function} [constructor] - The constructor function that will be
 *  invoked when the given resource is retrieved.  EG: Account, Directory,
 *  Group, etc.  Defaults to `InstanceResource`.  If a resource returned from
 *  the API is a collection (not a single resource object), then each returned
 *  object in the `items` array will be passed into this constructor function
 *  and initialized.
 * @param {createResourceCallback} callback - The callback that handles the
 *  resposne.
 */
Client.prototype.createResource = function() {
  this._dataStore.createResource.apply(this._dataStore, arguments);
};

/**
 * @callback getApplicationsCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} applications - The retrieved Application objects.
 */

/**
 * Retrieves all Application objects.
 *
 * @method
 * @param {Object} [options] - Options.
 * @param {getApplicationsCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.getApplications = function() {
  var args = Array.prototype.slice.call(arguments);
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  this.getCurrentTenant(function(err, tenant) {
    if (err) {
      return callback(err);
    }

    return tenant.getApplications(options, callback);
  });
};

/**
 * @callback createApplicationCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} application - The created Application object.
 */

/**
 * Creates a new Application object.
 *
 * @method createApplication
 * @param {Object} application - The Application object to create.
 * @param {Object} [options] - Options.
 * @param {createApplicationCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.createApplication = function() {
  var args = Array.prototype.slice.call(arguments);
  var app = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  this.getCurrentTenant(function(err, tenant) {
    if (err) {
      return callback(err);
    }

    return tenant.createApplication(app, options, callback);
  });
};

/**
 * @callback getAccountsCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} directories - The retrieved Account objects.
 */

/**
 * Retrieves all Account objects.
 *
 * @method
 * @param {Object} [options] - Options.
 * @param {getAccountsCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.getAccounts = function() {
  var args = Array.prototype.slice.call(arguments);
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  this.getCurrentTenant(function(err, tenant) {
    if (err) {
      return callback(err);
    }

    return tenant.getAccounts(options, callback);
  });
};

/**
 * @callback getGroupsCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} groups - The retrieved Group objects.
 */

/**
 * Retrieves all Group objects.
 *
 * @method
 * @param {Object} [options] - Options.
 * @param {getGroupsCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.getGroups = function() {
  var args = Array.prototype.slice.call(arguments);
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  this.getCurrentTenant(function(err, tenant) {
    if (err) {
      return callback(err);
    }

    return tenant.getGroups(options, callback);
  });
};

/**
 * @callback getDirectoriesCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} directories - The retrieved Directory objects.
 */

/**
 * Retrieves all Directory objects.
 *
 * @method
 * @param {Object} [options] - Options.
 * @param {getDirectoriesCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.getDirectories = function() {
  var args = Array.prototype.slice.call(arguments);
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  this.getCurrentTenant(function(err, tenant) {
    if (err) {
      return callback(err);
    }

    return tenant.getDirectories(options, callback);
  });
};

/**
 * @callback createDirectoryCallback
 * @param {Error} err - The error (if there is one).
 * @param {Object} directory - The created Directory object.
 */

/**
 * Creates a new Directory object.
 *
 * @method createDirectory
 * @param {Object} directory - The Directory object to create.
 * @param {Object} [options] - Options.
 * @param {createDirectoryCallback} callback - The callback that handles the
 *  response.
 */
Client.prototype.createDirectory = function() {
  var args = Array.prototype.slice.call(arguments);
  var dir = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  this.getCurrentTenant(function(err, tenant) {
    if (err) {
      return callback(err);
    }

    return tenant.createDirectory(dir, options, callback);
  });
};

// Individual resource type convenience methods:
Client.prototype.getAccount = function getClientAccount(/* href, [options,], callback */) {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var href = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  return self.getResource(href, options, require('./resource/Account'), callback);
};
Client.prototype.getApplication = function getClientApplication(/* href, [options,], callback */) {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var href = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  return self.getResource(href, options, require('./resource/Application'), callback);
};
Client.prototype.getDirectory = function getClientDirectory(/* href, [options,], callback */) {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var href = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  return self.getResource(href, options, require('./resource/Directory'), callback);
};
Client.prototype.getGroup = function getClientGroup(/* href, [options,], callback */) {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var href = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  return self.getResource(href, options, require('./resource/Group'), callback);
};
Client.prototype.getGroupMembership = function getClientGroupMembership(/* href, [options,], callback */) {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var href = args.shift();
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;

  return self.getResource(href, options, require('./resource/GroupMembership'), callback);
};

module.exports = Client;
<|endoftext|>


<commit_before>// See docs
//   https://developer.mozilla.org/en-US/docs/Web/API/Touch
module.exports = function GTouch(id, target, x, y) {
  this.identifier = id;
  this.clientX = x;
  this.clientY = y;
  this.force = 1.0; // default
  this.pageX = x; // TODO
  this.pageY = y; // TODO
  this.radiusX = 1; // default
  this.radiusY = 1; // default
  this.rotationAngle = 0; // probably default
  this.screenX = x; // TODO
  this.screenY = y; // TODO
  this.target = target; // original element
};
<commit_msg>Improved touch coordinates.<commit_after>// See docs
//   https://developer.mozilla.org/en-US/docs/Web/API/Touch

module.exports = function GTouch(id, target, x, y) {

  this.identifier = id;
  this.clientX = x;
  this.clientY = y;
  this.force = 1.0; // default
  this.pageX = x + document.body.scrollLeft;
  this.pageY = y + document.body.scrollTop;
  this.radiusX = 1; // default
  this.radiusY = 1; // default
  this.rotationAngle = 0; // probably default

  // It seems that there is no right way to get screen position.
  // http://stackoverflow.com/a/21274679/638546
  // http://stackoverflow.com/q/2337795/638546
  var windowLeftBorderWidth = (window.outerWidth - window.innerWidth) / 2;
  var windowTopBorderHeight = (window.outerHeight - window.innerHeight) / 2;
  var documentScreenX = window.screenX + windowLeftBorderWidth;
  var documentScreenY = window.screenY + windowTopBorderHeight;
  this.screenX = documentScreenX + x; // only approximation
  this.screenY = documentScreenY + y; // only approximation

  this.target = target; // original element
};
<|endoftext|>


<commit_before>
var _     = require('underscore')
_s        = require('underscore.string')
unhtml    = require('unhtml')
special   = require('special-html')
HTML_E    = require('entities')
URI_js    = require('uri-js')
;

var VALID_HTML_ID = /^[0-9a-zA-Z_]+$/;
var NL = "\n";

var Ok = exports.Ok = function () {};

var ESCAPE = Ok.escape = function (str) {
  return special( _s.escapeHTML( _s.unescapeHTML( HTML_E.decode( str , 2) ) ) );
};

Ok.throw = function (o) { throw o.err; };

Ok.escape_uri = function (raw) {
  var url = HTML_E.decode(raw, 2);
  var parse = URI_js.parse(url);
  if (parse.errors.length)
    return null
  return URI_js.normalize(url);
};

Ok.to_html = function (str_or_arr, on_err) {
  var arr = null;
  var ok  = new Ok;
  ok.on_err = on_err;

  if (_.isString(str_or_arr)) {
    arr = JSON.parse(str_or_arr);
  }

  if (_.isArray(str_or_arr)) {
    arr = str_or_arr;
  }

  if (!arr) {
    var msg = "Value must be either string or array: " + JSON.stringify(str_or_arr);
    ok.err = new Error(msg);
    return this.throw(ok);
  }

  if (!_.isArray(arr)) {
    var msg = "Value must be an array: " + JSON.stringify(arr);
    ok.err = new Error(msg);
    return this.throw(ok);
  }

  ok.code = arr;

  ok.throw = function (err) {
    ok.err = err;
    return Ok.throw(ok);
  };

  return ok.to_html();
};

Ok.prototype.to_html = function () {

  var me = this;
  var arr = [];
  var on_err = me.throw;

  _.each(this.code, function (val, i) {
    if (_.isObject(val)) {
      arr.push(O_TO_HTML(val, on_err));
    } else {
      arr.push(TO_HTML_DIV(val, on_err));
    }
  });

  return arr.join(NL);
};

function O_TO_HTML(val, on_err) {
  var errs = [];
  var arr  = [];

  _.each(val, function (props, meth) {
    switch (meth) {
      case 'form':
        arr.push(FORM_TO_HTML(props, on_err));
      break;
      case 'text_box':
        arr.push(TEXT_BOX_TO_HTML(props, on_err));
        break;
      case 'button':
        arr.push(BUTTON_TO_HTML(props, on_err));
      break;
      case 'link':
        arr.push(LINK_TO_HTML(props, on_err));
        break;
      default:
        errs.push('Unknown element: ' + meth);
    };
  });

  if (errs.length)
    return on_err(new Error(errs[0]));

  return arr.join(NL);
}

function TO_HTML_DIV(val) {
  return "<div>" + val + "</div>";
}

function FORM_TO_HTML(form, on_err) {
  var arr = [];

  _.each(form, function (o, i) {
    arr.push(O_TO_HTML(o, on_err));
  });

  return "<form>" + arr.join(NL) + "</form>";
}

function TEXT_BOX_TO_HTML(props, on_err) {
  var name         = props[0];
  var default_text = props[1];

  return HTML_Element('input', {id: name, name: name, type: "text", ok_type: 'text_box'}, (default_text || ""), on_err);
}

function BUTTON_TO_HTML(props, on_err) {
  var name = props[0] || "";
  var text = props[1] || "";

  return HTML_Element('button', {id: name, ok_type: 'button'}, text, on_err);
}

function HTML_Element(raw_tag, raw_props, raw_text, on_err) {
  var tag = Ok.escape(raw_tag);
  var text = Ok.escape(raw_text);
  var props = {};

  var ok_type = raw_props.ok_type || "";
  delete raw_props['ok_type'];

  var err_msg = null;
  var errs = _.find(raw_props, function (v, k) {
    if (_.contains(['id', 'name', 'type'], k) && !v.match(VALID_HTML_ID)) {
        err_msg = "Invalid chars in " + ok_type + " " + k + ": " + v;
        return true
    }

    if (!k.match(VALID_HTML_ID)) {
      err_msg = "Invalid chars in " + ok_type + " attribute name: " + k;
      return true;
    }

    var safe_name = Ok.escape(k).trim();
    var safe_val  = (k == 'href') ? Ok.escape_uri(v) : Ok.escape(v);
    props[safe_name] = safe_val;
  });

  if (errs)
    return on_err(new Error(err_msg));

  var prop_text = _.map(props, function (v, k) {
    return k + '="' + v + '"';
  }).join(' ');

  return "<" + tag + " " + prop_text + ">" + text + "</" + tag + ">";
}

<commit_msg>Refactored: throwing errors.<commit_after>
var _     = require('underscore')
_s        = require('underscore.string')
unhtml    = require('unhtml')
special   = require('special-html')
HTML_E    = require('entities')
URI_js    = require('uri-js')
;

var NL            = "\n";
var VALID_HTML_ID = /^[0-9a-zA-Z_]+$/;
var IS_ERROR      = function (o) { return (_.isObject(o) && o.prototype === Error); };

var Ok = exports.Ok = function () {};

var ESCAPE = Ok.escape = function (str) {
  return special( _s.escapeHTML( _s.unescapeHTML( HTML_E.decode( str , 2) ) ) );
};

Ok.throw = function (o) { throw o.err; };

Ok.escape_uri = function (raw) {
  var url = HTML_E.decode(raw, 2);
  var parse = URI_js.parse(url);
  if (parse.errors.length)
    return null
  return URI_js.normalize(url);
};

Ok.to_html = function (str_or_arr, on_err) {
  var arr = null;
  var ok  = new Ok;
  ok.on_err = on_err;

  if (_.isString(str_or_arr)) {
    arr = JSON.parse(str_or_arr);
  }

  if (_.isArray(str_or_arr)) {
    arr = str_or_arr;
  }

  if (!arr) {
    var msg = "Value must be either string or array: " + JSON.stringify(str_or_arr);
    ok.err = new Error(msg);
    return this.throw(ok);
  }

  if (!_.isArray(arr)) {
    var msg = "Value must be an array: " + JSON.stringify(arr);
    ok.err = new Error(msg);
    return this.throw(ok);
  }

  ok.code = arr;

  ok.throw = function (err) {
    ok.err = err;
    return Ok.throw(ok);
  };

  return ok.to_html();
};

Ok.prototype.to_html = function () {

  var me             = this;
  var arr            = [];
  var method_to_html = null;
  var temp           = null;
  var err            = null;

  _.find(this.code, function (val, i) {

    method_to_html = (_.isObject(val)) ?  O_TO_HTML : STRING_TO_HTML;
    var result = method_to_html(val);

    if (result.prototype == Error) {
      err = result;
      return err;
    }

    arr.push(result);

  });

  if (err)
    return me.throw(err);

  return arr.join(NL);
};

function O_TO_HTML(val) {
  var err = null;
  var arr = [];
  var temp = null;

  _.find(val, function (props, meth) {

    switch (meth) {
      case 'form':
        temp = FORM_TO_HTML(props);
      break;
      case 'text_box':
        temp = TEXT_BOX_TO_HTML(props);
        break;
      case 'button':
        temp = BUTTON_TO_HTML(props);
      break;
      case 'link':
        temp = LINK_TO_HTML(props);
        break;
      default:
        temp = new Error('Unknown element: ' + meth);
    };

    if (meth.prototype === Error) {
      err = temp;
      return err;
    }

    arr.push(temp);

  });

  if (err)
    return err;

  return arr.join(NL);
}

function STRING_TO_HTML(val) {
  return HTML_Element('div', {},  val);
}

function FORM_TO_HTML(form) {
  var arr = [];
  var err = null;
  var temp = null;

  _.find(form, function (o, i) {
    temp = O_TO_HTML(o);
    if (IS_ERROR(temp)) {
      err = temp;
      return err;
    }
    arr.push(temp);
  });

  if (err)
    return err;

  return "<form>" + arr.join(NL) + "</form>";
}

function TEXT_BOX_TO_HTML(props) {
  var name         = props[0];
  var default_text = props[1];

  return HTML_Element('input', {id: name, name: name, type: "text", ok_type: 'text_box'}, (default_text || ""));
}

function BUTTON_TO_HTML(props) {
  var name = props[0] || "";
  var text = props[1] || "";

  return HTML_Element('button', {id: name, ok_type: 'button'}, text);
}

function HTML_Element(raw_tag, raw_props, raw_text) {
  var tag   = Ok.escape(raw_tag);
  var text  = Ok.escape(raw_text);
  var props = {};
  var err   = null;

  var ok_type = raw_props.ok_type || "";
  delete raw_props['ok_type'];

  _.find(raw_props, function (v, k) {
    if (_.contains(['id', 'name', 'type'], k) && !v.match(VALID_HTML_ID)) {
        err = new Error("Invalid chars in " + ok_type + " " + k + ": " + v);
        return err;
    }

    if (!k.match(VALID_HTML_ID)) {
      err = new Error("Invalid chars in " + ok_type + " attribute name: " + k);
      return err;
    }

    var safe_name = Ok.escape(k).trim();
    var safe_val  = (k == 'href') ? Ok.escape_uri(v) : Ok.escape(v);
    props[safe_name] = safe_val;
  });

  if (IS_ERROR(err))
    return err;

  var prop_text = _.map(props, function (v, k) {
    return k + '="' + v + '"';
  }).join(' ');

  return "<" + tag + " " + prop_text + ">" + text + "</" + tag + ">";
}

<|endoftext|>


<commit_before>const raven = require('raven');
const winston = require('winston');

const Config = require('../config/Config.js');

const logger = new winston.Logger();

logger.add(winston.transports.Console, {
  timestamp: true,
  stringify: true,
  colorize: true,
});

/**
 * A wrapper around logger.log because we can't export log on it's own
 * meant to be used as borq.log
 * @param {string} logLevel - The logLevel like error, warn etc.
 * @param {string} message - the message to log
 */
function log(logLevel, message) {
  if (Config.environment !== 'test') {
    if (message === undefined) {
      logger.log(logLevel);
    } else {
      logger.log(logLevel, message);
    }
  }
}

/**
 * Configure Sentry using the env vars pased if in production
 * @param {string} sentryDSN The url given by Sentry tied to your account
 * @param {string} environment dev, testing, peoduction etc.
 * @param {string} loggingLevel error, info, warn etc.
 * @return {object} return raven object if in production
 */
function setupSentry(sentryDSN, environment, loggingLevel) {
  raven
    .config(sentryDSN, {
      logger: loggingLevel,
      environment,
    })
    .install();

  if (Config.sentryDSN) {
    return raven;
  }
  return null;
}

const sentry = Config.sentryDSN
  ? setupSentry(Config.sentryDSN, Config.environment, 'error')
  : undefined;

/**
 * A function to send rejected promise errors to both winston and sentry
 * @param {string} text the promise rejection error text
 */
function logRejectedPromise(text) {
  const message = 'Promise rejected: ' + text;
  log('error', message);
  if (Config.environment === 'production') {
    sentry.captureMessage(message);
  }
}

module.exports = {
  log,
  sentry,
  logRejectedPromise,
};
<commit_msg>Have logs in JSON<commit_after>const raven = require('raven');
const winston = require('winston');

const Config = require('../config/Config.js');

const logger = new winston.Logger();

logger.add(winston.transports.Console, {
  timestamp: true,
  stringify: true,
  colorize: true,
  json: true,
});

/**
 * A wrapper around logger.log because we can't export log on it's own
 * meant to be used as borq.log
 * @param {string} logLevel - The logLevel like error, warn etc.
 * @param {string} message - the message to log
 */
function log(logLevel, message) {
  if (Config.environment !== 'test') {
    if (message === undefined) {
      logger.log(logLevel);
    } else {
      logger.log(logLevel, message);
    }
  }
}

/**
 * Configure Sentry using the env vars pased if in production
 * @param {string} sentryDSN The url given by Sentry tied to your account
 * @param {string} environment dev, testing, peoduction etc.
 * @param {string} loggingLevel error, info, warn etc.
 * @return {object} return raven object if in production
 */
function setupSentry(sentryDSN, environment, loggingLevel) {
  raven
    .config(sentryDSN, {
      logger: loggingLevel,
      environment,
    })
    .install();

  if (Config.sentryDSN) {
    return raven;
  }
  return null;
}

const sentry = Config.sentryDSN
  ? setupSentry(Config.sentryDSN, Config.environment, 'error')
  : undefined;

/**
 * A function to send rejected promise errors to both winston and sentry
 * @param {string} text the promise rejection error text
 */
function logRejectedPromise(text) {
  const message = 'Promise rejected: ' + text;
  log('error', message);
  if (Config.environment === 'production') {
    sentry.captureMessage(message);
  }
}

module.exports = {
  log,
  sentry,
  logRejectedPromise,
};
<|endoftext|>


<commit_before>'use strict';

/**
 *	Flips all given bits and returns the flipped bits.
 *
 *	@example
 *	not([1,0,1,1,0,1]) => [0,1,0,0,1,0]
 *
 *	@param bits {Array} the array containing the bits to flip
 *	@return {Array}
 */
function not (bits) {
	return applyOperation('not', bits);
}

/**
 *	Applies the OR operation, expects two arrays of the same size and returns a new one.
 *
 *	@example
 *	or([1,0,0,0,1,1,0,1], [0,1,1,0,0,1,0,0]) => [1,1,1,0,1,1,0,1]
 *
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function or (bits, otherBits) {
	return applyOperation('or', bits, otherBits);
}

/**
 *	Applies the NOR operation, expects two arrays of the same size and returns a new one.
 *
 *	@example
 *	nor([1,0,0,0,1,1,0,1], [0,1,1,0,0,1,0,0]) => [0,0,0,1,0,0,1,0]
 *
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function nor (bits, otherBits) {
	return applyOperation('nor', bits, otherBits);
}

/**
 *	Applies the exclusive or operation, expects two arrays of the same size and returns a new one.
 *
 *	@example
 *	xor([1,0,0,0,1,1,0,1], [0,1,1,0,0,1,0,0]) => [1,1,1,0,1,0,0,1]
 *
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function xor (bits, otherBits) {
	return applyOperation('xor', bits, otherBits);
}

/**
 *	Applies the exclusive NOR operation, expects two arrays of the same size and returns a new one.
 *
 *	@example
 *	xnor([1,0,0,0,1,1,0,1], [0,1,1,0,0,1,0,0]) => [0,0,0,1,0,1,1,0]
 *
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function xnor (bits, otherBits) {
	return applyOperation('xnor', bits, otherBits);
}

/**
 *	Applies the AND operation, expects two arrays of the same size and returns a new one.
 *
 *	@example
 *	and([1,0,0,0,1,1,0,1], [0,1,1,0,0,1,0,0]) => [0,0,0,0,0,1,0,0]
 *
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function and (bits, otherBits) {
	return applyOperation('and', bits, otherBits);
}

/**
 *	Applies the NAND operation, expects two arrays of the same size and returns a new one.
 *
 *	@example
 *	nand([1,0,0,0,1,1,0,1], [0,1,1,0,0,1,0,0]) => [1,1,1,1,1,0,1,1]
 *
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function nand (bits, otherBits) {
	return applyOperation('nand', bits, otherBits);
}

/**
 *	Helper method, contains the logic for the bitwise operations in this script.
 *
 *	@example
 *	applyOperation('nand', bits, otherBits);
 *
 *	@param type {String} the type of the operation
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function applyOperation (type, bits, otherBits) {
	var result = [];
	for (var i = 0; i < bits.length; i++) {
		switch (type) {
			case 'not':
				result[i] = bits[i] === 0 ? 1 : 0;
			break;
			case 'or':
				result[i] = bits[i] === 0 && bits[i] === otherBits[i] ? 0 : 1;
			break;
			case 'nor':
				result[i] = bits[i] === 0 && bits[i] === otherBits[i] ? 1 : 0;
			break;
			case 'xor':
				result[i] = bits[i] === otherBits[i] ? 0 : 1;
			break;
			case 'xnor':
				result[i] = bits[i] === otherBits[i] ? 1 : 0;
			break;
			case 'and':
				result[i] = bits[i] * otherBits[i];
			break;
			case 'nand':
				result[i] = bits[i] === 1 && bits[i] === otherBits[i] ? 0 : 1;
			break;
		}
	}
	return result;
}

module.exports = {
	not: not,
	or: or,
	nor: nor,
	xor: xor,
	xnor: xnor,
	and: and,
	nand: nand
};
<commit_msg>fixed some formatting<commit_after>'use strict';

/**
 *	Flips all given bits and returns the flipped bits.
 *
 *	@example
 *	not([1,0,1,1,0,1]) => [0,1,0,0,1,0]
 *
 *	@param bits {Array} the array containing the bits to flip
 *	@return {Array}
 */
function not (bits) {
	return applyOperation('not', bits);
}

/**
 *	Applies the OR operation, expects two arrays of the same size and returns a new one.
 *
 *	@example
 *	or([1,0,0,0,1,1,0,1], [0,1,1,0,0,1,0,0]) => [1,1,1,0,1,1,0,1]
 *
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function or (bits, otherBits) {
	return applyOperation('or', bits, otherBits);
}

/**
 *	Applies the NOR operation, expects two arrays of the same size and returns a new one.
 *
 *	@example
 *	nor([1,0,0,0,1,1,0,1], [0,1,1,0,0,1,0,0]) => [0,0,0,1,0,0,1,0]
 *
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function nor (bits, otherBits) {
	return applyOperation('nor', bits, otherBits);
}

/**
 *	Applies the exclusive or operation, expects two arrays of the same size and returns a new one.
 *
 *	@example
 *	xor([1,0,0,0,1,1,0,1], [0,1,1,0,0,1,0,0]) => [1,1,1,0,1,0,0,1]
 *
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function xor (bits, otherBits) {
	return applyOperation('xor', bits, otherBits);
}

/**
 *	Applies the exclusive NOR operation, expects two arrays of the same size and returns a new one.
 *
 *	@example
 *	xnor([1,0,0,0,1,1,0,1], [0,1,1,0,0,1,0,0]) => [0,0,0,1,0,1,1,0]
 *
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function xnor (bits, otherBits) {
	return applyOperation('xnor', bits, otherBits);
}

/**
 *	Applies the AND operation, expects two arrays of the same size and returns a new one.
 *
 *	@example
 *	and([1,0,0,0,1,1,0,1], [0,1,1,0,0,1,0,0]) => [0,0,0,0,0,1,0,0]
 *
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function and (bits, otherBits) {
	return applyOperation('and', bits, otherBits);
}

/**
 *	Applies the NAND operation, expects two arrays of the same size and returns a new one.
 *
 *	@example
 *	nand([1,0,0,0,1,1,0,1], [0,1,1,0,0,1,0,0]) => [1,1,1,1,1,0,1,1]
 *
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function nand (bits, otherBits) {
	return applyOperation('nand', bits, otherBits);
}

/**
 *	Helper method, contains the logic for the bitwise operations in this script.
 *
 *	@example
 *	applyOperation('nand', bits, otherBits);
 *
 *	@param type {String} the type of the operation
 *	@param bits {Array} the array containing the bits
 *	@param otherBits {Array} the array containing the other bits
 *	@return {Array}
 */
function applyOperation (type, bits, otherBits) {
	var result = [];
	for (var i = 0; i < bits.length; i++) {
		switch (type) {
			case 'not':
				result[i] = bits[i] === 0 ? 1 : 0;
			break;
			case 'or':
				result[i] = bits[i] === 0 && bits[i] === otherBits[i] ? 0 : 1;
			break;
			case 'nor':
				result[i] = bits[i] === 0 && bits[i] === otherBits[i] ? 1 : 0;
			break;
			case 'xor':
				result[i] = bits[i] === otherBits[i] ? 0 : 1;
			break;
			case 'xnor':
				result[i] = bits[i] === otherBits[i] ? 1 : 0;
			break;
			case 'and':
				result[i] = bits[i] * otherBits[i];
			break;
			case 'nand':
				result[i] = bits[i] === 1 && bits[i] === otherBits[i] ? 0 : 1;
			break;
		}
	}
	return result;
}

module.exports = {
	not: not,
	or: or,
	nor: nor,
	xor: xor,
	xnor: xnor,
	and: and,
	nand: nand
};
<|endoftext|>