<commit_before>app.factory('QueryService', ['$resource', '$injector', '$q', '$filter', 'PollingService', 'DownloadService', 'TableService', 'BrowserService', function($resource, $injector, $q, $filter, PollingService, DownloadService, TableService, BrowserService) {

    /* get the base url */

    var baseurl = angular.element('meta[name="baseurl"]').attr('content');

    /* configure resources */

    var resources = {
        status: $resource(baseurl + 'query/api/status/'),
        forms: $resource(baseurl + 'query/api/forms/'),
        dropdowns: $resource(baseurl + 'query/api/dropdowns/'),
        jobs: $resource(baseurl + 'query/api/jobs/:id/:detail_route/'),
        examples: $resource(baseurl + 'query/api/examples/user/'),
        queues: $resource(baseurl + 'query/api/queues/'),
        querylanguages: $resource(baseurl + 'query/api/querylanguages/'),
        databases: $resource(baseurl + 'metadata/api/databases/user/'),
        functions: $resource(baseurl + 'metadata/api/functions/user/'),
    };

    /* initialise the browser service */

    BrowserService.init('databases', ['databases', 'tables', 'columns'])
    BrowserService.init('columns', ['columns'], true)
    BrowserService.init('functions', ['functions'])
    BrowserService.init('examples', ['examples'])

    /* create the query service */

    var service = {
        forms: {},
        dropdowns: {},
        values: {},
        errors: {}
    };

    service.init = function() {
        // fetch queues,  query languages and then load forms
        service.queues = resources.queues.query();
        service.query_languages = resources.querylanguages.query();

        $q.all([service.queues.$promise, service.query_languages.$promise]).then(function(){
            service.active_queue = service.queues[0].id;

            resources.forms.query(function(response) {
                angular.forEach(response, function(form) {
                    service.forms[form.key] = $injector.get(form.form_service);
                });

                // activate first form
                service.forms[response[0].key].activate();
            });
        });

        // load dropdowns
        resources.dropdowns.query(function(response) {
            angular.forEach(response, function(dropdown) {
                service.dropdowns[dropdown.key] = $injector.get(dropdown.dropdown_service);
                service.dropdowns[dropdown.key].options = dropdown.options;
            });
        });

        // fetch status
        service.fetchStatus();

        // fetch functions
        resources.functions.query(function(response) {
            BrowserService.render('functions', response);
        });

        // fetch examples
        resources.examples.query(function(response) {
            BrowserService.render('examples', response);
        });

        // fetch databases
        resources.databases.query(function(response) {
            service.databases = response;

            service.columns = []
            angular.forEach(service.databases, function(database) {
                angular.forEach(database.tables, function(table) {
                    angular.forEach(table.columns, function(column) {
                        var column_copy = angular.copy(column);
                        column_copy.name = database.name + '.' + table.name + '.' + column.name;
                        service.columns.push(column_copy);
                    });
                });
            });

            // load user database when databases have been fetched
            service.fetchUserDatabase();
        });

        // fetch joblist
        service.fetchJobs();

        // activate overview tab
        service.tab = 'overview';

        // start the polling service
        PollingService.init();
        PollingService.register('status', service.fetchStatus);
        PollingService.register('jobs', service.fetchJobs);
        PollingService.register('database', service.fetchUserDatabase);

        // load the download service
        service.downloads = DownloadService;
    };

    service.fetchStatus = function() {
        return resources.status.query(function(response) {
            service.status = response[0];
        }).$promise;
    };

    service.fetchUserDatabase = function() {
        return resources.jobs.query({
            'detail_route': 'tables'
        }, function(response) {
            var user_database = response[0];

            var user_columns = [];
            angular.forEach(user_database.tables, function(table) {
                angular.forEach(table.columns, function(column) {
                    var column_copy = angular.copy(column);
                    column_copy.name = user_database.name + '.' + table.name + '.' + column.name;
                    user_columns.push(column_copy);
                });
            });

            BrowserService.render('databases', service.databases.concat(user_database));
            BrowserService.render('columns', service.columns.concat(user_columns));
        }).$promise;
    }

    service.fetchJobs = function() {
        return resources.jobs.query(function(response) {
            service.jobs = response;

            if (service.job) {
                // get the phase of the current job in the jobs list
                var phase = $filter('filter')(service.jobs, {'id': service.job.id})[0].phase;

                // if the phase has changed, fetch it again
                if (phase != service.job.phase) {
                    service.fetchJob(service.job);
                }
            }

        }).$promise;
    };

    service.fetchJob = function(job) {
        return resources.jobs.get({id: job.id}, function(response) {
            service.job = response;
            service.job.time_queue = moment.duration(moment(service.job.start_time) - moment(service.job.creation_time)).seconds();
            service.job.time_query = moment.duration(moment(service.job.end_time) - moment(service.job.start_time)).seconds();

            // get the phase of the current job in the jobs list
            var phase = $filter('filter')(service.jobs, {'id': service.job.id})[0].phase;

            // if the phase has changed, fetch the job list again
            if (phase != service.job.phase) {
                service.fetchJobs();
            }

        }).$promise;
    };

    service.activateForm = function(key) {
        service.form = key;
        service.job = null;
    };

    service.activateJob = function(job) {
        service.form = null;
        service.fetchJob(job).then(function() {

            if (service.job.phase == 'COMPLETED') {
                TableService.init(service.job.database_name, service.job.table_name);
            } else {
                // activate overview tab
                service.tab = 'overview';

                // empty table
                TableService.init();
            }

            CodeMirror.runMode(service.job.query, "text/x-mariadb", angular.element('#query')[0]);
            CodeMirror.runMode(service.job.native_query, "text/x-mariadb", angular.element('#native-query')[0]);
            CodeMirror.runMode(service.job.actual_query, "text/x-mariadb", angular.element('#actual-query')[0]);
        });
    };

    service.submitJob = function(values) {
        values = angular.extend({}, values, {
            'queue': service.active_queue
        });

        return resources.jobs.save(values).$promise.then(function(job) {
            service.fetchStatus();
            service.fetchJobs();
            service.activateJob(job);
        });
    };

    service.showModal = function(modal, job) {
        service.errors = {};

        if (angular.isDefined(job)) {
            service.values = job;
        }

        $('#' + modal + '-modal').modal('show');
    };

    service.renameJob = function() {
        resources.jobs.update({id: service.values.id}, service.values).$promise.then(function() {
            service.fetchJobs();
            $('.modal').modal('hide');
        }, function(response) {
            service.errors = response.data;
        });
    };

    service.abortJob = function() {
        resources.jobs.update({id: service.values.id, detail_route: 'abort'}, {}, function() {
            service.fetchStatus();
            service.fetchJobs();
            $('.modal').modal('hide');
        });
    };

    service.removeJob = function() {
        var index = service.jobs.indexOf($filter('filter')(service.jobs, {'id': service.job.id})[0]);

        var next_job;
        if (index == 0) {
            next_job = service.jobs[1];
        } else {
            next_job = service.jobs[index - 1];
        }

        resources.jobs.delete({id: service.values.id}, function() {
            service.fetchStatus();
            service.fetchJobs();
            service.activateJob(next_job);
            $('.modal').modal('hide');
        });
    };

    return service;

}]);
<commit_msg>fix submitJob in query angular app<commit_after>app.factory('QueryService', ['$resource', '$injector', '$q', '$filter', 'PollingService', 'DownloadService', 'TableService', 'BrowserService', function($resource, $injector, $q, $filter, PollingService, DownloadService, TableService, BrowserService) {

    /* get the base url */

    var baseurl = angular.element('meta[name="baseurl"]').attr('content');

    /* configure resources */

    var resources = {
        status: $resource(baseurl + 'query/api/status/'),
        forms: $resource(baseurl + 'query/api/forms/'),
        dropdowns: $resource(baseurl + 'query/api/dropdowns/'),
        jobs: $resource(baseurl + 'query/api/jobs/:id/:detail_route/'),
        examples: $resource(baseurl + 'query/api/examples/user/'),
        queues: $resource(baseurl + 'query/api/queues/'),
        querylanguages: $resource(baseurl + 'query/api/querylanguages/'),
        databases: $resource(baseurl + 'metadata/api/databases/user/'),
        functions: $resource(baseurl + 'metadata/api/functions/user/'),
    };

    /* initialise the browser service */

    BrowserService.init('databases', ['databases', 'tables', 'columns'])
    BrowserService.init('columns', ['columns'], true)
    BrowserService.init('functions', ['functions'])
    BrowserService.init('examples', ['examples'])

    /* create the query service */

    var service = {
        forms: {},
        dropdowns: {},
        values: {},
        errors: {}
    };

    service.init = function() {
        // fetch queues,  query languages and then load forms
        service.queues = resources.queues.query();
        service.query_languages = resources.querylanguages.query();

        $q.all([service.queues.$promise, service.query_languages.$promise]).then(function(){
            service.active_queue = service.queues[0].id;

            resources.forms.query(function(response) {
                angular.forEach(response, function(form) {
                    service.forms[form.key] = $injector.get(form.form_service);
                });

                // activate first form
                service.forms[response[0].key].activate();
            });
        });

        // load dropdowns
        resources.dropdowns.query(function(response) {
            angular.forEach(response, function(dropdown) {
                service.dropdowns[dropdown.key] = $injector.get(dropdown.dropdown_service);
                service.dropdowns[dropdown.key].options = dropdown.options;
            });
        });

        // fetch status
        service.fetchStatus();

        // fetch functions
        resources.functions.query(function(response) {
            BrowserService.render('functions', response);
        });

        // fetch examples
        resources.examples.query(function(response) {
            BrowserService.render('examples', response);
        });

        // fetch databases
        resources.databases.query(function(response) {
            service.databases = response;

            service.columns = []
            angular.forEach(service.databases, function(database) {
                angular.forEach(database.tables, function(table) {
                    angular.forEach(table.columns, function(column) {
                        var column_copy = angular.copy(column);
                        column_copy.name = database.name + '.' + table.name + '.' + column.name;
                        service.columns.push(column_copy);
                    });
                });
            });

            // load user database when databases have been fetched
            service.fetchUserDatabase();
        });

        // fetch joblist
        service.fetchJobs();

        // activate overview tab
        service.tab = 'overview';

        // start the polling service
        PollingService.init();
        PollingService.register('status', service.fetchStatus);
        PollingService.register('jobs', service.fetchJobs);
        PollingService.register('database', service.fetchUserDatabase);

        // load the download service
        service.downloads = DownloadService;
    };

    service.fetchStatus = function() {
        return resources.status.query(function(response) {
            service.status = response[0];
        }).$promise;
    };

    service.fetchUserDatabase = function() {
        return resources.jobs.query({
            'detail_route': 'tables'
        }, function(response) {
            var user_database = response[0];

            var user_columns = [];
            angular.forEach(user_database.tables, function(table) {
                angular.forEach(table.columns, function(column) {
                    var column_copy = angular.copy(column);
                    column_copy.name = user_database.name + '.' + table.name + '.' + column.name;
                    user_columns.push(column_copy);
                });
            });

            BrowserService.render('databases', service.databases.concat(user_database));
            BrowserService.render('columns', service.columns.concat(user_columns));
        }).$promise;
    }

    service.fetchJobs = function() {
        return resources.jobs.query(function(response) {
            service.jobs = response;

            if (service.job) {
                // get the phase of the current job in the jobs list
                var phase = $filter('filter')(service.jobs, {'id': service.job.id})[0].phase;

                // if the phase has changed, fetch it again
                if (phase != service.job.phase) {
                    service.fetchJob(service.job);
                }
            }

        }).$promise;
    };

    service.fetchJob = function(job) {
        return resources.jobs.get({id: job.id}, function(response) {
            service.job = response;
            service.job.time_queue = moment.duration(moment(service.job.start_time) - moment(service.job.creation_time)).seconds();
            service.job.time_query = moment.duration(moment(service.job.end_time) - moment(service.job.start_time)).seconds();

            // get the current job in the jobs list
            var jobs_job = $filter('filter')(service.jobs, {'id': service.job.id})[0]

            if (angular.isUndefined(jobs_job) || jobs_job.phase != service.job.phase) {
                // if the phase has changed, fetch the job list again
                service.fetchJobs();
            }
        }).$promise;
    };

    service.activateForm = function(key) {
        service.form = key;
        service.job = null;
    };

    service.activateJob = function(job) {
        service.form = null;
        service.fetchJob(job).then(function() {
            if (service.job.phase == 'COMPLETED') {
                TableService.init(service.job.database_name, service.job.table_name);
            } else {
                // activate overview tab
                service.tab = 'overview';

                // empty table
                TableService.init();
            }

            CodeMirror.runMode(service.job.query, "text/x-mariadb", angular.element('#query')[0]);
            CodeMirror.runMode(service.job.native_query, "text/x-mariadb", angular.element('#native-query')[0]);
            CodeMirror.runMode(service.job.actual_query, "text/x-mariadb", angular.element('#actual-query')[0]);
        });
    };

    service.submitJob = function(values) {
        values = angular.extend({}, values, {
            'queue': service.active_queue
        });

        return resources.jobs.save(values).$promise.then(function(job) {
            service.fetchStatus();
            service.activateJob(job);
        });
    };

    service.showModal = function(modal, job) {
        service.errors = {};

        if (angular.isDefined(job)) {
            service.values = job;
        }

        $('#' + modal + '-modal').modal('show');
    };

    service.renameJob = function() {
        resources.jobs.update({id: service.values.id}, service.values).$promise.then(function() {
            service.fetchJobs();
            $('.modal').modal('hide');
        }, function(response) {
            service.errors = response.data;
        });
    };

    service.abortJob = function() {
        resources.jobs.update({id: service.values.id, detail_route: 'abort'}, {}, function() {
            service.fetchStatus();
            service.fetchJobs();
            $('.modal').modal('hide');
        });
    };

    service.removeJob = function() {
        var index = service.jobs.indexOf($filter('filter')(service.jobs, {'id': service.job.id})[0]);

        var next_job;
        if (index == 0) {
            next_job = service.jobs[1];
        } else {
            next_job = service.jobs[index - 1];
        }

        resources.jobs.delete({id: service.values.id}, function() {
            service.fetchStatus();
            service.fetchJobs();
            service.activateJob(next_job);
            $('.modal').modal('hide');
        });
    };

    return service;

}]);
<|endoftext|>


