<commit_before>import Ember from 'ember';
import environment from '../config/environment';

const { COUCHDB_HOST } = environment;

const {
  Logger: { info }
} = Ember;

const databaseMapping = {
  main: 'thing',
  _users: '_users'
};

const url = `${COUCHDB_HOST}:6016`;

export default {
  name: 'dummy:dev',
  initialize(app) {
    let stores = app.lookup('documents:stores');

    let store = stores.store({
      url,
      databaseNameForIdentifier: identifier => databaseMapping[identifier]
    });

    store.enableFastBootWithIdentifier('dummy-documents');

    let db = store.database('main');

    let changes = db.changes({ feed: 'event-source' });
    changes.start();

    app.register('service:stores', stores, { instantiate: false });
    app.register('service:store', store, { instantiate: false });
    app.register('service:db', db, { instantiate: false });

    window.log = info;
    window.stores = stores;
    window.store = store;
    window.db = db;
    window.recreate = () => db.get('documents.database').recreate({ documents: true, design: true });

    app.inject('route', 'store', 'service:store');
    app.inject('route', 'db', 'service:db');
    app.inject('component', 'store', 'service:store');
    app.inject('component', 'db', 'service:db');

    window.author = db.doc({
      id: 'author:ampatspell',
      type: 'author',
      name: 'ampatspell'
    });

    window.blog = db.doc({
      id: 'blog:ducks',
      type: 'blog',
      title: 'The Ducks',
      owner: 'author:ampatspell'
    });

    window.post = db.doc({
      id: 'blog-post:ducks:one',
      type: 'blog-post',
      title: 'Welcome',
      owner: 'author:ampatspell',
      blog: 'blog:ducks'
    });

  }
};
<commit_msg>dummy<commit_after>import Ember from 'ember';
import environment from '../config/environment';

const { COUCHDB_HOST } = environment;

const {
  Logger: { info }
} = Ember;

const databaseMapping = {
  main: 'thing',
  _users: '_users'
};

const url = `${COUCHDB_HOST}:6016`;

export default {
  name: 'dummy:dev',
  initialize(app) {
    let stores = app.lookup('documents:stores');

    let store = stores.store({
      url,
      databaseNameForIdentifier: identifier => databaseMapping[identifier],
      // fastbootIdentifier: 'dummy-ducments'
    });

    store.enableFastBootWithIdentifier('dummy-documents');

    let db = store.database('main');

    let changes = db.changes({ feed: [ 'event-source', 'long-polling' ] });
    changes.start();

    app.register('service:stores', stores, { instantiate: false });
    app.register('service:store', store, { instantiate: false });
    app.register('service:db', db, { instantiate: false });

    window.log = info;
    window.stores = stores;
    window.store = store;
    window.db = db;
    window.recreate = () => db.get('documents.database').recreate({ documents: true, design: true });

    app.inject('route', 'store', 'service:store');
    app.inject('route', 'db', 'service:db');
    app.inject('component', 'store', 'service:store');
    app.inject('component', 'db', 'service:db');

    window.author = db.doc({
      id: 'author:ampatspell',
      type: 'author',
      name: 'ampatspell'
    });

    window.blog = db.doc({
      id: 'blog:ducks',
      type: 'blog',
      title: 'The Ducks',
      owner: 'author:ampatspell'
    });

    window.post = db.doc({
      id: 'blog-post:ducks:one',
      type: 'blog-post',
      title: 'Welcome',
      owner: 'author:ampatspell',
      blog: 'blog:ducks'
    });

  }
};
<|endoftext|>


<commit_before>var shell = require('shelljs')

if(process.env.CI !== 'true' && shell.exec('npm run build --color=always').code != 0){
  shell.exit(1);
}

if(shell.exec('ava test/**/*.js --color=always').code != 0){
  shell.exit(1);
}<commit_msg>Removed build from test, as we are testing from src/<commit_after>var shell = require('shelljs')

if(shell.exec('ava test/**/*.js --color=always').code != 0){
  shell.exit(1);
}<|endoftext|>


<commit_before>let coreDependencies = require('ima/build.js');
let path = require('path');
let sharedTasksState = require('./gulpState');
let macroTasks = require('./macroTasks.js');

let appDependencies;
try {
  appDependencies = require(path.resolve('.', 'app/build.js'));
} catch (error) {
  console.info(error.message);
  console.info('The default application dependencies will be used.');

  appDependencies = {
    js: [],
    languages: [],
    less: [],
    vendors: {
      common: [],
      server: [],
      client: []
    },
    bundle: {
      js: [],
      es: [],
      css: []
    }
  };
}

let vendorOptions = {
  debug: false,
  insertGlobals: false,
  basedir: '.',
  cache: {},
  packageCache: {},
  noParse: ['clone']
};
let babelConfig = {
  esVendor: {
    presets: ['react'],
    plugins: ['external-helpers'],
    options: Object.assign({}, vendorOptions)
  },
  vendor: {
    presets: ['es2017', 'es2016', ['es2015', { loose: true }], 'react'],
    plugins: ['external-helpers'],
    options: Object.assign({}, vendorOptions)
  },
  serverApp: {
    presets: ['react'],
    plugins: ['transform-es2015-modules-systemjs', 'external-helpers']
  },
  esApp: {
    presets: [],
    plugins: ['external-helpers']
  },
  app: {
    presets: ['es2017', 'es2016', ['es2015', { loose: true }]],
    plugins: ['external-helpers']
  },
  server: {
    presets: ['react'],
    plugins: ['transform-es2015-modules-commonjs']
  }
};
let $Debug = true;
let legacyCompactMode = false;

if (['production', 'prod', 'test'].includes(process.env.NODE_ENV)) {
  const esPlugins = [
    'transform-react-constant-elements',
    'transform-react-inline-elements',
    'transform-react-remove-prop-types'
  ];
  babelConfig.esApp.plugins = babelConfig.esApp.plugins.concat(esPlugins);
  babelConfig.esVendor.plugins = babelConfig.esVendor.plugins.concat(esPlugins);
  $Debug = false;
  legacyCompactMode = true;
}

if (
  ['dev', undefined].includes(process.env.NODE_ENV) &&
  (process.argv.some(arg => /^--legacy-compat-mode$/.test(arg)) ||
    Object.keys(process.env).includes('npm_config_legacy_compat_mode'))
) {
  legacyCompactMode = true;
}

exports.legacyCompactMode = legacyCompactMode;
exports.babelConfig = babelConfig;
exports.$Debug = $Debug;

exports.uglifyCompression = {
  global_defs: {
    $Debug: $Debug
  },
  ecma: 6,
  dead_code: true
};

exports.vendorDependencies = {
  common: coreDependencies.vendors.common.concat(
    appDependencies.vendors.common
  ),
  server: coreDependencies.vendors.server.concat(
    appDependencies.vendors.server
  ),
  client: coreDependencies.vendors.client.concat(
    appDependencies.vendors.client
  ),
  test: coreDependencies.vendors.test.concat(appDependencies.vendors.test)
};

exports.tasks = {
  dev: macroTasks.DEFAULT_DEV_SUBTASKS,
  build: macroTasks.DEFAULT_BUILD_SUBTASKS,
  spa: macroTasks.DEFAULT_SPA_SUBTASKS
};

exports.files = {
  vendor: {
    src: {
      client: 'vendor.client.src.js'
    },
    name: {
      server: 'vendor.server.js',
      esClient: 'vendor.client.es.js',
      client: 'vendor.client.js'
    },
    dest: {
      server: './build/ima/',
      client: './build/static/js/',
      tmp: './build/ima/'
    },
    watch: ['./app/build.js', './ima/build.js']
  },
  app: {
    name: {
      server: 'app.server.js',
      client: 'app.client.js',
      esClient: 'app.client.es.js'
    },
    clearServerSide: ['production', 'prod', 'test'].includes(
      process.env.NODE_ENV
    ),
    src: [].concat(appDependencies.js, appDependencies.mainjs),
    dest: {
      server: './build/ima/',
      client: './build/static/js/'
    },
    watch: ['./app/**/*.{js,jsx}', './app/main.js', '!./app/environment.js']
  },
  server: {
    cwd: '/',
    src: ['./server/*.js', './server/**/*.js'],
    base: './server/',
    dest: './build/',
    watch: [
      './server/*.js',
      './server/**/*.js',
      './app/*.js',
      '!./server/ima/config/*.js'
    ]
  },
  less: {
    cwd: '/',
    base: './app/assets/less/',
    name: './app/assets/less/app.less',
    src: appDependencies.less,
    dest: './build/static/css/',
    watch: ['./app/**/*.less', '!./app/assets/bower/']
  },
  locale: {
    src: appDependencies.languages,
    dest: {
      server: './build/ima/locale/',
      client: './build/static/js/locale/'
    },
    watch: ['./app/**/*.json']
  },
  shim: {
    js: {
      name: 'shim.js',
      src: ['./node_modules/ima/polyfill/collectionEnumeration.js'],
      dest: {
        client: './build/static/js/'
      }
    },
    es: {
      name: 'shim.es.js',
      src: [],
      dest: {
        client: './build/static/js/',
        server: './build/ima/'
      }
    }
  },
  polyfill: {
    js: {
      name: 'polyfill.js',
      src: [
        './node_modules/babel-polyfill/dist/polyfill.min.js',
        './node_modules/custom-event-polyfill/custom-event-polyfill.js'
      ],
      dest: {
        client: './build/static/js/'
      }
    },
    es: {
      name: 'polyfill.es.js',
      src: [],
      dest: {
        client: './build/static/js/'
      }
    },
    fetch: {
      name: 'fetch-polyfill.js',
      src: [
        './node_modules/core-js/client/shim.min.js',
        './node_modules/whatwg-fetch/fetch.js'
      ],
      dest: {
        client: './build/static/js/'
      }
    }
  },
  bundle: {
    js: {
      name: 'app.bundle.min.js',
      src: appDependencies.bundle.js,
      dest: './build/static/js/'
    },
    es: {
      name: 'app.bundle.es.min.js',
      src: appDependencies.bundle.es,
      dest: './build/static/js/'
    },
    css: {
      name: 'app.bundle.min.css',
      src: appDependencies.bundle.css,
      dest: './build/static/css/'
    }
  }
};

exports.onTerminate = () => {
  if (sharedTasksState.karmaServer) {
    sharedTasksState.karmaServer.stop();
  }

  setTimeout(() => {
    process.exit();
  });
};
<commit_msg>#! set transform-react-jsx to using Object.assign instead of babel's extend helper<commit_after>let coreDependencies = require('ima/build.js');
let path = require('path');
let sharedTasksState = require('./gulpState');
let macroTasks = require('./macroTasks.js');

