<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { isEqual } from 'lodash';
import { compose } from 'redux';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import { withRouter } from 'react-router';
import localforage from 'localforage';

import { withModules } from '../Modules';
import { LastVisitedContext } from '../LastVisited';
import { clearOkapiToken, clearCurrentUser } from '../../okapiActions';
import { resetStore } from '../../mainActions';
import {
  updateQueryResource,
  getLocationQuery,
  updateLocation,
  getCurrentModule,
  isQueryResourceModule
} from '../../locationService';

import css from './MainNav.css';
import NavDivider from './NavDivider';
import NavGroup from './NavGroup';
import { CurrentAppGroup } from './CurrentApp';
import ProfileDropdown from './ProfileDropdown';
import AppList from './AppList';

import settingsIcon from './settings.svg';

class MainNav extends Component {
  static propTypes = {
    intl: intlShape,
    stripes: PropTypes.shape({
      config: PropTypes.shape({
        showPerms: PropTypes.bool,
      }),
      store: PropTypes.shape({
        dispatch: PropTypes.func.isRequired,
      }),
      hasPerm: PropTypes.func.isRequired,
      withOkapi: PropTypes.bool,
    }),
    history: PropTypes.shape({
      listen: PropTypes.func.isRequired,
      replace: PropTypes.func.isRequired,
      push: PropTypes.func.isRequired,
    }).isRequired,
    location: PropTypes.shape({
      pathname: PropTypes.string,
    }).isRequired,
    modules: PropTypes.shape({
      app: PropTypes.array,
    })
  };

  static contextTypes = {
    router: PropTypes.object.isRequired,
  }

  static childContextTypes = {
    // It seems wrong that we have to tell this generic component what specific properties to put in the context
    stripes: PropTypes.object,
  };

  constructor(props) {
    super(props);
    this.state = {
      userMenuOpen: false,
    };
    this.store = props.stripes.store;
    this.logout = this.logout.bind(this);
    this.getAppList = this.getAppList.bind(this);
  }

  getChildContext() {
    return {
      stripes: this.props.stripes,
    };
  }

  componentDidMount() {
    let curQuery = getLocationQuery(this.props.location);
    this._unsubscribe = this.store.subscribe(() => {
      const { history, location } = this.props;
      const module = this.curModule;
      if (module && isQueryResourceModule(module, location)) {
        curQuery = updateLocation(module, curQuery, this.store, history, location);
      }
    });
  }

  componentDidUpdate(prevProps) {
    const { modules, location } = this.props;
    this.curModule = getCurrentModule(modules, location);
    if (this.curModule && !isEqual(location, prevProps.location)) {
      updateQueryResource(location, this.curModule, this.store);
    }
  }

  componentWillUnmount() {
    this._unsubscribe();
  }

  toggleUserMenu() {
    const isOpen = this.state.userMenuOpen;
    this.setState({
      userMenuOpen: !isOpen,
    });
  }

  logout() {
    this.store.dispatch(clearOkapiToken());
    this.store.dispatch(clearCurrentUser());
    this.store.dispatch(resetStore());
    localforage.removeItem('okapiSess');
    this.context.router.history.push('/');
  }

  getAppList(lastVisited) {
    const { stripes, location: { pathname }, modules, intl: { formatMessage } } = this.props;

    const apps = modules.app.map((entry) => {
      const name = entry.module.replace(/^@[a-z0-9_]+\//, '');
      const perm = `module.${name}.enabled`;

      if (!stripes.hasPerm(perm)) {
        return null;
      }

      const id = `clickable-${name}-module`;

      const pathRoot = pathname.split('/')[1];
      const entryRoot = entry.route.split('/')[1];
      const active = pathRoot === entryRoot;

      const href = lastVisited[name] || entry.home || entry.route;

      return {
        id,
        href,
        active,
        name,
        ...entry,
      };
    }).filter(app => app);

    /**
     * Add Settings to apps array manually
     * until Settings becomes a standalone app
     */

    if (stripes.hasPerm('settings.enabled')) {
      apps.push({
        displayName: formatMessage({ id: 'stripes-core.settings' }),
        id: 'clickable-settings',
        href: lastVisited.x_settings || '/settings',
        active: pathname.startsWith('/settings'),
        description: 'FOLIO settings',
        iconData: {
          src: settingsIcon,
          alt: 'Tenant Settings',
          title: 'Settings',
        },
        route: '/settings'
      });
    }

    return apps;
  }

  render() {
    const { stripes } = this.props;

    return (
      <LastVisitedContext.Consumer>
        {({ lastVisited }) => {
          const apps = this.getAppList(lastVisited);
          const selectedApp = apps.find(entry => entry.active);

          return (

              <NavGroup>

                  <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26">
                    <polygon style={{ fill: '#999' }} points="13 16.5 1.2 5.3 3.2 3.1 13 12.4 22.8 3.1 24.8 5.3 " />
                    <polygon style={{ fill: '#999' }} points="13 24.8 1.2 13.5 3.2 11.3 13 20.6 22.8 11.3 24.8 13.5 " />
                  </svg>

                <CurrentAppGroup selectedApp={selectedApp} />
              </NavGroup>

                  <FormattedMessage id="stripes-core.mainnav.topLevelLabel" />

                <NavGroup>
                  <NavDivider md="hide" />
                  <AppList
                    apps={apps}
                    selectedApp={selectedApp}
                    dropdownToggleId="app-list-dropdown-toggle"
                  />
                  <NavDivider md="hide" />
                  <ProfileDropdown
                    onLogout={this.logout}
                    stripes={stripes}
                  />
                </NavGroup>

          );
        }}
      </LastVisitedContext.Consumer>
    );
  }
}

export default compose(
  injectIntl,
  withRouter,
  withModules,
)(MainNav);
<commit_msg>STRIPES-614: Fixed logout throwing errors<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { isEqual } from 'lodash';
import { compose } from 'redux';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import { withRouter } from 'react-router';
import localforage from 'localforage';

import { withModules } from '../Modules';
import { LastVisitedContext } from '../LastVisited';
import { clearOkapiToken, clearCurrentUser } from '../../okapiActions';
import { resetStore } from '../../mainActions';
import {
  updateQueryResource,
  getLocationQuery,
  updateLocation,
  getCurrentModule,
  isQueryResourceModule
} from '../../locationService';

import css from './MainNav.css';
import NavDivider from './NavDivider';
import NavGroup from './NavGroup';
import { CurrentAppGroup } from './CurrentApp';
import ProfileDropdown from './ProfileDropdown';
import AppList from './AppList';

import settingsIcon from './settings.svg';

class MainNav extends Component {
  static propTypes = {
    intl: intlShape,
    stripes: PropTypes.shape({
      config: PropTypes.shape({
        showPerms: PropTypes.bool,
      }),
      store: PropTypes.shape({
        dispatch: PropTypes.func.isRequired,
      }),
      hasPerm: PropTypes.func.isRequired,
      withOkapi: PropTypes.bool,
    }),
    history: PropTypes.shape({
      listen: PropTypes.func.isRequired,
      replace: PropTypes.func.isRequired,
      push: PropTypes.func.isRequired,
    }).isRequired,
    location: PropTypes.shape({
      pathname: PropTypes.string,
    }).isRequired,
    modules: PropTypes.shape({
      app: PropTypes.array,
    })
  };

  static contextTypes = {
    router: PropTypes.object.isRequired,
  }

  static childContextTypes = {
    // It seems wrong that we have to tell this generic component what specific properties to put in the context
    stripes: PropTypes.object,
  };

  constructor(props) {
    super(props);
    this.state = {
      userMenuOpen: false,
    };
    this.store = props.stripes.store;
    this.logout = this.logout.bind(this);
    this.getAppList = this.getAppList.bind(this);
  }

  getChildContext() {
    return {
      stripes: this.props.stripes,
    };
  }

  componentDidMount() {
    let curQuery = getLocationQuery(this.props.location);
    this._unsubscribe = this.store.subscribe(() => {
      const { history, location } = this.props;
      const module = this.curModule;
      if (module && isQueryResourceModule(module, location)) {
        curQuery = updateLocation(module, curQuery, this.store, history, location);
      }
    });
  }

  componentDidUpdate(prevProps) {
    const { modules, location } = this.props;
    this.curModule = getCurrentModule(modules, location);
    if (this.curModule && !isEqual(location, prevProps.location)) {
      updateQueryResource(location, this.curModule, this.store);
    }
  }

  componentWillUnmount() {
    this._unsubscribe();
  }

  toggleUserMenu() {
    const isOpen = this.state.userMenuOpen;
    this.setState({
      userMenuOpen: !isOpen,
    });
  }

  logout() {
    this.store.dispatch(clearOkapiToken());
    this.store.dispatch(clearCurrentUser());
    this.store.dispatch(resetStore());
    localforage.removeItem('okapiSess');
    this.props.history.push('/');
  }