<commit_before>angular.module("routes", []).service('routes', ['$interpolate', function($interpolate) {
    var routes = {
        helpTextSearch: '/help/text-search/',
        contactUs: '/contact',
        submitQuery: '/export/submit-query',
        resultsPage: '/export/results',
        rnaView: '/rna/{{ upi }}',
        rnaViewWithTaxid: '/rna/{{upi}}/{{ taxid }}',
        apiPublicationsView: '/api/v1/rna/{{ upi }}/publications/{{ taxid }}',
        apiRnaView: '/api/v1/rna/{{ upi }}',
        apiGenomeLocationsView: '/api/v1/rna/{{ upi }}/genome-locations/{{ taxid }}',
        apiRfamHitsView: '/api/v1/rna/{{ upi }}/rfam-hits/{{ taxid }}',
        apiProteinTargetsView: '/api/v1/rna/{{ upi }}/protein-targets/{{ taxid }}',
        apiLncrnaTargetsView: '/api/v1/rna/{{ upi }}/lncrna-targets/{{ taxid }}',
        apiSequenceFeaturesView: '/api/v1/rna/{{ upi }}/sequence-features/{{ taxid }}',
        lineageView: '/rna/{{ upi }}/lineage',
        expertDbsApi: '/api/v1/expert-dbs/{{ expertDbName }}',
        expertDbStatsApi: '/api/v1/expert-db-stats/{{ expertDbName }}',
        textSearch: 'search',
        expertDbLogo: '/static/img/expert-db-logos/{{ expertDbName }}.png',
        apiSecondaryStructuresView: '/api/v1/rna/{{ upi }}/2d/{{ taxid }}',
        sequenceSearchSubmitJob: '/sequence-search/submit-job',
        sequenceSearchJobStatus: '/sequence-search/job-status/{{ jobId }}',
        sequenceSearchResults: '/sequence-search/job-results/{{ jobId }}',
        sequenceSearchInfernalJobStatus: '/sequence-search/infernal-job-status/{{ jobId }}',
        sequenceSearchInfernalResults: '/sequence-search/infernal-results/{{ jobId }}',
        apiEnsemblComparaView: '/api/v1/rna/{{ upi }}/ensembl-compara/{{ taxid }}',
        genomesApi: '/api/v1/genomes/{{ ensemblAssembly }}',
        proxy: '/api/internal/proxy?url={{ url }}',
        ebiSearch:
            '{{ ebiBaseUrl }}' +
            '?query={{ query }}' +
            '&format=json' +
            '&hlfields={{ hlfields }}' +
            '&facetcount={{ facetcount }}' +
            '&facetfields={{ facetfields }}' +
            '&facetdepth=15' +
            '&size={{ pagesize }}' +
            '&start={{ start }}' +
            '&sort={{ sort }}' +
            '&hlpretag=' +
            '&hlposttag='
        ,
        ebiMd5Lookup:
            '{{ ebiBaseUrl }}' +
            '?query={{ md5 }}' +
            '&fields=description' +
            '&format=json' +
            '&sort=boost:descending'
        ,
        ebiAutocomplete: 'http://www.ebi.ac.uk/ebisearch/ws/rest/RNAcentral/autocomplete?term={{ query }}&format=json',
        apiGoTermsView: '/api/v1/rna/{{ upi }}/go-annotations/{{ taxid }}',
        quickGoSummaryPage: 'https://www.ebi.ac.uk/QuickGO/term/{{ term_id }}',
        quickGoChart: 'https://www.ebi.ac.uk/QuickGO/services/ontology/{{ ontology }}/terms/{{ term_ids }}/chart?base64=true',
    };

    // apply $interpolate to each route template expression
    return Object.keys(routes)
          .map(function(key) { var output = {}; output[key] = $interpolate(routes[key]); return output })
          .reduce(function(result, keyValue ) { return _.extend(result, keyValue) } );
}]);
<commit_msg>Fix typo<commit_after>angular.module("routes", []).service('routes', ['$interpolate', function($interpolate) {
    var routes = {
        helpTextSearch: '/help/text-search/',
        contactUs: '/contact',
        submitQuery: '/export/submit-query',
        resultsPage: '/export/results',
        rnaView: '/rna/{{ upi }}',
        rnaViewWithTaxid: '/rna/{{upi}}/{{ taxid }}',
        apiPublicationsView: '/api/v1/rna/{{ upi }}/publications/{{ taxid }}',
        apiRnaView: '/api/v1/rna/{{ upi }}',
        apiGenomeLocationsView: '/api/v1/rna/{{ upi }}/genome-locations/{{ taxid }}',
        apiRfamHitsView: '/api/v1/rna/{{ upi }}/rfam-hits/{{ taxid }}',
        apiProteinTargetsView: '/api/v1/rna/{{ upi }}/protein-targets/{{ taxid }}',
        apiLncrnaTargetsView: '/api/v1/rna/{{ upi }}/lncrna-targets/{{ taxid }}',
        apiSequenceFeaturesView: '/api/v1/rna/{{ upi }}/sequence-features/{{ taxid }}',
        lineageView: '/rna/{{ upi }}/lineage',
        expertDbsApi: '/api/v1/expert-dbs/{{ expertDbName }}',
        expertDbStatsApi: '/api/v1/expert-db-stats/{{ expertDbName }}',
        textSearch: 'search',
        expertDbLogo: '/static/img/expert-db-logos/{{ expertDbName }}.png',
        apiSecondaryStructuresView: '/api/v1/rna/{{ upi }}/2d/{{ taxid }}',
        sequenceSearchSubmitJob: '/sequence-search/submit-job',
        sequenceSearchJobStatus: '/sequence-search/job-status/{{ jobId }}',
        sequenceSearchResults: '/sequence-search/job-results/{{ jobId }}',
        sequenceSearchInfernalJobStatus: '/sequence-search/infernal-job-status/{{ jobId }}',
        sequenceSearchInfernalResults: '/sequence-search/infernal-results/{{ jobId }}',
        apiEnsemblComparaView: '/api/v1/rna/{{ upi }}/ensembl-compara/{{ taxid }}',
        genomesApi: '/api/v1/genomes/{{ ensemblAssembly }}',
        proxy: '/api/internal/proxy?url={{ url }}',
        ebiSearch:
            '{{ ebiBaseUrl }}' +
            '?query={{ query }}' +
            '&format=json' +
            '&hlfields={{ hlfields }}' +
            '&facetcount={{ facetcount }}' +
            '&facetfields={{ facetfields }}' +
            '&facetsdepth=10' +
            '&size={{ pagesize }}' +
            '&start={{ start }}' +
            '&sort={{ sort }}' +
            '&hlpretag=' +
            '&hlposttag='
        ,
        ebiMd5Lookup:
            '{{ ebiBaseUrl }}' +
            '?query={{ md5 }}' +
            '&fields=description' +
            '&format=json' +
            '&sort=boost:descending'
        ,
        ebiAutocomplete: 'http://www.ebi.ac.uk/ebisearch/ws/rest/RNAcentral/autocomplete?term={{ query }}&format=json',
        apiGoTermsView: '/api/v1/rna/{{ upi }}/go-annotations/{{ taxid }}',
        quickGoSummaryPage: 'https://www.ebi.ac.uk/QuickGO/term/{{ term_id }}',
        quickGoChart: 'https://www.ebi.ac.uk/QuickGO/services/ontology/{{ ontology }}/terms/{{ term_ids }}/chart?base64=true',
    };

    // apply $interpolate to each route template expression
    return Object.keys(routes)
          .map(function(key) { var output = {}; output[key] = $interpolate(routes[key]); return output })
          .reduce(function(result, keyValue ) { return _.extend(result, keyValue) } );
}]);
<|endoftext|>


