<commit_before>/**
 * A list of all shareable constants for the application.
 */

export const ROOT_URL = (() => {
  // This is an "absolute path reference (a URL without the domain name)"
  // according to the Django docs
  let rootPath = document.head.querySelector('meta[name=kpi-root-path]');
  if (rootPath === null) {
    console.error('no kpi-root-path meta tag set. defaulting to ""');
    rootPath = '';
  } else {
    // Strip trailing slashes
    rootPath = rootPath.content.replace(/\/*$/, '');
  }
  return `${window.location.protocol}//${window.location.host}${rootPath}`;
})();

export const ANON_USERNAME = 'AnonymousUser';

/**
 * A hardcoded list of permissions codenames.
 * All of them are really defined on backend, but we need it here to be able to
 * build UI for handling them.
 */
export const PERMISSIONS_CODENAMES = {};
new Set([
  'view_asset',
  'change_asset',
  'discover_asset',
  'manage_asset',
  'add_submissions',
  'view_submissions',
  'partial_submissions',
  'change_submissions',
  'delete_submissions',
  'validate_submissions',
]).forEach((codename) => {PERMISSIONS_CODENAMES[codename] = codename;});
Object.freeze(PERMISSIONS_CODENAMES);

export const HOOK_LOG_STATUSES = {
  SUCCESS: 2,
  PENDING: 1,
  FAILED: 0,
};

export const KEY_CODES = Object.freeze({
  TAB: 9,
  ENTER: 13,
  ESC: 27,
  SPACE: 32,
  NBSP: 160, // non-breakable space
});

export const MODAL_TYPES = {
  SHARING: 'sharing',
  UPLOADING_XLS: 'uploading-xls',
  NEW_FORM: 'new-form',
  LIBRARY_NEW_ITEM: 'library-new-item',
  LIBRARY_TEMPLATE: 'library-template',
  LIBRARY_COLLECTION: 'library-collection',
  LIBRARY_UPLOAD: 'library-upload',
  ENKETO_PREVIEW: 'enketo-preview',
  SUBMISSION: 'submission',
  REPLACE_PROJECT: 'replace-project',
  TABLE_COLUMNS: 'table-columns',
  REST_SERVICES: 'rest-services',
  FORM_LANGUAGES: 'form-languages',
  FORM_TRANSLATIONS_TABLE: 'form-translation-table',
  ASSET_TAGS: 'asset-tags',
  ENCRYPT_FORM: 'encrypt-form',
  BULK_EDIT_SUBMISSIONS: 'bulk-edit-submissions',
};

export const PROJECT_SETTINGS_CONTEXTS = {
  NEW: 'newForm',
  EXISTING: 'existingForm',
  REPLACE: 'replaceProject',
  BUILDER: 'formBuilderAside',
};

export const update_states = {
  UNSAVED_CHANGES: -1,
  UP_TO_DATE: true,
  PENDING_UPDATE: false,
  SAVE_FAILED: 'SAVE_FAILED',
};

export const AVAILABLE_FORM_STYLES = [
  {value: '', label: t('Default - single page')},
  {value: 'theme-grid no-text-transform', label: t('Grid theme')},
  {value: 'theme-grid', label: t('Grid theme with headings in ALL CAPS')},
  {value: 'pages', label: t('Multiple pages')},
  {value: 'theme-grid pages no-text-transform', label: t('Grid theme + Multiple pages')},
  {value: 'theme-grid pages', label: t('Grid theme + Multiple pages + headings in ALL CAPS')},
];

export const VALIDATION_STATUSES = {
  no_status: {
    value: null,
    label: '—',
  },
  validation_status_not_approved: {
    value: 'validation_status_not_approved',
    label: t('Not Approved'),
  },
  validation_status_approved: {
    value: 'validation_status_approved',
    label: t('Approved'),
  },
  validation_status_on_hold: {
    value: 'validation_status_on_hold',
    label: t('On Hold'),
  },
};

export const VALIDATION_STATUSES_LIST = [
  VALIDATION_STATUSES.no_status,
  VALIDATION_STATUSES.validation_status_not_approved,
  VALIDATION_STATUSES.validation_status_approved,
  VALIDATION_STATUSES.validation_status_on_hold,
];

export const ASSET_TYPES = {
  question: {
    id: 'question',
    label: t('question'),
  },
  block: {
    id: 'block',
    label: t('block'),
  },
  template: {
    id: 'template',
    label: t('template'),
  },
  survey: {
    id: 'survey',
    label: t('project'),
  },
  collection: {
    id: 'collection',
    label: t('collection'),
  },
};

export const QUESTION_TYPES = Object.freeze({
  select_one: {
    label: t('Select One'),
    faIcon: 'fa-dot-circle-o',
    id: 'select_one',
  },
  select_multiple: {
    label: t('Select Many'),
    faIcon: 'fa-list-ul',
    id: 'select_multiple',
  },
  text: {
    label: t('Text'),
    faIcon: 'fa-lato-text',
    id: 'text',
  },
  integer: {
    label: t('Number'),
    faIcon: 'fa-lato-integer',
    id: 'integer',
  },
  decimal: {
    label: t('Decimal'),
    faIcon: 'fa-lato-decimal',
    id: 'decimal',
  },
  date: {
    label: t('Date'),
    faIcon: 'fa-calendar',
    id: 'date',
  },
  time: {
    label: t('Time'),
    faIcon: 'fa-clock-o',
    id: 'time',
  },
  datetime: {
    label: t('Date & time'),
    faIcon: 'fa-calendar clock-over',
    id: 'datetime',
  },
  geopoint: {
    label: t('Point'),
    faIcon: 'fa-map-marker',
    id: 'geopoint',
  },
  image: {
    label: t('Photo'),
    faIcon: 'fa-picture-o',
    id: 'image',
  },
  audio: {
    label: t('Audio'),
    faIcon: 'fa-volume-up',
    id: 'audio',
  },
  video: {
    label: t('Video'),
    faIcon: 'fa-video-camera',
    id: 'video',
  },
  geotrace: {
    label: t('Line'),
    faIcon: 'fa-share-alt',
    id: 'geotrace',
  },
  note: {
    label: t('Note'),
    faIcon: 'fa-bars',
    id: 'note',
  },
  barcode: {
    label: t('Barcode / QR Code'),
    faIcon: 'fa-qrcode',
    id: 'barcode',
  },
  acknowledge: {
    label: t('Acknowledge'),
    faIcon: 'fa-check-square-o',
    id: 'acknowledge',
  },
  geoshape: {
    label: t('Area'),
    faIcon: 'fa-square',
    id: 'geoshape',
  },
  score: {
    label: t('Rating'),
    faIcon: 'fa-server',
    id: 'score',
  },
  kobomatrix: {
    label: t('Question Matrix'),
    faIcon: 'fa-table',
    id: 'kobomatrix',
  },
  rank: {
    label: t('Ranking'),
    faIcon: 'fa-sort-amount-desc',
    id: 'rank',
  },
  calculate: {
    label: t('Calculate'),
    faIcon: 'fa-lato-calculate',
    id: 'calculate',
  },
  hidden: {
    label: t('Hidden'),
    faIcon: 'fa-eye-slash',
    id: 'hidden',
  },
  file: {
    label: t('File'),
    faIcon: 'fa-file',
    id: 'file',
  },
  range: {
    label: t('Range'),
    faIcon: 'fa-lato-range',
    id: 'range',
  },
});

export const META_QUESTION_TYPES = {};
new Set([
  'start',
  'end',
  'today',
  'username',
  'simserial',
  'subscriberid',
  'deviceid',
  'phonenumber',
  'audit',
]).forEach((codename) => {META_QUESTION_TYPES[codename] = codename;});
Object.freeze(META_QUESTION_TYPES);

// submission data extras being added by backend. see both of these:
// 1. https://github.com/kobotoolbox/kobocat/blob/78133d519f7b7674636c871e3ba5670cd64a7227/onadata/apps/viewer/models/parsed_instance.py#L242-L260
// 2. https://github.com/kobotoolbox/kpi/blob/7db39015866c905edc645677d72b9c1ea16067b1/jsapp/js/constants.es6#L284-L294
export const ADDITIONAL_SUBMISSION_PROPS = {};
new Set([
  // match the ordering of (Python) kpi.models.import_export_task.ExportTask.COPY_FIELDS
  '_id',
  '_uuid',
  '_submission_time',
  '_validation_status',
  '_notes',
  '_status',
  '_submitted_by',
  '_tags',
]).forEach((codename) => {ADDITIONAL_SUBMISSION_PROPS[codename] = codename;});
Object.freeze(ADDITIONAL_SUBMISSION_PROPS);

export const NAME_MAX_LENGTH = 255;

/**
 * for Backend calls, see their definitions at `kpi/filters.py`
 * NOTE: ORs require a parenthesis to work
 */
export const COMMON_QUERIES = Object.freeze({
  b: 'asset_type:block',
  q: 'asset_type:question',
  t: 'asset_type:template',
  s: 'asset_type:survey',
  c: 'asset_type:collection',
  qb: '(asset_type:question OR asset_type:block)',
  qbt: '(asset_type:question OR asset_type:block OR asset_type:template)',
  qbtc: '(asset_type:question OR asset_type:block OR asset_type:template OR asset_type:collection)',
});

export const ACCESS_TYPES = {};
new Set([
  'owned',
  'shared',
  'public',
  'subscribed',
]).forEach((codename) => {ACCESS_TYPES[codename] = codename;});
Object.freeze(ACCESS_TYPES);

export const GROUP_TYPES_BEGIN = {};
new Set([
  'begin_group',
  'begin_score',
  'begin_rank',
  'begin_kobomatrix',
  'begin_repeat',
]).forEach((kind) => {GROUP_TYPES_BEGIN[kind] = kind;});
Object.freeze(GROUP_TYPES_BEGIN);

export const GROUP_TYPES_END = {};
new Set([
  'end_group',
  'end_score',
  'end_rank',
  'end_kobomatrix',
  'end_repeat',
]).forEach((kind) => {GROUP_TYPES_END[kind] = kind;});
Object.freeze(GROUP_TYPES_END);

// a custom question type for score
export const SCORE_ROW_TYPE = 'score__row';

// a custom question type for rank
export const RANK_LEVEL_TYPE = 'rank__level';

export const CHOICE_LISTS = Object.freeze({
  SELECT: 'select_from_list_name',
  MATRIX: 'kobo--matrix_list',
  SCORE: 'kobo--score-choices',
  RANK: 'kobo--rank-items',
});

export const MATRIX_PAIR_PROPS = {
  inSurvey: CHOICE_LISTS.MATRIX,
  inChoices: 'list_name',
};

export const DEPLOYMENT_CATEGORIES = Object.freeze({
  Deployed: {id: 'Deployed', label: t('Deployed')},
  Draft: {id: 'Draft', label: t('Draft')},
  Archived: {id: 'Archived', label: t('Archived')},
});

export const REPORT_STYLES = Object.freeze({
  vertical: {value: 'vertical', label: t('Vertical')},
  donut: {value: 'donut', label: t('Donut')},
  area: {value: 'area', label: t('Area')},
  horizontal: {value: 'horizontal', label: t('Horizontal')},
  pie: {value: 'pie', label: t('Pie')},
  line: {value: 'line', label: t('Line')},
});

export const QUERY_LIMIT_DEFAULT = 5000;

export const ROUTES = Object.freeze({
  ACCOUNT_SETTINGS: '/account-settings',
  CHANGE_PASSWORD: '/change-password',
  LIBRARY: '/library',
  MY_LIBRARY: '/library/my-library',
  PUBLIC_COLLECTIONS: '/library/public-collections',
  NEW_LIBRARY_ITEM: '/library/asset/new',
  LIBRARY_ITEM: '/library/asset/:uid',
  EDIT_LIBRARY_ITEM: '/library/asset/:uid/edit',
  NEW_LIBRARY_CHILD: '/library/asset/:uid/new',
  LIBRARY_ITEM_JSON: '/library/asset/:uid/json',
  LIBRARY_ITEM_XFORM: '/library/asset/:uid/xform',
  FORMS: '/forms',
  FORM: '/forms/:uid',
  FORM_JSON: '/forms/:uid/json',
  FORM_XFORM: '/forms/:uid/xform',
  FORM_EDIT: '/forms/:uid/edit',
  FORM_SUMMARY: '/forms/:uid/summary',
  FORM_LANDING: '/forms/:uid/landing',
  FORM_DATA: '/forms/:uid/data',
  FORM_REPORT: '/forms/:uid/data/report',
  FORM_REPORT_OLD: '/forms/:uid/data/report-legacy',
  FORM_TABLE: '/forms/:uid/data/table',
  FORM_DOWNLOADS: '/forms/:uid/data/downloads',
  FORM_GALLERY: '/forms/:uid/data/gallery',
  FORM_MAP: '/forms/:uid/data/map',
  FORM_MAP_BY: '/forms/:uid/data/map/:viewby',
  FORM_SETTINGS: '/forms/:uid/settings',
  FORM_MEDIA: '/forms/:uid/settings/media',
  FORM_SHARING: '/forms/:uid/settings/sharing',
  FORM_REST: '/forms/:uid/settings/rest',
  FORM_REST_HOOK: '/forms/:uid/settings/rest/:hookUid',
  FORM_KOBOCAT: '/forms/:uid/settings/kobocat',
  FORM_RESET: '/forms/:uid/reset',
});

const constants = {
  ROOT_URL,
  ANON_USERNAME,
  PERMISSIONS_CODENAMES,
  HOOK_LOG_STATUSES,
  KEY_CODES,
  MODAL_TYPES,
  PROJECT_SETTINGS_CONTEXTS,
  update_states,
  AVAILABLE_FORM_STYLES,
  VALIDATION_STATUSES,
  VALIDATION_STATUSES_LIST,
  ASSET_TYPES,
  QUESTION_TYPES,
  META_QUESTION_TYPES,
  ADDITIONAL_SUBMISSION_PROPS,
  NAME_MAX_LENGTH,
  COMMON_QUERIES,
  ACCESS_TYPES,
  GROUP_TYPES_BEGIN,
  GROUP_TYPES_END,
  SCORE_ROW_TYPE,
  RANK_LEVEL_TYPE,
  DEPLOYMENT_CATEGORIES,
  REPORT_STYLES,
  ROUTES,
  QUERY_LIMIT_DEFAULT,
  CHOICE_LISTS,
};

export default constants;
<commit_msg>add useful note about permissions<commit_after>/**
 * A list of all shareable constants for the application.
 */

export const ROOT_URL = (() => {
  // This is an "absolute path reference (a URL without the domain name)"
  // according to the Django docs
  let rootPath = document.head.querySelector('meta[name=kpi-root-path]');
  if (rootPath === null) {
    console.error('no kpi-root-path meta tag set. defaulting to ""');
    rootPath = '';
  } else {
    // Strip trailing slashes
    rootPath = rootPath.content.replace(/\/*$/, '');
  }
  return `${window.location.protocol}//${window.location.host}${rootPath}`;
})();

export const ANON_USERNAME = 'AnonymousUser';

/**
 * BAD CODE™ A hardcoded list of permissions codenames.
 *
 * All of them are really defined on backend, and we get them through the
 * permissions config endpoint, but as we need these names to reference them in
 * the code to build the UI it's a necessary evil.
 *
 * NOTE: to know what these permissions permit see `kpi/permissions.py` file,
 * where you have to match the classes with endpoints and their HTTP methods.
 */
export const PERMISSIONS_CODENAMES = {};
new Set([
  'view_asset',
  'change_asset',
  'discover_asset',
  'manage_asset',
  'add_submissions',
  'view_submissions',
  'partial_submissions',
  'change_submissions',
  'delete_submissions',
  'validate_submissions',
]).forEach((codename) => {PERMISSIONS_CODENAMES[codename] = codename;});
Object.freeze(PERMISSIONS_CODENAMES);

export const HOOK_LOG_STATUSES = {
  SUCCESS: 2,
  PENDING: 1,
  FAILED: 0,
};

export const KEY_CODES = Object.freeze({
  TAB: 9,
  ENTER: 13,
  ESC: 27,
  SPACE: 32,
  NBSP: 160, // non-breakable space
});

export const MODAL_TYPES = {
  SHARING: 'sharing',
  UPLOADING_XLS: 'uploading-xls',
  NEW_FORM: 'new-form',
  LIBRARY_NEW_ITEM: 'library-new-item',
  LIBRARY_TEMPLATE: 'library-template',
  LIBRARY_COLLECTION: 'library-collection',
  LIBRARY_UPLOAD: 'library-upload',
  ENKETO_PREVIEW: 'enketo-preview',
  SUBMISSION: 'submission',
  REPLACE_PROJECT: 'replace-project',
  TABLE_COLUMNS: 'table-columns',
  REST_SERVICES: 'rest-services',
  FORM_LANGUAGES: 'form-languages',
  FORM_TRANSLATIONS_TABLE: 'form-translation-table',
  ASSET_TAGS: 'asset-tags',
  ENCRYPT_FORM: 'encrypt-form',
  BULK_EDIT_SUBMISSIONS: 'bulk-edit-submissions',
};

export const PROJECT_SETTINGS_CONTEXTS = {
  NEW: 'newForm',
  EXISTING: 'existingForm',
  REPLACE: 'replaceProject',
  BUILDER: 'formBuilderAside',
};

export const update_states = {
  UNSAVED_CHANGES: -1,
  UP_TO_DATE: true,
  PENDING_UPDATE: false,
  SAVE_FAILED: 'SAVE_FAILED',
};

export const AVAILABLE_FORM_STYLES = [
  {value: '', label: t('Default - single page')},
  {value: 'theme-grid no-text-transform', label: t('Grid theme')},
  {value: 'theme-grid', label: t('Grid theme with headings in ALL CAPS')},
  {value: 'pages', label: t('Multiple pages')},
  {value: 'theme-grid pages no-text-transform', label: t('Grid theme + Multiple pages')},
  {value: 'theme-grid pages', label: t('Grid theme + Multiple pages + headings in ALL CAPS')},
];

export const VALIDATION_STATUSES = {
  no_status: {
    value: null,
    label: '—',
  },
  validation_status_not_approved: {
    value: 'validation_status_not_approved',
    label: t('Not Approved'),
  },
  validation_status_approved: {
    value: 'validation_status_approved',
    label: t('Approved'),
  },
  validation_status_on_hold: {
    value: 'validation_status_on_hold',
    label: t('On Hold'),
  },
};

export const VALIDATION_STATUSES_LIST = [
  VALIDATION_STATUSES.no_status,
  VALIDATION_STATUSES.validation_status_not_approved,
  VALIDATION_STATUSES.validation_status_approved,
  VALIDATION_STATUSES.validation_status_on_hold,
];

export const ASSET_TYPES = {
  question: {
    id: 'question',
    label: t('question'),
  },
  block: {
    id: 'block',
    label: t('block'),
  },
  template: {
    id: 'template',
    label: t('template'),
  },
  survey: {
    id: 'survey',
    label: t('project'),
  },
  collection: {
    id: 'collection',
    label: t('collection'),
  },
};

export const QUESTION_TYPES = Object.freeze({
  select_one: {
    label: t('Select One'),
    faIcon: 'fa-dot-circle-o',
    id: 'select_one',
  },
  select_multiple: {
    label: t('Select Many'),
    faIcon: 'fa-list-ul',
    id: 'select_multiple',
  },
  text: {
    label: t('Text'),
    faIcon: 'fa-lato-text',
    id: 'text',
  },
  integer: {
    label: t('Number'),
    faIcon: 'fa-lato-integer',
    id: 'integer',
  },
  decimal: {
    label: t('Decimal'),
    faIcon: 'fa-lato-decimal',
    id: 'decimal',
  },
  date: {
    label: t('Date'),
    faIcon: 'fa-calendar',
    id: 'date',
  },
  time: {
    label: t('Time'),
    faIcon: 'fa-clock-o',
    id: 'time',
  },
  datetime: {
    label: t('Date & time'),
    faIcon: 'fa-calendar clock-over',
    id: 'datetime',
  },
  geopoint: {
    label: t('Point'),
    faIcon: 'fa-map-marker',
    id: 'geopoint',
  },
  image: {
    label: t('Photo'),
    faIcon: 'fa-picture-o',
    id: 'image',
  },
  audio: {
    label: t('Audio'),
    faIcon: 'fa-volume-up',
    id: 'audio',
  },
  video: {
    label: t('Video'),
    faIcon: 'fa-video-camera',
    id: 'video',
  },
  geotrace: {
    label: t('Line'),
    faIcon: 'fa-share-alt',
    id: 'geotrace',
  },
  note: {
    label: t('Note'),
    faIcon: 'fa-bars',
    id: 'note',
  },
  barcode: {
    label: t('Barcode / QR Code'),
    faIcon: 'fa-qrcode',
    id: 'barcode',
  },
  acknowledge: {
    label: t('Acknowledge'),
    faIcon: 'fa-check-square-o',
    id: 'acknowledge',
  },
  geoshape: {
    label: t('Area'),
    faIcon: 'fa-square',
    id: 'geoshape',
  },
  score: {
    label: t('Rating'),
    faIcon: 'fa-server',
    id: 'score',
  },
  kobomatrix: {
    label: t('Question Matrix'),
    faIcon: 'fa-table',
    id: 'kobomatrix',
  },
  rank: {
    label: t('Ranking'),
    faIcon: 'fa-sort-amount-desc',
    id: 'rank',
  },
  calculate: {
    label: t('Calculate'),
    faIcon: 'fa-lato-calculate',
    id: 'calculate',
  },
  hidden: {
    label: t('Hidden'),
    faIcon: 'fa-eye-slash',
    id: 'hidden',
  },
  file: {
    label: t('File'),
    faIcon: 'fa-file',
    id: 'file',
  },
  range: {
    label: t('Range'),
    faIcon: 'fa-lato-range',
    id: 'range',
  },
});

export const META_QUESTION_TYPES = {};
new Set([
  'start',
  'end',
  'today',
  'username',
  'simserial',
  'subscriberid',
  'deviceid',
  'phonenumber',
  'audit',
]).forEach((codename) => {META_QUESTION_TYPES[codename] = codename;});
Object.freeze(META_QUESTION_TYPES);

// submission data extras being added by backend. see both of these:
// 1. https://github.com/kobotoolbox/kobocat/blob/78133d519f7b7674636c871e3ba5670cd64a7227/onadata/apps/viewer/models/parsed_instance.py#L242-L260
// 2. https://github.com/kobotoolbox/kpi/blob/7db39015866c905edc645677d72b9c1ea16067b1/jsapp/js/constants.es6#L284-L294
export const ADDITIONAL_SUBMISSION_PROPS = {};
new Set([
  // match the ordering of (Python) kpi.models.import_export_task.ExportTask.COPY_FIELDS
  '_id',
  '_uuid',
  '_submission_time',
  '_validation_status',
  '_notes',
  '_status',
  '_submitted_by',
  '_tags',
]).forEach((codename) => {ADDITIONAL_SUBMISSION_PROPS[codename] = codename;});
Object.freeze(ADDITIONAL_SUBMISSION_PROPS);

export const NAME_MAX_LENGTH = 255;

/**
 * for Backend calls, see their definitions at `kpi/filters.py`
 * NOTE: ORs require a parenthesis to work
 */
export const COMMON_QUERIES = Object.freeze({
  b: 'asset_type:block',
  q: 'asset_type:question',
  t: 'asset_type:template',
  s: 'asset_type:survey',
  c: 'asset_type:collection',
  qb: '(asset_type:question OR asset_type:block)',
  qbt: '(asset_type:question OR asset_type:block OR asset_type:template)',
  qbtc: '(asset_type:question OR asset_type:block OR asset_type:template OR asset_type:collection)',
});

export const ACCESS_TYPES = {};
new Set([
  'owned',
  'shared',
  'public',
  'subscribed',
]).forEach((codename) => {ACCESS_TYPES[codename] = codename;});
Object.freeze(ACCESS_TYPES);

export const GROUP_TYPES_BEGIN = {};
new Set([
  'begin_group',
  'begin_score',
  'begin_rank',
  'begin_kobomatrix',
  'begin_repeat',
]).forEach((kind) => {GROUP_TYPES_BEGIN[kind] = kind;});
Object.freeze(GROUP_TYPES_BEGIN);

export const GROUP_TYPES_END = {};
new Set([
  'end_group',
  'end_score',
  'end_rank',
  'end_kobomatrix',
  'end_repeat',
]).forEach((kind) => {GROUP_TYPES_END[kind] = kind;});
Object.freeze(GROUP_TYPES_END);

// a custom question type for score
export const SCORE_ROW_TYPE = 'score__row';

// a custom question type for rank
export const RANK_LEVEL_TYPE = 'rank__level';

export const CHOICE_LISTS = Object.freeze({
  SELECT: 'select_from_list_name',
  MATRIX: 'kobo--matrix_list',
  SCORE: 'kobo--score-choices',
  RANK: 'kobo--rank-items',
});

export const MATRIX_PAIR_PROPS = {
  inSurvey: CHOICE_LISTS.MATRIX,
  inChoices: 'list_name',
};

export const DEPLOYMENT_CATEGORIES = Object.freeze({
  Deployed: {id: 'Deployed', label: t('Deployed')},
  Draft: {id: 'Draft', label: t('Draft')},
  Archived: {id: 'Archived', label: t('Archived')},
});

export const REPORT_STYLES = Object.freeze({
  vertical: {value: 'vertical', label: t('Vertical')},
  donut: {value: 'donut', label: t('Donut')},
  area: {value: 'area', label: t('Area')},
  horizontal: {value: 'horizontal', label: t('Horizontal')},
  pie: {value: 'pie', label: t('Pie')},
  line: {value: 'line', label: t('Line')},
});

export const QUERY_LIMIT_DEFAULT = 5000;

export const ROUTES = Object.freeze({
  ACCOUNT_SETTINGS: '/account-settings',
  CHANGE_PASSWORD: '/change-password',
  LIBRARY: '/library',
  MY_LIBRARY: '/library/my-library',
  PUBLIC_COLLECTIONS: '/library/public-collections',
  NEW_LIBRARY_ITEM: '/library/asset/new',
  LIBRARY_ITEM: '/library/asset/:uid',
  EDIT_LIBRARY_ITEM: '/library/asset/:uid/edit',
  NEW_LIBRARY_CHILD: '/library/asset/:uid/new',
  LIBRARY_ITEM_JSON: '/library/asset/:uid/json',
  LIBRARY_ITEM_XFORM: '/library/asset/:uid/xform',
  FORMS: '/forms',
  FORM: '/forms/:uid',
  FORM_JSON: '/forms/:uid/json',
  FORM_XFORM: '/forms/:uid/xform',
  FORM_EDIT: '/forms/:uid/edit',
  FORM_SUMMARY: '/forms/:uid/summary',
  FORM_LANDING: '/forms/:uid/landing',
  FORM_DATA: '/forms/:uid/data',
  FORM_REPORT: '/forms/:uid/data/report',
  FORM_REPORT_OLD: '/forms/:uid/data/report-legacy',
  FORM_TABLE: '/forms/:uid/data/table',
  FORM_DOWNLOADS: '/forms/:uid/data/downloads',
  FORM_GALLERY: '/forms/:uid/data/gallery',
  FORM_MAP: '/forms/:uid/data/map',
  FORM_MAP_BY: '/forms/:uid/data/map/:viewby',
  FORM_SETTINGS: '/forms/:uid/settings',
  FORM_MEDIA: '/forms/:uid/settings/media',
  FORM_SHARING: '/forms/:uid/settings/sharing',
  FORM_REST: '/forms/:uid/settings/rest',
  FORM_REST_HOOK: '/forms/:uid/settings/rest/:hookUid',
  FORM_KOBOCAT: '/forms/:uid/settings/kobocat',
  FORM_RESET: '/forms/:uid/reset',
});

const constants = {
  ROOT_URL,
  ANON_USERNAME,
  PERMISSIONS_CODENAMES,
  HOOK_LOG_STATUSES,
  KEY_CODES,
  MODAL_TYPES,
  PROJECT_SETTINGS_CONTEXTS,
  update_states,
  AVAILABLE_FORM_STYLES,
  VALIDATION_STATUSES,
  VALIDATION_STATUSES_LIST,
  ASSET_TYPES,
  QUESTION_TYPES,
  META_QUESTION_TYPES,
  ADDITIONAL_SUBMISSION_PROPS,
  NAME_MAX_LENGTH,
  COMMON_QUERIES,
  ACCESS_TYPES,
  GROUP_TYPES_BEGIN,
  GROUP_TYPES_END,
  SCORE_ROW_TYPE,
  RANK_LEVEL_TYPE,
  DEPLOYMENT_CATEGORIES,
  REPORT_STYLES,
  ROUTES,
  QUERY_LIMIT_DEFAULT,
  CHOICE_LISTS,
};

export default constants;
<|endoftext|>


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

    /*
    group
    name
    slam
    score1
    score2
    scoreN
    ignoredScore1
    ignoredScore2
    extraScore
    totalScore
    totalScoreWithIgnoredScore
    totalScoreWithIgnoredScoreAndExtraScore
    */

    angular.module('psadmin').service('csvExportService', function (storageService, Blob, FileSaver) {
        this.exportCSV = function(competitionId) {
          var e = angular.fromJson(storageService.getEventFromLocalStorage());

          var competition = {};
          for(var element of e.competitions) {
            if(element.id == competitionId) {
              competition = element;
              break;
            }
          }
          if(competition == {}) {
            return;
          }

          var content = "";

          var append = function(value) {
            content += "\"" + value + "\";";
          }

          append("group");
          append("name");
          append("slam");
          for(var i = 1; i <= competition.jurors; i++) {
            append("score" + i);
          }
          append("ignoredScore1");
          append("ignoredScore2");
          append("extraScore");
          append("totalScore");
          append("totalScoreWithIgnoredScore");
          append("totalScoreWithIgnoredScoreAndExtraScore");
          content += "\n";

          for(var group of competition.groups) {
            for(var participant of group.participants) {
              console.log(participant);
              for(var p of e.participants) {
                if(p.id == participant.id) {
                  append(group.name);
                  append(p.name);
                  append(p.slam);
                  for(var score of participant.scores) {
                    append(score.value);
                  }
                  for(var score of participant.scores) {
                    if(score.ignored) {
                      append(score.value);
                    }
                  }
                  append(participant.extraScore);
                  append(participant.totalScore);
                  append(participant.secondTotalScore);
                  append(participant.thirdTotalScore);
                  content += "\n";
                }
              }
            }
          }

          var blob = new Blob([content], {type: "text/plain;charset=utf-8"})
          FileSaver.saveAs(blob, competition.name + "-scores.csv");
        };

        return this;
    });
})();
<commit_msg>replace for of loops in csvExportService for better browser support<commit_after>(function () {
    'use strict';

    angular.module('psadmin').service('csvExportService', function ($rootScope, Blob, FileSaver) {
        this.exportCSV = function(competitionId) {
            var e = $rootScope.event;

            var competition = null;
            var matchingCompetitionKeys = Object.keys(e.competitions).filter(function (key) {
                return e.competitions[key].id == competitionId;
            });
            if (matchingCompetitionKeys && matchingCompetitionKeys.length === 1) {
                competition = e.competitions[matchingCompetitionKeys[0]];
            }
            if (competition === null) {
                return false;
            }

            var content = "";

            var append = function (value) {
                content += "\"" + value + "\";";
            };

            append("group");
            append("name");
            append("slam");
            for (var i = 1; i <= competition.jurors; i++) {
                append("score" + i);
            }
            append("ignoredScore1");
            append("ignoredScore2");
            append("extraScore");
            append("totalScore");
            append("totalScoreWithIgnoredScore");
            append("totalScoreWithIgnoredScoreAndExtraScore");
            content += "\n";

            competition.groups.forEach(function (group) {
                group.participants.forEach(function (participant) {
                    console.log(participant);
                    e.participants.forEach(function (p) {
                        if (p.id == participant.id) {
                            append(group.name);
                            append(p.name);
                            append(p.slam);
                            participant.scores.forEach(function (score) {
                                append(score.value);
                            });
                            participant.scores.forEach(function (score) {
                                if (score.ignored) {
                                    append(score.value);
                                }
                            });
                            append(participant.extraScore);
                            append(participant.totalScore);
                            append(participant.secondTotalScore);
                            append(participant.thirdTotalScore);
                            content += "\n";
                        }
                    })
                })
            });

            var blob = new Blob([content], {type: "text/plain;charset=utf-8"});
            FileSaver.saveAs(blob, competition.name + "-scores.csv");
        };

        return this;
    });
})();
<|endoftext|>


<commit_before>// Setup basic express server
var path = require('path');
var read = require('fs').readFileSync;
var express = require('express');
var app = express();

app.set('views','cloud/views');   // 设置模板目录
app.set('view engine', 'ejs');    // 设置 template 引擎
app.use(express.bodyParser());    // 读取请求 body 的中间件

// var clientSource = read(path.resolve('.', 'socket.io-client/socket.io.js'), 'utf-8');
// var clientSource1 = read('socket.io-client/socket.io.js', 'utf-8');
var clientSource2 = read('node_modules/socket.io-client/socket.io.js', 'utf-8');
var clientSource3 = read('../node_modules/socket.io-client/socket.io.js', 'utf-8');

app.get('/socket.io/socket.io.js', function(req, res) {
    var etag = req.headers['if-none-match'];
    if (etag) {
      if (clientVersion == etag) {
        debug('serve client 304');
        res.writeHead(304);
        res.end();
        return;
      }
    }

    debug('serve client source');
    res.setHeader('Content-Type', 'application/javascript');
    res.setHeader('ETag', clientVersion);
    res.writeHead(200);
    res.end(clientSource);
});

var server = require('http').createServer(app);
var io = require('socket.io')(server);
// var port = process.env.PORT || 3000;
var port = 80;

server.listen(port, function () {
  console.log('Server listening at port %d', port);
});

// Routing
// app.use(express.static(__dirname + '/public'));

// Chatroom

// usernames which are currently connected to the chat
var usernames = {};
var numUsers = 0;

io.on('connection', function (socket) {
  var addedUser = false;

  // when the client emits 'new message', this listens and executes
  socket.on('new message', function (data) {
    // we tell the client to execute 'new message'
    socket.broadcast.emit('new message', {
      username: socket.username,
      message: data
    });
  });

  // when the client emits 'add user', this listens and executes
  socket.on('add user', function (username) {
    // we store the username in the socket session for this client
    socket.username = username;
    // add the client's username to the global list
    usernames[username] = username;
    ++numUsers;
    addedUser = true;
    socket.emit('login', {
      numUsers: numUsers
    });
    // echo globally (all clients) that a person has connected
    socket.broadcast.emit('user joined', {
      username: socket.username,
      numUsers: numUsers
    });
  });

  // when the client emits 'typing', we broadcast it to others
  socket.on('typing', function () {
    socket.broadcast.emit('typing', {
      username: socket.username
    });
  });

  // when the client emits 'stop typing', we broadcast it to others
  socket.on('stop typing', function () {
    socket.broadcast.emit('stop typing', {
      username: socket.username
    });
  });

  // when the user disconnects.. perform this
  socket.on('disconnect', function () {
    // remove the username from global usernames list
    if (addedUser) {
      delete usernames[socket.username];
      --numUsers;

      // echo globally that this client has left
      socket.broadcast.emit('user left', {
        username: socket.username,
        numUsers: numUsers
      });
    }
  });
});
<commit_msg>Modify page.<commit_after>// Setup basic express server
var path = require('path');
var read = require('fs').readFileSync;
var express = require('express');
var app = express();

app.set('views','cloud/views');   // 设置模板目录
app.set('view engine', 'ejs');    // 设置 template 引擎
app.use(express.bodyParser());    // 读取请求 body 的中间件

// var clientSource = read(path.resolve('.', 'socket.io-client/socket.io.js'), 'utf-8');
// var clientSource1 = read('socket.io-client/socket.io.js', 'utf-8');
// var clientSource2 = read('node_modules/socket.io-client/socket.io.js', 'utf-8');
var clientSource3 = read('../node_modules/socket.io-client/socket.io.js', 'utf-8');

app.get('/socket.io/socket.io.js', function(req, res) {
    var etag = req.headers['if-none-match'];
    if (etag) {
      if (clientVersion == etag) {
        debug('serve client 304');
        res.writeHead(304);
        res.end();
        return;
      }
    }

    debug('serve client source');
    res.setHeader('Content-Type', 'application/javascript');
    res.setHeader('ETag', clientVersion);
    res.writeHead(200);
    res.end(clientSource);
});

var server = require('http').createServer(app);
var io = require('socket.io')(server);
// var port = process.env.PORT || 3000;
var port = 80;

server.listen(port, function () {
  console.log('Server listening at port %d', port);
});

// Routing
// app.use(express.static(__dirname + '/public'));

// Chatroom

// usernames which are currently connected to the chat
var usernames = {};
var numUsers = 0;

io.on('connection', function (socket) {
  var addedUser = false;

  // when the client emits 'new message', this listens and executes
  socket.on('new message', function (data) {
    // we tell the client to execute 'new message'
    socket.broadcast.emit('new message', {
      username: socket.username,
      message: data
    });
  });

  // when the client emits 'add user', this listens and executes
  socket.on('add user', function (username) {
    // we store the username in the socket session for this client
    socket.username = username;
    // add the client's username to the global list
    usernames[username] = username;
    ++numUsers;
    addedUser = true;
    socket.emit('login', {
      numUsers: numUsers
    });
    // echo globally (all clients) that a person has connected
    socket.broadcast.emit('user joined', {
      username: socket.username,
      numUsers: numUsers
    });
  });

  // when the client emits 'typing', we broadcast it to others
  socket.on('typing', function () {
    socket.broadcast.emit('typing', {
      username: socket.username
    });
  });

  // when the client emits 'stop typing', we broadcast it to others
  socket.on('stop typing', function () {
    socket.broadcast.emit('stop typing', {
      username: socket.username
    });
  });

  // when the user disconnects.. perform this
  socket.on('disconnect', function () {
    // remove the username from global usernames list
    if (addedUser) {
      delete usernames[socket.username];
      --numUsers;

      // echo globally that this client has left
      socket.broadcast.emit('user left', {
        username: socket.username,
        numUsers: numUsers
      });
    }
  });
});
<|endoftext|>


<commit_before>!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.debug=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){

/**
 * This is the common logic for both the Node.js and web browser
 * implementations of `debug()`.
 *
 * Expose `debug()` as the module.
 */

exports = module.exports = debug;
exports.coerce = coerce;
exports.disable = disable;
exports.enable = enable;
exports.enabled = enabled;
exports.humanize = require('ms');

/**
 * The currently active debug mode names, and names to skip.
 */

exports.names = [];
exports.skips = [];

/**
 * Map of special "%n" handling functions, for the debug "format" argument.
 *
 * Valid key names are a single, lowercased letter, i.e. "n".
 */

exports.formatters = {};

/**
 * Previously assigned color.
 */

var prevColor = 0;

/**
 * Previous log timestamp.
 */

var prevTime;

/**
 * Select a color.
 *
 * @return {Number}
 * @api private
 */

function selectColor() {
  return exports.colors[prevColor++ % exports.colors.length];
}

/**
 * Create a debugger with the given `namespace`.
 *
 * @param {String} namespace
 * @return {Function}
 * @api public
 */

function debug(namespace) {

  // define the `disabled` version
  function disabled() {
  }
  disabled.enabled = false;

  // define the `enabled` version
  function enabled() {

    var self = enabled;

    // set `diff` timestamp
    var curr = +new Date();
    var ms = curr - (prevTime || curr);
    self.diff = ms;
    self.prev = prevTime;
    self.curr = curr;
    prevTime = curr;

    // add the `color` if not set
    if (null == self.useColors) self.useColors = exports.useColors();
    if (null == self.color && self.useColors) self.color = selectColor();

    var args = Array.prototype.slice.call(arguments);

    args[0] = exports.coerce(args[0]);

    if ('string' !== typeof args[0]) {
      // anything else let's inspect with %o
      args = ['%o'].concat(args);
    }

    // apply any `formatters` transformations
    var index = 0;
    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {
      // if we encounter an escaped % then don't increase the array index
      if (match === '%%') return match;
      index++;
      var formatter = exports.formatters[format];
      if ('function' === typeof formatter) {
        var val = args[index];
        match = formatter.call(self, val);

        // now we need to remove `args[index]` since it's inlined in the `format`
        args.splice(index, 1);
        index--;
      }
      return match;
    });

    if ('function' === typeof exports.formatArgs) {
      args = exports.formatArgs.apply(self, args);
    }
    var logFn = enabled.log || exports.log || console.log.bind(console);
    logFn.apply(self, args);
  }
  enabled.enabled = true;

  var fn = exports.enabled(namespace) ? enabled : disabled;

  fn.namespace = namespace;

  return fn;
}

/**
 * Enables a debug mode by namespaces. This can include modes
 * separated by a colon and wildcards.
 *
 * @param {String} namespaces
 * @api public
 */

function enable(namespaces) {
  exports.save(namespaces);

  var split = (namespaces || '').split(/[\s,]+/);
  var len = split.length;

  for (var i = 0; i < len; i++) {
    if (!split[i]) continue; // ignore empty strings
    namespaces = split[i].replace(/\*/g, '.*?');
    if (namespaces[0] === '-') {
      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
    } else {
      exports.names.push(new RegExp('^' + namespaces + '$'));
    }
  }
}

/**
 * Disable debug output.
 *
 * @api public
 */

function disable() {
  exports.enable('');
}

/**
 * Returns true if the given mode name is enabled, false otherwise.
 *
 * @param {String} name
 * @return {Boolean}
 * @api public
 */

function enabled(name) {
  var i, len;
  for (i = 0, len = exports.skips.length; i < len; i++) {
    if (exports.skips[i].test(name)) {
      return false;
    }
  }
  for (i = 0, len = exports.names.length; i < len; i++) {
    if (exports.names[i].test(name)) {
      return true;
    }
  }
  return false;
}

/**
 * Coerce `val`.
 *
 * @param {Mixed} val
 * @return {Mixed}
 * @api private
 */

function coerce(val) {
  if (val instanceof Error) return val.stack || val.message;
  return val;
}

},{"ms":2}],2:[function(require,module,exports){
/**
 * Helpers.
 */

var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var y = d * 365.25;

/**
 * Parse or format the given `val`.
 *
 * Options:
 *
 *  - `long` verbose formatting [false]
 *
 * @param {String|Number} val
 * @param {Object} options
 * @return {String|Number}
 * @api public
 */

module.exports = function(val, options){
  options = options || {};
  if ('string' == typeof val) return parse(val);
  return options.long
    ? long(val)
    : short(val);
};

/**
 * Parse the given `str` and return milliseconds.
 *
 * @param {String} str
 * @return {Number}
 * @api private
 */

function parse(str) {
  var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
  if (!match) return;
  var n = parseFloat(match[1]);
  var type = (match[2] || 'ms').toLowerCase();
  switch (type) {
    case 'years':
    case 'year':
    case 'y':
      return n * y;
    case 'days':
    case 'day':
    case 'd':
      return n * d;
    case 'hours':
    case 'hour':
    case 'h':
      return n * h;
    case 'minutes':
    case 'minute':
    case 'm':
      return n * m;
    case 'seconds':
    case 'second':
    case 's':
      return n * s;
    case 'ms':
      return n;
  }
}

/**
 * Short format for `ms`.
 *
 * @param {Number} ms
 * @return {String}
 * @api private
 */

function short(ms) {
  if (ms >= d) return Math.round(ms / d) + 'd';
  if (ms >= h) return Math.round(ms / h) + 'h';
  if (ms >= m) return Math.round(ms / m) + 'm';
  if (ms >= s) return Math.round(ms / s) + 's';
  return ms + 'ms';
}

/**
 * Long format for `ms`.
 *
 * @param {Number} ms
 * @return {String}
 * @api private
 */

function long(ms) {
  return plural(ms, d, 'day')
    || plural(ms, h, 'hour')
    || plural(ms, m, 'minute')
    || plural(ms, s, 'second')
    || ms + ' ms';
}

/**
 * Pluralization helper.
 */

function plural(ms, n, name) {
  if (ms < n) return;
  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
  return Math.ceil(ms / n) + ' ' + name + 's';
}

},{}],3:[function(require,module,exports){

/**
 * This is the web browser implementation of `debug()`.
 *
 * Expose `debug()` as the module.
 */

exports = module.exports = require('./debug');
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;

/**
 * Colors.
 */

exports.colors = [
  'lightseagreen',
  'forestgreen',
  'goldenrod',
  'dodgerblue',
  'darkorchid',
  'crimson'
];

/**
 * Currently only WebKit-based Web Inspectors, Firefox >= v31,
 * and the Firebug extension (any Firefox version) are known
 * to support "%c" CSS customizations.
 *
 * TODO: add a `localStorage` variable to explicitly enable/disable colors
 */

function useColors() {
  // is webkit? http://stackoverflow.com/a/16459606/376773
  return ('WebkitAppearance' in document.documentElement.style) ||
    // is firebug? http://stackoverflow.com/a/398120/376773
    (window.console && (console.firebug || (console.exception && console.table))) ||
    // is firefox >= v31?
    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
    (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31);
}

/**
 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
 */

exports.formatters.j = function(v) {
  return JSON.stringify(v);
};

/**
 * Colorize log arguments if enabled.
 *
 * @api public
 */

function formatArgs() {
  var args = arguments;
  var useColors = this.useColors;

  args[0] = (useColors ? '%c' : '')
    + this.namespace
    + (useColors ? ' %c' : ' ')
    + args[0]
    + (useColors ? '%c ' : ' ')
    + '+' + exports.humanize(this.diff);

  if (!useColors) return args;

  var c = 'color: ' + this.color;
  args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));

  // the final "%c" is somewhat tricky, because there could be other
  // arguments passed either before or after the %c, so we need to
  // figure out the correct index to insert the CSS into
  var index = 0;
  var lastC = 0;
  args[0].replace(/%[a-z%]/g, function(match) {
    if ('%%' === match) return;
    index++;
    if ('%c' === match) {
      // we only are interested in the *last* %c
      // (the user may have provided their own)
      lastC = index;
    }
  });

  args.splice(lastC, 0, c);
  return args;
}

/**
 * Invokes `console.log()` when available.
 * No-op when `console.log` is not a "function".
 *
 * @api public
 */

function log() {
  // This hackery is required for IE8,
  // where the `console.log` function doesn't have 'apply'
  return 'object' == typeof console
    && 'function' == typeof console.log
    && Function.prototype.apply.call(console.log, console, arguments);
}

/**
 * Save `namespaces`.
 *
 * @param {String} namespaces
 * @api private
 */

function save(namespaces) {
  try {
    if (null == namespaces) {
      localStorage.removeItem('debug');
    } else {
      localStorage.debug = namespaces;
    }
  } catch(e) {}
}

/**
 * Load `namespaces`.
 *
 * @return {String} returns the previously persisted debug modes
 * @api private
 */

function load() {
  var r;
  try {
    r = localStorage.debug;
  } catch(e) {}
  return r;
}

/**
 * Enable namespaces listed in `localStorage.debug` initially.
 */

exports.enable(load());

},{"./debug":1}]},{},[3])(3)
});<commit_msg>dist: recompile<commit_after>(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.debug = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){

/**
 * This is the common logic for both the Node.js and web browser
 * implementations of `debug()`.
 *
 * Expose `debug()` as the module.
 */

exports = module.exports = debug;
exports.coerce = coerce;
exports.disable = disable;
exports.enable = enable;
exports.enabled = enabled;
exports.humanize = require('ms');

/**
 * The currently active debug mode names, and names to skip.
 */

exports.names = [];
exports.skips = [];

/**
 * Map of special "%n" handling functions, for the debug "format" argument.
 *
 * Valid key names are a single, lowercased letter, i.e. "n".
 */

exports.formatters = {};

/**
 * Previously assigned color.
 */

var prevColor = 0;

/**
 * Previous log timestamp.
 */

var prevTime;

/**
 * Select a color.
 *
 * @return {Number}
 * @api private
 */

function selectColor() {
  return exports.colors[prevColor++ % exports.colors.length];
}

/**
 * Create a debugger with the given `namespace`.
 *
 * @param {String} namespace
 * @return {Function}
 * @api public
 */

function debug(namespace) {

  // define the `disabled` version
  function disabled() {
  }
  disabled.enabled = false;

  // define the `enabled` version
  function enabled() {

    var self = enabled;

    // set `diff` timestamp
    var curr = +new Date();
    var ms = curr - (prevTime || curr);
    self.diff = ms;
    self.prev = prevTime;
    self.curr = curr;
    prevTime = curr;

    // add the `color` if not set
    if (null == self.useColors) self.useColors = exports.useColors();
    if (null == self.color && self.useColors) self.color = selectColor();

    var args = Array.prototype.slice.call(arguments);

    args[0] = exports.coerce(args[0]);

    if ('string' !== typeof args[0]) {
      // anything else let's inspect with %o
      args = ['%o'].concat(args);
    }

    // apply any `formatters` transformations
    var index = 0;
    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {
      // if we encounter an escaped % then don't increase the array index
      if (match === '%%') return match;
      index++;
      var formatter = exports.formatters[format];
      if ('function' === typeof formatter) {
        var val = args[index];
        match = formatter.call(self, val);

        // now we need to remove `args[index]` since it's inlined in the `format`
        args.splice(index, 1);
        index--;
      }
      return match;
    });

    if ('function' === typeof exports.formatArgs) {
      args = exports.formatArgs.apply(self, args);
    }
    var logFn = enabled.log || exports.log || console.log.bind(console);
    logFn.apply(self, args);
  }
  enabled.enabled = true;

  var fn = exports.enabled(namespace) ? enabled : disabled;

  fn.namespace = namespace;

  return fn;
}

