<commit_before>const test = require('tap').test;
const path = require('path');
const VirtualMachine = require('../../src/index');
const sb3 = require('../../src/serialization/sb3');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const exampleProjectPath = path.resolve(__dirname, '../fixtures/clone-cleanup.sb2');
const commentsSB2ProjectPath = path.resolve(__dirname, '../fixtures/comments.sb2');
const commentsSB3ProjectPath = path.resolve(__dirname, '../fixtures/comments.sb3');
const commentsSB3NoDupeIds = path.resolve(__dirname, '../fixtures/comments_no_duplicate_id_serialization.sb3');
const variableReporterSB2ProjectPath = path.resolve(__dirname, '../fixtures/top-level-variable-reporter.sb2');
const topLevelReportersProjectPath = path.resolve(__dirname, '../fixtures/top-level-reporters.sb3');
const FakeRenderer = require('../fixtures/fake-renderer');

test('serialize', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(exampleProjectPath))
        .then(() => {
            const result = sb3.serialize(vm.runtime);
            // @todo Analyze
            t.type(JSON.stringify(result), 'string');
            t.end();
        });
});

test('deserialize', t => {
    const vm = new VirtualMachine();
    sb3.deserialize('', vm.runtime).then(({targets}) => {
        // @todo Analyze
        t.type(targets, 'object');
        t.end();
    });
});

test('serialize sb2 project with comments as sb3', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(commentsSB2ProjectPath))
        .then(() => {
            const result = sb3.serialize(vm.runtime);

            t.type(JSON.stringify(result), 'string');
            t.type(result.targets, 'object');
            t.equal(Array.isArray(result.targets), true);
            t.equal(result.targets.length, 2);

            const stage = result.targets[0];
            t.equal(stage.isStage, true);
            // The stage has 0 blocks, and 1 workspace comment
            t.type(stage.blocks, 'object');
            t.equal(Object.keys(stage.blocks).length, 0);
            t.type(stage.comments, 'object');
            t.equal(Object.keys(stage.comments).length, 1);
            const stageBlockComments = Object.values(stage.comments).filter(comment => !!comment.blockId);
            const stageWorkspaceComments = Object.values(stage.comments).filter(comment => comment.blockId === null);
            t.equal(stageBlockComments.length, 0);
            t.equal(stageWorkspaceComments.length, 1);

            const sprite = result.targets[1];
            t.equal(sprite.isStage, false);
            t.type(sprite.blocks, 'object');
            // Sprite 1 has 6 blocks, 5 block comments, and 1 workspace comment
            t.equal(Object.keys(sprite.blocks).length, 6);
            t.type(sprite.comments, 'object');
            t.equal(Object.keys(sprite.comments).length, 6);

            const spriteBlockComments = Object.values(sprite.comments).filter(comment => !!comment.blockId);
            const spriteWorkspaceComments = Object.values(sprite.comments).filter(comment => comment.blockId === null);
            t.equal(spriteBlockComments.length, 5);
            t.equal(spriteWorkspaceComments.length, 1);

            t.end();
        });
});

test('deserialize sb3 project with comments', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(commentsSB3ProjectPath))
        .then(() => {
            const runtime = vm.runtime;

            t.type(runtime.targets, 'object');
            t.equal(Array.isArray(runtime.targets), true);
            t.equal(runtime.targets.length, 2);

            const stage = runtime.targets[0];
            t.equal(stage.isStage, true);
            // The stage has 0 blocks, and 1 workspace comment
            t.type(stage.blocks, 'object');
            t.equal(Object.keys(stage.blocks._blocks).length, 0);
            t.type(stage.comments, 'object');
            t.equal(Object.keys(stage.comments).length, 1);
            const stageBlockComments = Object.values(stage.comments).filter(comment => !!comment.blockId);
            const stageWorkspaceComments = Object.values(stage.comments).filter(comment => comment.blockId === null);
            t.equal(stageBlockComments.length, 0);
            t.equal(stageWorkspaceComments.length, 1);

            const sprite = runtime.targets[1];
            t.equal(sprite.isStage, false);
            t.type(sprite.blocks, 'object');
            // Sprite 1 has 6 blocks, 5 block comments, and 1 workspace comment
            t.equal(Object.values(sprite.blocks._blocks).filter(block => !block.shadow).length, 6);
            t.type(sprite.comments, 'object');
            t.equal(Object.keys(sprite.comments).length, 6);

            const spriteBlockComments = Object.values(sprite.comments).filter(comment => !!comment.blockId);
            const spriteWorkspaceComments = Object.values(sprite.comments).filter(comment => comment.blockId === null);
            t.equal(spriteBlockComments.length, 5);
            t.equal(spriteWorkspaceComments.length, 1);

            t.end();
        });
});

test('deserialize sb3 project with comments - no duplicate id serialization', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(commentsSB3NoDupeIds))
        .then(() => {
            const runtime = vm.runtime;

            t.type(runtime.targets, 'object');
            t.equal(Array.isArray(runtime.targets), true);
            t.equal(runtime.targets.length, 2);

            const stage = runtime.targets[0];
            t.equal(stage.isStage, true);
            // The stage has 0 blocks, and 0 workspace comment
            t.type(stage.blocks, 'object');
            t.equal(Object.keys(stage.blocks._blocks).length, 0);
            t.type(stage.comments, 'object');
            t.equal(Object.keys(stage.comments).length, 0);

            const sprite = runtime.targets[1];
            t.equal(sprite.isStage, false);
            t.type(sprite.blocks, 'object');
            // Sprite1 has 1 blocks, 1 block comment, and 1 workspace comment
            t.equal(Object.values(sprite.blocks._blocks).filter(block => !block.shadow).length, 1);
            t.type(sprite.comments, 'object');
            t.equal(Object.keys(sprite.comments).length, 2);

            const spriteBlockComments = Object.values(sprite.comments).filter(comment => !!comment.blockId);
            const spriteWorkspaceComments = Object.values(sprite.comments).filter(comment => comment.blockId === null);
            t.equal(spriteBlockComments.length, 1);
            t.equal(spriteWorkspaceComments.length, 1);

            t.end();
        });
});

test('serialize sb3 preserves sprite layer order', t => {
    const vm = new VirtualMachine();
    vm.attachRenderer(new FakeRenderer());
    vm.loadProject(readFileToBuffer(path.resolve(__dirname, '../fixtures/ordering.sb2')))
        .then(() => {
            // Target get layer order needs a renderer,
            // fake the numbers we would get back from the
            // renderer in order to test that they are serialized
            // correctly
            vm.runtime.targets[0].getLayerOrder = () => 0;
            vm.runtime.targets[1].getLayerOrder = () => 20;
            vm.runtime.targets[2].getLayerOrder = () => 10;
            vm.runtime.targets[3].getLayerOrder = () => 30;

            const result = sb3.serialize(vm.runtime);

            t.type(JSON.stringify(result), 'string');
            t.type(result.targets, 'object');
            t.equal(Array.isArray(result.targets), true);
            t.equal(result.targets.length, 4);

            // First check that the sprites are ordered correctly (as they would
            // appear in the target pane)
            t.equal(result.targets[0].name, 'Stage');
            t.equal(result.targets[1].name, 'First');
            t.equal(result.targets[2].name, 'Second');
            t.equal(result.targets[3].name, 'Third');

            // Check that they are in the correct layer order (as they would render
            // back to front on the stage)
            t.equal(result.targets[0].layerOrder, 0);
            t.equal(result.targets[1].layerOrder, 2);
            t.equal(result.targets[2].layerOrder, 1);
            t.equal(result.targets[3].layerOrder, 3);

            t.end();
        });
});

test('serializeBlocks', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(commentsSB3ProjectPath))
        .then(() => {
            const blocks = vm.runtime.targets[1].blocks._blocks;
            const result = sb3.serializeBlocks(blocks);
            // @todo Analyze
            t.type(result[0], 'object');
            t.ok(Object.keys(result[0]).length < Object.keys(blocks).length, 'less blocks in serialized format');
            t.ok(Array.isArray(result[1]));
            t.end();
        });
});

test('serializeBlocks serializes x and y for topLevel blocks with x,y of 0,0', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(topLevelReportersProjectPath))
        .then(() => {
            // Verify that there are 2 blocks and they are both top level
            const blocks = vm.runtime.targets[1].blocks._blocks;
            const blockIds = Object.keys(blocks);
            t.equal(blockIds.length, 2);
            const blocksArray = blockIds.map(key => blocks[key]);
            t.equal(blocksArray.every(b => b.topLevel), true);
            // Simulate cleaning up the blocks by resetting x and y positions to 0
            blockIds.forEach(blockId => {
                blocks[blockId].x = 0;
                blocks[blockId].y = 0;
            });
            const result = sb3.serializeBlocks(blocks);
            const serializedBlocks = result[0];

            t.type(serializedBlocks, 'object');
            const serializedBlockIds = Object.keys(serializedBlocks);
            t.equal(serializedBlockIds.length, 2);
            const firstBlock = serializedBlocks[serializedBlockIds[0]];
            const secondBlock = serializedBlocks[serializedBlockIds[1]];
            t.equal(firstBlock.x, 0);
            t.equal(firstBlock.y, 0);
            t.equal(secondBlock.x, 0);
            t.equal(secondBlock.y, 0);

            t.end();
        });
});

test('deserializeBlocks', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(commentsSB3ProjectPath))
        .then(() => {
            const blocks = vm.runtime.targets[1].blocks._blocks;
            const serialized = sb3.serializeBlocks(blocks)[0];
            const deserialized = sb3.deserializeBlocks(serialized);
            t.equal(Object.keys(deserialized).length, Object.keys(blocks).length, 'same number of blocks');
            t.end();
        });
});

test('deserializeBlocks on already deserialized input', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(commentsSB3ProjectPath))
        .then(() => {
            const blocks = vm.runtime.targets[1].blocks._blocks;
            const serialized = sb3.serializeBlocks(blocks)[0];
            const deserialized = sb3.deserializeBlocks(serialized);
            const deserializedAgain = sb3.deserializeBlocks(deserialized);
            t.deepEqual(deserialized, deserializedAgain, 'no change from second pass of deserialize');
            t.end();
        });
});

test('getExtensionIdForOpcode', t => {
    t.equal(sb3.getExtensionIdForOpcode('wedo_loopy'), 'wedo');

    // does not consider CORE to be extensions
    t.false(sb3.getExtensionIdForOpcode('control_loopy'));

    // only considers things before the first underscore
    t.equal(sb3.getExtensionIdForOpcode('hello_there_loopy'), 'hello');

    // does not return anything for opcodes with no extension
    t.false(sb3.getExtensionIdForOpcode('hello'));

    t.end();
});

test('(#1608) serializeBlocks maintains top level variable reporters', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(variableReporterSB2ProjectPath))
        .then(() => {
            const blocks = vm.runtime.targets[0].blocks._blocks;
            const result = sb3.serialize(vm.runtime);
            // Project should have 1 block, a top-level variable reporter
            t.equal(Object.keys(blocks).length, 1);
            t.equal(Object.keys(result.targets[0].blocks).length, 1);

            // Make sure deserializing these blocks works
            t.doesNotThrow(() => {
                sb3.deserialize(JSON.parse(JSON.stringify(result)), vm.runtime);
            });
            t.end();
        });
});
<commit_msg>add unit test for loading draggability<commit_after>const test = require('tap').test;
const path = require('path');
const VirtualMachine = require('../../src/index');
const sb3 = require('../../src/serialization/sb3');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const exampleProjectPath = path.resolve(__dirname, '../fixtures/clone-cleanup.sb2');
const commentsSB2ProjectPath = path.resolve(__dirname, '../fixtures/comments.sb2');
const commentsSB3ProjectPath = path.resolve(__dirname, '../fixtures/comments.sb3');
const commentsSB3NoDupeIds = path.resolve(__dirname, '../fixtures/comments_no_duplicate_id_serialization.sb3');
const variableReporterSB2ProjectPath = path.resolve(__dirname, '../fixtures/top-level-variable-reporter.sb2');
const topLevelReportersProjectPath = path.resolve(__dirname, '../fixtures/top-level-reporters.sb3');
const draggableSB3ProjectPath = path.resolve(__dirname, '../fixtures/draggable.sb3');
const FakeRenderer = require('../fixtures/fake-renderer');

test('serialize', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(exampleProjectPath))
        .then(() => {
            const result = sb3.serialize(vm.runtime);
            // @todo Analyze
            t.type(JSON.stringify(result), 'string');
            t.end();
        });
});