  getAppList(lastVisited) {
    const { stripes, location: { pathname }, modules, intl: { formatMessage } } = this.props;

    const apps = modules.app.map((entry) => {
      const name = entry.module.replace(/^@[a-z0-9_]+\//, '');
      const perm = `module.${name}.enabled`;

      if (!stripes.hasPerm(perm)) {
        return null;
      }

      const id = `clickable-${name}-module`;

      const pathRoot = pathname.split('/')[1];
      const entryRoot = entry.route.split('/')[1];
      const active = pathRoot === entryRoot;

      const href = lastVisited[name] || entry.home || entry.route;

      return {
        id,
        href,
        active,
        name,
        ...entry,
      };
    }).filter(app => app);

    /**
     * Add Settings to apps array manually
     * until Settings becomes a standalone app
     */

    if (stripes.hasPerm('settings.enabled')) {
      apps.push({
        displayName: formatMessage({ id: 'stripes-core.settings' }),
        id: 'clickable-settings',
        href: lastVisited.x_settings || '/settings',
        active: pathname.startsWith('/settings'),
        description: 'FOLIO settings',
        iconData: {
          src: settingsIcon,
          alt: 'Tenant Settings',
          title: 'Settings',
        },
        route: '/settings'
      });
    }

    return apps;
  }

  render() {
    const { stripes } = this.props;

    return (
      <LastVisitedContext.Consumer>
        {({ lastVisited }) => {
          const apps = this.getAppList(lastVisited);
          const selectedApp = apps.find(entry => entry.active);

          return (

              <NavGroup>

                  <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26">
                    <polygon style={{ fill: '#999' }} points="13 16.5 1.2 5.3 3.2 3.1 13 12.4 22.8 3.1 24.8 5.3 " />
                    <polygon style={{ fill: '#999' }} points="13 24.8 1.2 13.5 3.2 11.3 13 20.6 22.8 11.3 24.8 13.5 " />
                  </svg>

                <CurrentAppGroup selectedApp={selectedApp} />
              </NavGroup>

                  <FormattedMessage id="stripes-core.mainnav.topLevelLabel" />

                <NavGroup>
                  <NavDivider md="hide" />
                  <AppList
                    apps={apps}
                    selectedApp={selectedApp}
                    dropdownToggleId="app-list-dropdown-toggle"
                  />
                  <NavDivider md="hide" />
                  <ProfileDropdown
                    onLogout={this.logout}
                    stripes={stripes}
                  />
                </NavGroup>

          );
        }}
      </LastVisitedContext.Consumer>
    );
  }
}

export default compose(
  injectIntl,
  withRouter,
  withModules,
)(MainNav);
<|endoftext|>


<commit_before>/*global module:false*/
module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    meta: {
      version: '0.1.0',
      banner: '/*! r3vis - v<%= meta.version %> - ' +
        '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
        '* http://github.com/hashd \n' +
        '* Copyright (c) <%= grunt.template.today("yyyy") %> ' +
        '; Licensed MIT */'
    },

    lint: {
      files: ['grunt.js', 'dist/r3.js', 'dist/r3_gfx.js']
    },

    qunit: {
      files: ['test/**/*.html']
    },

    concat: {
      dist: {
        src: ['<banner:meta.banner>', 'src/gfx/graph.js', 'src/util/utility.js', 'src/util/config.js', 'src/util/constants.js', 'src/util/effects.js', 'src/util/palette.js', 'src/gfx/area.js', 'src/gfx/bar.js',
              'src/gfx/donut.js', 'src/gfx/line.js', 'src/gfx/percent_area.js', 'src/gfx/percent_bar.js', 'src/gfx/pie.js', 'src/gfx/stacked_area.js', 'src/gfx/stacked_bar.js', 'src/gfx/stepup_bar.js',
              'src/gfx/table.js', 'src/gfx/tablegraph.js'],
        dest: 'dist/r3.js'
      },

      gfx : {
        src: ['<banner:meta.banner>', 'src/gfx/graph.js', 'src/util/utility.js', 'src/util/config.js', 'src/util/constants.js', 'src/util/effects.js', 'src/util/palette.js', 'src/gfx/area.js', 'src/gfx/bar.js',
              'src/gfx/donut.js', 'src/gfx/line.js', 'src/gfx/percent_area.js', 'src/gfx/percent_bar.js', 'src/gfx/pie.js', 'src/gfx/stacked_area.js', 'src/gfx/stacked_bar.js', 'src/gfx/stepup_bar.js',
              'src/gfx/table.js', 'src/gfx/tablegraph.js'],
        dest: 'dist/r3_gfx.js'
      }
    },

    min: {
      dist: {
        src: ['<banner:meta.banner>', '<config:concat.dist.dest>'],
        dest: 'dist/r3.min.js'
      },

      gfx : {
        src: ['<banner:meta.banner>', '<config:concat.gfx.dest>'],
        dest: 'dist/r3_gfx.min.js'
      }
    },

    watch: {
      files: '<config:lint.files>',
      tasks: 'lint qunit'
    },

    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true,
        browser: true
      },
      globals: {
        jQuery: true
      }
    },

    uglify: {}
  });

  // Default task.
  grunt.registerTask('default', 'lint qunit concat min');
  grunt.registerTask('build_gfx', 'concat:gfx min:gfx')
};
<commit_msg>Grunt task modified to now watch and rebuild minified files on save<commit_after>/*global module:false*/
module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    meta: {
      version: '0.1.0',
      banner: '/*! r3vis - v<%= meta.version %> - ' +
        '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
        '* http://github.com/hashd \n' +
        '* Copyright (c) <%= grunt.template.today("yyyy") %> ' +
        '; Licensed MIT */'
    },

    lint: {
      files: ['grunt.js', 'dist/r3.js', 'dist/r3_gfx.js']
    },

    qunit: {
      files: ['test/**/*.html']
    },

    concat: {
      dist: {
        src: ['src/gfx/graph.js', 'src/util/utility.js', 'src/util/config.js', 'src/util/constants.js', 'src/util/effects.js', 'src/util/palette.js', 'src/gfx/area.js', 'src/gfx/bar.js',
              'src/gfx/donut.js', 'src/gfx/line.js', 'src/gfx/percent_area.js', 'src/gfx/percent_bar.js', 'src/gfx/pie.js', 'src/gfx/stacked_area.js', 'src/gfx/stacked_bar.js', 'src/gfx/stepup_bar.js',
              'src/gfx/table.js', 'src/gfx/tablegraph.js'],
        dest: 'dist/r3.js'
      },

      gfx : {
        src: ['src/gfx/graph.js', 'src/util/utility.js', 'src/util/config.js', 'src/util/constants.js', 'src/util/effects.js', 'src/util/palette.js', 'src/gfx/area.js', 'src/gfx/bar.js',
              'src/gfx/donut.js', 'src/gfx/line.js', 'src/gfx/percent_area.js', 'src/gfx/percent_bar.js', 'src/gfx/pie.js', 'src/gfx/stacked_area.js', 'src/gfx/stacked_bar.js', 'src/gfx/stepup_bar.js',
              'src/gfx/table.js', 'src/gfx/tablegraph.js'],
        dest: 'dist/r3_gfx.js'
      }
    },

    min: {
      dist: {
        src: ['<banner:meta.banner>', '<config:concat.dist.dest>'],
        dest: 'dist/r3.min.js'
      },

      gfx : {
        src: ['<banner:meta.banner>', '<config:concat.gfx.dest>'],
        dest: 'dist/r3_gfx.min.js'
      }
    },

    watch: {
      files: '<config:concat.gfx.src>',
      tasks: 'build_gfx'
    },

    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true,
        browser: true
      },
      globals: {
        jQuery: true
      }
    },

    uglify: {}
  });

  // Default task.
  grunt.registerTask('default', 'lint qunit concat min');
  grunt.registerTask('build_gfx', 'concat:gfx min:gfx')
};
<|endoftext|>


<commit_before>import Controller from '@ember/controller';
import { computed } from '@ember/object';
import { sumBy } from 'lodash';