/**
 * Enables a debug mode by namespaces. This can include modes
 * separated by a colon and wildcards.
 *
 * @param {String} namespaces
 * @api public
 */

function enable(namespaces) {
  exports.save(namespaces);

  var split = (namespaces || '').split(/[\s,]+/);
  var len = split.length;

  for (var i = 0; i < len; i++) {
    if (!split[i]) continue; // ignore empty strings
    namespaces = split[i].replace(/\*/g, '.*?');
    if (namespaces[0] === '-') {
      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
    } else {
      exports.names.push(new RegExp('^' + namespaces + '$'));
    }
  }
}

/**
 * Disable debug output.
 *
 * @api public
 */

function disable() {
  exports.enable('');
}

/**
 * Returns true if the given mode name is enabled, false otherwise.
 *
 * @param {String} name
 * @return {Boolean}
 * @api public
 */

function enabled(name) {
  var i, len;
  for (i = 0, len = exports.skips.length; i < len; i++) {
    if (exports.skips[i].test(name)) {
      return false;
    }
  }
  for (i = 0, len = exports.names.length; i < len; i++) {
    if (exports.names[i].test(name)) {
      return true;
    }
  }
  return false;
}

/**
 * Coerce `val`.
 *
 * @param {Mixed} val
 * @return {Mixed}
 * @api private
 */