let appDependencies;
try {
  appDependencies = require(path.resolve('.', 'app/build.js'));
} catch (error) {
  console.info(error.message);
  console.info('The default application dependencies will be used.');

  appDependencies = {
    js: [],
    languages: [],
    less: [],
    vendors: {
      common: [],
      server: [],
      client: []
    },
    bundle: {
      js: [],
      es: [],
      css: []
    }
  };
}

let vendorOptions = {
  debug: false,
  insertGlobals: false,
  basedir: '.',
  cache: {},
  packageCache: {},
  noParse: ['clone']
};
let babelConfig = {
  esVendor: {
    presets: ['react'],
    plugins: ['external-helpers', ["transform-react-jsx", { "useBuiltIns": true }]],
    options: Object.assign({}, vendorOptions)
  },
  vendor: {
    presets: ['es2017', 'es2016', ['es2015', { loose: true }], 'react'],
    plugins: ['external-helpers', ["transform-react-jsx", { "useBuiltIns": true }]],
    options: Object.assign({}, vendorOptions)
  },
  serverApp: {
    presets: ['react'],
    plugins: ['transform-es2015-modules-systemjs', 'external-helpers', ["transform-react-jsx", { "useBuiltIns": true }]]
  },
  esApp: {
    presets: [],
    plugins: ['external-helpers']
  },
  app: {
    presets: ['es2017', 'es2016', ['es2015', { loose: true }]],
    plugins: ['external-helpers']
  },
  server: {
    presets: ['react'],
    plugins: ['transform-es2015-modules-commonjs', ["transform-react-jsx", { "useBuiltIns": true }]]
  }
};
let $Debug = true;
let legacyCompactMode = false;

if (['production', 'prod', 'test'].includes(process.env.NODE_ENV)) {
  const esPlugins = [
    'transform-react-constant-elements',
    'transform-react-inline-elements',
    'transform-react-remove-prop-types'
  ];
  babelConfig.esApp.plugins = babelConfig.esApp.plugins.concat(esPlugins);
  babelConfig.esVendor.plugins = babelConfig.esVendor.plugins.concat(esPlugins);
  $Debug = false;
  legacyCompactMode = true;
}

if (
  ['dev', undefined].includes(process.env.NODE_ENV) &&
  (process.argv.some(arg => /^--legacy-compat-mode$/.test(arg)) ||
    Object.keys(process.env).includes('npm_config_legacy_compat_mode'))
) {
  legacyCompactMode = true;
}

exports.legacyCompactMode = legacyCompactMode;
exports.babelConfig = babelConfig;
exports.$Debug = $Debug;

exports.uglifyCompression = {
  global_defs: {
    $Debug: $Debug
  },
  ecma: 6,
  dead_code: true
};

exports.vendorDependencies = {
  common: coreDependencies.vendors.common.concat(
    appDependencies.vendors.common
  ),
  server: coreDependencies.vendors.server.concat(
    appDependencies.vendors.server
  ),
  client: coreDependencies.vendors.client.concat(
    appDependencies.vendors.client
  ),
  test: coreDependencies.vendors.test.concat(appDependencies.vendors.test)
};

exports.tasks = {
  dev: macroTasks.DEFAULT_DEV_SUBTASKS,
  build: macroTasks.DEFAULT_BUILD_SUBTASKS,
  spa: macroTasks.DEFAULT_SPA_SUBTASKS
};

exports.files = {
  vendor: {
    src: {
      client: 'vendor.client.src.js'
    },
    name: {
      server: 'vendor.server.js',
      esClient: 'vendor.client.es.js',
      client: 'vendor.client.js'
    },
    dest: {
      server: './build/ima/',
      client: './build/static/js/',
      tmp: './build/ima/'
    },
    watch: ['./app/build.js', './ima/build.js']
  },
  app: {
    name: {
      server: 'app.server.js',
      client: 'app.client.js',
      esClient: 'app.client.es.js'
    },
    clearServerSide: ['production', 'prod', 'test'].includes(
      process.env.NODE_ENV
    ),
    src: [].concat(appDependencies.js, appDependencies.mainjs),
    dest: {
      server: './build/ima/',
      client: './build/static/js/'
    },
    watch: ['./app/**/*.{js,jsx}', './app/main.js', '!./app/environment.js']
  },
  server: {
    cwd: '/',
    src: ['./server/*.js', './server/**/*.js'],
    base: './server/',
    dest: './build/',
    watch: [
      './server/*.js',
      './server/**/*.js',
      './app/*.js',
      '!./server/ima/config/*.js'
    ]
  },
  less: {
    cwd: '/',
    base: './app/assets/less/',
    name: './app/assets/less/app.less',
    src: appDependencies.less,
    dest: './build/static/css/',
    watch: ['./app/**/*.less', '!./app/assets/bower/']
  },
  locale: {
    src: appDependencies.languages,
    dest: {
      server: './build/ima/locale/',
      client: './build/static/js/locale/'
    },
    watch: ['./app/**/*.json']
  },
  shim: {
    js: {
      name: 'shim.js',
      src: ['./node_modules/ima/polyfill/collectionEnumeration.js'],
      dest: {
        client: './build/static/js/'
      }
    },
    es: {
      name: 'shim.es.js',
      src: [],
      dest: {
        client: './build/static/js/',
        server: './build/ima/'
      }
    }
  },
  polyfill: {
    js: {
      name: 'polyfill.js',
      src: [
        './node_modules/babel-polyfill/dist/polyfill.min.js',
        './node_modules/custom-event-polyfill/custom-event-polyfill.js'
      ],
      dest: {
        client: './build/static/js/'
      }
    },
    es: {
      name: 'polyfill.es.js',
      src: [],
      dest: {
        client: './build/static/js/'
      }
    },
    fetch: {
      name: 'fetch-polyfill.js',
      src: [
        './node_modules/core-js/client/shim.min.js',
        './node_modules/whatwg-fetch/fetch.js'
      ],
      dest: {
        client: './build/static/js/'
      }
    }
  },
  bundle: {
    js: {
      name: 'app.bundle.min.js',
      src: appDependencies.bundle.js,
      dest: './build/static/js/'
    },
    es: {
      name: 'app.bundle.es.min.js',
      src: appDependencies.bundle.es,
      dest: './build/static/js/'
    },
    css: {
      name: 'app.bundle.min.css',
      src: appDependencies.bundle.css,
      dest: './build/static/css/'
    }
  }
};

exports.onTerminate = () => {
  if (sharedTasksState.karmaServer) {
    sharedTasksState.karmaServer.stop();
  }

  setTimeout(() => {
    process.exit();
  });
};
<|endoftext|>


<commit_before>const Promise = require('bluebird');

const server = require('./../../server.js');

const Models = server.sequelize.models;
const SLocation = Models.Location;

const Service = {
  getLocationsList: () => {
    const processedLocations = [];
    return SLocation.findAll().then(rawLocations => new Promise((resolve) => {
      rawLocations.forEach((location) => {
        processedLocations.push({
          id: location.id,
          name: location.name,
          latitude: location.latitude,
          longitude: location.longitude,
          radius: location.radius,
        });
      });
      resolve(processedLocations);
    }), error => new Promise((_, reject) => reject(error)));
  },
  createLocation: (location) => {
    const DEFAULT_LOCATION = {
      name: 'DEFAULT',
      latitude: 33.9698,
      longitude: -118.4169,
      radius: 0.003,
    };

    const data = DEFAULT_LOCATION;
    data.name = location.name || data.name;
    data.latitude = location.latitude || data.latitude;
    data.longitude = location.longitude || data.longitude;
    data.radius = location.radius || data.radius;

    return SLocation.create(data).then(rawLocation => new Promise((resolve) => {
      resolve({
        id: rawLocation.id,
        name: rawLocation.name,
        latitude: rawLocation.latitude,
        longitude: rawLocation.longitude,
        radius: rawLocation.radius,
      });
    }), error => new Promise((_, reject) => reject(error)));
  },
  getLocation: id => SLocation.findById(id).then(rawLocation => new Promise((resolve) => {
    if (!rawLocation) resolve({});
    resolve({
      id: rawLocation.id,
      name: rawLocation.name,
      latitude: rawLocation.latitude,
      longitude: rawLocation.longitude,
      radius: rawLocation.radius,
    });
  }), error => new Promise((_, reject) => reject(error))),
};

module.exports = Service;
<commit_msg>Added service to count devices at location<commit_after>const Promise = require('bluebird');

const server = require('./../../server.js');
const CollectionService = require('./../Collection/Service.js');

const Models = server.sequelize.models;
const SLocation = Models.Location;

const Service = {
  getLocationsList: () => {
    const processedLocations = [];
    return SLocation.findAll().then(rawLocations => new Promise((resolve) => {
      rawLocations.forEach((location) => {
        processedLocations.push({
          id: location.id,
          name: location.name,
          latitude: location.latitude,
          longitude: location.longitude,
          radius: location.radius,
        });
      });
      resolve(processedLocations);
    }));
  },
  createLocation: (location) => {
    const DEFAULT_LOCATION = {
      name: 'DEFAULT',
      latitude: 33.9698,
      longitude: -118.4169,
      radius: 0.003,
    };

    const data = DEFAULT_LOCATION;
    data.name = location.name || data.name;
    data.latitude = location.latitude || data.latitude;
    data.longitude = location.longitude || data.longitude;
    data.radius = location.radius || data.radius;

    return SLocation.create(data).then(rawLocation => new Promise((resolve) => {
      resolve({
        id: rawLocation.id,
        name: rawLocation.name,
        latitude: rawLocation.latitude,
        longitude: rawLocation.longitude,
        radius: rawLocation.radius,
      });
    }));
  },
  getLocation: id => SLocation.findById(id).then(rawLocation => new Promise((resolve) => {
    if (!rawLocation) resolve({});
    resolve({
      id: rawLocation.id,
      name: rawLocation.name,
      latitude: rawLocation.latitude,
      longitude: rawLocation.longitude,
      radius: rawLocation.radius,
    });
  })),
  getLocationCount: id => SLocation.findById(id).then((location) => {
    return CollectionService.getAddressesWithinRange({
      latitude: location.latitude,
      longitude: location.longitude,
      radius: location.radius,
    });
  }),
};

module.exports = Service;
<|endoftext|>


<commit_before>var models = require('../../models');
var formidable = require('formidable');
var config = require('../../config.js');
var knox = require('knox');
var path = require('path');
var util = require('./util');
var passport = require('passport');
require('../../passportConfig')(passport);