<commit_before>// @flow
import React, {Component} from 'react'
import {Box, Icon, Text, ProgressIndicator, NativeImage} from '../../../common-adapters/index.native'
import {ImageIcon as AttachmentStatusIcon} from '../messages/attachment'
import {globalColors, globalMargins, globalStyles} from '../../../styles'
import {formatTimeForPopup} from '../../../util/timestamp'

import type {Props} from './'

class AutoMaxSizeImage extends Component<void, any, {width: number, height: number}> {
  state = {height: 0, width: 0}

  componentDidMount () {
    NativeImage.getSize(this.props.source.uri, (width, height) => {
      this.setState({height, width})
    })
  }

  render () {
    return <NativeImage {...this.props} style={{...this.props.style, maxHeight: this.state.height, maxWidth: this.state.width}} />
  }
}

const AttachmentView = ({isZoomed, onToggleZoom, messageState, path}: {isZoomed: boolean, onToggleZoom: () => void, path: ?string}) => (
  <Box style={{...globalStyles.flexBoxCenter, flex: 1}}>
    {!!path && <AutoMaxSizeImage source={{uri: `file://${path}`}} style={{flex: 1, width: '100%', height: '100%', resizeMode: 'contain'}} />}
    {!path && <ProgressIndicator style={{width: 48}} white={true} />}
  </Box>
)

const AttachmentPopup = ({message, isZoomed, onClose, onDownloadAttachment, onDeleteMessage, onMessageAction, onToggleZoom, onOpenInFileUI, you}: Props) => {
  const {messageState, previewType, title, author, timestamp} = message
  let statusIcon
  if (messageState === 'downloading' || messageState === 'downloaded') {
    statusIcon = <AttachmentStatusIcon
      style={{position: 'absolute', bottom: -3, right: -3}}
      type={messageState === 'downloading' ? 'Downloading' : 'Downloaded'}
    />
  }

  if (!previewType || previewType === 'Other') {
    return (
      <Box style={{
        ...globalStyles.flexBoxColumn,
        ...globalStyles.fillAbsolute,
        backgroundColor: globalColors.white,
      }}>
        <Text type='Body' onClick={onClose} style={{color: globalColors.blue, marginLeft: globalMargins.small, marginTop: globalMargins.small, borderBottomWidth: 1, borderBottomColor: globalColors.black_40}}>Close</Text>
        <Box style={{...globalStyles.flexBoxColumn, justifyContent: 'center', alignItems: 'center', flex: 1}}>
          <Icon type='icon-file-48' />
          <Text type='BodySemibold' style={{marginTop: globalMargins.large, marginBottom: globalMargins.tiny}}>{title}</Text>
          <Text type='BodySmall'>Sent by {author}</Text>
          <Text type='BodySmall'>{formatTimeForPopup(timestamp)}</Text>
          <Text type='BodySmall' style={{color: globalColors.black, marginTop: globalMargins.large}}>Your device can not preview this file.</Text>
        </Box>
        <Box style={styleHeaderFooter}>
          <Icon type='iconfont-ellipsis' onClick={onMessageAction} />
        </Box>
        {statusIcon}
      </Box>
    )
  }

  return (
    <Box style={{
      ...globalStyles.flexBoxColumn,
      ...globalStyles.fillAbsolute,
      backgroundColor: globalColors.black,
    }}>
      <Text type='Body' onClick={onClose} style={{color: globalColors.white, marginLeft: globalMargins.small, marginTop: globalMargins.small}}>Close</Text>
      <AttachmentView isZoomed={isZoomed} onToggleZoom={onToggleZoom} path={message.hdPreviewPath} />
      <Box style={styleHeaderFooter}>
        <Icon type='iconfont-ellipsis' style={{color: globalColors.white}} onClick={onMessageAction} />
      </Box>
      {statusIcon}
    </Box>
  )
}

const styleHeaderFooter = {
  ...globalStyles.flexBoxRow,
  alignItems: 'center',
  flexShrink: 0,
  height: 32,
  marginLeft: globalMargins.small,
  marginBottom: globalMargins.small,
}