function coerce(val) {
  if (val instanceof Error) return val.stack || val.message;
  return val;
}

},{"ms":2}],2:[function(require,module,exports){
/**
 * Helpers.
 */

var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var y = d * 365.25;

/**
 * Parse or format the given `val`.
 *
 * Options:
 *
 *  - `long` verbose formatting [false]
 *
 * @param {String|Number} val
 * @param {Object} options
 * @return {String|Number}
 * @api public
 */

module.exports = function(val, options){
  options = options || {};
  if ('string' == typeof val) return parse(val);
  return options.long
    ? long(val)
    : short(val);
};

/**
 * Parse the given `str` and return milliseconds.
 *
 * @param {String} str
 * @return {Number}
 * @api private
 */

function parse(str) {
  var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);
  if (!match) return;
  var n = parseFloat(match[1]);
  var type = (match[2] || 'ms').toLowerCase();
  switch (type) {
    case 'years':
    case 'year':
    case 'yrs':
    case 'yr':
    case 'y':
      return n * y;
    case 'days':
    case 'day':
    case 'd':
      return n * d;
    case 'hours':
    case 'hour':
    case 'hrs':
    case 'hr':
    case 'h':
      return n * h;
    case 'minutes':
    case 'minute':
    case 'mins':
    case 'min':
    case 'm':
      return n * m;
    case 'seconds':
    case 'second':
    case 'secs':
    case 'sec':
    case 's':
      return n * s;
    case 'milliseconds':
    case 'millisecond':
    case 'msecs':
    case 'msec':
    case 'ms':
      return n;
  }
}

/**
 * Short format for `ms`.
 *
 * @param {Number} ms
 * @return {String}
 * @api private
 */

function short(ms) {
  if (ms >= d) return Math.round(ms / d) + 'd';
  if (ms >= h) return Math.round(ms / h) + 'h';
  if (ms >= m) return Math.round(ms / m) + 'm';
  if (ms >= s) return Math.round(ms / s) + 's';
  return ms + 'ms';
}

/**
 * Long format for `ms`.
 *
 * @param {Number} ms
 * @return {String}
 * @api private
 */

function long(ms) {
  return plural(ms, d, 'day')
    || plural(ms, h, 'hour')
    || plural(ms, m, 'minute')
    || plural(ms, s, 'second')
    || ms + ' ms';
}

/**
 * Pluralization helper.
 */

function plural(ms, n, name) {
  if (ms < n) return;
  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
  return Math.ceil(ms / n) + ' ' + name + 's';
}

},{}],3:[function(require,module,exports){

/**
 * This is the web browser implementation of `debug()`.
 *
 * Expose `debug()` as the module.
 */

exports = module.exports = require('./debug');
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;

/**
 * Use chrome.storage.local if we are in an app
 */

var storage;

if (typeof chrome !== 'undefined' && typeof chrome.storage !== 'undefined')
  storage = chrome.storage.local;
else
  storage = localstorage();

/**
 * Colors.
 */

exports.colors = [
  'lightseagreen',
  'forestgreen',
  'goldenrod',
  'dodgerblue',
  'darkorchid',
  'crimson'
];

/**
 * Currently only WebKit-based Web Inspectors, Firefox >= v31,
 * and the Firebug extension (any Firefox version) are known
 * to support "%c" CSS customizations.
 *
 * TODO: add a `localStorage` variable to explicitly enable/disable colors
 */

function useColors() {
  // is webkit? http://stackoverflow.com/a/16459606/376773
  return ('WebkitAppearance' in document.documentElement.style) ||
    // is firebug? http://stackoverflow.com/a/398120/376773
    (window.console && (console.firebug || (console.exception && console.table))) ||
    // is firefox >= v31?
    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
    (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31);
}

/**
 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
 */

exports.formatters.j = function(v) {
  return JSON.stringify(v);
};

/**
 * Colorize log arguments if enabled.
 *
 * @api public
 */

function formatArgs() {
  var args = arguments;
  var useColors = this.useColors;

  args[0] = (useColors ? '%c' : '')
    + this.namespace
    + (useColors ? ' %c' : ' ')
    + args[0]
    + (useColors ? '%c ' : ' ')
    + '+' + exports.humanize(this.diff);

  if (!useColors) return args;

  var c = 'color: ' + this.color;
  args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));

  // the final "%c" is somewhat tricky, because there could be other
  // arguments passed either before or after the %c, so we need to
  // figure out the correct index to insert the CSS into
  var index = 0;
  var lastC = 0;
  args[0].replace(/%[a-z%]/g, function(match) {
    if ('%%' === match) return;
    index++;
    if ('%c' === match) {
      // we only are interested in the *last* %c
      // (the user may have provided their own)
      lastC = index;
    }
  });

  args.splice(lastC, 0, c);
  return args;
}