module.exports = function(app, baseUrl) {
  var apiUrl = baseUrl + '/audiorecordings';

  app.post(apiUrl, passport.authenticate(['jwt', 'anonymous'], { session: false }), function(req,
    res) {
    var device = req.user; // passport put the jwt in the user field. But for us it's a device.
    //TODO check that device is valid. Id not redirect to device authentication..

    util.fileAndDataFromPost(req)
      .then(function(result) {
        var file = result.file;
        var data = result.data;
        var messages = [];
        var errorMessages = [];

        // Generate file URL
        var date = util.getDateFromMetadata(data);
        var s3Path = util.s3PathFromDate(date) + path.extname(file.name);

        // Create IR Video Recording and save to database.
        var model = models.AudioRecording.build(
          data, {
            fields: models.AudioRecording.apiSettableFields // Limit what fields can be set by the user.
          });

        // Add device data to recording.
        if (typeof device != 'undefined') {
          console.log(device.id);
          model.setDataValue('DeviceId', device.id); // From JWT.
          model.setDataValue('GroupId', device.GroupId); // FROM JWT.
          if (typeof device.public == 'boolean')
            model.setDataValue('public', device.public); // From JWT TODO Check if this has been updated.
        } else {
          console.log("No device found");
          model.public = true; //TODO Remove this after add redirect for failed device authentication is added.
        }

        // Save model to database.
        model.save()
          .then(function() { // Successful post.
            messages.push("Thanks for the Audio Recording!");
            util.handleResponse(res, {
              success: true,
              statusCode: 200,
              messages: messages
            });
          })
          .catch(function(err) { // Upload to database failed.
            util.serverErrorResponse(res, err);
          });

        // Upload file.
        util.convertAudio(file)
          .then(function(convertedAudio) {
            return util.uploadToS3(convertedAudio, s3Path);
          })
          .then(function(res) {
            if (res.statusCode == 200) {
              console.log("Uploaded File.");
              model.uploadFileSuccess(res);
            } else {
              console.log("Upload failed.");
              //model.uploadFileError(res); //TODO add
            }
          })
          .catch(function(err) {
            console.log("Upload error");
            console.log(err);
            //model.uploadFileError(err); //TODO add
          });
      })
      .catch(function(err) { // Erorr with parsing post.
        handleResponse(err);
      });
  });

  /**
   *  Get request for Audio Recordings.
   *  headers.where,  Sequelize conditions for query,
   *  headres.offset, Query offset.
   *  headers.limit,  Query results limit.
   */
  app.get(apiUrl, passport.authenticate(['jwt', 'anonymous'], { session: false }),
    function(req, res) {
      var queryParams = util.getSequelizeQueryFromHeaders(req);
      // Return HTTP 400 if error when getting query from headers.
      if (queryParams.error) {
        return util.handleResponse(res, {
          success: false,
          statusCode: 400,
          messages: queryParams.errMsgs
        });
      }

      // Check if authorization of a User by JWT failed.
      if (!req.user && req.headers.authorization) {
        //TODO Redirect to login page, note on login page that can can query an anonymous user but will not see recording private to that user.
        //TODO maybe I can set up the anonymous passport to do this?
      }

      // Request was valid. Now quering database.
      models.AudioRecording.findAllWithUser(req.user, queryParams)
        .then(function(models) {
          var result = [];
          for (key in models) result.push(models[key].getFrontendFields());
          return util.handleResponse(res, {
            success: true,
            statusCode: 200,
            messages: ["Successful request."],
            result: result
          })
        })
    });
}
<commit_msg>Rejects audio recordings from devices that are not registered.<commit_after>var models = require('../../models');
var formidable = require('formidable');
var config = require('../../config.js');
var knox = require('knox');
var path = require('path');
var util = require('./util');
var passport = require('passport');
require('../../passportConfig')(passport);

module.exports = function(app, baseUrl) {
  var apiUrl = baseUrl + '/audiorecordings';

  app.post(apiUrl, passport.authenticate(['jwt', 'anonymous'], { session: false }), function(req,
    res) {
    var device = req.user; // passport put the jwt in the user field. But for us it's a device.
    //TODO check that device is valid. Id not redirect to device authentication..
    if (typeof device == 'undefined') {
      console.log("No device found in audio recordign.");
      return util.handleResponse(res, {
        success: false,
        statusCode: 400,
        messages: ['No device with audio recording.']
      });
    }

    util.fileAndDataFromPost(req)
      .then(function(result) {
        var file = result.file;
        var data = result.data;
        var messages = [];
        var errorMessages = [];

        // Generate file URL
        var date = util.getDateFromMetadata(data);
        var s3Path = util.s3PathFromDate(date) + path.extname(file.name);

        // Create IR Video Recording and save to database.
        var model = models.AudioRecording.build(
          data, {
            fields: models.AudioRecording.apiSettableFields // Limit what fields can be set by the user.
          });

        // Add device data to recording.
        model.setDataValue('DeviceId', device.id); // From JWT.
        model.setDataValue('GroupId', device.GroupId); // FROM JWT.
        if (typeof device.public == 'boolean')
          model.setDataValue('public', device.public); // From JWT TODO Check if this has been updated.
        else
          model.setDataValue('public', false);  // Not public by defult.

        // Save model to database.
        model.save()
          .then(function() { // Successful post.
            messages.push("Thanks for the Audio Recording!");
            util.handleResponse(res, {
              success: true,
              statusCode: 200,
              messages: messages
            });
          })
          .catch(function(err) { // Upload to database failed.
            util.serverErrorResponse(res, err);
          });

        // Upload file.
        util.convertAudio(file)
          .then(function(convertedAudio) {
            return util.uploadToS3(convertedAudio, s3Path);
          })
          .then(function(res) {
            if (res.statusCode == 200) {
              console.log("Uploaded File.");
              model.uploadFileSuccess(res);
            } else {
              console.log("Upload failed.");
              //model.uploadFileError(res); //TODO add
            }
          })
          .catch(function(err) {
            console.log("Upload error");
            //model.uploadFileError(err); //TODO add
          });
      })
      .catch(function(err) { // Erorr with parsing post.
        console.log("Error with parsing post.");
        util.serverErrorResponse(res, err);
      });
  });

  /**
   *  Get request for Audio Recordings.
   *  headers.where,  Sequelize conditions for query,
   *  headres.offset, Query offset.
   *  headers.limit,  Query results limit.
   */
  app.get(apiUrl, passport.authenticate(['jwt', 'anonymous'], { session: false }),
    function(req, res) {
      var queryParams = util.getSequelizeQueryFromHeaders(req);
      // Return HTTP 400 if error when getting query from headers.
      if (queryParams.error) {
        return util.handleResponse(res, {
          success: false,
          statusCode: 400,
          messages: queryParams.errMsgs
        });
      }

      // Check if authorization of a User by JWT failed.
      if (!req.user && req.headers.authorization) {
        //TODO Redirect to login page, note on login page that can can query an anonymous user but will not see recording private to that user.
        //TODO maybe I can set up the anonymous passport to do this?
      }

      // Request was valid. Now quering database.
      models.AudioRecording.findAllWithUser(req.user, queryParams)
        .then(function(models) {
          var result = [];
          for (var key in models) result.push(models[key].getFrontendFields());
          return util.handleResponse(res, {
            success: true,
            statusCode: 200,
            messages: ["Successful request."],
            result: result
          });
        });
    });
};
<|endoftext|>


<commit_before>import Ember from 'ember';
import {moduleForComponent, test} from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('ember-youtube', 'Integration | Component | ember youtube', {
	integration: true
});

test('it renders', function (assert) {
	assert.expect(2);
	// Set any properties with this.set('myProperty', 'value');
	// Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +

	this.render(hbs`{{ember-youtube}}`);

	assert.equal(this.$().text().trim(), '', 'starts empty');

	// Template block usage:" + EOL +
	this.render(hbs`
		{{#ember-youtube}}
			template block text
		{{/ember-youtube}}
	`);
	assert.equal(this.$('.EmberYoutube-yield').text().trim(), 'template block text', 'yield is wrapped in an extra <div>');
});

test('it can show and remove controls', function (assert) {
	assert.expect(3);
	this.set('controls', true);
	this.render(hbs`{{ember-youtube showControls=controls}}`);
	assert.ok(this.$('.EmberYoutube-controls button').length);
	assert.equal(this.$('.EmberYoutube-controls button').eq(0).text().trim(), 'Play');
	this.set('controls', false);
	assert.notOk(this.$('.EmberYoutube-controls button').length);
});

test('it can show and hide progress', function (assert) {
	assert.expect(2);
	this.set('progress', false);
	this.render(hbs`{{ember-youtube showProgress=progress}}`);
	assert.equal(this.$('.EmberYoutube-progress').length, 0, 'Progress is hidden by default');
	this.set('progress', true);
	assert.equal(this.$('.EmberYoutube-progress').length, 1, 'Progress can be shown');
});

test('it has an iframe', function (assert) {
	const done = assert.async();
	this.set('youtubeVideoId', 'fZ7MhTRmJ60');
	this.render(hbs`{{ember-youtube ytid=youtubeVideoId}}`);
	// It takes some time before the youtube api is loaded,
	// how do we avoid the timeout?
	Ember.run.later(this, function () {
		assert.ok(this.$('iframe').length);
		done();
	}, 1000);
});
<commit_msg>Fix async tests<commit_after>// import Ember from 'ember';
import {moduleForComponent, test} from 'ember-qunit';
import wait from 'ember-test-helpers/wait';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('ember-youtube', 'Integration | Component | ember youtube', {
	integration: true
});

test('it loads the youtubeapi and create an iframe', function (assert) {
	this.set('youTubeId', 'w311Hd4K_Fk');
	this.render(hbs`{{ember-youtube ytid=youTubeId}}`);
	return wait().then(() => {
		return wait().then(() => {
			// it needs a double wait for whatever reason
			assert.ok(this.$('iframe').length, 'has iframe');
		});
	});
});

// Todo: create a promise so we can assert autoplay is working
// test('it can autoplay', function (assert) {
// 	this.set('youTubeId', 'w311Hd4K_Fk');
// 	this.set('myPlayerVars', {autoplay: 1});
// 	this.render(hbs`{{ember-youtube ytid=youTubeId showControls=true playerVars=myPlayerVars}}`);
// 	// console.log(this.$('.EmberYoutube-controls button').eq(0).text());
// 	return wait().then(() => {
// 		// it needs a double wait for whatever reason
// 		return wait().then(() => {
// 			assert.ok(this.$('iframe').length, 'has iframe');
// 			// var btnText = this.$('.EmberYoutube-controls button').eq(0).text();
// 			// assert.equal(btnText, 'pause');
// 		});
// 	});
// });

test('it can show and remove controls', function (assert) {
	assert.expect(3);
	this.set('controls', true);
	this.render(hbs`{{ember-youtube showControls=controls}}`);
	assert.ok(this.$('.EmberYoutube-controls button').length);
	assert.equal(this.$('.EmberYoutube-controls button').eq(0).text().trim(), 'Play');
	this.set('controls', false);
	assert.notOk(this.$('.EmberYoutube-controls button').length);
});

