Improve profiling for UI interactions v2. (#3451)

* Extends the instrumentation of the code base and upgrades some FRPs to the newer API macro.
* Extends the run-graph demo scene to specify a profile via URL without recompilation.
* Fixes labels in the flame graph demo scene.
* Fixes an issue with loading profiles that contains escaped characters.

# Important Notes
* no longer contains the upgrade of the `text::View` to `define_endpoints_2`. This should be fixed as part of the text rendering rewrite.

[ci no changelog needed]
This commit is contained in:
Michael Mauderer 2022-05-16 13:28:50 +01:00 committed by GitHub
parent c313a4c499
commit 0b34346c19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 544 additions and 326 deletions

13
Cargo.lock generated
View File

@ -91,6 +91,7 @@ dependencies = [
"derive_more",
"enso-data-structures",
"enso-prelude",
"enso-profiler",
"enso-shapely",
"enso-text",
"failure",
@ -1517,7 +1518,9 @@ dependencies = [
"ensogl-text-msdf-sys",
"ensogl-tooltip",
"futures 0.3.21",
"qstring",
"serde",
"url 2.2.2",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
@ -1537,6 +1540,7 @@ dependencies = [
"ensogl-hardcoded-theme",
"ensogl-text",
"ensogl-text-msdf-sys",
"ensogl-tooltip",
"futures 0.3.21",
"wasm-bindgen",
"wasm-bindgen-futures",
@ -3366,6 +3370,15 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "qstring"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e"
dependencies = [
"percent-encoding 2.1.0",
]
[[package]]
name = "quote"
version = "1.0.18"

View File

@ -21,3 +21,4 @@ enso-data-structures = { path = "../../../../../lib/rust/data-structures" }
enso-text = { path = "../../../../../lib/rust/text" }
enso-prelude = { path = "../../../../../lib/rust/prelude" }
enso-shapely = { path = "../../../../../lib/rust/shapely" }
enso-profiler = { path = "../../../../../lib/rust/profiler" }

View File

@ -1464,7 +1464,7 @@ pub trait TraversableAst: Sized {
self.get_traversing(&[])
}
/// Calculate the span of the descendent AST node described by given crumbs..
/// Calculate the span of the descendent AST node described by given crumbs.
fn range_of_descendant_at(&self, crumbs: &[Crumb]) -> FallibleResult<text::Range<Bytes>> {
let mut position = 0.bytes();
let mut ast = self.my_ast()?;

View File

@ -120,6 +120,7 @@ impl Parser {
/// Program is expected to be single non-empty line module. The line's AST is
/// returned. The program is parsed with empty IdMap.
#[profile(Debug)]
pub fn parse_line_ast(&self, program: impl Str) -> FallibleResult<Ast> {
self.parse_line_with_id_map(program, default()).map(|line| line.elem)
}

View File

@ -841,6 +841,7 @@ impl Handle {
}
/// Sets the given's node expression.
#[profile(Debug)]
pub fn set_expression_ast(&self, id: ast::Id, expression: Ast) -> FallibleResult {
info!(self.logger, "Setting node {id} expression to `{expression.repr()}`");
self.update_definition_ast(|definition| {
@ -1052,6 +1053,7 @@ pub mod tests {
self.module_path.method_pointer(self.project_name.clone(), self.graph_id.to_string())
}
#[profile(Debug)]
pub fn suggestion_db(&self) -> Rc<model::SuggestionDatabase> {
use model::suggestion_database::SuggestionDatabase;
let entries = self.suggestions.iter();

View File

@ -56,6 +56,7 @@ impl StatusNotificationPublisher {
}
/// Publish a new status event (see [`StatusNotification::Event`])
#[profile(Debug)]
pub fn publish_event(&self, label: impl Into<String>) {
let label = label.into();
let notification = StatusNotification::Event { label };
@ -65,6 +66,7 @@ impl StatusNotificationPublisher {
/// Publish a notification about new process (see [`StatusNotification::ProcessStarted`]).
///
/// Returns the handle to be used when notifying about process finishing.
#[profile(Debug)]
pub fn publish_background_task(&self, label: impl Into<String>) -> BackgroundTaskHandle {
let label = label.into();
let handle = self.next_process_handle.get();
@ -76,6 +78,7 @@ impl StatusNotificationPublisher {
/// Publish a notfication that process has finished (see
/// [`StatusNotification::ProcessFinished`])
#[profile(Debug)]
pub fn published_background_task_finished(&self, handle: BackgroundTaskHandle) {
let notification = StatusNotification::BackgroundTaskFinished { handle };
executor::global::spawn(self.publisher.publish(notification));

View File

@ -194,6 +194,7 @@ pub struct ParsedInput {
impl ParsedInput {
/// Constructor from the plain input.
#[profile(Debug)]
fn new(input: impl Into<String>, parser: &Parser) -> FallibleResult<Self> {
let mut input = input.into();
let leading_spaces = input.chars().take_while(|c| *c == ' ').count();
@ -421,6 +422,7 @@ impl Data {
/// Committing node will then edit the exiting node's expression instead of adding a new one.
/// Additionally searcher should restore information about intended method, so we will be able
/// to suggest arguments.
#[profile(Debug)]
fn new_with_edited_node(
project_name: project::QualifiedName,
graph: &controller::Graph,
@ -498,6 +500,7 @@ impl Searcher {
}
/// Create new Searcher Controller, when you have Executed Graph Controller handy.
#[profile(Task)]
pub fn new_from_graph_controller(
parent: impl AnyLogger,
ide: controller::Ide,
@ -563,6 +566,7 @@ impl Searcher {
///
/// This function should be called each time user modifies Searcher input in view. It may result
/// in a new action list (the appropriate notification will be emitted).
#[profile(Debug)]
pub fn set_input(&self, new_input: String) -> FallibleResult {
debug!(self.logger, "Manually setting input to {new_input}.");
let parsed_input = ParsedInput::new(new_input, self.ide.parser())?;
@ -600,6 +604,7 @@ impl Searcher {
/// This function should be called when user do the _use as suggestion_ action as a code
/// suggestion (see struct documentation). The picked suggestion will be remembered, and the
/// searcher's input will be updated and returned by this function.
#[profile(Debug)]
pub fn use_suggestion(&self, picked_suggestion: action::Suggestion) -> FallibleResult<String> {
info!(self.logger, "Picking suggestion: {picked_suggestion:?}");
let id = self.data.borrow().input.next_completion_id();
@ -695,6 +700,7 @@ impl Searcher {
}
/// See `execute_action` documentation.
#[profile(Task)]
pub fn execute_action_by_index(&self, index: usize) -> FallibleResult<Option<ast::Id>> {
let error = || NoSuchAction { index };
let action = {
@ -724,6 +730,7 @@ impl Searcher {
/// If the searcher was brought by editing existing node, the input is set as a new node
/// expression, otherwise a new node is added. This will also add all imports required by
/// picked suggestions.
#[profile(Debug)]
pub fn commit_node(&self) -> FallibleResult<ast::Id> {
let _transaction_guard = self.graph.get_or_open_transaction("Commit node");
let expr_and_method = || {
@ -772,6 +779,7 @@ impl Searcher {
///
/// The example piece of code will be inserted as a new function definition, and in current
/// graph the node calling this function will appear.
#[profile(Debug)]
pub fn add_example(
&self,
example: &action::Example,
@ -814,6 +822,7 @@ impl Searcher {
Ok(added_node_id)
}
#[profile(Debug)]
fn invalidate_fragments_added_by_picking(&self) {
let mut data = self.data.borrow_mut();
let data = data.deref_mut();
@ -844,6 +853,7 @@ impl Searcher {
///
/// The current list will be set as "Loading" and Language Server will be requested for a new
/// list - once it be retrieved, the new list will be set and notification will be emitted.
#[profile(Debug)]
fn reload_list(&self) {
let this_type = self.this_arg_type_for_next_completion();
let return_types = match self.data.borrow().input.next_completion_id() {
@ -858,6 +868,7 @@ impl Searcher {
/// Get the typename of "this" value for current completion context. Returns `Future`, as the
/// type information might not have came yet from the Language Server.
#[profile(Debug)]
fn this_arg_type_for_next_completion(&self) -> impl Future<Output = Option<String>> {
let next_id = self.data.borrow().input.next_completion_id();
let logger = self.logger.clone_ref();
@ -931,6 +942,7 @@ impl Searcher {
}
/// Process multiple completion responses from the engine into a single list of suggestion.
#[profile(Debug)]
fn make_action_list(
&self,
completion_responses: Vec<json_rpc::Result<language_server::response::Completion>>,

View File

@ -240,6 +240,7 @@ impl ListEntry {
/// The ordering on the action list: first, are the matched entries are gathered on the top of
/// the list, then sorted by categories, and those of same category are ordered by match score
/// (the best matches are first).
#[profile(Debug)]
pub fn ordering_on_list(&self, rhs: &Self) -> std::cmp::Ordering {
self.matches()
.cmp(&rhs.matches())
@ -297,6 +298,7 @@ impl List {
///
/// The "matching score" of each entry is recalculated against the given pattern and the entries
/// are re-ordered, so the best matches will go first.
#[profile(Debug)]
pub fn update_filtering(&self, pattern: impl Str) {
{
let mut entries_mut = self.entries.borrow_mut();
@ -370,6 +372,7 @@ impl List {
self.entries.borrow().iter().map(|entry| entry.action.clone_ref()).collect()
}
#[profile(Debug)]
fn update_sorting(&self) {
let mut entries_mut = self.entries.borrow_mut();
entries_mut.sort_by(|l, r| l.ordering_on_list(r));

View File

@ -74,13 +74,13 @@ impl Ide {
enso_frp::extend! { network
on_log_sent <- source::<()>();
mouse_moved <- mouse.position.constant(());
any_mouse_press <- any(mouse.up,mouse.down).constant(());
any_mouse_event <- any(any_mouse_press,mouse_moved,mouse.wheel);
any_keyboard_event <- any(keyboard.down,keyboard.up).constant(());
any_input_event <- any(any_mouse_event,any_keyboard_event);
mouse_moved <- mouse.position.constant(()).profile();
any_mouse_press <- any(mouse.up,mouse.down).constant(()).profile();
any_mouse_event <- any(any_mouse_press,mouse_moved,mouse.wheel).profile();
any_keyboard_event <- any(keyboard.down,keyboard.up).constant(()).profile();
any_input_event <- any(any_mouse_event,any_keyboard_event).profile();
// True if any input event was captured since the last "alive" log sending.
input_event_received <- bool(&on_log_sent,&any_input_event).sampler();
input_event_received <- bool(&on_log_sent,&any_input_event).profile().sampler();
}
async move {
loop {

View File

@ -52,6 +52,7 @@ pub trait Aware {
fn undo_redo_repository(&self) -> Rc<Repository>;
/// Get current ongoing transaction. If there is no ongoing transaction, create a one.
#[profile(Debug)]
#[must_use]
fn get_or_open_transaction(&self, name: &str) -> Rc<Transaction> {
self.undo_redo_repository().transaction(name)

View File

@ -37,6 +37,7 @@ struct Model {
}
impl Model {
#[profile(Debug)]
fn new(
parent: impl AnyLogger,
controller: controller::Searcher,
@ -47,6 +48,7 @@ impl Model {
Self { logger, controller, view, input_view }
}
#[profile(Debug)]
fn input_changed(&self, new_input: &str) {
if let Err(err) = self.controller.set_input(new_input.to_owned()) {
error!(self.logger, "Error while setting new searcher input: {err}");
@ -69,6 +71,7 @@ impl Model {
}
}
#[profile(Task)]
fn commit_editing(&self, entry_id: Option<view::searcher::entry::Id>) -> Option<AstNodeId> {
let result = match entry_id {
Some(id) => self.controller.execute_action_by_index(id),
@ -107,6 +110,7 @@ pub struct Searcher {
impl Searcher {
/// Constructor. The returned structure works rigth away.
#[profile(Task)]
pub fn new(
parent: impl AnyLogger,
controller: controller::Searcher,
@ -151,6 +155,7 @@ impl Searcher {
/// Setup new, appropriate searcher controller for the edition of `node_view`, and construct
/// presenter handling it.
#[profile(Task)]
pub fn setup_controller(
parent: impl AnyLogger,
ide_controller: controller::Ide,
@ -189,6 +194,7 @@ impl Searcher {
/// editing finishes. The `entry_id` might be none in case where the searcher should accept
/// the node input without any entry selected. If the commitment will result in creating a new
/// node, its AST id is returned.
#[profile(Task)]
pub fn commit_editing(self, entry_id: Option<view::searcher::entry::Id>) -> Option<AstNodeId> {
self.model.commit_editing(entry_id)
}

View File

@ -438,6 +438,7 @@ pub struct NodeModel {
impl NodeModel {
/// Constructor.
#[profile(Debug)]
pub fn new(app: &Application, registry: visualization::Registry) -> Self {
ensogl::shapes_order_dependencies! {
app.display.default_scene => {
@ -528,17 +529,20 @@ impl NodeModel {
.init()
}
#[profile(Debug)]
#[allow(missing_docs)] // FIXME[everyone] All pub functions should have docs.
pub fn get_crumbs_by_id(&self, id: ast::Id) -> Option<Crumbs> {
let input_crumbs = self.input.get_crumbs_by_id(id).map(Crumbs::input);
input_crumbs.or_else(|| self.output.get_crumbs_by_id(id).map(Crumbs::output))
}
#[profile(Debug)]
fn init(self) -> Self {
self.set_expression(Expression::new_plain("empty"));
self
}
#[profile(Debug)]
fn set_layers(&self, layer: &Layer, text_layer: &Layer, action_bar_layer: &Layer) {
layer.add_exclusive(&self.display_object);
action_bar_layer.add_exclusive(&self.action_bar);
@ -555,6 +559,7 @@ impl NodeModel {
///
/// `action_bar` is moved to the `edited_node` layer as well, though normally it lives on a
/// separate `above_nodes` layer, unlike every other node component.
#[profile(Debug)]
pub fn move_to_edited_node_layer(&self) {
let scene = &self.app.display.default_scene;
let layer = &scene.layers.edited_node;
@ -570,6 +575,7 @@ impl NodeModel {
///
/// `action_bar` is handled separately, as it uses `above_nodes` scene layer unlike any other
/// node component.
#[profile(Debug)]
pub fn move_to_main_layer(&self) {
let scene = &self.app.display.default_scene;
let layer = &scene.layers.main;
@ -588,12 +594,14 @@ impl NodeModel {
HEIGHT
}
#[profile(Debug)]
fn set_expression(&self, expr: impl Into<Expression>) {
let expr = expr.into();
self.output.set_expression(&expr);
self.input.set_expression(&expr);
}
#[profile(Debug)]
fn set_expression_usage_type(&self, crumbs: &Crumbs, tp: &Option<Type>) {
match crumbs.endpoint {
Endpoint::Input => self.input.set_expression_usage_type(&crumbs.crumbs, tp),
@ -601,6 +609,7 @@ impl NodeModel {
}
}
#[profile(Debug)]
fn set_width(&self, width: f32) -> Vector2 {
let height = self.height();
let size = Vector2(width, height);
@ -630,11 +639,13 @@ impl NodeModel {
size
}
#[profile(Debug)]
#[allow(missing_docs)] // FIXME[everyone] All pub functions should have docs.
pub fn visualization(&self) -> &visualization::Container {
&self.visualization
}
#[profile(Debug)]
fn set_error(&self, error: Option<&Error>) {
if let Some(error) = error {
self.error_visualization.display_kind(*error.kind);
@ -647,6 +658,7 @@ impl NodeModel {
}
}
#[profile(Debug)]
fn set_error_color(&self, color: &color::Lcha) {
self.error_indicator.color_rgba.set(color::Rgba::from(color).into());
if color.alpha < EPSILON {
@ -659,6 +671,7 @@ impl NodeModel {
impl Node {
#[allow(missing_docs)] // FIXME[everyone] All pub functions should have docs.
#[profile(Debug)]
pub fn new(app: &Application, registry: visualization::Registry) -> Self {
let frp = Frp::new();
let network = &frp.private.network;
@ -954,6 +967,7 @@ impl Node {
Node { widget }
}
#[profile(Debug)]
fn error_color(error: &Option<Error>, style: &StyleWatch) -> color::Lcha {
use ensogl_hardcoded_theme::graph_editor::node::error as error_theme;
@ -988,6 +1002,7 @@ fn visualization_offset(node_width: f32) -> Vector2 {
Vector2(x_offset_to_node_center(node_width), VISUALIZATION_OFFSET_Y)
}
#[profile(Debug)]
fn bounding_box(
node_position: Vector2,
node_size: Vector2,

View File

@ -11,10 +11,12 @@ use crate::node;
use crate::node::input::port;
use crate::node::profiling;
use crate::view;
use crate::FrpNetworkProvider;
use crate::Type;
use enso_frp as frp;
use enso_frp;
use enso_frp::stream::ValueProvider;
use enso_text::text::Text;
use ensogl::application::Application;
use ensogl::data::color;
@ -25,7 +27,6 @@ use ensogl_component::text;
use ensogl_hardcoded_theme as theme;
// =================
// === Constants ===
// =================
@ -166,7 +167,7 @@ impl From<node::Expression> for Expression {
// === Model ===
// =============
ensogl::define_endpoints! {
ensogl::define_endpoints_2! {
Input {
/// Set the mode in which the cursor will indicate that editing of the node is possible.
set_edit_ready_mode (bool),
@ -233,6 +234,7 @@ pub struct Model {
impl Model {
/// Constructor.
#[profile(Debug)]
pub fn new(logger: impl AnyLogger, app: &Application) -> Self {
let logger = Logger::new_sub(&logger, "input_ports");
let display_object = display::object::Instance::new(&logger);
@ -262,6 +264,7 @@ impl Model {
.init()
}
#[profile(Debug)]
fn init(self) -> Self {
// FIXME[WD]: Depth sorting of labels to in front of the mouse pointer. Temporary solution.
// It needs to be more flexible once we have proper depth management.
@ -312,6 +315,7 @@ impl Model {
}
/// Update expression type for the particular `ast::Id`.
#[profile(Debug)]
fn set_expression_usage_type(&self, crumbs: &Crumbs, tp: &Option<Type>) {
if let Ok(port) = self.expression.borrow().span_tree.root_ref().get_descendant(crumbs) {
port.set_usage_type(tp)
@ -351,10 +355,11 @@ impl Deref for Area {
impl Area {
/// Constructor.
#[profile(Debug)]
pub fn new(logger: impl AnyLogger, app: &Application) -> Self {
let model = Rc::new(Model::new(logger, app));
let frp = Frp::new();
let network = &frp.network;
let network = frp.network();
let selection_color = Animation::new(network);
frp::extend! { network
@ -364,12 +369,12 @@ impl Area {
// learn more about the architecture and the importance of the hover
// functionality.
frp.output.source.body_hover <+ frp.set_hover;
frp.private.output.body_hover <+ frp.set_hover;
// === Cursor setup ===
eval frp.input.set_edit_mode ([model](edit_mode) {
eval frp.private.input.set_edit_mode ([model](edit_mode) {
model.label.set_focus(edit_mode);
if *edit_mode {
// Reset the code to hide non-connected port names.
@ -392,8 +397,8 @@ impl Area {
);
port_vis <- all_with(&frp.input.set_ports_active,&edit_mode,|(a,_),b|*a&&(!b));
frp.output.source.ports_visible <+ port_vis;
frp.output.source.editing <+ edit_mode;
frp.private.output.ports_visible <+ port_vis;
frp.private.output.editing <+ edit_mode;
// === Label Hover ===
@ -415,8 +420,8 @@ impl Area {
// === Properties ===
width <- model.label.width.map(|t| t + 2.0 * TEXT_OFFSET);
frp.output.source.width <+ width;
frp.output.source.expression <+ model.label.content;
frp.private.output.width <+ width;
frp.private.output.expression <+ model.label.content;
// === Expression Type ===
@ -426,7 +431,7 @@ impl Area {
// === View Mode ===
frp.output.source.view_mode <+ frp.set_view_mode;
frp.private.output.view_mode <+ frp.set_view_mode;
in_profiling_mode <- frp.view_mode.map(|m| m.is_profiling());
finished <- frp.set_profiling_status.map(|s| s.is_finished());
@ -518,6 +523,7 @@ struct PortLayerBuilder {
impl PortLayerBuilder {
/// Constructor.
#[profile(Debug)]
fn new(
parent: impl display::Object,
parent_frp: Option<port::FrpEndpoints>,
@ -534,6 +540,7 @@ impl PortLayerBuilder {
}
/// Create a nested builder with increased depth and updated `parent_frp`.
#[profile(Debug)]
fn nested(
&self,
parent: display::object::Instance,
@ -548,10 +555,12 @@ impl PortLayerBuilder {
}
impl Area {
#[profile(Debug)]
fn set_label_on_new_expression(&self, expression: &Expression) {
self.model.label.set_content(expression.viz_code.clone());
}
#[profile(Debug)]
fn build_port_shapes_on_new_expression(&self, expression: &mut Expression) {
let mut is_header = true;
let mut id_crumbs_map = HashMap::new();
@ -630,7 +639,7 @@ impl Area {
let any_type_sel_color = styles_frp.get_color(theme::code::types::any::selection);
let crumbs = port.crumbs.clone_ref();
let port_network = &port.network;
let frp = &self.frp.output;
let frp = &self.frp.private;
frp::extend! { port_network
@ -649,7 +658,7 @@ impl Area {
// Please note, that this is computed first in order to compute `ports_visible`
// when needed, and thus it has to be run before the following lines.
self.frp.output.source.body_hover <+ bool(&mouse_out,&mouse_over_raw);
self.frp.private.output.body_hover <+ bool(&mouse_out,&mouse_over_raw);
// TODO[WD] for FRP3: Consider the following code. Here, we have to first
// handle `bg_down` and then `mouse_down`. Otherwise, `mouse_down` may
@ -660,21 +669,21 @@ impl Area {
// be solved by solving in the FRP engine all children first, and then their
// children (then both `bg_down` and `mouse_down` will be resolved before
// the `ports_visible` changes).
bg_down <- mouse_down_raw.gate_not(&frp.ports_visible);
mouse_down <- mouse_down_raw.gate(&frp.ports_visible);
mouse_over <- mouse_over_raw.gate(&frp.ports_visible);
self.frp.output.source.on_background_press <+ bg_down;
bg_down <- mouse_down_raw.gate_not(&frp.output.ports_visible);
mouse_down <- mouse_down_raw.gate(&frp.output.ports_visible);
mouse_over <- mouse_over_raw.gate(&frp.output.ports_visible);
self.frp.private.output.on_background_press <+ bg_down;
// === Press ===
eval_ mouse_down ([crumbs,frp] frp.source.on_port_press.emit(&crumbs));
eval_ mouse_down ([crumbs,frp] frp.output.on_port_press.emit(&crumbs));
// === Hover ===
hovered <- bool(&mouse_out,&mouse_over);
hover <- hovered.map (f!([crumbs](t) Switch::new(crumbs.clone_ref(),*t)));
frp.source.on_port_hover <+ hover;
frp.output.on_port_hover <+ hover;
// === Pointer Style ===
@ -685,13 +694,13 @@ impl Area {
init_color <- source::<()>();
any_type_sel_color <- all_with(&any_type_sel_color,&init_color,
|c,_| color::Lcha::from(c));
tp <- all_with(&port.tp,&frp.set_ports_active,
tp <- all_with(&port.tp,&frp.input.set_ports_active,
|tp,(_,edge_tp)| tp.clone().or_else(||edge_tp.clone()));
tp_color <- tp.map(
f!([styles](tp) tp.map_ref(|tp| type_coloring::compute(tp,&styles))));
tp_color <- all_with(&tp_color,&any_type_sel_color,
|tp_color,any_type_sel_color| tp_color.unwrap_or(*any_type_sel_color));
in_profiling_mode <- frp.view_mode.map(|m| matches!(m,view::Mode::Profiling));
in_profiling_mode <- frp.output.view_mode.map(|m| matches!(m,view::Mode::Profiling));
pointer_color_over <- in_profiling_mode.switch(&tp_color,&any_type_sel_color);
pointer_style_over <- pointer_color_over.map(move |color|
cursor::Style::new_highlight(&port_shape_hover,padded_size,Some(color))
@ -701,10 +710,10 @@ impl Area {
pointer_style_hover <- any(pointer_style_over,pointer_style_out);
pointer_styles <- all[pointer_style_hover,self.model.label.pointer_style];
pointer_style <- pointer_styles.fold();
self.frp.output.source.pointer_style <+ pointer_style;
self.frp.private.output.pointer_style <+ pointer_style;
}
init_color.emit(());
frp.source.view_mode.emit(frp.view_mode.value());
frp.output.view_mode.emit(frp.output.view_mode.value());
port_shape.display_object().clone_ref()
};
@ -725,6 +734,7 @@ impl Area {
/// Initializes FRP network for every port. Please note that the networks are connected
/// hierarchically (children get events from parents), so it is easier to init all networks
/// this way, rather than delegate it to every port.
#[profile(Debug)]
fn init_port_frp_on_new_expression(&self, expression: &mut Expression) {
let model = &self.model;
@ -754,7 +764,7 @@ impl Area {
);
frp.source.tp <+ final_tp;
self.frp.source.on_port_type_change <+ frp.tp.map(move |t|(crumbs.clone(),t.clone()));
self.frp.private.output.on_port_type_change <+ frp.tp.map(move |t|(crumbs.clone(),t.clone()));
}
@ -864,7 +874,7 @@ impl Area {
Some(frp.tp.clone_ref().into())
});
self.frp.source.view_mode.emit(self.frp.view_mode.value());
self.frp.private.output.view_mode.emit(self.frp.view_mode.value());
}
/// This function first assigns the new expression to the model and then emits the definition
@ -875,6 +885,7 @@ impl Area {
/// For example, firing the `port::set_definition_type` will fire `on_port_type_change`, which
/// may require some edges to re-color, which consequently will require to checking the current
/// expression types.
#[profile(Debug)]
fn init_new_expression(&self, expression: Expression) {
*self.model.expression.borrow_mut() = expression;
let expression = self.model.expression.borrow();
@ -883,6 +894,7 @@ impl Area {
});
}
#[profile(Debug)]
pub(crate) fn set_expression(&self, new_expression: impl Into<node::Expression>) {
let mut new_expression = Expression::from(new_expression.into());
if DEBUG {

View File

@ -175,6 +175,7 @@ impl Model {
/// as some are skipped. For example, given the expression `(((foo)))`, the inner parentheses
/// will be skipped, as there is no point in making them ports. The skip algorithm is
/// implemented as part of the port are initialization.
#[profile(Debug)]
pub fn init_shape(
&mut self,
logger: impl AnyLogger,

View File

@ -8,11 +8,13 @@ use crate::component::node::input;
use crate::component::node::output::port;
use crate::tooltip;
use crate::view;
use crate::FrpNetworkProvider;
use crate::Type;
use enso_config::ARGS;
use enso_frp as frp;
use enso_frp;
use enso_frp::stream::ValueProvider;
use ensogl::animation::hysteretic::HystereticAnimation;
use ensogl::application::Application;
use ensogl::data::color;
@ -120,7 +122,7 @@ impl From<node::Expression> for Expression {
// === Model ===
// =============
ensogl::define_endpoints! {
ensogl::define_endpoints_2! {
Input {
set_size (Vector2),
set_hover (bool),
@ -161,11 +163,12 @@ pub struct Model {
port_count: Cell<usize>,
styles: StyleWatch,
styles_frp: StyleWatchFrp,
frp: FrpEndpoints,
frp: Rc<api::Private>,
}
impl Model {
/// Constructor.
#[profile(Debug)]
pub fn new(logger: impl AnyLogger, app: &Application, frp: &Frp) -> Self {
let logger = Logger::new_sub(&logger, "output_ports");
let display_object = display::object::Instance::new(&logger);
@ -177,7 +180,7 @@ impl Model {
let port_count = default();
let styles = StyleWatch::new(&app.display.default_scene.style_sheet);
let styles_frp = StyleWatchFrp::new(&app.display.default_scene.style_sheet);
let frp = frp.output.clone_ref();
let frp = frp.private.clone_ref();
display_object.add_child(&label);
display_object.add_child(&ports);
Self {
@ -196,6 +199,7 @@ impl Model {
.init()
}
#[profile(Debug)]
fn init(self) -> Self {
// FIXME[WD]: Depth sorting of labels to in front of the mouse pointer. Temporary solution.
// It needs to be more flexible once we have proper depth management.
@ -228,10 +232,12 @@ impl Model {
ports
}
#[profile(Debug)]
fn set_label_layer(&self, layer: &display::scene::Layer) {
self.label.add_to_scene_layer(layer);
}
#[profile(Debug)]
fn set_label(&self, content: impl Into<String>) {
let str = if ARGS.node_labels.unwrap_or(true) { content.into() } else { default() };
self.label.set_content(str);
@ -239,6 +245,7 @@ impl Model {
}
/// Update expression type for the particular `ast::Id`.
#[profile(Debug)]
fn set_expression_usage_type(&self, crumbs: &Crumbs, tp: &Option<Type>) {
if let Ok(port) = self.expression.borrow().span_tree.root_ref().get_descendant(crumbs) {
if let Some(frp) = &port.frp {
@ -249,6 +256,7 @@ impl Model {
/// Traverse all span tree nodes that are considered ports. In case of empty span tree, include
/// its root as the port as well.
#[profile(Debug)]
fn traverse_borrowed_expression_mut(
&self,
mut f: impl FnMut(bool, &mut PortRefMut, &mut PortLayerBuilder),
@ -262,6 +270,7 @@ impl Model {
/// Traverse all span tree nodes that are considered ports. In case of empty span tree, include
/// its root as the port as well.
#[profile(Debug)]
fn traverse_borrowed_expression(
&self,
mut f: impl FnMut(bool, &PortRef, &mut PortLayerBuilder),
@ -274,6 +283,7 @@ impl Model {
}
/// Traverse all span tree nodes that are considered ports.
#[profile(Debug)]
fn traverse_borrowed_expression_raw_mut(
&self,
mut f: impl FnMut(bool, &mut PortRefMut, &mut PortLayerBuilder),
@ -293,6 +303,7 @@ impl Model {
}
/// Traverse all span tree nodes that are considered ports.
#[profile(Debug)]
fn traverse_borrowed_expression_raw(
&self,
mut f: impl FnMut(bool, &PortRef, &mut PortLayerBuilder),
@ -318,6 +329,7 @@ impl Model {
count
}
#[profile(Debug)]
fn set_size(&self, size: Vector2) {
self.ports.set_position_x(size.x / 2.0);
self.traverse_borrowed_expression_mut(|is_a_port, node, _| {
@ -327,10 +339,12 @@ impl Model {
})
}
#[profile(Debug)]
fn set_label_on_new_expression(&self, expression: &Expression) {
self.set_label(expression.code());
}
#[profile(Debug)]
fn build_port_shapes_on_new_expression(&self) {
let mut port_index = 0;
let mut id_crumbs_map = HashMap::new();
@ -359,19 +373,19 @@ impl Model {
let port_network = &port_frp.network;
frp::extend! { port_network
self.frp.source.on_port_hover <+ port_frp.on_hover.map
self.frp.output.on_port_hover <+ port_frp.on_hover.map
(f!([crumbs](t) Switch::new(crumbs.clone(),*t)));
self.frp.source.on_port_press <+ port_frp.on_press.constant(crumbs.clone());
self.frp.output.on_port_press <+ port_frp.on_press.constant(crumbs.clone());
port_frp.set_size_multiplier <+ self.frp.port_size_multiplier;
self.frp.source.on_port_type_change <+ port_frp.tp.map(move |t|(crumbs.clone(),t.clone()));
port_frp.set_type_label_visibility <+ self.frp.type_label_visibility;
self.frp.source.tooltip <+ port_frp.tooltip;
port_frp.set_view_mode <+ self.frp.view_mode;
port_frp.set_size_multiplier <+ self.frp.output.port_size_multiplier;
self.frp.output.on_port_type_change <+ port_frp.tp.map(move |t|(crumbs.clone(),t.clone()));
port_frp.set_type_label_visibility <+ self.frp.output.type_label_visibility;
self.frp.output.tooltip <+ port_frp.tooltip;
port_frp.set_view_mode <+ self.frp.output.view_mode;
}
port_frp.set_type_label_visibility.emit(self.frp.type_label_visibility.value());
port_frp.set_view_mode.emit(self.frp.view_mode.value());
port_frp.set_type_label_visibility.emit(self.frp.output.type_label_visibility.value());
port_frp.set_view_mode.emit(self.frp.output.view_mode.value());
self.ports.add_child(&port_shape);
port_index += 1;
}
@ -379,6 +393,7 @@ impl Model {
*self.id_crumbs_map.borrow_mut() = id_crumbs_map;
}
#[profile(Debug)]
fn init_definition_types(&self) {
let port_count = self.port_count.get();
let whole_expr_type = self.expression.borrow().whole_expr_type.clone();
@ -399,6 +414,7 @@ impl Model {
}
}
#[profile(Debug)]
fn set_expression(&self, new_expression: impl Into<node::Expression>) {
let new_expression = Expression::from(new_expression.into());
if DEBUG {
@ -452,7 +468,7 @@ impl Area {
pub fn new(logger: impl AnyLogger, app: &Application) -> Self {
let frp = Frp::new();
let model = Rc::new(Model::new(logger, app, &frp));
let network = &frp.network;
let network = &frp.network();
let label_color = color::Animation::new(network);
let hysteretic_transition =
@ -468,10 +484,10 @@ impl Area {
hysteretic_transition.to_start <+ on_hover_in;
hysteretic_transition.to_end <+ on_hover_out;
frp.source.port_size_multiplier <+ hysteretic_transition.value;
frp.private.output.port_size_multiplier <+ hysteretic_transition.value;
eval frp.set_size ((t) model.set_size(*t));
frp.source.type_label_visibility <+ frp.set_type_label_visibility;
frp.private.output.type_label_visibility <+ frp.set_type_label_visibility;
// === Expression ===
@ -482,12 +498,12 @@ impl Area {
// === Label Color ===
port_hover <- frp.on_port_hover.map(|t| t.is_on());
frp.source.body_hover <+ frp.set_hover || port_hover;
port_hover <- frp.output.on_port_hover.map(|t| t.is_on());
frp.private.output.body_hover <+ frp.set_hover || port_hover;
expr_vis <- frp.body_hover || frp.set_expression_visibility;
in_normal_mode <- frp.set_view_mode.map(|m| m.is_normal());
expr_vis <- expr_vis && in_normal_mode;
frp.source.expression_label_visibility <+ expr_vis;
frp.private.output.expression_label_visibility <+ expr_vis;
let label_vis_color = color::Lcha::from(model.styles.get_color(theme::graph_editor::node::text));
let label_vis_alpha = label_vis_color.alpha;
@ -500,7 +516,7 @@ impl Area {
// === View Mode ===
frp.source.view_mode <+ frp.set_view_mode;
frp.private.output.view_mode <+ frp.set_view_mode;
}
label_color.target_alpha(0.0);

View File

@ -364,9 +364,9 @@
"integrity": "sha512-kbMawY0WRPyL/lbknBkme4CNLl+Gw+E9G4OpNeXAauqoQiNkBgpIvZYy7BRT4sNGhZbxdxXxXbruqUwDzLmvTw=="
},
"node_modules/@firebase/analytics/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/@firebase/app": {
"version": "0.6.30",
@ -410,9 +410,9 @@
"integrity": "sha512-KJ+BqJbdNsx4QT/JIT1yDj5p6D+QN97iJs3GuHnORrqL+DU3RWc9nSYQsrY6Tv9jVWcOkMENXAgDT484vzsm2w=="
},
"node_modules/@firebase/app-check/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/@firebase/app-types": {
"version": "0.6.3",
@ -420,9 +420,9 @@
"integrity": "sha512-/M13DPPati7FQHEQ9Minjk1HGLm/4K4gs9bR4rzLCWJg64yGtVC0zNg9gDpkw9yc2cvol/mNFxqTtd4geGrwdw=="
},
"node_modules/@firebase/app/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/@firebase/auth": {
"version": "0.16.8",
@ -463,9 +463,9 @@
}
},
"node_modules/@firebase/component/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/@firebase/database": {
"version": "0.11.0",
@ -502,9 +502,9 @@
}
},
"node_modules/@firebase/database/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/@firebase/firestore": {
"version": "2.4.1",
@ -539,9 +539,9 @@
}
},
"node_modules/@firebase/firestore/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/@firebase/functions": {
"version": "0.6.16",
@ -565,9 +565,9 @@
"integrity": "sha512-3KElyO3887HNxtxNF1ytGFrNmqD+hheqjwmT3sI09FaDCuaxGbOnsXAXH2eQ049XRXw9YQpHMgYws/aUNgXVyQ=="
},
"node_modules/@firebase/functions/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/@firebase/installations": {
"version": "0.4.32",
@ -594,9 +594,9 @@
}
},
"node_modules/@firebase/installations/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/@firebase/logger": {
"version": "0.2.6",
@ -629,9 +629,9 @@
}
},
"node_modules/@firebase/messaging/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/@firebase/performance": {
"version": "0.4.18",
@ -656,9 +656,9 @@
"integrity": "sha512-6fZfIGjQpwo9S5OzMpPyqgYAUZcFzZxHFqOyNtorDIgNXq33nlldTL/vtaUZA8iT9TT5cJlCrF/jthKU7X21EA=="
},
"node_modules/@firebase/performance/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/@firebase/polyfill": {
"version": "0.3.36",
@ -693,9 +693,9 @@
"integrity": "sha512-G96qnF3RYGbZsTRut7NBX0sxyczxt1uyCgXQuH/eAfUCngxjEGcZQnBdy6mvSdqdJh5mC31rWPO4v9/s7HwtzA=="
},
"node_modules/@firebase/remote-config/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/@firebase/storage": {
"version": "0.7.1",
@ -723,9 +723,9 @@
}
},
"node_modules/@firebase/storage/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/@firebase/util": {
"version": "1.3.0",
@ -736,9 +736,9 @@
}
},
"node_modules/@firebase/util/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/@firebase/webchannel-wrapper": {
"version": "0.5.1",
@ -746,9 +746,9 @@
"integrity": "sha512-dZMzN0uAjwJXWYYAcnxIwXqRTZw3o14hGe7O6uhwjD1ZQWPVYA5lASgnNskEBra0knVBsOXB4KXg+HnlKewN/A=="
},
"node_modules/@grpc/grpc-js": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.6.tgz",
"integrity": "sha512-gEMn1+d01yO/QNHsDOPHxJYtA6QItbdQT4mGFS8Gt5IQCq+83OEsD0sbvPf3RLCtHy1HI412JgQPr5HM9QK0mw==",
"version": "1.6.7",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.7.tgz",
"integrity": "sha512-eBM03pu9hd3VqDQG+kHahiG1x80RGkkqqRb1Pchcwqej/KkAH95gAvKs6laqaHCycYaPK+TKuNQnOz9UXYA8qw==",
"dependencies": {
"@grpc/proto-loader": "^0.6.4",
"@types/node": ">=12.12.47"
@ -758,9 +758,9 @@
}
},
"node_modules/@grpc/proto-loader": {
"version": "0.6.9",
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.9.tgz",
"integrity": "sha512-UlcCS8VbsU9d3XTXGiEVFonN7hXk+oMXZtoHHG2oSA1/GcDP1q6OUgs20PzHDGizzyi8ufGSUDlk3O2NyY7leg==",
"version": "0.6.12",
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.12.tgz",
"integrity": "sha512-filTVbETFnxb9CyRX98zN18ilChTuf/C5scZ2xyaOTp0EHGq0/ufX8rjqXUcSb1Gpv7eZq4M2jDvbh9BogKnrg==",
"dependencies": {
"@types/long": "^4.0.1",
"lodash.camelcase": "^4.3.0",
@ -2454,9 +2454,9 @@
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ=="
},
"node_modules/@types/long": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
"integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
"integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
},
"node_modules/@types/minimatch": {
"version": "3.0.3",
@ -2935,9 +2935,9 @@
"integrity": "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA=="
},
"node_modules/app-builder-lib": {
"version": "23.0.6",
"resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-23.0.6.tgz",
"integrity": "sha512-CmDyNldqqt7hMNV3EaHCPeml4iCqBZPXBOEq0M1j9KkBHPMXnQzoYECq2IQ3xv4PxADEqMeVAt/W2iAXBy4v5Q==",
"version": "23.0.8",
"resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-23.0.8.tgz",
"integrity": "sha512-IObTdRc/0TQsfGn9IvaEXULE/QacgyFgpz3+vmlpZgHHjQ6V1c/T4pKlzNTsNHGjJBuEg2FvTvYi9ZVFfhyWow==",
"dependencies": {
"@develar/schema-utils": "~2.6.5",
"@electron/universal": "1.2.1",
@ -2945,24 +2945,25 @@
"7zip-bin": "~5.1.1",
"async-exit-hook": "^2.0.1",
"bluebird-lst": "^1.0.9",
"builder-util": "23.0.6",
"builder-util-runtime": "9.0.1",
"builder-util": "23.0.8",
"builder-util-runtime": "9.0.2",
"chromium-pickle-js": "^0.2.0",
"debug": "^4.3.2",
"ejs": "^3.1.6",
"debug": "^4.3.4",
"ejs": "^3.1.7",
"electron-osx-sign": "^0.6.0",
"electron-publish": "23.0.6",
"electron-publish": "23.0.8",
"form-data": "^4.0.0",
"fs-extra": "^10.0.0",
"hosted-git-info": "^4.0.2",
"fs-extra": "^10.1.0",
"hosted-git-info": "^4.1.0",
"is-ci": "^3.0.0",
"isbinaryfile": "^4.0.8",
"isbinaryfile": "^4.0.10",
"js-yaml": "^4.1.0",
"lazy-val": "^1.0.5",
"minimatch": "^3.0.4",
"minimatch": "^3.1.2",
"read-config-file": "6.2.0",
"sanitize-filename": "^1.6.3",
"semver": "^7.3.5",
"semver": "^7.3.7",
"tar": "^6.1.11",
"temp-file": "^3.4.0"
},
"engines": {
@ -4055,19 +4056,19 @@
}
},
"node_modules/builder-util": {
"version": "23.0.6",
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-23.0.6.tgz",
"integrity": "sha512-xV6JmZmHvpeUtsJNKDoKTefFLo9LRPnm4ii3ckRQe39BNu0nDyfpRLhici7KqnRxBdMSpIVIfayJX9syN+7zDw==",
"version": "23.0.8",
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-23.0.8.tgz",
"integrity": "sha512-xPpnoLLAEPx5oxxzRFINRnxmLNQDn+FddU7QRvCJDQi0jvUJ7UjdoGoM+UPy9yh+p9O82/nC7MHGuUptJkOXyQ==",
"dependencies": {
"@types/debug": "^4.1.6",
"@types/fs-extra": "^9.0.11",
"7zip-bin": "~5.1.1",
"app-builder-bin": "4.0.0",
"bluebird-lst": "^1.0.9",
"builder-util-runtime": "9.0.1",
"builder-util-runtime": "9.0.2",
"chalk": "^4.1.1",
"cross-spawn": "^7.0.3",
"debug": "^4.3.2",
"debug": "^4.3.4",
"fs-extra": "^10.0.0",
"http-proxy-agent": "^5.0.0",
"https-proxy-agent": "^5.0.0",
@ -4079,11 +4080,11 @@
}
},
"node_modules/builder-util-runtime": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.0.1.tgz",
"integrity": "sha512-f9pjsGKjGaLWqYwIn11Lxc2YL0g8UnnxWECOS9GubCRNYWnqMz1ZjwwCedOUKk2UlD2J7zyVKJcCMt9v/pP/uQ==",
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.0.2.tgz",
"integrity": "sha512-xF55W/8mgfT6+sMbX0TeiJkTusA5GMOzckM4rajN4KirFcUIuLTH8oEaTYmM86YwVCZaTwa/7GyFhauXaEICwA==",
"dependencies": {
"debug": "^4.3.2",
"debug": "^4.3.4",
"sax": "^1.2.4"
},
"engines": {
@ -4533,9 +4534,9 @@
}
},
"node_modules/camel-case/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/camelcase": {
"version": "5.3.1",
@ -5022,9 +5023,9 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"node_modules/color-string": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz",
"integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==",
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
"dependencies": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
@ -6497,6 +6498,17 @@
"node": ">= 0.6.x"
}
},
"node_modules/dir-compare/node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/dir-glob": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
@ -6509,19 +6521,19 @@
}
},
"node_modules/dmg-builder": {
"version": "23.0.6",
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-23.0.6.tgz",
"integrity": "sha512-+2Wp3wDLAuj7qEBwqD9AssF68Uz3U0cwfvsz1qODKW1GBBEu/6X2LQUs4oDIdoIVpkai660+zyPok6f3DMfcSw==",
"version": "23.0.8",
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-23.0.8.tgz",
"integrity": "sha512-dXguxjekxY70hzgAW+0NPCI7bagQ2ZrLDwYf1bvHSwlVfVizyJ/EC+e71U/NUgiWlXU5nogbWcGC3H74mFu0iw==",
"dependencies": {
"app-builder-lib": "23.0.6",
"builder-util": "23.0.6",
"builder-util-runtime": "9.0.1",
"app-builder-lib": "23.0.8",
"builder-util": "23.0.8",
"builder-util-runtime": "9.0.2",
"fs-extra": "^10.0.0",
"iconv-lite": "^0.6.2",
"js-yaml": "^4.1.0"
},
"optionalDependencies": {
"dmg-license": "^1.0.9"
"dmg-license": "^1.0.11"
}
},
"node_modules/dmg-builder/node_modules/argparse": {
@ -6734,9 +6746,9 @@
}
},
"node_modules/dot-case/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/dot-prop": {
"version": "4.2.1",
@ -6809,11 +6821,11 @@
"dev": true
},
"node_modules/ejs": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
"integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.7.tgz",
"integrity": "sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==",
"dependencies": {
"jake": "^10.6.1"
"jake": "^10.8.5"
},
"bin": {
"ejs": "bin/cli.js"
@ -6840,16 +6852,16 @@
}
},
"node_modules/electron-builder": {
"version": "23.0.6",
"resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-23.0.6.tgz",
"integrity": "sha512-VA50mfjjsoEQ5DHwgT61CGua6F337phNYPumMXkcedfjpAS82H23H2hnu75E77m6zf0wRNGVj9o7Z3rYpwyXlg==",
"version": "23.0.8",
"resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-23.0.8.tgz",
"integrity": "sha512-7WxdR4+l+VL4QN/K6NdqRQg7+cbIka4By1+4eN8odMPySSTI5d6nrV8R+SSRt9MXeWVdWlW8RCX5Pk6L0oaRug==",
"dependencies": {
"@types/yargs": "^17.0.1",
"app-builder-lib": "23.0.6",
"builder-util": "23.0.6",
"builder-util-runtime": "9.0.1",
"app-builder-lib": "23.0.8",
"builder-util": "23.0.8",
"builder-util-runtime": "9.0.2",
"chalk": "^4.1.1",
"dmg-builder": "23.0.6",
"dmg-builder": "23.0.8",
"fs-extra": "^10.0.0",
"is-ci": "^3.0.0",
"lazy-val": "^1.0.5",
@ -7176,13 +7188,13 @@
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"node_modules/electron-publish": {
"version": "23.0.6",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-23.0.6.tgz",
"integrity": "sha512-ikjgf93uHKyjfTIxVBs3jrDY3x2C06c7Vbq7QDMIQnvMWUqZd1mNTqWUBAr1IQfwX5xvapsWxAJ5TF/Ops5KLg==",
"version": "23.0.8",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-23.0.8.tgz",
"integrity": "sha512-GnqJH7Wh8LnapN4npl1Xs2Er/486/qxE3dV42WxXHX2VeoKAJTOuCzOVWCxpajaR3Msji4SkS0p81R018uK6Mg==",
"dependencies": {
"@types/fs-extra": "^9.0.11",
"builder-util": "23.0.6",
"builder-util-runtime": "9.0.1",
"builder-util": "23.0.8",
"builder-util-runtime": "9.0.2",
"chalk": "^4.1.1",
"fs-extra": "^10.0.0",
"lazy-val": "^1.0.5",
@ -11350,9 +11362,9 @@
}
},
"node_modules/lower-case/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/lowercase-keys": {
"version": "1.0.1",
@ -11899,9 +11911,9 @@
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
},
"node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@ -12264,9 +12276,9 @@
}
},
"node_modules/no-case/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/node-abi": {
"version": "3.15.0",
@ -13287,9 +13299,9 @@
}
},
"node_modules/param-case/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/parse-asn1": {
"version": "5.1.6",
@ -13424,9 +13436,9 @@
}
},
"node_modules/pascal-case/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/pascalcase": {
"version": "0.1.1",
@ -16706,9 +16718,9 @@
}
},
"node_modules/ts-loader": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.3.0.tgz",
"integrity": "sha512-MgGly4I6cStsJy27ViE32UoqxPTN9Xly4anxxVyaIWR+9BGxboV4EyJBGfR3RePV7Ksjj3rHmPZJeIt+7o4Vag==",
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.4.0.tgz",
"integrity": "sha512-6nFY3IZ2//mrPc+ImY3hNWx1vCHyEhl6V+wLmL4CZcm6g1CqX7UKrkc6y0i4FwcfOhxyMPCfaEvh20f4r9GNpw==",
"dependencies": {
"chalk": "^4.1.0",
"enhanced-resolve": "^4.0.0",
@ -19088,9 +19100,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -19114,9 +19126,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -19134,9 +19146,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -19185,9 +19197,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -19214,9 +19226,9 @@
}
},
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -19246,9 +19258,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -19271,9 +19283,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -19295,9 +19307,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -19326,9 +19338,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -19352,9 +19364,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -19387,9 +19399,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -19411,9 +19423,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -19432,9 +19444,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -19444,18 +19456,18 @@
"integrity": "sha512-dZMzN0uAjwJXWYYAcnxIwXqRTZw3o14hGe7O6uhwjD1ZQWPVYA5lASgnNskEBra0knVBsOXB4KXg+HnlKewN/A=="
},
"@grpc/grpc-js": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.6.tgz",
"integrity": "sha512-gEMn1+d01yO/QNHsDOPHxJYtA6QItbdQT4mGFS8Gt5IQCq+83OEsD0sbvPf3RLCtHy1HI412JgQPr5HM9QK0mw==",
"version": "1.6.7",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.7.tgz",
"integrity": "sha512-eBM03pu9hd3VqDQG+kHahiG1x80RGkkqqRb1Pchcwqej/KkAH95gAvKs6laqaHCycYaPK+TKuNQnOz9UXYA8qw==",
"requires": {
"@grpc/proto-loader": "^0.6.4",
"@types/node": ">=12.12.47"
}
},
"@grpc/proto-loader": {
"version": "0.6.9",
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.9.tgz",
"integrity": "sha512-UlcCS8VbsU9d3XTXGiEVFonN7hXk+oMXZtoHHG2oSA1/GcDP1q6OUgs20PzHDGizzyi8ufGSUDlk3O2NyY7leg==",
"version": "0.6.12",
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.12.tgz",
"integrity": "sha512-filTVbETFnxb9CyRX98zN18ilChTuf/C5scZ2xyaOTp0EHGq0/ufX8rjqXUcSb1Gpv7eZq4M2jDvbh9BogKnrg==",
"requires": {
"@types/long": "^4.0.1",
"lodash.camelcase": "^4.3.0",
@ -20879,9 +20891,9 @@
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ=="
},
"@types/long": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
"integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
"integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
},
"@types/minimatch": {
"version": "3.0.3",
@ -21300,9 +21312,9 @@
"integrity": "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA=="
},
"app-builder-lib": {
"version": "23.0.6",
"resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-23.0.6.tgz",
"integrity": "sha512-CmDyNldqqt7hMNV3EaHCPeml4iCqBZPXBOEq0M1j9KkBHPMXnQzoYECq2IQ3xv4PxADEqMeVAt/W2iAXBy4v5Q==",
"version": "23.0.8",
"resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-23.0.8.tgz",
"integrity": "sha512-IObTdRc/0TQsfGn9IvaEXULE/QacgyFgpz3+vmlpZgHHjQ6V1c/T4pKlzNTsNHGjJBuEg2FvTvYi9ZVFfhyWow==",
"requires": {
"@develar/schema-utils": "~2.6.5",
"@electron/universal": "1.2.1",
@ -21310,24 +21322,25 @@
"7zip-bin": "~5.1.1",
"async-exit-hook": "^2.0.1",
"bluebird-lst": "^1.0.9",
"builder-util": "23.0.6",
"builder-util-runtime": "9.0.1",
"builder-util": "23.0.8",
"builder-util-runtime": "9.0.2",
"chromium-pickle-js": "^0.2.0",
"debug": "^4.3.2",
"ejs": "^3.1.6",
"debug": "^4.3.4",
"ejs": "^3.1.7",
"electron-osx-sign": "^0.6.0",
"electron-publish": "23.0.6",
"electron-publish": "23.0.8",
"form-data": "^4.0.0",
"fs-extra": "^10.0.0",
"hosted-git-info": "^4.0.2",
"fs-extra": "^10.1.0",
"hosted-git-info": "^4.1.0",
"is-ci": "^3.0.0",
"isbinaryfile": "^4.0.8",
"isbinaryfile": "^4.0.10",
"js-yaml": "^4.1.0",
"lazy-val": "^1.0.5",
"minimatch": "^3.0.4",
"minimatch": "^3.1.2",
"read-config-file": "6.2.0",
"sanitize-filename": "^1.6.3",
"semver": "^7.3.5",
"semver": "^7.3.7",
"tar": "^6.1.11",
"temp-file": "^3.4.0"
},
"dependencies": {
@ -22193,19 +22206,19 @@
"integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s="
},
"builder-util": {
"version": "23.0.6",
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-23.0.6.tgz",
"integrity": "sha512-xV6JmZmHvpeUtsJNKDoKTefFLo9LRPnm4ii3ckRQe39BNu0nDyfpRLhici7KqnRxBdMSpIVIfayJX9syN+7zDw==",
"version": "23.0.8",
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-23.0.8.tgz",
"integrity": "sha512-xPpnoLLAEPx5oxxzRFINRnxmLNQDn+FddU7QRvCJDQi0jvUJ7UjdoGoM+UPy9yh+p9O82/nC7MHGuUptJkOXyQ==",
"requires": {
"@types/debug": "^4.1.6",
"@types/fs-extra": "^9.0.11",
"7zip-bin": "~5.1.1",
"app-builder-bin": "4.0.0",
"bluebird-lst": "^1.0.9",
"builder-util-runtime": "9.0.1",
"builder-util-runtime": "9.0.2",
"chalk": "^4.1.1",
"cross-spawn": "^7.0.3",
"debug": "^4.3.2",
"debug": "^4.3.4",
"fs-extra": "^10.0.0",
"http-proxy-agent": "^5.0.0",
"https-proxy-agent": "^5.0.0",
@ -22383,11 +22396,11 @@
}
},
"builder-util-runtime": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.0.1.tgz",
"integrity": "sha512-f9pjsGKjGaLWqYwIn11Lxc2YL0g8UnnxWECOS9GubCRNYWnqMz1ZjwwCedOUKk2UlD2J7zyVKJcCMt9v/pP/uQ==",
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.0.2.tgz",
"integrity": "sha512-xF55W/8mgfT6+sMbX0TeiJkTusA5GMOzckM4rajN4KirFcUIuLTH8oEaTYmM86YwVCZaTwa/7GyFhauXaEICwA==",
"requires": {
"debug": "^4.3.2",
"debug": "^4.3.4",
"sax": "^1.2.4"
},
"dependencies": {
@ -22557,9 +22570,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -22957,9 +22970,9 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"color-string": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz",
"integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==",
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
"requires": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
@ -24165,6 +24178,14 @@
"requires": {
"graceful-readlink": ">= 1.0.0"
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
"brace-expansion": "^1.1.7"
}
}
}
},
@ -24177,14 +24198,14 @@
}
},
"dmg-builder": {
"version": "23.0.6",
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-23.0.6.tgz",
"integrity": "sha512-+2Wp3wDLAuj7qEBwqD9AssF68Uz3U0cwfvsz1qODKW1GBBEu/6X2LQUs4oDIdoIVpkai660+zyPok6f3DMfcSw==",
"version": "23.0.8",
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-23.0.8.tgz",
"integrity": "sha512-dXguxjekxY70hzgAW+0NPCI7bagQ2ZrLDwYf1bvHSwlVfVizyJ/EC+e71U/NUgiWlXU5nogbWcGC3H74mFu0iw==",
"requires": {
"app-builder-lib": "23.0.6",
"builder-util": "23.0.6",
"builder-util-runtime": "9.0.1",
"dmg-license": "^1.0.9",
"app-builder-lib": "23.0.8",
"builder-util": "23.0.8",
"builder-util-runtime": "9.0.2",
"dmg-license": "^1.0.11",
"fs-extra": "^10.0.0",
"iconv-lite": "^0.6.2",
"js-yaml": "^4.1.0"
@ -24348,9 +24369,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -24419,11 +24440,11 @@
"dev": true
},
"ejs": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
"integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.7.tgz",
"integrity": "sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==",
"requires": {
"jake": "^10.6.1"
"jake": "^10.8.5"
}
},
"electron": {
@ -24437,16 +24458,16 @@
}
},
"electron-builder": {
"version": "23.0.6",
"resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-23.0.6.tgz",
"integrity": "sha512-VA50mfjjsoEQ5DHwgT61CGua6F337phNYPumMXkcedfjpAS82H23H2hnu75E77m6zf0wRNGVj9o7Z3rYpwyXlg==",
"version": "23.0.8",
"resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-23.0.8.tgz",
"integrity": "sha512-7WxdR4+l+VL4QN/K6NdqRQg7+cbIka4By1+4eN8odMPySSTI5d6nrV8R+SSRt9MXeWVdWlW8RCX5Pk6L0oaRug==",
"requires": {
"@types/yargs": "^17.0.1",
"app-builder-lib": "23.0.6",
"builder-util": "23.0.6",
"builder-util-runtime": "9.0.1",
"app-builder-lib": "23.0.8",
"builder-util": "23.0.8",
"builder-util-runtime": "9.0.2",
"chalk": "^4.1.1",
"dmg-builder": "23.0.6",
"dmg-builder": "23.0.8",
"fs-extra": "^10.0.0",
"is-ci": "^3.0.0",
"lazy-val": "^1.0.5",
@ -24690,13 +24711,13 @@
}
},
"electron-publish": {
"version": "23.0.6",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-23.0.6.tgz",
"integrity": "sha512-ikjgf93uHKyjfTIxVBs3jrDY3x2C06c7Vbq7QDMIQnvMWUqZd1mNTqWUBAr1IQfwX5xvapsWxAJ5TF/Ops5KLg==",
"version": "23.0.8",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-23.0.8.tgz",
"integrity": "sha512-GnqJH7Wh8LnapN4npl1Xs2Er/486/qxE3dV42WxXHX2VeoKAJTOuCzOVWCxpajaR3Msji4SkS0p81R018uK6Mg==",
"requires": {
"@types/fs-extra": "^9.0.11",
"builder-util": "23.0.6",
"builder-util-runtime": "9.0.1",
"builder-util": "23.0.8",
"builder-util-runtime": "9.0.2",
"chalk": "^4.1.1",
"fs-extra": "^10.0.0",
"lazy-val": "^1.0.5",
@ -27964,9 +27985,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -28386,9 +28407,9 @@
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"requires": {
"brace-expansion": "^1.1.7"
}
@ -28700,9 +28721,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -29515,9 +29536,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -29638,9 +29659,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
}
}
},
@ -32252,9 +32273,9 @@
}
},
"ts-loader": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.3.0.tgz",
"integrity": "sha512-MgGly4I6cStsJy27ViE32UoqxPTN9Xly4anxxVyaIWR+9BGxboV4EyJBGfR3RePV7Ksjj3rHmPZJeIt+7o4Vag==",
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.4.0.tgz",
"integrity": "sha512-6nFY3IZ2//mrPc+ImY3hNWx1vCHyEhl6V+wLmL4CZcm6g1CqX7UKrkc6y0i4FwcfOhxyMPCfaEvh20f4r9GNpw==",
"requires": {
"chalk": "^4.1.0",
"enhanced-resolve": "^4.0.0",

View File

@ -207,7 +207,7 @@ commands.build.rust = async function (argv) {
console.log('Minimizing the WASM binary.')
await gzip(paths.wasm.main, paths.wasm.mainGz)
const releaseLimitMb = 4.25
const releaseLimitMb = 4.36
let limitMb = releaseLimitMb + allowExtraMb
await checkWasmSize(paths.wasm.mainGz, limitMb)
}

View File

@ -642,6 +642,7 @@ impl AreaModel {
fn on_modified_selection(&self, _: &buffer::selection::Group, _: f32, _: bool) {}
#[cfg(target_arch = "wasm32")]
#[profile(Debug)]
fn on_modified_selection(
&self,
selections: &buffer::selection::Group,
@ -753,6 +754,7 @@ impl AreaModel {
Location(line, column)
}
#[profile(Debug)]
fn init(self) -> Self {
self.redraw(true);
self
@ -1010,6 +1012,8 @@ impl AreaModel {
selection.with_start(start).with_end(end)
}
#[cfg(target_arch = "wasm32")]
#[profile(Debug)]
#[cfg(target_arch = "wasm32")]
fn set_font(&self, font_name: &str) {
let app = &self.app;
@ -1143,3 +1147,22 @@ impl Drop for Area {
self.remove_all_cursors();
}
}
#[cfg(test)]
mod tests {
use super::*;
/// Assert that there is no inherent memory leak in the [text::Area].
#[test]
fn assert_no_leak() {
let app = Application::new("root");
let text = app.new_view::<Area>();
let text_frp = Rc::downgrade(&text.frp);
let text_data = Rc::downgrade(&text.data);
drop(text);
assert_eq!(text_frp.strong_count(), 0, "There are FRP references left.");
assert_eq!(text_data.strong_count(), 0, "There are data references left.");
}
}

View File

@ -60,11 +60,13 @@ impl Collector {
/// The collector is designed to handle EnsoGL component's FRP networks and models, but any
/// structure with static timeline may be put. See [`Collector`] docs for information when
/// the object will be finally dropped.
#[profile(Debug)]
pub fn collect<T: 'static>(&self, object: T) {
self.garbage.borrow_mut().before_pixel_sync.push(Box::new(object));
}
/// Pixel value requested (the points 1 and 2 in [`Collector`] docs).
#[profile(Debug)]
pub fn pixel_synced(&self) {
let mut garbage = self.garbage.borrow_mut();
let objects_being_moved = std::mem::take(&mut garbage.before_pixel_sync);
@ -72,6 +74,7 @@ impl Collector {
}
/// Pixel value retrieved (the point 3 in [`Collector`] docs).
#[profile(Debug)]
pub fn pixel_updated(&self) {
let mut garbage = self.garbage.borrow_mut();
let objects_being_moved = std::mem::take(&mut garbage.before_pixel_update);
@ -79,6 +82,7 @@ impl Collector {
}
/// Mouse events handled (the point 4 in [`Collector`] docs).
#[profile(Debug)]
pub fn mouse_events_handled(&self) {
let mut garbage = self.garbage.borrow_mut();
drop(std::mem::take(&mut garbage.before_mouse_events));

View File

@ -459,6 +459,7 @@ macro_rules! _define_shape_system {
type StaticShape = Shape;
type System = ShapeSystem;
#[profile(Debug)]
fn new(logger:impl AnyLogger) -> Self {
let logger : Logger = Logger::new_sub(&logger,"dyn_shape");
let display_object = display::object::Instance::new(&logger);
@ -477,6 +478,7 @@ macro_rules! _define_shape_system {
}
impl display::shape::system::DynamicShapeInternals for DynamicShape {
#[profile(Debug)]
fn add_instance(&self, shape:Shape) {
self.display_object.add_child(&shape);
self.params.size.add_attribute_binding(shape.sprite.size.clone_ref());
@ -487,6 +489,7 @@ macro_rules! _define_shape_system {
self.shapes.borrow_mut().push(shape);
}
#[profile(Debug)]
fn drop_instances(&self) {
for shape in mem::take(&mut *self.shapes.borrow_mut()) {
self.display_object.remove_child(&shape);
@ -539,6 +542,7 @@ macro_rules! _define_shape_system {
std::any::TypeId::of::<ShapeSystem>().into()
}
#[profile(Debug)]
fn new(scene:&display::scene::Scene) -> Self {
let style_watch = display::shape::StyleWatch::new(&scene.style_sheet);
let shape_def = Self::shape_def(&style_watch);
@ -568,6 +572,7 @@ macro_rules! _define_shape_system {
impl display::shape::StaticShapeSystemInstance for ShapeSystem {
type Shape = Shape;
#[profile(Debug)]
fn new_instance(&self) -> Self::Shape {
let sprite = self.shape_system.new_instance();
let id = sprite.instance_id;
@ -579,6 +584,7 @@ macro_rules! _define_shape_system {
impl display::shape::DynShapeSystemInstance for ShapeSystem {
type DynamicShape = DynamicShape;
#[profile(Debug)]
fn instantiate(&self, dyn_shape:&Self::DynamicShape) -> symbol::GlobalInstanceId {
let sprite = self.shape_system.new_instance();
let instance_id = sprite.instance_id;
@ -597,6 +603,7 @@ macro_rules! _define_shape_system {
}
impl ShapeSystem {
#[profile(Debug)]
fn init_refresh_on_style_change(self) -> Self {
let shape_system = self.shape_system.clone_ref();
let style_watch = self.style_watch.clone_ref();
@ -607,6 +614,7 @@ macro_rules! _define_shape_system {
}
/// The canvas shape definition.
#[profile(Debug)]
pub fn shape_def
(__style_watch__:&display::shape::StyleWatch)
-> display::shape::primitive::def::AnyShape {

View File

@ -300,6 +300,7 @@ impl WorldData {
/// function is more precise than time obtained from the [`window.performance().now()`] one.
/// Follow this link to learn more:
/// https://stackoverflow.com/questions/38360250/requestanimationframe-now-vs-performance-now-time-discrepancy.
#[profile(Objective)]
pub fn run_next_frame(&self, time: animation::TimeInfo) {
let previous_frame_stats = self.stats.begin_frame();
if let Some(stats) = previous_frame_stats {
@ -319,6 +320,7 @@ impl WorldData {
///
/// The collector is designed to handle EnsoGL component's FRP networks and models, but any
/// structure with static timeline may be put. For details, see docs of [`garbage::Collector`].
#[profile(Debug)]
pub fn collect_garbage<T: 'static>(&self, object: T) {
self.garbage_collector.collect(object);
}

View File

@ -4,6 +4,7 @@ use crate::display::shape::*;
use crate::gui::style::*;
use crate::prelude::*;
use crate::application::command::FrpNetworkProvider;
use crate::data::color;
use crate::define_style;
use crate::display;
@ -162,7 +163,7 @@ pub mod shape {
// === Frp ===
// ===========
crate::define_endpoints! {
crate::define_endpoints_2! {
Input {
set_style (Style),
}
@ -239,7 +240,7 @@ impl Cursor {
/// Constructor.
pub fn new(scene: &Scene) -> Self {
let frp = Frp::new();
let network = &frp.network;
let network = frp.network();
let model = CursorModel::new(scene);
let mouse = &scene.mouse.frp;
@ -456,10 +457,10 @@ impl Cursor {
// === Outputs ===
frp.source.position <+ position;
frp.source.screen_position <+ screen_position;
frp.source.scene_position <+ scene_position;
frp.source.scene_position_delta <+ scene_position_delta;
frp.private.output.position <+ position;
frp.private.output.screen_position <+ screen_position;
frp.private.output.scene_position <+ scene_position;
frp.private.output.scene_position_delta <+ scene_position_delta;
}
// Hide on init.

View File

@ -25,6 +25,8 @@ futures = "0.3"
serde = "1"
wasm-bindgen = { version = "0.2.58", features = [ "nightly" ] }
wasm-bindgen-futures = "0.4"
url = "2.2.2"
qstring = "0.7.2"
[dependencies.web-sys]
version = "0.3"

View File

@ -1,7 +1,9 @@
//! Demo scene showing a sample flame graph. Can be used to display a log file, if you have one.
//! To do so, set the `PROFILER_LOG_NAME` to contain the profiling log name and it
//! will be used for rendering the visualisation. See the docs of `PROFILER_LOG_NAME` for more
//! information.
//! To do so, set a query parameter in the url to contain `file=<name _of_log_file>` and it
//! will be used for rendering the visualisation. Note that the log file needs to be located in
//! the assets subdirectory that is served by the webserver, i.e. `enso/dist/content` or
//! `app/ide-desktop/lib/content/assets`. If no name is given a file named `profile.json` will
//! be loaded by default. If that file is not present, some dummy data will be displayed.
// === Standard Linter Configuration ===
#![deny(non_ascii_idents)]
@ -50,16 +52,9 @@ use ensogl_sequence_diagram::SequenceDiagram;
// === Constants ===
// =================
/// Content of a profiler log, that will be rendered. If this is `None` some dummy data will be
/// generated and rendered. The file must be located in the assets subdirectory that is
/// served by the webserver, i.e. `enso/dist/content` or `app/ide-desktop/lib/content/assets`.
/// For example use `Some("profile.json")`.
const PROFILER_LOG_NAME: Option<&str> = Some("combined.json");
const SHOW_RPC_EVENT_MARKS: bool = false;
const SHOW_BACKEND_MESSAGE_MARKS: bool = false;
const DEFAULT_LOG_NAME: &str = "profile.json";
const SHOW_RPC_EVENT_MARKS: bool = true;
const SHOW_BACKEND_MESSAGE_MARKS: bool = true;
@ -142,6 +137,30 @@ fn init_theme(scene: &Scene) {
mod js {
use super::*;
#[wasm_bindgen(inline_js = "
export function get_url() {
return window.location.href
}
")]
extern "C" {
#[allow(unsafe_code)]
pub fn get_url() -> String;
}
}
fn get_target_file_from_url() -> Option<String> {
let url = js::get_url();
let url = url::Url::parse(&url).ok()?;
let query = url.query()?;
let query = qstring::QString::from(query);
query.get("file").map(|s| s.to_owned())
}
// ===========================
// === Metadata Processing ===
// ===========================
@ -204,11 +223,13 @@ fn make_rendering_performance_blocks(
// === Profiler Log Reading ===
// ============================
/// Read the `PROFILER_LOG_NAME` data from a file.
/// Read the log file data from a file, if one is specified.
async fn get_data_raw() -> Option<String> {
use wasm_bindgen::JsCast;
let url = &["assets/", PROFILER_LOG_NAME?].concat();
let file_name = get_target_file_from_url();
let file_name = file_name.as_deref().unwrap_or(DEFAULT_LOG_NAME);
let url = &["assets/", file_name].concat();
let mut opts = web_sys::RequestInit::new();
opts.method("GET");
opts.mode(web_sys::RequestMode::Cors);

View File

@ -19,10 +19,12 @@ ensogl-flame-graph = { path = "../../component/flame-graph" }
ensogl-hardcoded-theme = { path = "../../app/theme/hardcoded" }
ensogl-text = { path = "../../component/text" }
ensogl-text-msdf-sys = { path = "../../component/text/msdf-sys" }
ensogl-tooltip = { path = "../../component/tooltip" }
futures = "0.3"
wasm-bindgen = { version = "0.2.58", features = [ "nightly" ] }
wasm-bindgen-futures = "0.4"
[dependencies.web-sys]
version = "0.3"
features = [

View File

@ -18,10 +18,13 @@ use wasm_bindgen::prelude::*;
use enso_profiler_data as profiler_data;
use enso_profiler_flame_graph as profiler_flame_graph;
use ensogl_core::application;
use ensogl_core::application::command::FrpNetworkProvider;
use ensogl_core::application::tooltip::Placement;
use ensogl_core::data::color;
use ensogl_core::display;
use ensogl_core::display::navigation::navigator;
use ensogl_core::display::style::theme;
use ensogl_core::frp;
use ensogl_flame_graph as flame_graph;
@ -35,25 +38,33 @@ use ensogl_flame_graph as flame_graph;
#[allow(dead_code)]
pub async fn entry_point_render_profile_flamegraph() {
use ensogl_core::display::object::ObjectOps;
let app = application::Application::new("root");
let app = &application::Application::new("root");
let world = &app.display;
let scene = &world.default_scene;
let network = app.frp.network();
let navigator = navigator::Navigator::new(scene, &scene.camera());
init_theme(scene);
let data = get_data().await;
let profile: profiler_data::Profile<profiler_data::OpaqueMetadata> = data.parse().unwrap();
let mut builder = profiler_flame_graph::FlamegraphBuilder::default();
builder.add_profile(&profile);
let flame_graph = flame_graph::FlameGraph::from_data(builder.into(), &app);
let flame_graph = flame_graph::FlameGraph::from_data(builder.into(), app);
scene.add_child(&flame_graph);
scene.layers.main.add_exclusive(&flame_graph);
world.keep_alive_forever();
let tooltip = ensogl_tooltip::Tooltip::new(app);
scene.add_child(&tooltip);
tooltip.frp.set_placement.emit(Placement::Right);
frp::extend! { network
tooltip.frp.set_style <+ app.frp.tooltip.map(|tt| tt.clone().with_placement(Placement::Right));
}
world
.on
.before_frame
.add(move |_time| {
let _keep_alive = &navigator;
let _keep_alive = &flame_graph;
let _keep_alive = &tooltip;
})
.forget();
}
@ -67,7 +78,7 @@ pub async fn entry_point_render_profile_flamegraph() {
async fn get_data() -> String {
use wasm_bindgen::JsCast;
let url = "/profile.json";
let url = "assets/profile.json";
let mut opts = web_sys::RequestInit::new();
opts.method("GET");
opts.mode(web_sys::RequestMode::Cors);
@ -88,6 +99,7 @@ fn init_theme(scene: &display::Scene) {
let theme = theme::Theme::new();
const COLOR_PATH: &str = "flame_graph_color";
theme.set(COLOR_PATH, color::Rgb::new(1.0, 45.0 / 255.0, 0.0));
theme.set("component.label.text", color::Lcha::black());
theme_manager.register("theme", theme);
theme_manager.set_enabled(&["theme".to_string()]);
let style_watch = ensogl_core::display::shape::StyleWatch::new(&scene.style_sheet);

View File

@ -306,7 +306,7 @@ impl<Out: Data> EventEmitter for NodeData<Out> {
impl<Out: Data> ValueProvider for NodeData<Out> {
fn value(&self) -> Out {
if !self.use_caching() {
panic!("Trying to read not cached value.")
Out::default();
}
self.value_cache.borrow().clone()
}

View File

@ -33,7 +33,6 @@ use enso_profiler_data as data;
use std::collections;
// ============
// === main ===
// ============

View File

@ -285,7 +285,7 @@ impl<M: serde::de::DeserializeOwned> LogVisitor<M> {
format::Event::Pause { id, timestamp } =>
visitor.visit_pause(log_pos, id, timestamp),
format::Event::Metadata(metadata) => visitor.visit_metadata(log_pos, metadata),
format::Event::Label { label } => visitor.visit_label(log_pos, label),
format::Event::Label { label } => visitor.visit_label(log_pos, label.as_ref()),
};
result.map_err(|error| crate::EventError { log_pos: i, error })?;
event_count += 1;

View File

@ -18,6 +18,13 @@ use enso_profiler_data as data;
type RowNumber = i32;
// =======================
// === Label Formating ===
// =======================
fn with_timing_info(base: &str, [t1, t2]: [f64; 2]) -> String {
format!("{}\n[{:.2},{:.2}]", base, t1, t2)
}
// ==================
// === Block Data ===
@ -167,6 +174,7 @@ impl<'p, Metadata> CallgraphBuilder<'p, Metadata> {
return;
}
let label = self.profile[active.measurement].label.to_string();
let label = with_timing_info(&label, [start, end]);
self.blocks.push(Block { start, end, label, row, block_type: Activity::Active });
for child in &active.children {
self.visit_interval(*child, row + 1);
@ -228,9 +236,13 @@ impl<'p, Metadata> RungraphBuilder<'p, Metadata> {
let active_interval = [current_start, current_end];
let sleep_interval = [current_end, next_start];
let label_active = self.profile[current.measurement].label.to_string();
let label_active = with_timing_info(&label_active, active_interval);
let label_sleep =
format!("{} (inactive)", self.profile[current.measurement].label);
let label_sleep = with_timing_info(&label_sleep, sleep_interval);
self.blocks.push(Block {
start: active_interval[0],
@ -253,10 +265,15 @@ impl<'p, Metadata> RungraphBuilder<'p, Metadata> {
// Add first inactive interval.
let first = measurement.intervals.first().unwrap(); // There are at least two intervals.
let first = &self.profile[*first];
let inactive_interval = [measurement.created.into_ms(), first.interval.start.into_ms()];
let label = with_timing_info(
&self.profile[first.measurement].label.to_string(),
inactive_interval,
);
self.blocks.push(Block {
start: measurement.created.into_ms(),
end: first.interval.start.into_ms(),
label: self.profile[first.measurement].label.to_string(),
start: inactive_interval[0],
end: inactive_interval[1],
label,
row,
block_type: Activity::Paused,
});
@ -264,10 +281,18 @@ impl<'p, Metadata> RungraphBuilder<'p, Metadata> {
// Add last active interval.
let last = measurement.intervals.last().unwrap(); // There are at least two intervals.
let last = &self.profile[*last];
let active_interval = [
last.interval.start.into_ms(),
last.interval.end.map(|end| end.into_ms()).unwrap_or(f64::INFINITY),
];
let label = with_timing_info(
&self.profile[last.measurement].label.to_string(),
active_interval,
);
self.blocks.push(Block {
start: last.interval.start.into_ms(),
end: last.interval.end.map(|end| end.into_ms()).unwrap_or(f64::INFINITY),
label: self.profile[last.measurement].label.to_string(),
start: active_interval[0],
end: active_interval[1],
label,
row,
block_type: Activity::Active,
});

View File

@ -5,6 +5,7 @@
use serde;
use serde::Deserialize;
use serde::Serialize;
use std::borrow::Cow;
// ==============
@ -32,9 +33,10 @@ pub enum Event<'a> {
/// Registers a label to be referenced by ID.
#[serde(rename = "L")]
Label {
/// The text content of the label.
/// The text content of the label. Might need to be an owned string, if the original data
/// contains an escape sequence.
#[serde(rename = "l")]
label: &'a str,
label: Cow<'a, str>,
},
/// The beginning of a measurement that starts in the paused state.
#[serde(rename = "C")]
@ -298,4 +300,13 @@ mod tests {
// re-serializing the data structures produces the same blob as the input.
assert_eq!(LOG, serde_json::to_string(&events).unwrap());
}
/// Verify that the current implementation can deserialize escaped paths in the json file.
#[test]
fn escaped_json() {
// Example data containing a string with escaped characters.
const LOG: &str = r#"[{"L":{"l":"entry_point_ide (app\\ui\\src\\lib.rs:134)"}}]"#;
// Check that we can deserialize the data.
let _events: Vec<format::Event> = serde_json::from_str(LOG).unwrap();
}
}

View File

@ -43,6 +43,7 @@ impl<'a> Builder<'a> {
// Get or register label.
let next_label_id = self.labels.len();
let label = *self.labels.entry(label).or_insert_with(|| {
let label = label.into();
self.events.push(format::Event::Label { label });
format::Label(next_label_id)
});