/**
 * Invokes `console.log()` when available.
 * No-op when `console.log` is not a "function".
 *
 * @api public
 */

function log() {
  // this hackery is required for IE8/9, where
  // the `console.log` function doesn't have 'apply'
  return 'object' === typeof console
    && console.log
    && Function.prototype.apply.call(console.log, console, arguments);
}

/**
 * Save `namespaces`.
 *
 * @param {String} namespaces
 * @api private
 */

function save(namespaces) {
  try {
    if (null == namespaces) {
      storage.removeItem('debug');
    } else {
      storage.debug = namespaces;
    }
  } catch(e) {}
}

/**
 * Load `namespaces`.
 *
 * @return {String} returns the previously persisted debug modes
 * @api private
 */

function load() {
  var r;
  try {
    r = storage.debug;
  } catch(e) {}
  return r;
}

/**
 * Enable namespaces listed in `localStorage.debug` initially.
 */

exports.enable(load());

/**
 * Localstorage attempts to return the localstorage.
 *
 * This is necessary because safari throws
 * when a user disables cookies/localstorage
 * and you attempt to access it.
 *
 * @return {LocalStorage}
 * @api private
 */

function localstorage(){
  try {
    return window.localStorage;
  } catch (e) {}
}

},{"./debug":1}]},{},[3])(3)
});<|endoftext|>