export default Controller.extend({
  hasTicketsInOrder: computed('model.tickets.@each.orderQuantity', function() {
    return sumBy(this.get('model.tickets').toArray(),
      ticket => ticket.getWithDefault('orderQuantity', 0)
    ) > 0;
  }),
  total: computed('model.tickets.@each.orderQuantity', function() {
    let sum = 0.0;
    this.get('model.tickets').forEach(ticket => {
      sum += ticket.get('orderQuantity') * ticket.get('price');
    });
    return sum;
  }),
  columns: [
    {
      propertyName : 'name',
      title        : 'Ticket Type'
    },
    {
      propertyName   : 'price',
      title          : 'Price',
      template       : 'components/ui-table/cell/events/view/tickets/cell-add-order-price',
      disableSorting : true
    },
    {
      propertyName : 'quantity',
      title        : 'Quantity',
      template     : 'components/ui-table/cell/events/view/tickets/cell-add-order-quantity'
    },
    {
      propertyName : 'itemTotal',
      title        : 'Item Total',
      template     : 'components/ui-table/cell/events/view/tickets/cell-add-order-total'
    }
  ],

  actions: {
    updateOrder(ticket, count) {
      let order = this.get('model.order');
      ticket.set('orderQuantity', count);
      order.set('amount', this.get('total'));
      if (!this.get('total')) {
        order.set('amount', 0);
      }
      if (count > 0) {
        order.tickets.addObject(ticket);
      } else {
        if (order.tickets.includes(ticket)) {
          order.tickets.removeObject(ticket);
        }
      }
    },
    async placeOrder() {
      this.set('isLoading', true);
      let order = this.get('model.order');
      let event = order.get('event');
      order.tickets.forEach(ticket => {
        let numberOfAttendees = ticket.orderQuantity;
        while (numberOfAttendees--) {
          this.get('model.attendees').addObject(this.store.createRecord('attendee', {
            firstname : 'John',
            lastname  : 'Doe',
            email     : 'johndoe@example.com',
            event,
            ticket
          }));
        }
      });
      try {
        let order = this.get('model.order');
        let attendees = this.get('model.attendees');
        for (const attendee of attendees ? attendees.toArray() : []) {
          await attendee.save();
        }
        order.set('attendees', attendees.slice());
        await order.save()
          .then(order => {
            this.get('notify').success(this.get('l10n').t('Order details saved. Please fill further details within 10 minutes.'));
            this.transitionToRoute('orders.new', order.identifier);
          })
          .catch(async() => {
            for (const attendee of attendees ? attendees.toArray() : []) {
              await attendee.destroyRecord();
            }
            this.get('notify').error(this.get('l10n').t('Oops something went wrong. Please try again'));
          })
          .finally(() => {
            this.set('isLoading', false);
          });
      } catch (e) {
        this.get('notify').error(this.get('l10n').t('Oops something went wrong. Please try again'));
      }
    }
  }
});
<commit_msg>Enabled sorting in ember table on basis of ticket price (#2814)<commit_after>import Controller from '@ember/controller';
import { computed } from '@ember/object';
import { sumBy } from 'lodash';

export default Controller.extend({
  hasTicketsInOrder: computed('model.tickets.@each.orderQuantity', function() {
    return sumBy(this.get('model.tickets').toArray(),
      ticket => ticket.getWithDefault('orderQuantity', 0)
    ) > 0;
  }),
  total: computed('model.tickets.@each.orderQuantity', function() {
    let sum = 0.0;
    this.get('model.tickets').forEach(ticket => {
      sum += ticket.get('orderQuantity') * ticket.get('price');
    });
    return sum;
  }),
  columns: [
    {
      propertyName : 'name',
      title        : 'Ticket Type'
    },
    {
      propertyName : 'price',
      title        : 'Price',
      template     : 'components/ui-table/cell/events/view/tickets/cell-add-order-price'
    },
    {
      propertyName : 'quantity',
      title        : 'Quantity',
      template     : 'components/ui-table/cell/events/view/tickets/cell-add-order-quantity'
    },
    {
      propertyName : 'itemTotal',
      title        : 'Item Total',
      template     : 'components/ui-table/cell/events/view/tickets/cell-add-order-total'
    }
  ],

  actions: {
    updateOrder(ticket, count) {
      let order = this.get('model.order');
      ticket.set('orderQuantity', count);
      order.set('amount', this.get('total'));
      if (!this.get('total')) {
        order.set('amount', 0);
      }
      if (count > 0) {
        order.tickets.addObject(ticket);
      } else {
        if (order.tickets.includes(ticket)) {
          order.tickets.removeObject(ticket);
        }
      }
    },
    async placeOrder() {
      this.set('isLoading', true);
      let order = this.get('model.order');
      let event = order.get('event');
      order.tickets.forEach(ticket => {
        let numberOfAttendees = ticket.orderQuantity;
        while (numberOfAttendees--) {
          this.get('model.attendees').addObject(this.store.createRecord('attendee', {
            firstname : 'John',
            lastname  : 'Doe',
            email     : 'johndoe@example.com',
            event,
            ticket
          }));
        }
      });
      try {
        let order = this.get('model.order');
        let attendees = this.get('model.attendees');
        for (const attendee of attendees ? attendees.toArray() : []) {
          await attendee.save();
        }
        order.set('attendees', attendees.slice());
        await order.save()
          .then(order => {
            this.get('notify').success(this.get('l10n').t('Order details saved. Please fill further details within 10 minutes.'));
            this.transitionToRoute('orders.new', order.identifier);
          })
          .catch(async() => {
            for (const attendee of attendees ? attendees.toArray() : []) {
              await attendee.destroyRecord();
            }
            this.get('notify').error(this.get('l10n').t('Oops something went wrong. Please try again'));
          })
          .finally(() => {
            this.set('isLoading', false);
          });
      } catch (e) {
        this.get('notify').error(this.get('l10n').t('Oops something went wrong. Please try again'));
      }
    }
  }
});
<|endoftext|>


<commit_before>define(['js/core/EventDispatcher','js/lib/parser','js/core/Binding', 'underscore'], function(EventDispatcher,Parser, Binding, _){

    function findTransformFunction(path, scope) {
        var pathElement = path[0];
        if (pathElement.type == Binding.TYPE_FNC) {
            scope = scope.getScopeForFncName(pathElement.name);
        } else {
            scope = scope.getScopeForKey(pathElement.name);
        }

        var nScope = scope;
        while (nScope && path.length > 0) {
            pathElement = path.shift();
            if (pathElement.type == Binding.TYPE_FNC) {
                return nScope[pathElement.name];
            } else if (pathElement.type == Binding.TYPE_VAR) {
                nScope = nScope.get(pathElement.name);
            }
        }

        return false;
    }

    var bindingCache = {},
        idCounter = 0,
        cacheCounter = 0;

    function pathToString(path){
        if(path instanceof Array){
            var el = [];
            for(var i = 0; i < path.length; i++){
                if(path[i].type === Binding.TYPE_VAR){
                    el.push(path[i].name);
                } else if(path[i].type === Binding.TYPE_FNC){
                    el.push(path[i].name + "(" + (idCounter++) + ")");
                }
            }

            return el.join(".");
        } else {
            return path;
        }
    }

    return EventDispatcher.inherit('js.core.BindingCreator',{

        /***
         *
         * @param bindingDef
         * @param targetScope
         * @param {String|Function} attrKey key where to bind, or callback function
         * @param context
         * @return {*}
         */
        create: function(bindingDef, targetScope, attrKey, context){
            var path = bindingDef.path;
            var pathElement = path[0];

            var scope;
            var searchScope = targetScope;
            if (pathElement.type != Binding.TYPE_FNC && attrKey == pathElement.name) {
                searchScope = searchScope.$parentScope;
            }

            if (pathElement.type == Binding.TYPE_FNC) {
                scope = searchScope.getScopeForFncName(pathElement.name);
            } else {
                scope = searchScope.getScopeForKey(pathElement.name);
            }

            if(scope){
                if (bindingDef.type !== "static") {
                    var cb;
                    if (_.isFunction(attrKey)) {
                        cb = attrKey;
                    }

                    var twoWay = (bindingDef.type == Binding.TYPE_TWOWAY),
                        cacheId;

                    if(!cb && !twoWay){
                        cacheId = pathToString(bindingDef.path) + scope.$cid;
                        if(bindingCache[cacheId]){
                            bindingCache[cacheId].addTarget(targetScope,attrKey);
                            return bindingCache[cacheId];
                        }
                    }

                    var options = {
                        scope: scope,
                        path: path,
                        parent: bindingDef.parent,
                        target: targetScope,
                        twoWay: twoWay,
                        context: context,
                        bindingCreator: this
                    };

                    if (twoWay) {
                        if (bindingDef.transform) {
                            var transformFnc = findTransformFunction(bindingDef.transform, searchScope);
                            if (transformFnc) {
                                options.transform = transformFnc;
                            }
                        }

                        if (bindingDef.transformBack) {
                            var transformBackFnc = findTransformFunction(bindingDef.transformBack, searchScope);
                            if (transformBackFnc) {
                                options.transformBack = transformBackFnc;
                            }
                        }
                    }

                    if (cb) {
                        options['callback'] = cb;
                    } else {
                        options['targetKey'] = attrKey;
                    }

                    var binding = new Binding(options);
                    if(!twoWay && !(cb)){
                        binding.bind('destroy', function(){
                            delete bindingCache[cacheId];
                        });
                        bindingCache[cacheId] = binding
                    }

                    return binding;

                } else {
                    return scope.get(bindingDef.path);
                }
            }else{
                throw new Error("Couldn't find scope for " + pathElement.name);
            }

        },

        /***
         *
         * @param text
         * @param scope
         * @param attrKey
         * @param [bindingDefinitions]
         * @return {*}
         */
        evaluate: function (text, scope, attrKey, bindingDefinitions) {
            if (!_.isString(text)) {
                return text;
            }

            bindingDefinitions = bindingDefinitions || this.parse(text);

            var binding,
                bindings = [];

            for (var i = 0; i < bindingDefinitions.length; i++) {
                var bindingDef = bindingDefinitions[i];
                if (bindingDef.length) {
                    bindingDefinitions[i] = bindingDef;
                } else {
                    try {
                        binding = this.create(bindingDef, scope, attrKey, bindingDefinitions);
                    } catch (e) {
                        throw new Error("Create binding for '" + text + "'. " + e.message);
                    }

                    if (binding instanceof Binding) {
                        bindings.push(binding);
                        scope.$bindings[attrKey] = scope.$bindings[attrKey] || [];
                        scope.$bindings[attrKey].push(binding);
                    }
                    bindingDefinitions[i] = binding;
                }

            }

            if (bindings.length > 0) {
                return bindings[0].getContextValue();
            } else if (bindingDefinitions.length > 0) {
                if (bindingDefinitions.length === 1) {
                    return bindingDefinitions[0];
                }
                return Binding.contextToString(bindingDefinitions);
            } else {
                return text;
            }

        },

        parse: function(text) {
            if (_.isString(text)) {
                return Parser.parse(text, "text");
            }
        },

        parsePath: function(text){
            return Parser.parse(text, "path");
        },
        containsBindingDefinition: function(bindingDefinitions) {

            if (bindingDefinitions) {
                for (var i = 0; i < bindingDefinitions.length; i++) {
                    if (bindingDefinitions[i] instanceof Object) {
                        return true;
                    }
                }
            }

            return false;
        }
    });

});<commit_msg>fixed binding cache<commit_after>define(['js/core/EventDispatcher','js/lib/parser','js/core/Binding', 'underscore'], function(EventDispatcher,Parser, Binding, _){

    function findTransformFunction(path, scope) {
        var pathElement = path[0];
        if (pathElement.type == Binding.TYPE_FNC) {
            scope = scope.getScopeForFncName(pathElement.name);
        } else {
            scope = scope.getScopeForKey(pathElement.name);
        }

        var nScope = scope;
        while (nScope && path.length > 0) {
            pathElement = path.shift();
            if (pathElement.type == Binding.TYPE_FNC) {
                return nScope[pathElement.name];
            } else if (pathElement.type == Binding.TYPE_VAR) {
                nScope = nScope.get(pathElement.name);
            }
        }

        return false;
    }

    var bindingCache = {},
        idCounter = 0,
        bindings = 0,
        cacheCounter = 0;

    function pathToString(path){
        if(path instanceof Array){
            var el = [];
            for(var i = 0; i < path.length; i++){
                if(path[i].type === Binding.TYPE_VAR){
                    el.push(path[i].name);
                } else if(path[i].type === Binding.TYPE_FNC){
                    el.push(path[i].name + "(" + (idCounter++) + ")");
                }
            }

            return el.join(".");
        } else {
            return path;
        }
    }

    return EventDispatcher.inherit('js.core.BindingCreator',{

        /***
         *
         * @param bindingDef
         * @param targetScope
         * @param {String|Function} attrKey key where to bind, or callback function
         * @param context
         * @return {*}
         */
        create: function(bindingDef, targetScope, attrKey, context){

            var path = bindingDef.path;
            var pathElement = path[0];

            var scope;
            var searchScope = targetScope;
            if (pathElement.type != Binding.TYPE_FNC && attrKey == pathElement.name) {
                searchScope = searchScope.$parentScope;
            }

            if (pathElement.type == Binding.TYPE_FNC) {
                scope = searchScope.getScopeForFncName(pathElement.name);
            } else {
                scope = searchScope.getScopeForKey(pathElement.name);
            }

            if(scope){
                if (bindingDef.type !== "static") {
                    var cb;
                    if (_.isFunction(attrKey)) {
                        cb = attrKey;
                    }

                    var twoWay = (bindingDef.type == Binding.TYPE_TWOWAY),
                        cacheId;

                    bindings++;

                    if(!cb && !twoWay && context && context.length === 1 && (context[0] instanceof Object)){
                        cacheId = pathToString(bindingDef.path) + "_" + scope.$cid;
                        cacheCounter++;
                        if(bindingCache[cacheId]){
                            bindingCache[cacheId].addTarget(targetScope,attrKey);
                            return bindingCache[cacheId];
                        }
                    }

                    var options = {
                        scope: scope,
                        path: path,
                        parent: bindingDef.parent,
                        target: targetScope,
                        twoWay: twoWay,
                        context: context,
                        bindingCreator: this
                    };

                    if (twoWay) {
                        if (bindingDef.transform) {
                            var transformFnc = findTransformFunction(bindingDef.transform, searchScope);
                            if (transformFnc) {
                                options.transform = transformFnc;
                            }
                        }

                        if (bindingDef.transformBack) {
                            var transformBackFnc = findTransformFunction(bindingDef.transformBack, searchScope);
                            if (transformBackFnc) {
                                options.transformBack = transformBackFnc;
                            }
                        }
                    }

                    if (cb) {
                        options['callback'] = cb;
                    } else {
                        options['targetKey'] = attrKey;
                    }

                    var binding = new Binding(options);
                    if(!twoWay && !(cb)){
                        binding.bind('destroy', function(){
                            delete bindingCache[cacheId];
                        });
                        bindingCache[cacheId] = binding
                    }

                    return binding;

                } else {
                    return scope.get(bindingDef.path);
                }
            }else{
                throw new Error("Couldn't find scope for " + pathElement.name);
            }

        },

        /***
         *
         * @param text
         * @param scope
         * @param attrKey
         * @param [bindingDefinitions]
         * @return {*}
         */
        evaluate: function (text, scope, attrKey, bindingDefinitions) {
            if (!_.isString(text)) {
                return text;
            }

            bindingDefinitions = bindingDefinitions || this.parse(text);

            var binding,
                bindings = [];

            for (var i = 0; i < bindingDefinitions.length; i++) {
                var bindingDef = bindingDefinitions[i];
                if (bindingDef.length) {
                    bindingDefinitions[i] = bindingDef;
                } else {
                    try {
                        binding = this.create(bindingDef, scope, attrKey, bindingDefinitions);
                    } catch (e) {
                        throw new Error("Create binding for '" + text + "'. " + e.message);
                    }

                    if (binding instanceof Binding) {
                        bindings.push(binding);
                        scope.$bindings[attrKey] = scope.$bindings[attrKey] || [];
                        scope.$bindings[attrKey].push(binding);
                    }
                    bindingDefinitions[i] = binding;
                }

            }

            if (bindings.length > 0) {
                return bindings[0].getContextValue();
            } else if (bindingDefinitions.length > 0) {
                if (bindingDefinitions.length === 1) {
                    return bindingDefinitions[0];
                }
                return Binding.contextToString(bindingDefinitions);
            } else {
                return text;
            }

        },

        parse: function(text) {
            if (_.isString(text)) {
                return Parser.parse(text, "text");
            }
        },

        parsePath: function(text){
            return Parser.parse(text, "path");
        },
        containsBindingDefinition: function(bindingDefinitions) {

            if (bindingDefinitions) {
                for (var i = 0; i < bindingDefinitions.length; i++) {
                    if (bindingDefinitions[i] instanceof Object) {
                        return true;
                    }
                }
            }

            return false;
        }
    });

});<|endoftext|>


<commit_before>var workQueue = require('./workQueue');
var Promise = require('unexpected-bluebird');
module.exports = function oathbreaker(value) {
    if (!value || typeof value.then !== 'function') {
        return value;
    }

    if (!value.isRejected) {
        // this is not a bluebird promise
        return value;
    }

    if (value.isFulfilled()) {
        return value;
    }

    if (value.isRejected()) {
        value.caught(function () {
            // Ignore - already handled
        });

        throw value.reason();
    }

    var onResolve = function () {};
    var onReject = function () {};

    var evaluated = false;
    var error;
    value.then(function (obj) {
        evaluated = true;
        onResolve(value);
    }, function (err) {
        evaluated = true;
        error = err;
        onReject(err);
    });

    workQueue.drain();

    if (evaluated && error) {
        if (error._isUnexpected && Error.captureStackTrace) {
            Error.captureStackTrace(error);
        }
        throw error;
    } else if (evaluated) {
        return value;
    }

    return new Promise(function (resolve, reject) {
        onResolve = resolve;
        onReject = reject;
    });
};
<commit_msg>oathbreaker: Attach a _trace to non-oathbreakable promises so a long stack trace will be rendered.<commit_after>var workQueue = require('./workQueue');
var Promise = require('unexpected-bluebird');
module.exports = function oathbreaker(value) {
    if (!value || typeof value.then !== 'function') {
        return value;
    }

    if (!value.isRejected) {
        // this is not a bluebird promise
        return value;
    }

    if (value.isFulfilled()) {
        return value;
    }

    if (value.isRejected()) {
        value.caught(function () {
            // Ignore - already handled
        });

        throw value.reason();
    }

    var onResolve = function () {};
    var onReject = function () {};

    var evaluated = false;
    var error;
    value.then(function (obj) {
        evaluated = true;
        onResolve(value);
    }, function (err) {
        evaluated = true;
        error = err;
        onReject(err);
    });

    workQueue.drain();

    if (evaluated && error) {
        if (error._isUnexpected && Error.captureStackTrace) {
            Error.captureStackTrace(error);
        }
        throw error;
    } else if (evaluated) {
        return value;
    } else {
        value._captureStackTrace(true);
    }

    return new Promise(function (resolve, reject) {
        onResolve = resolve;
        onReject = reject;
    });
};
<|endoftext|>


<commit_before>
function setEntityInclude(selectEleId, pagePath) {
	var entityType = document.getElementById(selectEleId).value;
	CompositionManager.getEntityIncludePage(entityType, pagePath, populatePage);
}
function populatePage(pageData) {
	if (pageData.length > 0) {
		dwr.util.setValue("entityInclude", pageData, {escapeHtml:false});
	}
}
function getComposingElementOptions(selectEleId) {
	var compFuncTypeValue = dwr.util.getValue(selectEleId);
	CompositionManager.getComposingElementTypeOptions(compFuncTypeValue, function (data) {
		dwr.util.removeAllOptions("compElemType");
		dwr.util.addOptions("compElemType", [""]);
		dwr.util.addOptions("compElemType", data);
		dwr.util.addOptions("compElemType", ["[Other]"]);
	});
}
function getBiopolymerOptions(selectEleId) {
	var compFuncTypeValue = dwr.util.getValue(selectEleId);
	if (compFuncTypeValue == "biopolymer") {
		CompositionManager.getBiopolymerTypeOptions(compFuncTypeValue, function (data) {
			dwr.util.removeAllOptions("biopolymerType");
			dwr.util.addOptions("biopolymerType", [""]);
			dwr.util.addOptions("biopolymerType", data);
			dwr.util.addOptions("biopolymerType", ["[Other]"]);
		});
	}
}
function getWallTypeOptions(selectEleId) {
	var compFuncTypeValue = dwr.util.getValue(selectEleId);
	if (compFuncTypeValue == "carbon nanotube") {
		CompositionManager.getWallTypeOptions(compFuncTypeValue, function (data) {
			dwr.util.removeAllOptions("wallType");
			dwr.util.addOptions("wallType", [""]);
			dwr.util.addOptions("wallType", data);
		});
	}
}
function getNETypeOptions(selectEleId) {
	getBiopolymerOptions(selectEleId);
	getWallTypeOptions(selectEleId);
	getComposingElementOptions(selectEleId);
	setEntityTypeTitle(selectEleId);
}
function getAntibodyTypeOptions(selectEleId) {
	var compFuncTypeValue = dwr.util.getValue(selectEleId);
	if (compFuncTypeValue == "antibody") {
		CompositionManager.getAntibodyTypeOptions(compFuncTypeValue, function (data) {
			dwr.util.removeAllOptions("antibodyType");
			dwr.util.addOptions("antibodyType", [""]);
			dwr.util.addOptions("antibodyType", data);
			dwr.util.addOptions("antibodyType", ["[Other]"]);
		});
	}
}
function getAntibodyIsotypeOptions(selectEleId) {
	var compFuncTypeValue = dwr.util.getValue(selectEleId);
	if (compFuncTypeValue == "antibody") {
		CompositionManager.getAntibodyIsotypeOptions(compFuncTypeValue, function (data) {
			dwr.util.removeAllOptions("antibodyIsotype");
			dwr.util.addOptions("antibodyIsotype", [""]);
			dwr.util.addOptions("antibodyIsotype", data);
			dwr.util.addOptions("antibodyIsotype", ["[Other]"]);
		});
	}
}
function getAntibodySpeciesOptions(selectEleId) {
	var compFuncTypeValue = dwr.util.getValue(selectEleId);
	if (compFuncTypeValue == "antibody") {
		CompositionManager.getAntibodySpeciesOptions(compFuncTypeValue, function (data) {
			dwr.util.removeAllOptions("antibodySpecies");
			dwr.util.addOptions("antibodySpecies", [""]);
			dwr.util.addOptions("antibodySpecies", data);
		});
	}
}
function setEntityTypeTitle(selectEleId) {
	var selectEle = document.getElementById(selectEleId);
	document.getElementById("entityTypeTitle").innerHTML = selectEle.options[selectEle.options.selectedIndex].text;
}
function getFETypeOptions(selectEleId) {
	getBiopolymerOptions(selectEleId);
	getAntibodyTypeOptions(selectEleId);
	getAntibodyIsotypeOptions(selectEleId);
	getAntibodySpeciesOptions(selectEleId);
	setEntityTypeTitle(selectEleId);
}
function displayFEModality(functionIndex) {
	var functionType = document.getElementById("funcType_" + functionIndex).value;
	var modalityDiv = document.getElementById("modalityDiv_" + functionIndex);
	var modalityStrong = document.getElementById("modalityStrong_" + functionIndex);
	if (functionType == "imaging") {
		modalityDiv.style.display = "inline";
		modalityStrong.style.display = "inline";
	} else {
		modalityDiv.style.display = "none";
		modalityStrong.style.display = "none";
	}
	return false;
}
function displayTarget(functionIndex) {
	var functionType = document.getElementById("funcType_" + functionIndex).value;
	var targetSpan = document.getElementById("targetSpan_" + functionIndex);
	var targetDiv = document.getElementById("targetDiv_" + functionIndex);
	if (functionType == "targeting") {
		targetSpan.style.display = "block";
		targetDiv.style.display = "block";
	} else {
		targetSpan.style.display = "none";
		targetDiv.style.display = "none";
	}
	return false;
}
function displayModality(compEleIndex, functionIndex) {
	var functionType = document.getElementById("funcType_" + compEleIndex + "_" + functionIndex).value;
	var modalityTd = document.getElementById("modalityTypeTd_" + compEleIndex + "_" + functionIndex);
	var modalityTitle = document.getElementById("modalityTitle_" + compEleIndex + "_" + functionIndex);
	if (functionType == "imaging") {
		modalityTd.style.display = "inline";
		modalityTitle.style.display = "inline";
	} else {
		modalityTd.style.display = "none";
		modalityTitle.style.display = "none";
	}
	return false;
}
function displayAntigenSpecies(parentIndex, childIndex) {
	var type = document.getElementById("targetType_" + parentIndex + "_" + childIndex).value;
	var sdiv = document.getElementById("speciesDiv_" + parentIndex + "_" + childIndex);
	var removeSpan = document.getElementById("removeSpan_" + parentIndex + "_" + childIndex);
	if (type == "antigen") {
		sdiv.style.display = "inline";
	} else {
		sdiv.style.display = "none";
	}
	return false;
}
function radLinkOrUpload(radioIndex, fileIndex) {
	var linkEle = document.getElementById("linkEle_" + fileIndex);
	var loadEle = document.getElementById("loadEle_" + fileIndex);
	var titleEle = document.getElementById("lutitle_" + fileIndex);
	if (radioIndex == 0) {
		loadEle.style.display = "inline";
		linkEle.style.display = "none";
		titleEle.innerHTML = "Upload New File";
	} else {
		loadEle.style.display = "none";
		linkEle.style.display = "inline";
		titleEle.innerHTML = "Enter File URL";
	}
}

/*
 * for chemical association
 */
function getAssociatedElementOptions(compositionTypeId, entityTypeId, compEleId) {
	var compositionType = dwr.util.getValue(compositionTypeId);
	var compEle = document.getElementById(compEleId);
	if (compositionType != "") {
		CompositionManager.getAssociatedElementOptions(compositionType, function (data) {
			dwr.util.removeAllOptions(entityTypeId);
			if (data != null) {
				dwr.util.addOptions(entityTypeId, [""]);
				dwr.util.addOptions(entityTypeId, data, "dataId", "dataDisplayType");
			}
		});
	} else {
		dwr.util.removeAllOptions(entityTypeId);
	}
	if (compositionType != "Nanoparticle Entity") {
		compEle.style.display = "none";
	}
}
function getAssociatedComposingElements(compositionTypeId, entityTypeId, compEleTypeId, compEleId) {
	var compositionType = dwr.util.getValue(compositionTypeId);
	var compEle = document.getElementById(compEleId);
	if (compositionType == "Nanoparticle Entity") {
		var entityId = dwr.util.getValue(entityTypeId);
		if (entityId != "") {
			CompositionManager.getAssociatedComposingElements(entityId, function (data) {
				dwr.util.removeAllOptions(compEleTypeId);
				if (data != null) {
					dwr.util.addOptions(compEleTypeId, [""]);
					dwr.util.addOptions(compEleTypeId, data, "domainComposingElementId", "displayName");
				}
			});
		}
		compEle.style.display = "inline";
	} else {
		dwr.util.removeAllOptions(compEleTypeId);
		compEle.style.display = "none";
	}
	return false;
}
function displayBondType() {
	var type = document.getElementById("assoType").value;
	var btTitleEle = document.getElementById("bondTypeTitle");
	var btLineEle = document.getElementById("bondTypeLine");
	if (type == "attachment") {
		btTitleEle.style.display = "inline";
		btLineEle.style.display = "inline";
	} else {
		btTitleEle.style.display = "none";
		btLineEle.style.display = "none";
	}
}

function setEntityDisplayName(entityTypeId, displayNameEleId) {
	var selectEle = document.getElementById(entityTypeId);
	var selectedName = selectEle.options[selectEle.options.selectedIndex].text;
	document.getElementById(displayNameEleId).value = selectedName;
	// alert(document.getElementById(displayNameEleId).value);
}

/*
 * the following functions using AJAX to display modality dropdown menu in the
 * bodyNanoparticleEntityUpdate.jsp and bodyFunctionUpdate.jsp
 *
 */
/*
function setModalityTypeOptions(compEleIndex, functionIndex) {
	var functionType = dwr.util.getValue("funcType_" + compEleIndex + "_" + functionIndex);
	CompositionManager.getModalityTypeOptions(functionType, function(data) {

			dwr.util.removeAllOptions("modalityType_" + compEleIndex + "_" + functionIndex);
			dwr.util.addOptions("modalityType_" + compEleIndex + "_" + functionIndex, ['']);
    		dwr.util.addOptions("modalityType_" + compEleIndex + "_" + functionIndex, data);
    		dwr.util.addOptions("modalityType_" + compEleIndex + "_" + functionIndex, ['[Other]']);
  	});
}

function setModalityInclude(compEleIndex, functionIndex) {
	var functionType = dwr.util.getValue("funcType_" + compEleIndex + "_" + functionIndex);

	CompositionManager.getModalityIncludePage(compEleIndex, functionIndex, functionType, function(pageData) {

		document.getElementById("modalityTypeTd_" + compEleIndex + "_" + functionIndex).innerHTML = "";
		dwr.util.setValue("modalityTypeTd_" + compEleIndex + "_" + functionIndex, pageData, {escapeHtml:false});

	});

  	if(functionType != "imaging") {
  		document.getElementById("modalityType_" + compEleIndex + "_" + functionIndex).innerHTML =
  			" ";
  	}
}
*/

<commit_msg>added function  to selectively display uploaded file or file URL for composition file<commit_after>
function setEntityInclude(selectEleId, pagePath) {
	var entityType = document.getElementById(selectEleId).value;
	CompositionManager.getEntityIncludePage(entityType, pagePath, populatePage);
}
function populatePage(pageData) {
	if (pageData.length > 0) {
		dwr.util.setValue("entityInclude", pageData, {escapeHtml:false});
	}
}
function getComposingElementOptions(selectEleId) {
	var compFuncTypeValue = dwr.util.getValue(selectEleId);
	CompositionManager.getComposingElementTypeOptions(compFuncTypeValue, function (data) {
		dwr.util.removeAllOptions("compElemType");
		dwr.util.addOptions("compElemType", [""]);
		dwr.util.addOptions("compElemType", data);
		dwr.util.addOptions("compElemType", ["[Other]"]);
	});
}
function getBiopolymerOptions(selectEleId) {
	var compFuncTypeValue = dwr.util.getValue(selectEleId);
	if (compFuncTypeValue == "biopolymer") {
		CompositionManager.getBiopolymerTypeOptions(compFuncTypeValue, function (data) {
			dwr.util.removeAllOptions("biopolymerType");
			dwr.util.addOptions("biopolymerType", [""]);
			dwr.util.addOptions("biopolymerType", data);
			dwr.util.addOptions("biopolymerType", ["[Other]"]);
		});
	}
}
function getWallTypeOptions(selectEleId) {
	var compFuncTypeValue = dwr.util.getValue(selectEleId);
	if (compFuncTypeValue == "carbon nanotube") {
		CompositionManager.getWallTypeOptions(compFuncTypeValue, function (data) {
			dwr.util.removeAllOptions("wallType");
			dwr.util.addOptions("wallType", [""]);
			dwr.util.addOptions("wallType", data);
		});
	}
}
function getNETypeOptions(selectEleId) {
	getBiopolymerOptions(selectEleId);
	getWallTypeOptions(selectEleId);
	getComposingElementOptions(selectEleId);
	setEntityTypeTitle(selectEleId);
}
function getAntibodyTypeOptions(selectEleId) {
	var compFuncTypeValue = dwr.util.getValue(selectEleId);
	if (compFuncTypeValue == "antibody") {
		CompositionManager.getAntibodyTypeOptions(compFuncTypeValue, function (data) {
			dwr.util.removeAllOptions("antibodyType");
			dwr.util.addOptions("antibodyType", [""]);
			dwr.util.addOptions("antibodyType", data);
			dwr.util.addOptions("antibodyType", ["[Other]"]);
		});
	}
}
function getAntibodyIsotypeOptions(selectEleId) {
	var compFuncTypeValue = dwr.util.getValue(selectEleId);
	if (compFuncTypeValue == "antibody") {
		CompositionManager.getAntibodyIsotypeOptions(compFuncTypeValue, function (data) {
			dwr.util.removeAllOptions("antibodyIsotype");
			dwr.util.addOptions("antibodyIsotype", [""]);
			dwr.util.addOptions("antibodyIsotype", data);
			dwr.util.addOptions("antibodyIsotype", ["[Other]"]);
		});
	}
}
function getAntibodySpeciesOptions(selectEleId) {
	var compFuncTypeValue = dwr.util.getValue(selectEleId);
	if (compFuncTypeValue == "antibody") {
		CompositionManager.getAntibodySpeciesOptions(compFuncTypeValue, function (data) {
			dwr.util.removeAllOptions("antibodySpecies");
			dwr.util.addOptions("antibodySpecies", [""]);
			dwr.util.addOptions("antibodySpecies", data);
		});
	}
}
function setEntityTypeTitle(selectEleId) {
	var selectEle = document.getElementById(selectEleId);
	document.getElementById("entityTypeTitle").innerHTML = selectEle.options[selectEle.options.selectedIndex].text;
}
function getFETypeOptions(selectEleId) {
	getBiopolymerOptions(selectEleId);
	getAntibodyTypeOptions(selectEleId);
	getAntibodyIsotypeOptions(selectEleId);
	getAntibodySpeciesOptions(selectEleId);
	setEntityTypeTitle(selectEleId);
}
function displayFEModality(functionIndex) {
	var functionType = document.getElementById("funcType_" + functionIndex).value;
	var modalityDiv = document.getElementById("modalityDiv_" + functionIndex);
	var modalityStrong = document.getElementById("modalityStrong_" + functionIndex);
	if (functionType == "imaging") {
		modalityDiv.style.display = "inline";
		modalityStrong.style.display = "inline";
	} else {
		modalityDiv.style.display = "none";
		modalityStrong.style.display = "none";
	}
	return false;
}
function displayTarget(functionIndex) {
	var functionType = document.getElementById("funcType_" + functionIndex).value;
	var targetSpan = document.getElementById("targetSpan_" + functionIndex);
	var targetDiv = document.getElementById("targetDiv_" + functionIndex);
	if (functionType == "targeting") {
		targetSpan.style.display = "block";
		targetDiv.style.display = "block";
	} else {
		targetSpan.style.display = "none";
		targetDiv.style.display = "none";
	}
	return false;
}
function displayModality(compEleIndex, functionIndex) {
	var functionType = document.getElementById("funcType_" + compEleIndex + "_" + functionIndex).value;
	var modalityTd = document.getElementById("modalityTypeTd_" + compEleIndex + "_" + functionIndex);
	var modalityTitle = document.getElementById("modalityTitle_" + compEleIndex + "_" + functionIndex);
	if (functionType == "imaging") {
		modalityTd.style.display = "inline";
		modalityTitle.style.display = "inline";
	} else {
		modalityTd.style.display = "none";
		modalityTitle.style.display = "none";
	}
	return false;
}
function displayAntigenSpecies(parentIndex, childIndex) {
	var type = document.getElementById("targetType_" + parentIndex + "_" + childIndex).value;
	var sdiv = document.getElementById("speciesDiv_" + parentIndex + "_" + childIndex);
	var removeSpan = document.getElementById("removeSpan_" + parentIndex + "_" + childIndex);
	if (type == "antigen") {
		sdiv.style.display = "inline";
	} else {
		sdiv.style.display = "none";
	}
	return false;
}

function radLinkOrUpload(fileIndex) {
	var linkEle = document.getElementById("link_" + fileIndex);
	var loadEle = document.getElementById("load_" + fileIndex);
	if (document.getElementById("external_" + fileIndex).checked) {
		loadEle.style.display = "inline";
		linkEle.style.display = "none";
	} else {
		loadEle.style.display = "none";
		linkEle.style.display = "inline";
	}
}

/*
 * for chemical association
 */
function getAssociatedElementOptions(compositionTypeId, entityTypeId, compEleId) {
	var compositionType = dwr.util.getValue(compositionTypeId);
	var compEle = document.getElementById(compEleId);
	if (compositionType != "") {
		CompositionManager.getAssociatedElementOptions(compositionType, function (data) {
			dwr.util.removeAllOptions(entityTypeId);
			if (data != null) {
				dwr.util.addOptions(entityTypeId, [""]);
				dwr.util.addOptions(entityTypeId, data, "dataId", "dataDisplayType");
			}
		});
	} else {
		dwr.util.removeAllOptions(entityTypeId);
	}
	if (compositionType != "Nanoparticle Entity") {
		compEle.style.display = "none";
	}
}
function getAssociatedComposingElements(compositionTypeId, entityTypeId, compEleTypeId, compEleId) {
	var compositionType = dwr.util.getValue(compositionTypeId);
	var compEle = document.getElementById(compEleId);
	if (compositionType == "Nanoparticle Entity") {
		var entityId = dwr.util.getValue(entityTypeId);
		if (entityId != "") {
			CompositionManager.getAssociatedComposingElements(entityId, function (data) {
				dwr.util.removeAllOptions(compEleTypeId);
				if (data != null) {
					dwr.util.addOptions(compEleTypeId, [""]);
					dwr.util.addOptions(compEleTypeId, data, "domainComposingElementId", "displayName");
				}
			});
		}
		compEle.style.display = "inline";
	} else {
		dwr.util.removeAllOptions(compEleTypeId);
		compEle.style.display = "none";
	}
	return false;
}
function displayBondType() {
	var type = document.getElementById("assoType").value;
	var btTitleEle = document.getElementById("bondTypeTitle");
	var btLineEle = document.getElementById("bondTypeLine");
	if (type == "attachment") {
		btTitleEle.style.display = "inline";
		btLineEle.style.display = "inline";
	} else {
		btTitleEle.style.display = "none";
		btLineEle.style.display = "none";
	}
}

function setEntityDisplayName(entityTypeId, displayNameEleId) {
	var selectEle = document.getElementById(entityTypeId);
	var selectedName = selectEle.options[selectEle.options.selectedIndex].text;
	document.getElementById(displayNameEleId).value = selectedName;
	// alert(document.getElementById(displayNameEleId).value);
}

/*
 * the following functions using AJAX to display modality dropdown menu in the
 * bodyNanoparticleEntityUpdate.jsp and bodyFunctionUpdate.jsp
 *
 */
/*
function setModalityTypeOptions(compEleIndex, functionIndex) {
	var functionType = dwr.util.getValue("funcType_" + compEleIndex + "_" + functionIndex);
	CompositionManager.getModalityTypeOptions(functionType, function(data) {

			dwr.util.removeAllOptions("modalityType_" + compEleIndex + "_" + functionIndex);
			dwr.util.addOptions("modalityType_" + compEleIndex + "_" + functionIndex, ['']);
    		dwr.util.addOptions("modalityType_" + compEleIndex + "_" + functionIndex, data);
    		dwr.util.addOptions("modalityType_" + compEleIndex + "_" + functionIndex, ['[Other]']);
  	});
}

function setModalityInclude(compEleIndex, functionIndex) {
	var functionType = dwr.util.getValue("funcType_" + compEleIndex + "_" + functionIndex);

	CompositionManager.getModalityIncludePage(compEleIndex, functionIndex, functionType, function(pageData) {

		document.getElementById("modalityTypeTd_" + compEleIndex + "_" + functionIndex).innerHTML = "";
		dwr.util.setValue("modalityTypeTd_" + compEleIndex + "_" + functionIndex, pageData, {escapeHtml:false});

	});

  	if(functionType != "imaging") {
  		document.getElementById("modalityType_" + compEleIndex + "_" + functionIndex).innerHTML =
  			" ";
  	}
}
*/

<|endoftext|>


<commit_before>'use strict';

var Proto = require('uberproto');
var errors = require('feathers-errors').types;
var _ = require('lodash');

// TODO (EK): Should we allow the ability to specify ascending
// or descending order for sort and/or order functions? Should
// you be able to sort by multiple attributes?
//
// ie. { sort: ['name', 'birthday'], order: 'ascending'}
var filters = {
  sort: function (values, param) {
    return _.sortBy(values, function (item) {
      return item[param];
    });
  },
  order: function (values) {
    return values.reverse();
  },
  skip: function (values, param) {
    return values.slice(param);
  },
  limit: function (values, param) {
    return values.slice(0, param);
  }
};

var MemoryService = Proto.extend({
  init: function (options) {
    options = options || {};

    this.type = 'memory';
    this._id = options.idField || 'id';
    this._uId = options.startId || 0;
    this.store = options.store || {};
  },

  find: function (params, cb) {
    if (_.isFunction(params)){
      cb = params;
      params = {};
    }

    params.query = params.query || {};

    var values = _.values(this.store);

    _.each(filters, function(handler, name) {
      values = params.query[name] ? handler(values, params.query[name]) : values;
    });

    cb(null, values);
  },

  // TODO: This should support more than id
  get: function (id, params, cb) {
    if (_.isFunction(params)){
      cb = params;
      params = {};
    }

    if (id in this.store) {
      return cb(null, this.store[id]);
    }
    cb(new errors.NotFound('Could not find record', { id: id }));
  },

  create: function (data, params, cb) {
    if (_.isFunction(params)){
      cb = params;
    }

    var id = data[this._id] || this._uId++;
    data[this._id] = id;

    if (this.store[id]){
      return cb(new errors.Conflict('A record with id: ' + id + ' already exists'));
    }

    this.store[id] = data;

    cb(null, data);
  },

  update: function (id, data, params, cb) {
    if (_.isFunction(params)){
      cb = params;
    }

    var self = this;
    if (id in this.store) {
      _.each(_.omit(data, this._id), function(value, key){
        self.store[id][key] = value;
      });

      return cb(null, this.store[id]);
    }

    cb(new errors.NotFound('Could not find record', { id: id }));
  },

  patch: function(id, data, params, cb) {
    if (_.isFunction(params)){
      cb = params;
    }

    var self = this;
    if (id in this.store) {
      _.each(_.omit(data, this._id), function(value, key){
        self.store[id][key] = value;
      });

      return cb(null, this.store[id]);
    }

    cb(new errors.NotFound('Could not find record', { id: id }));
  },

  remove: function (id, params, cb) {
    if (_.isFunction(params)){
      cb = params;
    }

    if (id in this.store) {
      var deleted = this.store[id];
      delete this.store[id];

      return cb(null, deleted);
    }

    cb(new errors.NotFound('Could not find record', { id: id }));
  }
});

module.exports = MemoryService;
<commit_msg>exporting the module properly<commit_after>'use strict';

var Proto = require('uberproto');
var errors = require('feathers-errors').types;
var _ = require('lodash');

// TODO (EK): Should we allow the ability to specify ascending
// or descending order for sort and/or order functions? Should
// you be able to sort by multiple attributes?
//
// ie. { sort: ['name', 'birthday'], order: 'ascending'}
var filters = {
  sort: function (values, param) {
    return _.sortBy(values, function (item) {
      return item[param];
    });
  },
  order: function (values) {
    return values.reverse();
  },
  skip: function (values, param) {
    return values.slice(param);
  },
  limit: function (values, param) {
    return values.slice(0, param);
  }
};

var MemoryService = Proto.extend({
  init: function (options) {
    options = options || {};

    this.type = 'memory';
    this._id = options.idField || 'id';
    this._uId = options.startId || 0;
    this.store = options.store || {};
  },

  find: function (params, cb) {
    if (_.isFunction(params)){
      cb = params;
      params = {};
    }

    params.query = params.query || {};

    var values = _.values(this.store);

    _.each(filters, function(handler, name) {
      values = params.query[name] ? handler(values, params.query[name]) : values;
    });

    cb(null, values);
  },

  // TODO: This should support more than id
  get: function (id, params, cb) {
    if (_.isFunction(params)){
      cb = params;
      params = {};
    }

    if (id in this.store) {
      return cb(null, this.store[id]);
    }
    cb(new errors.NotFound('Could not find record', { id: id }));
  },

  create: function (data, params, cb) {
    if (_.isFunction(params)){
      cb = params;
    }

    var id = data[this._id] || this._uId++;
    data[this._id] = id;

    if (this.store[id]){
      return cb(new errors.Conflict('A record with id: ' + id + ' already exists'));
    }

    this.store[id] = data;

    cb(null, data);
  },

  update: function (id, data, params, cb) {
    if (_.isFunction(params)){
      cb = params;
    }

    var self = this;
    if (id in this.store) {
      _.each(_.omit(data, this._id), function(value, key){
        self.store[id][key] = value;
      });

      return cb(null, this.store[id]);
    }

    cb(new errors.NotFound('Could not find record', { id: id }));
  },

  patch: function(id, data, params, cb) {
    if (_.isFunction(params)){
      cb = params;
    }

    var self = this;
    if (id in this.store) {
      _.each(_.omit(data, this._id), function(value, key){
        self.store[id][key] = value;
      });

      return cb(null, this.store[id]);
    }

    cb(new errors.NotFound('Could not find record', { id: id }));
  },

  remove: function (id, params, cb) {
    if (_.isFunction(params)){
      cb = params;
    }

    if (id in this.store) {
      var deleted = this.store[id];
      delete this.store[id];

      return cb(null, deleted);
    }

    cb(new errors.NotFound('Could not find record', { id: id }));
  }
});

module.exports = function(options) {
  return Proto.create.call(MemoryService, options);
};

module.exports.Service = MemoryService;
<|endoftext|>


<commit_before>/*jslint node: true*/
var assert = require('chai').assert;
var fs = require('fs');
var $rdf = require('rdflib');
var request = require('request');
var S = require('string');
var supertest = require('supertest');
var async = require('async');

// Helper functions for the FS
var rm = require('./test-utils').rm;
var write = require('./test-utils').write;
var cp = require('./test-utils').cp;
var read = require('./test-utils').read;

var ldnode = require('../index');
var ACL = require('../lib/acl').ACL;
var ns = require('../lib/vocab/ns.js').ns;

describe('Error page tests', function() {
    var errorAddress = 'http://localhost:3457/test/';

    var errorLdp = ldnode.createServer({
        root: __dirname + '/resources',
    });
    errorLdp.listen(3457);

    var errorServer = supertest(errorAddress);

    // Instance of server with error pages flag set to false
    var noErrorAddress = 'http://localhost:3458/test/';

    var noErrorLdp = ldnode.createServer({
        root: __dirname + '/resources',
        noErrorPages: true
    });
    noErrorLdp.listen(3458);

    var noErrorServer = supertest(errorAddress);

    describe('Error page test', function() {
        it('Should return 404 custom page if flag set to true',
           function(done) {
               errorServer.get('/non-existent-file.html')
                   .expect(/404 Error Page/)
                   .expect(404, done);
           });
        it('Should return 404 default page if flag set to false',
           function(done) {
               function isDefaultErrorPage(customText) {
                   var handler = function (res) {
                       if (res.text.match(customText)){
                           console.log("Not default text");
                       }
                   };
                   return handler;
               }
               noErrorServer.get('/non-existent-file.html')
                   .expect(isDefaultErrorPage('404 Error Page'))
                   .expect(404, done);
           });
    });
});
<commit_msg>Tests now read the file instead of comparing againts fixed string<commit_after>/*jslint node: true*/
var assert = require('chai').assert;
var fs = require('fs');
var $rdf = require('rdflib');
var request = require('request');
var S = require('string');
var supertest = require('supertest');
var async = require('async');

// Helper functions for the FS
var rm = require('./test-utils').rm;
var write = require('./test-utils').write;
var cp = require('./test-utils').cp;
var read = require('./test-utils').read;

var ldnode = require('../index');
var ACL = require('../lib/acl').ACL;
var ns = require('../lib/vocab/ns.js').ns;

describe('Error page tests', function() {
    var errorAddress = 'http://localhost:3457/test/';

    var errorLdp = ldnode.createServer({
        root: __dirname + '/resources',
    });
    errorLdp.listen(3457);

    var errorServer = supertest(errorAddress);

    // Instance of server with error pages flag set to false
    var noErrorAddress = 'http://localhost:3458/test/';

    var noErrorLdp = ldnode.createServer({
        root: __dirname + '/resources',
        noErrorPages: true
    });
    noErrorLdp.listen(3458);

    var noErrorServer = supertest(errorAddress);

    describe('Error page test', function() {
        var file404 = 'errorPages/404.html';
        function defaultErrorPage(filepath, expected) {
            var handler = function (res) {
                var errorFile = read(filepath);
                if (res.text === errorFile && !expected){
                    console.log("Not default text");
                }
            };
            return handler;
        }
        it('Should return 404 custom page if flag set to true',
           function(done) {
               errorServer.get('non-existent-file.html')
                   .expect(defaultErrorPage(file404, true))
                   .expect(404, done);
           });
        it('Should return 404 default page if flag set to false',
           function(done) {
               noErrorServer.get('non-existent-file.html')
                   .expect(defaultErrorPage(file404, false))
                   .expect(404, done);
           });
    });
});
<|endoftext|>


<commit_before>var _ = require('underscore'),
    fu = require('./fileUtil'),
    path = require('path'),
    vm = require('vm');

/**
 * Reads the RAW JSON for a lumbar config file.
 */
exports.readConfig = function(lumbarFile) {
  try {
    var data = '(' + fu.readFileSync(lumbarFile) + ')';

    // Yes this is totally unsafe, but we don't want the strictness of pure JSON for our
    // config files and if you are running an untrusted lumbar file you already have concerns.
    return vm.runInThisContext(data, lumbarFile);
  } catch (err) {
    var line;
    try {
      var esprima = require('esprima');
      console.log(err.stack, esprima.parse(data));
    } catch (err) {
      if (err.lineNumber) {
        line = ':' + err.lineNumber;
      }
    }
    throw new Error('Failed to load config ' + lumbarFile + line + ': ' + err);
  }
};

/**
 *
 * @name load
 * @function This function loads the lumbar JSON file, and returns
 *  helper methods associated with accessing its specific data.
 * @param {string} lumbarFile the location of the lumbar file.
 * @return {Object}
 */
exports.load = function(lumbarFile) {
  fu.lookupPath('');

  var config = exports.readConfig(lumbarFile);
  fu.lookupPath(path.dirname(lumbarFile));

  return exports.create(config);
};

exports.create = function(config) {
  var packageList, moduleList;

  function loadPackageList() {
    if (!config.packages) {
      config.packages = { web: { name: '' } };
    }

    packageList = _.keys(config.packages);
  }
  function loadModuleList() {
    if (!config.modules) {
      throw new Error('No modules object defined: ' + JSON.stringify(config, undefined, 2));
    }
    moduleList = _.keys(config.modules);
  }

  loadPackageList();
  loadModuleList();

  return {
    /** @typedef {Object} The raw lumbar file as a JSON object. */
    attributes: config,
    loadPrefix: function() {
      return config.loadPrefix || '';
    },

    /**
     *
     * @name packageList
     * @function This function returns the list of packages found
     *  in the lumbar file.
     * @return {Array.<Object>} array of package(s).
     */
    packageList: function() {
      return packageList;
    },

    /**
     *
     * @name combineModules
     * @function This functions checks to see if the package, pkg,
     *  is going to combine all its modules or not.
     * @param {string} pkg the name of the package
     * @return {boolean} is this package destined to be combined?
     */
    combineModules: function(pkg) {
      if (config && config.packages && config.packages[pkg]) {
        return config.packages[pkg].combine;
      }
      return false;
    },
    platformList: function(pkg) {
      if (!pkg) {
        return config.platforms || [''];
      } else {
        if (config.packages[pkg]) {
          return config.packages[pkg].platforms || this.platformList();
        }
        return this.platformList();
      }
    },

    moduleList: function(pkg) {
      return (config.packages[pkg] || {}).modules || _.keys(config.modules);
    },

    module: function(name) {
      var ret = config.modules[name];
      if (ret) {
        ret.name = name;
      }
      return ret;
    },
    isAppModule: function(module) {
      var app = config.application;
      return (app && app.module) === (module.name || module);
    },
    scopedAppModuleName: function(module) {
      var app = config.application;
      if (this.isAppModule(module)) {
        return 'module.exports';
      } else {
        var app = config.application;
        return app && app.name;
      }
    },

    routeList: function(module) {
      return config.modules[module].routes;
    },

    serialize: function() {
      function objectClone(object) {
        var clone = object;

        if (object && object.serialize) {
          // Allow specialized objects to handle themselves
          clone = object.serialize();
        } else if (_.isArray(object)) {
          clone = _.map(object, objectClone);
        } else if (_.isObject(object)) {
          clone = {};
          _.each(object, function(value, name) {
            clone[name] = objectClone(value);
          });
        }

        // Collapse simple resources
        if (clone.src && _.keys(clone).length === 1) {
          clone = clone.src;
        }

        return clone;
      }

      return objectClone(this.attributes);
    }
  };
};

<commit_msg>Handle missing keys on clone<commit_after>var _ = require('underscore'),
    fu = require('./fileUtil'),
    path = require('path'),
    vm = require('vm');

/**
 * Reads the RAW JSON for a lumbar config file.
 */
exports.readConfig = function(lumbarFile) {
  try {
    var data = '(' + fu.readFileSync(lumbarFile) + ')';

    // Yes this is totally unsafe, but we don't want the strictness of pure JSON for our
    // config files and if you are running an untrusted lumbar file you already have concerns.
    return vm.runInThisContext(data, lumbarFile);
  } catch (err) {
    var line;
    try {
      var esprima = require('esprima');
      console.log(err.stack, esprima.parse(data));
    } catch (err) {
      if (err.lineNumber) {
        line = ':' + err.lineNumber;
      }
    }
    throw new Error('Failed to load config ' + lumbarFile + line + ': ' + err);
  }
};

/**
 *
 * @name load
 * @function This function loads the lumbar JSON file, and returns
 *  helper methods associated with accessing its specific data.
 * @param {string} lumbarFile the location of the lumbar file.
 * @return {Object}
 */
exports.load = function(lumbarFile) {
  fu.lookupPath('');

  var config = exports.readConfig(lumbarFile);
  fu.lookupPath(path.dirname(lumbarFile));

  return exports.create(config);
};

exports.create = function(config) {
  var packageList, moduleList;

  function loadPackageList() {
    if (!config.packages) {
      config.packages = { web: { name: '' } };
    }

    packageList = _.keys(config.packages);
  }
  function loadModuleList() {
    if (!config.modules) {
      throw new Error('No modules object defined: ' + JSON.stringify(config, undefined, 2));
    }
    moduleList = _.keys(config.modules);
  }

  loadPackageList();
  loadModuleList();

  return {
    /** @typedef {Object} The raw lumbar file as a JSON object. */
    attributes: config,
    loadPrefix: function() {
      return config.loadPrefix || '';
    },

    /**
     *
     * @name packageList
     * @function This function returns the list of packages found
     *  in the lumbar file.
     * @return {Array.<Object>} array of package(s).
     */
    packageList: function() {
      return packageList;
    },

    /**
     *
     * @name combineModules
     * @function This functions checks to see if the package, pkg,
     *  is going to combine all its modules or not.
     * @param {string} pkg the name of the package
     * @return {boolean} is this package destined to be combined?
     */
    combineModules: function(pkg) {
      if (config && config.packages && config.packages[pkg]) {
        return config.packages[pkg].combine;
      }
      return false;
    },
    platformList: function(pkg) {
      if (!pkg) {
        return config.platforms || [''];
      } else {
        if (config.packages[pkg]) {
          return config.packages[pkg].platforms || this.platformList();
        }
        return this.platformList();
      }
    },

    moduleList: function(pkg) {
      return (config.packages[pkg] || {}).modules || _.keys(config.modules);
    },

    module: function(name) {
      var ret = config.modules[name];
      if (ret) {
        ret.name = name;
      }
      return ret;
    },
    isAppModule: function(module) {
      var app = config.application;
      return (app && app.module) === (module.name || module);
    },
    scopedAppModuleName: function(module) {
      var app = config.application;
      if (this.isAppModule(module)) {
        return 'module.exports';
      } else {
        var app = config.application;
        return app && app.name;
      }
    },

    routeList: function(module) {
      return config.modules[module].routes;
    },

    serialize: function() {
      function objectClone(object) {
        var clone = object;

        if (object && object.serialize) {
          // Allow specialized objects to handle themselves
          clone = object.serialize();
        } else if (_.isArray(object)) {
          clone = _.map(object, objectClone);
        } else if (_.isObject(object)) {
          clone = {};
          _.each(object, function(value, name) {
            clone[name] = objectClone(value);
          });
        }

        // Collapse simple resources
        if (clone && clone.src && _.keys(clone).length === 1) {
          clone = clone.src;
        }

        return clone;
      }

      return objectClone(this.attributes);
    }
  };
};

<|endoftext|>