Coder Social home page Coder Social logo

jerosoler / drawflow Goto Github PK

View Code? Open in Web Editor NEW
4.2K 71.0 692.0 7.06 MB

Simple flow library ๐Ÿ–ฅ๏ธ๐Ÿ–ฑ๏ธ

Home Page: https://jerosoler.github.io/Drawflow/

License: MIT License

CSS 1.85% JavaScript 64.20% HTML 33.95%
flow javascript javascript-library flow-based-programming flowchart visual-programming dataflow-programming graph-editor dataflow drawflow

drawflow's Introduction

Hi, I'm Jero ๐Ÿ‘‹

๐Ÿ‘€ Look at my projects! ๐Ÿ‘€

๐Ÿ“ฆ Libraries

๐Ÿ“ฆ WebComponents

๐ŸŽจ CSS/SVG generators

๐Ÿง™โ€โ™‚๏ธ CSS Houdini

๐ŸŽ‰ Fun

๐Ÿ•ต๏ธ See more projects

Follow me! on ๐Ÿฆ Twitter

drawflow's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

drawflow's Issues

nodeRemoved triggers before connectionRemoved

Hey again,

Sorry for another issue!

Inside of removeNodeId(id), this.removeConnectionNodeId is called at the bottom which means that nodeRemoved is triggered before connectionRemoved. This is a problem because if you need data from the node that was deleted inside the connectionRemoved event this is not possible because it is already deleted.

In my instance, I need some data from the data object inside of the node which relates to the connection.

However I cannot see this being an issue for many others. In my development version I have moved the removeConnectionNodeId to the top of removeNodeId just so the connection is always removed first, which makes sense anyways.

You can see what I have done here: https://github.com/icabbi-joegarlick/Drawflow/commit/ad98179506395323e650b39776040021cd703913
In this commit also I have added a param to addNode to allow me to specify the nodeId for my loading system - Not sure this is the best solution for this issue but works for what I need at the moment. If i figure out a better solution i will tell you unless you have any ideas?

Let me know what you think.

Thanks,
Joe

Export issue in data field

whenever use select HTML element in any block and choose an option as selected,

when click on Export the Json result does not include any "date" field.

but when select an option manually the json rebuilds and this time include "data" field on selected item.

thank you

Adding/Deleting outputs

Hi, first of all,great script.
I would like to know if there is any method available to add/delete output of any node?

Dynamic Input-Output

How to "bind" input/output's position created with node's body elements (created dynamically)?

Edit node?

Hi,
First off Drawflow is brilliant, thank you!

I couldn't see any method to actually update the content of an existing node, e.g. to change the layout in the template. Failing this, perhaps a redraw method which doesn't clear the IDs?

The use-case is to have my application change content, e.g. the title or icon or other HTML content, then display this change to the user.

Thanks!
Sam

Delete icon

Hi, I would like to be able to show a custom delete icon (like a trash icon or something else ,for nodes and connections) and also to be able to show it on node/connection selection (not in contextmenu).

I'm working with VueJS, can you help me about those features? Thanks for your work!

Can we have a before node delete event?

Hello, Thank you once again for this amazing project. Is it possible to have a before node delete event? If we cancel this event then it won't bubble up to delete the selected node?
I need to intercept a prior to delete action and proceed if the user responds as yes
Thanks a lot

Getting mouse coordinates on canvas, not screen