<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict
 * @format
 */

'use strict';

const Profiler = require('./GraphQLCompilerProfiler');

const invariant = require('invariant');

const {createUserError} = require('./RelayCompilerError');
// $FlowFixMe - immutable.js is not flow-typed
const {OrderedMap: ImmutableOrderedMap} = require('immutable');

import type {Reporter} from '../reporters/Reporter';
import type {Fragment, Location, Root, SplitOperation} from './GraphQLIR';
import type {Schema} from './Schema';

export type IRTransform = GraphQLCompilerContext => GraphQLCompilerContext;

export type CompilerContextDocument = Fragment | Root | SplitOperation;

/**
 * An immutable representation of a corpus of documents being compiled together.
 * For each document, the context stores the IR and any validation errors.
 */
class GraphQLCompilerContext {
  _isMutable: boolean;
  _documents: ImmutableOrderedMap<string, CompilerContextDocument>;
  _withTransform: WeakMap<IRTransform, GraphQLCompilerContext>;
  +_schema: Schema;

  constructor(schema: Schema) {
    this._isMutable = false;
    this._documents = new ImmutableOrderedMap();
    this._withTransform = new WeakMap();
    this._schema = schema;
  }

  /**
   * Returns the documents for the context in the order they were added.
   */
  documents(): Array<CompilerContextDocument> {
    return this._documents.toArray();
  }

  forEachDocument(fn: CompilerContextDocument => void): void {
    this._documents.forEach(fn);
  }

  replace(node: CompilerContextDocument): GraphQLCompilerContext {
    return this._update(
      this._documents.update(node.name, existing => {
        invariant(
          existing,
          'GraphQLCompilerContext: Expected to replace existing node %s, but' +
            'one was not found in the context.',
          node.name,
        );
        return node;
      }),
    );
  }

  add(node: CompilerContextDocument): GraphQLCompilerContext {
    return this._update(
      this._documents.update(node.name, existing => {
        invariant(
          !existing,
          'GraphQLCompilerContext: Duplicate document named `%s`. GraphQL ' +
            'fragments and roots must have unique names.',
          node.name,
        );
        return node;
      }),
    );
  }

  addAll(
    nodes: $ReadOnlyArray<CompilerContextDocument>,
  ): GraphQLCompilerContext {
    return this.withMutations(mutable =>
      nodes.reduce((ctx, definition) => ctx.add(definition), mutable),
    );
  }

  /**
   * Apply a list of compiler transforms and return a new compiler context.
   */
  applyTransforms(
    transforms: $ReadOnlyArray<IRTransform>,
    reporter?: Reporter,
  ): GraphQLCompilerContext {
    return Profiler.run('applyTransforms', () =>
      transforms.reduce(
        (ctx, transform) => ctx.applyTransform(transform, reporter),
        this,
      ),
    );
  }

  /**
   * Applies a transform to this context, returning a new context.
   *
   * This is memoized such that applying the same sequence of transforms will
   * not result in duplicated work.
   */
  applyTransform(
    transform: IRTransform,
    reporter?: Reporter,
  ): GraphQLCompilerContext {
    let transformed = this._withTransform.get(transform);
    if (!transformed) {
      const start = process.hrtime();
      transformed = Profiler.instrument(transform)(this);
      const delta = process.hrtime(start);
      const deltaMs = Math.round((delta[0] * 1e9 + delta[1]) / 1e6);
      reporter && reporter.reportTime(transform.name, deltaMs);
      this._withTransform.set(transform, transformed);
    }
    return transformed;
  }

  get(name: string): ?CompilerContextDocument {
    return this._documents.get(name);
  }

  getFragment(name: string, referencedFrom?: ?Location): Fragment {
    const node = this._documents.get(name);
    if (node == null) {
      throw createUserError(
        `Cannot find fragment '${name}'.`,
        referencedFrom != null ? [referencedFrom] : null,
      );
    } else if (node.kind !== 'Fragment') {
      throw createUserError(
        `Cannot find fragment '${name}', a document with this name exists ` +
          'but is not a fragment.',
        [node.loc, referencedFrom].filter(Boolean),
      );
    }
    return node;
  }