export default AttachmentPopup
<commit_msg>attachment arrow again master (#6806)<commit_after>// @flow
import React, {Component} from 'react'
import {Box, Icon, Text, ProgressIndicator, NativeImage} from '../../../common-adapters/index.native'
import {globalColors, globalMargins, globalStyles} from '../../../styles'
import {formatTimeForPopup} from '../../../util/timestamp'

import type {Props} from './'

class AutoMaxSizeImage extends Component<void, any, {width: number, height: number}> {
  state = {height: 0, width: 0}

  componentDidMount () {
    NativeImage.getSize(this.props.source.uri, (width, height) => {
      this.setState({height, width})
    })
  }

  render () {
    return <NativeImage {...this.props} style={{...this.props.style, maxHeight: this.state.height, maxWidth: this.state.width}} />
  }
}

const AttachmentView = ({isZoomed, onToggleZoom, path}: {isZoomed: boolean, onToggleZoom: () => void, path: ?string}) => (
  <Box style={{...globalStyles.flexBoxCenter, flex: 1}}>
    {!!path && <AutoMaxSizeImage source={{uri: `file://${path}`}} style={{flex: 1, width: '100%', height: '100%', resizeMode: 'contain', position: 'relative'}} />}
    {!path && <ProgressIndicator style={{width: 48}} white={true} />}
  </Box>
)

const AttachmentPopup = ({message, isZoomed, onClose, onDownloadAttachment, onDeleteMessage, onMessageAction, onToggleZoom, onOpenInFileUI, you}: Props) => {
  const {previewType, title, author, timestamp} = message

  if (!previewType || previewType === 'Other') {
    return (
      <Box style={{
        ...globalStyles.flexBoxColumn,
        ...globalStyles.fillAbsolute,
        backgroundColor: globalColors.white,
      }}>
        <Text type='Body' onClick={onClose} style={{color: globalColors.blue, marginLeft: globalMargins.small, marginTop: globalMargins.small, borderBottomWidth: 1, borderBottomColor: globalColors.black_40}}>Close</Text>
        <Box style={{...globalStyles.flexBoxColumn, justifyContent: 'center', alignItems: 'center', flex: 1}}>
          <Icon type='icon-file-48' />
          <Text type='BodySemibold' style={{marginTop: globalMargins.large, marginBottom: globalMargins.tiny}}>{title}</Text>
          <Text type='BodySmall'>Sent by {author}</Text>
          <Text type='BodySmall'>{formatTimeForPopup(timestamp)}</Text>
          <Text type='BodySmall' style={{color: globalColors.black, marginTop: globalMargins.large}}>Your device can not preview this file.</Text>
        </Box>
        <Box style={styleHeaderFooter}>
          <Icon type='iconfont-ellipsis' onClick={onMessageAction} />
        </Box>
      </Box>
    )
  }

  return (
    <Box style={{
      ...globalStyles.flexBoxColumn,
      ...globalStyles.fillAbsolute,
      backgroundColor: globalColors.black,
    }}>
      <Text type='Body' onClick={onClose} style={{color: globalColors.white, marginLeft: globalMargins.small, marginTop: globalMargins.small}}>Close</Text>
      <AttachmentView isZoomed={isZoomed} onToggleZoom={onToggleZoom} path={message.hdPreviewPath} />
      <Box style={styleHeaderFooter}>
        <Icon type='iconfont-ellipsis' style={{color: globalColors.white}} onClick={onMessageAction} />
      </Box>
    </Box>
  )
}

const styleHeaderFooter = {
  ...globalStyles.flexBoxRow,
  alignItems: 'center',
  flexShrink: 0,
  height: 32,
  marginLeft: globalMargins.small,
  marginBottom: globalMargins.small,
}

export default AttachmentPopup
<|endoftext|>


<commit_before>define(function(require, exports, module) {
"use strict";

var _ = require("libs.underscore");

var defaults = {
    signout: "about: blank",
    modules: []
};

var app_config = (parent.app && parent.app.config) || {};

module.exports = _.defaults(app_config, defaults);

});
<commit_msg>Define global variables<commit_after>define(function(require, exports, module) {
"use strict";

var _ = require("libs.underscore");

var defaults = {
    base: "", // with trailing slash (e.g. http://example.com/foo/bar/)
    baseurl: "", // without trailing slash (e.g. /foo/bar)
    signout: "about: blank",
    modules: [],
    username: ""
};

var config = (window.root.app && window.root.app.config) || {};

module.exports = _.defaults(config, defaults);

});
<|endoftext|>


<commit_before>/*
 * Boardfarm Management application
 * Copyright (c) 2017 Heiko Stuebner <heiko@sntech.de>
 *
 * License:
 *   MIT: https://opensource.org/licenses/MIT
 *   See the LICENSE file in the project's top-level directory for details.
 */

var power = require("./Power");
var ipower = require("./IPowerPort");
var exec = require('child_process').exec;

qx.Class.define("sn.boardfarm.backend.power.AbstractCRelay",
{
	extend : qx.core.Object,

	construct : function(serial)
	{
		var pwr = sn.boardfarm.backend.power.Power.getInstance();

		console.log("Power: added " + this.getRelayType() +" CRelay " + serial);
		this.setAdapterIdent(this.getRelayType() + ":" + serial);
		this.setSerial(serial);

		var states = [];
		for (var i = 0; i < this.adapterGetPortNum(); i++)
			states.push(-1);
		this.__states = states;
		this.__ports = {};

		pwr.addAdapter(this.getAdapterIdent(), this);
	},

	events :
	{
		"adapterPowerChanged" : "qx.event.type.Data",
		"adapterPortStateChanged" : "qx.event.type.Data"
	},

	properties :
	{
		relayType : { init : "unknown" },

		adapterIdent : {},
		serial : {}
	},

	members :
	{
		adapterReadPower : function()
		{
			/* can't read power measurements */
			this.fireDataEvent("adapterPowerChanged", 0);
		},

		__states : null,

		adapterReadState : function()
		{
			var child;
			var serial = this.getSerial();
			var base = this;

			/* FIXME: crelay most likely cannot read the relay state */
		},

		__ports : null,

		adapterShutdown : function()
		{
			for (var i = 0; i < this.adapterGetPortNum(); i++)
				this.adapterSetPortState(i, 0);
		},

		adapterAddPort : function(port, obj)
		{
			if (this.__ports[port])
				throw "Port "+port+" already set on "+this.getAdapterIdent();

			this.__ports[port] = obj;
		},

		adapterGetPort : function(port)
		{
			if (!this.__ports[port])
				throw "Port "+port+" not set on "+this.getAdapterIdent();

			return this.__ports[port];
		},

		adapterGetPortState : function(port)
		{
			return this.__states[port];
		},

		adapterSetPortState : function(port, newState)
		{
			var child;
			var serial = this.getSerial();
			var base = this;
			var cmd = newState ? "ON" : "OFF";

			child = exec("sudo /usr/local/bin/crelay -s " + serial + " " + (parseInt(port) + 1) + " " + cmd, function (error, stdout, stderr)
			{
				if (error !== null) {
					console.log("crelay command returned " + error);
					return;
				}

				base.__states[port] = newState;
				base.fireDataEvent("adapterPortStateChanged", { port : port, state : newState });
				console.log("Power: set port " + parseInt(port) + " of " + base.getAdapterIdent() + " to "+ newState);
			});
		}
	}
});

qx.Class.define("sn.boardfarm.backend.power.AbstractCRelayPort",
{
	extend : qx.core.Object,

	construct : function(serial, port)
	{
		this.setPort(port);
		this.__adapter.adapterAddPort(port, this);
	},

	properties :
	{
		port : {},
		board : {}
	},

	members :
	{
		__adapter : null,

		portGetAdapter : function()
		{
			return this.__adapter;
		},

		portGetState : function()
		{
			return this.portGetAdapter().adapterGetPortState(this.getPort());
		},

		portSetState : function(newState)
		{
			this.portGetAdapter().adapterSetPortState(this.getPort(), newState);
		}
	}
});
<commit_msg>AbstractCRelay: move to execSync<commit_after>/*
 * Boardfarm Management application
 * Copyright (c) 2017 Heiko Stuebner <heiko@sntech.de>
 *
 * License:
 *   MIT: https://opensource.org/licenses/MIT
 *   See the LICENSE file in the project's top-level directory for details.
 */

var power = require("./Power");
var ipower = require("./IPowerPort");
var execSync = require('child_process').execSync;

qx.Class.define("sn.boardfarm.backend.power.AbstractCRelay",
{
	extend : qx.core.Object,

	construct : function(serial)
	{
		var pwr = sn.boardfarm.backend.power.Power.getInstance();

		console.log("Power: added " + this.getRelayType() +" CRelay " + serial);
		this.setAdapterIdent(this.getRelayType() + ":" + serial);
		this.setSerial(serial);

		var states = [];
		for (var i = 0; i < this.adapterGetPortNum(); i++)
			states.push(-1);
		this.__states = states;
		this.__ports = {};

		pwr.addAdapter(this.getAdapterIdent(), this);
	},

	events :
	{
		"adapterPowerChanged" : "qx.event.type.Data",
		"adapterPortStateChanged" : "qx.event.type.Data"
	},

	properties :
	{
		relayType : { init : "unknown" },

		adapterIdent : {},
		serial : {}
	},

	members :
	{
		adapterReadPower : function()
		{
			/* can't read power measurements */
			this.fireDataEvent("adapterPowerChanged", 0);
		},

		__states : null,

		adapterReadState : function()
		{
			var child;
			var serial = this.getSerial();
			var base = this;

			/* FIXME: crelay most likely cannot read the relay state */
		},

		__ports : null,

		adapterShutdown : function()
		{
			for (var i = 0; i < this.adapterGetPortNum(); i++)
				this.adapterSetPortState(i, 0);
		},

		adapterAddPort : function(port, obj)
		{
			if (this.__ports[port])
				throw "Port "+port+" already set on "+this.getAdapterIdent();

			this.__ports[port] = obj;
		},

		adapterGetPort : function(port)
		{
			if (!this.__ports[port])
				throw "Port "+port+" not set on "+this.getAdapterIdent();

			return this.__ports[port];
		},

		adapterGetPortState : function(port)
		{
			return this.__states[port];
		},

		adapterSetPortState : function(port, newState)
		{
			var child;
			var serial = this.getSerial();
			var base = this;
			var cmd = newState ? "ON" : "OFF";

			error = execSync("sudo /usr/local/bin/crelay -s " + serial + " " + (parseInt(port) + 1) + " " + cmd);
			base.__states[port] = newState;
			base.fireDataEvent("adapterPortStateChanged", { port : port, state : newState });
			console.log("Power: set port " + parseInt(port) + " of " + base.getAdapterIdent() + " to "+ newState);
		}
	}
});

qx.Class.define("sn.boardfarm.backend.power.AbstractCRelayPort",
{
	extend : qx.core.Object,

	construct : function(serial, port)
	{
		this.setPort(port);
		this.__adapter.adapterAddPort(port, this);
	},

	properties :
	{
		port : {},
		board : {}
	},

	members :
	{
		__adapter : null,

		portGetAdapter : function()
		{
			return this.__adapter;
		},

		portGetState : function()
		{
			return this.portGetAdapter().adapterGetPortState(this.getPort());
		},

		portSetState : function(newState)
		{
			this.portGetAdapter().adapterSetPortState(this.getPort(), newState);
		}
	}
});
<|endoftext|>


<commit_before>/*
 * Copyright 2010-2011 Research In Motion Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var PictureSourceType = {
        PHOTOLIBRARY : 0,    // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
        CAMERA : 1,          // Take picture from camera
        SAVEDPHOTOALBUM : 2  // Choose image from picture library (same as PHOTOLIBRARY for Android)
    },
    DestinationType = {
        DATA_URL: 0,         // Return base64 encoded string
        FILE_URI: 1,         // Return file uri (content://media/external/images/media/2 for Android)
        NATIVE_URI: 2        // Return native uri (eg. asset-library://... for iOS)
    };

function encodeBase64(filePath, callback) {
    var sandbox = window.qnx.webplatform.getController().setFileSystemSandbox, // save original sandbox value
        errorHandler = function (err) {
            var msg = "An error occured: ";

            switch (err.code) {
            case FileError.NOT_FOUND_ERR:
                msg += "File or directory not found";
                break;

            case FileError.NOT_READABLE_ERR:
                msg += "File or directory not readable";
                break;

            case FileError.PATH_EXISTS_ERR:
                msg += "File or directory already exists";
                break;

            case FileError.TYPE_MISMATCH_ERR:
                msg += "Invalid file type";
                break;

            default:
                msg += "Unknown Error";
                break;
            };

            // set it back to original value
            window.qnx.webplatform.getController().setFileSystemSandbox = sandbox;
            callback(msg);
        },
        gotFile = function (fileEntry) {
            fileEntry.file(function (file) {
                var reader = new FileReader();

                reader.onloadend = function (e) {
                    // set it back to original value
                    window.qnx.webplatform.getController().setFileSystemSandbox = sandbox;
                    callback(this.result);
                };

                reader.readAsDataURL(file);
            }, errorHandler);
        },
        onInitFs = function (fs) {
            window.qnx.webplatform.getController().setFileSystemSandbox = false;
            fs.root.getFile(filePath, {create: false}, gotFile, errorHandler);
        };

    window.webkitRequestFileSystem(window.TEMPORARY, 10 * 1024 * 1024, onInitFs, errorHandler); // set size to 10MB max
}

module.exports = {
    takePicture: function (success, fail, args, env) {
        var destinationType = JSON.parse(decodeURIComponent(args[1])),
            sourceType = JSON.parse(decodeURIComponent(args[2])),
            result = new PluginResult(args, env),
            done = function (data) {
                if (destinationType === DestinationType.FILE_URI) {
                    data = "file://" + data;
                    result.callbackOk(data, false);
                } else {
                    encodeBase64(data, function (data) {
                        if (/^data:/.test(data)) {
                            data = data.slice(data.indexOf(",") + 1);
                            result.callbackOk(data, false);
                        } else {
                            result.callbackError(data, false);
                        }
                    });
                }
            },
            cancel = function (reason) {
                result.callbackError(reason, false);
            },
            invoked = function (error) {
                if (error) {
                    result.callbackError(error, false);
                }
            };

        switch(sourceType) {
        case PictureSourceType.CAMERA:
            window.qnx.webplatform.getApplication().cards.camera.open("photo", done, cancel, invoked);
            break;

        case PictureSourceType.PHOTOLIBRARY:
        case PictureSourceType.SAVEDPHOTOALBUM:
            window.qnx.webplatform.getApplication().cards.filePicker.open({
                mode: "Picker",
                type: ["picture"]
            }, done, cancel, invoked);
            break;
        }

        result.noResult(true);
    }
};
<commit_msg>[CB-4432] copyright notice change<commit_after>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/
var PictureSourceType = {
        PHOTOLIBRARY : 0,    // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
        CAMERA : 1,          // Take picture from camera
        SAVEDPHOTOALBUM : 2  // Choose image from picture library (same as PHOTOLIBRARY for Android)
    },
    DestinationType = {
        DATA_URL: 0,         // Return base64 encoded string
        FILE_URI: 1,         // Return file uri (content://media/external/images/media/2 for Android)
        NATIVE_URI: 2        // Return native uri (eg. asset-library://... for iOS)
    };

function encodeBase64(filePath, callback) {
    var sandbox = window.qnx.webplatform.getController().setFileSystemSandbox, // save original sandbox value
        errorHandler = function (err) {
            var msg = "An error occured: ";

            switch (err.code) {
            case FileError.NOT_FOUND_ERR:
                msg += "File or directory not found";
                break;

            case FileError.NOT_READABLE_ERR:
                msg += "File or directory not readable";
                break;

            case FileError.PATH_EXISTS_ERR:
                msg += "File or directory already exists";
                break;

            case FileError.TYPE_MISMATCH_ERR:
                msg += "Invalid file type";
                break;

            default:
                msg += "Unknown Error";
                break;
            };

            // set it back to original value
            window.qnx.webplatform.getController().setFileSystemSandbox = sandbox;
            callback(msg);
        },
        gotFile = function (fileEntry) {
            fileEntry.file(function (file) {
                var reader = new FileReader();

                reader.onloadend = function (e) {
                    // set it back to original value
                    window.qnx.webplatform.getController().setFileSystemSandbox = sandbox;
                    callback(this.result);
                };

                reader.readAsDataURL(file);
            }, errorHandler);
        },
        onInitFs = function (fs) {
            window.qnx.webplatform.getController().setFileSystemSandbox = false;
            fs.root.getFile(filePath, {create: false}, gotFile, errorHandler);
        };

    window.webkitRequestFileSystem(window.TEMPORARY, 10 * 1024 * 1024, onInitFs, errorHandler); // set size to 10MB max
}

module.exports = {
    takePicture: function (success, fail, args, env) {
        var destinationType = JSON.parse(decodeURIComponent(args[1])),
            sourceType = JSON.parse(decodeURIComponent(args[2])),
            result = new PluginResult(args, env),
            done = function (data) {
                if (destinationType === DestinationType.FILE_URI) {
                    data = "file://" + data;
                    result.callbackOk(data, false);
                } else {
                    encodeBase64(data, function (data) {
                        if (/^data:/.test(data)) {
                            data = data.slice(data.indexOf(",") + 1);
                            result.callbackOk(data, false);
                        } else {
                            result.callbackError(data, false);
                        }
                    });
                }
            },
            cancel = function (reason) {
                result.callbackError(reason, false);
            },
            invoked = function (error) {
                if (error) {
                    result.callbackError(error, false);
                }
            };

        switch(sourceType) {
        case PictureSourceType.CAMERA:
            window.qnx.webplatform.getApplication().cards.camera.open("photo", done, cancel, invoked);
            break;

        case PictureSourceType.PHOTOLIBRARY:
        case PictureSourceType.SAVEDPHOTOALBUM:
            window.qnx.webplatform.getApplication().cards.filePicker.open({
                mode: "Picker",
                type: ["picture"]
            }, done, cancel, invoked);
            break;
        }

        result.noResult(true);
    }
};
<|endoftext|>


<commit_before>export default {
  title: 'Components|Pagination',
};
<commit_msg>Add pagination stories for vanilla<commit_after>import { useEffect } from '@storybook/client-api';
import { pagination } from './pagination';

export default {
  title: 'Components|Pagination',
};

export const defaultStory = () => {
  useEffect(() => {
    pagination();
  }, []);

  return `

          Prev
          <svg
            class="sprk-c-Icon sprk-c-Icon--stroke-current-color"
            viewBox="0 0 64 64"
          >
            <use xlink:href="#chevron-left"></use>
          </svg>

          1

          2

          3

          Next
          <svg
            class="sprk-c-Icon sprk-c-Icon--stroke-current-color"
            viewBox="0 0 64 64"
          >
            <use xlink:href="#chevron-right"></use>
          </svg>

  `;
};

defaultStory.story = {
  name: 'default',
};

export const long = () => {
  useEffect(() => {
    pagination();
  }, []);

  return `

          Prev
          <svg
            class="sprk-c-Icon sprk-c-Icon--stroke-current-color"
            viewBox="0 0 64 64"
          >
            <use xlink:href="#chevron-left"></use>
          </svg>

          1

        ...

          11

        ...

          22

          <svg
            class="sprk-c-Icon sprk-c-Icon--stroke-current-color"
            viewBox="0 0 64 64"
          >
            <use xlink:href="#chevron-right"></use>
          </svg>

  `;
};

export const pager = () => {
  useEffect(() => {
    pagination();
  }, []);

  return `

          <svg
            class="sprk-c-Icon sprk-c-Icon--stroke-current-color"
            viewBox="0 0 64 64"
          >
            <use xlink:href="#chevron-left"></use>
          </svg>
          Prev

          <svg
            class="sprk-c-Icon sprk-c-Icon--stroke-current-color"
            viewBox="0 0 64 64"
          >
            <use xlink:href="#chevron-right"></use>
          </svg>
          Next

  `;
};
<|endoftext|>


<commit_before>// Import
var BinaryWriter = require("./BinaryWriter");

function UpdateLeaderboard(playerTracker, leaderboard, leaderboardType) {
    this.playerTracker = playerTracker;
    this.leaderboard = leaderboard;
    this.leaderboardType = leaderboardType;
    this.leaderboardCount = Math.min(leaderboard.length, playerTracker.gameServer.config.serverMaxLB);
}
module.exports = UpdateLeaderboard;
UpdateLeaderboard.prototype.build = function(protocol) {
    switch (this.leaderboardType) {
        case 48:
            // UserText
            return protocol < 13 ? this.buildUserText(protocol) : this.buildUserText13();
        case 49:
            // FFA
            if (protocol < 6) return this.buildFfa5();
            else if (protocol < 11) return this.buildFfa6();
            //else if (protocol == 11)
            //return this.buildFfa11();
            else return this.buildFfa13();
        case 50:
            // Team
            return this.buildTeam();
        default:
            return null;
    }
}
// UserText prorocols 5/6/11
UpdateLeaderboard.prototype.buildUserText = function(protocol) {
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboard.length);
    for (var i = 0; i < this.leaderboard.length; i++) {
        var item = this.leaderboard[i] || "";
        if (protocol < 11) writer.writeUInt32(0);
        if (protocol < 6) writer.writeStringZeroUnicode(item);
        else writer.writeStringZeroUtf8(item);
    }
    return writer.toBuffer();
};
// UserText protocol 13
UpdateLeaderboard.prototype.buildUserText13 = function () {
    var writer = new BinaryWriter();
    writer.writeUInt8(0x33);
    for (var i = 0; i < this.leaderboard.length; i++) {
        writer.writeUInt8(0x02);
        writer.writeStringZeroUtf8(this.leaderboard[i]);
    }
    return writer.toBuffer();
};
// FFA protocol 5
UpdateLeaderboard.prototype.buildFfa5 = function() {
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboardCount);
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        var name = item._nameUnicode;
        var id = 0;
        if (item == this.playerTracker && item.cells.length) id = item.cells[0].nodeId ^ this.playerTracker.scrambleId;
        writer.writeUInt32(id >>> 0); // Player cell Id
        if (name) writer.writeBytes(name);
        else writer.writeUInt16(0);
    }
    return writer.toBuffer();
};
// FFA protocol 6
UpdateLeaderboard.prototype.buildFfa6 = function() {
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboardCount);
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        var name = item._nameUtf8;
        var id = item == this.playerTracker ? 1 : 0;
        writer.writeUInt32(id >>> 0); // isMe flag
        if (name) writer.writeBytes(name);
        else writer.writeUInt8(0);
    }
    return writer.toBuffer();
};
// FFA protocol 11
UpdateLeaderboard.prototype.buildFfa11 = function() {
    var pos = require('./LeaderboardPosition');
    this.playerTracker.socket.packetHandler.sendPacket(new pos(this.leaderboard.indexOf(this.playerTracker) + 1));
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboardCount);
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        var name = item._nameUtf8;
        if (name) writer.writeBytes(name);
        else writer.writeUInt8(0);
    }
    return writer.toBuffer();
};
// FFA protocol 13
UpdateLeaderboard.prototype.buildFfa13 = function() {
    var writer = new BinaryWriter();
    writer.writeUInt8(0x33); // Packet ID
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        if (item === this.playerTracker) {
            writer.writeUInt8(0x09);
            writer.writeUInt16(1);
        } else {
            var name = item._name;
            writer.writeUInt8(0x02);
            if (name != null && name.length) writer.writeStringZeroUtf8(name);
            else writer.writeUInt8(0);
        }
    }
    var thing = this.leaderboard.indexOf(this.playerTracker) + 1;
    var place = (thing <= 10) ? null : thing;
    if (this.playerTracker.cells.length && place != null) {
        writer.writeUInt8(0x09);
        writer.writeUInt16(place);
    }
    return writer.toBuffer();
};
// Party
// TODO: Implement the "minimap"
UpdateLeaderboard.prototype.buildParty = function() {
    var protocol13s = 0;
    for (var i in this.playerTracker.gameServer.clients) {
        var client = this.playerTracker.gameServer.clients[i].packetHandler;
        if (client.protocol >= 13) protocol13s++;
    }
    var writer = new BinaryWriter();
    writer.writeUInt8(0x34); // Packet ID
    writer.writeUInt16(protocol13s); // How many friends are in-game
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        if (item === this.playerTracker) {
            writer.writeUInt8(0x09);
            writer.writeUInt16(1);
        } else {
            var name = item._name;
            writer.writeUInt8(0x02);
            if (name != null && name.length) writer.writeStringZeroUtf8(name);
            else writer.writeUInt8(0);
        }
    }
    var thing = this.leaderboard.indexOf(this.playerTracker) + 1;
    var place = (thing <= 10) ? null : thing;
    if (this.playerTracker.cells.length && place != null) {
        writer.writeUInt16(place);
    }
    return writer.toBuffer();
};

function writeCount(writer, flag1, flag2) {
    writer.writeUInt8(flag1); // Packet ID
    writer.writeUInt32(flag2 >>> 0); // Number of elements
}
// Team
UpdateLeaderboard.prototype.buildTeam = function() {
    var writer = new BinaryWriter();
    writeCount(writer, 0x32, this.leaderboard.length);
    for (var i = 0; i < this.leaderboard.length; i++) {
        var value = this.leaderboard[i];
        if (value == null) return null; // bad leaderboardm just don't send it
        if (isNaN(value)) value = 0;
        value = value < 0 ? 0 : value;
        value = value > 1 ? 1 : value;
        writer.writeFloat(value); // isMe flag (previously cell ID)
    }
    return writer.toBuffer();
};
<commit_msg>Fix for empty strings escaping for text based leaderboard<commit_after>// Import
var BinaryWriter = require("./BinaryWriter");

function UpdateLeaderboard(playerTracker, leaderboard, leaderboardType) {
    this.playerTracker = playerTracker;
    this.leaderboard = leaderboard;
    this.leaderboardType = leaderboardType;
    this.leaderboardCount = Math.min(leaderboard.length, playerTracker.gameServer.config.serverMaxLB);
}
module.exports = UpdateLeaderboard;
UpdateLeaderboard.prototype.build = function(protocol) {
    switch (this.leaderboardType) {
        case 48:
            // UserText
            return protocol < 13 ? this.buildUserText(protocol) : this.buildUserText13();
        case 49:
            // FFA
            if (protocol < 6) return this.buildFfa5();
            else if (protocol < 11) return this.buildFfa6();
            //else if (protocol == 11)
            //return this.buildFfa11();
            else return this.buildFfa13();
        case 50:
            // Team
            return this.buildTeam();
        default:
            return null;
    }
}
// UserText prorocols 5/6/11
UpdateLeaderboard.prototype.buildUserText = function(protocol) {
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboard.length);
    for (var i = 0; i < this.leaderboard.length; i++) {
        var item = this.leaderboard[i] || "";
        if (protocol < 11) writer.writeUInt32(0);
        if (protocol < 6) writer.writeStringZeroUnicode(item);
        else writer.writeStringZeroUtf8(item);
    }
    return writer.toBuffer();
};
// UserText protocol 13
UpdateLeaderboard.prototype.buildUserText13 = function () {
    var writer = new BinaryWriter();
    writer.writeUInt8(0x33);
    for (var i = 0; i < this.leaderboard.length; i++) {
        var item = this.leaderboard[i] || "";
        writer.writeUInt8(0x02);
        writer.writeStringZeroUtf8(item);
    }
    return writer.toBuffer();
};
// FFA protocol 5
UpdateLeaderboard.prototype.buildFfa5 = function() {
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboardCount);
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        var name = item._nameUnicode;
        var id = 0;
        if (item == this.playerTracker && item.cells.length) id = item.cells[0].nodeId ^ this.playerTracker.scrambleId;
        writer.writeUInt32(id >>> 0); // Player cell Id
        if (name) writer.writeBytes(name);
        else writer.writeUInt16(0);
    }
    return writer.toBuffer();
};
// FFA protocol 6
UpdateLeaderboard.prototype.buildFfa6 = function() {
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboardCount);
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        var name = item._nameUtf8;
        var id = item == this.playerTracker ? 1 : 0;
        writer.writeUInt32(id >>> 0); // isMe flag
        if (name) writer.writeBytes(name);
        else writer.writeUInt8(0);
    }
    return writer.toBuffer();
};
// FFA protocol 11
UpdateLeaderboard.prototype.buildFfa11 = function() {
    var pos = require('./LeaderboardPosition');
    this.playerTracker.socket.packetHandler.sendPacket(new pos(this.leaderboard.indexOf(this.playerTracker) + 1));
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboardCount);
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        var name = item._nameUtf8;
        if (name) writer.writeBytes(name);
        else writer.writeUInt8(0);
    }
    return writer.toBuffer();
};
// FFA protocol 13
UpdateLeaderboard.prototype.buildFfa13 = function() {
    var writer = new BinaryWriter();
    writer.writeUInt8(0x33); // Packet ID
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        if (item === this.playerTracker) {
            writer.writeUInt8(0x09);
            writer.writeUInt16(1);
        } else {
            var name = item._name;
            writer.writeUInt8(0x02);
            if (name != null && name.length) writer.writeStringZeroUtf8(name);
            else writer.writeUInt8(0);
        }
    }
    var thing = this.leaderboard.indexOf(this.playerTracker) + 1;
    var place = (thing <= 10) ? null : thing;
    if (this.playerTracker.cells.length && place != null) {
        writer.writeUInt8(0x09);
        writer.writeUInt16(place);
    }
    return writer.toBuffer();
};
// Party
// TODO: Implement the "minimap"
UpdateLeaderboard.prototype.buildParty = function() {
    var protocol13s = 0;
    for (var i in this.playerTracker.gameServer.clients) {
        var client = this.playerTracker.gameServer.clients[i].packetHandler;
        if (client.protocol >= 13) protocol13s++;
    }
    var writer = new BinaryWriter();
    writer.writeUInt8(0x34); // Packet ID
    writer.writeUInt16(protocol13s); // How many friends are in-game
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        if (item === this.playerTracker) {
            writer.writeUInt8(0x09);
            writer.writeUInt16(1);
        } else {
            var name = item._name;
            writer.writeUInt8(0x02);
            if (name != null && name.length) writer.writeStringZeroUtf8(name);
            else writer.writeUInt8(0);
        }
    }
    var thing = this.leaderboard.indexOf(this.playerTracker) + 1;
    var place = (thing <= 10) ? null : thing;
    if (this.playerTracker.cells.length && place != null) {
        writer.writeUInt16(place);
    }
    return writer.toBuffer();
};

function writeCount(writer, flag1, flag2) {
    writer.writeUInt8(flag1); // Packet ID
    writer.writeUInt32(flag2 >>> 0); // Number of elements
}
// Team
UpdateLeaderboard.prototype.buildTeam = function() {
    var writer = new BinaryWriter();
    writeCount(writer, 0x32, this.leaderboard.length);
    for (var i = 0; i < this.leaderboard.length; i++) {
        var value = this.leaderboard[i];
        if (value == null) return null; // bad leaderboardm just don't send it
        if (isNaN(value)) value = 0;
        value = value < 0 ? 0 : value;
        value = value > 1 ? 1 : value;
        writer.writeFloat(value); // isMe flag (previously cell ID)
    }
    return writer.toBuffer();
};
<|endoftext|>


<commit_before>import React, { Component, Fragment } from 'react'
import Login from 'components/apply/Login'
import LoadingAnimation from 'components/LoadingAnimation'
import ErrorPage from 'components/admin/ErrorPage'
import Nav from 'components/apply/ApplyNav'
import ClubForm from 'components/checkup/ClubForm'
import LeadershipPositionsForm from 'components/checkup/LeadershipPositionsForm'
import LeaderInviteForm from 'components/checkup/LeaderInviteForm'
import api from 'api'
import search from 'search'
import { Container, Link, Card, Heading, Text } from '@hackclub/design-system'

export default class extends Component {
  state = {
    status: 'loading'
  }

  componentDidMount() {
    const id = search.get('id')
    api
      .get(`v1/users/current`)
      .then(user =>
        api.get(`v1/new_clubs/${id}`).then(club => {
          this.setState({ user, club, status: 'success' })
        })
      )
      .catch(err => {
        console.error(err)
        if (err.status === 401) {
          this.setState({ status: 'needsToAuth' })
        } else {
          this.setState({ status: 'error' })
        }
      })
  }

  render() {
    const { status, club, user } = this.state
    switch (status) {
      case 'loading':
        return <LoadingAnimation />
      case 'success':
        return (
          <Fragment>
            <Nav />
            <Container my={3} maxWidth={32}>
              <Heading.h2>Confirm your club info</Heading.h2>
              <Text my={3}>
                If anything is out of date, please fix it and press submit
              </Text>
              <Card boxShadowSize="sm" p={3} my={3}>
                <p>{`${location.origin}${location.pathname}/leaders?id=${
                  club.id
                }`}</p>
                <ClubForm
                  {...club}
                  redirectUrl={`${location.origin}${
                    location.pathname
                  }/leaders?id=${club.id}`}
                />
              </Card>
            </Container>
          </Fragment>
        )
      case 'needsToAuth':
        return <Login heading="Login to view" />
      default:
        return <ErrorPage />
    }
  }
}
<commit_msg>Delete URL paragraph<commit_after>import React, { Component, Fragment } from 'react'
import Login from 'components/apply/Login'
import LoadingAnimation from 'components/LoadingAnimation'
import ErrorPage from 'components/admin/ErrorPage'
import Nav from 'components/apply/ApplyNav'
import ClubForm from 'components/checkup/ClubForm'
import LeadershipPositionsForm from 'components/checkup/LeadershipPositionsForm'
import LeaderInviteForm from 'components/checkup/LeaderInviteForm'
import api from 'api'
import search from 'search'
import { Container, Link, Card, Heading, Text } from '@hackclub/design-system'

export default class extends Component {
  state = {
    status: 'loading'
  }

  componentDidMount() {
    const id = search.get('id')
    api
      .get(`v1/users/current`)
      .then(user =>
        api.get(`v1/new_clubs/${id}`).then(club => {
          this.setState({ user, club, status: 'success' })
        })
      )
      .catch(err => {
        console.error(err)
        if (err.status === 401) {
          this.setState({ status: 'needsToAuth' })
        } else {
          this.setState({ status: 'error' })
        }
      })
  }

  render() {
    const { status, club, user } = this.state
    switch (status) {
      case 'loading':
        return <LoadingAnimation />
      case 'success':
        return (
          <Fragment>
            <Nav />
            <Container my={3} maxWidth={32}>
              <Heading.h2>Confirm your club info</Heading.h2>
              <Text my={3}>
                If anything is out of date, please fix it and press submit
              </Text>
              <Card boxShadowSize="sm" p={3} my={3}>
                <ClubForm
                  {...club}
                  redirectUrl={`${location.origin}${
                    location.pathname
                  }/leaders?id=${club.id}`}
                />
              </Card>
            </Container>
          </Fragment>
        )
      case 'needsToAuth':
        return <Login heading="Login to view" />
      default:
        return <ErrorPage />
    }
  }
}
<|endoftext|>


<commit_before>define([
  'extensions/views/graph/axis'
],
function (Axis) {

  describe("render", function() {

    var el, wrapper;
    beforeEach(function() {
      el = $('

').appendTo($('body'));
      wrapper = Axis.prototype.d3.select(el[0]).append('svg').append('g');
    });

    afterEach(function() {
      el.remove();
    });

    it("requires a scale", function() {
      expect(function () {
        var view = new Axis({
          wrapper: wrapper
        });
        view.render()
      }).toThrow();
    });

    it("renders a d3 axis component", function() {

      var view = new Axis({
        collection: {
          on: jasmine.createSpy()
        },
        wrapper: wrapper,
        classed: 'testclass',
        getScale: function () {
          return view.d3.scale.linear()
        },
        graph: {
          innerWidth: 100,
          innerHeight: 100
        }
      });
      spyOn(view.d3.svg, "axis").andCallThrough();

      view.render()

      expect(wrapper.selectAll('.tick')[0].length).toEqual(11);
    });

  });

  describe("getTransform", function() {

    var view;
    beforeEach(function() {
      view = new Axis({
        collection: {
          on: jasmine.createSpy()
        },
        graph: {
          innerWidth: 555,
          innerHeight: 444
        }
      });
    });

    it("calculates default translation for position left", function() {
      view.position = 'left';
      expect(view.getTransform()).toEqual('translate(0,0)');
    });

    it("calculates default translation for position right", function() {
      view.position = 'right';
      expect(view.getTransform()).toEqual('translate(555,0)');
    });

    it("calculates default translation for position top", function() {
      view.position = 'top';
      expect(view.getTransform()).toEqual('translate(0,0)');
    });

    it("calculates default translation for position bottom", function() {
      view.position = 'bottom';
      expect(view.getTransform()).toEqual('translate(0,444)');
    });

    it("calculates custom translation for position left", function() {
      view.position = 'left';
      view.offsetX = 7;
      view.offsetY = 8;
      expect(view.getTransform()).toEqual('translate(7,8)');
    });

    it("calculates custom translation for position right", function() {
      view.position = 'right';
      view.offsetX = 7;
      view.offsetY = 8;
      expect(view.getTransform()).toEqual('translate(562,8)');
    });

    it("calculates custom translation for position top", function() {
      view.position = 'top';
      view.offsetX = 7;
      view.offsetY = 8;
      expect(view.getTransform()).toEqual('translate(7,8)');
    });

    it("calculates custom translation for position bottom", function() {
      view.position = 'bottom';
      view.offsetX = 7;
      view.offsetY = 8;
      expect(view.getTransform()).toEqual('translate(7,452)');
    });

  });

});
<commit_msg>add test for axis re-ordering<commit_after>define([
  'extensions/views/graph/axis'
],
function (Axis) {

  describe("render", function() {

    var el, wrapper;
    beforeEach(function() {
      el = $('

').appendTo($('body'));
      wrapper = Axis.prototype.d3.select(el[0]).append('svg').append('g');
    });

    afterEach(function() {
      el.remove();
    });

    it("requires a scale", function() {
      expect(function () {
        var view = new Axis({
          wrapper: wrapper
        });
        view.render()
      }).toThrow();
    });

    it("renders a d3 axis component", function() {

      var view = new Axis({
        collection: {
          on: jasmine.createSpy()
        },
        wrapper: wrapper,
        classed: 'testclass',
        getScale: function () {
          return view.d3.scale.linear()
        },
        graph: {
          innerWidth: 100,
          innerHeight: 100
        }
      });
      spyOn(view.d3.svg, "axis").andCallThrough();

      view.render()

      expect(wrapper.selectAll('.tick')[0].length).toEqual(11);
    });

    it("re-orders tick elements correctly when re-using tick elements", function () {
      var view = new Axis({
        collection: {
          on: jasmine.createSpy()
        },
        wrapper: wrapper,
        classed: 'testclass',
        getScale: function () {
          return view.d3.scale.linear()
        },
        graph: {
          innerWidth: 100,
          innerHeight: 100
        },
        tickValues: [2,4,6]
      });
      spyOn(view.d3.svg, "axis").andCallThrough();

      view.render()

      var ticks = wrapper.selectAll('.tick')[0];
      expect(wrapper.selectAll('.tick')[0].length).toEqual(3);
      expect(d3.select(ticks[0]).text()).toEqual('2.0');
      expect(d3.select(ticks[1]).text()).toEqual('4.0');
      expect(d3.select(ticks[2]).text()).toEqual('6.0');

      view.tickValues = [1,2,3];
      view.render();

      var ticks = wrapper.selectAll('.tick')[0];
      expect(d3.select(ticks[0]).text()).toEqual('1.0');
      expect(d3.select(ticks[1]).text()).toEqual('2.0');
      expect(d3.select(ticks[2]).text()).toEqual('3.0');
    });

  });

  describe("getTransform", function() {

    var view;
    beforeEach(function() {
      view = new Axis({
        collection: {
          on: jasmine.createSpy()
        },
        graph: {
          innerWidth: 555,
          innerHeight: 444
        }
      });
    });

    it("calculates default translation for position left", function() {
      view.position = 'left';
      expect(view.getTransform()).toEqual('translate(0,0)');
    });

    it("calculates default translation for position right", function() {
      view.position = 'right';
      expect(view.getTransform()).toEqual('translate(555,0)');
    });

    it("calculates default translation for position top", function() {
      view.position = 'top';
      expect(view.getTransform()).toEqual('translate(0,0)');
    });

    it("calculates default translation for position bottom", function() {
      view.position = 'bottom';
      expect(view.getTransform()).toEqual('translate(0,444)');
    });

    it("calculates custom translation for position left", function() {
      view.position = 'left';
      view.offsetX = 7;
      view.offsetY = 8;
      expect(view.getTransform()).toEqual('translate(7,8)');
    });

    it("calculates custom translation for position right", function() {
      view.position = 'right';
      view.offsetX = 7;
      view.offsetY = 8;
      expect(view.getTransform()).toEqual('translate(562,8)');
    });

    it("calculates custom translation for position top", function() {
      view.position = 'top';
      view.offsetX = 7;
      view.offsetY = 8;
      expect(view.getTransform()).toEqual('translate(7,8)');
    });

    it("calculates custom translation for position bottom", function() {
      view.position = 'bottom';
      view.offsetX = 7;
      view.offsetY = 8;
      expect(view.getTransform()).toEqual('translate(7,452)');
    });

  });

});
<|endoftext|>


<commit_before>var _ = require('../utility');
var logger = require('./logger');

function checkIgnore(item, settings) {
  var level = item.level;
  var levelVal = _.LEVELS[level] || 0;
  var reportLevel = _.LEVELS[settings.reportLevel] || 0;

  if (levelVal < reportLevel) {
    return false;
  }

  if (_.get(settings, 'plugins.jquery.ignoreAjaxErrors')) {
    return !_.get(item, 'body.message.extra.isAjax');
  }
  return true;
}

function userCheckIgnore(item, settings) {
  var isUncaught = !!item._isUncaught;
  delete item._isUncaught;
  var args = item._originalArgs;
  delete item._originalArgs;
  try {
    if (_.isFunction(settings.checkIgnore) && settings.checkIgnore(isUncaught, args, item)) {
      return false;
    }
  } catch (e) {
    settings.checkIgnore = null;
    logger.error('Error while calling custom checkIgnore(), removing', e);
  }
  return true;
}

function urlIsNotBlacklisted(item, settings) {
  return !urlIsOnAList(item, settings, 'blacklist');
}

function urlIsWhitelisted(item, settings) {
  return urlIsOnAList(item, settings, 'whitelist');
}

function urlIsOnAList(item, settings, whiteOrBlack) {
  // whitelist is the default
  var black = false;
  if (whiteOrBlack === 'blacklist') {
    black = true;
  }
  var list, trace, frame, filename, frameLength, url, listLength, urlRegex;
  var i, j;

  try {
    list = black ? settings.hostBlackList : settings.hostWhiteList;
    listLength = list && list.length;
    trace = _.get(item, 'body.trace');

    // These two checks are important to come first as they are defaults
    // in case the list is missing or the trace is missing or not well-formed
    if (!list || listLength === 0) {
      return true;
    }
    if (!trace || !trace.frames) {
      return true;
    }

    frameLength = trace.frames.length;
    for (i = 0; i < frameLength; i++) {
      frame = trace.frames[i];
      filename = frame.filename;

      if (!_.isType(filename, 'string')) {
        return true;
      }

      for (j = 0; j < listLength; j++) {
        url = list[j];
        urlRegex = new RegExp(url);

        if (urlRegex.test(filename)){
          return !black;
        }
      }
    }
  } catch (e)
  /* istanbul ignore next */
  {
    if (black) {
      settings.hostBlackList = null;
    } else {
      settings.hostWhiteList = null;
    }
    var listName = black ? 'hostBlackList' : 'hostWhiteList';
    logger.error('Error while reading your configuration\'s ' + listName + ' option. Removing custom ' + listName + '.', e);
    return true;
  }
  return black;
}