test('deserialize', t => {
    const vm = new VirtualMachine();
    sb3.deserialize('', vm.runtime).then(({targets}) => {
        // @todo Analyze
        t.type(targets, 'object');
        t.end();
    });
});

test('serialize sb2 project with comments as sb3', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(commentsSB2ProjectPath))
        .then(() => {
            const result = sb3.serialize(vm.runtime);

            t.type(JSON.stringify(result), 'string');
            t.type(result.targets, 'object');
            t.equal(Array.isArray(result.targets), true);
            t.equal(result.targets.length, 2);

            const stage = result.targets[0];
            t.equal(stage.isStage, true);
            // The stage has 0 blocks, and 1 workspace comment
            t.type(stage.blocks, 'object');
            t.equal(Object.keys(stage.blocks).length, 0);
            t.type(stage.comments, 'object');
            t.equal(Object.keys(stage.comments).length, 1);
            const stageBlockComments = Object.values(stage.comments).filter(comment => !!comment.blockId);
            const stageWorkspaceComments = Object.values(stage.comments).filter(comment => comment.blockId === null);
            t.equal(stageBlockComments.length, 0);
            t.equal(stageWorkspaceComments.length, 1);

            const sprite = result.targets[1];
            t.equal(sprite.isStage, false);
            t.type(sprite.blocks, 'object');
            // Sprite 1 has 6 blocks, 5 block comments, and 1 workspace comment
            t.equal(Object.keys(sprite.blocks).length, 6);
            t.type(sprite.comments, 'object');
            t.equal(Object.keys(sprite.comments).length, 6);

            const spriteBlockComments = Object.values(sprite.comments).filter(comment => !!comment.blockId);
            const spriteWorkspaceComments = Object.values(sprite.comments).filter(comment => comment.blockId === null);
            t.equal(spriteBlockComments.length, 5);
            t.equal(spriteWorkspaceComments.length, 1);

            t.end();
        });
});

test('deserialize sb3 project with comments', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(commentsSB3ProjectPath))
        .then(() => {
            const runtime = vm.runtime;

            t.type(runtime.targets, 'object');
            t.equal(Array.isArray(runtime.targets), true);
            t.equal(runtime.targets.length, 2);

            const stage = runtime.targets[0];
            t.equal(stage.isStage, true);
            // The stage has 0 blocks, and 1 workspace comment
            t.type(stage.blocks, 'object');
            t.equal(Object.keys(stage.blocks._blocks).length, 0);
            t.type(stage.comments, 'object');
            t.equal(Object.keys(stage.comments).length, 1);
            const stageBlockComments = Object.values(stage.comments).filter(comment => !!comment.blockId);
            const stageWorkspaceComments = Object.values(stage.comments).filter(comment => comment.blockId === null);
            t.equal(stageBlockComments.length, 0);
            t.equal(stageWorkspaceComments.length, 1);

            const sprite = runtime.targets[1];
            t.equal(sprite.isStage, false);
            t.type(sprite.blocks, 'object');
            // Sprite 1 has 6 blocks, 5 block comments, and 1 workspace comment
            t.equal(Object.values(sprite.blocks._blocks).filter(block => !block.shadow).length, 6);
            t.type(sprite.comments, 'object');
            t.equal(Object.keys(sprite.comments).length, 6);

            const spriteBlockComments = Object.values(sprite.comments).filter(comment => !!comment.blockId);
            const spriteWorkspaceComments = Object.values(sprite.comments).filter(comment => comment.blockId === null);
            t.equal(spriteBlockComments.length, 5);
            t.equal(spriteWorkspaceComments.length, 1);

            t.end();
        });
});

test('deserialize sb3 project with comments - no duplicate id serialization', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(commentsSB3NoDupeIds))
        .then(() => {
            const runtime = vm.runtime;

            t.type(runtime.targets, 'object');
            t.equal(Array.isArray(runtime.targets), true);
            t.equal(runtime.targets.length, 2);

            const stage = runtime.targets[0];
            t.equal(stage.isStage, true);
            // The stage has 0 blocks, and 0 workspace comment
            t.type(stage.blocks, 'object');
            t.equal(Object.keys(stage.blocks._blocks).length, 0);
            t.type(stage.comments, 'object');
            t.equal(Object.keys(stage.comments).length, 0);

            const sprite = runtime.targets[1];
            t.equal(sprite.isStage, false);
            t.type(sprite.blocks, 'object');
            // Sprite1 has 1 blocks, 1 block comment, and 1 workspace comment
            t.equal(Object.values(sprite.blocks._blocks).filter(block => !block.shadow).length, 1);
            t.type(sprite.comments, 'object');
            t.equal(Object.keys(sprite.comments).length, 2);

            const spriteBlockComments = Object.values(sprite.comments).filter(comment => !!comment.blockId);
            const spriteWorkspaceComments = Object.values(sprite.comments).filter(comment => comment.blockId === null);
            t.equal(spriteBlockComments.length, 1);
            t.equal(spriteWorkspaceComments.length, 1);

            t.end();
        });
});

test('serialize sb3 preserves sprite layer order', t => {
    const vm = new VirtualMachine();
    vm.attachRenderer(new FakeRenderer());
    vm.loadProject(readFileToBuffer(path.resolve(__dirname, '../fixtures/ordering.sb2')))
        .then(() => {
            // Target get layer order needs a renderer,
            // fake the numbers we would get back from the
            // renderer in order to test that they are serialized
            // correctly
            vm.runtime.targets[0].getLayerOrder = () => 0;
            vm.runtime.targets[1].getLayerOrder = () => 20;
            vm.runtime.targets[2].getLayerOrder = () => 10;
            vm.runtime.targets[3].getLayerOrder = () => 30;

            const result = sb3.serialize(vm.runtime);

            t.type(JSON.stringify(result), 'string');
            t.type(result.targets, 'object');
            t.equal(Array.isArray(result.targets), true);
            t.equal(result.targets.length, 4);

            // First check that the sprites are ordered correctly (as they would
            // appear in the target pane)
            t.equal(result.targets[0].name, 'Stage');
            t.equal(result.targets[1].name, 'First');
            t.equal(result.targets[2].name, 'Second');
            t.equal(result.targets[3].name, 'Third');

            // Check that they are in the correct layer order (as they would render
            // back to front on the stage)
            t.equal(result.targets[0].layerOrder, 0);
            t.equal(result.targets[1].layerOrder, 2);
            t.equal(result.targets[2].layerOrder, 1);
            t.equal(result.targets[3].layerOrder, 3);

            t.end();
        });
});

test('serializeBlocks', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(commentsSB3ProjectPath))
        .then(() => {
            const blocks = vm.runtime.targets[1].blocks._blocks;
            const result = sb3.serializeBlocks(blocks);
            // @todo Analyze
            t.type(result[0], 'object');
            t.ok(Object.keys(result[0]).length < Object.keys(blocks).length, 'less blocks in serialized format');
            t.ok(Array.isArray(result[1]));
            t.end();
        });
});

test('serializeBlocks serializes x and y for topLevel blocks with x,y of 0,0', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(topLevelReportersProjectPath))
        .then(() => {
            // Verify that there are 2 blocks and they are both top level
            const blocks = vm.runtime.targets[1].blocks._blocks;
            const blockIds = Object.keys(blocks);
            t.equal(blockIds.length, 2);
            const blocksArray = blockIds.map(key => blocks[key]);
            t.equal(blocksArray.every(b => b.topLevel), true);
            // Simulate cleaning up the blocks by resetting x and y positions to 0
            blockIds.forEach(blockId => {
                blocks[blockId].x = 0;
                blocks[blockId].y = 0;
            });
            const result = sb3.serializeBlocks(blocks);
            const serializedBlocks = result[0];

            t.type(serializedBlocks, 'object');
            const serializedBlockIds = Object.keys(serializedBlocks);
            t.equal(serializedBlockIds.length, 2);
            const firstBlock = serializedBlocks[serializedBlockIds[0]];
            const secondBlock = serializedBlocks[serializedBlockIds[1]];
            t.equal(firstBlock.x, 0);
            t.equal(firstBlock.y, 0);
            t.equal(secondBlock.x, 0);
            t.equal(secondBlock.y, 0);

            t.end();
        });
});

test('deserializeBlocks', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(commentsSB3ProjectPath))
        .then(() => {
            const blocks = vm.runtime.targets[1].blocks._blocks;
            const serialized = sb3.serializeBlocks(blocks)[0];
            const deserialized = sb3.deserializeBlocks(serialized);
            t.equal(Object.keys(deserialized).length, Object.keys(blocks).length, 'same number of blocks');
            t.end();
        });
});

test('deserializeBlocks on already deserialized input', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(commentsSB3ProjectPath))
        .then(() => {
            const blocks = vm.runtime.targets[1].blocks._blocks;
            const serialized = sb3.serializeBlocks(blocks)[0];
            const deserialized = sb3.deserializeBlocks(serialized);
            const deserializedAgain = sb3.deserializeBlocks(deserialized);
            t.deepEqual(deserialized, deserializedAgain, 'no change from second pass of deserialize');
            t.end();
        });
});

test('getExtensionIdForOpcode', t => {
    t.equal(sb3.getExtensionIdForOpcode('wedo_loopy'), 'wedo');

    // does not consider CORE to be extensions
    t.false(sb3.getExtensionIdForOpcode('control_loopy'));

    // only considers things before the first underscore
    t.equal(sb3.getExtensionIdForOpcode('hello_there_loopy'), 'hello');

    // does not return anything for opcodes with no extension
    t.false(sb3.getExtensionIdForOpcode('hello'));

    t.end();
});

test('(#1608) serializeBlocks maintains top level variable reporters', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(variableReporterSB2ProjectPath))
        .then(() => {
            const blocks = vm.runtime.targets[0].blocks._blocks;
            const result = sb3.serialize(vm.runtime);
            // Project should have 1 block, a top-level variable reporter
            t.equal(Object.keys(blocks).length, 1);
            t.equal(Object.keys(result.targets[0].blocks).length, 1);

            // Make sure deserializing these blocks works
            t.doesNotThrow(() => {
                sb3.deserialize(JSON.parse(JSON.stringify(result)), vm.runtime);
            });
            t.end();
        });
});

test('(#1850) sprite draggability state read when loading SB3 file', t => {
    const vm = new VirtualMachine();
    vm.loadProject(readFileToBuffer(draggableSB3ProjectPath))
        .then(() => {
            const sprite1Obj = vm.runtime.targets.find(target => target.sprite.name === 'Sprite1')
            // Sprite1 in project should have draggable set to true
            t.equal(sprite1Obj.draggable, true);
            t.end();
        });
});
<|endoftext|>


<commit_before>/** @const */ var BOOL=0;
/** @const */ var I8=1;
/** @const */ var U8=2;
/** @const */ var I16=3;
/** @const */ var U16=4;
/** @const */ var I32=5;
/** @const */ var U32=6;
/** @const */ var F32=7;
/** @const */ var F64=8;
/** @const */ var DATE=9;
/** @const */ var UTF8=10;

/**
 * Creates binary stream reader with the following API:
 * - stream.read(type) - reads specified type from the stream,
 *   where type could be one of the following values:
 *     BOOL - to read boolean value,
 *     I8 - to read signed 8-bit integer number,
 *     U8 - to read unsigned 8-bit integer number,
 *     I16 - to read signed 16-bit integer number,
 *     U16 - to read unsigned 16-bit integer number,
 *     I32 - to read signed 32-bit integer number,
 *     U32 - to read unsigned 32-bit integer number,
 *     F32 - to read 32-bit floating number,
 *     F64 - to read 64-bit floating number,
 *     UTF8 - to read UTF8 string sequence terminated by zero,
 *     object - to read struct as sequence of primitive types or structs.
 */
