<commit_before>// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
"use strict";

var _ = require("underscore");
var Backbone = require("backbone");
var base = require("@jupyter-widgets/base");
var widgets = require("@jupyter-widgets/controls");
var outputWidgets = require("./widget_output");
var saveState = require("./save_state");
var embedWidgets = require("./embed_widgets");
var version = require("../package.json").version;
var output = require("./widget_output");

var MIME_TYPE = 'application/vnd.jupyter.widget-view+json';


function polyfill_new_comm_buffers(manager, target_name, data, callbacks, metadata, comm_id, buffers) {
    /**
     * This polyfills services/kernel/comm/CommManager.new_comm to
     * accept the buffers argument.
     *
     * argument comm_id is optional
     */
    return new Promise(function(resolve) {
        requirejs(["services/kernels/comm"], function(comm) {
            var comm = new comm.Comm(target_name, comm_id);
            manager.register_comm(comm);
            // inline Comm.open(), but with buffers
            var content = {
                comm_id : comm_id,
                target_name : target_name,
                data : data || {},
            };
            comm.kernel.send_shell_message("comm_open", content, callbacks, metadata, buffers);
            resolve(comm);
        });
    });
}

function new_comm(manager, target_name, data, callbacks, metadata, comm_id, buffers) {
    // Checks whether new_comm needs a polyfill, and calls the correct version
    // Polyfill needed for notebook <5.1, in which the new_comm method does not support a buffers argument.
    // See https://github.com/jupyter-widgets/ipywidgets/pull/1817
    var need_polyfill = manager.new_comm.length < 6;
    if (need_polyfill) {
        return polyfill_new_comm_buffers.apply(null, arguments);
    }
    return manager.new_comm.apply(manager, Array.prototype.slice.call(arguments, 1));
}

//--------------------------------------------------------------------
// WidgetManager class
//--------------------------------------------------------------------
var WidgetManager = function (comm_manager, notebook) {
    base.ManagerBase.apply(this);
    // Managers are stored in *reverse* order, so that _managers[0] is the most recent.
    WidgetManager._managers.unshift(this);

    // Attach a comm manager
    this.notebook = notebook;
    this.keyboard_manager = notebook.keyboard_manager;
    this.comm_manager = comm_manager;

    var widget_md = notebook.metadata.widgets
    if (widget_md && widget_md['application/vnd.jupyter.widget-state+json']) {
        this.set_state(notebook.metadata.widgets['application/vnd.jupyter.widget-state+json'])
    }

    // Register with the comm manager.
    this.comm_manager.register_target(this.comm_target_name, _.bind(this.handle_comm_open,this));

    // Attempt to reconstruct any live comms by requesting them from the back-end.
    var that = this;
    var backed_widgets_loaded = this._get_comm_info().then(function(comm_ids) {

        // Create comm class instances from comm ids.
        var comm_promises = Object.keys(comm_ids).map(function(comm_id) {
            return that._create_comm(that.comm_target_name, comm_id);
        });

        // Send a state request message out for each widget comm and wait
        // for the responses.
        return Promise.all(comm_promises).then(function(comms) {
            return Promise.all(comms.map(function(comm) {
                var update_promise = new Promise(function(resolve, reject) {
                    comm.on_msg(function (msg) {
                        base.put_buffers(msg.content.data.state, msg.content.data.buffer_paths, msg.buffers);
                        // A suspected response was received, check to see if
                        // it's a state update. If so, resolve.
                        if (msg.content.data.method === 'update') {
                            resolve({
                                comm: comm,
                                msg: msg
                            });
                        }
                    });
                });
                comm.send({
                    method: 'request_state'
                }, that.callbacks());
                return update_promise;
            }));
        }).then(function(widgets_info) {
            return Promise.all(widgets_info.map(function(widget_info) {
                return that.new_model({
                    model_name: widget_info.msg.content.data.state._model_name,
                    model_module: widget_info.msg.content.data.state._model_module,
                    model_module_version: widget_info.msg.content.data.state._model_module_version,
                    comm: widget_info.comm,
                }, widget_info.msg.content.data.state);
            }));
        }).then(function() {
            // Rerender cells that have widget data
            that.notebook.get_cells().forEach(function(cell) {
                var rerender = cell.output_area && cell.output_area.outputs.find(function(output) {
                    return output.data && output.data[MIME_TYPE];
                });
                if (rerender) {
                    that.notebook.render_cell_output(cell);
                }
            });
        });
    });

    // Create the actions and menu
    this._init_actions();
    this._init_menu();
};

WidgetManager.prototype = Object.create(base.ManagerBase.prototype);
WidgetManager._managers = []; /* List of widget managers in *reverse* order (_managers[0] is the most recent) */