  getRoot(name: string): Root {
    const node = this._documents.get(name);
    if (node == null) {
      throw createUserError(`Cannot find root '${name}'.`);
    } else if (node.kind !== 'Root') {
      throw createUserError(
        `Cannot find root '${name}', a document with this name exists but ` +
          'is not a root.',
        [node.loc],
      );
    }
    return node;
  }

  remove(name: string): GraphQLCompilerContext {
    return this._update(this._documents.delete(name));
  }

  withMutations(
    fn: GraphQLCompilerContext => GraphQLCompilerContext,
  ): GraphQLCompilerContext {
    const mutableCopy = this._update(this._documents.asMutable());
    mutableCopy._isMutable = true;
    const result = fn(mutableCopy);
    result._isMutable = false;
    result._documents = result._documents.asImmutable();
    return this._documents === result._documents ? this : result;
  }

  _update(
    documents: ImmutableOrderedMap<string, CompilerContextDocument>,
  ): GraphQLCompilerContext {
    const context = this._isMutable
      ? this
      : new GraphQLCompilerContext(this.getSchema());
    context._documents = documents;
    return context;
  }

  getSchema(): Schema {
    return this._schema;
  }
}

module.exports = GraphQLCompilerContext;
<commit_msg>fix missing space in invariant<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict
 * @format
 */

'use strict';

const Profiler = require('./GraphQLCompilerProfiler');

const invariant = require('invariant');

const {createUserError} = require('./RelayCompilerError');
// $FlowFixMe - immutable.js is not flow-typed
const {OrderedMap: ImmutableOrderedMap} = require('immutable');

import type {Reporter} from '../reporters/Reporter';
import type {Fragment, Location, Root, SplitOperation} from './GraphQLIR';
import type {Schema} from './Schema';

export type IRTransform = GraphQLCompilerContext => GraphQLCompilerContext;

export type CompilerContextDocument = Fragment | Root | SplitOperation;

/**
 * An immutable representation of a corpus of documents being compiled together.
 * For each document, the context stores the IR and any validation errors.
 */
class GraphQLCompilerContext {
  _isMutable: boolean;
  _documents: ImmutableOrderedMap<string, CompilerContextDocument>;
  _withTransform: WeakMap<IRTransform, GraphQLCompilerContext>;
  +_schema: Schema;

  constructor(schema: Schema) {
    this._isMutable = false;
    this._documents = new ImmutableOrderedMap();
    this._withTransform = new WeakMap();
    this._schema = schema;
  }

  /**
   * Returns the documents for the context in the order they were added.
   */
  documents(): Array<CompilerContextDocument> {
    return this._documents.toArray();
  }

  forEachDocument(fn: CompilerContextDocument => void): void {
    this._documents.forEach(fn);
  }

  replace(node: CompilerContextDocument): GraphQLCompilerContext {
    return this._update(
      this._documents.update(node.name, existing => {
        invariant(
          existing,
          'GraphQLCompilerContext: Expected to replace existing node %s, but ' +
            'one was not found in the context.',
          node.name,
        );
        return node;
      }),
    );
  }

  add(node: CompilerContextDocument): GraphQLCompilerContext {
    return this._update(
      this._documents.update(node.name, existing => {
        invariant(
          !existing,
          'GraphQLCompilerContext: Duplicate document named `%s`. GraphQL ' +
            'fragments and roots must have unique names.',
          node.name,
        );
        return node;
      }),
    );
  }

  addAll(
    nodes: $ReadOnlyArray<CompilerContextDocument>,
  ): GraphQLCompilerContext {
    return this.withMutations(mutable =>
      nodes.reduce((ctx, definition) => ctx.add(definition), mutable),
    );
  }

  /**
   * Apply a list of compiler transforms and return a new compiler context.
   */
  applyTransforms(
    transforms: $ReadOnlyArray<IRTransform>,
    reporter?: Reporter,
  ): GraphQLCompilerContext {
    return Profiler.run('applyTransforms', () =>
      transforms.reduce(
        (ctx, transform) => ctx.applyTransform(transform, reporter),
        this,
      ),
    );
  }

  /**
   * Applies a transform to this context, returning a new context.
   *
   * This is memoized such that applying the same sequence of transforms will
   * not result in duplicated work.
   */
  applyTransform(
    transform: IRTransform,
    reporter?: Reporter,
  ): GraphQLCompilerContext {
    let transformed = this._withTransform.get(transform);
    if (!transformed) {
      const start = process.hrtime();
      transformed = Profiler.instrument(transform)(this);
      const delta = process.hrtime(start);
      const deltaMs = Math.round((delta[0] * 1e9 + delta[1]) / 1e6);
      reporter && reporter.reportTime(transform.name, deltaMs);
      this._withTransform.set(transform, transformed);
    }
    return transformed;
  }

  get(name: string): ?CompilerContextDocument {
    return this._documents.get(name);
  }

  getFragment(name: string, referencedFrom?: ?Location): Fragment {
    const node = this._documents.get(name);
    if (node == null) {
      throw createUserError(
        `Cannot find fragment '${name}'.`,
        referencedFrom != null ? [referencedFrom] : null,
      );
    } else if (node.kind !== 'Fragment') {
      throw createUserError(
        `Cannot find fragment '${name}', a document with this name exists ` +
          'but is not a fragment.',
        [node.loc, referencedFrom].filter(Boolean),
      );
    }
    return node;
  }

  getRoot(name: string): Root {
    const node = this._documents.get(name);
    if (node == null) {
      throw createUserError(`Cannot find root '${name}'.`);
    } else if (node.kind !== 'Root') {
      throw createUserError(
        `Cannot find root '${name}', a document with this name exists but ` +
          'is not a root.',
        [node.loc],
      );
    }
    return node;
  }

  remove(name: string): GraphQLCompilerContext {
    return this._update(this._documents.delete(name));
  }

  withMutations(
    fn: GraphQLCompilerContext => GraphQLCompilerContext,
  ): GraphQLCompilerContext {
    const mutableCopy = this._update(this._documents.asMutable());
    mutableCopy._isMutable = true;
    const result = fn(mutableCopy);
    result._isMutable = false;
    result._documents = result._documents.asImmutable();
    return this._documents === result._documents ? this : result;
  }

  _update(
    documents: ImmutableOrderedMap<string, CompilerContextDocument>,
  ): GraphQLCompilerContext {
    const context = this._isMutable
      ? this
      : new GraphQLCompilerContext(this.getSchema());
    context._documents = documents;
    return context;
  }

  getSchema(): Schema {
    return this._schema;
  }
}

module.exports = GraphQLCompilerContext;
<|endoftext|>


<commit_before>w2utils.locale('bower_components/w2ui/locale/es-mx.json');
// # /ofertas/mias
// # /overtas/inbox
// # /ofertas/mercado

// # /pedidos/mios
// # /pedidos/inbox
// # /pedidos/mercado

var unidades = ['kg', 'bolsa', 'ramo', 'litro', 'domo', 'manojo', 'pieza'];

////////////////
// top layout //
////////////////
var layout = { name: 'layout',
               padding: 0,
               panels: [
                 { type: 'left', size: 200, resizable: true, minSize: 120 },
                 { type: 'main', minSize: 550, overflow: 'hidden' }
               ]
             };

/////////////////////////////////
// menu general a la izquierda //
/////////////////////////////////
var sidebar = { name: 'sidebar',
                nodes: [
                  { id: 'ofertas', text: 'Ofertas', group: true, expanded: true, nodes: [
                    { id: 'o_mias', text: 'Mías', img: ' w2ui-icon-columns', selected: true },
                    { id: 'o_inbox', text: 'Inbox', img: 'icon-folder' },
                    { id: 'o_mercado', text: 'En el mercado', img: 'icon-page' }
                  ]},
                  { id: 'pedidos', text: 'Pedidos', group: true, expanded: true, nodes: [
                    { id: 'p_mias', text: 'Mis pedidos', img: 'w2ui-icon-columns' },
                    { id: 'p_inbox', text: 'Inbox', img: 'icon-folder' },
                    { id: 'p_mercado', text: 'En el mercado', img: 'icon-page' }
                  ]}

                ],
                onClick: function (event) {
                  switch (event.target) {
                    case 'o_mias':
                    w2ui.layout.content('main', w2ui.o_mias);
                    break;
                    case 'o_inbox':
                    $().w2grid(o_inbox);
                    w2ui.layout.content('main', w2ui.o_inbox);
                    break;
                    case 'o_mercado':
                    //w2ui.layout.content('main', "la patita se ha enojado ya sabes por qué");
                    $().w2grid(config.o_inbox);
                    w2ui.layout.content('main', w2ui.o_inbox);
                    break;

                    case 'p_mias':
                    w2ui.layout.content('main', w2ui.grid1);
                    break;
                    case 'p_inbox':
                    $().w2grid(config.o_inbox);
                    w2ui.layout.content('main', w2ui.o_inbox);
                    break;
                    case 'p_mercado':
                    //w2ui.layout.content('main', "la patita se ha enojado ya sabes por qué");
                    $().w2grid(config.o_inbox);
                    w2ui.layout.content('main', w2ui.o_inbox);
                  }
                }
              };

////////////////////////////////////////////
// grid con mis ofertas
////////////////////////////////////////////
var o_mias = {
  name: 'o_mias',
  url: '/ofertas/mias',

  show: {
    toolbar : true,
    toolbarDelete: true,
    toolbarSave: false,
    toolbarEdit: true
  },

  toolbar: {
    items: [
      { id: 'add', type: 'button', caption: 'Nueva oferta', icon: 'w2ui-icon-plus' },
      { type: 'break',  id: 'break0' },
      { id: 'save', type: 'button', caption: 'Guardar', icon: 'w2ui-icon-check' }
    ],
    onClick: function (event) {
      if (event.target == 'add') {
        console.log('dafuq');
        var newid = w2ui.o_mias.records.length + 1;
        w2ui.o_mias.add({ recid: newid });
        w2ui.o_mias.select( newid );
      }
      if (event.target == 'save') {
        //console.log(w2ui.o_mias.records);
        w2ui.o_mias.mergeChanges();
        $.ajax({
          type: "POST",
          url: "/ofertas/save",
          data: JSON.stringify( w2ui.o_mias.records ),
          contentType: "application/json; charset=utf-8",
          dataType: "json",
          error: function(errMsg) {
            console.log(errMsg);
            w2ui.o_mias.error("AJAX error" + errMsg.responseText);
          }
        });
      }
    }
  }, // toolbar

  columns: [
    { field: 'titulo', caption: 'Título', size: '180px', editable: { type: 'text' } },
    { field: 'desc', caption: 'Descripción', size: '180px', editable: { type: 'text' } },
    { field: 'vigencia', caption: 'Vigencia', size: '120px', sortable: true, editable: { type: 'date' }},
    { field: 'publicado', caption: 'Publicado', size: '100px', sortable: true, resizable: true, editable: { type: 'checkbox' }
    }
  ],

  searches: [
    { type: 'date', field: 'vigencia', caption: 'Vigencia' }
  ],

  // abre lista de items
  onEdit: function(event) {
    $().w2grid(o_itemgrid(event.recid));
    openOfertaItemPopup(event.recid);
  }

}; // o_mias

var o_inbox = {
  name: 'o_inbox',
  show: {
    toolbar : true
  },
  searches: [
    { type: 'date', field: 'vigencia', caption: 'Vigencia' }
  ],
  url: '/ofertas/inbox',
  columns: [
    { field: 'usuario', caption: 'Usuario', size: '180px' },
    { field: 'titulo', caption: 'Título', size: '180px' },
    { field: 'desc', caption: 'Descripción', size: '180px' },
    { field: 'vigencia', caption: 'Vigencia', size: '120px', sortable: true },
    { field: 'lugar', caption: 'Lugar', size: '180px'}
  ],

  onClick: function (event) {
    $().w2grid(p_itemgrid(event.recid));
    openPedidoItemPopup(event.recid);
  },

  records: [
    { recid: 1, usuario: "la granja", titulo: 'puesto', desc: 'Tianguis el 100', email: 'jdoe@gmail.com', vigencia: '4/3/2012', lugar: 'mercado100' },
    { recid: 2, usuario: "la nicolasa", titulo: 'A domicilio', desc: 'fruta y verdura otoñal', email: 'jdoe@gmail.com', vigencia: '4/3/2012', lugar: 'indefinido' }
  ]
};