function Stream(buffer, offset, length, le){
	if (arguments.length <= 1) offset = 0;
	if (arguments.length <= 2) length = buffer.byteLength;
	if (arguments.length <= 3) le = true;

	if (offset < 0 || offset >= buffer.byteLength)
		throw new RangeError("Offset is out of range.");

	var start = offset;
	var pos = offset;
	var view = new DataView(buffer, offset, length);
	var stream = {
		length: length,
		position: function() { return pos; }
	};

	function isObject(v) { return !!(v && (typeof v == 'object')); }

	if (Object.keys === undefined) {
		Object.keys = function(v) {
			var arr = [];
			for (var k in v) {
				arr.push(k);
			}
			return arr;
		};
	}

	stream.read = function(type) {
		if (isObject(type)) return readSeq(type);
		return readPrimitive(type);
	};

	stream.readByte = function() {
		return view.getUint8(pos++);
	};

	stream.readBytes = function(count) {
		// TODO find a way to read buffer with one call
		var bytes = new Array(count);
		for (var i = 0; i < count; i++)
			bytes[i] = readByte();
		return bytes;
	};

	// TODO origin parameter
	stream.seek = function(offset) {
		pos = offset;
		return stream;
	};

	stream.skip = function(bytes) {
		pos += bytes;
		return stream;
	};

	stream.slice = function(position, size) {
		return Stream(buffer, start + position, size, le);
	};

	function NotImplemented() { return new Error("not implemented yet!"); }

	function readSeq(type) {
		var keys = Object.keys(type);
		var result = {};
		for (var i = 0; i < keys.length; i++) {
			var k = keys[i];
			var t = type[k];
			var v = stream.read(t);
			result[k] = v;
		}
		return result;
	}

	function readPrimitive(type) {
		var v;
		switch (type){
			case BOOL:
				return !!view.getInt8(pos++);
			case I8:
				return view.getInt8(pos++);
			case U8:
				return view.getUint8(pos++);
			case I16:
				v = view.getInt16(pos, le);
				pos += 2;
				break;
			case U16:
				v = view.getUint16(pos, le);
				pos += 2;
				break;
			case I32:
				v = view.getInt32(pos, le);
				pos += 4;
				break;
			case U32:
				v = view.getUint32(pos, le);
				pos += 4;
				break;
			case F32:
				v = view.getFloat32(pos, le);
				pos += 4;
				break;
			case F64:
				v = view.getFloat64(pos, le);
				pos += 8;
				break;
			case UTF8:
				return readUtf8();
			case DATE:
				throw NotImplemented();
		}
		return v;
	}

	function readByte(){
		return view.getUint8(pos++);
	}

	// TODO: find native way to read utf8 strings from array buffer

	/*
	 * UTF8 to unicode algorithm:
	 * Let's take a UTF-8 byte sequence. The first byte in a new sequence will tell us how long the sequence is.
	 * Let's call the subsequent decimal bytes z y x w v u.
	 *
	 * If z is between and including 0 - 127, then there is 1 byte z. The decimal Unicode value ud = the value of z.
	 * If z is between and including 192 - 223, then there are 2 bytes z y; ud = (z-192)*64 + (y-128)
	 * If z is between and including 224 - 239, then there are 3 bytes z y x; ud = (z-224)*4096 + (y-128)*64 + (x-128)
	 * If z is between and including 240 - 247, then there are 4 bytes z y x w; ud = (z-240)*262144 + (y-128)*4096 + (x-128)*64 + (w-128)
	 * If z is between and including 248 - 251, then there are 5 bytes z y x w v; ud = (z-248)*16777216 + (y-128)*262144 + (x-128)*4096 + (w-128)*64 + (v-128)
	 * If z is 252 or 253, then there are 6 bytes z y x w v u; ud = (z-252)*1073741824 + (y-128)*16777216 + (x-128)*262144 + (w-128)*4096 + (v-128)*64 + (u-128)
	 * If z = 254 or 255 then there is something wrong!
	 *
	 * Example: take the decimal Unicode designation 8482 (decimal), which is for the trademark sign.
	 * This number is larger than 2048, so we get three numbers.
	 * The first number is 224 + (8482 div 4096) = 224 + 2 = 226.
	 * The second number is 128 + (8482 div 64) mod 64) = 128 + (132 mod 64) = 128 + 4 = 132.
	 * The third number is 128 + (8482 mod 64) = 128 + 34 = 162.
	 * Now the other way round. We see the numbers 226, 132 and 162. What is the decimal Unicode value?
	 * In this case: (226-224)*4096+(132-128)*64+(162-128) = 8482.
	 * And the conversion between hexadecimal and decimal? Come on, this is not a math tutorial! In case you don't know, use a calculator.
	*/
	function readUtf8(bytesToRead) {
		if (arguments.length == 0) bytesToRead = -1;

		var s = "";
		var byteCount = 0;

		while (bytesToRead == -1 || byteCount < bytesToRead) {
			var b0 = readByte();
			byteCount++;
			if (b0 == 0) break;

			if ((b0 & 0x80) == 0) {
				s += String.fromCharCode(b0);
				continue;
			}

			var ch;
			var b1 = readByte();
			byteCount++;
			if (b1 == 0) {
				//Dangling lead byte, do not decompose
				s += String.fromCharCode(b0);
				break;
			}

			if ((b0 & 0x20) == 0) {
				ch = String.fromCharCode(((b0 & 0x1F) << 6) | (b1 & 0x3F));
			} else {
				var b2 = readByte();
				byteCount++;
				if (b2 == 0) {
					//Dangling lead bytes, do not decompose
					s += String.fromCharCode((b0 << 8) | b1);
					break;
				}

				var ch32;
				if ((b0 & 0x10) == 0) {
					ch32 = ((b0 & 0x0F) << 12) | ((b1 & 0x3F) << 6) | (b2 & 0x3F);
				} else {
					var b3 = readByte();
					byteCount++;
					if (b3 == 0) {
						s += String.fromCharCode((b0 << 8) | b1);
						s += String.fromCharCode(b2);
						break;
					}
					ch32 = ((b0 & 0x07) << 0x18) // combine 6 bit parts
							| ((b1 & 0x3F) << 12)
							| ((b2 & 0x3F) << 6)
							| (b3 & 0x3F);
				}

				if ((ch32 & 0xFFFF0000) == 0) {
					ch = String.fromCharCode(ch32);
				} else {
					//break up into UTF16 surrogate pair
					s += String.fromCharCode((ch32 >> 10) | 0xD800);
					ch = String.fromCharCode((ch32 & 0x3FF) | 0xDC00);
				}
			}

			s += ch;
		}

		return s;
	}

	return stream;
}

<commit_msg>fixed initial stream pos<commit_after>/** @const */ var BOOL=0;
/** @const */ var I8=1;
/** @const */ var U8=2;
/** @const */ var I16=3;
/** @const */ var U16=4;
/** @const */ var I32=5;
/** @const */ var U32=6;
/** @const */ var F32=7;
/** @const */ var F64=8;
/** @const */ var DATE=9;
/** @const */ var UTF8=10;

/**
 * Creates binary stream reader with the following API:
 * - stream.read(type) - reads specified type from the stream,
 *   where type could be one of the following values:
 *     BOOL - to read boolean value,
 *     I8 - to read signed 8-bit integer number,
 *     U8 - to read unsigned 8-bit integer number,
 *     I16 - to read signed 16-bit integer number,
 *     U16 - to read unsigned 16-bit integer number,
 *     I32 - to read signed 32-bit integer number,
 *     U32 - to read unsigned 32-bit integer number,
 *     F32 - to read 32-bit floating number,
 *     F64 - to read 64-bit floating number,
 *     UTF8 - to read UTF8 string sequence terminated by zero,
 *     object - to read struct as sequence of primitive types or structs.
 */
function Stream(buffer, offset, length, le){
	if (arguments.length <= 1) offset = 0;
	if (arguments.length <= 2) length = buffer.byteLength;
	if (arguments.length <= 3) le = true;

	if (offset < 0 || offset >= buffer.byteLength)
		throw new RangeError("Offset is out of range.");

	var start = offset;
	var pos = 0;
	var view = new DataView(buffer, offset, length);
	var stream = {
		length: length,
		position: function() { return pos; }
	};

	function isObject(v) { return !!(v && (typeof v == 'object')); }

	if (Object.keys === undefined) {
		Object.keys = function(v) {
			var arr = [];
			for (var k in v) {
				arr.push(k);
			}
			return arr;
		};
	}

	stream.read = function(type) {
		if (isObject(type)) return readSeq(type);
		return readPrimitive(type);
	};

	stream.readByte = function() {
		return view.getUint8(pos++);
	};

	stream.readBytes = function(count) {
		// TODO find a way to read buffer with one call
		var bytes = new Array(count);
		for (var i = 0; i < count; i++)
			bytes[i] = readByte();
		return bytes;
	};

	// TODO origin parameter
	stream.seek = function(offset) {
		pos = offset;
		return stream;
	};

	stream.skip = function(bytes) {
		pos += bytes;
		return stream;
	};

	stream.slice = function(position, size) {
		return Stream(buffer, start + position, size, le);
	};

	function NotImplemented() { return new Error("not implemented yet!"); }

	function readSeq(type) {
		var keys = Object.keys(type);
		var result = {};
		for (var i = 0; i < keys.length; i++) {
			var k = keys[i];
			var t = type[k];
			var v = stream.read(t);
			result[k] = v;
		}
		return result;
	}

	function readPrimitive(type) {
		var v;
		switch (type){
			case BOOL:
				return !!view.getInt8(pos++);
			case I8:
				return view.getInt8(pos++);
			case U8:
				return view.getUint8(pos++);
			case I16:
				v = view.getInt16(pos, le);
				pos += 2;
				break;
			case U16:
				v = view.getUint16(pos, le);
				pos += 2;
				break;
			case I32:
				v = view.getInt32(pos, le);
				pos += 4;
				break;
			case U32:
				v = view.getUint32(pos, le);
				pos += 4;
				break;
			case F32:
				v = view.getFloat32(pos, le);
				pos += 4;
				break;
			case F64:
				v = view.getFloat64(pos, le);
				pos += 8;
				break;
			case UTF8:
				return readUtf8();
			case DATE:
				throw NotImplemented();
		}
		return v;
	}

	function readByte(){
		return view.getUint8(pos++);
	}

	// TODO: find native way to read utf8 strings from array buffer

	/*
	 * UTF8 to unicode algorithm:
	 * Let's take a UTF-8 byte sequence. The first byte in a new sequence will tell us how long the sequence is.
	 * Let's call the subsequent decimal bytes z y x w v u.
	 *
	 * If z is between and including 0 - 127, then there is 1 byte z. The decimal Unicode value ud = the value of z.
	 * If z is between and including 192 - 223, then there are 2 bytes z y; ud = (z-192)*64 + (y-128)
	 * If z is between and including 224 - 239, then there are 3 bytes z y x; ud = (z-224)*4096 + (y-128)*64 + (x-128)
	 * If z is between and including 240 - 247, then there are 4 bytes z y x w; ud = (z-240)*262144 + (y-128)*4096 + (x-128)*64 + (w-128)
	 * If z is between and including 248 - 251, then there are 5 bytes z y x w v; ud = (z-248)*16777216 + (y-128)*262144 + (x-128)*4096 + (w-128)*64 + (v-128)
	 * If z is 252 or 253, then there are 6 bytes z y x w v u; ud = (z-252)*1073741824 + (y-128)*16777216 + (x-128)*262144 + (w-128)*4096 + (v-128)*64 + (u-128)
	 * If z = 254 or 255 then there is something wrong!
	 *
	 * Example: take the decimal Unicode designation 8482 (decimal), which is for the trademark sign.
	 * This number is larger than 2048, so we get three numbers.
	 * The first number is 224 + (8482 div 4096) = 224 + 2 = 226.
	 * The second number is 128 + (8482 div 64) mod 64) = 128 + (132 mod 64) = 128 + 4 = 132.
	 * The third number is 128 + (8482 mod 64) = 128 + 34 = 162.
	 * Now the other way round. We see the numbers 226, 132 and 162. What is the decimal Unicode value?
	 * In this case: (226-224)*4096+(132-128)*64+(162-128) = 8482.
	 * And the conversion between hexadecimal and decimal? Come on, this is not a math tutorial! In case you don't know, use a calculator.
	*/
	function readUtf8(bytesToRead) {
		if (arguments.length == 0) bytesToRead = -1;

		var s = "";
		var byteCount = 0;

		while (bytesToRead == -1 || byteCount < bytesToRead) {
			var b0 = readByte();
			byteCount++;
			if (b0 == 0) break;

			if ((b0 & 0x80) == 0) {
				s += String.fromCharCode(b0);
				continue;
			}

			var ch;
			var b1 = readByte();
			byteCount++;
			if (b1 == 0) {
				//Dangling lead byte, do not decompose
				s += String.fromCharCode(b0);
				break;
			}

			if ((b0 & 0x20) == 0) {
				ch = String.fromCharCode(((b0 & 0x1F) << 6) | (b1 & 0x3F));
			} else {
				var b2 = readByte();
				byteCount++;
				if (b2 == 0) {
					//Dangling lead bytes, do not decompose
					s += String.fromCharCode((b0 << 8) | b1);
					break;
				}

				var ch32;
				if ((b0 & 0x10) == 0) {
					ch32 = ((b0 & 0x0F) << 12) | ((b1 & 0x3F) << 6) | (b2 & 0x3F);
				} else {
					var b3 = readByte();
					byteCount++;
					if (b3 == 0) {
						s += String.fromCharCode((b0 << 8) | b1);
						s += String.fromCharCode(b2);
						break;
					}
					ch32 = ((b0 & 0x07) << 0x18) // combine 6 bit parts
							| ((b1 & 0x3F) << 12)
							| ((b2 & 0x3F) << 6)
							| (b3 & 0x3F);
				}

				if ((ch32 & 0xFFFF0000) == 0) {
					ch = String.fromCharCode(ch32);
				} else {
					//break up into UTF16 surrogate pair
					s += String.fromCharCode((ch32 >> 10) | 0xD800);
					ch = String.fromCharCode((ch32 & 0x3FF) | 0xDC00);
				}
			}

			s += ch;
		}

		return s;
	}

	return stream;
}