test('it can show and hide progress', function (assert) {
	assert.expect(2);
	this.set('progress', false);
	this.render(hbs`{{ember-youtube showProgress=progress}}`);
	assert.equal(this.$('.EmberYoutube-progress').length, 0, 'Progress is hidden by default');
	this.set('progress', true);
	assert.equal(this.$('.EmberYoutube-progress').length, 1, 'Progress can be shown');
});
<|endoftext|>


<commit_before>'use strict';

const userMiddleware = require('../middlewares/user');
const errorMiddleware = require('../middlewares/error');
const authorizationMiddleware = require('../middlewares/authorization');
const connectionParamsMiddleware = require('../middlewares/connection-params');
const { initializeProfilerMiddleware } = require('../middlewares/profiler');
const rateLimitsMiddleware = require('../middlewares/rate-limit');
const dbQuotaMiddleware = require('../middlewares/db-quota');
const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimitsMiddleware;
const errorHandlerFactory = require('../services/error_handler_factory');
const StreamCopy = require('../services/stream_copy');
const StreamCopyMetrics = require('../services/stream_copy_metrics');
const zlib = require('zlib');
const { PassThrough } = require('stream');

function CopyController(metadataBackend, userDatabaseService, userLimitsService, logger) {
    this.metadataBackend = metadataBackend;
    this.userDatabaseService = userDatabaseService;
    this.userLimitsService = userLimitsService;
    this.logger = logger;
}

CopyController.prototype.route = function (app) {
    const { base_url } = global.settings;

    const copyFromMiddlewares = endpointGroup => {
        return [
            initializeProfilerMiddleware('copyfrom'),
            userMiddleware(this.metadataBackend),
            rateLimitsMiddleware(this.userLimitsService, endpointGroup),
            authorizationMiddleware(this.metadataBackend),
            connectionParamsMiddleware(this.userDatabaseService),
            validateCopyQuery(),
            dbQuotaMiddleware(),
            handleCopyFrom(this.logger),
            errorHandler(),
            errorMiddleware()
        ];
    };

    const copyToMiddlewares = endpointGroup => {
        return [
            initializeProfilerMiddleware('copyto'),
            userMiddleware(this.metadataBackend),
            rateLimitsMiddleware(this.userLimitsService, endpointGroup),
            authorizationMiddleware(this.metadataBackend),
            connectionParamsMiddleware(this.userDatabaseService),
            validateCopyQuery(),
            handleCopyTo(this.logger),
            errorHandler(),
            errorMiddleware()
        ];
    };

    app.post(`${base_url}/sql/copyfrom`, copyFromMiddlewares(RATE_LIMIT_ENDPOINTS_GROUPS.COPY_FROM));
    app.get(`${base_url}/sql/copyto`, copyToMiddlewares(RATE_LIMIT_ENDPOINTS_GROUPS.COPY_TO));
};

function handleCopyTo (logger) {
    return function handleCopyToMiddleware (req, res, next) {
        const sql = req.query.q;
        const { userDbParams, user } = res.locals;
        const filename = req.query.filename || 'carto-sql-copyto.dmp';

        const streamCopy = new StreamCopy(sql, userDbParams);
        const metrics = new StreamCopyMetrics(logger, 'copyto', sql, user);

        res.header("Content-Disposition", `attachment; filename=${encodeURIComponent(filename)}`);
        res.header("Content-Type", "application/octet-stream");

        streamCopy.getPGStream(StreamCopy.ACTION_TO, (err, pgstream) => {
            if (err) {
                return next(err);
            }

            pgstream
                .on('data', data => metrics.addSize(data.length))
                .on('error', err => {
                    metrics.end(null, err);
                    pgstream.unpipe(res);

                    return next(err);
                })
                .on('end', () => metrics.end( streamCopy.getRowCount(StreamCopy.ACTION_TO) ))
                .pipe(res)
                .on('close', () => {
                    const err = new Error('Connection closed by client');
                    pgstream.emit('cancelQuery', err);
                    pgstream.emit('error', err);
                })
                .on('error', err => {
                    pgstream.emit('error', err);
                });
        });
    };
}

function handleCopyFrom (logger) {
    return function handleCopyFromMiddleware (req, res, next) {
        const sql = req.query.q;
        const { userDbParams, user, dbRemainingQuota } = res.locals;
        const isGzip = req.get('content-encoding') === 'gzip';
        const COPY_FROM_MAX_POST_SIZE = global.settings.copy_from_max_post_size || 2 * 1024 * 1024 * 1024; // 2 GB
        const COPY_FROM_MAX_POST_SIZE_PRETTY = global.settings.copy_from_max_post_size_pretty || '2 GB';

        const streamCopy = new StreamCopy(sql, userDbParams);
        const metrics = new StreamCopyMetrics(logger, 'copyfrom', sql, user, isGzip);

        streamCopy.getPGStream(StreamCopy.ACTION_FROM, (err, pgstream) => {
            if (err) {
                return next(err);
            }

            req
                .on('data', data => isGzip ? metrics.addGzipSize(data.length) : undefined)
                .on('close', () => {
                    const err = new Error('Connection closed by client');
                    pgstream.emit('cancelQuery', err);
                    pgstream.emit('error', err);
                })
                .pipe(isGzip ? zlib.createGunzip() : new PassThrough())
                .on('error', err => {
                    metrics.end(null, err);
                    pgstream.emit('error', err);
                })
                .on('data', data => {
                    metrics.addSize(data.length);

                    if(metrics.size > dbRemainingQuota) {
                        const quotaError = new Error('DB Quota exceeded');
                        pgstream.emit('error', quotaError);
                    }
                    if((metrics.gzipSize || metrics.size) > COPY_FROM_MAX_POST_SIZE) {
                        const maxPostSizeError = new Error(
                            `COPY FROM maximum POST size of ${COPY_FROM_MAX_POST_SIZE_PRETTY} exceeded`
                        );
                        pgstream.emit('error', maxPostSizeError);
                    }
                })
                .pipe(pgstream)
                .on('error', err => {
                    metrics.end(null, err);
                    req.unpipe(pgstream);
                    return next(err);
                })
                .on('end', () => {
                    metrics.end( streamCopy.getRowCount(StreamCopy.ACTION_FROM) );

                    const { time, rows } = metrics;

                    if (!rows) {
                        return next(new Error("No rows copied"));
                    }

                    res.send({
                        time,
                        total_rows: rows
                    });
                });
        });
    };
}

function validateCopyQuery () {
    return function validateCopyQueryMiddleware (req, res, next) {
        const sql = req.query.q;

        if (!sql) {
            return next(new Error("SQL is missing"));
        }

        if (!sql.toUpperCase().startsWith("COPY ")) {
            return next(new Error("SQL must start with COPY"));
        }

        next();
    };
}

function errorHandler () {
    return function errorHandlerMiddleware (err, req, res, next) {
        if (res.headersSent) {
            console.error("EXCEPTION REPORT: " + err.stack);
            const errorHandler = errorHandlerFactory(err);
            res.write(JSON.stringify(errorHandler.getResponse()));
            res.end();
        } else {
            return next(err);
        }
    };
}

module.exports = CopyController;
<commit_msg>maintain req error handler<commit_after>'use strict';

const userMiddleware = require('../middlewares/user');
const errorMiddleware = require('../middlewares/error');
const authorizationMiddleware = require('../middlewares/authorization');
const connectionParamsMiddleware = require('../middlewares/connection-params');
const { initializeProfilerMiddleware } = require('../middlewares/profiler');
const rateLimitsMiddleware = require('../middlewares/rate-limit');
const dbQuotaMiddleware = require('../middlewares/db-quota');
const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimitsMiddleware;
const errorHandlerFactory = require('../services/error_handler_factory');
const StreamCopy = require('../services/stream_copy');
const StreamCopyMetrics = require('../services/stream_copy_metrics');
const zlib = require('zlib');
const { PassThrough } = require('stream');

function CopyController(metadataBackend, userDatabaseService, userLimitsService, logger) {
    this.metadataBackend = metadataBackend;
    this.userDatabaseService = userDatabaseService;
    this.userLimitsService = userLimitsService;
    this.logger = logger;
}

CopyController.prototype.route = function (app) {
    const { base_url } = global.settings;

    const copyFromMiddlewares = endpointGroup => {
        return [
            initializeProfilerMiddleware('copyfrom'),
            userMiddleware(this.metadataBackend),
            rateLimitsMiddleware(this.userLimitsService, endpointGroup),
            authorizationMiddleware(this.metadataBackend),
            connectionParamsMiddleware(this.userDatabaseService),
            validateCopyQuery(),
            dbQuotaMiddleware(),
            handleCopyFrom(this.logger),
            errorHandler(),
            errorMiddleware()
        ];
    };

    const copyToMiddlewares = endpointGroup => {
        return [
            initializeProfilerMiddleware('copyto'),
            userMiddleware(this.metadataBackend),
            rateLimitsMiddleware(this.userLimitsService, endpointGroup),
            authorizationMiddleware(this.metadataBackend),
            connectionParamsMiddleware(this.userDatabaseService),
            validateCopyQuery(),
            handleCopyTo(this.logger),
            errorHandler(),
            errorMiddleware()
        ];
    };

    app.post(`${base_url}/sql/copyfrom`, copyFromMiddlewares(RATE_LIMIT_ENDPOINTS_GROUPS.COPY_FROM));
    app.get(`${base_url}/sql/copyto`, copyToMiddlewares(RATE_LIMIT_ENDPOINTS_GROUPS.COPY_TO));
};

function handleCopyTo (logger) {
    return function handleCopyToMiddleware (req, res, next) {
        const sql = req.query.q;
        const { userDbParams, user } = res.locals;
        const filename = req.query.filename || 'carto-sql-copyto.dmp';

        const streamCopy = new StreamCopy(sql, userDbParams);
        const metrics = new StreamCopyMetrics(logger, 'copyto', sql, user);

        res.header("Content-Disposition", `attachment; filename=${encodeURIComponent(filename)}`);
        res.header("Content-Type", "application/octet-stream");

        streamCopy.getPGStream(StreamCopy.ACTION_TO, (err, pgstream) => {
            if (err) {
                return next(err);
            }

            pgstream
                .on('data', data => metrics.addSize(data.length))
                .on('error', err => {
                    metrics.end(null, err);
                    pgstream.unpipe(res);

                    return next(err);
                })
                .on('end', () => metrics.end( streamCopy.getRowCount(StreamCopy.ACTION_TO) ))
                .pipe(res)
                .on('close', () => {
                    const err = new Error('Connection closed by client');
                    pgstream.emit('cancelQuery', err);
                    pgstream.emit('error', err);
                })
                .on('error', err => {
                    pgstream.emit('error', err);
                });
        });
    };
}