function messageIsIgnored(item, settings) {
  var exceptionMessage, i, ignoredMessages,
      len, messageIsIgnored, rIgnoredMessage,
      body, traceMessage, bodyMessage;

  try {
    messageIsIgnored = false;
    ignoredMessages = settings.ignoredMessages;

    if (!ignoredMessages || ignoredMessages.length === 0) {
      return true;
    }

    body = item.body;
    traceMessage = _.get(body, 'trace.exception.message');
    bodyMessage = _.get(body, 'message.body');

    exceptionMessage = traceMessage || bodyMessage;

    if (!exceptionMessage){
      return true;
    }

    len = ignoredMessages.length;
    for (i = 0; i < len; i++) {
      rIgnoredMessage = new RegExp(ignoredMessages[i], 'gi');
      messageIsIgnored = rIgnoredMessage.test(exceptionMessage);

      if (messageIsIgnored) {
        break;
      }
    }
  } catch(e)
  /* istanbul ignore next */
  {
    settings.ignoredMessages = null;
    logger.error('Error while reading your configuration\'s ignoredMessages option. Removing custom ignoredMessages.');
  }

  return !messageIsIgnored;
}

module.exports = {
  checkIgnore: checkIgnore,
  userCheckIgnore: userCheckIgnore,
  urlIsNotBlacklisted: urlIsNotBlacklisted,
  urlIsWhitelisted: urlIsWhitelisted,
  messageIsIgnored: messageIsIgnored
};