<|endoftext|>


<commit_before>import { htmlSafe } from 'ember-string';
import makeHelper from 'ember-svg-jar/utils/make-helper';
import makeSVG from 'ember-svg-jar/utils/make-svg';
import inlineAssets from '../inline-assets';

export default makeHelper((assetId, svgAttrs) => (
  htmlSafe(makeSVG(assetId, svgAttrs, inlineAssets))
));
<commit_msg>Make svgJar a callable method<commit_after>import { htmlSafe } from 'ember-string';
import makeHelper from 'ember-svg-jar/utils/make-helper';
import makeSVG from 'ember-svg-jar/utils/make-svg';
import inlineAssets from '../inline-assets';

export function svgJar(assetId, svgAttrs) {
  return htmlSafe(makeSVG(assetId, svgAttrs, inlineAssets));
}

export default makeHelper(svgJar);
<|endoftext|>


<commit_before>/**
 * 2017-9-17    sunzhiyue
 */
var str = '    hello world 1     ';
//var str = ''
console.log(str.charAt(0));
console.log(str.charAt(-4));
console.log(str.charAt(14));
console.log(str.charAt(7));
console.log(str.concat(' how are you'));
console.log(str.concat(' '));
console.log('-------------------')
console.log(str.includes('hello'));
console.log(str.includes('no'));
console.log(str.includes('hello',1));
console.log(str.includes('hello 1', -1));
console.log(str.includes(''))
console.log('-----------------------')
console.log(str.endsWith('1'))
console.log(str.endsWith('hello',5))
console.log(str.endsWith('2'))
console.log(str.endsWith('hello',-1))
console.log(str.endsWith(''))
console.log('------------------------');
console.log(str.indexOf('world'))
console.log(str.indexOf('worldo'));
console.log(str.indexOf('8'))
console.log(str.indexOf('9'))
console.log(str.indexOf('world',8));
console.log(str.indexOf('world',-7));
console.log(str.indexOf('world',0))
console.log(str.indexOf(''))
console.log('----------------------');
console.log(str.lastIndexOf('e'))
console.log(str.lastIndexOf('q'))
console.log(str.lastIndexOf('e',-1))
console.log(str.lastIndexOf('e',23))
console.log(str.lastIndexOf('e',0))
console.log(str.lastIndexOf('o',0))
console.log(str.lastIndexOf('o',8))
console.log('---------------------')
console.log(str.padEnd(1,'hello'))
console.log(str.padEnd(-1,'hello'))
console.log(str.padEnd(18,'hello'))
console.log(str.padEnd(30,'hello'))
console.log(str.padEnd(100,'hello'))
console.log('---------------------')
console.log(str.padStart(20,'11'));
console.log(str.padStart(1,'1'))
console.log(str.padStart(-1,'11'))
console.log('---------------------')
console.log(str.repeat(3))
console.log(str.repeat(0))
console.log(str.repeat(2.5))
console.log(str.repeat(3/4))
console.log(str.repeat(3*3))
console.log('---------------------')
console.log(str.slice(1,4));
console.log(str.slice(9,-2));
console.log(str.slice(0));
console.log(str.slice(-1));
console.log(str.slice(30));
console.log(str.slice(10));
console.log(str.slice(-1,10));
console.log('---------------------')
console.log(str.split('o',4));  //数字是切几段
console.log(str.split('o',-1));  //负数无意义
console.log(str.split('o',1));
console.log(str.split('o',2));
console.log(str.split('llo',4));
console.log('---------------------')
console.log(str.startsWith('hello'));
console.log(str.startsWith('w',2));
console.log(str.startsWith('e',1));
console.log(str.startsWith('h',-1));//负数默认为0
console.log(str.startsWith('w',-1));
console.log('---------------------')
console.log(str.substr(2));
console.log(str.substr(20));//超了不显示
console.log(str.substr(-3, -2));
console.log(str.substr(-3, 5));
console.log(str.substr(-3, 5));
console.log(str.substr(3, -2))//长度负数为空
console.log(str.substr(3, 5));
console.log('---------------------')
console.log(str.trim());
console.log(str.trimLeft());
console.log(str.trimRight());
<commit_msg>string 的使用方法<commit_after>/**
 * 2017-9-17    sunzhiyue
 */
var str = '    hello world 1     ';
//var str = ''
console.log(str.charAt(0));
console.log(str.charAt(-4));
console.log(str.charAt(14));
console.log(str.charAt(7));
console.log(str.concat(' how are you'));
console.log(str.concat(' '));
console.log('-------------------')
console.log(str.includes('hello'));
console.log(str.includes('no'));
console.log(str.includes('hello', 1));
console.log(str.includes('hello 1', -1));
console.log(str.includes(''))
console.log('-----------------------')
console.log(str.endsWith('1'))
console.log(str.endsWith('hello', 5))
console.log(str.endsWith('2'))
console.log(str.endsWith('hello', -1))
console.log(str.endsWith(''))
console.log('------------------------');
console.log(str.indexOf('world'))
console.log(str.indexOf('worldo'));
console.log(str.indexOf('8'))
console.log(str.indexOf('9'))
console.log(str.indexOf('world', 8));
console.log(str.indexOf('world', -7));
console.log(str.indexOf('world', 0))
console.log(str.indexOf(''))
console.log('----------------------');
console.log(str.lastIndexOf('e'))
console.log(str.lastIndexOf('q'))
console.log(str.lastIndexOf('e', -1))
console.log(str.lastIndexOf('e', 23))
console.log(str.lastIndexOf('e', 0))
console.log(str.lastIndexOf('o', 0))
console.log(str.lastIndexOf('o', 8))
console.log('---------------------')
console.log(str.padEnd(1, 'hello'))
console.log(str.padEnd(-1, 'hello'))
console.log(str.padEnd(18, 'hello'))
console.log(str.padEnd(30, 'hello'))
console.log(str.padEnd(100, 'hello'))
console.log('---------------------')
console.log(str.padStart(20, '11'));
console.log(str.padStart(1, '1'))
console.log(str.padStart(-1, '11'))
console.log('---------------------')
console.log(str.repeat(3))
console.log(str.repeat(0))
console.log(str.repeat(2.5))
console.log(str.repeat(3 / 4))
console.log(str.repeat(3 * 3))
console.log('---------------------')
console.log(str.slice(1, 4));
console.log(str.slice(9, -2));
console.log(str.slice(0));
console.log(str.slice(-1));
console.log(str.slice(30));
console.log(str.slice(10));
console.log(str.slice(-1, 10));
console.log('---------------------')
console.log(str.split('o', 4));  //数字是切几段
console.log(str.split('o', -1));  //负数无意义
console.log(str.split('o', 1));
console.log(str.split('o', 2));
console.log(str.split('llo', 4));
console.log('---------------------')
console.log(str.startsWith('hello'));
console.log(str.startsWith('w', 2));
console.log(str.startsWith('e', 1));
console.log(str.startsWith('h', -1));//负数默认为0
console.log(str.startsWith('w', -1));
console.log('---------------------')
console.log(str.substr(2));
console.log(str.substr(20));//超了不显示
console.log(str.substr(-3, -2));
console.log(str.substr(-3, 5));
console.log(str.substr(-3, 5));
console.log(str.substr(3, -2))//长度负数为空
console.log(str.substr(3, 5));
console.log('---------------------')
console.log(str.trim());
console.log(str.trimLeft());
console.log(str.trimRight());
<|endoftext|>


<commit_before>'use strict';

/**
Magicka Wizard Wars spell parser function.
Recieves a string.
Outputs a Array of spellMatch objects.
spellMatch = {
	start, // position in the original string where spell begins
	end,   // position in the original string where spell ends
	spell, // string containing the spell (modifiers included)
}
**/

function spellParser(str) {
	var filter = ['FAQ'];
	var result = [];
	var re = /(!|c)?([QWERASDFX]{3}|[QWERASDFX]\[[QWERASDFX][QWERASDFX]\]|\[[QWERASDFX][QWERASDFX]\][QWERASDFX]|\[[QWERASDFX]{3}\])(:[0-9]{3})?/g;
	var match = re.exec(str);
	while (match != null) {
		var s = {
			start : match.index,
			end   : re.lastIndex,
			spell : str.substring(match.index, re.lastIndex)
		};
		if (filter.indexOf(s.spell) < 0 &&
			(s.start == 0 || str[s.start-1].match(/[\W\S]/) != null) &&
			(s.end == str.length || str[s.end].match(/[\W\S]/) != null)
			)
			result.push(s);
		else
			console.log(str.substring(s.start-1, s.end +1));
		match = re.exec(str);
	}
	return result;
}
<commit_msg>Detects 1 element spells with modifiers and 2-3 element spells with and without modifiers<commit_after>'use strict';

/**
Magicka Wizard Wars spell parser function.
Recieves a string.
Outputs a Array of spellMatch objects.
spellMatch = {
	start, // position in the original string where spell begins
	end,   // position in the original string where spell ends
	spell, // string containing the spell (modifiers included)
}
**/

function spellParser(str) {
	var filter = ['FAQ'];
	var result = [];
	var re = /((!|c)?([QWERASDFX]{2,3}|[QWERASDFX]\[[QWERASDFX][QWERASDFX]\]|\[[QWERASDFX][QWERASDFX]\][QWERASDFX]|\[[QWERASDFX]{2,3}\])|(!|c)([QWERASDFX]))(:[0-9]{1,3})?/g;
	var match = re.exec(str);
	while (match != null) {
		var s = {
			start : match.index,
			end   : re.lastIndex,
			spell : str.substring(match.index, re.lastIndex)
		};
		if (filter.indexOf(s.spell) < 0 &&
			(s.start == 0 || str[s.start-1].match(/[\W\s]/) != null) &&
			(s.end == str.length || str[s.end].match(/[\W\s]/) != null)
			)
			result.push(s);
		else
			console.log(str.substring(s.start-1, s.end +1));
		match = re.exec(str);
	}
	return result;
}
<|endoftext|>


<commit_before>//
// nntpchan.js -- frontend ui niceness
//

// insert a backlink for a post given its short hash
function nntpchan_backlink(shorthash)
{
  var elem = document.getElementById("postform_message");
  if ( elem )
  {
    elem.value += ">>" + shorthash.substr(0,8) + "\n";
  }
}
<commit_msg>fuggg<commit_after>//
// nntpchan.js -- frontend ui niceness
//

// insert a backlink for a post given its short hash
function nntpchan_backlink(shorthash)
{
  var elem = document.getElementById("postform_message");
  if ( elem )
  {
    elem.value += ">>" + shorthash.substr(2,10) + "\n";
  }
}
<|endoftext|>


<commit_before>
var _onreadyfuncs = [];

var onready = function(f) {
  _onreadyfuncs.push(function() {f();});
};

var ready = function() {
  for(var idx = 0; idx < _onreadyfuncs.length; idx++) _onreadyfuncs[idx]();
};

var quickreply = function(shorthash, longhash, url) {
  if (!window.location.pathname.startsWith("/t/"))
  {
    window.location.href = url;
    return;
  }
  var elem = document.getElementById("comment");
  if(!elem) return;
  elem.value += ">>" + shorthash + "\n";
};

var get_storage = function() {
  var st = null;
  if (window.localStorage) {
    st = window.localStorage;
  } else if (localStorage) {
    st = localStorage;
  }
  return st;
};

var setSrcQuery = function(e, q) {
	var src  = e.src;
	var p = src.indexOf('?');
	if (p >= 0) {
		src = src.substr(0, p);
	}
	e.src = src + "?" + q
};