function handleCopyFrom (logger) {
    return function handleCopyFromMiddleware (req, res, next) {
        const sql = req.query.q;
        const { userDbParams, user, dbRemainingQuota } = res.locals;
        const isGzip = req.get('content-encoding') === 'gzip';
        const COPY_FROM_MAX_POST_SIZE = global.settings.copy_from_max_post_size || 2 * 1024 * 1024 * 1024; // 2 GB
        const COPY_FROM_MAX_POST_SIZE_PRETTY = global.settings.copy_from_max_post_size_pretty || '2 GB';

        const streamCopy = new StreamCopy(sql, userDbParams);
        const metrics = new StreamCopyMetrics(logger, 'copyfrom', sql, user, isGzip);

        streamCopy.getPGStream(StreamCopy.ACTION_FROM, (err, pgstream) => {
            if (err) {
                return next(err);
            }

            req
                .on('data', data => isGzip ? metrics.addGzipSize(data.length) : undefined)
                .on('error', err => {
                    metrics.end(null, err);
                    pgstream.emit('error', err);
                })
                .on('close', () => {
                    const err = new Error('Connection closed by client');
                    pgstream.emit('cancelQuery', err);
                    pgstream.emit('error', err);
                })
                .pipe(isGzip ? zlib.createGunzip() : new PassThrough())
                .on('error', err => {
                    metrics.end(null, err);
                    pgstream.emit('error', err);
                })
                .on('data', data => {
                    metrics.addSize(data.length);

                    if(metrics.size > dbRemainingQuota) {
                        const quotaError = new Error('DB Quota exceeded');
                        pgstream.emit('error', quotaError);
                    }
                    if((metrics.gzipSize || metrics.size) > COPY_FROM_MAX_POST_SIZE) {
                        const maxPostSizeError = new Error(
                            `COPY FROM maximum POST size of ${COPY_FROM_MAX_POST_SIZE_PRETTY} exceeded`
                        );
                        pgstream.emit('error', maxPostSizeError);
                    }
                })
                .pipe(pgstream)
                .on('error', err => {
                    metrics.end(null, err);
                    req.unpipe(pgstream);
                    return next(err);
                })
                .on('end', () => {
                    metrics.end( streamCopy.getRowCount(StreamCopy.ACTION_FROM) );

                    const { time, rows } = metrics;

                    if (!rows) {
                        return next(new Error("No rows copied"));
                    }

                    res.send({
                        time,
                        total_rows: rows
                    });
                });
        });
    };
}

function validateCopyQuery () {
    return function validateCopyQueryMiddleware (req, res, next) {
        const sql = req.query.q;

        if (!sql) {
            return next(new Error("SQL is missing"));
        }

        if (!sql.toUpperCase().startsWith("COPY ")) {
            return next(new Error("SQL must start with COPY"));
        }

        next();
    };
}

function errorHandler () {
    return function errorHandlerMiddleware (err, req, res, next) {
        if (res.headersSent) {
            console.error("EXCEPTION REPORT: " + err.stack);
            const errorHandler = errorHandlerFactory(err);
            res.write(JSON.stringify(errorHandler.getResponse()));
            res.end();
        } else {
            return next(err);
        }
    };
}

module.exports = CopyController;
<|endoftext|>


<commit_before>angular.module('MyModule')
    .controller('flockcontroller', function ($scope, $window, $timeout, UtilityService) {
        'use strict';
        $scope.windowWidth = function () {
            return $window.innerWidth;
        };

        $scope.$on('$locationChangeStart', function (event, next, current) {
            game.destroy();
            angular.element(document.querySelectorAll('canvas')).remove();
        });

        var game = new $window.Phaser.Game(600, 600, $window.Phaser.AUTO, 'container', { preload: preload, create: create, update: update });

        function preload() {
            game.load.image('agent', 'assets/triangle.png');
            game.load.image('target', 'assets/circle.png');
        }

        var agents;
        var target;
        var agentCollisionGroup;

        function createAgent(x, y) {
            var agent;
            agent = agents.create(x, y, 'agent');
            agent.width = 6;
            agent.height = 6;
            agent.anchor.setTo(0.5, 1.0);
            agent.body.rotPerFrame = (game.math.PI2 / UtilityService.randomInt(2,4)) * deltaTime;

            //TODO: custom property. Remove when flocking fixed.
            agent.speed = game.rnd.integerInRange(120,160);

            agent.body.setCollisionGroup(agentCollisionGroup);
            agent.body.collideWorldBounds = false;
//            agent.body.collides(circleCollisionGroup);
//            agent.body.angle = UtilityService.randomInt(0,359);

            return agent;
        }

        function create() {
            game.physics.startSystem(Phaser.Physics.P2JS);
            agents = game.add.group();
            agents.enableBody = true;
            agents.physicsBodyType = Phaser.Physics.P2JS;
            game.time.advancedTiming = true;

            agentCollisionGroup = game.physics.p2.createCollisionGroup();
            var targetCollisionGroup = game.physics.p2.createCollisionGroup();
            game.physics.p2.updateBoundsCollisionGroup();

            target = game.add.sprite(300,300,'target');
            target.width = 15;
            target.height = target.width;
            target.anchor.setTo(0.5, 0.5);
            target.tint = 0x00ffff;
            game.physics.p2.enable(target);
            target.body.setCollisionGroup(targetCollisionGroup);

            for(var i = 0; i < 150; i++) {
                createAgent(UtilityService.randomInt(50, 550), UtilityService.randomInt(50, 550));
            }

//            var a1 = createAgent(100,100);
//            var a2 = createAgent(200,200);
//            var a3 = createAgent(300,300);
//            var a4 = createAgent(400,400);
        }

        var deltaTime = 0.016667;
        var twoPi = Math.PI * 2;
        function move(agent) {
            //var pi4 = (game.math.PI2 / 4)
            //var angle = game.math.angleBetweenPoints(agent.position, target.position) + pi4;

            //Swap y position to correctly calculate in Quad I.
            var tmpp1 = new Vec2(agent.position.x, target.position.y);
            var tmpp2 = new Vec2(target.position.x, agent.position.y);

            var vecp1p2 = vMath.normalize(vMath.subV(tmpp2, tmpp1));
            var angle = Math.atan2(vecp1p2.x, vecp1p2.y);

            if (angle < 0) {
                angle = twoPi + angle;
            }

            agent.body.moveForward(agent.speed);
            //agent.body.rotation = angle;
            var diff = agent.body.rotation - angle;
            var absDiff = Math.abs(diff);

            if ((Math.abs(agent.body.rotation + twoPi - angle) < agent.body.rotPerFrame) ||
                (Math.abs(angle + twoPi - agent.body.rotation) < agent.body.rotPerFrame)) {
                return;
            }

            if (absDiff > Math.PI && diff < 0) {
                agent.body.rotation -= agent.body.rotPerFrame;
            } else if (absDiff > Math.PI && diff > 0) {
                agent.body.rotation += agent.body.rotPerFrame;
            } else if ((absDiff) > agent.body.rotPerFrame ) {
                if (agent.body.rotation < angle) {
                    agent.body.rotation += agent.body.rotPerFrame;
                } else {
                    agent.body.rotation -= agent.body.rotPerFrame;
                }
            }

            if (agent.body.rotation < 0) {
                agent.body.rotation += twoPi;
            } else if (agent.body.rotation > twoPi) {
                agent.body.rotation -= twoPi;
            }

//            if (absDiff > Math.PI) {
//                if (absDiff + agent.body.rotPerFrame > (2 * Math.PI)) {
//
//                }
//            } else {
//            }

//            if (Math.abs(agent.body.rotation - angle) > agent.body.rotPerFrame ) {
//                if (agent.body.rotation < angle) {
//                    agent.body.rotation += agent.body.rotPerFrame;
//                } else {
//                    agent.body.rotation -= agent.body.rotPerFrame;
//                }
//            }

//            var p = new Vec2(target.position.x, target.position.y);
//            var t = new Vec2(agent.position.x, agent.position.y);
//            var h = new Vec2(agent.body.velocity.x, agent.body.velocity.y);
//            var H = vMath.normalize(h);
//            var tp = vMath.subV(p, t);
//            var TP = vMath.normalize(tp);
//            var dot = vMath.dot(TP, H);
//            var theta = Math.acos(dot);
//
////            agent.body.rotation = theta;
//
//            if (Math.abs(agent.body.rotation - theta) > agent.body.rotPerFrame ) {
//                if (agent.body.rotation < theta) {
//                    agent.body.rotation += agent.body.rotPerFrame;
//                } else {
//                    agent.body.rotation -= agent.body.rotPerFrame;
//                }
//
//                if (agent.body.rotation > game.math.PI2) {
//                    agent.body.rotation -= game.math.PI2;
//                } else if (agent.body.rotation < 0) {
//                    agent.body.rotation += game.math.PI2;
//                }
//            }
        }

        function destroyAgent() {
            var agent;

            for (var i = 0; i < agents.children.length; i++) {
                agent = agents.children[i];
                if (!agent.body) {
                    continue;
                }

                var left = agents.children[i].x - agents.children[i].width / 2;
                var top = agents.children[i].y - agents.children[i].width / 2;
                var right = agents.children[i].x + agents.children[i].width / 2;
                var bot = agents.children[i].y + agents.children[i].width / 2;

                if (left <= 0) {
                    break;
                } else if (right >= game.world.width) {
                    break;
                } else if (top <= 0) {
                    break;
                } else if (bot >= game.world.height) {
                    break;
                }

                agent = null;
            }

            if (agent && agent.body) {
                agent.body.destroy();
                agent.body = null;
                agent.destroy();
            }
        }

        var wFrameCount = 120;
        var wSpeed = 50;
        var totFps = 0;
        var avgFps = 0;

        function moveTarget() {
            var angle = game.rnd.integerInRange(0, 359);
            wSpeed = game.rnd.integerInRange(20,200);
            target.body.angle = angle;
            target.body.moveForward(wSpeed);
        }

        function update() {
            for(var i = 0; i < agents.children.length; i++) {
                move(agents.children[i]);
            }

            wFrameCount++;
            totFps += game.time.fps;
            avgFps = totFps / wFrameCount;

            if (wFrameCount >= 120) {
                wFrameCount = 0;
                totFps = 0;
                moveTarget();
            }

            if ((target.position.x < 100) ||
                (target.position.x > game.width - 100) ||
                (target.position.y < 100) ||
                (target.position.y > game.height - 100)) {

                target.body.angle = target.body.angle - 180;
                target.body.moveForward(wSpeed);
            }

            if (avgFps <= 55 && game.time.fps <= 55 && agents.children.length > 150) {
                destroyAgent();
            }

            if (avgFps >= 60 && game.time.fps >= 60) {
                createAgent(game.width + 50, game.height + 50);
            }
        }

        function init() {
            $scope.pageName = "Flocking";
        }

        init();
    });<commit_msg>Remove unused code and adjust speeds.<commit_after>angular.module('MyModule')
    .controller('flockcontroller', function ($scope, $window, $timeout, UtilityService) {
        'use strict';
        $scope.windowWidth = function () {
            return $window.innerWidth;
        };

        $scope.$on('$locationChangeStart', function (event, next, current) {
            game.destroy();
            angular.element(document.querySelectorAll('canvas')).remove();
        });

        var game = new $window.Phaser.Game(600, 600, $window.Phaser.AUTO, 'container', { preload: preload, create: create, update: update });

        function preload() {
            game.load.image('agent', 'assets/triangle.png');
            game.load.image('target', 'assets/circle.png');
        }

        var agents;
        var target;
        var agentCollisionGroup;

        function createAgent(x, y) {
            var agent;
            agent = agents.create(x, y, 'agent');
            agent.width = 6;
            agent.height = 6;
            agent.anchor.setTo(0.5, 1.0);
            agent.body.rotPerFrame = (game.math.PI2 / UtilityService.randomInt(1,5)) * deltaTime;

            //TODO: custom property. Remove when flocking fixed.
            agent.speed = game.rnd.integerInRange(120,160);

            agent.body.setCollisionGroup(agentCollisionGroup);
            agent.body.collideWorldBounds = false;

            return agent;
        }

        function create() {
            game.physics.startSystem(Phaser.Physics.P2JS);
            agents = game.add.group();
            agents.enableBody = true;
            agents.physicsBodyType = Phaser.Physics.P2JS;
            game.time.advancedTiming = true;

            agentCollisionGroup = game.physics.p2.createCollisionGroup();
            var targetCollisionGroup = game.physics.p2.createCollisionGroup();
            game.physics.p2.updateBoundsCollisionGroup();

            target = game.add.sprite(300,300,'target');
            target.width = 15;
            target.height = target.width;
            target.anchor.setTo(0.5, 0.5);
            target.tint = 0x00ffff;
            game.physics.p2.enable(target);
            target.body.setCollisionGroup(targetCollisionGroup);

            for(var i = 0; i < 150; i++) {
                createAgent(UtilityService.randomInt(50, 550), UtilityService.randomInt(50, 550));
            }
        }

        var deltaTime = 0.016667;
        var twoPi = Math.PI * 2;

        function move(agent) {
            //Swap y position to correctly calculate in Quad I.
            var tmpp1 = new Vec2(agent.position.x, target.position.y);
            var tmpp2 = new Vec2(target.position.x, agent.position.y);

            var vecp1p2 = vMath.normalize(vMath.subV(tmpp2, tmpp1));
            var angle = Math.atan2(vecp1p2.x, vecp1p2.y);

            if (angle < 0) {
                angle = twoPi + angle;
            }

            agent.body.moveForward(agent.speed);

            var diff = agent.body.rotation - angle;
            var absDiff = Math.abs(diff);

            if ((Math.abs(agent.body.rotation + twoPi - angle) < agent.body.rotPerFrame) ||
                (Math.abs(angle + twoPi - agent.body.rotation) < agent.body.rotPerFrame)) {
                return;
            }

            if (absDiff > Math.PI && diff < 0) {
                agent.body.rotation -= agent.body.rotPerFrame;
            } else if (absDiff > Math.PI && diff > 0) {
                agent.body.rotation += agent.body.rotPerFrame;
            } else if ((absDiff) > agent.body.rotPerFrame ) {
                if (agent.body.rotation < angle) {
                    agent.body.rotation += agent.body.rotPerFrame;
                } else {
                    agent.body.rotation -= agent.body.rotPerFrame;
                }
            }

            if (agent.body.rotation < 0) {
                agent.body.rotation += twoPi;
            } else if (agent.body.rotation > twoPi) {
                agent.body.rotation -= twoPi;
            }
        }

        function destroyAgent() {
            var agent;

            for (var i = 0; i < agents.children.length; i++) {
                agent = agents.children[i];
                if (!agent.body) {
                    continue;
                }

                var left = agents.children[i].x - agents.children[i].width / 2;
                var top = agents.children[i].y - agents.children[i].width / 2;
                var right = agents.children[i].x + agents.children[i].width / 2;
                var bot = agents.children[i].y + agents.children[i].width / 2;

                if (left <= 0) {
                    break;
                } else if (right >= game.world.width) {
                    break;
                } else if (top <= 0) {
                    break;
                } else if (bot >= game.world.height) {
                    break;
                }

                agent = null;
            }

            if (agent && agent.body) {
                agent.body.destroy();
                agent.body = null;
                agent.destroy();
            }
        }

        var wFrameCount = 120;
        var wSpeed = 50;
        var totFps = 0;
        var avgFps = 0;

        function moveTarget() {
            var angle = game.rnd.integerInRange(0, 359);
            wSpeed = game.rnd.integerInRange(20,100);
            target.body.angle = angle;
            target.body.moveForward(wSpeed);
        }

        function update() {
            for(var i = 0; i < agents.children.length; i++) {
                move(agents.children[i]);
            }

            wFrameCount++;
            totFps += game.time.fps;
            avgFps = totFps / wFrameCount;

            if (wFrameCount >= 240) {
                wFrameCount = 0;
                totFps = 0;
                moveTarget();
            }

            if ((target.position.x < 100) ||
                (target.position.x > game.width - 100) ||
                (target.position.y < 100) ||
                (target.position.y > game.height - 100)) {

                target.body.angle = target.body.angle - 180;
                target.body.moveForward(wSpeed);
            }

            if (avgFps <= 55 && game.time.fps <= 55 && agents.children.length > 150) {
                destroyAgent();
            }

            if (avgFps >= 60 && game.time.fps >= 60) {
                createAgent(game.width + 50, game.height + 50);
            }
        }

        function init() {
            $scope.pageName = "Flocking";
        }

        init();
    });<|endoftext|>