function o_itemgrid(recid) {
    return {
        name: 'o_itemgrid',
        show: {
            toolbar: true,
            toolbarDelete: true,
            toolbarSave: true
        },
//        url: '/'+recid,

        toolbar: {
            items: [
                { id: 'add', type: 'button', caption: 'Otro item', icon: 'w2ui-icon-plus' }
            ],
            onClick: function (event) {
                if (event.target == 'add') {
                    w2ui.o_itemgrid.add({ recid: w2ui.o_itemgrid.records.length + 1 });
                }
            }
        },

        columns: [
            { field: 'text', caption: 'nombre', size: '120px', sortable: true, resizable: true,
              editable: { type: 'text' }
            },
            { field: 'desc', caption: 'descripción', size: '50%', sortable: true, resizable: true,
              editable: { type: 'text' }
            },
            { field: 'presentacion', caption: 'presentación', size: '100px', sortable: true, resizable: true,
              editable: { type: 'combo', items: unidades, openOnFocus: true }
            },
            { field: 'precio', caption: 'precio', size: '80px', sortable: true, resizable: true, render: 'money',
              editable: { type: 'money' }
            },
        ],
        records: [
        ]
    }
}

function p_itemgrid(recid) {
    return {
        name: 'p_itemgrid',
        show: {
            toolbar: true,
            toolbarDelete: true,
            toolbarSave: true
        },
//        url: '/'+recid,

        columns: [
            { field: 'nombre', caption: 'nombre', size: '120px', sortable: true, resizable: true },
            { field: 'desc', caption: 'descripción', size: '50%', sortable: true, resizable: true },
            { field: 'presentacion', caption: 'presentación', size: '100px', sortable: true, resizable: true },
            { field: 'precio', caption: 'precio', size: '80px', resizable: true, render: 'money' },
            { field: 'cantidad', caption: 'cantidad', size: '80px', resizable: true, render: 'float:3',
              editable: { type: 'float' } }
        ],
        records: [
            { recid: 1, nombre: "jitomate", desc: 'hidroponico', presentacion: 'kg', cantidad: 2.2 }
        ]
    }
}

function openOfertaItemPopup(recid) {
    w2popup.open({
        title   : 'items en la oferta '+recid,
        width   : 900,
        height  : 600,
        body    : '

',
        onOpen  : function (event) {
            event.onComplete = function () {
                $('#w2ui-popup #poplayout').w2render('o_itemgrid');
            };
        },
        onToggle: function (event) {
            event.onComplete = function () {
                w2ui.layout.resize();
            }
        }
    });
}

function openPedidoItemPopup(recid) {
    w2popup.open({
        title   : 'ordena contra '+recid,
        width   : 600,
        height  : 600,
        body    : '

',
        onOpen  : function (event) {
            event.onComplete = function () {
                $('#w2ui-popup #poplayout').w2render('p_itemgrid');
            };
        },
        onToggle: function (event) {
            event.onComplete = function () {
                w2ui.layout.resize();
            }
        }
    });
}

// initialization
$(function () {
    $('#main').w2layout(layout);
    w2ui.layout.content('left', $().w2sidebar(sidebar));
    w2ui.layout.content('main', $().w2grid(o_mias));
    w2ui.o_mias.autoLoad = false;
    w2ui.o_mias.skip(0);
});
<commit_msg>mudado a js<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.views.calendar["Attendance"] = {
	field_map: {
		"start": "date",
		"end": "date",
		"id": "name",
		"docstatus": 1
	},
	options: {
		header: {
			left: 'prev,next today',
			center: 'title',
			right: 'month'
		}
	},
	get_events_method: "erpnext.hr.doctype.attendance.attendance.get_events"
};<commit_msg>fix: attendance gantt fix<commit_after>// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.views.calendar["Attendance"] = {
	field_map: {
		"start": "attendance_date",
		"end": "attendance_date",
		"id": "name",
		"docstatus": 1
	},
	options: {
		header: {
			left: 'prev,next today',
			center: 'title',
			right: 'month'
		}
	},
	get_events_method: "erpnext.hr.doctype.attendance.attendance.get_events"
};<|endoftext|>


<commit_before>var animationTime = 1;
var bst;
var treeGUI;
var loadingSequence;
var codeDisplayManager;
var markerInitialPosition;

function makeGUIUnEditable() {
    d3.select("#g_circles").selectAll('circle').on('click', null);
    d3.select("#g_labels").selectAll('text').on('click', null);
}

function findNodeInTreeEditor(binaryNode) {
    for (var i = 0; i < treeGUI.vis.length; i++) {
        if (treeGUI.vis[i].l === binaryNode.element) return treeGUI.vis[i];
    }
}

function createMarker(x, y) {
    markerInitialPosition = treeGUI.vis[0].p;
    /*if (x !== undefined && y !== undefined)
        markerInitialPosition = {x: x, y: y};*/
    d3.select("#treesvg").append('g').attr('class', 'markers').append('circle').attr('id', 'marker')
        .attr('cx', markerInitialPosition.x).attr('cy', markerInitialPosition.y).attr('r', 14)/*.attr('opacity', 0)*/;
}

function moveMarker(cx, cy) {
    return [{ e: $("#marker"), p: { x: cx - markerInitialPosition.x, y: cy - markerInitialPosition.y, opacity: 1 },
        o: { duration: animationTime} }];
}

function removeMarker() {$("#marker").remove()}

function getVertixMarkAnimation(n) {
    var point = findNodeInTreeEditor(n).p;
    return moveMarker(point.x, point.y);
}

function init(rootLbl) {
    if (rootLbl == null) return;
    codeDisplayManager = new CodeDisplayManager("javascript", "binarySearchTree");
    bst = new BinarySearchTree();
    bst.insert(rootLbl);
    treeGUI = new tree(rootLbl);

    makeGUIUnEditable();
}

function visualizeInsert(lbl) {
    function insert(x, t) {
        var hasBeenInIf = false;
        if (t !== null) {
            appendAnimation(null, getVertixMarkAnimation(t), codeDisplayManager);
        }
        else {
            var p = treeGUI.getFutureLeafPositionHelper(findNodeInTreeEditor(parent).v, direction);
            var tmp = moveMarker(p.x, p.y);
            appendAnimation(null, tmp, codeDisplayManager);
        }
        appendCodeLines([0], codeDisplayManager);

        if (t === null && !hasBeenInIf) {
            hasBeenInIf = true;
            t = new BinaryNode(x);

            // Following line of animation does nothing in particular.
            // It is a dummy animation in order to access and utilize onComplete and onReverseComplete
            var tmp = [{e: $("#marker"), p: {attr:{stroke: "red"}}, o:{duration: animationTime}}];

            tmp[0].p.onComplete = function() {
                var parentInGUI = findNodeInTreeEditor(parent);
                treeGUI.addLeaf(parentInGUI.v, direction, lbl);
                //$("#marker").animate()
            };
            tmp[0].p.onReverseComplete = function() {
                var parentInGUI = findNodeInTreeEditor(parent);
                for(var i = 0; i < parentInGUI.c.length; i++) {
                    if(parentInGUI.c[i].d === direction) {
                        treeGUI.removeLeaf(parentInGUI.c[i].v);
                    }
                }
                t = null;
            };

            appendAnimation(1, tmp, codeDisplayManager);
            appendCodeLines([2, 4, 6], codeDisplayManager);
        }

        else if (x - t.getElement() < 0 && !hasBeenInIf) {
            hasBeenInIf = true, direction = "left", parent = t;
            appendCodeLines([2, 3], codeDisplayManager);
            t.setLeft(insert(x, t.getLeft()));
            appendCodeLines([4, 6], codeDisplayManager);
        }

        else if (x - t.getElement() > 0 && !hasBeenInIf) {
            hasBeenInIf = true, direction = "right", parent = t;
            appendCodeLines([2, 4, 5], codeDisplayManager);
            t.setRight(insert(x, t.getRight()));
            appendCodeLines([6], codeDisplayManager);
        }

        else if(!hasBeenInIf) {
            hasBeenInIf = true;
            //throw { name: "DuplicateItemException", message: "Duplicate items are not allowed" };
            var animation = [{ e: $("#graphics, .treeEditor svg"), p: {"background-color": "#ff0000", opacity: 0.5}, o: { duration: animationTime/2} }];
            animation.push({ e: $("#graphics, .treeEditor svg"), p: {"background-color": "#fcfcfc", opacity: 1}, o: { duration: animationTime/2} });
            appendAnimation(7, animation, codeDisplayManager);
            return t;
        }
        appendCodeLines([8], codeDisplayManager);
        return t;
    }

    removeMarker();
    createMarker();
    codeDisplayManager.loadFunctions("insertNode");
    codeDisplayManager.changeFunction("insertNode");
    var parent = bst.root, direction = null;
    insert(lbl, bst.root);
    makeGUIUnEditable();
}

function visualizeSearch(lbl) {
    removeMarker();
    codeDisplayManager.loadFunctions("findNode");
    codeDisplayManager.changeFunction("findNode");
    var t = bst.root;
    createMarker();
    while (t !== null) {
        var hasBeenInIf = false;
        appendCodeLines([0], codeDisplayManager);
        appendCodeLines([1], codeDisplayManager);
        if (lbl - t.getElement() < 0) {
            t = t.getLeft();
            if (t !== null) {
                appendAnimation(2, getVertixMarkAnimation(t), codeDisplayManager);
            }
            appendCodeLines([3, 5, 7], codeDisplayManager);
            hasBeenInIf = true;
        }
        else if (lbl - t.getElement() > 0 && !hasBeenInIf) {
            appendCodeLines([3], codeDisplayManager);
            t = t.getRight();
            if (t !== null) {
                appendAnimation(4, getVertixMarkAnimation(t), codeDisplayManager);
            }
            appendCodeLines([5, 7], codeDisplayManager);
            hasBeenInIf = true;
        }
        else if(!hasBeenInIf) {
            appendCodeLines([3, 5], codeDisplayManager);
            var animation = [{ e: $("#marker"), p: {stroke: "#00cd00", "stroke-width": 5}, o: { duration: animationTime} }];
            appendAnimation(6, animation, codeDisplayManager);
            return t; // Match
        }
    }

    var animation = [{ e: $("#graphics, .treeEditor svg"), p: {"background-color": "#ff0000", opacity: 0.5}, o: { duration: animationTime/2} }];
    animation.push({ e: $("#graphics, .treeEditor svg"), p: {"background-color": "#fcfcfc", opacity: 1}, o: { duration: animationTime/2} });
    appendAnimation(9, animation, codeDisplayManager);
    makeGUIUnEditable();
    return null; // Not Found
}

function visualizeRemove(lbl) {
    function remove(x, t) {
        hasBeenInIf = false;
        if (t === null) {
            hasBeenInIf = true;
            appendCodeLines([0], codeDisplayManager);
            var animation = [{ e: $("#graphics, .treeEditor svg"), p: {"background-color": "#ff0000", opacity: 0.5}, o: { duration: animationTime/2} }];
            animation.push({ e: $("#graphics, .treeEditor svg"), p: {"background-color": "#fcfcfc", opacity: 1}, o: { duration: animationTime/2} });
            appendAnimation(1, animation, codeDisplayManager);
            makeGUIUnEditable();
            return null;
        } else {
            appendAnimation(null, getVertixMarkAnimation(t), codeDisplayManager);
        }

        appendCodeLines([2], codeDisplayManager);
        if (x - t.getElement() < 0) {
            hasBeenInIf = true, parent = t, direction = 'left';
            appendCodeLines([3], codeDisplayManager);
            t.setLeft(remove(x, t.getLeft()));
            appendCodeLines([4, 6, 9], codeDisplayManager);
        }
        else if (x - t.getElement() > 0) {
            hasBeenInIf = true, parent = t, direction = 'right';
            appendCodeLines([4, 5], codeDisplayManager);
            t.setRight(remove(x, t.getRight()));
            appendCodeLines([6, 9], codeDisplayManager);

        }
        else if (t.getLeft() !== null && t.getRight() !== null) { // Two children
            hasBeenInIf = true;
            appendCodeLines([6, 7, 8], codeDisplayManager);
            t.setElement(bst.findMinNode(t.getRight()).getElement()); // Bytter verdiene på elementene
            t.setRight(bst.removeMinNode(t.getRight())); // Fjerner noden den har bytta med, og setter
            appendCodeLines([9], codeDisplayManager);
        }
        else {
            appendCodeLines([10, 11], codeDisplayManager);
            hasBeenInIf = true;
            if (t.getLeft() !== null) {
                parent = t, direction = 'left';
                t = t.getLeft();
            }
            else {
                parent = t, direction = 'right';
                t = t.getRight();
            }
        }
        appendCodeLines([12], codeDisplayManager);
        return t;
    }
    removeMarker();
    createMarker();
    codeDisplayManager.loadFunctions("removeNode");
    codeDisplayManager.changeFunction("removeNode");
    var parent = bst.root, direction = null, hasBeenInIf = false;
    remove(lbl, bst.root);
    makeGUIUnEditable();
}