var reloadImg = function(el) {
	setSrcQuery(el, "reload=" + (new Date()).getTime());
	return false;
};

var reloadThreadJSON = function(ourPost) {
  var url = window.location.pathname + "/json";
  var ajax = new XMLHttpRequest();
  ajax.onreadystatechange = function() {
    if(ajax.readyState == 4) {
      if(ajax.status == 404) {
        console.log("thread gone");
      } else if (ajax.status == 200) {
        var rootelem = document.getElementById("thread_"+window.location.pathname.split("/")[2]);
        var posts = JSON.parse(ajax.responseText);
        for(var idx = 0; idx < posts.length; idx ++ )
        {
          var id = posts[idx].HashLong;
          var e = document.getElementById(id);
          if(!e) {
            e = document.createElement("div");
            e.innerHTML = posts[idx].PostMarkup;
            rootelem.appendChild(e);
            if(ourPost && posts[idx].Message_id == ourPost) {
              // focus on our post
              window.location.hash = id;
            }
          }
        }
      }
    }
  };
  ajax.open("GET", url);
  ajax.send();
}

// form resubmit
onready(function() {
  var submitPost = function(form, elem, cb) {
    var ajax = new XMLHttpRequest();
    ajax.onreadystatechange = function() {
      if (ajax.readyState == 4) {
        var err = "unknown error";
        var j = null;
        try {
          j = JSON.parse(ajax.responseText);
          err = j.error || err;
        } catch (ex) {
          err = "error parsing reply: "+ ex;
        }
        if(ajax.status == 201) {
          // success
          form.reset();
          cb(null, j);
        } else if (ajax.status == 200) {
          cb(err, j);
        } else {
          cb("http "+ajax.status, j);
        }
      } else {
        elem.value += ".";
      }
    };
    var data = new FormData();
    data.append("message", document.getElementById("comment").value);
    var inputs = form.getElementsByTagName("input");
    for(var idx = 0; idx < inputs.length; idx++)
    {
      var input = inputs[idx];
      console.log(input);
      if(input.files)
      {
        for (var i =0 ; i < input.files.length; i++)
        {
          var file = input.files[i];
          data.append(input.name, file, file.name);
        }
      }
      else if(input.name)
        data.append(input.name, input.value);
    }
    console.log("posting...");
    ajax.open("POST", form.action+"/json");
    ajax.send(data);
  };
  var elems = document.getElementsByClassName("postbutton");
  if(elems && elems.length > 0 && elems[0]) {
    var e = elems[0];
    var parent = e.parentElement;
    var origText = e.value;
    e.remove();
    e = document.createElement("input");
    e.type = "button";
    parent.appendChild(e);
    e.value = origText;
    e.onclick = function(ev) {
      console.log("clicked post");
      e.disabled = true;
      e.value = "posting ";
      submitPost(document.forms[0], e, function(err, j) {
        if(err) {
          var captcha = document.getElementById("captcha_solution");
          if(captcha) {
            captcha.value = "";
          }
        }
        var msg = err || "posted";
        console.log(msg, j.url);
        e.value = msg;
        if(window.location.pathname === j.url) {
          reloadThreadJSON(j.message_id);
        } else if (j && j.url) {
          // do redirect
          window.location.pathname = j.url;
          return;
        }
        var img = document.getElementById("captcha_img");
        if (img) {
          reloadImg(img);
        }
        setTimeout(function() {
          e.disabled = false;
          e.value = origText;
        }, 1000);

      });
    }
  }

});

// captcha reload
onready(function(){

  var e = document.getElementById("captcha_img");
  if (e) {
    e.onclick = function() {
		  reloadImg(e);
	  };
  }
});

// rewrite all images to add inline expand
onready(function() {

  // is the filename matching an image?
  var filenameIsImage = function(fname) {
    return /\.(gif|jpeg|jpg|png|webp)/.test(fname.toLowerCase());
  };

  // setup image inlining for 1 element
  var setupInlineImage = function(thumb, url) {
    if(thumb.inlineIsSetUp) return;
    thumb.inlineIsSetUp = true;
    var img = thumb.querySelector("img.image");
    var expanded = false;
    var oldurl = img.src;
    thumb.onclick = function() {
      if (expanded) {
        img.setAttribute("class", "image");
        img.src = oldurl;
        expanded = false;
      } else {
        img.setAttribute("class", "expanded-thumbnail");
        img.src = url;
        expanded = true;
      }
      return false;
    };
  };

  // set up image inlining for all applicable children in an element
  var setupInlineImageIn = function(element) {
    var thumbs = element.querySelectorAll("a.image_link");
    for ( var i = 0 ; i < thumbs.length ; i++ ) {
      var url = thumbs[i].href;
      if (filenameIsImage(url)) {
        // match
        setupInlineImage(thumbs[i], url);
      }
    }
  };
  // Setup Javascript events for document
  setupInlineImageIn(document);

  // Setup Javascript events via updater
  if (window.MutationObserver) {
    var observer = new MutationObserver(function(mutations) {
      for (var i = 0; i < mutations.length; i++) {
        var additions = mutations[i].addedNodes;
        if (additions == null) continue;
        for (var j = 0; j < additions.length; j++) {
          var node = additions[j];
          if (node.nodeType == 1) {
            setupInlineImageIn(node);
          }
        }
      }
    });
    observer.observe(document.body, {childList: true, subtree: true});
  }
});

// set up post hider
onready(function() {

  var get_hidden_posts = function() {
    var st = get_storage();
    var prefix = "nntpchan_hide_post_";
    return  {
      all : function() {
        var msgids = [];
        for ( var k in st) {
          if (k.indexOf(prefix) == 0) {
            var m = k.substring(prefix.length);
            msgids.push(m);
          }
        }
        return msgids;
      },

      add : function (msg) {
        st[prefix+msg] = "post";
      },

      del : function (msg) {
        st.removeItem(prefix+msg);
      }
    };
  };

  // is a post elem an OP?
  var postIsOP = function(elem) {
    var ds = elem.dataset;
    return ds && ds.rootmsgid == ds.msgid ;
  };

  var hide_elem = function(elem, fade) {
    if (elem.style) {
      elem.style.display = "none";
    } else {
      elem.style = {display: "none" };
    }
    elem.dataset.userhide = "yes";
  };

  var unhide_elem = function(elem) {
    elem.style = "";
    elem.dataset.userhide = "no";
  };

  // return true if element is hidden
  var elemIsHidden = function(elem) {
    return elem.dataset && elem.dataset.userhide == "yes";
  };

  // hide a post
  var hidepost = function(elem, nofade) {
    console.log("hidepost("+elem.dataset.msgid+")");
    var posts = get_hidden_posts();
    if (posts) {
      // add to persitant hide
      posts.add(elem.dataset.msgidhash);
    }
    if(postIsOP(elem)) {
      // hide thread it's an OP
      var thread = document.getElementById("thread_"+elem.dataset.rootmsgidhash);
      if (thread) {
        var e = thread.getElementsByClassName("post");
        for ( var idx = 0; idx < e.length ; idx ++ ) {
          if (e[idx].dataset.msgid == elem.dataset.msgid) continue; // don't apply
          hidepost(e[idx]);
        }
      }
    }
    // hide attachments and post body
    var es = elem.getElementsByClassName("image");
    for (var idx = 0; idx < es.length ; idx ++ ) {
      hide_elem(es[idx]);
    }
    es = elem.getElementsByClassName("message_span");
    for (var idx = 0; idx < es.length ; idx ++ ) {
      hide_elem(es[idx]);
    }
    es = elem.getElementsByClassName("topicline");
    for (var idx = 0; idx < es.length ; idx ++ ) {
      hide_elem(es[idx]);
    }
    elem.dataset.userhide = "yes";
    elem.setHideLabel("[show]");
  };

  // unhide a post
  var unhidepost = function(elem) {
    console.log("unhidepost("+elem.dataset.msgid+")");
    var posts = get_hidden_posts();
    if (posts) {
      // remove from persiting hide
      posts.del(elem.dataset.msgidhash);
    }
    if(postIsOP(elem)) {
      var thread = document.getElementById("thread_"+elem.dataset.rootmsgidhash);
      if(thread) {
        var e = thread.getElementsByClassName("post");
        for ( var idx = 0; idx < e.length ; idx ++ ) {
          if(e[idx].dataset.msgid == elem.dataset.msgid) continue;
          unhidepost(e[idx]);
        }
      }
    }
    // unhide attachments and post body
    var es = elem.getElementsByClassName("image");
    for (var idx = 0; idx < es.length ; idx ++ ) {
      unhide_elem(es[idx]);
    }
    es = elem.getElementsByClassName("message_span");
    for (var idx = 0; idx < es.length ; idx ++ ) {
      unhide_elem(es[idx]);
    }
    es = elem.getElementsByClassName("topicline");
    for (var idx = 0; idx < es.length ; idx ++ ) {
      unhide_elem(es[idx]);
    }
    elem.dataset.userhide = "no";
    elem.setHideLabel("[hide]");
  };

  // hide a post given a callback that checks each post
  var hideposts = function(check_func) {
    var es = document.getElementsByClassName("post");
    for ( var idx = 0; idx < es.length ; idx ++ ) {
      var elem = es[idx];
      if(check_func && elem && check_func(elem)) {
        hidepost(elem);
      }
    }
  };

  // unhide all posts given callback
  // if callback is null unhide all
  var unhideall = function(check_func) {
    var es = document.getElementsByClassName("post");
    for (var idx=0 ; idx < es.length; idx ++ ) {
      var elem = es[idx];
      if(!check_func) { unhide(elem); }
      else if(check_func(elem)) { unhide(elem); }
    }
  };

  // inject posthide into page
  var inject = function (elem) {
    var hider = document.createElement("a");
    hider.setAttribute("class", "hider");
    elem.setHideLabel = function (txt) {
      var e_hider = hider;
      e_hider.innerHTML = txt;
    };
    elem.hidepost = function() {
      var e_self = elem;
      var e_hider = hider;
      hidepost(e_self);
    };
    elem.unhidepost = function() {
      var e_self = elem;
      var e_hider = hider;
      unhidepost(e_self);
    };
    elem.isHiding = function() {
      var e_self = elem;
      return elemIsHidden(e_self);
    };
    hider.appendChild(document.createTextNode("[hide]"));
    hider.onclick = function() {
      var e_self = elem;
      if(e_self.isHiding()) {
        e_self.unhidepost();
      } else {
        e_self.hidepost();
      }
    };
    elem.appendChild(hider);
  };

  var posts = document.getElementsByClassName("post");
  for (var idx = 0 ; idx < posts.length; idx++ ) {
    inject(posts[idx]);
  }
  // apply persiting hidden posts
  posts = get_hidden_posts();
  if(posts) {
    var all = posts.all();
    for ( var idx = 0 ; idx < all.length; idx ++ ) {
      var id = all[idx];
      var elem = document.getElementById(id);
      if(elem)
        hidepost(elem, true);
    }
  }
});
<commit_msg>Revert "fix"<commit_after>
var _onreadyfuncs = [];

var onready = function(f) {
  _onreadyfuncs.push(function() {f();});
};

var ready = function() {
  for(var idx = 0; idx < _onreadyfuncs.length; idx++) _onreadyfuncs[idx]();
};

var quickreply = function(shorthash, longhash, url) {
  if (!window.location.pathname.startsWith("/t/"))
  {
    window.location.href = url;
    return;
  }
  var elem = document.getElementById("comment");
  if(!elem) return;
  elem.value += ">>" + shorthash + "\n";
};

var get_storage = function() {
  var st = null;
  if (window.localStorage) {
    st = window.localStorage;
  } else if (localStorage) {
    st = localStorage;
  }
  return st;
};

var setSrcQuery = function(e, q) {
	var src  = e.src;
	var p = src.indexOf('?');
	if (p >= 0) {
		src = src.substr(0, p);
	}
	e.src = src + "?" + q
};

var reloadImg = function(el) {
	setSrcQuery(el, "reload=" + (new Date()).getTime());
	return false;
};