<commit_before>// ==UserScript==
// @name         Колхоз. Кликер
// @namespace    https://odkl.kolhoz.mobi/
// @version      2.3
// @description  Высаживает, поливает, удобряет, кормит животный, продаёт растения, окучивает ранчо, открывает сундуки и собирает карты
// @author       GoodVin
// @match        *://*.kolhoz.mobi/*
// @match        *://kolhoz.mobi/*
// @require      https://code.jquery.com/jquery-3.2.1.slim.min.js
// @require      https://github.com/wisegoodvin/mobclickers/raw/master/shared_functions.js
// @downloadURL  https://github.com/wisegoodvin/mobclickers/raw/master/kolhmobi_clicker.user.js
// @updateURL    https://github.com/wisegoodvin/mobclickers/raw/master/kolhmobi_clicker.user.js
// @grant        unsafeWindow
// @grant        GM_setValue
// @grant        GM_getValue
// @icon         http://kolhoz.mobi/favicon.ico
// ==/UserScript==
unsafeWindow.$ = jQuery;
//console.log(navigator);
var today = ("00" + (new Date()).getYear()).slice(-2) + ("00" + ((new Date()).getMonth() + 1)).slice(-2) + ("00" + (new Date()).getDate()).slice(-2);
var time = parseInt(today + ("00" + (new Date()).getHours()).slice(-2) + ("00" + (new Date()).getMinutes()).slice(-2), 10);

