<commit_before><link rel="import" href="../the-library/the-library.html">
<link rel="import" href="../the-graph/the-graph.html">
<link rel="import" href="../the-graph-nav/the-graph-nav.html">

<polymer-element name="the-graph-editor" attributes="grid snap" lightdom>
  <template>
    <link rel="stylesheet" href="../themes/default/the-graph.css">
    <the-library id="library"></the-library>
    <the-graph id="graph" name="{{ graph.properties.name }}" snap="{{snap}}" grid="{{grid}}" scale="{{scale}}" pan="{{pan}}">
      <the-behaviors>
        <the-behavior id="graphpinch" type="pinch"></the-behavior>
        <the-behavior id="scratch" type="scratch" accept="nodeName=svg" mindistance="30" minspeed="0.6"></the-behavior>
        <the-behavior type="swipe" direction="north" accept="nodeName=THE-GRAPH-PROCESS" action="remove" minspeed="1.5" mindistance="40"></the-behavior>
        <the-behavior type="drag" direction="north south" accept="nodeName=THE-GRAPH-PROCESS" action="attribute" mindistance="20"></the-behavior>
        <the-behavior id="nodehighlight" type="drag" direction="east west" accept="nodeName=THE-GRAPH-PROCESS" mindistance="20"></the-behavior>
        <the-behavior id="graphpan" type="drag" direction="north south east west" accept="nodeName=svg" mindistance="20"></the-behavior>
      </the-behaviors>
    </the-graph>
    <the-graph-nav id="nav" scale="{{scale}}" pan="{{pan}}"></the-graph-nav>
  </template>
  <script>
  (function () {
    Polymer('the-graph-editor', {
      graph: {},
      library: {},
      grid: 70,
      snap: 35,
      scale: 1,
      pan: "0 0",
      plugins: {},
      addPlugin: function (name, plugin) {
        this.plugins[name] = plugin;
        plugin.register(this);
      },
      enteredView: function () {
        this.addEventListener('mousewheel', function (event) {
          event.preventDefault();
          
          var pan = this.pan.split(" ");
          var x = parseInt(pan[0], 10);
          var y = parseInt(pan[1], 10);
          x += event.wheelDeltaX;
          y += event.wheelDeltaY;
          this.pan = x + " " + y;
        });
      },
      leftView: function () {
        for (var name in this.plugins) {
          this.plugins[name].unregister(this);
          delete this.plugins[name];
        }
      },
      graphChanged: function () {
        this.buildInitialLibrary();
        this.$.graph.graph = this.graph;
        this.$.graph.library = this.$.library;

        // Reference the graph element
        this.$.nav.graph = this.$.graph;
      },
      buildInitialLibrary: function () {
        Object.keys(this.graph.processes).forEach(function (id) {
          var node = this.graph.processes[id];
          var component = {
            name: node.component,
            description: '',
            inports: [],
            outports: []
          };

          this.graph.connections.forEach(function (edge) {
            var i;
            if (edge.src && edge.src.process === id) {
              for (i = 0; i < component.outports.length; i++) {
                if (component.outports[i].name === edge.src.port) {
                  return;
                }
              }
              component.outports.push({
                name: edge.src.port,
                type: 'all'
              });
            }
            if (edge.tgt.process === id) {
              for (i = 0; i < component.inports.length; i++) {
                if (component.inports[i].name === edge.tgt.port) {
                  return;
                }
              }
              component.inports.push({
                name: edge.tgt.port,
                type: 'all'
              });
            }
          });
          this.registerComponent(component);
        }.bind(this));
      },
      registerComponent: function (definition) {
        if (!this.library[definition.name]) {
          // New component, register
          this.library[definition.name] = definition;
          this.$.library.components.push(this.library[definition.name]);
          return;
        }
        // Update existing
        var component = this.library[definition.name];
        if (definition.description) {
          component.description = definition.description;
        }
        if (definition.icon) {
          component.icon = definition.icon;
        }
        definition.inports.forEach(function (defPort) {
          var port = null;
          component.inports.forEach(function (p) {
            if (p.name === defPort.name) {
              port = p;
            }
          });
          if (port) {
            port.type = defPort.type;
            return;
          }
          component.inports.push({
            name: defPort.name,
            type: defPort.type,
            array: defPort.array
          });
        });
        definition.outports.forEach(function (defPort) {
          var port = null;
          component.outports.forEach(function (p) {
            if (p.name === defPort.name) {
              port = p;
            }
          });
          if (port) {
            port.type = defPort.type;
            return;
          }
          component.outports.push({
            name: defPort.name,
            type: defPort.type,
            array: defPort.array
          });
        });
      },
      toJSON: function () {
        return this.$.graph.toJSON();
      }
    });
  })();
  </script>
</polymer-element>
<commit_msg>Keep dragging canvas even when mouse leaves window, like on Google Maps<commit_after><link rel="import" href="../the-library/the-library.html">
<link rel="import" href="../the-graph/the-graph.html">
<link rel="import" href="../the-graph-nav/the-graph-nav.html">