var reloadThreadJSON = function(ourPost) {
  var url = window.location.pathname + "/json";
  var ajax = new XMLHttpRequest();
  ajax.onreadystatechange = function() {
    if(ajax.readyState == 4) {
      if(ajax.status == 404) {
        console.log("thread gone");
      } else if (ajax.status == 200) {
        var rootelem = document.getElementById("thread_"+window.location.pathname.split("/")[2]);
        var posts = JSON.parse(ajax.responseText);
        for(var idx = 0; idx < posts.length; idx ++ )
        {
          var id = posts[idx].HashLong;
          var e = document.getElementById(id);
          if(!e) {
            e = document.createElement("div");
            e.innerHTML = posts[idx].PostMarkup;
            rootelem.appendChild(e.childNodes[0]);
            e.remove();
            if(ourPost && posts[idx].Message_id == ourPost) {
              // focus on our post
              window.location.hash = id;
            }
          }
        }
      }
    }
  };
  ajax.open("GET", url);
  ajax.send();
}

// form resubmit
onready(function() {
  var submitPost = function(form, elem, cb) {
    var ajax = new XMLHttpRequest();
    ajax.onreadystatechange = function() {
      if (ajax.readyState == 4) {
        var err = "unknown error";
        var j = null;
        try {
          j = JSON.parse(ajax.responseText);
          err = j.error || err;
        } catch (ex) {
          err = "error parsing reply: "+ ex;
        }
        if(ajax.status == 201) {
          // success
          form.reset();
          cb(null, j);
        } else if (ajax.status == 200) {
          cb(err, j);
        } else {
          cb("http "+ajax.status, j);
        }
      } else {
        elem.value += ".";
      }
    };
    var data = new FormData();
    data.append("message", document.getElementById("comment").value);
    var inputs = form.getElementsByTagName("input");
    for(var idx = 0; idx < inputs.length; idx++)
    {
      var input = inputs[idx];
      console.log(input);
      if(input.files)
      {
        for (var i =0 ; i < input.files.length; i++)
        {
          var file = input.files[i];
          data.append(input.name, file, file.name);
        }
      }
      else if(input.name)
        data.append(input.name, input.value);
    }
    console.log("posting...");
    ajax.open("POST", form.action+"/json");
    ajax.send(data);
  };
  var elems = document.getElementsByClassName("postbutton");
  if(elems && elems.length > 0 && elems[0]) {
    var e = elems[0];
    var parent = e.parentElement;
    var origText = e.value;
    e.remove();
    e = document.createElement("input");
    e.type = "button";
    parent.appendChild(e);
    e.value = origText;
    e.onclick = function(ev) {
      console.log("clicked post");
      e.disabled = true;
      e.value = "posting ";
      submitPost(document.forms[0], e, function(err, j) {
        if(err) {
          var captcha = document.getElementById("captcha_solution");
          if(captcha) {
            captcha.value = "";
          }
        }
        var msg = err || "posted";
        console.log(msg, j.url);
        e.value = msg;
        if(window.location.pathname === j.url) {
          reloadThreadJSON(j.message_id);
        } else if (j && j.url) {
          // do redirect
          window.location.pathname = j.url;
          return;
        }
        var img = document.getElementById("captcha_img");
        if (img) {
          reloadImg(img);
        }
        setTimeout(function() {
          e.disabled = false;
          e.value = origText;
        }, 1000);

      });
    }
  }

});

// captcha reload
onready(function(){

  var e = document.getElementById("captcha_img");
  if (e) {
    e.onclick = function() {
		  reloadImg(e);
	  };
  }
});

// rewrite all images to add inline expand
onready(function() {

  // is the filename matching an image?
  var filenameIsImage = function(fname) {
    return /\.(gif|jpeg|jpg|png|webp)/.test(fname.toLowerCase());
  };

  // setup image inlining for 1 element
  var setupInlineImage = function(thumb, url) {
    if(thumb.inlineIsSetUp) return;
    thumb.inlineIsSetUp = true;
    var img = thumb.querySelector("img.image");
    var expanded = false;
    var oldurl = img.src;
    thumb.onclick = function() {
      if (expanded) {
        img.setAttribute("class", "image");
        img.src = oldurl;
        expanded = false;
      } else {
        img.setAttribute("class", "expanded-thumbnail");
        img.src = url;
        expanded = true;
      }
      return false;
    };
  };

  // set up image inlining for all applicable children in an element
  var setupInlineImageIn = function(element) {
    var thumbs = element.querySelectorAll("a.image_link");
    for ( var i = 0 ; i < thumbs.length ; i++ ) {
      var url = thumbs[i].href;
      if (filenameIsImage(url)) {
        // match
        setupInlineImage(thumbs[i], url);
      }
    }
  };
  // Setup Javascript events for document
  setupInlineImageIn(document);

  // Setup Javascript events via updater
  if (window.MutationObserver) {
    var observer = new MutationObserver(function(mutations) {
      for (var i = 0; i < mutations.length; i++) {
        var additions = mutations[i].addedNodes;
        if (additions == null) continue;
        for (var j = 0; j < additions.length; j++) {
          var node = additions[j];
          if (node.nodeType == 1) {
            setupInlineImageIn(node);
          }
        }
      }
    });
    observer.observe(document.body, {childList: true, subtree: true});
  }
});

// set up post hider
onready(function() {

  var get_hidden_posts = function() {
    var st = get_storage();
    var prefix = "nntpchan_hide_post_";
    return  {
      all : function() {
        var msgids = [];
        for ( var k in st) {
          if (k.indexOf(prefix) == 0) {
            var m = k.substring(prefix.length);
            msgids.push(m);
          }
        }
        return msgids;
      },

      add : function (msg) {
        st[prefix+msg] = "post";
      },

      del : function (msg) {
        st.removeItem(prefix+msg);
      }
    };
  };

  // is a post elem an OP?
  var postIsOP = function(elem) {
    var ds = elem.dataset;
    return ds && ds.rootmsgid == ds.msgid ;
  };

  var hide_elem = function(elem, fade) {
    if (elem.style) {
      elem.style.display = "none";
    } else {
      elem.style = {display: "none" };
    }
    elem.dataset.userhide = "yes";
  };

  var unhide_elem = function(elem) {
    elem.style = "";
    elem.dataset.userhide = "no";
  };

  // return true if element is hidden
  var elemIsHidden = function(elem) {
    return elem.dataset && elem.dataset.userhide == "yes";
  };

  // hide a post
  var hidepost = function(elem, nofade) {
    console.log("hidepost("+elem.dataset.msgid+")");
    var posts = get_hidden_posts();
    if (posts) {
      // add to persitant hide
      posts.add(elem.dataset.msgidhash);
    }
    if(postIsOP(elem)) {
      // hide thread it's an OP
      var thread = document.getElementById("thread_"+elem.dataset.rootmsgidhash);
      if (thread) {
        var e = thread.getElementsByClassName("post");
        for ( var idx = 0; idx < e.length ; idx ++ ) {
          if (e[idx].dataset.msgid == elem.dataset.msgid) continue; // don't apply
          hidepost(e[idx]);
        }
      }
    }
    // hide attachments and post body
    var es = elem.getElementsByClassName("image");
    for (var idx = 0; idx < es.length ; idx ++ ) {
      hide_elem(es[idx]);
    }
    es = elem.getElementsByClassName("message_span");
    for (var idx = 0; idx < es.length ; idx ++ ) {
      hide_elem(es[idx]);
    }
    es = elem.getElementsByClassName("topicline");
    for (var idx = 0; idx < es.length ; idx ++ ) {
      hide_elem(es[idx]);
    }
    elem.dataset.userhide = "yes";
    elem.setHideLabel("[show]");
  };

  // unhide a post
  var unhidepost = function(elem) {
    console.log("unhidepost("+elem.dataset.msgid+")");
    var posts = get_hidden_posts();
    if (posts) {
      // remove from persiting hide
      posts.del(elem.dataset.msgidhash);
    }
    if(postIsOP(elem)) {
      var thread = document.getElementById("thread_"+elem.dataset.rootmsgidhash);
      if(thread) {
        var e = thread.getElementsByClassName("post");
        for ( var idx = 0; idx < e.length ; idx ++ ) {
          if(e[idx].dataset.msgid == elem.dataset.msgid) continue;
          unhidepost(e[idx]);
        }
      }
    }
    // unhide attachments and post body
    var es = elem.getElementsByClassName("image");
    for (var idx = 0; idx < es.length ; idx ++ ) {
      unhide_elem(es[idx]);
    }
    es = elem.getElementsByClassName("message_span");
    for (var idx = 0; idx < es.length ; idx ++ ) {
      unhide_elem(es[idx]);
    }
    es = elem.getElementsByClassName("topicline");
    for (var idx = 0; idx < es.length ; idx ++ ) {
      unhide_elem(es[idx]);
    }
    elem.dataset.userhide = "no";
    elem.setHideLabel("[hide]");
  };

  // hide a post given a callback that checks each post
  var hideposts = function(check_func) {
    var es = document.getElementsByClassName("post");
    for ( var idx = 0; idx < es.length ; idx ++ ) {
      var elem = es[idx];
      if(check_func && elem && check_func(elem)) {
        hidepost(elem);
      }
    }
  };

  // unhide all posts given callback
  // if callback is null unhide all
  var unhideall = function(check_func) {
    var es = document.getElementsByClassName("post");
    for (var idx=0 ; idx < es.length; idx ++ ) {
      var elem = es[idx];
      if(!check_func) { unhide(elem); }
      else if(check_func(elem)) { unhide(elem); }
    }
  };

  // inject posthide into page
  var inject = function (elem) {
    var hider = document.createElement("a");
    hider.setAttribute("class", "hider");
    elem.setHideLabel = function (txt) {
      var e_hider = hider;
      e_hider.innerHTML = txt;
    };
    elem.hidepost = function() {
      var e_self = elem;
      var e_hider = hider;
      hidepost(e_self);
    };
    elem.unhidepost = function() {
      var e_self = elem;
      var e_hider = hider;
      unhidepost(e_self);
    };
    elem.isHiding = function() {
      var e_self = elem;
      return elemIsHidden(e_self);
    };
    hider.appendChild(document.createTextNode("[hide]"));
    hider.onclick = function() {
      var e_self = elem;
      if(e_self.isHiding()) {
        e_self.unhidepost();
      } else {
        e_self.hidepost();
      }
    };
    elem.appendChild(hider);
  };

  var posts = document.getElementsByClassName("post");
  for (var idx = 0 ; idx < posts.length; idx++ ) {
    inject(posts[idx]);
  }
  // apply persiting hidden posts
  posts = get_hidden_posts();
  if(posts) {
    var all = posts.all();
    for ( var idx = 0 ; idx < all.length; idx ++ ) {
      var id = all[idx];
      var elem = document.getElementById(id);
      if(elem)
        hidepost(elem, true);
    }
  }
});
<|endoftext|>


<commit_before>var tdl = require('./lib/api');
var twp = require('./lib/twp');

var api = tdl.fromFile('./misc/echo.tdl');

var client = new twp.Client(api.protocols.byName['Echo']);

client.connect(80, 'www.dcl.hpi.uni-potsdam.de');

client.on('connect', function() {
    client.send('Request', {
        text: 'foo'
    });

    client.on('message', function(name, content) {
        console.warn(name, content);
        client.close();
    });
});
<commit_msg>allow supplying an argument to echo_client.js<commit_after>var tdl = require('./lib/api');
var twp = require('./lib/twp');

var api = tdl.fromFile('./misc/echo.tdl');

if (process.argv.length !== 3) {
    console.warn('Usage: ' + process.env._ + ' "string"');
    process.exit(1);
}

var client = new twp.Client(api.protocols.byName['Echo']);

client.connect(80, 'www.dcl.hpi.uni-potsdam.de');

client.on('connect', function() {
    var string = process.argv[2];
    console.warn('Measuring "' + string + '"');

    client.send('Request', {
        text: string
    });

    client.on('message', function(name, content) {
        console.warn(name, content);
        client.close();
    });
});
<|endoftext|>