$(function(){
	// сначала добавляем кнопки
	$('[ скрипт: в'+(options.scriptenabled ? '' : 'ы')+'кл ]').appendTo("body");
	if(!options.scriptenabled) return false;
	$('[ тип продаж: '+(options.sellertype ? 'умн' : 'прост')+' ]').appendTo("body");
	$('[ автозагоны: в'+(options.feeder ? '' : 'ы')+'кл ]').appendTo("body");
	$('[ обмен рубинов: в'+(options.rubys ? '' : 'ы')+'кл ]').appendTo("body");
	$('[ сбор карт: в'+(options.cardcollector ? '' : 'ы')+'кл ]').appendTo("body");
	$('[ ранчо: в'+(options.rancho ? '' : 'ы')+'кл ]').appendTo("body");

	// кончилось бабло
	if($("a:text(продать товар из амбара)").length) {
		console.log("Не хватает денег на покупку семян/удобрений!");
		if(!options.sellertype) return $("a:text(продать товар из амбара)").cl();
		else {
			if(options.feeder) {
				setvar('feeddate', '');
				return go('/mypetfarm');
			} else {
				setvar('feeddate', '');
				setvar('selldate', '');
				return go('/warehouse');
			}
		}
	}

    if($("a:text(вскопать)").length) return $("a:text(вскопать)").log("КОПАЙ!").cl();
	if($("a:text(всё)").length) return $("a:text(всё)").log("Действия по ссылке ВСЁ").cl();

	// действия на главном экране
	$(".block .ptm > ul > li a").each(function(){
		// вскапывание
		if(hastxt(this, "вскопать")) return cl(this, 250, 300);
	});
    if(clicktimer) return false;

	// простые продажи
    if(!options.sellertype) {
        // вход в амбар (шанс зайти туда - 10%)
        if(1 == rand(1, 10)) return go('/warehouse');
        // действия в амбаре
        if('/warehouse' == self.location.pathname) {
            console.log('Продажа из амбара');
            if($(".block a:text(продать)").length) return $(".block a:text(продать)").cl(this);
            if($(".block:text(амбар пуст)").length) return go('/');
        }
        if(clicktimer) return false;
    }
	// умные продажи
	else {
		if(empty(options.selldate) || today != options.selldate) {
			if(options.feeddate == today || !options.feeder) {
				if('/warehouse' == self.location.pathname) {
					if($(".block a:text(продать)").length) return $(".block a:text(продать)").cl();
					if($(".block .title:text(ключ)").length) return $(".block a:text(открыть):first").cl();
					if($(".block:text(амбар пуст)").length) {
						setvar('selldate', today);
						return go('/');
					}
				} else return go('/warehouse');
			} else if('/mypetfarm' != self.location.pathname) return go('/mypetfarm');
		} else if('/warehouse' == self.location.pathname) return go('/myfarm');
	}

	// кормёжка
	if(options.feeder && (empty(options.feeddate) || options.feeddate != today)) {
		if('/mypetfarm' == self.location.pathname) {
			if($(".feedbackPanelERROR:text(не хватает)").length) {
				setvar('feeddate', today);
				console.log("Кончились продукты");
				return go('/myfarm');
			}
			else if($("a[href*='harvest']:text(продать)").length) return $("a[href*='harvest']:text(продать)").log("Продаём звериную хрень").cl();
			else if($("a[href*='food']:text(покормить)").length) return $("a[href*='food']:text(покормить)").log("Надо выбрать корм для скотинки").cl();
			else if($("a[href*='lastFood']:text(покормить)").length) return $("a[href*='lastFood']:text(покормить)").log("Кормим скотинку").cl();
			else if($("a[href*='fruits']:text(кормить)").length) return $("a[href*='fruits']:text(кормить)").log("Выбираем первую попавшуюся жрачку").cl();
			else {
				setvar('feeddate', today);
				return go('/myfarm');
			}
		} else return go('/mypetfarm');
	}

	// обмен рубинов
	if(options.rubys && (empty(options.rubysdate) || 720 <= time - options.rubysdate)) {
		if('/converter' == self.location.pathname) {
			if($("a[href*='convertAllRubyLink']").length) return $("a[href*='convertAllRubyLink']").log("Конвертируем все доступные рубины").cl();
			else {
				setvar('rubysdate', time);
				return go('/myfarm');
			}
		} else return go('/converter');
	}

	// сбор карт
	if(options.cardcollector && (empty(options.cardtime) || time - options.cardtime >= 181)) {
		if('/queue' == self.location.pathname) {
			if($("a.btny[href*='open']").length) $("a.btny[href*='open']").log("Открываем доступный сундук").cl();
			else {
				setvar('cardtime', time);
				return go('/myfarm');
			}
		}
		else if('/reward' == self.location.pathname && $("a:text(продолжить)").length) $("a:text(продолжить)").log("Забираем карты").cl();
		else return go('/queue');
	}

	// ранчо
	if(options.rancho && /AmericanSelectSeedPage/i.test(self.location.href)) {
		console.log('Ранчо - выбор растения');
		var all = $("img[src*='afarm']").toArray(), dis = $("img[style*='opacity']").toArray(), allow = [];
		for(var i=0, l=all.length; i<l; i++) if(dis.indexOf(all[i]) < 0) allow.push(all[i]);
		if(allow.length) return $(allow[allow.length - 1]).closest("a").cl();
		else return go('/');
	}
	if(options.rancho && $("a[href*='rancho']").parent().find("span.title").length && /farm/i.test(self.location.pathname)) return go('/rancho');
	if('/rancho' == self.location.pathname) {
		console.log('Ранчо');
		if($("a:text(собрать)").length) return $("a:text(собрать)").log("Собираем уражай").cl();
		if($("a:text(выбрать)").length) return $("a:text(выбрать)").log("Выбираем растение").cl();
		if($("a:text(посадить)").length) return $("a:text(посадить)").log("Сажаем растение").cl();
		return go('/');
	}

    // запуск таймера
    var txt = $(".ptm > ul > li").text().toLowerCase().replace(/\n/g,' ').replace(/\r/g,'').replace(/\s{1,}/g,' ').trim();
    if(!empty(txt)) {
        const timeregex = /(\d+\s+(?:д|ч|м|с)[а-яё\s]+)?\d+\s(?:ч|м|с)/g;
        var mintime = null;
        var idx = 0;
        while((res = timeregex.exec(txt)) !== null) {
            if (res.index === timeregex.lastIndex) timeregex.lastIndex++;
            if(empty(res[0])) continue;
            var t = str2secs(res[0]);
            if(empty(mintime) || t < mintime) mintime = t;
        }
		if(options.rancho && mintime > 60) mintime = 60;
        else mintime += 5;
        console.log('Никаких действие не сделано - запущен таймер на '+mintime+' сек. до ближайшего действия.');
        return go("/", mintime * 1000);
    }

	// ошибка
	if(/Error/i.test(self.location.href) || /actionsBlock/i.test(self.location.href)) {
		console.log("Мы на странице с ошибкой - запущен таймер на переход к основному окну");
		return go('/', rand(3000,5000));
	}
});
<commit_msg>сделал питомник<commit_after>// ==UserScript==
// @name         Колхоз. Кликер
// @namespace    https://odkl.kolhoz.mobi/
// @version      2.4
// @description  Высаживает, поливает, удобряет, кормит животный, продаёт растения, окучивает ранчо, открывает сундуки и собирает карты
// @author       GoodVin
// @match        *://*.kolhoz.mobi/*
// @match        *://kolhoz.mobi/*
// @require      https://code.jquery.com/jquery-3.2.1.slim.min.js
// @require      https://github.com/wisegoodvin/mobclickers/raw/master/shared_functions.js
// @downloadURL  https://github.com/wisegoodvin/mobclickers/raw/master/kolhmobi_clicker.user.js
// @updateURL    https://github.com/wisegoodvin/mobclickers/raw/master/kolhmobi_clicker.user.js
// @grant        unsafeWindow
// @grant        GM_setValue
// @grant        GM_getValue
// @icon         http://kolhoz.mobi/favicon.ico
// ==/UserScript==
unsafeWindow.$ = jQuery;
var today = ("00" + (new Date()).getYear()).slice(-2) + ("00" + ((new Date()).getMonth() + 1)).slice(-2) + ("00" + (new Date()).getDate()).slice(-2);
var time = parseInt(today + ("00" + (new Date()).getHours()).slice(-2) + ("00" + (new Date()).getMinutes()).slice(-2), 10);