<polymer-element name="the-graph-editor" attributes="grid snap" lightdom>
  <template>
    <link rel="stylesheet" href="../themes/default/the-graph.css">
    <the-library id="library"></the-library>
    <the-graph id="graph" name="{{ graph.properties.name }}" snap="{{snap}}" grid="{{grid}}" scale="{{scale}}" pan="{{pan}}">
    <the-behaviors listento="html">
        <the-behavior id="graphpinch" type="pinch"></the-behavior>
        <the-behavior id="scratch" type="scratch" accept="nodeName=svg" mindistance="30" minspeed="0.6"></the-behavior>
        <the-behavior type="swipe" direction="north" accept="nodeName=THE-GRAPH-PROCESS" action="remove" minspeed="1.5" mindistance="40"></the-behavior>
        <the-behavior type="drag" direction="north south" accept="nodeName=THE-GRAPH-PROCESS" action="attribute" mindistance="20"></the-behavior>
        <the-behavior id="nodehighlight" type="drag" direction="east west" accept="nodeName=THE-GRAPH-PROCESS" mindistance="20"></the-behavior>
        <the-behavior id="graphpan" type="drag" direction="north south east west" accept="nodeName=svg" mindistance="20"></the-behavior>
      </the-behaviors>
    </the-graph>
    <the-graph-nav id="nav" scale="{{scale}}" pan="{{pan}}"></the-graph-nav>
  </template>
  <script>
  (function () {
    Polymer('the-graph-editor', {
      graph: {},
      library: {},
      grid: 70,
      snap: 35,
      scale: 1,
      pan: "0 0",
      plugins: {},
      addPlugin: function (name, plugin) {
        this.plugins[name] = plugin;
        plugin.register(this);
      },
      enteredView: function () {
        this.addEventListener('mousewheel', function (event) {
          event.preventDefault();
          
          var pan = this.pan.split(" ");
          var x = parseInt(pan[0], 10);
          var y = parseInt(pan[1], 10);
          x += event.wheelDeltaX;
          y += event.wheelDeltaY;
          this.pan = x + " " + y;
        });
      },
      leftView: function () {
        for (var name in this.plugins) {
          this.plugins[name].unregister(this);
          delete this.plugins[name];
        }
      },
      graphChanged: function () {
        this.buildInitialLibrary();
        this.$.graph.graph = this.graph;
        this.$.graph.library = this.$.library;

        // Reference the graph element
        this.$.nav.graph = this.$.graph;
      },
      buildInitialLibrary: function () {
        Object.keys(this.graph.processes).forEach(function (id) {
          var node = this.graph.processes[id];
          var component = {
            name: node.component,
            description: '',
            inports: [],
            outports: []
          };

          this.graph.connections.forEach(function (edge) {
            var i;
            if (edge.src && edge.src.process === id) {
              for (i = 0; i < component.outports.length; i++) {
                if (component.outports[i].name === edge.src.port) {
                  return;
                }
              }
              component.outports.push({
                name: edge.src.port,
                type: 'all'
              });
            }
            if (edge.tgt.process === id) {
              for (i = 0; i < component.inports.length; i++) {
                if (component.inports[i].name === edge.tgt.port) {
                  return;
                }
              }
              component.inports.push({
                name: edge.tgt.port,
                type: 'all'
              });
            }
          });
          this.registerComponent(component);
        }.bind(this));
      },
      registerComponent: function (definition) {
        if (!this.library[definition.name]) {
          // New component, register
          this.library[definition.name] = definition;
          this.$.library.components.push(this.library[definition.name]);
          return;
        }
        // Update existing
        var component = this.library[definition.name];
        if (definition.description) {
          component.description = definition.description;
        }
        if (definition.icon) {
          component.icon = definition.icon;
        }
        definition.inports.forEach(function (defPort) {
          var port = null;
          component.inports.forEach(function (p) {
            if (p.name === defPort.name) {
              port = p;
            }
          });
          if (port) {
            port.type = defPort.type;
            return;
          }
          component.inports.push({
            name: defPort.name,
            type: defPort.type,
            array: defPort.array
          });
        });
        definition.outports.forEach(function (defPort) {
          var port = null;
          component.outports.forEach(function (p) {
            if (p.name === defPort.name) {
              port = p;
            }
          });
          if (port) {
            port.type = defPort.type;
            return;
          }
          component.outports.push({
            name: defPort.name,
            type: defPort.type,
            array: defPort.array
          });
        });
      },
      toJSON: function () {
        return this.$.graph.toJSON();
      }
    });
  })();
  </script>
</polymer-element>

{'fraction_non_alphanumeric': 0.15370573201898502, 'fraction_numerical': 0.00529390288426433, 'mean_word_length': 1.7648246278072168, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2874272', 'n_tokens_mistral': 3169, 'n_tokens_neox': 3068, 'n_words': 572}