<commit_before>const fs = require('fs')
const path = require('path')
const AWS = require('aws-sdk')
const mime = require('mime')
const promisify = require('es6-promisify')
const zlib = require('zlib')
const gzip = promisify(zlib.gzip)

const s3 = new AWS.S3()
const cloudfront = new AWS.CloudFront()

module.exports.default = function handler (event, context, callback) {
  run()
  .then(result => callback(null, result))
  .catch(err => callback(err))
}

function run () {
  const files = fs.readdirSync(path.join(__dirname, 'app'))
  return Promise.all(files.map(upload))
  .then(invalidate)
}

function upload (filename) {
  const absolutePath = path.join(__dirname, 'app', filename)
  const ext = path.extname(filename)
  const expiresIn = ext === '.html' ? 900 : 7200
  const file = fs.readFileSync(absolutePath)
  return gzip(file).then(contents => {
    const params = {
      Bucket: process.env.S3_BUCKET,
      ACL: 'public-read',
      Key: filename,
      ContentType: `${mime.getType(ext)};charset=utf-8`,
      ContentEncoding: 'gzip',
      CacheControl: `max-age=${expiresIn}`,
      Body: contents
    }
    return s3.putObject(params).promise()
  })
}

function invalidate () {
  const params = {
    DistributionId: process.env.CF_DISTRIBUTION,
    InvalidationBatch: {
      CallerReference: `${+(new Date())}`,
      Paths: {
        Quantity: 1,
        Items: ['/*']
      }
    }
  }
  return cloudfront.createInvalidation(params).promise()
}
<commit_msg>Create function to recursively read nested payload structure<commit_after>const fs = require('fs')
const path = require('path')
const AWS = require('aws-sdk')
const mime = require('mime')
const promisify = require('es6-promisify')
const zlib = require('zlib')
const gzip = promisify(zlib.gzip)

const s3 = new AWS.S3()
const cloudfront = new AWS.CloudFront()

module.exports.default = function handler (event, context, callback) {
  run()
  .then(result => callback(null, result))
  .catch(err => callback(err))
}

function run () {
  const files = readdir('app')
  return Promise.all(files.map(upload))
  .then(invalidate)
}

function upload (filename) {
  const absolutePath = path.join(__dirname, 'app', filename)
  const ext = path.extname(filename)
  const expiresIn = ext === '.html' ? 900 : 7200
  const file = fs.readFileSync(absolutePath)
  return gzip(file).then(contents => {
    const params = {
      Bucket: process.env.S3_BUCKET,
      ACL: 'public-read',
      Key: filename,
      ContentType: `${mime.getType(ext)};charset=utf-8`,
      ContentEncoding: 'gzip',
      CacheControl: `max-age=${expiresIn}`,
      Body: contents
    }
    return s3.putObject(params).promise()
  })
}

function invalidate () {
  const params = {
    DistributionId: process.env.CF_DISTRIBUTION,
    InvalidationBatch: {
      CallerReference: `${+(new Date())}`,
      Paths: {
        Quantity: 1,
        Items: ['/*']
      }
    }
  }
  return cloudfront.createInvalidation(params).promise()
}