<commit_before>/*exported Hungarian*/
var Hungarian = (function() {
  'use strict';

  var Type = {
    NONE:  0,
    STAR:  1,
    PRIME: 2
  };

  /**
   * Array minima mutation functions.
   */
  function subtractRowMinima( row ) {
    var min = Math.min.apply( Math, row );

    for ( var i = 0, il = row.length; i < il; i++ ) {
      row[i] -= min;
    }

    return row;
  }

  function subtractRowsMinima( array ) {
    var i, il;
    for ( i = 0, il = array.length; i < il; i++ ) {
      subtractRowMinima( array[i] );
    }
  }

  /**
   * Takes a two-dimensional n by m matrix.
   */
  function subtractColMinima( array, colIndex ) {
    var min = Number.POSITIVE_INFINITY;
    var value;
    var i, il;
    // Create col array and find min.
    for ( i = 0, il = array.length; i < il; i++ ) {
      value = array[i][ colIndex ];
      if ( value < min ) {
        min = value;
      }
    }

    for ( i = 0, il = array.length; i < il; i++ ) {
      array[i][ colIndex ] -= min;
    }

    return array;
  }

  function subtractColsMinima( array ) {
    var i, il;
    for ( i = 0, il = array[0].length; i < il; i++ ) {
      subtractColMinima( array, i );
    }
  }

  function calculate( costMatrix ) {
    var coveredRows = [],
        coveredCols = [];

    var marked = [];

    function init() {
      var i, il;
      for ( i = 0, il = costMatrix[0].length; i < il; i++ ) {
        marked.push( [] );
      }

      step1();
    }

    init();

    function step1() {
      subtractRowsMinima( costMatrix );
      step2();
    }

    function step2() {
      var i, il;
      var j, jl;
      var row;
      for ( i = 0, il = costMatrix.length; i < il; i++ ) {
        row = costMatrix[i];
        for ( j = 0, jl = row.length; j < jl; j++ ) {
          // Mark uncovered zeros.
          if ( !costMatrix && !coveredRows[i] && !coveredCols[j] ) {
            marked[i][j] = true;
            coveredRows[i] = true;
            coveredCols[j] = true;
          }
        }
      }

      // Empty covers.
      coveredRows = [];
      coveredCols = [];
    }

    function step3() {
      var i, il;
      var j, jl;
      // Cover each column containing a starred zero.
      for ( i = 0, il = costMatrix.length; i < il; i++ ) {
        for ( j = 0, jl = costMatrix[i].length; j < jl; j++ ) {
          if ( marked[i][j] === Type.STAR ) {
            coveredCols[j] = true;
          }
        }
      }

      // Count covered columns.
      var count = 0;
      for ( i = 0, il = coveredCols.length; i < il; i++ ) {
        if ( coveredCols[i] ) {
          count++;
        }
      }

      if ( count >= costMatrix[0].length ) {
        // Finished.
        return;
      } else {
        step4();
      }
    }

    // Step 4 helper functions.
    function findUncoveredZero( costMatrix, coveredRows, coveredCols ) {
      var row = -1,
          col = -1;

      var i, il;
      var j, jl;
      for ( i = 0, il = costMatrix.length; i < il; i++ ) {
        for ( j = 0, jl = costMatrix[i].length; j < jl; j++ ) {
          if ( !costMatrix[i][j] && !coveredRows[i] && !coveredCols[j] ) {
            // TODO: Out variable these.
            row = i;
            col = j;
            break;
          }
        }
      }

      return {
        row: row,
        col: col
      };
    }

    function isRowStarred( row ) {
      for ( var i = 0, il = row.length; i < il; i++ ) {
        if ( row[i] === Type.STAR ) {
          return true;
        }
      }

      return false;
    }

    function indexOfStar( row ) {
      for ( var i = 0, il = row.length; i < il; i++ ) {
        if ( row[i] === Type.STAR ) {
          return i;
        }
      }

      return -1;
    }

    function step4() {
      var index;
      var starIndex;
      while ( true ) {
        index = findUncoveredZero( costMatrix, coveredRows, coveredCols );
        if ( index.row === -1 ) {
          return step6();
        } else {
          marked[ index.row ][ index.col ] = 2;

          starIndex = indexOfStar( marked, index.row );
          if ( starIndex !== -1 ) {
            coveredRows[ index.row ] = true;
            coveredCols[ index.col ] = false;
          } else {
            return step5( index.row, index.col );
          }
        }
      }
    }

    function step5( row, col ) {
      function indexOfStarCol( costMatrix, col ) {
        for ( var i = 0, il = costMatrix.length; i < il; i++ ) {
          if ( costMatrix[i][ col ] === Type.STAR ) {
            return i;
          }
        }

        return -1;
      }

      function indexOfPrimeRow( row ) {
        for ( var i = 0, il = costMatrix.length; i < il; i++ ) {
          if ( row[i] === Type.PRIME ) {
            return i;
          }
        }

        return -1;
      }

      function augmentPath( marked, path, lastIndex ) {
        var row, col;
        for ( var i = 0; i < lastIndex; i++ ) {
          row = path[i][0];
          col = path[i][1];
          if ( marked[ row ][ col ] === 1 ) {
            marked[ row ][ col ] = 0;
          } else {
            marked[ row ][ col ] = 1;
          }
        }
      }

      function clearCovers() {
        coveredRows = [];
        coveredCols = [];
      }

      function removePrimes( marked ) {
        var i, j;
        for ( i = 0; i < marked.length; i++ ) {
          for ( j = 0; j < marked[i].length; j++ ) {
            if ( marked[i][j] === Type.PRIME ) {
              marked[i][j] = 0;
            }
          }
        }
      }

      var pathIndex = 0;
      var path = [
        [ row, col ]
      ];
      var index;
      while ( true ) {
        index = indexOfStarCol( path[ pathIndex ][1] );
        if ( index > -1 ) {
          pathIndex++;
          path[ pathIndex ] = [
            index,
            path[ pathIndex - 1 ][1]
          ];

          index = indexOfPrimeRow( path[ pathIndex ][0] );
          pathIndex++;
          path[ pathIndex ] = [
            path[ pathIndex - 1 ][0],
            index
          ];
        } else {
          break;
        }
      }

      augmentPath( marked, path, pathIndex );
      clearCovers();
      removePrimes( marked );
      step3();
    }

    function uncoveredMinima( costMatrix, coveredRows, coveredCols ) {
      var min = Number.POSITIVE_INFINITY;

      var value;
      var i, il;
      var j, jl;
      for ( i = 0, i = costMatrix.length; i < il; i++ ) {
        for ( j = 0, j = costMatrix[i].length; j < jl; j++ ) {
          value = costMatrix[i][j];
          if ( value < min && !coveredRows[i] && !coveredCols[j] ) {
            min = value;
          }
        }
      }

      return value;
    }

    function step6() {
      var min = uncoveredMinima( costMatrix, coveredRows, coveredCols );
      var i, il;
      var j, jl;
      for ( i = 0, il = costMatrix.length; i < il; i++ ) {
        for ( j = 0, jl = costMatrix[i].length; j < jl; j++ ) {
          // Add min to every element of each covered row.
          if ( coveredRows[i] ) {
            costMatrix[i][j] += min;
          }

          // Subtract min from every element of each uncoverd column.
          if ( !coveredCols[j] ) {
            costMatrix[i][j] -= min;
          }
        }
      }

      step4();
    }

    return;
  }

  return {
    calculate: calculate
  };

}) ();
<commit_msg>registration[points]: Add logMatrix debug utility function.<commit_after>/*exported Hungarian*/
var Hungarian = (function() {
  'use strict';

  var Type = {
    NONE:  0,
    STAR:  1,
    PRIME: 2
  };

  /**
   * Array minima mutation functions.
   */
  function subtractRowMinima( row ) {
    var min = Math.min.apply( Math, row );

    for ( var i = 0, il = row.length; i < il; i++ ) {
      row[i] -= min;
    }

    return row;
  }

  function subtractRowsMinima( array ) {
    var i, il;
    for ( i = 0, il = array.length; i < il; i++ ) {
      subtractRowMinima( array[i] );
    }
  }

  /**
   * Takes a two-dimensional n by m matrix.
   */
  function subtractColMinima( array, colIndex ) {
    var min = Number.POSITIVE_INFINITY;
    var value;
    var i, il;
    // Create col array and find min.
    for ( i = 0, il = array.length; i < il; i++ ) {
      value = array[i][ colIndex ];
      if ( value < min ) {
        min = value;
      }
    }

    for ( i = 0, il = array.length; i < il; i++ ) {
      array[i][ colIndex ] -= min;
    }

    return array;
  }

  function subtractColsMinima( array ) {
    var i, il;
    for ( i = 0, il = array[0].length; i < il; i++ ) {
      subtractColMinima( array, i );
    }
  }

  function logMatrix( matrix, precision ) {
    var string = '';

    // Get number of integer digits.
    var maxDigits = 0;
    var digits;
    var i, il;
    var j, jl;
    for ( i = 0, il = matrix.length; i < il; i++ ) {
      for ( j = 0, jl = matrix[i].length; j < jl; j++ ) {
        digits = Math.floor( matrix[i][j] ).toString().length;
        if ( digits > maxDigits ) {
          maxDigits = digits;
        }
      }
    }

    /**
     * Pads an number with leading spaces.
     *
     * For example: pad( 3.24, 3 ) => '  3.24'.
     */
    function pad( number, digits ) {
      var count = digits - Math.floor( number ).toString().length;
      var padding = '';

      while ( count > 0 ) {
        padding += ' ';
        count--;
      }

      return padding + number;
    }

    // Construct string representation of matrix.
    for ( i = 0, il = matrix.length; i < il; i++ ) {
      for ( j = 0, jl = matrix[i].length; j < jl; j++ ) {
        string += pad( matrix[i][j].toFixed( precision ), maxDigits );

        // Append a comma if not at end.
        if ( j < jl - 1) {
          string += ', ';
        }
      }

      string += '\n';
    }

    return string;
  }

  function calculate( costMatrix ) {
    var coveredRows = [],
        coveredCols = [];

    var marked = [];

    function init() {
      for ( var i = 0, il = costMatrix[0].length; i < il; i++ ) {
        marked.push( [] );
      }

      step1();
    }

    init();

    function step1() {
      subtractRowsMinima( costMatrix );
      step2();
    }

    function step2() {
      var i, il;
      var j, jl;
      var row;
      for ( i = 0, il = costMatrix.length; i < il; i++ ) {
        row = costMatrix[i];
        for ( j = 0, jl = row.length; j < jl; j++ ) {
          // Mark uncovered zeros.
          if ( !costMatrix && !coveredRows[i] && !coveredCols[j] ) {
            marked[i][j] = true;
            coveredRows[i] = true;
            coveredCols[j] = true;
          }
        }
      }

      // Empty covers.
      coveredRows = [];
      coveredCols = [];
    }

    function step3() {
      var i, il;
      var j, jl;
      // Cover each column containing a starred zero.
      for ( i = 0, il = costMatrix.length; i < il; i++ ) {
        for ( j = 0, jl = costMatrix[i].length; j < jl; j++ ) {
          if ( marked[i][j] === Type.STAR ) {
            coveredCols[j] = true;
          }
        }
      }

      // Count covered columns.
      var count = 0;
      for ( i = 0, il = coveredCols.length; i < il; i++ ) {
        if ( coveredCols[i] ) {
          count++;
        }
      }

      if ( count >= costMatrix[0].length ) {
        // Finished.
        return;
      } else {
        step4();
      }
    }

    // Step 4 helper functions.
    function findUncoveredZero( costMatrix, coveredRows, coveredCols ) {
      var row = -1,
          col = -1;

      var i, il;
      var j, jl;
      for ( i = 0, il = costMatrix.length; i < il; i++ ) {
        for ( j = 0, jl = costMatrix[i].length; j < jl; j++ ) {
          if ( !costMatrix[i][j] && !coveredRows[i] && !coveredCols[j] ) {
            // TODO: Out variable these.
            row = i;
            col = j;
            break;
          }
        }
      }

      return {
        row: row,
        col: col
      };
    }

    function isRowStarred( row ) {
      for ( var i = 0, il = row.length; i < il; i++ ) {
        if ( row[i] === Type.STAR ) {
          return true;
        }
      }

      return false;
    }

    function indexOfStar( row ) {
      for ( var i = 0, il = row.length; i < il; i++ ) {
        if ( row[i] === Type.STAR ) {
          return i;
        }
      }

      return -1;
    }

    function step4() {
      var index;
      var starIndex;
      while ( true ) {
        index = findUncoveredZero( costMatrix, coveredRows, coveredCols );
        if ( index.row === -1 ) {
          return step6();
        } else {
          marked[ index.row ][ index.col ] = 2;

          starIndex = indexOfStar( marked, index.row );
          if ( starIndex !== -1 ) {
            coveredRows[ index.row ] = true;
            coveredCols[ index.col ] = false;
          } else {
            return step5( index.row, index.col );
          }
        }
      }
    }

    function step5( row, col ) {
      function indexOfStarCol( costMatrix, col ) {
        for ( var i = 0, il = costMatrix.length; i < il; i++ ) {
          if ( costMatrix[i][ col ] === Type.STAR ) {
            return i;
          }
        }

        return -1;
      }

      function indexOfPrimeRow( row ) {
        for ( var i = 0, il = costMatrix.length; i < il; i++ ) {
          if ( row[i] === Type.PRIME ) {
            return i;
          }
        }

        return -1;
      }

      function augmentPath( marked, path, lastIndex ) {
        var row, col;
        for ( var i = 0; i < lastIndex; i++ ) {
          row = path[i][0];
          col = path[i][1];
          if ( marked[ row ][ col ] === 1 ) {
            marked[ row ][ col ] = 0;
          } else {
            marked[ row ][ col ] = 1;
          }
        }
      }

      function clearCovers() {
        coveredRows = [];
        coveredCols = [];
      }

      function removePrimes( marked ) {
        var i, j;
        for ( i = 0; i < marked.length; i++ ) {
          for ( j = 0; j < marked[i].length; j++ ) {
            if ( marked[i][j] === Type.PRIME ) {
              marked[i][j] = 0;
            }
          }
        }
      }

      var pathIndex = 0;
      var path = [
        [ row, col ]
      ];
      var index;
      while ( true ) {
        index = indexOfStarCol( path[ pathIndex ][1] );
        if ( index > -1 ) {
          pathIndex++;
          path[ pathIndex ] = [
            index,
            path[ pathIndex - 1 ][1]
          ];

          index = indexOfPrimeRow( path[ pathIndex ][0] );
          pathIndex++;
          path[ pathIndex ] = [
            path[ pathIndex - 1 ][0],
            index
          ];
        } else {
          break;
        }
      }

      augmentPath( marked, path, pathIndex );
      clearCovers();
      removePrimes( marked );
      step3();
    }

    function uncoveredMinima( costMatrix, coveredRows, coveredCols ) {
      var min = Number.POSITIVE_INFINITY;

      var value;
      var i, il;
      var j, jl;
      for ( i = 0, i = costMatrix.length; i < il; i++ ) {
        for ( j = 0, j = costMatrix[i].length; j < jl; j++ ) {
          value = costMatrix[i][j];
          if ( value < min && !coveredRows[i] && !coveredCols[j] ) {
            min = value;
          }
        }
      }

      return value;
    }

    function step6() {
      var min = uncoveredMinima( costMatrix, coveredRows, coveredCols );
      var i, il;
      var j, jl;
      for ( i = 0, il = costMatrix.length; i < il; i++ ) {
        for ( j = 0, jl = costMatrix[i].length; j < jl; j++ ) {
          // Add min to every element of each covered row.
          if ( coveredRows[i] ) {
            costMatrix[i][j] += min;
          }

          // Subtract min from every element of each uncoverd column.
          if ( !coveredCols[j] ) {
            costMatrix[i][j] -= min;
          }
        }
      }

      step4();
    }

    return;
  }

  return {
    calculate: calculate
  };

}) ();
<|endoftext|>