<commit_msg>fix blacklist<commit_after>var _ = require('../utility');
var logger = require('./logger');

function checkIgnore(item, settings) {
  var level = item.level;
  var levelVal = _.LEVELS[level] || 0;
  var reportLevel = _.LEVELS[settings.reportLevel] || 0;

  if (levelVal < reportLevel) {
    return false;
  }

  if (_.get(settings, 'plugins.jquery.ignoreAjaxErrors')) {
    return !_.get(item, 'body.message.extra.isAjax');
  }
  return true;
}

function userCheckIgnore(item, settings) {
  var isUncaught = !!item._isUncaught;
  delete item._isUncaught;
  var args = item._originalArgs;
  delete item._originalArgs;
  try {
    if (_.isFunction(settings.checkIgnore) && settings.checkIgnore(isUncaught, args, item)) {
      return false;
    }
  } catch (e) {
    settings.checkIgnore = null;
    logger.error('Error while calling custom checkIgnore(), removing', e);
  }
  return true;
}

function urlIsNotBlacklisted(item, settings) {
  return !urlIsOnAList(item, settings, 'blacklist');
}

function urlIsWhitelisted(item, settings) {
  return urlIsOnAList(item, settings, 'whitelist');
}

function urlIsOnAList(item, settings, whiteOrBlack) {
  // whitelist is the default
  var black = false;
  if (whiteOrBlack === 'blacklist') {
    black = true;
  }
  var list, trace, frame, filename, frameLength, url, listLength, urlRegex;
  var i, j;

  try {
    list = black ? settings.hostBlackList : settings.hostWhiteList;
    listLength = list && list.length;
    trace = _.get(item, 'body.trace');

    // These two checks are important to come first as they are defaults
    // in case the list is missing or the trace is missing or not well-formed
    if (!list || listLength === 0) {
      return !black;
    }
    if (!trace || !trace.frames) {
      return !black;
    }

    frameLength = trace.frames.length;
    for (i = 0; i < frameLength; i++) {
      frame = trace.frames[i];
      filename = frame.filename;

      if (!_.isType(filename, 'string')) {
        return !black;
      }

      for (j = 0; j < listLength; j++) {
        url = list[j];
        urlRegex = new RegExp(url);

        if (urlRegex.test(filename)) {
          return true;
        }
      }
    }
  } catch (e)
  /* istanbul ignore next */
  {
    if (black) {
      settings.hostBlackList = null;
    } else {
      settings.hostWhiteList = null;
    }
    var listName = black ? 'hostBlackList' : 'hostWhiteList';
    logger.error('Error while reading your configuration\'s ' + listName + ' option. Removing custom ' + listName + '.', e);
    return !black;
  }
  return false;
}