I'm doing a context menu that enables adding nodes to drawflow canvas right where the contextmenu is, but I'm having problems positioning the context menu correctly with scaling
Below code works perfectly when locating mouse coordinates when zoom is not used within drawflow, but after using zoom it does not work. I've been trying to fiddle with the editorZoom multiplier to client values and the rect values, without success. Any ideas on how to implement this thing?

	editor.on('zoom', function(zoom) {
	  editorZoom = zoom;
	})

  	editor.on('translate', function(position) {
	  translateX = position.x;
	  translateY = position.y;
	})
	
    editor.on('contextmenu', function(event) {
    	var rect = document.getElementById('drawflow').getBoundingClientRect();
    	var contextmenux = event.clientX - translateX / editorZoom - rect.left ;
    	var contextmenuy = event.clientY - translateY / editorZoom - rect.top ;
   }

It seems none of the coordinate events return coordinates relative to the canvas, but instead relative to the viewport. Could some canvas related coordinate events would be nice as well? So that it returns negative coordinates if that is where the event happens on canvas. This is because addNode takes coordinates relative to canvas, not relative to screen.

Proper VUE example or how to bind node props to VUE props?

Hey!

Just wanted to say that this is a fantastic library, I am building some cool product with it at the moment.
But not being a super experienced frontend developer I stuck with Drawflow + Vue integration.

Is it possible to bind node's df-* data properties to Vue data properties?
Can you provide a complete example or point me to it please?

Thanks.

pressing delete key inside contenteditable=true element deletes the current node

I'm using contenteditable elements inside html nodes. When the user presses the delete key, the node is removed. This behaviour works fine inside input text and textarea.
Example code:

var find = <div> <div class=title-box><svg class=icon> <use xlink:href=#magnifying-glass></use></svg><span class="changeable" contenteditable="true" placeholder="Enter name ">Find</span></div> <div class=content-box> <input ondrop="dropit(event)" class="form-control clsAlphaNoOnly" placeholder="Enter search text" ondragover="allowDropit(event)" required=true df-find> </div> </div>; editor.addNode('find', 1, 2, pos_x, pos_y, 'find', {"find": ""}, find.replace(/\s\s+/g, ' ') );

Can you add contenteditable elements to this exception also? Thank you very much

Typescript version

Hi,
First, I'd like to say this is a great library!
I am wondering if you are planning on creating a type version for the library since iโ€™d like to add this to my angular app

Save zoom value on editor.export

Hi, @jerosoler hope you are doing well..i think you should consider saving the zoom value on editor.export...because if anyone zoom out, move the nodes to left and save the flow,then when the editor.import happens, it resets to the default zoom size, for this reason, some nodes get outside of the monitor.
flowzoom

Add a method to get a node from id

Hello!

First of all, love this script!

I was wondering if it would be possible to add a function to be able to get the node object from the node is.

The reason i want this is because I don't want multiple connections from an output. My idea is to register the connection event which passes the node ID, use that id to see how many connections the output it currently has.

Thanks,
Joe

Vertical ports or drawing connections from node edges

Really like the library!

It would be nice to have an option for inputs/outputs to be on the top/bottom of nodes instead as it appears the logic for drawing connections is hard coded with the assumption that ports are on the sides.

For example:

top-bottom

Similarly, removing a reliance on port elements entirely and instead being able to just draw connections from any of a nodes edges would be nice, though maybe that's too much an impractical change.

For example:

nodes

Self connect nodes

first things first, this library looks awesome. is possible self connect nodes in order to represent loops and/or draw kind of state machine diagrams?

More comfortable zooming on big canvas

I have a very big canvas where items can be located at "top: 6305px; left: 400px;" and even more, sometimes even 20 000 px. When items are so far off the 0,0, then zooming around is not very comfortable is items on canvas do not remain in view and zooming does not work intuitively. I tried to overwrite the zoom functions with trickery to manipulate the translate coordinates, such as:

editor.zoom_out = function(){
    if(this.zoom > this.zoom_min) {
      this.zoom-=0.1;
      this.canvas_y =this.canvas_y - (this.canvas_y/7/this.zoom); //That 7 is just a test
      this.zoom_refresh();
    }
  }

but no success. It requires some kind transformation of canvas coordinates based on zoom multiplier as well as current canvas location but i cannot figure out how. Any ideas on this?

Re-Route Nodes

Hey @jerosoler, me again....

I was wondering how hard it would be to add reroute nodes like how Unreal does it so I can make my flowcharts neater especially when routing back to the beginning.

image

Thanks,
Joe

input text cannot be selected by dragging mouse

Hi, its a major problem i think...if you have any input or textarea inside a node, you cannot select the texts inside it by dragging your cursor...because the node itself gets moved instead of the texts being selected..

is there any way to prevent the node drag mechanism while inside in any input or textarea?

Multi-select + drag

Hi, great project, good features and works nicely! Also quite customizable and it provides is HTML nodes, which other libraries really do not.
Have you considered adding multi-select + multi-drag feature?

Distinction between user created events and programmatically created events

I am using JS to modify node connections from external sources during editing.
Then user also has possibility to manually create node connections.
The event is fired for both when using editor.on('connectionCreated', function(conn) {
Do you think there is a way or a trick to catch only user created connections? Maybe combining somehow to click event?
I tried to use Promises var prom1 = new Promise(function(resolve, reject){ editor.on('connectionCreated',resolve); }); var prom2 = new Promise(function(resolve, reject){ editor.on('click',resolve); }); Promise.all([prom1, prom2]).then(function(){ alert('click + connection create'); });
But that's not quite achieving this..

build list of blocks from Json input

hi again

it's possible to build model based on json file which is fantastic.

my question: is it possible to build list of block at Left Col (class="col") based on the same Json file?

want to send list of blocks from server.

Connecting one input with unlimited outputs

images (76)

Please see the picture.Its a common case when the input of any node has to be connected with the outputs of multiple (in fact unlimited) nodes.

I can see its already possible.But can i prevent more than 1 wire coming out of 1 output?

In a nutshell:
An input can be connected with unlimited outputs.
But one output can only be connected with one input.

access output_name of pre blocks

dear @jerosoler, thank you again for advises which cause i progress in my project.

the new issue:
suppose a selection list of output available in block #1

then connect #1 to #2
is there any way to access the chosen name of #1 output (or even block#1 name) in block #2 as input name?
i.e : need to know what is input1 and input2 name in block #2 to do specific jobs like comparison between inputs.

image

Regards

Use function vue in components HTML

In vuejs function I use Library function this.editor.addNode and i used "@click="Clicked" It's not working in vuejs
You can recommend for using in vuejs

card_devices: ' <div class="card-devices" > <div class="header"> <h1> Test </h1> </div> <div class="body" > <span @click="Clicked"> Name :</span> </div> </div> </div> '

Option to add default input and direction arrows

Hi @jerosoler, i am proposing a new feature which may be called as "default input"

Suppose i only use one input port in all of my nodes.Since the port area is visually too small,sometimes user fails to connect with the input.This will happen a lot if there are so many nodes and hence the view is too small.Then user will have to zoom everytime and connect with the inputs.this is not a good idea

To solve this,we can define a default input option while configuring the plugin.If user drags the connection to any place of the node,it will be connected with that default input.so user has a big area to drop his connection,instead of that small input port area.This will improve the user experience a lot. trust me.

Popular flow builders like manychat also have this option.user can drop the connection on any part of the node,and it gets comnected.Since in our case, we can have multiple inputs,so we can define a default input for that operation.

Another feature request is a nice arrow at the end of the connection for presenting the flow direction.These two feature will make this plugin even powerful.

How to restrict the node to single input

I really like your project and willing to use it but I have a question according to my requirement.
Is it possible to restrict the node to a single input ?

Also, Can we customize it?

Connection Metadata / Module(?)

For some use cases, it would be nice to add metadata (name, weight, etc) to the connections between nodes/modules. Is this something that would be a) easy to implement and b) valuable to the general community?

I'd be happy to help implement it, but I'm new to this code base and would likely need a few pointers on where to get started, and how it would be best to architect this to work well with existing ideas and coding practices.

Using mouse wheel to scroll up and down on canvas

I wanted to scroll up and down on canvas using plain mouse wheel. Here's the javascript needed to achieve it:

var Drawflowoverride = class extends Drawflow {
  zoom_enter(event, delta) {
	  event.preventDefault();
	  if (event.ctrlKey) {
	      if(event.deltaY > 0) {
	        // Zoom Out
	        this.zoom_out();
	      } else {
	        // Zoom In
	        this.zoom_in();
	      }
	    }
	  else {
		  if(event.deltaY > 0) {
			  var moveAm = -40;
			  //Scroll up
		  } else {
			  //Scroll down
			  var moveAm = 40;
		  }

		  this.canvas_y = this.canvas_y + moveAm;
	      this.dispatch('translate', { x: this.canvas_x , y: this.canvas_y});
	      this.precanvas.style.transform = "translate("+this.canvas_x+"px, "+this.canvas_y+"px) scale("+this.zoom+")";

	 }
}

Can we have 'unselect node' events?

So, considering we may want to bind any kind of function to the nodeSelected event, it would be very usefull to have an event to bind functions when the user clicks on any empty space between nodes.

Using in react.js

Hi,hope you are doing well

I have another question.can i use it with react js?if yes,how?

Connectors not visible when loading nodes from json object

I tried the following code to load modules, with their respective inputs and outputs, but the connections don't show up initially. After the import, if I select and move the nodes slightly then the connections appear. The json used was initially obtained by using the export method.

var id = document.getElementById("drawflow");
const editor = new Drawflow(id);
editor.start();
editor.import( {"drawflow":{"Home":{"data":{"3":{"id":3,"name":"reply_message","data":{"reply":"[[name]], your query for outstanding [[find.text]] is [[amount]]"},"class":"reply_message","html":"\n          <div>\n            <div class=\"title-box\"><svg class=\"icon\">\n              <use xlink:href=\"#arroba\"></use></svg> Reply message</div>\n              <div class=\"content-box\">\n                <textarea class=\"resize-vertical form-control\" required data-parsley-trigger=\"change blur\" data-parsley-errors-messages-disabled data-parsley-required-message=\"Value is required!\" placeholder=\"Enter reply message\" placeholder=\"Enter reply message\" df-reply ondrop=\"drop(event)\" ondragover=\"allowDrop(event)\"></textarea>\n              </div>\n          </div>\n          ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"6","input":"output_1"}]}},"outputs":{"output_1":{"connections":[]},"output_2":{"connections":[]}},"pos_x":910,"pos_y":52},"4":{"id":4,"name":"WhatsApp","data":{},"class":"WhatsApp","html":"<div class=\"blockelem noselect block\">\n                            <input type=\"hidden\" name=\"blockelemtype\" class=\"blockelemtype\" value=\"5\">\n                            <input type=\"hidden\" name=\"blockid\" class=\"blockid\" value=\"0\">\n                            <div class=\"blockyleft\"><img src=\"/images/workflow/WhatsApp.png\" class=\"blockyname\"><label class=\"blockyname\">WhatsApp</label></div>                     \n                            <div class=\"blockydiv\"></div><div class=\"blockyinfo\">Triggers the start of the work flow</div></div>","typenode":false,"inputs":{},"outputs":{"output_1":{"connections":[{"node":"5","output":"input_1"}]}},"pos_x":18,"pos_y":55},"5":{"id":5,"name":"find","data":{"find":"balance"},"class":"find","html":"\n            <div>\n              <div class=\"title-box\"><svg class=\"icon\">\n                <use xlink:href=\"#magnifying-glass\"></use></svg> Find</div>\n                <div class=\"content-box\">\n                  <input type=\"text\" class=\"form-control\" required data-parsley-trigger=\"change blur\" data-parsley-errors-messages-disabled placeholder=\"Enter search text\" df-find>\n                </div>\n            </div>\n          ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"4","input":"output_1"}]}},"outputs":{"output_1":{"connections":[{"node":"6","output":"input_1"}]},"output_2":{"connections":[]}},"pos_x":295,"pos_y":60},"6":{"id":6,"name":"db_connection","data":{"connection":"","query":"select [[amount]] from pending_payment"},"class":"db_connection","html":"\n            <div>\n              <div class=\"title-box\"><svg class=\"icon\">\n                <use xlink:href=\"#database\"></use></svg> Database query</div>\n                <div class=\"content-box\">\n                    <div class=\"input-group\">\n                        <select class=\"form-control\" name=\"connections\" id=\"connections\" required data-parsley-trigger=\"change blur\" placeholder=\"Select connection\" data-parsley-errors-messages-disabled df-connection>\n                        </select>\n                    </div>\n                    <div class=\"input-group\">\n                        <textarea class=\"form-control resize-vertical\" required data-parsley-trigger=\"change blur\" data-parsley-errors-messages-disabled data-parsley-required-message=\"Value is required!\" placeholder=\"Type query here\" df-query ondrop=\"drop(event)\" ondragover=\"allowDrop(event)\"></textarea>\n                    </div>\n                </div>\n            </div>\n            ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"5","input":"output_1"}]}},"outputs":{"output_1":{"connections":[{"node":"3","output":"input_1"}]},"output_2":{"connections":[{"node":"7","output":"input_1"}]}},"pos_x":573,"pos_y":55},"7":{"id":7,"name":"reply_message","data":{"reply":"Sorry, I didn't find find anything"},"class":"reply_message","html":"\n          <div>\n            <div class=\"title-box\"><svg class=\"icon\">\n              <use xlink:href=\"#arroba\"></use></svg> Reply message</div>\n              <div class=\"content-box\">\n                <textarea class=\"resize-vertical form-control\" required data-parsley-trigger=\"change blur\" data-parsley-errors-messages-disabled data-parsley-required-message=\"Value is required!\" placeholder=\"Enter reply message\" placeholder=\"Enter reply message\" df-reply ondrop=\"drop(event)\" ondragover=\"allowDrop(event)\"></textarea>\n              </div>\n          </div>\n          ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"6","input":"output_2"}]}},"outputs":{"output_1":{"connections":[]},"output_2":{"connections":[]}},"pos_x":911,"pos_y":216}}}}} );

Programmatically Create Reroute Point

I want to programmatically add points between nodes. I think it would be great if such a feature could be added to the library.

Like: createReroutePoint(pos_x, pos_y, output_node_id, input_node_id, output_class?, input_class?)

createReroutePoint(100,50,1,2,'output_1');

or

createReroutePoint(75, 150, 2, 1, null, 'input_1');

image

Error during import

addNodeImport (dataNode, precanvas) {

Hi Jero, I'm trying to import drawflow data i saved in current storage (Vuex) but I'm getting this error (screenshot attached):

Uncaught TypeError: Cannot read property 'options' of undefined

Screenshot 2020-10-26 at 18 23 31

If it could be useful, I'm not using options during nodes creation (I tried to set it to empty object or null, but it gave me same error). Any help? Could it be e bug?

Arrows?

Is it possible to add arrows to indicate direction between nodes?

Please add an after import event

Can we have an event triggered after nodes are imported? An event handler would be than using a timer to call the updateConnectionNodes method after import

removeConnectionNodeId(id) does not actually delete the connection

While using removeConnectionNodeId(id) method,although the connection path is deleted visually,but the connection is still there in the connection data.
After using removeConnectionNodeId(id) , if we use getNodeFromId(id) we can still show the previous connections in the connection array of that node.

Custom draggable nodes

This is awesome! I love how straightforward tracking the nodes is, but I am wondering what the best way to create my own node types/templates i.e. "Slack Message", "Github Star", "Template", etc. I've been looking through both the css and js and I don't see any references pointing to those elements in the side-menu in your demo yet. Maybe i'm missing something though?

removeNodeOutput() doesn't work correctly with more than 9 outputs

Great library :)
I discovered that if you have more than 9 outputs the method to remove outputs updates the data correctly but not the html, causing the next remove call to fail with the following:
ERROR TypeError: Cannot read property 'remove' of null
at i.removeNodeOutput (drawflow.min.js:1)
at WorkflowDesignerComponent.removeOutput (workflow-designer.component.ts:133)
at WorkflowDesignerComponent_Template_button_click_3_listener (workflow-designer.component.html:3)
at executeListenerWithErrorHandling (core.js:21888)
at wrapListenerIn_markDirtyAndPreventDefault (core.js:21930)
at HTMLButtonElement. (platform-browser.js:976)
at ZoneDelegate.invokeTask (zone-evergreen.js:399)
at Object.onInvokeTask (core.js:41709)
at ZoneDelegate.invokeTask (zone-evergreen.js:398)
at Zone.runTask (zone-evergreen.js:167)

html after the remove of output_10

image

Thanks,
Carla

add method to redraw connection

I'm calling the import method, but the connection lines are not appearing for some reason. If I move the nodes slightly then the connections appear.

Can we have a method to redraw the connection lines?

property sidebar for blocks

greeting and thank you for the great package which is unique i believe!

is there any way to have blocks property sidebar onclick to add extra conditions and rules for filtering blocks?

node.js browserify > ParseError: Unexpected token

in browserify the js file to bundle below error halt the process which is belong to css.

ow-delete{position:absolute;display:block;width:30px;height:30px;background:#000;color:#fff;z-index:4;border:2px solid #fff;line-height:30px;font-weight:700;text-align:center;border-radius:50%;font-family:monospace;cursor:pointer}.drawflow>.drawflow-delete{margin-left:-15px;margin-top:15px}.parent-node .drawflow-delete{right:-15px;top:-15px} ^ **ParseError: Unexpected token**

the browserify command is:
browserify dflow.js -o bundle.js

and the dflow.js file includes:
`var Drawflow = require('drawflow')
var styleDrawflow = require('drawflow/dist/drawflow.min.css')

var id = document.getElementById("drawflow");
const editor = new Drawflow(id);
editor.start();`

CTRL+Z or +Y

dear @jerosoler

it would be good idea to add CTRL+Z and CTRL+Y in next versions to accelerate editing.

specially if you want to correct wrongly added node or connection have to delete it manually.

** for delete a node in Mac have to push down both fn+Del to do. i thought its possible to use only Del key.

thank you

Cannot read property 'classList' of null"

Hi!
Thank you for the great library!๐Ÿ˜๐Ÿค—

I ran a test file on my server - work!๐Ÿ‘

Now I'm trying to run this example using the VueJS components.
image

Here is the result of this component
image

But on the editor.start(); get the error "Cannot read property 'classList' of null"
image

Please tell me what the error may be and how to fix it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.