$(function(){
	// сначала добавляем кнопки
	$('[ скрипт: в'+(options.scriptenabled ? '' : 'ы')+'кл ]').appendTo("body");
	if(!options.scriptenabled) return false;
	$('[ тип продаж: '+(options.sellertype ? 'умн' : 'прост')+' ]').appendTo("body");
	$('[ автозагоны: в'+(options.feeder ? '' : 'ы')+'кл ]').appendTo("body");
	$('[ обмен рубинов: в'+(options.rubys ? '' : 'ы')+'кл ]').appendTo("body");
	$('[ сбор карт: в'+(options.cardcollector ? '' : 'ы')+'кл ]').appendTo("body");
	$('[ ранчо: в'+(options.rancho ? '' : 'ы')+'кл ]').appendTo("body");
	$('[ питомник: в'+(options.nursery ? '' : 'ы')+'кл ]').appendTo("body");

	// кончилось бабло
	if($("a:text(продать товар из амбара)").length) {
		console.log("Не хватает денег на покупку семян/удобрений!");
		if(!options.sellertype) return $("a:text(продать товар из амбара)").cl();
		else {
			if(options.feeder) {
				setvar('feeddate', '');
				return go('/mypetfarm');
			} else {
				setvar('feeddate', '');
				setvar('selldate', '');
				return go('/warehouse');
			}
		}
	}

    if($("a:text(вскопать)").length) return $("a:text(вскопать)").log("КОПАЙ!").cl();
	if($("a:text(всё)").length) return $("a:text(всё)").log("Действия по ссылке ВСЁ").cl();

	// действия на главном экране
	$(".block .ptm > ul > li a").each(function(){
		// вскапывание
		if(hastxt(this, "вскопать")) return cl(this, 250, 300);
	});
    if(clicktimer) return false;

	// простые продажи
    if(!options.sellertype) {
        // вход в амбар (шанс зайти туда - 10%)
        if(1 == rand(1, 10)) return go('/warehouse');
        // действия в амбаре
        if('/warehouse' == self.location.pathname) {
            console.log('Продажа из амбара');
            if($(".block a:text(продать)").length) return $(".block a:text(продать)").cl(this);
            if($(".block:text(амбар пуст)").length) return go('/');
        }
        if(clicktimer) return false;
    }
	// умные продажи
	else {
		if(empty(options.selldate) || today != options.selldate) {
			if(options.feeddate == today || !options.feeder) {
				if('/warehouse' == self.location.pathname) {
					if($(".block a:text(продать)").length) return $(".block a:text(продать)").cl();
					if($(".block .title:text(ключ)").length) return $(".block a:text(открыть):first").cl();
					if($(".block:text(амбар пуст)").length) {
						setvar('selldate', today);
						return go('/');
					}
				} else return go('/warehouse');
			} else if('/mypetfarm' != self.location.pathname) return go('/mypetfarm');
		} else if('/warehouse' == self.location.pathname) return go('/myfarm');
	}

	// кормёжка
	if(options.feeder && (empty(options.feeddate) || options.feeddate != today)) {
		if('/mypetfarm' == self.location.pathname) {
			if($(".feedbackPanelERROR:text(не хватает)").length) {
				setvar('feeddate', today);
				console.log("Кончились продукты");
				return go('/myfarm');
			}
			else if($("a[href*='harvest']:text(продать)").length) return $("a[href*='harvest']:text(продать)").log("Продаём звериную хрень").cl();
			else if($("a[href*='food']:text(покормить)").length) return $("a[href*='food']:text(покормить)").log("Надо выбрать корм для скотинки").cl();
			else if($("a[href*='lastFood']:text(покормить)").length) return $("a[href*='lastFood']:text(покормить)").log("Кормим скотинку").cl();
			else if($("a[href*='fruits']:text(кормить)").length) return $("a[href*='fruits']:text(кормить)").log("Выбираем первую попавшуюся жрачку").cl();
			else {
				setvar('feeddate', today);
				return go('/myfarm');
			}
		} else return go('/mypetfarm');
	}

	// обмен рубинов
	if(options.rubys && (empty(options.rubysdate) || 720 <= time - options.rubysdate)) {
		if('/converter' == self.location.pathname) {
			if($("a[href*='convertAllRubyLink']").length) return $("a[href*='convertAllRubyLink']").log("Конвертируем все доступные рубины").cl();
			else {
				setvar('rubysdate', time);
				return go('/myfarm');
			}
		} else return go('/converter');
	}

	// сбор карт
	if(options.cardcollector && (empty(options.cardtime) || time - options.cardtime >= 181)) {
		if('/queue' == self.location.pathname) {
			if($("a.btny[href*='open']").length) $("a.btny[href*='open']").log("Открываем доступный сундук").cl();
			else {
				setvar('cardtime', time);
				return go('/myfarm');
			}
		}
		else if('/reward' == self.location.pathname && $("a:text(продолжить)").length) $("a:text(продолжить)").log("Забираем карты").cl();
		else return go('/queue');
	}

	// ранчо
	if(options.rancho && /AmericanSelectSeedPage/i.test(self.location.href)) {
		console.log('Ранчо - выбор растения');
		var all = $("img[src*='afarm']").toArray(), dis = $("img[style*='opacity']").toArray(), allow = [];
		for(var i=0, l=all.length; i<l; i++) if(dis.indexOf(all[i]) < 0) allow.push(all[i]);
		if(allow.length) return $(allow[allow.length - 1]).closest("a").cl();
		else return go('/');
	}
	if(options.rancho && $("a[href*='rancho']").parent().find("span.title").length && /farm/i.test(self.location.pathname)) return go('/rancho');
	if('/rancho' == self.location.pathname) {
		console.log('Ранчо');
		if($("a:text(собрать)").length) return $("a:text(собрать)").log("Собираем уражай").cl();
		if($("a:text(выбрать)").length) return $("a:text(выбрать)").log("Выбираем растение").cl();
		if($("a:text(посадить)").length) return $("a:text(посадить)").log("Сажаем растение").cl();
		return go('/');
	}

	// питомник
	if(options.nursery) {
		if(self.location.pathname == '/mynursery') {
			console.log('Питомник');
			if($("a:text(сдать заказчику)").length) {
				setvar('nurseryjob', null);
				return $("a:text(сдать заказчику)").log('Сдаём заказчику').cl();
			}
			if($("a:text(забрать)").length) return $("a:text(забрать)").log('Забираем детёныша').cl();
			if(!options.nurseryjob) {
				console.log('Надо определиться с заданием');
				var jobs = $(".content li:text(очк)"), need = null, max=0;
				for(var i = 0; i<jobs.length;i++) {
					var txt = jobs[i].textContent.trim();
					var find = /^([^\(]+)[^\d]+(\d+)\s+очк.+(\d+)\s*\/\s*(\d+)/.exec(txt);

					if(find) {
						var ock = parseInt(find[2]);
						var cnt = parseInt(find[4]);
						var don = parseInt(find[3]);
						console.log(find,txt);
						if(ock/cnt > max && don != cnt) {
							need = find[1].trim();
							max = ock/cnt;
						}
					}
				}
				if(need && $("a:text(выращивать)").length) {
					console.log('Определились - '+need);
					setvar('nurseryjob', need);
					return $("a:text(выращивать)").cl();
				}
			}
		}
		if(options.nurseryjob && self.location.pathname == '/nursery-select') {
			console.log('Выбираем животное - '+options.nurseryjob);
			if($("a:text("+options.nurseryjob+")").length) return $("a:text("+options.nurseryjob+")").log('Начинаем выращивать').cl();
		}
		if($(".framed a[href*='mynursery']").parent().find("span.title").length) return go('/mynursery');
	}

    // запуск таймера
    var txt = $(".ptm > ul > li").text().toLowerCase().replace(/\n/g,' ').replace(/\r/g,'').replace(/\s{1,}/g,' ').trim();
    if(!empty(txt)) {
        const timeregex = /(\d+\s+(?:д|ч|м|с)[а-яё\s]+)?\d+\s(?:ч|м|с)/g;
        var mintime = null;
        var idx = 0;
        while((res = timeregex.exec(txt)) !== null) {
            if (res.index === timeregex.lastIndex) timeregex.lastIndex++;
            if(empty(res[0])) continue;
            var t = str2secs(res[0]);
            if(empty(mintime) || t < mintime) mintime = t;
        }
		if(options.rancho && mintime > 20) mintime = 20;
        else mintime += 5;
        console.log('Никаких действие не сделано - запущен таймер на '+mintime+' сек. до ближайшего действия.');
        return go("/", mintime * 1000);
    }

	// ошибка
	if(/Error/i.test(self.location.href) || /actionsBlock/i.test(self.location.href)) {
		console.log("Мы на странице с ошибкой - запущен таймер на переход к основному окну");
		return go('/', rand(3000,5000));
	}

	// хз где - надо уйти в корень
	console.log('Уйти на главную страницу');
	return go('/', rand(3000,5000));
});
<|endoftext|>


<commit_before>/**
 * This sample demonstrates a simple skill built with the Amazon Alexa Skills Kit.
 * For additional samples, visit the Alexa Skills Kit developer documentation at
 * https://developer.amazon.com/appsandservices/solutions/alexa/alexa-skills-kit/getting-started-guide
 */

var request = require('request');

var SERVER_LOCATION = "http://home.kevinmook.com:7200";

// Route the incoming request based on type (LaunchRequest, IntentRequest,
// etc.) The JSON body of the request is provided in the event parameter.
exports.handler = function (event, context) {
  try {
    console.log("event.session.application.applicationId=" + event.session.application.applicationId);

    if (event.session.application.applicationId !== "amzn1.echo-sdk-ams.app.998f8ea6-f1d8-4fe1-ae1e-8b4d878e03d7") {
       context.fail("Invalid Application ID");
     }

    if (event.request.type === "LaunchRequest") {
      // nothing to do
      context.succeed();
    }  else if (event.request.type === "IntentRequest") {
      onIntent(event.request,
           event.session,
           function callback(sessionAttributes, speechletResponse) {
             context.succeed(buildResponse(sessionAttributes, speechletResponse));
           });
    } else if (event.request.type === "SessionEndedRequest") {
      onSessionEnded(event.request, event.session);
      context.succeed();
    }
  } catch (e) {
    context.fail("Exception: " + e);
  }
};

/**
 * Called when the user specifies an intent for this skill.
 */
function onIntent(intentRequest, session, callback) {
  console.log("onIntent requestId=" + intentRequest.requestId
        + ", sessionId=" + session.sessionId);

  var intent = intentRequest.intent;
  var intentName = intentRequest.intent.name;

  // Dispatch to your skill's intent handlers
  if (intentName === "PlayIntent") {
    handlePlayIntent(intent, session, callback);
  } else if (intentName === "TypeIntent") {
    handleTypeIntent(intent, session, callback);
  } else if (intentName === "SkipIntent") {
    handleSkipIntent(intent, session, callback);
  } else {
    throw "Invalid intent";
  }
}

function handlePlayIntent(intent, session, callback) {
  sendRokuCommand("play", null, intent, session, callback);
}

function handleTypeIntent(intent, session, callback) {
  sendRokuCommand("type", intent.slots.TypeText, intent, session, callback);
}

function handleSkipIntent(intent, session, callback) {
  var direction = intent.slots.SkipDirection;
  var command;
  if(direction == "ahead" || direction == "forward") {
    command = "skip_forward";
  } else if(direction == "back" || direction == "backward") {
    command = "skip_back";
  } else {
    context.succeed();
    return;
  }
  sendRokuCommand(command, parseInt(intent.slots.SkipAmount), intent, session, callback);
}

// --------------- Functions that control the skill's behavior -----------------------

function sendRokuCommand(commandName, arg, intent, session, callback) {
  var sessionAttributes = {};

  var cardTitle = commandName;
  var speechOutput = null;
  var repromptText = null;
  var shouldEndSession = true;

  request(SERVER_LOCATION + "?command=" + commandName, function (error, response, body) {
    callback(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
  });
}

// --------------- Helpers that build all of the responses -----------------------

function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
  return {
    outputSpeech: {
      type: "PlainText",
      text: output
    },
    card: {
      type: "Simple",
      title: "SessionSpeechlet - " + title,
      content: "SessionSpeechlet - " + output
    },
    reprompt: {
      outputSpeech: {
        type: "PlainText",
        text: repromptText
      }
    },
    shouldEndSession: shouldEndSession
  }
}

function buildResponse(sessionAttributes, speechletResponse) {
  return {
    version: "1.0",
    sessionAttributes: sessionAttributes,
    response: speechletResponse
  }
}
<commit_msg>update application id<commit_after>/**
 * This sample demonstrates a simple skill built with the Amazon Alexa Skills Kit.
 * For additional samples, visit the Alexa Skills Kit developer documentation at
 * https://developer.amazon.com/appsandservices/solutions/alexa/alexa-skills-kit/getting-started-guide
 */

var request = require('request');

var SERVER_LOCATION = "http://home.kevinmook.com:7200";
var APPLICATION_ID = "amzn1.echo-sdk-ams.app.bacef1fa-7bb6-47b3-9358-d94905956121";

// Route the incoming request based on type (LaunchRequest, IntentRequest,
// etc.) The JSON body of the request is provided in the event parameter.
exports.handler = function (event, context) {
  try {
    console.log("event.session.application.applicationId=" + event.session.application.applicationId);

    if (event.session.application.applicationId !== APPLICATION_ID) {
       context.fail("Invalid Application ID");
     }

    if (event.request.type === "LaunchRequest") {
      // nothing to do
      context.succeed();
    }  else if (event.request.type === "IntentRequest") {
      onIntent(event.request,
           event.session,
           function callback(sessionAttributes, speechletResponse) {
             context.succeed(buildResponse(sessionAttributes, speechletResponse));
           });
    } else if (event.request.type === "SessionEndedRequest") {
      onSessionEnded(event.request, event.session);
      context.succeed();
    }
  } catch (e) {
    context.fail("Exception: " + e);
  }
};

/**
 * Called when the user specifies an intent for this skill.
 */
function onIntent(intentRequest, session, callback) {
  console.log("onIntent requestId=" + intentRequest.requestId
        + ", sessionId=" + session.sessionId);

  var intent = intentRequest.intent;
  var intentName = intentRequest.intent.name;

  // Dispatch to your skill's intent handlers
  if (intentName === "PlayIntent") {
    handlePlayIntent(intent, session, callback);
  } else if (intentName === "TypeIntent") {
    handleTypeIntent(intent, session, callback);
  } else if (intentName === "SkipIntent") {
    handleSkipIntent(intent, session, callback);
  } else {
    throw "Invalid intent";
  }
}

function handlePlayIntent(intent, session, callback) {
  sendRokuCommand("play", null, intent, session, callback);
}

function handleTypeIntent(intent, session, callback) {
  sendRokuCommand("type", intent.slots.TypeText, intent, session, callback);
}

function handleSkipIntent(intent, session, callback) {
  var direction = intent.slots.SkipDirection;
  var command;
  if(direction == "ahead" || direction == "forward") {
    command = "skip_forward";
  } else if(direction == "back" || direction == "backward") {
    command = "skip_back";
  } else {
    context.succeed();
    return;
  }
  sendRokuCommand(command, parseInt(intent.slots.SkipAmount), intent, session, callback);
}

// --------------- Functions that control the skill's behavior -----------------------

function sendRokuCommand(commandName, arg, intent, session, callback) {
  var sessionAttributes = {};

  var cardTitle = commandName;
  var speechOutput = null;
  var repromptText = null;
  var shouldEndSession = true;

  request(SERVER_LOCATION + "?command=" + commandName, function (error, response, body) {
    callback(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
  });
}

// --------------- Helpers that build all of the responses -----------------------

function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
  return {
    outputSpeech: {
      type: "PlainText",
      text: output
    },
    card: {
      type: "Simple",
      title: "SessionSpeechlet - " + title,
      content: "SessionSpeechlet - " + output
    },
    reprompt: {
      outputSpeech: {
        type: "PlainText",
        text: repromptText
      }
    },
    shouldEndSession: shouldEndSession
  }
}

function buildResponse(sessionAttributes, speechletResponse) {
  return {
    version: "1.0",
    sessionAttributes: sessionAttributes,
    response: speechletResponse
  }
}
<|endoftext|>