<commit_before>var EventEmitter = require('events');
var Sequencer = require('./sequencer');
var Thread = require('./thread');
var util = require('util');

var defaultBlockPackages = {
    'scratch3': require('../blocks/scratch3'),
    'wedo2': require('../blocks/wedo2')
};

/**
 * Manages blocks, stacks, and the sequencer.
 */
function Runtime () {
    // Bind event emitter
    EventEmitter.call(this);

    // State for the runtime
    /**
     * All blocks in the workspace.
     * Keys are block IDs, values are metadata about the block.
     * @type {Object.<string, Object>}
     */
    this.blocks = {};

    /**
     * All stacks in the workspace.
     * A list of block IDs that represent stacks (first block in stack).
     * @type {Array.<String>}
     */
    this.stacks = [];

    /**
     * A list of threads that are currently running in the VM.
     * Threads are added when execution starts and pruned when execution ends.
     * @type {Array.<Thread>}
     */
    this.threads = [];

    /** @type {!Sequencer} */
    this.sequencer = new Sequencer(this);

    /**
     * Map to look up a block primitive's implementation function by its opcode.
     * This is a two-step lookup: package name first, then primitive name.
     * @type {Object.<string, Function>}
     */
    this._primitives = {};
    this._registerBlockPackages();
}

/**
 * Event name for glowing a stack
 * @const {string}
 */
Runtime.STACK_GLOW_ON = 'STACK_GLOW_ON';

/**
 * Event name for unglowing a stack
 * @const {string}
 */
Runtime.STACK_GLOW_OFF = 'STACK_GLOW_OFF';

/**
 * Event name for glowing a block
 * @const {string}
 */
Runtime.BLOCK_GLOW_ON = 'BLOCK_GLOW_ON';

/**
 * Event name for unglowing a block
 * @const {string}
 */
Runtime.BLOCK_GLOW_OFF = 'BLOCK_GLOW_OFF';

/**
 * Inherit from EventEmitter
 */
util.inherits(Runtime, EventEmitter);

/**
 * How rapidly we try to step threads, in ms.
 */
Runtime.THREAD_STEP_INTERVAL = 1000 / 30;

/**
 * Block management: create blocks and stacks from a `create` event
 * @param {!Object} block Blockly create event to be processed
 */
Runtime.prototype.createBlock = function (block, opt_isFlyoutBlock) {
    // Create new block
    this.blocks[block.id] = block;

    // Push block id to stacks array.
    // Blocks are added as a top-level stack if they are marked as a topBlock
    // (if they were top-level XML in the event) and if they are not
    // flyout blocks.
    if (!opt_isFlyoutBlock && block.topBlock) {
        this._addStack(block.id);
    }
};

/**
 * Block management: change block field values
 * @param {!Object} args Blockly change event to be processed
 */
Runtime.prototype.changeBlock = function (args) {
    // Validate
    if (args.element !== 'field') return;
    if (typeof this.blocks[args.id] === 'undefined') return;
    if (typeof this.blocks[args.id].fields[args.name] === 'undefined') return;

    // Update block value
    this.blocks[args.id].fields[args.name].value = args.value;
};

/**
 * Block management: move blocks from parent to parent
 * @param {!Object} e Blockly move event to be processed
 */
