')
55 |
56 | var w=$('#site').width()
57 | var h=$('#site').height()
58 |
59 | $('#ht_separator').css({
60 | height: "100%",
61 | width: "1%",
62 | float: "left",
63 | backgroundColor: "grey"
64 | })
65 |
66 | $('#ht_separator').after('
')
67 |
68 |
69 | $('#ht_main').width((1-this._nbw-.02)*w)
70 |
71 | $('#ht_main').css({
72 | float:'left',
73 | height:'100%',
74 | overflow:'scroll'
75 | })
76 |
77 | var self=this
78 | $('#ht_separator').draggable({
79 | axis: 'x',
80 | containment: 'parent',
81 | helper: 'clone',
82 | start: function(event, ui) {
83 | self.ow=$(window).width()
84 | },
85 | drag: function (event, ui) {
86 | //console.log(ui)
87 | var width=ui.offset.left
88 | $(this).prev().width(width)
89 | //console.log(self.ow)
90 | $(this).next().width(self.ow-width-0.01*self.ow)
91 | }
92 | });
93 |
94 | React.render(
,document.getElementById("ht_main"))
95 | this.has_loaded=true
96 | }
97 |
98 | UI.prototype.show_ui = function(){
99 | // load the split view
100 | // slide notebook to left and inject ui
101 |
102 | // something weird going on - has show_ui and hide_ui in prototype
103 | // but missing load_ui and test()
104 | // for now, manually access the global object
105 |
106 | $('#site').width(this._nbw*100+'%')
107 | $('#notebook-container').width(this._nbw*100+'%')
108 | $('#site').css('float','left');
109 |
110 | $('#ht_main').show()
111 | }
112 |
113 | UI.prototype.hide_ui = function() {
114 | // hide the split view
115 | $('#ht_main').hide()
116 | $('#site').width('')
117 | $('#notebook-container').width('')
118 | }
119 |
120 | return UI
121 | })
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/tdb_ext/components/user_msg_view.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | * system messages/errors appear here
3 | */
4 |
5 | define([
6 | 'react',
7 | 'jquery',
8 | 'dispatcher',
9 | ], function(React,$,dispatcher){
10 |
11 | var UserMsgView = React.createClass({
12 | getInitialState: function() {
13 | return {msg:"Waiting for TDB to connect..."}
14 | },
15 | render: function() {
16 | return (
17 |
18 |
{this.state.msg}
19 |
20 | )
21 | },
22 | componentDidMount: function() {
23 | var self=this
24 | dispatcher.register(function(action){
25 | if (action.actionType == 'user_msg')
26 | self.setState({msg:action.data})
27 | })
28 | }
29 | })
30 |
31 | return UserMsgView
32 | });
33 |
34 |
--------------------------------------------------------------------------------
/tdb_ext/config.yaml:
--------------------------------------------------------------------------------
1 | # Jupyter Notebook Extension Description
2 | Name: HyperTree
3 | Description: Deep Learning IDE
4 | Link: evjang.com/hypertree
5 | #Icon: icon.png
6 | Main: main.js
7 | Compatibility: 4.x
8 |
--------------------------------------------------------------------------------
/tdb_ext/dispatcher.js:
--------------------------------------------------------------------------------
1 | // application-wide event dispatcher
2 |
3 | define([
4 | "flux"
5 | ], function(flux){
6 | return new flux.Dispatcher()
7 | })
8 |
--------------------------------------------------------------------------------
/tdb_ext/htapp.js:
--------------------------------------------------------------------------------
1 | // communicates with the corresponding htapp on the python side
2 |
3 |
4 | define([
5 | 'base/js/namespace',
6 | 'jsx!/nbextensions/tdb_ext/components/ui',
7 | 'base/js/events',
8 | 'dispatcher'
9 | ], function(Jupyter,UI,events,dispatcher){
10 |
11 | var HTApp=function(comm_manager){
12 | //
13 | // MEMBER VARIABLES
14 | //
15 |
16 | this.ui = new UI()
17 | this._comm = null
18 | this.is_connected = true
19 |
20 | //
21 | // CONSTRUCTOR INITIALIZATION
22 | //
23 | var self=this
24 | comm_manager.register_target('tdb', function(comm,msg){
25 | dispatcher.dispatch({
26 | actionType:'user_msg',
27 | data:'TDB connected: success'
28 | })
29 |
30 | self._comm=comm
31 | this.is_connected=true
32 | comm.on_msg(function(msg){
33 | var data=msg['content']['data']
34 |
35 | var msg_type=data['msg_type']
36 | if (msg_type == 'action') {
37 | // if we receive an action, send it to dispatcher
38 | var action={
39 | actionType: data['action'],
40 | data: data['params']
41 | }
42 | dispatcher.dispatch(action)
43 | } else {
44 | console.log('Unrecognized msg_type ' + msg_type)
45 | console.log(data)
46 | }
47 | })
48 | })
49 |
50 | events.on('kernel_restarting.Kernel', function() {
51 | dispatcher.dispatch({
52 | actionType: 'clear'
53 | })
54 | });
55 |
56 | }
57 |
58 |
59 | return HTApp
60 | })
61 |
62 |
63 |
--------------------------------------------------------------------------------
/tdb_ext/keymirror.js:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * AMD-version of Facebook's Keymirror
4 | * Constructs an enumeration with keys equal to their value.
5 | *
6 | * For example:
7 | *
8 | * var COLORS = keyMirror({blue: null, red: null});
9 | * var myColor = COLORS.blue;
10 | * var isColorValid = !!COLORS[myColor];
11 | *
12 | * The last line could not be performed if the values of the generated enum were
13 | * not equal to their keys.
14 | *
15 | * Input: {key1: val1, key2: val2}
16 | * Output: {key1: key1, key2: key2}
17 | *
18 | * @param {object} obj
19 | * @return {object}
20 | */
21 |
22 | define([],function(){
23 | var keyMirror = function(obj) {
24 | var ret = {};
25 | var key;
26 | if (!(obj instanceof Object && !Array.isArray(obj))) {
27 | throw new Error('keyMirror(...): Argument must be an object.');
28 | }
29 | for (key in obj) {
30 | if (obj.hasOwnProperty(key)) {
31 | ret[key] = key;
32 | }
33 | }
34 | return ret;
35 | };
36 | return keyMirror;
37 | })
38 |
--------------------------------------------------------------------------------
/tdb_ext/main.js:
--------------------------------------------------------------------------------
1 | /*
2 | This is the entry point into HyperTree nbextension
3 | after installing into ~/.jupyter/nbextensions/, do
4 | javascript:require(["nbextensions/tdb_ext"] function(ht){});
5 | */
6 |
7 | var ROOT = '/nbextensions/tdb_ext'
8 | var BOWER = ROOT+'/bower_components'
9 | var STORES = '/nbextensions/tdb_ext/stores'
10 |
11 | // easy access to vendor libs
12 |
13 | require.config({
14 | paths: {
15 | "dispatcher": ROOT + "/dispatcher",
16 | "flux":BOWER+"/flux/dist/Flux.min",
17 | "eventemitter2":BOWER + '/eventemitter2/lib/eventemitter2',
18 | "keyMirror":ROOT+'/keymirror',
19 | "raphael":BOWER + "/raphael/raphael-min",
20 | "dispatcher": ROOT + "/dispatcher",
21 | "react": BOWER + "/react/react-with-addons",
22 | "JSXTransformer": BOWER + "/react/JSXTransformer",
23 | "jsx": BOWER + "/requirejs-react-jsx/jsx",
24 | "text": BOWER + "/requirejs-text/text",
25 | "plotstore":STORES + "/plotstore"
26 | },
27 | shim : {
28 | "react": {
29 | "exports": "React"
30 | },
31 | "JSXTransformer": "JSXTransformer"
32 | },
33 | config: {
34 | jsx: {
35 | fileExtension: ".jsx",
36 | transformOptions: {
37 | harmony: true,
38 | stripTypes: false,
39 | inlineSourceMap: true
40 | },
41 | usePragma: false
42 | }
43 | }
44 | });
45 |
46 | define([
47 | 'base/js/namespace',
48 | ROOT + '/htapp.js'
49 | ], function(Jupyter,HTApp){
50 | var kernel = Jupyter.notebook.kernel
51 | var comm_manager=Jupyter.notebook.kernel.comm_manager
52 | // icky - binding as a global variable
53 | HT=new HTApp(comm_manager)
54 | HT.ui.load_ui()
55 | HT.ui.show_ui()
56 | console.log('HT nbextension loaded')
57 | })
58 |
--------------------------------------------------------------------------------
/tdb_ext/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ht",
3 | "version": "0.0.0",
4 | "description": "Deep Learning IDE",
5 | "main": "",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "Eric Jang",
10 | "license": "Apache 2.0",
11 | "devDependencies": {
12 | "bower": "~1.6.7"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tdb_ext/stores/plotstore.js:
--------------------------------------------------------------------------------
1 |
2 | define([
3 | 'dispatcher',
4 | 'eventemitter2'
5 | ], function(dispatcher,EventEmitter){
6 |
7 | var CHANGE_EVENT = 'change'
8 |
9 | // key = PlotOp node name
10 | // value = img src
11 | var _plots = {}
12 |
13 |
14 | var PlotStore = Object.assign({}, EventEmitter.prototype, {
15 | getPlots: function() {
16 | return _plots
17 | },
18 | update: function(data) {
19 | _plots[data.name]=data.src
20 | },
21 | clear: function() {
22 | _plots={}
23 | },
24 | remove: function(name) {
25 | if (_plots.hasOwnProperty(name)) {
26 | delete _plots[name]
27 | }
28 | },
29 | emitChange: function() {
30 | this.emit(CHANGE_EVENT);
31 | },
32 | addChangeListener: function(callback) {
33 | this.on(CHANGE_EVENT, callback)
34 | },
35 | removeChangeListener: function(callback) {
36 | this.removeListener(CHANGE_EVENT, callback)
37 | }
38 | })
39 |
40 | // register store with the dispatcher
41 | dispatcher.register(function(action){
42 | switch(action.actionType){
43 | case 'update_plot':
44 | // create new plot or update an old one
45 | PlotStore.update(action.data)
46 | PlotStore.emitChange()
47 | break;
48 | case 'remove_plot':
49 | PlotStore.remove(action.name)
50 | PlotStore.emitChange()
51 | break;
52 | case 'clear':
53 | PlotStore.clear()
54 | PlotStore.emitChange()
55 | break;
56 | default:
57 | // no op
58 | }
59 | })
60 |
61 | return PlotStore
62 | })
63 |
--------------------------------------------------------------------------------