<commit_before>(function() {
    var RARE = 'rgb(196, 159, 39)',
        UNCOMMON = 'rgb(119, 119, 119)',
        COMMON = 'rgb(0, 0, 0)',
        MYTHIC = 'rgb(132, 47, 7)',
        BASIC = 'rgb(4, 26, 72)';

    var cards = $('.cardtable').find('tr.deck_card'),
        proxies = [],
        rarity = {rare: [], uncommon: [], common: [], mythic: [], basic: []};

    for (var i = 0; i < cards.length; i++) {
        var row = $(cards[i]),
            price = $(row.find('.card_price')[0]).text().trim().replace('\u20AC',''),
            num = $(row.find('.card_amount')[0]).text().trim(),
            name = $(row.find('a')[0]).text().trim(),
            each = (price/num).toFixed(2),
            comment =  $(row.find('.hbtronix_icon')[0]).attr('title');
        //replace us price
        $(row.find('.card_price')[1]).text(each + ' \u20AC');
        //log proxies
        if (comment && (comment.length === 1 || comment === 'proxy')) {
            $(row.find('.hbtronix_icon')[0]).prop('src', 'http://i.hbtronix.de/picture_empty.png');
            comment.length === 1 ? proxies.push(comment + ' ' + name) : proxies.push(num + ' ' + name);
        }

        //reorder edition
        var span = $($(row.find('.info_link'))[0]).find('span').remove(),
            leg = $($(row.find('.info_link'))[0]).text().trim().replace('(', '').replace(')', '').trim(),
            cell = $($(row.find('.info_link'))[0]);

        if (span.css('color') === RARE)
            rarity.rare.push(num + ' ' + name);
        if (span.css('color') === UNCOMMON)
            rarity.uncommon.push(num + ' ' + name);
        if (span.css('color') === COMMON)
            rarity.common.push(num + ' ' + name);
        if (span.css('color') === MYTHIC)
            rarity.mythic.push(num + ' ' + name);
        if (span.css('color') === BASIC)
            rarity.basic.push(num + ' ' + name);
        span.text(span.text().trim());
        cell.text(leg + ' (')
            .append(span)
            .append(')');
        //replace link
        var href = $(row.find('.cardlink')).attr('href'),
            card = href.split('=').pop(),
            newl = 'https://www.magickartenmarkt.de/?mainPage=showSearchResult&searchFor=' + card + '&v=card&s=cname&card=' + card;
        $(row.find('.cardlink')).attr('href', newl);
    }
    //remove flag and sum
    $($('.cardtable').find('.card_price.header')[1]).empty();
    $($('.cardtable').find('.deck_footer').find('.card_price')[1]).empty()

    //write proxie block
    if (proxies.length) {
        proxies.sort(function (a, b) {
            return a.substr(2,1).charCodeAt(0) - b.substr(2,1).charCodeAt(0);
        });
        $('.custom').remove();
        var node = $($('div.ui-widget')[1]).clone();
        //set content
        $(node.find('p')[0]).empty()
                            .append(proxies.join('
'));
        //remove title and add bottom margin
        node.attr('title', '')
            .css('margin', '1em .5em');
        //prepend to main container
        $('.inhalt').prepend(node.addClass('custom'));
    }

    //list view sort by name
    $('.decks_list.decks_list_narrow').find('.decks_list_subtitle').remove();
    var lines = $('.decks_list.decks_list_narrow').find('tr').remove();
    lines.sort(function (a, b) {
        var valueA = $(a).find('a').text().trim(),
            valueB = $(b).find('a').text().trim();
        if(valueA < valueB) return -1;
        if(valueA > valueB) return 1;
        return 0;
    });
    $('.decks_list.decks_list_narrow').find('tbody').append(lines);

    //types
    console.log(rarity);

    //bigger card preview
    var id = setInterval(function() {
        $('#kartenOverlay')
            .css('border', '0px')
            .css('width', 'auto');
        $('#kartenOverlayBild')
            .css('height', '400px')
            .css('width', '280px');
        $('#kartenOverlayContent')
            .css('display', 'none');
        if($('#kartenOverlay').length)
            clearInterval(id);
        }, 1000);
})();

<commit_msg>set banner link to own deck list view (if logged in)<commit_after>(function() {
    var RARE = 'rgb(196, 159, 39)',
        UNCOMMON = 'rgb(119, 119, 119)',
        COMMON = 'rgb(0, 0, 0)',
        MYTHIC = 'rgb(132, 47, 7)',
        BASIC = 'rgb(4, 26, 72)';

    var cards = $('.cardtable').find('tr.deck_card'),
        proxies = [],
        rarity = {rare: [], uncommon: [], common: [], mythic: [], basic: []};

    for (var i = 0; i < cards.length; i++) {
        var row = $(cards[i]),
            price = $(row.find('.card_price')[0]).text().trim().replace('\u20AC',''),
            num = $(row.find('.card_amount')[0]).text().trim(),
            name = $(row.find('a')[0]).text().trim(),
            each = (price/num).toFixed(2),
            comment =  $(row.find('.hbtronix_icon')[0]).attr('title');
        //replace us price
        $(row.find('.card_price')[1]).text(each + ' \u20AC');
        //log proxies
        if (comment && (comment.length === 1 || comment === 'proxy')) {
            $(row.find('.hbtronix_icon')[0]).prop('src', 'http://i.hbtronix.de/picture_empty.png');
            comment.length === 1 ? proxies.push(comment + ' ' + name) : proxies.push(num + ' ' + name);
        }

        //reorder edition
        var span = $($(row.find('.info_link'))[0]).find('span').remove(),
            leg = $($(row.find('.info_link'))[0]).text().trim().replace('(', '').replace(')', '').trim(),
            cell = $($(row.find('.info_link'))[0]);

        if (span.css('color') === RARE)
            rarity.rare.push(num + ' ' + name);
        if (span.css('color') === UNCOMMON)
            rarity.uncommon.push(num + ' ' + name);
        if (span.css('color') === COMMON)
            rarity.common.push(num + ' ' + name);
        if (span.css('color') === MYTHIC)
            rarity.mythic.push(num + ' ' + name);
        if (span.css('color') === BASIC)
            rarity.basic.push(num + ' ' + name);
        span.text(span.text().trim());
        cell.text(leg + ' (')
            .append(span)
            .append(')');
        //replace link
        var href = $(row.find('.cardlink')).attr('href'),
            card = href.split('=').pop(),
            newl = 'https://www.magickartenmarkt.de/?mainPage=showSearchResult&searchFor=' + card + '&v=card&s=cname&card=' + card;
        $(row.find('.cardlink')).attr('href', newl);
    }
    //remove flag and sum
    $($('.cardtable').find('.card_price.header')[1]).empty();
    $($('.cardtable').find('.deck_footer').find('.card_price')[1]).empty()

    //write proxie block
    if (proxies.length) {
        proxies.sort(function (a, b) {
            return a.substr(2,1).charCodeAt(0) - b.substr(2,1).charCodeAt(0);
        });
        $('.custom').remove();
        var node = $($('div.ui-widget')[1]).clone();
        //set content
        $(node.find('p')[0]).empty()
                            .append(proxies.join('
'));
        //remove title and add bottom margin
        node.attr('title', '')
            .css('margin', '1em .5em');
        //prepend to main container
        $('.inhalt').prepend(node.addClass('custom'));
    }

    //list view sort by name
    $('.decks_list.decks_list_narrow').find('.decks_list_subtitle').remove();
    var lines = $('.decks_list.decks_list_narrow').find('tr').remove();
    lines.sort(function (a, b) {
        var valueA = $(a).find('a').text().trim(),
            valueB = $(b).find('a').text().trim();
        if(valueA < valueB) return -1;
        if(valueA > valueB) return 1;
        return 0;
    });
    $('.decks_list.decks_list_narrow').find('tbody').append(lines);

    //types
    console.log(rarity);

    //bigger card preview
    var id = setInterval(function() {
        $('#kartenOverlay')
            .css('border', '0px')
            .css('width', 'auto');
        $('#kartenOverlayBild')
            .css('height', '400px')
            .css('width', '280px');
        $('#kartenOverlayContent')
            .css('display', 'none');
        if($('#kartenOverlay').length)
            clearInterval(id);
        }, 1000);

    //set banner link to list view
    var listview = $($('ul#user_menu a')[0]).attr('href');
    if (listview)
        $($('#header_left a')).attr('href', listview)

})();

<|endoftext|>


<commit_before>'use strict';

const Animals = require('../models/animals');

module.exports.getAnimal = ({params: {id}}, res, next) => {
  Animals.getOneAnimal(id)
  .then(Animals => res.status(200).json(Animals))
  .catch((err) => {return next(err)})
}

module.exports.getAnimals = (req, res, next)  =>  {
  Animals.getAllAnimals()
  .then(Animals =>  res.status(200).json(Animals))
  .catch((err)  => { return next(err)})
}
<commit_msg>post and delete methods in animal controller<commit_after>'use strict';

const Animals = require('../models/animals');

module.exports.getAnimal = ({params: {id}}, res, next) => {
  Animals.getOneAnimal(id)
  .then(Animals => res.status(200).json(Animals))
  .catch((err) => {return next(err)})
}

module.exports.getAnimals = (req, res, next)  =>  {
  Animals.getAllAnimals()
  .then(Animals =>  res.status(200).json(Animals))
  .catch((err)  => { return next(err)})
}

module.exports.postNewAnimal = ({ body }, res, next)  =>  {
  Animals.forge(body)
  .then(Animals =>  res.status(201).json({msg: 'You posted an animal!'}))
  .catch((err)  => { return next(err)})
}

module.exports.deleteShow = ({ params: { id }}, res, next) => {
  Animals.forge({id})
  .destroy()
  .then( (animal) => {
    res.status(200).json(animal)
  })
  .catch( (err) => {
    console.log('deleteshow err', err)
  })
}
<|endoftext|>