Runtime.prototype.moveBlock = function (e) {
    var _this = this;

    // Block was removed from parent
    if (e.newParent === undefined && e.oldParent !== undefined) {
        _this.addStack(e.id);

        // Update old parent
        if (e.oldField === undefined) {
            _this.blocks[e.oldParent].next = null;
        } else {
            delete _this.blocks[e.oldParent].fields[e.oldField];
        }
    } else if (e.newParent !== undefined) {
        // Block was moved to a new parent
        // Either happens because it was previously parentless
        // (e.oldParent === undefined)
        // or because a block was moved in front of it.

        // Remove stack
        _this._deleteStack(e.id);

        // Update new parent
        if (e.newField === undefined) {
            _this.blocks[e.newParent].next = e.id;
        } else {
            _this.blocks[e.newParent].fields[e.newField] = {
                name: e.newField,
                value: e.id,
                blocks: {}
            };<commit_msg>Rewrite of moveBlock to better reflect Blockly<commit_after>var EventEmitter = require('events');
var Sequencer = require('./sequencer');
var Thread = require('./thread');
var util = require('util');

var defaultBlockPackages = {
    'scratch3': require('../blocks/scratch3'),
    'wedo2': require('../blocks/wedo2')
};

/**
 * Manages blocks, stacks, and the sequencer.
 */
function Runtime () {
    // Bind event emitter
    EventEmitter.call(this);

    // State for the runtime
    /**
     * All blocks in the workspace.
     * Keys are block IDs, values are metadata about the block.
     * @type {Object.<string, Object>}
     */
    this.blocks = {};

    /**
     * All stacks in the workspace.
     * A list of block IDs that represent stacks (first block in stack).
     * @type {Array.<String>}
     */
    this.stacks = [];

    /**
     * A list of threads that are currently running in the VM.
     * Threads are added when execution starts and pruned when execution ends.
     * @type {Array.<Thread>}
     */
    this.threads = [];

    /** @type {!Sequencer} */
    this.sequencer = new Sequencer(this);

    /**
     * Map to look up a block primitive's implementation function by its opcode.
     * This is a two-step lookup: package name first, then primitive name.
     * @type {Object.<string, Function>}
     */
    this._primitives = {};
    this._registerBlockPackages();
}

/**
 * Event name for glowing a stack
 * @const {string}
 */
Runtime.STACK_GLOW_ON = 'STACK_GLOW_ON';

/**
 * Event name for unglowing a stack
 * @const {string}
 */
Runtime.STACK_GLOW_OFF = 'STACK_GLOW_OFF';

/**
 * Event name for glowing a block
 * @const {string}
 */
Runtime.BLOCK_GLOW_ON = 'BLOCK_GLOW_ON';

/**
 * Event name for unglowing a block
 * @const {string}
 */
Runtime.BLOCK_GLOW_OFF = 'BLOCK_GLOW_OFF';

/**
 * Inherit from EventEmitter
 */
util.inherits(Runtime, EventEmitter);

/**
 * How rapidly we try to step threads, in ms.
 */
Runtime.THREAD_STEP_INTERVAL = 1000 / 30;

/**
 * Block management: create blocks and stacks from a `create` event
 * @param {!Object} block Blockly create event to be processed
 */
Runtime.prototype.createBlock = function (block, opt_isFlyoutBlock) {
    // Create new block
    this.blocks[block.id] = block;

    // Push block id to stacks array.
    // Blocks are added as a top-level stack if they are marked as a topBlock
    // (if they were top-level XML in the event) and if they are not
    // flyout blocks.
    if (!opt_isFlyoutBlock && block.topBlock) {
        this._addStack(block.id);
    }
};

/**
 * Block management: change block field values
 * @param {!Object} args Blockly change event to be processed
 */
Runtime.prototype.changeBlock = function (args) {
    // Validate
    if (args.element !== 'field') return;
    if (typeof this.blocks[args.id] === 'undefined') return;
    if (typeof this.blocks[args.id].fields[args.name] === 'undefined') return;

    // Update block value
    this.blocks[args.id].fields[args.name].value = args.value;
};

/**
 * Block management: move blocks from parent to parent
 * @param {!Object} e Blockly move event to be processed
 */
Runtime.prototype.moveBlock = function (e) {
    var _this = this;

    // Remove from any old parent.
    if (e.oldParent !== undefined) {
        var oldParent = _this.blocks[e.oldParent];
        if (e.oldInput !== undefined &&
            oldParent.inputs[e.oldInput].block === e.id) {
            // This block was connected to the old parent's input.
            oldParent.inputs[e.oldInput].block = null;
        } else if (oldParent.next === e.id) {
            // This block was connected to the old parent's next connection.
            oldParent.next = null;
        }
    }

    // Has the block become a top-level block?
    if (e.newParent === undefined) {
        _this._addStack(e.id);
    } else {
        // Remove stack, if one exists.
        _this._deleteStack(e.id);
        // Otherwise, try to connect it in its new place.
        if (e.newInput !== undefined) {
            // Moved to the new parent's input.
            _this.blocks[e.newParent].inputs[e.newInput] = {
                name: e.newInput,
                block: e.id
            };
        } else {
            // Moved to the new parent's next connection.
            _this.blocks[e.newParent].next = e.id;
{'fraction_non_alphanumeric': 0.13013698630136986, 'fraction_numerical': 0.0023618327822390174, 'mean_word_length': 2.490931574608409, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4899158', 'n_tokens_mistral': 2579, 'n_tokens_neox': 2522, 'n_words': 802}