init(50);
/*
setTimeout(function(){
    visualizeInsert(90);
    setTimeout(function() {
        visualizeInsert(30);
    }, 3000)
}, 3000);
*/
<commit_msg>added reverse marker<commit_after>var animationTime = 1;
var bst;
var treeGUI;
var loadingSequence;
var codeDisplayManager;
var markerInitialPosition;

function makeGUIUnEditable() {
    d3.select("#g_circles").selectAll('circle').on('click', null);
    d3.select("#g_labels").selectAll('text').on('click', null);
}

function findNodeInTreeEditor(binaryNode) {
    for (var i = 0; i < treeGUI.vis.length; i++) {
        if (treeGUI.vis[i].l === binaryNode.element) return treeGUI.vis[i];
    }
}

function createMarker(x, y) {
    markerInitialPosition = treeGUI.vis[0].p;
    /*if (x !== undefined && y !== undefined)
        markerInitialPosition = {x: x, y: y};*/
    d3.select("#treesvg").append('g').attr('class', 'markers').append('circle').attr('id', 'marker')
        .attr('cx', markerInitialPosition.x).attr('cy', markerInitialPosition.y).attr('r', 14)/*.attr('opacity', 0)*/;
}

function moveMarker(cx, cy) {
    return [{ e: $("#marker"), p: { x: cx - markerInitialPosition.x, y: cy - markerInitialPosition.y, opacity: 1 },
        o: { duration: animationTime} }];
}

function removeMarker() {$("#marker").remove()}

function getVertixMarkAnimation(n) {
    var point = findNodeInTreeEditor(n).p;
    return moveMarker(point.x, point.y);
}

function init(rootLbl) {
    if (rootLbl == null) return;
    codeDisplayManager = new CodeDisplayManager("javascript", "binarySearchTree");
    bst = new BinarySearchTree();
    bst.insert(rootLbl);
    treeGUI = new tree(rootLbl);

    makeGUIUnEditable();
}

function visualizeInsert(lbl) {
    function insert(x, t) {
        var hasBeenInIf = false;
        if (t !== null) {
            appendAnimation(null, getVertixMarkAnimation(t), codeDisplayManager);
        }
        else {
            var p = treeGUI.getFutureLeafPositionHelper(findNodeInTreeEditor(parent).v, direction);
            var tmp = moveMarker(p.x, p.y);
            appendAnimation(null, tmp, codeDisplayManager);
        }
        appendCodeLines([0], codeDisplayManager);

        if (t === null && !hasBeenInIf) {
            hasBeenInIf = true;
            t = new BinaryNode(x);

            // Following line of animation does nothing in particular.
            // It is a dummy animation in order to access and utilize onComplete and onReverseComplete
            var tmp = [{e: $("#marker"), p: {attr:{stroke: "red"}}, o:{duration: animationTime}}];

            tmp[0].p.onComplete = function() {
                var parentInGUI = findNodeInTreeEditor(parent);
                treeGUI.addLeaf(parentInGUI.v, direction, lbl);
                //$("#marker").animate()
            };
            tmp[0].p.onReverseComplete = function() {
                var parentInGUI = findNodeInTreeEditor(parent);
                for(var i = 0; i < parentInGUI.c.length; i++) {
                    if(parentInGUI.c[i].d === direction) {
                        treeGUI.removeLeaf(parentInGUI.c[i].v);
                    }
                }
                t = null;
            };

            appendAnimation(1, tmp, codeDisplayManager);
            appendCodeLines([2, 4, 6], codeDisplayManager);
        }

        else if (x - t.getElement() < 0 && !hasBeenInIf) {
            hasBeenInIf = true, direction = "left", parent = t;
            appendCodeLines([2, 3], codeDisplayManager);
            t.setLeft(insert(x, t.getLeft()));
            appendAnimation(null, getVertixMarkAnimation(t), codeDisplayManager);
            appendCodeLines([4, 6], codeDisplayManager);
        }

        else if (x - t.getElement() > 0 && !hasBeenInIf) {
            hasBeenInIf = true, direction = "right", parent = t;
            appendCodeLines([2, 4, 5], codeDisplayManager);
            t.setRight(insert(x, t.getRight()));
            appendAnimation(null, getVertixMarkAnimation(t), codeDisplayManager);
            appendCodeLines([6], codeDisplayManager);
        }

        else if(!hasBeenInIf) {
            hasBeenInIf = true;
            //throw { name: "DuplicateItemException", message: "Duplicate items are not allowed" };
            var animation = [{ e: $("#graphics, .treeEditor svg"), p: {"background-color": "#ff0000", opacity: 0.5}, o: { duration: animationTime/2} }];
            animation.push({ e: $("#graphics, .treeEditor svg"), p: {"background-color": "#fcfcfc", opacity: 1}, o: { duration: animationTime/2} });
            appendAnimation(7, animation, codeDisplayManager);
            return t;
        }
        appendCodeLines([8], codeDisplayManager);
        return t;
    }

    removeMarker();
    createMarker();
    codeDisplayManager.loadFunctions("insertNode");
    codeDisplayManager.changeFunction("insertNode");
    var parent = bst.root, direction = null;
    insert(lbl, bst.root);
    makeGUIUnEditable();
}

function visualizeSearch(lbl) {
    removeMarker();
    codeDisplayManager.loadFunctions("findNode");
    codeDisplayManager.changeFunction("findNode");
    var t = bst.root;
    createMarker();
    while (t !== null) {
        var hasBeenInIf = false;
        appendCodeLines([0], codeDisplayManager);
        appendCodeLines([1], codeDisplayManager);
        if (lbl - t.getElement() < 0) {
            t = t.getLeft();
            if (t !== null) {
                appendAnimation(2, getVertixMarkAnimation(t), codeDisplayManager);
            }
            appendCodeLines([3, 5, 7], codeDisplayManager);
            hasBeenInIf = true;
        }
        else if (lbl - t.getElement() > 0 && !hasBeenInIf) {
            appendCodeLines([3], codeDisplayManager);
            t = t.getRight();
            if (t !== null) {
                appendAnimation(4, getVertixMarkAnimation(t), codeDisplayManager);
            }
            appendCodeLines([5, 7], codeDisplayManager);
            hasBeenInIf = true;
        }
        else if(!hasBeenInIf) {
            appendCodeLines([3, 5], codeDisplayManager);
            var animation = [{ e: $("#marker"), p: {stroke: "#00cd00", "stroke-width": 5}, o: { duration: animationTime} }];
            appendAnimation(6, animation, codeDisplayManager);
            return t; // Match
        }
    }

    var animation = [{ e: $("#graphics, .treeEditor svg"), p: {"background-color": "#ff0000", opacity: 0.5}, o: { duration: animationTime/2} }];
    animation.push({ e: $("#graphics, .treeEditor svg"), p: {"background-color": "#fcfcfc", opacity: 1}, o: { duration: animationTime/2} });
    appendAnimation(9, animation, codeDisplayManager);
    makeGUIUnEditable();
    return null; // Not Found
}

function visualizeRemove(lbl) {
    function remove(x, t) {
        hasBeenInIf = false;
        if (t === null) {
            hasBeenInIf = true;
            appendCodeLines([0], codeDisplayManager);
            var animation = [{ e: $("#graphics, .treeEditor svg"), p: {"background-color": "#ff0000", opacity: 0.5}, o: { duration: animationTime/2} }];
            animation.push({ e: $("#graphics, .treeEditor svg"), p: {"background-color": "#fcfcfc", opacity: 1}, o: { duration: animationTime/2} });
            appendAnimation(1, animation, codeDisplayManager);
            makeGUIUnEditable();
            return null;
        } else {
            appendAnimation(null, getVertixMarkAnimation(t), codeDisplayManager);
        }

        appendCodeLines([2], codeDisplayManager);
        if (x - t.getElement() < 0) {
            hasBeenInIf = true, parent = t, direction = 'left';
            appendCodeLines([3], codeDisplayManager);
            t.setLeft(remove(x, t.getLeft()));
            appendCodeLines([4, 6, 9], codeDisplayManager);
        }
        else if (x - t.getElement() > 0) {
            hasBeenInIf = true, parent = t, direction = 'right';
            appendCodeLines([4, 5], codeDisplayManager);
            t.setRight(remove(x, t.getRight()));
            appendCodeLines([6, 9], codeDisplayManager);

        }
        else if (t.getLeft() !== null && t.getRight() !== null) { // Two children
            hasBeenInIf = true;
            appendCodeLines([6, 7, 8], codeDisplayManager);
            t.setElement(bst.findMinNode(t.getRight()).getElement()); // Bytter verdiene på elementene
            t.setRight(bst.removeMinNode(t.getRight())); // Fjerner noden den har bytta med, og setter
            appendCodeLines([9], codeDisplayManager);
        }
        else {
            appendCodeLines([10, 11], codeDisplayManager);
            hasBeenInIf = true;
            if (t.getLeft() !== null) {
                parent = t, direction = 'left';
                t = t.getLeft();
            }
            else {
                parent = t, direction = 'right';
                t = t.getRight();
            }
        }
        appendCodeLines([12], codeDisplayManager);
        return t;
    }
    removeMarker();
    createMarker();
    codeDisplayManager.loadFunctions("removeNode");
    codeDisplayManager.changeFunction("removeNode");
    var parent = bst.root, direction = null, hasBeenInIf = false;
    remove(lbl, bst.root);
    makeGUIUnEditable();
}

init(50);
/*
setTimeout(function(){
    visualizeInsert(90);
    setTimeout(function() {
        visualizeInsert(30);
    }, 3000)
}, 3000);
*/
<|endoftext|>


<commit_before>
"use strict";

let paths = {};
let loc;

class Navigation {

    constructor($location) {
        loc = $location;
    }

    register(menu, url, label) {
        let selected = false;
        paths[menu] = paths[menu] || [];
        paths[menu].push({url, label, selected});
        if (!this.hasOwnProperty(menu)) {
            Object.defineProperty(this, menu, {get: () => paths[menu]});
        }
    }

    current() {
        for (let path in paths) {
            paths[path].map(item => item.selected = item.url != '/' && ('#' + loc.path()).indexOf(item.url) != -1);
        }
    }

    select(item = {}) {
        for (let path in paths) {
            paths[path].map(item => item.selected = false);
        }
        item.selected = true;
    }

}

Navigation.$inject = ['$location'];

export {Navigation};

<commit_msg>make this also callable from a non-angular environment<commit_after>
"use strict";

let paths = {};
let loc;

class Navigation {

    constructor($location = undefined) {
        if ($location) {
            loc = $location;
        }
    }

    register(menu, url, label) {
        let selected = false;
        paths[menu] = paths[menu] || [];
        paths[menu].push({url, label, selected});
        if (!this.hasOwnProperty(menu)) {
            Object.defineProperty(this, menu, {get: () => paths[menu]});
        }
    }

    current() {
        for (let path in paths) {
            paths[path].map(item => item.selected = item.url != '/' && ('#' + loc.path()).indexOf(item.url) != -1);
        }
    }

    select(item = {}) {
        for (let path in paths) {
            paths[path].map(item => item.selected = false);
        }
        item.selected = true;
    }

    /**
     * Main menu is (virtually) always defined anyway.
     */
    get main() {
        return paths.main;
    }

}

Navigation.$inject = ['$location'];

export {Navigation};

<|endoftext|>