function messageIsIgnored(item, settings) {
  var exceptionMessage, i, ignoredMessages,
      len, messageIsIgnored, rIgnoredMessage,
      body, traceMessage, bodyMessage;

  try {
    messageIsIgnored = false;
    ignoredMessages = settings.ignoredMessages;

    if (!ignoredMessages || ignoredMessages.length === 0) {
      return true;
    }

    body = item.body;
    traceMessage = _.get(body, 'trace.exception.message');
    bodyMessage = _.get(body, 'message.body');

    exceptionMessage = traceMessage || bodyMessage;

    if (!exceptionMessage){
      return true;
    }

    len = ignoredMessages.length;
    for (i = 0; i < len; i++) {
      rIgnoredMessage = new RegExp(ignoredMessages[i], 'gi');
      messageIsIgnored = rIgnoredMessage.test(exceptionMessage);

      if (messageIsIgnored) {
        break;
      }
    }
  } catch(e)
  /* istanbul ignore next */
  {
    settings.ignoredMessages = null;
    logger.error('Error while reading your configuration\'s ignoredMessages option. Removing custom ignoredMessages.');
  }

  return !messageIsIgnored;
}

module.exports = {
  checkIgnore: checkIgnore,
  userCheckIgnore: userCheckIgnore,
  urlIsNotBlacklisted: urlIsNotBlacklisted,
  urlIsWhitelisted: urlIsWhitelisted,
  messageIsIgnored: messageIsIgnored
};

<|endoftext|>


<commit_before>/*!
	Adds a SQL filter to a query based on
	the resource_request object information
*/

import typs from 'typs';
import squel from 'squel';

// utilities to build concisely the name of a field in the form <table>.<column>
const naming_macros = (context) => {
	const makeFieldName = (type, field) => context.resources[type].sql_table + '.' + context.resources[type].columns[field];
	const pkFieldName = (type) => makeFieldName(type, context.resources[type].primary_key);
	return {makeFieldName, pkFieldName};
};