WidgetManager.prototype.loadClass = function(className, moduleName, moduleVersion) {
    if (moduleName === "@jupyter-widgets/controls") {
        return Promise.resolve(widgets[className]);<commit_msg>Clean up state restore in nbextension manager<commit_after>// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
"use strict";

var _ = require("underscore");
var Backbone = require("backbone");
var base = require("@jupyter-widgets/base");
var widgets = require("@jupyter-widgets/controls");
var outputWidgets = require("./widget_output");
var saveState = require("./save_state");
var embedWidgets = require("./embed_widgets");
var version = require("../package.json").version;
var output = require("./widget_output");

var MIME_TYPE = 'application/vnd.jupyter.widget-view+json';


function polyfill_new_comm_buffers(manager, target_name, data, callbacks, metadata, comm_id, buffers) {
    /**
     * This polyfills services/kernel/comm/CommManager.new_comm to
     * accept the buffers argument.
     *
     * argument comm_id is optional
     */
    return new Promise(function(resolve) {
        requirejs(["services/kernels/comm"], function(comm) {
            var comm = new comm.Comm(target_name, comm_id);
            manager.register_comm(comm);
            // inline Comm.open(), but with buffers
            var content = {
                comm_id : comm_id,
                target_name : target_name,
                data : data || {},
            };
            comm.kernel.send_shell_message("comm_open", content, callbacks, metadata, buffers);
            resolve(comm);
        });
    });
}

function new_comm(manager, target_name, data, callbacks, metadata, comm_id, buffers) {
    // Checks whether new_comm needs a polyfill, and calls the correct version
    // Polyfill needed for notebook <5.1, in which the new_comm method does not support a buffers argument.
    // See https://github.com/jupyter-widgets/ipywidgets/pull/1817
    var need_polyfill = manager.new_comm.length < 6;
    if (need_polyfill) {
        return polyfill_new_comm_buffers.apply(null, arguments);
    }
    return manager.new_comm.apply(manager, Array.prototype.slice.call(arguments, 1));
}

function filter_existing_model_state(manager, state) {
    var models = state.state;
    models = Object.keys(models)
          .filter(function(model_id) {
              return !manager._models[model_id];
          })
          .reduce(function(res, model_id) {
              return Object.assign(res, { [model_id]: models[model_id] });
          }, {});
    return Object.assign({}, state, {state: models});
}

//--------------------------------------------------------------------
// WidgetManager class
//--------------------------------------------------------------------
var WidgetManager = function (comm_manager, notebook) {
    base.ManagerBase.apply(this);
    // Managers are stored in *reverse* order, so that _managers[0] is the most recent.
    WidgetManager._managers.unshift(this);

    // Attach a comm manager
    this.notebook = notebook;
    this.keyboard_manager = notebook.keyboard_manager;
    this.comm_manager = comm_manager;

    var widget_md = notebook.metadata.widgets

    // Steps that needs to be done:
    // 1. Register comm target
    // 2. Get any widget state from the kernel and open comms with existing state
    // 3. Check saved state for widgets, and restore any that would not overwrite
    //    any live widgets.

    // Register with the comm manager. (1)
    this.comm_manager.register_target(this.comm_target_name, _.bind(this.handle_comm_open,this));

    // Attempt to reconstruct any live comms by requesting them from the back-end (2).
    var that = this;
    var backed_widgets_loaded = Promise.resolve().then(function() {
        return that._get_comm_info();
    }).then(function(comm_ids) {

        // Create comm class instances from comm ids (2).
        var comm_promises = Object.keys(comm_ids).map(function(comm_id) {
            return that._create_comm(that.comm_target_name, comm_id);
        });

        // Send a state request message out for each widget comm and wait
        // for the responses (2).
        return Promise.all(comm_promises).then(function(comms) {
            return Promise.all(comms.map(function(comm) {
                var update_promise = new Promise(function(resolve, reject) {
                    comm.on_msg(function (msg) {
                        base.put_buffers(msg.content.data.state, msg.content.data.buffer_paths, msg.buffers);
                        // A suspected response was received, check to see if
                        // it's a state update. If so, resolve.
                        if (msg.content.data.method === 'update') {
                            resolve({
                                comm: comm,
                                msg: msg
                            });
                        }
                    });
                });
                comm.send({
                    method: 'request_state'
                }, that.callbacks());
                return update_promise;
            }));
        }).then(function(widgets_info) {
            return Promise.all(widgets_info.map(function(widget_info) {
                return that.new_model({
                    model_name: widget_info.msg.content.data.state._model_name,
                    model_module: widget_info.msg.content.data.state._model_module,
                    model_module_version: widget_info.msg.content.data.state._model_module_version,
                    comm: widget_info.comm,
                }, widget_info.msg.content.data.state);
            }));
        }).then(function() {
            // Now that we have mirrored any widgets from the kernel...
            // Restore any widgets from saved state that are not live (3)
            if (widget_md && widget_md['application/vnd.jupyter.widget-state+json']) {
                var state = notebook.metadata.widgets['application/vnd.jupyter.widget-state+json'];
                state = filter_existing_model_state(that, state);
                return that.set_state(state);
            }
        }).then(function() {
            // Rerender cells that have widget data
            that.notebook.get_cells().forEach(function(cell) {
                var rerender = cell.output_area && cell.output_area.outputs.find(function(output) {
                    return output.data && output.data[MIME_TYPE];
                });
                if (rerender) {
                    that.notebook.render_cell_output(cell);
                }
            });
        });
    });

    // Create the actions and menu
    this._init_actions();
    this._init_menu();
};

WidgetManager.prototype = Object.create(base.ManagerBase.prototype);
WidgetManager._managers = []; /* List of widget managers in *reverse* order (_managers[0] is the most recent) */

WidgetManager.prototype.loadClass = function(className, moduleName, moduleVersion) {
    if (moduleName === "@jupyter-widgets/controls") {
        return Promise.resolve(widgets[className]);
{'fraction_non_alphanumeric': 0.12952231793265465, 'fraction_numerical': 0.002192638997650744, 'mean_word_length': 2.0825488776249097, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7466733', 'n_tokens_mistral': 3490, 'n_tokens_neox': 3351, 'n_words': 793}