function readdir (dir) {
  const contents = fs.readdirSync(path.join(__dirname, dir))
  return contents.reduce((acc, curr) => {
    let fileOrDirectory = path.join(dir, curr)
    let stats = fs.lstatSync(path.join(__dirname, fileOrDirectory))
    if (stats.isFile()) {
      return acc.concat([curr])
    } else if (stats.isDirectory()) {
      return acc.concat(readdir(fileOrDirectory).map(file => path.join(curr, file)))
    }
    return null
  }, []).filter(Boolean)
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var allocCluster = require('../lib/test-cluster.js');

allocCluster.test('set k and forward', {
    size: 10,
    remoteConfig: {
        'kValue.default': 5
    }
}, function t(cluster, assert) {
    var steve = cluster.remotes.steve;
    var bob = cluster.remotes.bob;
    var app = cluster.apps[0];

    cluster.checkExitKValue(assert, {
        serviceName: steve.serviceName,
        kValue: 5
    });

    app.client.sendSetK({
        serviceName: steve.serviceName,
        k: 15
    }, onSetK);

    function onSetK(err) {
        if (err) {
            return assert.end(err);
        }

        cluster.checkExitKValue(assert, {
            serviceName: steve.serviceName,
            kValue: 15
        });

        cluster.sendRegister(steve.channel, {
            serviceName: steve.serviceName
        }, onRegistered);
    }

    function onRegistered(err, resp) {
        if (err) {
            return assert.end(err);
        }

        cluster.checkExitPeers(assert, {
            serviceName: steve.serviceName,
            hostPort: steve.hostPort
        });

        var body = resp.body;
        assert.ok(body, 'got a body from register');

        var exitNodes = app.hostsFor('steve');
        assert.equal(body.connectionCount, exitNodes.length,
            'got expected number of addresses and response');

        bob.clientChannel.request({
            serviceName: 'steve'
        }).send('echo', null, JSON.stringify('oh hi lol'), onForwarded);
    }

    function onForwarded(err, res, arg2, arg3) {
        if (err) {
            return assert.end(err);
        }

        assert.equal(String(arg3), '"oh hi lol"',
            'forwarding body is correct');

        assert.end();
    }
});

allocCluster.test('k value get set correctly', {
    size: 10,
    remoteConfig: {
        'kValue.default': 11,
        'kValue.services': {
            'bob': 6,
            'steve': 7
        }
    }
}, function t(cluster, assert) {
    cluster.checkExitKValue(assert, {
        serviceName: 'nancy',
        kValue: 11
    });

    cluster.checkExitKValue(assert, {
        serviceName: 'bob',
        kValue: 6
    });

    cluster.checkExitKValue(assert, {
        serviceName: 'steve',
        kValue: 7
    });

    assert.end();
});
<commit_msg>tests: set kValue cleanly<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var allocCluster = require('../lib/test-cluster.js');

allocCluster.test('set k and forward', {
    size: 10,
    kValue: 5
}, function t(cluster, assert) {
    var steve = cluster.remotes.steve;
    var bob = cluster.remotes.bob;
    var app = cluster.apps[0];

    cluster.checkExitKValue(assert, {
        serviceName: steve.serviceName,
        kValue: 5
    });

    app.client.sendSetK({
        serviceName: steve.serviceName,
        k: 15
    }, onSetK);

    function onSetK(err) {
        if (err) {
            return assert.end(err);
        }

        cluster.checkExitKValue(assert, {
            serviceName: steve.serviceName,
            kValue: 15
        });

        cluster.sendRegister(steve.channel, {
            serviceName: steve.serviceName
        }, onRegistered);
    }

    function onRegistered(err, resp) {
        if (err) {
            return assert.end(err);
        }

        cluster.checkExitPeers(assert, {
            serviceName: steve.serviceName,
            hostPort: steve.hostPort
        });

        var body = resp.body;
        assert.ok(body, 'got a body from register');

        var exitNodes = app.hostsFor('steve');
        assert.equal(body.connectionCount, exitNodes.length,
            'got expected number of addresses and response');

        bob.clientChannel.request({
            serviceName: 'steve'
        }).send('echo', null, JSON.stringify('oh hi lol'), onForwarded);
    }

    function onForwarded(err, res, arg2, arg3) {
        if (err) {
            return assert.end(err);
        }

        assert.equal(String(arg3), '"oh hi lol"',
            'forwarding body is correct');

        assert.end();
    }
});

allocCluster.test('k value get set correctly', {
    size: 10,
    kValue: 11,
    remoteConfig: {
        'kValue.services': {
            'bob': 6,
            'steve': 7
        }
    }
}, function t(cluster, assert) {
    cluster.checkExitKValue(assert, {
        serviceName: 'nancy',
        kValue: 11
    });

    cluster.checkExitKValue(assert, {
        serviceName: 'bob',
        kValue: 6
    });

    cluster.checkExitKValue(assert, {
        serviceName: 'steve',
        kValue: 7
    });

    assert.end();
});
<|endoftext|>


<commit_before>var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
var db = null;

function cache(id, data) {
    var request = indexedDB.open("cache", 1);
    request.onupgradeneeded = function (event) {
        var db = event.target.result;
        db.createObjectStore("cache");
    };
    request.onsuccess = function(event) {
        var db = event.target.result;
        var transaction = db.transaction(["cache"], 'readwrite');
        transaction.objectStore("cache").put(data, id);
    };
}

function getCached(id, success) {
    var request = indexedDB.open("cache", 1);
    request.onsuccess = function(event) {
        var db = event.target.result;
        var transaction = db.transaction(["cache"], 'readwrite');
        transaction.objectStore("cache").get(id).onsuccess = function (event) {
            success(event.target.result);
        };
    };
}<commit_msg>create cache-objstore also when using normal flow<commit_after>var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
var db = null;

function cache(id, data) {
    var request = indexedDB.open("cache", 1);
    request.onupgradeneeded = function (event) {
        event.target.result.createObjectStore("cache");
    };
    request.onsuccess = function(event) {
        var db = event.target.result;
        var transaction = db.transaction(["cache"], 'readwrite');
        transaction.objectStore("cache").put(data, id);
    };
}

function getCached(id, success) {
    var request = indexedDB.open("cache", 1);
    request.onupgradeneeded = function (event) {
        event.target.result.createObjectStore("cache");
    };
    request.onsuccess = function(event) {
        var db = event.target.result;
        var transaction = db.transaction(["cache"], 'readwrite');
        transaction.objectStore("cache").get(id).onsuccess = function (event) {
            success(event.target.result);
        };
    };
}<|endoftext|>


<commit_before>// Hook the ready callback.
pulse.ready(function() {
  // Create an engine.
  var engine = new pulse.Engine({
    gameWindow: 'gameWindow',
    size: { width: 640, height: 480 }
  });

  // Create a scene.
  var scene = new pulse.Scene();

  // Create a layer and add it to the scene.
  var layer = new pulse.Layer();
  layer.position = { x: 300, y : 200 };
  scene.addLayer(layer);

  //
  // Setup the walls.
  //
  var bottom = new pulse.Sprite( {
    src: 'block.png',
    physics: {
       basicShape : 'box',
       isStatic : true
    },
    size : { width: 640, height: 16 }
  });

  var leftSide = new pulse.Sprite( {
    src: 'block.png',
    physics: {
       basicShape: 'box',
       isStatic: true
    },
    size: { width: 16, height: 480 }
  });

  var rightSide = new pulse.Sprite( {
    src: 'block.png',
    physics: {
       basicShape: 'box',
       isStatic: true
    },
    size: { width: 16, height: 480 }
  });

  //
  // Setup the bucket.
  //
  var bucketBottom = new pulse.Sprite( {
    src: 'block.png',
    physics: {
       basicShape : 'box',
       isStatic : true
    },
    size : { width: 60, height: 8 }
  });

  var bucketLeftSide = new pulse.Sprite( {
    src: 'block.png',
    physics: {
       basicShape: 'box',
       isStatic: true
    },
    size: { width: 8, height: 60 }
  });

  var bucketRightSide = new pulse.Sprite( {
    src: 'block.png',
    physics: {
       basicShape: 'box',
       isStatic: true
    },
    size: { width: 8, height: 60 }
  });

  leftSide.position = { x: 20, y: 200 };
  rightSide.position = { x: 620, y: 200 };
  bottom.position = { x: 308, y: 440 };

  bucketBottom.position = { x: 400, y: 300 };
  bucketLeftSide.position = { x: 370, y: 300 };
  bucketRightSide.position = { x: 430, y: 300 };

  layer.addNode(bottom);
  layer.addNode(leftSide);
  layer.addNode(rightSide);

  layer.addNode(bucketBottom);
  layer.addNode(bucketLeftSide);
  layer.addNode(bucketRightSide);

  // The Ball
  var circle = new pulse.Sprite({
      src: 'ball.png',
      size: { width: 24, height: 24 },
      physics: {
         basicShape : 'circle'
      }
   });

  circle.position = { x: 100, y: 100 };

  layer.addNode(circle);

  // Add an activate the scene.
  engine.scenes.addScene(scene);
  engine.scenes.activateScene(scene);

  // Start the update and render loop.
  engine.go(30);

  var socket = io();

  var impulseRight = false;
  var impulseLeft = false;
  var impulseUp = false;
  var impulseDown = false;

  var rolling = [];

  socket.on('acc', function(msg) {

    console.log('x: ' + msg.x, 'y: ' + msg.y);

    if(parseFloat(msg.x) > 0.75) {
      if(!impulseRight) {
        impulseRight = true;
        circle._physics.body.ApplyImpulse(new Box2D.Common.Math.b2Vec2(0.3, 0), circle._physics.body.GetPosition());
        setTimeout(function() {
          impulseRight = false;
        }, 1000);
      }
    }

    if(parseFloat(msg.x) < -0.75) {
      if(!impulseLeft) {
        impulseLeft = true;
        circle._physics.body.ApplyImpulse(new Box2D.Common.Math.b2Vec2(-0.3, 0), circle._physics.body.GetPosition());
        setTimeout(function() {
          impulseLeft = false;
        }, 1000);
      }
    }

    if(parseFloat(msg.y) < -0.75) {
      if(!impulseUp) {
        impulseUp = true;
        circle._physics.body.ApplyImpulse(new Box2D.Common.Math.b2Vec2(0, -0.3), circle._physics.body.GetPosition());
        setTimeout(function() {
          impulseUp = false;
        }, 1000);
      }
    }

    if(parseFloat(msg.y) > 0.75) {
      if(!impulseDown) {
        impulseDown = true;
        circle._physics.body.ApplyImpulse(new Box2D.Common.Math.b2Vec2(0, 0.3), circle._physics.body.GetPosition());
        setTimeout(function() {
          impulseDown = false;
        }, 1000);
      }
    }

    /*
    if(rolling[0] < -0.5 && rolling[1] < -0.5 && rolling[2] < -0.5) {
      if(!impulseLeft) {
        impulseLeft = true;
        circle._physics.body.ApplyImpulse(new Box2D.Common.Math.b2Vec2(-0.3, 0), circle._physics.body.GetPosition());
        setTimeout(function() {
          impulseLeft = false;
        }, 1000);
      }
    }
    */

  });
});<commit_msg>Removed commented out code.<commit_after>// Hook the ready callback.
pulse.ready(function() {
  // Create an engine.
  var engine = new pulse.Engine({
    gameWindow: 'gameWindow',
    size: { width: 640, height: 480 }
  });

  // Create a scene.
  var scene = new pulse.Scene();

  // Create a layer and add it to the scene.
  var layer = new pulse.Layer();
  layer.position = { x: 300, y : 200 };
  scene.addLayer(layer);

  //
  // Setup the walls.
  //
  var bottom = new pulse.Sprite( {
    src: 'block.png',
    physics: {
       basicShape : 'box',
       isStatic : true
    },
    size : { width: 640, height: 16 }
  });

  var leftSide = new pulse.Sprite( {
    src: 'block.png',
    physics: {
       basicShape: 'box',
       isStatic: true
    },
    size: { width: 16, height: 480 }
  });

  var rightSide = new pulse.Sprite( {
    src: 'block.png',
    physics: {
       basicShape: 'box',
       isStatic: true
    },
    size: { width: 16, height: 480 }
  });

  //
  // Setup the bucket.
  //
  var bucketBottom = new pulse.Sprite( {
    src: 'block.png',
    physics: {
       basicShape : 'box',
       isStatic : true
    },
    size : { width: 60, height: 8 }
  });

  var bucketLeftSide = new pulse.Sprite( {
    src: 'block.png',
    physics: {
       basicShape: 'box',
       isStatic: true
    },
    size: { width: 8, height: 60 }
  });

  var bucketRightSide = new pulse.Sprite( {
    src: 'block.png',
    physics: {
       basicShape: 'box',
       isStatic: true
    },
    size: { width: 8, height: 60 }
  });

  leftSide.position = { x: 20, y: 200 };
  rightSide.position = { x: 620, y: 200 };
  bottom.position = { x: 308, y: 440 };

  bucketBottom.position = { x: 400, y: 300 };
  bucketLeftSide.position = { x: 370, y: 300 };
  bucketRightSide.position = { x: 430, y: 300 };

  layer.addNode(bottom);
  layer.addNode(leftSide);
  layer.addNode(rightSide);

  layer.addNode(bucketBottom);
  layer.addNode(bucketLeftSide);
  layer.addNode(bucketRightSide);

  // The Ball
  var circle = new pulse.Sprite({
      src: 'ball.png',
      size: { width: 24, height: 24 },
      physics: {
         basicShape : 'circle'
      }
   });

  circle.position = { x: 100, y: 100 };

  layer.addNode(circle);

  // Add an activate the scene.
  engine.scenes.addScene(scene);
  engine.scenes.activateScene(scene);

  // Start the update and render loop.
  engine.go(30);

  var socket = io();

  var impulseRight = false;
  var impulseLeft = false;
  var impulseUp = false;
  var impulseDown = false;

  var rolling = [];

  socket.on('acc', function(msg) {

    console.log('x: ' + msg.x, 'y: ' + msg.y);

    if(parseFloat(msg.x) > 0.75) {
      if(!impulseRight) {
        impulseRight = true;
        circle._physics.body.ApplyImpulse(new Box2D.Common.Math.b2Vec2(0.3, 0), circle._physics.body.GetPosition());
        setTimeout(function() {
          impulseRight = false;
        }, 1000);
      }
    }

    if(parseFloat(msg.x) < -0.75) {
      if(!impulseLeft) {
        impulseLeft = true;
        circle._physics.body.ApplyImpulse(new Box2D.Common.Math.b2Vec2(-0.3, 0), circle._physics.body.GetPosition());
        setTimeout(function() {
          impulseLeft = false;
        }, 1000);
      }
    }

    if(parseFloat(msg.y) < -0.75) {
      if(!impulseUp) {
        impulseUp = true;
        circle._physics.body.ApplyImpulse(new Box2D.Common.Math.b2Vec2(0, -0.3), circle._physics.body.GetPosition());
        setTimeout(function() {
          impulseUp = false;
        }, 1000);
      }
    }

    if(parseFloat(msg.y) > 0.75) {
      if(!impulseDown) {
        impulseDown = true;
        circle._physics.body.ApplyImpulse(new Box2D.Common.Math.b2Vec2(0, 0.3), circle._physics.body.GetPosition());
        setTimeout(function() {
          impulseDown = false;
        }, 1000);
      }
    }

  });
});
<|endoftext|>


<commit_before>import path from 'path'
import webpack from 'webpack'
import resolve from 'resolve'
import CaseSensitivePathPlugin from 'case-sensitive-paths-webpack-plugin'
import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin'
import WebpackBar from 'webpackbar'
import {getPages} from './webpack/utils'
import PagesPlugin from './webpack/plugins/pages-plugin'
import NextJsSsrImportPlugin from './webpack/plugins/nextjs-ssr-import'
import NextJsSSRModuleCachePlugin from './webpack/plugins/nextjs-ssr-module-cache'
import NextJsRequireCacheHotReloader from './webpack/plugins/nextjs-require-cache-hot-reloader'
import UnlinkFilePlugin from './webpack/plugins/unlink-file-plugin'
import PagesManifestPlugin from './webpack/plugins/pages-manifest-plugin'
import BuildManifestPlugin from './webpack/plugins/build-manifest-plugin'
import ChunkNamesPlugin from './webpack/plugins/chunk-names-plugin'
import { ReactLoadablePlugin } from './webpack/plugins/react-loadable-plugin'
import {SERVER_DIRECTORY, REACT_LOADABLE_MANIFEST, CLIENT_STATIC_FILES_RUNTIME_WEBPACK, CLIENT_STATIC_FILES_RUNTIME_MAIN} from 'next-server/constants'
import {NEXT_PROJECT_ROOT, NEXT_PROJECT_ROOT_NODE_MODULES, NEXT_PROJECT_ROOT_DIST_CLIENT, NEXT_PROJECT_ROOT_DIST_SERVER, DEFAULT_PAGES_DIR} from '../lib/constants'
import AutoDllPlugin from 'autodll-webpack-plugin'
import TerserPlugin from 'terser-webpack-plugin'
import AssetsSizePlugin from './webpack/plugins/assets-size-plugin'

// The externals config makes sure that
// on the server side when modules are
// in node_modules they don't get compiled by webpack
function externalsConfig (dir, isServer, lambdas) {
  const externals = []

  if (!isServer) {
    return externals
  }

  // When lambdas mode is enabled all node_modules will be compiled into the server bundles
  // So that all dependencies can be devDependencies and are not required to be installed
  if (lambdas) {
    return [
      (context, request, callback) => {
        resolve(request, { basedir: context, preserveSymlinks: true }, (err, res) => {
          if (err) {
            return callback()
          }
          if (res.match(/next-server[/\\]dist[/\\]lib[/\\]head/)) {
            return callback(null, `commonjs next-server/dist/lib/head.js`)
          }
          if (res.match(/next-server[/\\]dist[/\\]lib[/\\]asset/)) {
            return callback(null, `commonjs next-server/dist/lib/asset.js`)
          }
          if (res.match(/next-server[/\\]dist[/\\]lib[/\\]runtime-config/)) {
            return callback(null, `commonjs next-server/dist/lib/runtime-config.js`)
          }
          // Default pages have to be transpiled
          if (res.match(/next-server[/\\]dist[/\\]lib[/\\]loadable/)) {
            return callback(null, `commonjs next-server/dist/lib/loadable.js`)
          }
          callback()
        })
      }
    ]
  }

  const notExternalModules = ['next/app', 'next/document', 'next/link', 'next/router', 'next/error', 'http-status', 'string-hash', 'ansi-html', 'hoist-non-react-statics', 'htmlescape']

  externals.push((context, request, callback) => {
    if (notExternalModules.indexOf(request) !== -1) {
      return callback()
    }

    resolve(request, { basedir: context, preserveSymlinks: true }, (err, res) => {
      if (err) {
        return callback()
      }

      // Default pages have to be transpiled
      if (res.match(/next[/\\]dist[/\\]pages/) || res.match(/next[/\\]dist[/\\]client/) || res.match(/node_modules[/\\]@babel[/\\]runtime[/\\]/) || res.match(/node_modules[/\\]@babel[/\\]runtime-corejs2[/\\]/)) {
        return callback()
      }

      // Webpack itself has to be compiled because it doesn't always use module relative paths
      if (res.match(/node_modules[/\\]webpack/) || res.match(/node_modules[/\\]css-loader/)) {
        return callback()
      }

      // styled-jsx has to be transpiled
      if (res.match(/node_modules[/\\]styled-jsx/)) {
        return callback()
      }

      if (res.match(/node_modules[/\\].*\.js$/)) {
        return callback(null, `commonjs ${request}`)
      }

      callback()
    })
  })

  return externals
}

function optimizationConfig ({ dir, dev, isServer, totalPages, lambdas }) {
  const terserPluginConfig = {
    parallel: true,
    sourceMap: false,
    cache: true,
    cacheKeys: (keys) => {
      // path changes per build because we add buildId
      // because the input is already hashed the path is not needed
      delete keys.path
      return keys
    }
  }

  if (isServer && lambdas) {
    return {
      splitChunks: false,
      minimizer: [
        new TerserPlugin(terserPluginConfig)
      ]
    }
  }

  if (isServer) {
    return {
      splitChunks: false,
      minimize: false
    }
  }

  const config = {
    runtimeChunk: {
      name: CLIENT_STATIC_FILES_RUNTIME_WEBPACK
    },
    splitChunks: {
      cacheGroups: {
        default: false,
        vendors: false
      }
    }
  }

  if (dev) {
    return config
  }

  // Terser is a better uglifier
  config.minimizer = [
    new TerserPlugin(terserPluginConfig)
  ]

  // Only enabled in production
  // This logic will create a commons bundle
  // with modules that are used in 50% of all pages
  config.splitChunks.chunks = 'all'
  config.splitChunks.cacheGroups.commons = {
    name: 'commons',
    chunks: 'all',
    minChunks: totalPages > 2 ? totalPages * 0.5 : 2
  }
  config.splitChunks.cacheGroups.react = {
    name: 'commons',
    chunks: 'all',
    test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/
  }

  return config
}

export default async function getBaseWebpackConfig (dir, {dev = false, isServer = false, buildId, config, lambdas = false}) {
  const defaultLoaders = {
    babel: {
      loader: 'next-babel-loader',
      options: {dev, isServer, cwd: dir}
    },
    hotSelfAccept: {
      loader: 'hot-self-accept-loader',
      options: {
        include: [
          path.join(dir, 'pages')
        ],
        // All pages are javascript files. So we apply hot-self-accept-loader here to facilitate hot reloading of pages.
        // This makes sure plugins just have to implement `pageExtensions` instead of also implementing the loader
        extensions: new RegExp(`\\.+(${config.pageExtensions.join('|')})$`)
      }
    }
  }

  // Support for NODE_PATH
  const nodePathList = (process.env.NODE_PATH || '')
    .split(process.platform === 'win32' ? ';' : ':')
    .filter((p) => !!p)

  const distDir = path.join(dir, config.distDir)
  const outputPath = path.join(distDir, isServer ? SERVER_DIRECTORY : '')
  const pagesEntries = await getPages(dir, {nextPagesDir: DEFAULT_PAGES_DIR, dev, buildId, isServer, pageExtensions: config.pageExtensions.join('|')})
  const totalPages = Object.keys(pagesEntries).length
  const clientEntries = !isServer ? {
    // Backwards compatibility
    'main.js': [],
    [CLIENT_STATIC_FILES_RUNTIME_MAIN]: [
      path.join(NEXT_PROJECT_ROOT_DIST_CLIENT, (dev ? `next-dev` : 'next'))
    ].filter(Boolean)
  } : {}
  const devServerEntries = dev && isServer ? {
    'error-debug.js': path.join(NEXT_PROJECT_ROOT_DIST_SERVER, 'error-debug.js')
  } : {}

  const resolveConfig = {
    // Disable .mjs for node_modules bundling
    extensions: ['.wasm', '.js', '.mjs', '.jsx', '.json'],
    modules: [
      NEXT_PROJECT_ROOT_NODE_MODULES,
      'node_modules',
      ...nodePathList // Support for NODE_PATH environment variable
    ],
    alias: {
      next: NEXT_PROJECT_ROOT
    },
    mainFields: [!isServer && 'browser', !isServer && 'module', 'main'].filter(Boolean)
  }

  const webpackMode = dev ? 'development' : 'production'

  let webpackConfig = {
    mode: webpackMode,
    devtool: dev ? 'cheap-module-source-map' : false,
    name: isServer ? 'server' : 'client',
    cache: true,
    target: isServer ? 'node' : 'web',
    externals: externalsConfig(dir, isServer, lambdas),
    optimization: optimizationConfig({dir, dev, isServer, totalPages, lambdas}),
    recordsPath: path.join(outputPath, 'records.json'),
    context: dir,
    // Kept as function to be backwards compatible
    entry: async () => {
      return {
        ...clientEntries,
        ...devServerEntries,
        // Only _error and _document when in development. The rest is handled by on-demand-entries
        ...pagesEntries
      }
    },
    output: {
      path: outputPath,
      filename: ({chunk}) => {
        // Use `[name]-[contenthash].js` in production
        if (!dev && (chunk.name === CLIENT_STATIC_FILES_RUNTIME_MAIN || chunk.name === CLIENT_STATIC_FILES_RUNTIME_WEBPACK)) {
          return chunk.name.replace(/\.js$/, '-[contenthash].js')
        }
        return '[name]'
      },
      libraryTarget: isServer ? 'commonjs2' : 'jsonp',
      hotUpdateChunkFilename: 'static/webpack/[id].[hash].hot-update.js',
      hotUpdateMainFilename: 'static/webpack/[hash].hot-update.json',
      // This saves chunks with the name given via `import()`
      chunkFilename: isServer ? `${dev ? '[name]' : '[name].[contenthash]'}.js` : `static/chunks/${dev ? '[name]' : '[name].[contenthash]'}.js`,
      strictModuleExceptionHandling: true,
      webassemblyModuleFilename: 'static/wasm/[modulehash].wasm'
    },
    performance: { hints: false },
    resolve: resolveConfig,
    resolveLoader: {
      modules: [
        NEXT_PROJECT_ROOT_NODE_MODULES,
        'node_modules',
        path.join(__dirname, 'webpack', 'loaders'), // The loaders Next.js provides
        ...nodePathList // Support for NODE_PATH environment variable
      ]
    },
    module: {
      rules: [
        dev && !isServer && {
          test: defaultLoaders.hotSelfAccept.options.extensions,
          include: defaultLoaders.hotSelfAccept.options.include,
          use: defaultLoaders.hotSelfAccept
        },
        {
          test: /\.(js|jsx)$/,
          include: [dir, NEXT_PROJECT_ROOT_DIST_CLIENT, DEFAULT_PAGES_DIR, /next-server[\\/]dist[\\/]lib/],
          exclude: (path) => {
            if (path.indexOf(NEXT_PROJECT_ROOT_DIST_CLIENT) === 0 || path.indexOf(DEFAULT_PAGES_DIR) === 0 || /next-server[\\/]dist[\\/]lib/.exec(path)) {
              return false
            }

            return /node_modules/.exec(path)
          },
          use: defaultLoaders.babel
        }
      ].filter(Boolean)
    },
    plugins: [
      // Precompile react / react-dom for development, speeding up webpack
      dev && !isServer && new AutoDllPlugin({
        filename: '[name]_[hash].js',
        path: './static/development/dll',
        context: dir,
        entry: {
          dll: [
            'react',
            'react-dom'
          ]
        },
        config: {
          mode: webpackMode,
          resolve: resolveConfig
        }
      }),
      // This plugin makes sure `output.filename` is used for entry chunks
      new ChunkNamesPlugin(),
      !isServer && new ReactLoadablePlugin({
        filename: REACT_LOADABLE_MANIFEST
      }),
      new WebpackBar({
        name: isServer ? 'server' : 'client'
      }),
      dev && !isServer && new FriendlyErrorsWebpackPlugin(),
      // Even though require.cache is server only we have to clear assets from both compilations
      // This is because the client compilation generates the build manifest that's used on the server side
      dev && new NextJsRequireCacheHotReloader(),
      dev && !isServer && new webpack.HotModuleReplacementPlugin(),
      dev && new webpack.NoEmitOnErrorsPlugin(),
      dev && new UnlinkFilePlugin(),
      dev && new CaseSensitivePathPlugin(), // Since on macOS the filesystem is case-insensitive this will make sure your path are case-sensitive
      !dev && new webpack.HashedModuleIdsPlugin(),
      // Removes server/client code by minifier
      new webpack.DefinePlugin({
        'process.browser': JSON.stringify(!isServer)
      }),
      // This is used in client/dev-error-overlay/hot-dev-client.js to replace the dist directory
      !isServer && dev && new webpack.DefinePlugin({
        'process.env.__NEXT_DIST_DIR': JSON.stringify(distDir)
      }),
      isServer && new PagesManifestPlugin(),
      !isServer && new BuildManifestPlugin(),
      !isServer && new PagesPlugin(),
      isServer && new NextJsSsrImportPlugin(),
      isServer && new NextJsSSRModuleCachePlugin({outputPath}),
      !isServer && !dev && new AssetsSizePlugin({buildId, distDir})
    ].filter(Boolean)
  }

  if (typeof config.webpack === 'function') {
    webpackConfig = config.webpack(webpackConfig, {dir, dev, isServer, buildId, config, defaultLoaders, totalPages})
  }

  // Backwards compat for `main.js` entry key
  const originalEntry = webpackConfig.entry
  webpackConfig.entry = async () => {
    const entry = {...await originalEntry()}

    // Server compilation doesn't have main.js
    if (typeof entry['main.js'] !== 'undefined') {
      entry[CLIENT_STATIC_FILES_RUNTIME_MAIN] = [
        ...entry['main.js'],
        ...entry[CLIENT_STATIC_FILES_RUNTIME_MAIN]
      ]

      delete entry['main.js']
    }

    return entry
  }

  return webpackConfig
}
<commit_msg>Mark react/react-dom as external when in lambdas mode (#5828)<commit_after>import path from 'path'
import webpack from 'webpack'
import resolve from 'resolve'
import CaseSensitivePathPlugin from 'case-sensitive-paths-webpack-plugin'
import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin'
import WebpackBar from 'webpackbar'
import {getPages} from './webpack/utils'
import PagesPlugin from './webpack/plugins/pages-plugin'
import NextJsSsrImportPlugin from './webpack/plugins/nextjs-ssr-import'
import NextJsSSRModuleCachePlugin from './webpack/plugins/nextjs-ssr-module-cache'
import NextJsRequireCacheHotReloader from './webpack/plugins/nextjs-require-cache-hot-reloader'
import UnlinkFilePlugin from './webpack/plugins/unlink-file-plugin'
import PagesManifestPlugin from './webpack/plugins/pages-manifest-plugin'
import BuildManifestPlugin from './webpack/plugins/build-manifest-plugin'
import ChunkNamesPlugin from './webpack/plugins/chunk-names-plugin'
import { ReactLoadablePlugin } from './webpack/plugins/react-loadable-plugin'
import {SERVER_DIRECTORY, REACT_LOADABLE_MANIFEST, CLIENT_STATIC_FILES_RUNTIME_WEBPACK, CLIENT_STATIC_FILES_RUNTIME_MAIN} from 'next-server/constants'
import {NEXT_PROJECT_ROOT, NEXT_PROJECT_ROOT_NODE_MODULES, NEXT_PROJECT_ROOT_DIST_CLIENT, NEXT_PROJECT_ROOT_DIST_SERVER, DEFAULT_PAGES_DIR} from '../lib/constants'
import AutoDllPlugin from 'autodll-webpack-plugin'
import TerserPlugin from 'terser-webpack-plugin'
import AssetsSizePlugin from './webpack/plugins/assets-size-plugin'

// The externals config makes sure that
// on the server side when modules are
// in node_modules they don't get compiled by webpack
function externalsConfig (dir, isServer, lambdas) {
  const externals = []

  if (!isServer) {
    return externals
  }

  // When lambdas mode is enabled all node_modules will be compiled into the server bundles
  // So that all dependencies can be devDependencies and are not required to be installed
  if (lambdas) {
    return [
      (context, request, callback) => {
        // Make react/react-dom external until we bundle the server/renderer.
        if (request === 'react' || request === 'react-dom') {
          return callback(null, `commonjs ${request}`)
        }

        resolve(request, { basedir: context, preserveSymlinks: true }, (err, res) => {
          if (err) {
            return callback()
          }
          if (res.match(/next-server[/\\]dist[/\\]lib[/\\]head/)) {
            return callback(null, `commonjs next-server/dist/lib/head.js`)
          }
          if (res.match(/next-server[/\\]dist[/\\]lib[/\\]asset/)) {
            return callback(null, `commonjs next-server/dist/lib/asset.js`)
          }
          if (res.match(/next-server[/\\]dist[/\\]lib[/\\]runtime-config/)) {
            return callback(null, `commonjs next-server/dist/lib/runtime-config.js`)
          }
          // Default pages have to be transpiled
          if (res.match(/next-server[/\\]dist[/\\]lib[/\\]loadable/)) {
            return callback(null, `commonjs next-server/dist/lib/loadable.js`)
          }
          callback()
        })
      }
    ]
  }

  const notExternalModules = ['next/app', 'next/document', 'next/link', 'next/router', 'next/error', 'http-status', 'string-hash', 'ansi-html', 'hoist-non-react-statics', 'htmlescape']

  externals.push((context, request, callback) => {
    if (notExternalModules.indexOf(request) !== -1) {
      return callback()
    }

    resolve(request, { basedir: context, preserveSymlinks: true }, (err, res) => {
      if (err) {
        return callback()
      }

      // Default pages have to be transpiled
      if (res.match(/next[/\\]dist[/\\]pages/) || res.match(/next[/\\]dist[/\\]client/) || res.match(/node_modules[/\\]@babel[/\\]runtime[/\\]/) || res.match(/node_modules[/\\]@babel[/\\]runtime-corejs2[/\\]/)) {
        return callback()
      }

      // Webpack itself has to be compiled because it doesn't always use module relative paths
      if (res.match(/node_modules[/\\]webpack/) || res.match(/node_modules[/\\]css-loader/)) {
        return callback()
      }

      // styled-jsx has to be transpiled
      if (res.match(/node_modules[/\\]styled-jsx/)) {
        return callback()
      }

      if (res.match(/node_modules[/\\].*\.js$/)) {
        return callback(null, `commonjs ${request}`)
      }

      callback()
    })
  })

  return externals
}

function optimizationConfig ({ dir, dev, isServer, totalPages, lambdas }) {
  const terserPluginConfig = {
    parallel: true,
    sourceMap: false,
    cache: true,
    cacheKeys: (keys) => {
      // path changes per build because we add buildId
      // because the input is already hashed the path is not needed
      delete keys.path
      return keys
    }
  }

  if (isServer && lambdas) {
    return {
      splitChunks: false,
      minimizer: [
        new TerserPlugin(terserPluginConfig)
      ]
    }
  }

  if (isServer) {
    return {
      splitChunks: false,
      minimize: false
    }
  }

  const config = {
    runtimeChunk: {
      name: CLIENT_STATIC_FILES_RUNTIME_WEBPACK
    },
    splitChunks: {
      cacheGroups: {
        default: false,
        vendors: false
      }
    }
  }

  if (dev) {
    return config
  }

  // Terser is a better uglifier
  config.minimizer = [
    new TerserPlugin(terserPluginConfig)
  ]

  // Only enabled in production
  // This logic will create a commons bundle
  // with modules that are used in 50% of all pages
  config.splitChunks.chunks = 'all'
  config.splitChunks.cacheGroups.commons = {
    name: 'commons',
    chunks: 'all',
    minChunks: totalPages > 2 ? totalPages * 0.5 : 2
  }
  config.splitChunks.cacheGroups.react = {
    name: 'commons',
    chunks: 'all',
    test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/
  }

  return config
}

export default async function getBaseWebpackConfig (dir, {dev = false, isServer = false, buildId, config, lambdas = false}) {
  const defaultLoaders = {
    babel: {
      loader: 'next-babel-loader',
      options: {dev, isServer, cwd: dir}
    },
    hotSelfAccept: {
      loader: 'hot-self-accept-loader',
      options: {
        include: [
          path.join(dir, 'pages')
        ],
        // All pages are javascript files. So we apply hot-self-accept-loader here to facilitate hot reloading of pages.
        // This makes sure plugins just have to implement `pageExtensions` instead of also implementing the loader
        extensions: new RegExp(`\\.+(${config.pageExtensions.join('|')})$`)
      }
    }
  }

  // Support for NODE_PATH
  const nodePathList = (process.env.NODE_PATH || '')
    .split(process.platform === 'win32' ? ';' : ':')
    .filter((p) => !!p)

  const distDir = path.join(dir, config.distDir)
  const outputPath = path.join(distDir, isServer ? SERVER_DIRECTORY : '')
  const pagesEntries = await getPages(dir, {nextPagesDir: DEFAULT_PAGES_DIR, dev, buildId, isServer, pageExtensions: config.pageExtensions.join('|')})
  const totalPages = Object.keys(pagesEntries).length
  const clientEntries = !isServer ? {
    // Backwards compatibility
    'main.js': [],
    [CLIENT_STATIC_FILES_RUNTIME_MAIN]: [
      path.join(NEXT_PROJECT_ROOT_DIST_CLIENT, (dev ? `next-dev` : 'next'))
    ].filter(Boolean)
  } : {}
  const devServerEntries = dev && isServer ? {
    'error-debug.js': path.join(NEXT_PROJECT_ROOT_DIST_SERVER, 'error-debug.js')
  } : {}

  const resolveConfig = {
    // Disable .mjs for node_modules bundling
    extensions: ['.wasm', '.js', '.mjs', '.jsx', '.json'],
    modules: [
      NEXT_PROJECT_ROOT_NODE_MODULES,
      'node_modules',
      ...nodePathList // Support for NODE_PATH environment variable
    ],
    alias: {
      next: NEXT_PROJECT_ROOT
    },
    mainFields: [!isServer && 'browser', !isServer && 'module', 'main'].filter(Boolean)
  }

  const webpackMode = dev ? 'development' : 'production'

  let webpackConfig = {
    mode: webpackMode,
    devtool: dev ? 'cheap-module-source-map' : false,
    name: isServer ? 'server' : 'client',
    cache: true,
    target: isServer ? 'node' : 'web',
    externals: externalsConfig(dir, isServer, lambdas),
    optimization: optimizationConfig({dir, dev, isServer, totalPages, lambdas}),
    recordsPath: path.join(outputPath, 'records.json'),
    context: dir,
    // Kept as function to be backwards compatible
    entry: async () => {
      return {
        ...clientEntries,
        ...devServerEntries,
        // Only _error and _document when in development. The rest is handled by on-demand-entries
        ...pagesEntries
      }
    },
    output: {
      path: outputPath,
      filename: ({chunk}) => {
        // Use `[name]-[contenthash].js` in production
        if (!dev && (chunk.name === CLIENT_STATIC_FILES_RUNTIME_MAIN || chunk.name === CLIENT_STATIC_FILES_RUNTIME_WEBPACK)) {
          return chunk.name.replace(/\.js$/, '-[contenthash].js')
        }
        return '[name]'
      },
      libraryTarget: isServer ? 'commonjs2' : 'jsonp',
      hotUpdateChunkFilename: 'static/webpack/[id].[hash].hot-update.js',
      hotUpdateMainFilename: 'static/webpack/[hash].hot-update.json',
      // This saves chunks with the name given via `import()`
      chunkFilename: isServer ? `${dev ? '[name]' : '[name].[contenthash]'}.js` : `static/chunks/${dev ? '[name]' : '[name].[contenthash]'}.js`,
      strictModuleExceptionHandling: true,
      webassemblyModuleFilename: 'static/wasm/[modulehash].wasm'
    },
    performance: { hints: false },
    resolve: resolveConfig,
    resolveLoader: {
      modules: [
        NEXT_PROJECT_ROOT_NODE_MODULES,
        'node_modules',
        path.join(__dirname, 'webpack', 'loaders'), // The loaders Next.js provides
        ...nodePathList // Support for NODE_PATH environment variable
      ]
    },
    module: {
      rules: [
        dev && !isServer && {
          test: defaultLoaders.hotSelfAccept.options.extensions,
          include: defaultLoaders.hotSelfAccept.options.include,
          use: defaultLoaders.hotSelfAccept
        },
        {
          test: /\.(js|jsx)$/,
          include: [dir, NEXT_PROJECT_ROOT_DIST_CLIENT, DEFAULT_PAGES_DIR, /next-server[\\/]dist[\\/]lib/],
          exclude: (path) => {
            if (path.indexOf(NEXT_PROJECT_ROOT_DIST_CLIENT) === 0 || path.indexOf(DEFAULT_PAGES_DIR) === 0 || /next-server[\\/]dist[\\/]lib/.exec(path)) {
              return false
            }

            return /node_modules/.exec(path)
          },
          use: defaultLoaders.babel
        }
      ].filter(Boolean)
    },
    plugins: [
      // Precompile react / react-dom for development, speeding up webpack
      dev && !isServer && new AutoDllPlugin({
        filename: '[name]_[hash].js',
        path: './static/development/dll',
        context: dir,
        entry: {
          dll: [
            'react',
            'react-dom'
          ]
        },
        config: {
          mode: webpackMode,
          resolve: resolveConfig
        }
      }),
      // This plugin makes sure `output.filename` is used for entry chunks
      new ChunkNamesPlugin(),
      !isServer && new ReactLoadablePlugin({
        filename: REACT_LOADABLE_MANIFEST
      }),
      new WebpackBar({
        name: isServer ? 'server' : 'client'
      }),
      dev && !isServer && new FriendlyErrorsWebpackPlugin(),
      // Even though require.cache is server only we have to clear assets from both compilations
      // This is because the client compilation generates the build manifest that's used on the server side
      dev && new NextJsRequireCacheHotReloader(),
      dev && !isServer && new webpack.HotModuleReplacementPlugin(),
      dev && new webpack.NoEmitOnErrorsPlugin(),
      dev && new UnlinkFilePlugin(),
      dev && new CaseSensitivePathPlugin(), // Since on macOS the filesystem is case-insensitive this will make sure your path are case-sensitive
      !dev && new webpack.HashedModuleIdsPlugin(),
      // Removes server/client code by minifier
      new webpack.DefinePlugin({
        'process.browser': JSON.stringify(!isServer)
      }),
      // This is used in client/dev-error-overlay/hot-dev-client.js to replace the dist directory
      !isServer && dev && new webpack.DefinePlugin({
        'process.env.__NEXT_DIST_DIR': JSON.stringify(distDir)
      }),
      isServer && new PagesManifestPlugin(),
      !isServer && new BuildManifestPlugin(),
      !isServer && new PagesPlugin(),
      isServer && new NextJsSsrImportPlugin(),
      isServer && new NextJsSSRModuleCachePlugin({outputPath}),
      !isServer && !dev && new AssetsSizePlugin({buildId, distDir})
    ].filter(Boolean)
  }

  if (typeof config.webpack === 'function') {
    webpackConfig = config.webpack(webpackConfig, {dir, dev, isServer, buildId, config, defaultLoaders, totalPages})
  }

  // Backwards compat for `main.js` entry key
  const originalEntry = webpackConfig.entry
  webpackConfig.entry = async () => {
    const entry = {...await originalEntry()}

    // Server compilation doesn't have main.js
    if (typeof entry['main.js'] !== 'undefined') {
      entry[CLIENT_STATIC_FILES_RUNTIME_MAIN] = [
        ...entry['main.js'],
        ...entry[CLIENT_STATIC_FILES_RUNTIME_MAIN]
      ]

      delete entry['main.js']
    }

    return entry
  }

  return webpackConfig
}
<|endoftext|>


<commit_before>/*
 * Translation to JavaScript
 *
 * Requiring this module adds a gen() method to each of the AST classes.
 * Nothing is actually exported from this module.
 *
 * Generally, calling e.gen() where e is an expression node will return the
 * JavaScript translation as a string, while calling s.gen() where s is a
 * statement-level node will write its translation to standard output.
 *
 *   require("./backend/javascript-generator");
 *   program.gen();
 */
 // eslint-disable no-unused-vars

const Context = require("../ast/context");
const Program = require("../ast/program");
const Block = require("../ast/block");
const Return = require("../ast/return");
const Stmt = require("../ast/stmt");
const Argument = require("../ast/arg");
const Arguments = require("../ast/args");
const StringLiteral = require("../ast/stringLit");
const FuncCall = require("../ast/funcCall");
const AddExp = require("../ast/addExp");
const BinExp = require("../ast/binExp");
const Body = require("../ast/body");
const CharLit = require("../ast/charLit");
const Decl = require("../ast/decl");
const ExpBinary = require("../ast/exp_binary");
const ExpTernary = require("../ast/exp_ternary");
const ExpoExp = require("../ast/expoExp");
const ParenExp = require("../ast/parenExp");
const FuncDec = require("../ast/funcDec");
const List = require("../ast/list");
const Matches = require("../ast/matches");
const MullExp = require("../ast/mullExp");
const NumLit = require("../ast/numLit");
const Param = require("../ast/param");
const Params = require("../ast/params");
const PrefixExp = require("../ast/prefix_Exp");
const Print = require("../ast/print");
const StatementIfElse = require("../ast/statementIfElse");
const TupLit = require("../ast/tuplit");
const Type = require("../ast/type");

const indentPadding = 2;
let indentLevel = 0;

function emit(line) {
  console.log(`${" ".repeat(indentPadding * indentLevel)}${line}`);
}

function genStatementList(statements) {
  indentLevel += 1;
  statements.forEach(statement => statement.gen());
  indentLevel -= 1;
}

function makeOp(op) {
  return { not: "!", and: "&&", or: "||", "==": "===", "!=": "!==" }[op] || op;
}

// jsName(e) takes any PlainScript object with an id property, such as a
// Variable, Parameter, or FunctionDeclaration, and produces a JavaScript
// name by appending a unique indentifying suffix, such as "_1" or "_503".
// It uses a cache so it can return the same exact string each time it is
// called with a particular entity.
const jsName = (() => {
  let lastId = 0;
  const map = new Map();
  return (v) => {
    if (!(map.has(v))) {
      map.set(v, ++lastId); // eslint-disable-line no-plusplus
    }
    return `${v.id}_${map.get(v)}`;
  };
})();

// This is a nice helper for variable declarations and assignment statements.
// The AST represents both of these with lists of sources and lists of targets,
// but when writing out JavaScript it seems silly to write `[x] = [y]` when
// `x = y` suffices.
function bracketIfNecessary(a) {
  if (a.length === 1) {
    return `${a}`;
  }
  return `[${a.join(", ")}]`;
}

function generateLibraryFunctions() {
  function generateLibraryStub(name, params, body) {
    const entity = Context.INITIAL.localVariables[name];
    emit(`function ${jsName(entity)}(${params}) {${body}}`);
  }
  // This is sloppy. There should be a better way to do this.
  generateLibraryStub("print", "_", "console.log(_);");
}

Object.assign(Argument.prototype, {
  gen() {
    let translation = jsName(this);
    if (this.id) {
      translation += ` = ${this.id.gen()}`;
    }
    return translation;
  },
});

Object.assign(Arguments.prototype, {
  gen() { return this.args.forEach(arg => arg.gen()); },
});

/*
Object.assign(AssignmentStatement.prototype, {
  gen() {
    const targets = this.targets.map(t => t.gen());
    const sources = this.sources.map(s => s.gen());
    emit(`${bracketIfNecessary(targets)} = ${bracketIfNecessary(sources)};`);
  },
});
*/

Object.assign(BinExp.prototype, {
  gen() { return `(${this.left.gen()} ${makeOp(this.op)} ${this.right.gen()})`; },
});

Object.assign(AddExp.prototype, {
  gen() { return `(${this.left.gen()} ${makeOp(this.op)} ${this.right.gen()})`; },
});

Object.assign(MullExp.prototype, {
  gen() { return `(${this.left.gen()} ${makeOp(this.op)} ${this.right.gen()})`; },
});

Object.assign(PrefixExp.prototype, {
  gen() { return `(${makeOp(this.op)} ${this.right.gen()})`; },
});

Object.assign(ExpoExp.prototype, {
  gen() { return `(${this.left.gen()} ${makeOp(this.op)} ${this.right.gen()})`; },
});

Object.assign(ParenExp.prototype, {
  gen() { return `(${this.addexp.gen()})`; },
});

/*
Object.assign(BooleanLiteral.prototype, {
  gen() { return `${this.value}`; },
});

Object.assign(BreakStatement.prototype, {
  gen() { return "break;"; },
});

Object.assign(CallStatement.prototype, {
  gen() { emit(`${this.call.gen()};`); },
});

Object.assign(Call.prototype, {
  gen() {
    const fun = this.callee.referent;
    const params = {};
    const args = Array(this.args.length).fill(undefined);
    fun.params.forEach((p, i) => { params[p.id] = i; });
    this.args.forEach((a, i) => { args[a.isPositionalArgument ? i : params[a.id]] = a; });
    return `${jsName(fun)}(${args.map(a => (a ? a.gen() : "undefined")).join(", ")})`;
  },
});
*/

Object.assign(FuncDec.prototype, {
  gen() { return this.body.gen(); },
});

Object.assign(List.prototype, {
  gen() { return `(${this.arg.gen()})`; },
});

/*

Object.assign(FunctionObject.prototype, {
  gen() {
    emit(`function ${jsName(this)}(${this.params.map(p => p.gen()).join(", ")}) {`);
    genStatementList(this.body);
    emit("}");
  },
});

Object.assign(IdentifierExpression.prototype, {
  gen() { return this.referent.gen(); },
});

Object.assign(IfStatement.prototype, {
  gen() {
    this.cases.forEach((c, index) => {
      const prefix = index === 0 ? "if" : "} else if";
      emit(`${prefix} (${c.test.gen()}) {`);
      genStatementList(c.body);
    });
    if (this.alternate) {
      emit("} else {");
      genStatementList(this.alternate);
    }
    emit("}");
  },
});
*/
Object.assign(NumLit.prototype, {
  gen() { return `${this.value}`; },
});

Object.assign(Param.prototype, {
  gen() {
    let translation = jsName(this);
    if (this.id) {
      translation += ` = ${this.id.gen()}`;
    }
    return translation;
  },
});

Object.assign(Program.prototype, {
  gen() {
    return `${this.block.gen()}`;
  },
});

Object.assign(Body.prototype, {
  gen() {
    return `${this.block.gen()}`;
  },
});

Object.assign(Block.prototype, {
    gen() {
        generateLibraryFunctions();
        this.statements.forEach(statement => statement.gen());
    },
});
/*

*/
Object.assign(Return.prototype, {
  gen() {
    if (this.returnValue) {
      emit(`return ${this.returnValue.gen()};`);
    } else {
      emit("return;");
    }
  },
});

Object.assign(Print.prototype, {
  gen() {
    if (this.binexp) {
      emit(`console.log(${this.binexp.gen()});`);
    } else {
      emit("console.log();");
    }
  },
});

Object.assign(StringLiteral.prototype, {
  gen() { return `${this.value}`; },
});
/*

Object.assign(SubscriptedExpression.prototype, {
  gen() {
    const base = this.variable.gen();
    const subscript = this.subscript.gen();
    return `${base}[${subscript}]`;
  },
});

Object.assign(UnaryExpression.prototype, {
  gen() { return `(${makeOp(this.op)} ${this.operand.gen()})`; },
});

Object.assign(VariableDeclaration.prototype, {
  gen() {
    const variables = this.variables.map(v => v.gen());
    const initializers = this.initializers.map(i => i.gen());
    emit(`let ${bracketIfNecessary(variables)} = ${bracketIfNecessary(initializers)};`);
  },
});

Object.assign(Variable.prototype, {
  gen() { return jsName(this); },
});

Object.assign(WhileStatement.prototype, {
  gen() {
    emit(`while (${this.test.gen()}) {`);
    genStatementList(this.body);
    emit("}");
  },
});
*/
<commit_msg>adding params proto<commit_after>/*
 * Translation to JavaScript
 *
 * Requiring this module adds a gen() method to each of the AST classes.
 * Nothing is actually exported from this module.
 *
 * Generally, calling e.gen() where e is an expression node will return the
 * JavaScript translation as a string, while calling s.gen() where s is a
 * statement-level node will write its translation to standard output.
 *
 *   require("./backend/javascript-generator");
 *   program.gen();
 */
 // eslint-disable no-unused-vars

const Context = require("../ast/context");
const Program = require("../ast/program");
const Block = require("../ast/block");
const Return = require("../ast/return");
const Stmt = require("../ast/stmt");
const Argument = require("../ast/arg");
const Arguments = require("../ast/args");
const StringLiteral = require("../ast/stringLit");
const FuncCall = require("../ast/funcCall");
const AddExp = require("../ast/addExp");
const BinExp = require("../ast/binExp");
const Body = require("../ast/body");
const CharLit = require("../ast/charLit");
const Decl = require("../ast/decl");
const ExpBinary = require("../ast/exp_binary");
const ExpTernary = require("../ast/exp_ternary");
const ExpoExp = require("../ast/expoExp");
const ParenExp = require("../ast/parenExp");
const FuncDec = require("../ast/funcDec");
const List = require("../ast/list");
const Matches = require("../ast/matches");
const MullExp = require("../ast/mullExp");
const NumLit = require("../ast/numLit");
const Param = require("../ast/param");
const Params = require("../ast/params");
const PrefixExp = require("../ast/prefix_Exp");
const Print = require("../ast/print");
const StatementIfElse = require("../ast/statementIfElse");
const TupLit = require("../ast/tuplit");
const Type = require("../ast/type");

const indentPadding = 2;
let indentLevel = 0;

function emit(line) {
  console.log(`${" ".repeat(indentPadding * indentLevel)}${line}`);
}

function genStatementList(statements) {
  indentLevel += 1;
  statements.forEach(statement => statement.gen());
  indentLevel -= 1;
}

function makeOp(op) {
  return { not: "!", and: "&&", or: "||", "==": "===", "!=": "!==" }[op] || op;
}

// jsName(e) takes any PlainScript object with an id property, such as a
// Variable, Parameter, or FunctionDeclaration, and produces a JavaScript
// name by appending a unique indentifying suffix, such as "_1" or "_503".
// It uses a cache so it can return the same exact string each time it is
// called with a particular entity.
const jsName = (() => {
  let lastId = 0;
  const map = new Map();
  return (v) => {
    if (!(map.has(v))) {
      map.set(v, ++lastId); // eslint-disable-line no-plusplus
    }
    return `${v.id}_${map.get(v)}`;
  };
})();

// This is a nice helper for variable declarations and assignment statements.
// The AST represents both of these with lists of sources and lists of targets,
// but when writing out JavaScript it seems silly to write `[x] = [y]` when
// `x = y` suffices.
function bracketIfNecessary(a) {
  if (a.length === 1) {
    return `${a}`;
  }
  return `[${a.join(", ")}]`;
}

function generateLibraryFunctions() {
  function generateLibraryStub(name, params, body) {
    const entity = Context.INITIAL.localVariables[name];
    emit(`function ${jsName(entity)}(${params}) {${body}}`);
  }
  // This is sloppy. There should be a better way to do this.
  generateLibraryStub("print", "_", "console.log(_);");
}

Object.assign(Argument.prototype, {
  gen() {
    let translation = jsName(this);
    if (this.id) {
      translation += ` = ${this.id.gen()}`;
    }
    return translation;
  },
});

Object.assign(Arguments.prototype, {
  gen() { return this.args.forEach(arg => arg.gen()); },
});

/*
Object.assign(AssignmentStatement.prototype, {
  gen() {
    const targets = this.targets.map(t => t.gen());
    const sources = this.sources.map(s => s.gen());
    emit(`${bracketIfNecessary(targets)} = ${bracketIfNecessary(sources)};`);
  },
});
*/

Object.assign(BinExp.prototype, {
  gen() { return `(${this.left.gen()} ${makeOp(this.op)} ${this.right.gen()})`; },
});

Object.assign(AddExp.prototype, {
  gen() { return `(${this.left.gen()} ${makeOp(this.op)} ${this.right.gen()})`; },
});

Object.assign(MullExp.prototype, {
  gen() { return `(${this.left.gen()} ${makeOp(this.op)} ${this.right.gen()})`; },
});

Object.assign(PrefixExp.prototype, {
  gen() { return `(${makeOp(this.op)} ${this.right.gen()})`; },
});

Object.assign(ExpoExp.prototype, {
  gen() { return `(${this.left.gen()} ${makeOp(this.op)} ${this.right.gen()})`; },
});

Object.assign(ParenExp.prototype, {
  gen() { return `(${this.addexp.gen()})`; },
});

/*
Object.assign(BooleanLiteral.prototype, {
  gen() { return `${this.value}`; },
});

Object.assign(BreakStatement.prototype, {
  gen() { return "break;"; },
});

Object.assign(CallStatement.prototype, {
  gen() { emit(`${this.call.gen()};`); },
});

Object.assign(Call.prototype, {
  gen() {
    const fun = this.callee.referent;
    const params = {};
    const args = Array(this.args.length).fill(undefined);
    fun.params.forEach((p, i) => { params[p.id] = i; });
    this.args.forEach((a, i) => { args[a.isPositionalArgument ? i : params[a.id]] = a; });
    return `${jsName(fun)}(${args.map(a => (a ? a.gen() : "undefined")).join(", ")})`;
  },
});
*/

Object.assign(FuncDec.prototype, {
  gen() { return this.body.gen(); },
});

Object.assign(List.prototype, {
  gen() { return `(${this.arg.gen()})`; },
});

/*

Object.assign(FunctionObject.prototype, {
  gen() {
    emit(`function ${jsName(this)}(${this.params.map(p => p.gen()).join(", ")}) {`);
    genStatementList(this.body);
    emit("}");
  },
});

Object.assign(IdentifierExpression.prototype, {
  gen() { return this.referent.gen(); },
});

Object.assign(IfStatement.prototype, {
  gen() {
    this.cases.forEach((c, index) => {
      const prefix = index === 0 ? "if" : "} else if";
      emit(`${prefix} (${c.test.gen()}) {`);
      genStatementList(c.body);
    });
    if (this.alternate) {
      emit("} else {");
      genStatementList(this.alternate);
    }
    emit("}");
  },
});
*/
Object.assign(NumLit.prototype, {
  gen() { return `${this.value}`; },
});

Object.assign(Param.prototype, {
  gen() {
    let translation = jsName(this);
    if (this.id) {
      translation += ` = ${this.id.gen()}`;
    }
    return translation;
  },
});

Object.assign(Program.prototype, {
  gen() {
    return `${this.block.gen()}`;
  },
});

Object.assign(Body.prototype, {
  gen() {
    return `${this.block.gen()}`;
  },
});

Object.assign(Block.prototype, {
    gen() {
        generateLibraryFunctions();
        this.statements.forEach(statement => statement.gen());
    },
});

Object.assign(Params.prototype, {
    gen() {
        this.params.forEach(param => param.gen());
    },
});
/*

*/
Object.assign(Return.prototype, {
  gen() {
    if (this.returnValue) {
      emit(`return ${this.returnValue.gen()};`);
    } else {
      emit("return;");
    }
  },
});

Object.assign(Print.prototype, {
  gen() {
    if (this.binexp) {
      emit(`console.log(${this.binexp.gen()});`);
    } else {
      emit("console.log();");
    }
  },
});

Object.assign(StringLiteral.prototype, {
  gen() { return `${this.value}`; },
});
/*

Object.assign(SubscriptedExpression.prototype, {
  gen() {
    const base = this.variable.gen();
    const subscript = this.subscript.gen();
    return `${base}[${subscript}]`;
  },
});

Object.assign(UnaryExpression.prototype, {
  gen() { return `(${makeOp(this.op)} ${this.operand.gen()})`; },
});

Object.assign(VariableDeclaration.prototype, {
  gen() {
    const variables = this.variables.map(v => v.gen());
    const initializers = this.initializers.map(i => i.gen());
    emit(`let ${bracketIfNecessary(variables)} = ${bracketIfNecessary(initializers)};`);
  },
});

Object.assign(Variable.prototype, {
  gen() { return jsName(this); },
});

Object.assign(WhileStatement.prototype, {
  gen() {
    emit(`while (${this.test.gen()}) {`);
    genStatementList(this.body);
    emit("}");
  },
});
*/
<|endoftext|>


<commit_before>import NJUApplicationController from "../../nju/app/ApplicationController";

import Application from "./Application";
import ServiceClient from "../service/ServiceClient";

export default class ApplicationController extends NJUApplicationController {

    init() {
        super.init();
        this._playLists = [];
        this._activePlayList = null;
        this._activeTrack = null;
    }

    get playLists() {
        return this._playLists;
    }
    set playLists(playLists) {
        this._playLists = playLists;
        this._onPlayListsChanged();
    }

    get activePlayList() {
        return this._activePlayList;
    }
    set activePlayList(activePlayList) {
        if (this._activePlayList !== activePlayList) {
            this._activePlayList = activePlayList;
            this._onActivePlayListChanged();
        }
    }

    get activeTrack() {
        return this._activeTrack;
    }
    set activeTrack(activeTrack) {
        if (this._activeTrack !== activeTrack) {
            this._activeTrack = activeTrack;
            this._onActiveTrackChanged();
        }
    }

    createApplication(options) {
        const application = new Application();
        application.playListView.on("selectionchanged", this._playListView_selectionchanged.bind(this));
        application.trackTableView.on("trackchanged", this._trackTableView_selectionchanged.bind(this));
        application.searchView.on("search", this._searchView_search.bind(this));
        application.searchView.on("searchchanged", this._searchView_searchchanged.bind(this));
        application.searchView.$element.find("input").on("focus", this._searchView_focus.bind(this));
        application.searchView.$element.find("input").on("blur", this._searchView_blur.bind(this));
        application.searchListView.on("itemclick", this._searchListView_itemclick.bind(this));
        return application;
    }

    async run() {
        console.log("Net Music Webapp is now running...");

        try {
            await ServiceClient.getInstance().login();

            await this._loadUserPlayLists();

        }
        catch (e) {
            throw new Error("Can't get data.");
        }
    }

    async _loadUserPlayLists() {
        this.playLists = await ServiceClient.getInstance().getUserPlayList();
    }

    _onPlayListsChanged() {
        this.application.playListView.items = this.playLists;
    }

    _onActivePlayListChanged() {
        if (this.activePlayList) {
            this.application.trackTableView.items = this.activePlayList;
        }
        else {
            this.trackTableView.items = [];
        }
    }

    _onActiveTrackChanged() {
        this.application.trackPlayerView.activeTrack = this.activeTrack;
    }

    async _playListView_selectionchanged(e) {
        const playList = await ServiceClient.getInstance().getPlayListDetail(this.application.playListView.selectedId);
        this.activePlayList = playList.tracks;
    }

    _trackTableView_selectionchanged(e) {
        if (e.parameters) {
            this.activeTrack = e.parameters;
        }
    }

    async _searchView_search(e) {
        const songs = await ServiceClient.getInstance().search(e.parameters.text);
        this.activePlayList = songs;
        this.application.playListView.selection = null;

        this.application.searchListView.hide();
    }

    async _searchView_searchchanged(e) {
        if (e.parameters.text !== "") {
            this.application.searchListView.items = await ServiceClient.getInstance().search(e.parameters.text, true);
            this.application.searchListView.show();
        }
        else {
            // hide search-list-view
            this.application.searchListView.hide();
        }
    }

    _searchView_focus(e) {
        this.application.searchListView.toggle(this.application.searchView.text && this.application.searchListView.items && this.application.searchListView.items.length > 0);
    }

    _searchView_blur(e) {
        this.application.searchListView.hide();
    }

    async _searchListView_itemclick(e) {
        if (e.parameters.itemName) {
            const songs = await ServiceClient.getInstance().search(e.parameters.itemName);
            this.activePlayList = songs;
        }
    }
}
<commit_msg>Fix bug.<commit_after>import NJUApplicationController from "../../nju/app/ApplicationController";

import Application from "./Application";
import ServiceClient from "../service/ServiceClient";

export default class ApplicationController extends NJUApplicationController {

    init() {
        super.init();
        this._playLists = [];
        this._activePlayList = null;
        this._activeTrack = null;
    }

    get playLists() {
        return this._playLists;
    }
    set playLists(playLists) {
        this._playLists = playLists;
        this._onPlayListsChanged();
    }

    get activePlayList() {
        return this._activePlayList;
    }
    set activePlayList(activePlayList) {
        if (this._activePlayList !== activePlayList) {
            this._activePlayList = activePlayList;
            this._onActivePlayListChanged();
        }
    }

    get activeTrack() {
        return this._activeTrack;
    }
    set activeTrack(activeTrack) {
        if (this._activeTrack !== activeTrack) {
            this._activeTrack = activeTrack;
            this._onActiveTrackChanged();
        }
    }

    createApplication(options) {
        const application = new Application();
        application.playListView.on("selectionchanged", this._playListView_selectionchanged.bind(this));
        application.trackTableView.on("trackchanged", this._trackTableView_selectionchanged.bind(this));
        application.searchView.on("search", this._searchView_search.bind(this));
        application.searchView.on("searchchanged", this._searchView_searchchanged.bind(this));
        application.searchView.$element.find("input").on("focus", this._searchView_focus.bind(this));
        application.searchView.$element.find("input").on("blur", this._searchView_blur.bind(this));
        application.searchListView.on("itemclick", this._searchListView_itemclick.bind(this));
        return application;
    }

    async run() {
        console.log("Net Music Webapp is now running...");

        try {
            await ServiceClient.getInstance().login();

            await this._loadUserPlayLists();

        }
        catch (e) {
            throw new Error("Can't get data.");
        }
    }

    async _loadUserPlayLists() {
        this.playLists = await ServiceClient.getInstance().getUserPlayList();
    }

    _onPlayListsChanged() {
        this.application.playListView.items = this.playLists;
    }

    _onActivePlayListChanged() {
        if (this.activePlayList) {
            this.application.trackTableView.items = this.activePlayList;
        }
        else {
            this.trackTableView.items = [];
        }
    }

    _onActiveTrackChanged() {
        this.application.trackPlayerView.activeTrack = this.activeTrack;
    }

    async _playListView_selectionchanged(e) {
        const playList = await ServiceClient.getInstance().getPlayListDetail(this.application.playListView.selectedId);
        this.activePlayList = playList.tracks;
    }

    _trackTableView_selectionchanged(e) {
        if (e.parameters) {
            this.activeTrack = e.parameters;
        }
    }

    async _searchView_search(e) {
        const songs = await ServiceClient.getInstance().search(e.parameters.text);
        this.activePlayList = songs;
        this.application.playListView.selection = null;

        this.application.searchListView.hide();
    }

    async _searchView_searchchanged(e) {
        if (e.parameters.text !== "") {
            this.application.searchListView.items = await ServiceClient.getInstance().search(e.parameters.text, true);
            this.application.searchListView.show();
        }
        else {
            // hide search-list-view
            this.application.searchListView.hide();
        }
    }

    _searchView_focus(e) {
        this.application.searchListView.toggle(this.application.searchView.text && this.application.searchListView.items && this.application.searchListView.items.length > 0);
    }

    _searchView_blur(e) {
        this.application.searchListView.hide();
    }

    async _searchListView_itemclick(e) {
        if (e.parameters.itemName) {
            const songs = await ServiceClient.getInstance().search(e.parameters.itemName);
            this.activePlayList = songs;

            this.application.searchView.text = e.parameters.itemName;
        }
    }
}
<|endoftext|>


<commit_before>openerp.base = function(instance) {

    instance.base.apps_remote = null;
    instance.base.apps_client = null;

    var _t = instance.web._t;

    instance.base.Apps = instance.web.Widget.extend({
        template: 'EmptyComponent',
        remote_action_id: 'loempia.action_embed',
        failback_action_id: 'base.open_module_tree',

        init: function(parent, action) {
            this._super(parent, action);
            var options = action.params || {};

            if (options.apps_user) {
                sessionStorage.setItem('apps.login', options.apps_user);
            }
            if (options.apps_access_token) {
                sessionStorage.setItem('apps.access_token', options.apps_access_token);
            }

            this.params = options; // NOTE read by embedded client action
        },

        get_client: function() {
            // return the client via a deferred, resolved or rejected depending if the remote host is available or not.
            var check_client_available = function(client) {
                var d = $.Deferred();
                var i = new Image();
                i.onerror = function() {
                    d.reject(client);
                };
                i.onload = function() {
                    client.session.session_bind(client.origin).then(function() {
                        // check if client can authenticate
                        client.authenticate().then(
                           function() {     /* done */
                            d.resolve(client);
                        }, function() {     /* fail */
                            if (client.login === 'anonymous') {
                                d.reject(client);
                            } else {
                                sessionStorage.removeItem('apps.login');
                                sessionStorage.removeItem('apps.access_token');
                                client.bind_crendentials(client.dbname, 'anonymous', 'anonymous');
                                client.authenticate().then(
                                   function() {     /* done */
                                    d.resolve(client);
                                }, function() {     /* fail */
                                    d.reject(client);
                                });
                            }
                        });
                    });

                };
                i.src = _.str.sprintf('%s/web/static/src/img/sep-a.gif', client.origin);
                return d.promise();
            };
            if (instance.base.apps_client) {
                return check_client_available(instance.base.apps_client);
            } else {
                var ICP = new instance.web.Model('ir.config_parameter');
                return ICP.call('get_param', ['apps.server', 'https://apps.openerp.com/apps']).then(function(u) {
                    var link = $(_.str.sprintf('', u))[0];
                    var host = _.str.sprintf('%s//%s', link.protocol, link.host);
                    var dbname = link.pathname;
                    if (dbname[0] === '/') {
                        dbname = dbname.substr(1);
                    }
                    var login = (sessionStorage ? sessionStorage.getItem('apps.login') : null) || 'anonymous';
                    var passwd = (sessionStorage ? sessionStorage.getItem('apps.access_token') : null) || 'anonymous';
                    if (_.isNull(instance.base.apps_remote)) {
                        instance.base.apps_remote = new openerp.init();
                    }
                    var client = new instance.base.apps_remote.web.EmbeddedClient(null, host, dbname, login, passwd);
                    instance.base.apps_client = client;
                    return check_client_available(client);
                });
            }
        },

        destroy: function() {
            if (instance.base.apps_client) {
                instance.base.apps_client.destroy();
            }
            return this._super();
        },

        start: function() {
            var self = this;
            return self.get_client().
                done(function(client) {
                    client.replace(self.$el).
                        done(function() {
                            client.$el.removeClass('openerp');
                            client.do_action(self.remote_action_id, {hide_breadcrumb: true});
                        });
                }).
                fail(function(client) {
                    self.do_warn(_t('OpenERP Apps Unreachable'), _t('Showing locally available modules'), true);
                    self.rpc('/web/action/load', {action_id: self.failback_action_id}).done(function(action) {
                        self.do_action(action);
                        instance.webclient.menu.open_action(action.id);
                    });
                });
        },
    });

    instance.base.AppsUpdates = instance.base.Apps.extend({
        remote_action_id: 'loempia.action_embed_updates'
    });

    instance.web.client_actions.add("apps", "instance.base.Apps");
    instance.web.client_actions.add("apps.updates", "instance.base.AppsUpdates");

};
<commit_msg>[FIX] apps: add timestamp to check image to avoid cache problems<commit_after>openerp.base = function(instance) {

    instance.base.apps_remote = null;
    instance.base.apps_client = null;

    var _t = instance.web._t;

    instance.base.Apps = instance.web.Widget.extend({
        template: 'EmptyComponent',
        remote_action_id: 'loempia.action_embed',
        failback_action_id: 'base.open_module_tree',

        init: function(parent, action) {
            this._super(parent, action);
            var options = action.params || {};

            if (options.apps_user) {
                sessionStorage.setItem('apps.login', options.apps_user);
            }
            if (options.apps_access_token) {
                sessionStorage.setItem('apps.access_token', options.apps_access_token);
            }

            this.params = options; // NOTE read by embedded client action
        },

        get_client: function() {
            // return the client via a deferred, resolved or rejected depending if the remote host is available or not.
            var check_client_available = function(client) {
                var d = $.Deferred();
                var i = new Image();
                i.onerror = function() {
                    d.reject(client);
                };
                i.onload = function() {
                    client.session.session_bind(client.origin).then(function() {
                        // check if client can authenticate
                        client.authenticate().then(
                           function() {     /* done */
                            d.resolve(client);
                        }, function() {     /* fail */
                            if (client.login === 'anonymous') {
                                d.reject(client);
                            } else {
                                sessionStorage.removeItem('apps.login');
                                sessionStorage.removeItem('apps.access_token');
                                client.bind_crendentials(client.dbname, 'anonymous', 'anonymous');
                                client.authenticate().then(
                                   function() {     /* done */
                                    d.resolve(client);
                                }, function() {     /* fail */
                                    d.reject(client);
                                });
                            }
                        });
                    });

                };
                var ts = new Date().getTime();
                i.src = _.str.sprintf('%s/web/static/src/img/sep-a.gif?%s', client.origin, ts);
                return d.promise();
            };
            if (instance.base.apps_client) {
                return check_client_available(instance.base.apps_client);
            } else {
                var ICP = new instance.web.Model('ir.config_parameter');
                return ICP.call('get_param', ['apps.server', 'https://apps.openerp.com/apps']).then(function(u) {
                    var link = $(_.str.sprintf('', u))[0];
                    var host = _.str.sprintf('%s//%s', link.protocol, link.host);
                    var dbname = link.pathname;
                    if (dbname[0] === '/') {
                        dbname = dbname.substr(1);
                    }
                    var login = (sessionStorage ? sessionStorage.getItem('apps.login') : null) || 'anonymous';
                    var passwd = (sessionStorage ? sessionStorage.getItem('apps.access_token') : null) || 'anonymous';
                    if (_.isNull(instance.base.apps_remote)) {
                        instance.base.apps_remote = new openerp.init();
                    }
                    var client = new instance.base.apps_remote.web.EmbeddedClient(null, host, dbname, login, passwd);
                    instance.base.apps_client = client;
                    return check_client_available(client);
                });
            }
        },

        destroy: function() {
            if (instance.base.apps_client) {
                instance.base.apps_client.destroy();
            }
            return this._super();
        },

        start: function() {
            var self = this;
            return self.get_client().
                done(function(client) {
                    client.replace(self.$el).
                        done(function() {
                            client.$el.removeClass('openerp');
                            client.do_action(self.remote_action_id, {hide_breadcrumb: true});
                        });
                }).
                fail(function(client) {
                    self.do_warn(_t('OpenERP Apps Unreachable'), _t('Showing locally available modules'), true);
                    self.rpc('/web/action/load', {action_id: self.failback_action_id}).done(function(action) {
                        self.do_action(action);
                        instance.webclient.menu.open_action(action.id);
                    });
                });
        },
    });

    instance.base.AppsUpdates = instance.base.Apps.extend({
        remote_action_id: 'loempia.action_embed_updates'
    });

    instance.web.client_actions.add("apps", "instance.base.Apps");
    instance.web.client_actions.add("apps.updates", "instance.base.AppsUpdates");

};
<|endoftext|>


<commit_before>/* eslint-env es6 */

_1 = 2
_2 = 2 * _1
_3 = 3 * _1
_4 = 4 * _1
_5 = 5 * _1
_z = _1

// intercept transforms
nx_py = align('nx_py')

a = (geometry, ...transforms) => _(geometry, nx_py, ...transforms)

A = $$([
  a([_1, _5, _z]),
  a([_1, _1, _z], tx(_1)),
  a([_1, _1, _z], tx(_1), ty(-_2)),
  a([_1, _5, _z], tx(_2)),
])

B = $$([
  a([_1, _5, _z]),
  a([_2, _1, _z], tx(_1)),
  a([_1, _1, _z], tx(_2), ty(-_1)),
  a([_1, _1, _z], tx(_1), ty(-_2)),
  a([_1, _1, _z], tx(_2), ty(-_3)),
  a([_2, _1, _z], tx(_1), ty(-_4)),
])

C = $$([
  a([_1, _3, _z], ty(-_1)),
  a([_2, _1, _z], tx(_1)),
  a([_2, _1, _z], tx(_1), ty(-_4)),
])

D = $$([
  a([_1, _5, _z]),
  a([_1, _1, _z], tx(_1)),
  a([_1, _1, _z], tx(_1), ty(-_4)),
  a([_1, _4, _z], tx(_2), ty(-_1)),
])

E = $$([
  a([_1, _5, _z]),
  a([_2, _1, _z], tx(_1)),
  a([_1, _1, _z], tx(_1), ty(-_2)),
  a([_2, _1, _z], tx(_1), ty(-_4)),
])

F = $$([
  a([_1, _5, _z]),
  a([_2, _1, _z], tx(_1)),
  a([_1, _1, _z], tx(_1), ty(-_2)),
])

G = $$([
  a([_1, _4, _z], ty(-_1)),
  a([_2, _1, _z], tx(_1)),
  a([_1, _1, _z], tx(_2), ty(-_3)),
  a([_2, _1, _z], tx(_1), ty(-_4)),
])

H = $$([
  a([_1, _5, _z]),
  a([_1, _1, _z], tx(_1), ty(-_2)),
  a([_1, _5, _z], tx(_2)),
])

I = $$([
  a([_3, _1, _z]),
  a([_1, _3, _z], tx(_1), ty(-_1)),
  a([_3, _1, _z], ty(-_4)),
])

J = $$([
  a([_3, _1, _z]),
  a([_1, _3, _z], tx(_1), ty(-_1)),
  a([_2, _1, _z], ty(-_4)),
])

K = $$([
  a([_1, _5, _z]),
  a([_1, _2, _z], tx(_2)),
  a([_1, _1, _z], tx(_1), ty(-_2)),
  a([_1, _2, _z], tx(_2), ty(-_3)),
])

L = $$([
  a([_1, _5, _z]),
  a([_2, _1, _z], tx(_1), ty(-_4)),
])

M = $$([
  a([_1, _5, _z]),
  a([_1, _2, _z], tx(_1)),
  a([_1, _5, _z], tx(_2)),
])

N = $$([
  a([_1, _5, _z]),
  a([_1, _1, _z], tx(_1)),
  a([_1, _4, _z], tx(_2), ty(-_1)),
])

O = $$([
  a([_1, _4, _z], ty(-_1)),
  a([_1, _1, _z], tx(_1)),
  a([_1, _1, _z], tx(_1), ty(-_4)),
  a([_1, _4, _z], tx(_2)),
])

P = $$([
  a([_1, _5, _z]),
  a([_1, _1, _z], tx(_1)),
  a([_1, _1, _z], tx(_1), ty(-_2)),
  a([_1, _3, _z], tx(_2)),
])

Q = $$([
  a([_1, _2, _z], ty(-_1)),
  a([_2, _1, _z], ty(-_3)),
  a([_1, _1, _z], tx(_1)),
  a([_2, _1, _z], tx(_1), ty(-_4)),
  a([_1, _2, _z], tx(_2), ty(-_1)),
])

R = $$([
  a([_1, _5, _z]),
  a([_1, _1, _z], tx(_1)),
  a([_1, _1, _z], tx(_1), ty(-_2)),
  a([_1, _2, _z], tx(_2)),
  a([_1, _2, _z], tx(_2), ty(-_3)),
])

S = $$([
  a([_2, _1, _z], tx(_1)),
  a([_1, _1, _z], ty(-_1)),
  a([_3, _1, _z], ty(-_2)),
  a([_1, _1, _z], tx(_2), ty(-_3)),
  a([_2, _1, _z], ty(-_4)),
])

T = $$([
  a([_3, _1, _z]),
  a([_1, _4, _z], tx(_1), ty(-_1)),
])

U = $$([
  a([_1, _4, _z]),
  a([_1, _1, _z], tx(_1), ty(-_4)),
  a([_1, _5, _z], tx(_2)),
])

V = $$([
  a([_1, _4, _z]),
  a([_1, _1, _z], tx(_1), ty(-_4)),
  a([_1, _4, _z], tx(_2)),
])

W = $$([
  a([_1, _5, _z]),
  a([_1, _2, _z], tx(_1), ty(-_3)),
  a([_1, _5, _z], tx(_2)),
])

X = $$([
  a([_1, _2, _z]),
  a([_1, _2, _z], ty(-_3)),
  a([_1, _1, _z], tx(_1), ty(-_2)),
  a([_1, _2, _z], tx(_2)),
  a([_1, _2, _z], tx(_2), ty(-_3)),
])

Y = $$([
  a([_1, _2, _z]),
  a([_2, _1, _z], ty(-_2)),
  a([_2, _1, _z], ty(-_4)),
  a([_1, _5, _z], tx(_2)),
])

Z = $$([
  a([_3, _1, _z]),
  a([_1, _1, _z], tx(_2), ty(-_1)),
  a([_1, _1, _z], tx(_1), ty(-_2)),
  a([_1, _1, _z], ty(-_3)),
  a([_3, _1, _z], ty(-_4)),
])

return [
  A,
  B,
  C,
  D,
  E,
  F,
  G,
  H,
  I,
  J,
  K,
  L,
  M,
  N,
  O,
  P,
  Q,
  R,
  S,
  T,
  U,
  V,
  W,
  X,
  Y,
  Z,
].map((geometry, index, array) =>
  _(geometry, tx(_4 * (index - array.length / 2)), ty(_5))
)
<commit_msg>lathe[cuboid]: First pass at simplifying alphabet declarations.<commit_after>/* eslint-env es6 */

_1 = 2
_2 = 2 * _1
_3 = 3 * _1
_4 = 4 * _1
_5 = 5 * _1
_z = _1

a = parameters => $$(parameters.map(
  ([geometry, ...transforms]) => _(
    [...geometry.map(d => d * _1), _z],
    align('nx_py'),
    ...transforms
  )
), ty(_5))

x = _x => tx(_x * _1)
y = _y => ty(_y * -_1)

A = a([
  [[1, 5]],
  [[1, 1], x(1)],
  [[1, 1], x(1), y(2)],
  [[1, 5], x(2)],
])

B = a([
  [[1, 5]],
  [[2, 1], x(1)],
  [[1, 1], x(2), y(1)],
  [[1, 1], x(1), y(2)],
  [[1, 1], x(2), y(3)],
  [[2, 1], x(1), y(4)],
])

C = a([
  [[1, 3], y(1)],
  [[2, 1], x(1)],
  [[2, 1], x(1), y(4)],
])

D = a([
  [[1, 5]],
  [[1, 1], x(1)],
  [[1, 1], x(1), y(4)],
  [[1, 4], x(2), y(1)],
])

E = a([
  [[1, 5]],
  [[2, 1], x(1)],
  [[1, 1], x(1), y(2)],
  [[2, 1], x(1), y(4)],
])

F = a([
  [[1, 5]],
  [[2, 1], x(1)],
  [[1, 1], x(1), y(2)],
])

G = a([
  [[1, 4], y(1)],
  [[2, 1], x(1)],
  [[1, 1], x(2), y(3)],
  [[2, 1], x(1), y(4)],
])

H = a([
  [[1, 5]],
  [[1, 1], x(1), y(2)],
  [[1, 5], x(2)],
])

I = a([
  [[3, 1]],
  [[1, 3], x(1), y(1)],
  [[3, 1], y(4)],
])

J = a([
  [[3, 1]],
  [[1, 3], x(1), y(1)],
  [[2, 1], y(4)],
])

K = a([
  [[1, 5]],
  [[1, 2], x(2)],
  [[1, 1], x(1), y(2)],
  [[1, 2], x(2), y(3)],
])

L = a([
  [[1, 5]],
  [[2, 1], x(1), y(4)],
])

M = a([
  [[1, 5]],
  [[1, 2], x(1)],
  [[1, 5], x(2)],
])

N = a([
  [[1, 5]],
  [[1, 1], x(1)],
  [[1, 4], x(2), y(1)],
])

O = a([
  [[1, 4], y(1)],
  [[1, 1], x(1)],
  [[1, 1], x(1), y(4)],
  [[1, 4], x(2)],
])

P = a([
  [[1, 5]],
  [[1, 1], x(1)],
  [[1, 1], x(1), y(2)],
  [[1, 3], x(2)],
])

Q = a([
  [[1, 2], y(1)],
  [[2, 1], y(3)],
  [[1, 1], x(1)],
  [[2, 1], x(1), y(4)],
  [[1, 2], x(2), y(1)],
])

R = a([
  [[1, 5]],
  [[1, 1], x(1)],
  [[1, 1], x(1), y(2)],
  [[1, 2], x(2)],
  [[1, 2], x(2), y(3)],
])

S = a([
  [[2, 1], x(1)],
  [[1, 1], y(1)],
  [[3, 1], y(2)],
  [[1, 1], x(2), y(3)],
  [[2, 1], y(4)],
])

T = a([
  [[3, 1]],
  [[1, 4], x(1), y(1)],
])

U = a([
  [[1, 4]],
  [[1, 1], x(1), y(4)],
  [[1, 5], x(2)],
])

V = a([
  [[1, 4]],
  [[1, 1], x(1), y(4)],
  [[1, 4], x(2)],
])

W = a([
  [[1, 5]],
  [[1, 2], x(1), y(3)],
  [[1, 5], x(2)],
])

X = a([
  [[1, 2]],
  [[1, 2], y(3)],
  [[1, 1], x(1), y(2)],
  [[1, 2], x(2)],
  [[1, 2], x(2), y(3)],
])

Y = a([
  [[1, 2]],
  [[2, 1], y(2)],
  [[2, 1], y(4)],
  [[1, 5], x(2)],
])

Z = a([
  [[3, 1]],
  [[1, 1], x(2), y(1)],
  [[1, 1], x(1), y(2)],
  [[1, 1], y(3)],
  [[3, 1], y(4)],
])

return [
  A,
  B,
  C,
  D,
  E,
  F,
  G,
  H,
  I,
  J,
  K,
  L,
  M,
  N,
  O,
  P,
  Q,
  R,
  S,
  T,
  U,
  V,
  W,
  X,
  Y,
  Z,
].map((geometry, index, array) =>
  _(geometry, tx(_4 * (index - array.length / 2)))
)
<|endoftext|>


<commit_before>// const $ = require('jquery');
const $urlInput = $('.url-input');
const $displayUrls = $('.display-urls');
const $submitButton = $('.submit-button');
const $urlInputValue = $('.url-input');

$(document).ready(() => {
  getAllUrls();
});

let getAllUrls = () => {
  $.getJSON('api/URLs', (data) => {
    putUrlsOnPage(data.URLs);
  });
};

let putUrlsOnPage = (urls) => {
  $.each(urls, (key,value) => {
     $displayUrls.append(
      `

        ${key} is short for ${value}

`);
  });
};

$submitButton.on('click', (e) => {
  e.preventDefault();
  // let urlString = $urlInputValue.toString();
  // $.post('/api/URLs', { longURL: urlString
  // })
  // .then(getAllUrls());
  $.ajax({
    url: '/api/URLs/',
    type: 'POST',
    data: {longURL: $urlInput.val()},
    success: () => {
      getAllUrls();
    }
  });
});
<commit_msg>Add todos<commit_after>// const $ = require('jquery');
const $urlInput = $('.url-input');
const $displayUrls = $('.display-urls');
const $submitButton = $('.submit-button');

$(document).ready(() => {
  getAllUrls();
});

let getAllUrls = () => {
  $.getJSON('api/URLs', (data) => {
    putUrlsOnPage(data.URLs);
  });
};

let putUrlsOnPage = (urls) => {
  $.each(urls, (key,value) => {
     $displayUrls.append(
      `

        ${key} is short for ${value}

`);
  });
};

// TODO:  need to render shorty, longy, date added, and how many times clicked
// TODO: sort by popularity and by date added both ascending and descending
// TODO: be able to click shortened URL

$submitButton.on('click', (e) => {
  e.preventDefault();
  $.ajax({
    url: '/api/URLs/',
    type: 'POST',
    data: {longURL: $urlInput.val()},
    success: () => {
      getAllUrls();
      $urlInput.val('');
    }
  });
});
<|endoftext|>