// adds WHERE clause to a query
export function filterBy(query, request, context) {

	const {makeFieldName, pkFieldName} = naming_macros(context);

	if (typs(request.superset).def().check()) {
		// add the next clause
		const apply_relationship_clause = (query) => {
			if (request.superset.superset !== undefined || request.superset.filters.length > 0) {
				return query.where(
					request.relationship.sql_table + '.' + request.relationship.from_key + ' IN ?',
					filterBy(
						squel.select()
							.field(pkFieldName(request.superset.type))
							.from(context.resources[request.superset.type].sql_table),
						request.superset,
						context
					)
				);
			// optimization: if we are selecting only by IDs we skip the generation
			// of a subquery and use directly a IN (<...ids>) clause
			} else if (request.superset.ids.length > 0) {
				return query.where(
					request.relationship.sql_table + '.' + request.relationship.from_key + ' IN ?',
					request.superset.ids
				);
			} else {
				return query;
			}
		};

		// we avoid to make subqueries on the same table we are quering (because DELETE wouldn't work)
		if (context.resources[request.type].sql_table === request.relationship.sql_table) {
			query = apply_relationship_clause(query);
		} else {
			query =	query.where(
				// the primary key of the request resource
				pkFieldName(request.type) + ' IN ?',
				// is in the values returned by the relationship
				apply_relationship_clause(
					squel.select()
						.field(request.relationship.sql_table + '.' + request.relationship.to_key)
						.from(request.relationship.sql_table)
				)
			);
		}
	}

	query = addFilters(request, query, context);

	return query;
}

export function addFilters(request, query, context) {

	const {makeFieldName, pkFieldName} = naming_macros(context);

	if (request.ids.length > 0) {
		query = query.where(pkFieldName(request.type) + ' IN ?', request.ids);
	}

	request.filters.forEach(({field, values}) => {
		query = query.where(makeFieldName(request.type, field) + ' IN ?', values);
	});

	request.sorters.forEach(({field, asc}) => {
		query = query.order(makeFieldName(request.type, field), asc);
	});

	return query;
}

export function selectBy (request, context) {
	// alias columns to exposed field names
	const addFields = (query, req, prefix) => {
		return req.fields.reduce((q, field) => q.field(prefix + '.' + context.resources[req.type].columns[field], prefix + '$' + field), query);
	};

	const base_alias = request.main.type;
	// base query
	let query = squel.select();

	query = query.from(context.resources[request.main.type].sql_table, base_alias);

	// related resources
	if (typs(request.related).def().check()) {

		// prefix the names with their relationship path
		const makeAlias = (r) => {
			// get all the nesting tree
			const ancestors = (rel) => {
				if (typs(rel).equals(request.main).check()) {
					return base_alias;
				} else if (typs(rel.superset).def().check()) {
					// chain the name of the relationships
					return ancestors(rel.superset).concat(rel.superset.relationship.name);
				}
				return [request.main.type];
			};
			return ancestors(r).concat(r.relationship.name).join('$');
		};

		// keep track of the joined tables
		let joined = [];

		// dig down the tree of relationships
		// and extract the correct joins to do
		// moreover, rearrange them to respect order of conditions
		const buildJoin = (rel, query) => {
			// if the relationship is deep, we have to build it to the top
			if (typs(rel.superset).def().check()) {
				query = buildJoin(rel.superset, query);
			}

			const same_table = false;//context.resources[rel.relationship.type].sql_table === rel.relationship.sql_table;
			const rel_alias = makeAlias(rel);
			const rel_info_alias = same_table ? rel_alias : rel_alias + '$info';
			const rel_superset = rel.superset || request.main;
			const rel_superset_alias = typs(rel.superset).def().check() ? makeAlias(rel.superset) : base_alias;

			if (typs(rel_info_alias).oneOf(joined).doesntCheck()) {
				// table where is stored the relationship
				query = query.left_join(
					rel.relationship.sql_table,
					rel_info_alias,
					rel_info_alias + '.' + rel.relationship.from_key +
					' = ' +
					rel_superset_alias + '.' + context.resources[rel_superset.type].primary_key
				);
				joined.push(rel_info_alias);
			}
			if (typs(rel_alias).oneOf(joined).doesntCheck() && !same_table) {
				// table where is stored the related resource
				query = query.left_join(
					context.resources[rel.relationship.type].sql_table,
					rel_alias,
					rel_alias + '.' + context.resources[rel.relationship.type].primary_key +
					' = ' +
					rel_info_alias + '.' + rel.relationship.to_key
				);
				joined.push(rel_alias);
			}

			return query;
		};

		const add_joins_fields = (rels) => {
			rels.forEach((rel) => {
				// set the fields to fetch
				query = addFields(
					// build then add the joins
					buildJoin(rel, query),
					rel,
					makeAlias(rel)
				);
			});
		};

		// add IDs for "implicit", related resources
		// inbetween directly related resources and deep related resources
		// (that's because when building a GET response, we need
		// intermediate resources ids to correctly parse joined relationships)
		let implicits = [];
		// if rel is a directly related resource, skip it,
		// otherwise we add it to the implicits collection
		const add_rel = (rel) => {
			if (rel === undefined) return;
			if (!rel.directly_requested) {
				rel.fields = [context.resources[rel.type].primary_key];
				implicits.push(rel);
			}
			add_rel(rel.superset);
		};
		request.related.forEach(add_rel);

		// add all the joins and the fields to the query
		add_joins_fields(request.related);
		add_joins_fields(implicits);
	}

	// add main resource fields
	query = addFields(filterBy(query, request.main, context), request.main, base_alias);

	return query;
}
<commit_msg>ooops (see be8925b)<commit_after>/*!
	Adds a SQL filter to a query based on
	the resource_request object information
*/

import typs from 'typs';
import squel from 'squel';

// utilities to build concisely the name of a field in the form <table>.<column>
const naming_macros = (context) => {
	const makeFieldName = (type, field) => context.resources[type].sql_table + '.' + context.resources[type].columns[field];
	const pkFieldName = (type) => makeFieldName(type, context.resources[type].primary_key);
	return {makeFieldName, pkFieldName};
};

// adds WHERE clause to a query
export function filterBy(query, request, context) {

	const {makeFieldName, pkFieldName} = naming_macros(context);

	if (typs(request.superset).def().check()) {
		// add the next clause
		const apply_relationship_clause = (query) => {
			if (request.superset.superset !== undefined || request.superset.filters.length > 0) {
				return query.where(
					request.relationship.sql_table + '.' + request.relationship.from_key + ' IN ?',
					filterBy(
						squel.select()
							.field(pkFieldName(request.superset.type))
							.from(context.resources[request.superset.type].sql_table),
						request.superset,
						context
					)
				);
			// optimization: if we are selecting only by IDs we skip the generation
			// of a subquery and use directly a IN (<...ids>) clause
			} else if (request.superset.ids.length > 0) {
				return query.where(
					request.relationship.sql_table + '.' + request.relationship.from_key + ' IN ?',
					request.superset.ids
				);
			} else {
				return query;
			}
		};

		// we avoid to make subqueries on the same table we are quering (because DELETE wouldn't work)
		if (context.resources[request.type].sql_table === request.relationship.sql_table) {
			query = apply_relationship_clause(query);
		} else {
			query =	query.where(
				// the primary key of the request resource
				pkFieldName(request.type) + ' IN ?',
				// is in the values returned by the relationship
				apply_relationship_clause(
					squel.select()
						.field(request.relationship.sql_table + '.' + request.relationship.to_key)
						.from(request.relationship.sql_table)
				)
			);
		}
	}

	query = addFilters(request, query, context);

	return query;
}

export function addFilters(request, query, context) {

	const {makeFieldName, pkFieldName} = naming_macros(context);

	if (request.ids.length > 0) {
		query = query.where(pkFieldName(request.type) + ' IN ?', request.ids);
	}

	request.filters.forEach(({field, values}) => {
		query = query.where(makeFieldName(request.type, field) + ' IN ?', values);
	});

	request.sorters.forEach(({field, asc}) => {
		query = query.order(makeFieldName(request.type, field), asc);
	});

	return query;
}

export function selectBy (request, context) {
	// alias columns to exposed field names
	const addFields = (query, req, prefix) => {
		return req.fields.reduce((q, field) => q.field(prefix + '.' + context.resources[req.type].columns[field], prefix + '$' + field), query);
	};

	const base_alias = request.main.type;
	// base query
	let query = squel.select();

	query = query.from(context.resources[request.main.type].sql_table, base_alias);

	// related resources
	if (typs(request.related).def().check()) {

		// prefix the names with their relationship path
		const makeAlias = (r) => {
			// get all the nesting tree
			const ancestors = (rel) => {
				if (typs(rel).equals(request.main).check()) {
					return base_alias;
				} else if (typs(rel.superset).def().check()) {
					// chain the name of the relationships
					return ancestors(rel.superset).concat(rel.superset.relationship.name);
				}
				return [request.main.type];
			};
			return ancestors(r).concat(r.relationship.name).join('$');
		};

		// keep track of the joined tables
		let joined = [];

		// dig down the tree of relationships
		// and extract the correct joins to do
		// moreover, rearrange them to respect order of conditions
		const buildJoin = (rel, query) => {
			// if the relationship is deep, we have to build it to the top
			if (typs(rel.superset).def().check()) {
				query = buildJoin(rel.superset, query);
			}

			const same_table = context.resources[rel.relationship.type].sql_table === rel.relationship.sql_table;
			const rel_alias = makeAlias(rel);
			const rel_info_alias = same_table ? rel_alias : rel_alias + '$info';
			const rel_superset = rel.superset || request.main;
			const rel_superset_alias = typs(rel.superset).def().check() ? makeAlias(rel.superset) : base_alias;

			if (typs(rel_info_alias).oneOf(joined).doesntCheck()) {
				// table where is stored the relationship
				query = query.left_join(
					rel.relationship.sql_table,
					rel_info_alias,
					rel_info_alias + '.' + rel.relationship.from_key +
					' = ' +
					rel_superset_alias + '.' + context.resources[rel_superset.type].primary_key
				);
				joined.push(rel_info_alias);
			}
			if (typs(rel_alias).oneOf(joined).doesntCheck() && !same_table) {
				// table where is stored the related resource
				query = query.left_join(
					context.resources[rel.relationship.type].sql_table,
					rel_alias,
					rel_alias + '.' + context.resources[rel.relationship.type].primary_key +
					' = ' +
					rel_info_alias + '.' + rel.relationship.to_key
				);
				joined.push(rel_alias);
			}

			return query;
		};

		const add_joins_fields = (rels) => {
			rels.forEach((rel) => {
				// set the fields to fetch
				query = addFields(
					// build then add the joins
					buildJoin(rel, query),
					rel,
					makeAlias(rel)
				);
			});
		};

		// add IDs for "implicit", related resources
		// inbetween directly related resources and deep related resources
		// (that's because when building a GET response, we need
		// intermediate resources ids to correctly parse joined relationships)
		let implicits = [];
		// if rel is a directly related resource, skip it,
		// otherwise we add it to the implicits collection
		const add_rel = (rel) => {
			if (rel === undefined) return;
			if (!rel.directly_requested) {
				rel.fields = [context.resources[rel.type].primary_key];
				implicits.push(rel);
			}
			add_rel(rel.superset);
		};
		request.related.forEach(add_rel);

		// add all the joins and the fields to the query
		add_joins_fields(request.related);
		add_joins_fields(implicits);
	}

	// add main resource fields
	query = addFields(filterBy(query, request.main, context), request.main, base_alias);

	return query;
}
<|endoftext|>