├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── 00-hello-world ├── README.md ├── hello-world.js └── hello-world.maxpat ├── 01-syntax-error ├── README.md ├── syntax-error.js └── syntax-error.maxpat ├── 02-message-handlers ├── README.md ├── message-handlers.js └── message-handlers.maxpat ├── 03-message-types ├── README.md ├── message-types.js └── message-types.maxpat ├── 04-outlet-methods ├── README.md ├── outlet-methods.js └── outlet-methods.maxpat ├── 05-dynamic-message-handlers ├── README.md ├── dynamic-message-handlers.js └── dynamic-message-handlers.maxpat ├── 06-using-dicts ├── README.md ├── using-dicts.js └── using-dicts.maxpat ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── package-lock.json └── package.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = tab 7 | insert_final_newline = true 8 | tab_width = 4 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | 01-syntax-error/syntax-error.js 2 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "c74", 3 | "env": { 4 | "node": true, 5 | "es6": true 6 | }, 7 | "parserOptions": { 8 | "ecmaVersion": 2017, 9 | "sourceType": "module" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | #### Nature of issue? 10 | 11 | - [ ] Found a bug in an example 12 | - [ ] Existing example enhancement 13 | - [ ] Suggest a new example 14 | 15 | 16 | #### Details about the bug: 17 | 18 | - Max version: 19 | - Operating System: 20 | - Name of example: 21 | - Steps to reproduce this: 22 | 23 | 24 | 25 | #### Existing example enhancement details: 26 | 27 | 28 | 29 | #### New example details: 30 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | I have verified that this pull request: 2 | 3 | * [ ] there are no linting errors -- `npm run lint`, from the root of the n4m-examples repository 4 | * [ ] is from a uniquely-named feature branch and has been rebased on top of the latest master. (If I was asked to make more changes, I have made sure to rebase onto master then too) 5 | * [ ] is descriptively named and links to an issue number, i.e. `Fixes #123` 6 | 7 | Thank you! 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "10.13.0" 4 | -------------------------------------------------------------------------------- /00-hello-world/README.md: -------------------------------------------------------------------------------- 1 | # Hello World 2 | 3 | This example serves as an introduction for how to use Node For Max in Max 8 with the `[node.script]` object. -------------------------------------------------------------------------------- /00-hello-world/hello-world.js: -------------------------------------------------------------------------------- 1 | // Include the Max API library so that Node can communicate with Max. 2 | let maxApi = require("max-api"); 3 | 4 | // Post to the Max Console 5 | maxApi.post("Hello, World (in the Max console)"); 6 | 7 | // Send a message to the leftmost outlet of node.script 8 | maxApi.outlet("Hello, World"); 9 | -------------------------------------------------------------------------------- /00-hello-world/hello-world.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 8, 6 | "minor" : 0, 7 | "revision" : 3, 8 | "architecture" : "x64", 9 | "modernui" : 1 10 | } 11 | , 12 | "classnamespace" : "box", 13 | "rect" : [ 100.0, 100.0, 656.0, 630.0 ], 14 | "bglocked" : 0, 15 | "openinpresentation" : 0, 16 | "default_fontsize" : 12.0, 17 | "default_fontface" : 0, 18 | "default_fontname" : "Arial", 19 | "gridonopen" : 1, 20 | "gridsize" : [ 15.0, 15.0 ], 21 | "gridsnaponopen" : 1, 22 | "objectsnaponopen" : 1, 23 | "statusbarvisible" : 2, 24 | "toolbarvisible" : 1, 25 | "lefttoolbarpinned" : 0, 26 | "toptoolbarpinned" : 0, 27 | "righttoolbarpinned" : 0, 28 | "bottomtoolbarpinned" : 0, 29 | "toolbars_unpinned_last_save" : 0, 30 | "tallnewobj" : 0, 31 | "boxanimatetime" : 200, 32 | "enablehscroll" : 1, 33 | "enablevscroll" : 1, 34 | "devicewidth" : 0.0, 35 | "description" : "", 36 | "digest" : "", 37 | "tags" : "", 38 | "style" : "", 39 | "subpatcher_template" : "", 40 | "boxes" : [ { 41 | "box" : { 42 | "bubble" : 1, 43 | "bubbleside" : 2, 44 | "id" : "obj-12", 45 | "linecount" : 4, 46 | "maxclass" : "comment", 47 | "numinlets" : 1, 48 | "numoutlets" : 0, 49 | "patching_rect" : [ 454.5, 268.5, 150.0, 79.0 ], 50 | "presentation_linecount" : 4, 51 | "text" : "This object is called node.debug, it can be used to observe the state of the script." 52 | } 53 | 54 | } 55 | , { 56 | "box" : { 57 | "bubble" : 1, 58 | "id" : "obj-11", 59 | "linecount" : 2, 60 | "maxclass" : "comment", 61 | "numinlets" : 1, 62 | "numoutlets" : 0, 63 | "patching_rect" : [ 175.5, 187.5, 139.0, 37.0 ], 64 | "presentation_linecount" : 2, 65 | "text" : "2. The \"script stop\" message will stop it" 66 | } 67 | 68 | } 69 | , { 70 | "box" : { 71 | "bubble" : 1, 72 | "id" : "obj-10", 73 | "linecount" : 2, 74 | "maxclass" : "comment", 75 | "numinlets" : 1, 76 | "numoutlets" : 0, 77 | "patching_rect" : [ 123.5, 136.5, 170.0, 37.0 ], 78 | "presentation_linecount" : 3, 79 | "text" : "1. Send the \"script start\" message to start the script" 80 | } 81 | 82 | } 83 | , { 84 | "box" : { 85 | "id" : "obj-9", 86 | "maxclass" : "newobj", 87 | "numinlets" : 1, 88 | "numoutlets" : 0, 89 | "patching_rect" : [ 46.0, 311.0, 91.0, 22.0 ], 90 | "text" : "print @popup 1" 91 | } 92 | 93 | } 94 | , { 95 | "box" : { 96 | "id" : "obj-8", 97 | "maxclass" : "message", 98 | "numinlets" : 2, 99 | "numoutlets" : 1, 100 | "outlettype" : [ "" ], 101 | "patching_rect" : [ 99.0, 195.0, 63.0, 22.0 ], 102 | "text" : "script stop" 103 | } 104 | 105 | } 106 | , { 107 | "box" : { 108 | "id" : "obj-6", 109 | "maxclass" : "message", 110 | "numinlets" : 2, 111 | "numoutlets" : 1, 112 | "outlettype" : [ "" ], 113 | "patching_rect" : [ 46.0, 144.0, 64.0, 22.0 ], 114 | "text" : "script start" 115 | } 116 | 117 | } 118 | , { 119 | "box" : { 120 | "fontname" : "Lato Regular", 121 | "fontsize" : 13.0, 122 | "id" : "obj-2", 123 | "linecount" : 2, 124 | "maxclass" : "comment", 125 | "numinlets" : 1, 126 | "numoutlets" : 0, 127 | "patching_rect" : [ 10.0, 79.0, 578.0, 38.0 ], 128 | "presentation_linecount" : 3, 129 | "text" : "The node.script object runs a Node script in a separate process. Using the max-api package, you can communicate with the parent Max process." 130 | } 131 | 132 | } 133 | , { 134 | "box" : { 135 | "fontname" : "Lato Regular", 136 | "fontsize" : 48.0, 137 | "id" : "obj-63", 138 | "maxclass" : "comment", 139 | "numinlets" : 1, 140 | "numoutlets" : 0, 141 | "patching_rect" : [ 10.0, 10.0, 360.0, 64.0 ], 142 | "presentation_linecount" : 3, 143 | "text" : "00 - Hello World" 144 | } 145 | 146 | } 147 | , { 148 | "box" : { 149 | "bubble" : 1, 150 | "id" : "obj-39", 151 | "linecount" : 2, 152 | "maxclass" : "comment", 153 | "numinlets" : 1, 154 | "numoutlets" : 0, 155 | "patching_rect" : [ 204.5, 248.5, 150.0, 37.0 ], 156 | "text" : "Double-click to view hello.world.js" 157 | } 158 | 159 | } 160 | , { 161 | "box" : { 162 | "bgmode" : 0, 163 | "border" : 0, 164 | "clickthrough" : 0, 165 | "enablehscroll" : 0, 166 | "enablevscroll" : 0, 167 | "id" : "obj-5", 168 | "lockeddragscroll" : 0, 169 | "maxclass" : "bpatcher", 170 | "name" : "n4m.monitor.maxpat", 171 | "numinlets" : 1, 172 | "numoutlets" : 1, 173 | "offset" : [ 0.0, 0.0 ], 174 | "outlettype" : [ "bang" ], 175 | "patching_rect" : [ 204.5, 356.0, 400.0, 220.0 ], 176 | "viewvisibility" : 1 177 | } 178 | 179 | } 180 | , { 181 | "box" : { 182 | "id" : "obj-1", 183 | "maxclass" : "newobj", 184 | "numinlets" : 1, 185 | "numoutlets" : 2, 186 | "outlettype" : [ "", "" ], 187 | "patching_rect" : [ 46.0, 256.0, 141.0, 22.0 ], 188 | "saved_object_attributes" : { 189 | "autostart" : 0, 190 | "defer" : 0, 191 | "node_bin_path" : "", 192 | "npm_bin_path" : "", 193 | "watch" : 0 194 | } 195 | , 196 | "text" : "node.script hello-world.js" 197 | } 198 | 199 | } 200 | ], 201 | "lines" : [ { 202 | "patchline" : { 203 | "destination" : [ "obj-5", 0 ], 204 | "source" : [ "obj-1", 1 ] 205 | } 206 | 207 | } 208 | , { 209 | "patchline" : { 210 | "destination" : [ "obj-9", 0 ], 211 | "source" : [ "obj-1", 0 ] 212 | } 213 | 214 | } 215 | , { 216 | "patchline" : { 217 | "destination" : [ "obj-1", 0 ], 218 | "source" : [ "obj-6", 0 ] 219 | } 220 | 221 | } 222 | , { 223 | "patchline" : { 224 | "destination" : [ "obj-1", 0 ], 225 | "source" : [ "obj-8", 0 ] 226 | } 227 | 228 | } 229 | ], 230 | "dependency_cache" : [ { 231 | "name" : "hello-world.js", 232 | "bootpath" : "~/git/n4m-core-examples/00-hello-world", 233 | "patcherrelativepath" : ".", 234 | "type" : "TEXT", 235 | "implicit" : 1 236 | } 237 | , { 238 | "name" : "n4m.monitor.maxpat", 239 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 240 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 241 | "type" : "JSON", 242 | "implicit" : 1 243 | } 244 | , { 245 | "name" : "resize_n4m_monitor_patcher.js", 246 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 247 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 248 | "type" : "TEXT", 249 | "implicit" : 1 250 | } 251 | , { 252 | "name" : "fit_jweb_to_bounds.js", 253 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 254 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 255 | "type" : "TEXT", 256 | "implicit" : 1 257 | } 258 | ], 259 | "autosave" : 0, 260 | "styles" : [ { 261 | "name" : "light", 262 | "default" : { 263 | "fontsize" : [ 32.0 ], 264 | "textcolor_inverse" : [ 0.0, 0.0, 0.0, 1.0 ], 265 | "bgfillcolor" : { 266 | "type" : "color", 267 | "color1" : [ 1.0, 1.0, 1.0, 1.0 ], 268 | "color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 269 | "color" : [ 0.65098, 0.666667, 0.662745, 1.0 ], 270 | "angle" : 270.0, 271 | "proportion" : 0.39, 272 | "autogradient" : 0.0 273 | } 274 | 275 | } 276 | , 277 | "parentstyle" : "", 278 | "multi" : 0 279 | } 280 | ] 281 | } 282 | 283 | } 284 | -------------------------------------------------------------------------------- /01-syntax-error/README.md: -------------------------------------------------------------------------------- 1 | # Syntax Error 2 | 3 | This example shows you how to diagnose a syntax error using `[node.debug]` 4 | -------------------------------------------------------------------------------- /01-syntax-error/syntax-error.js: -------------------------------------------------------------------------------- 1 | const x = 100; 2 | const y = 200; 3 | 4 | const out = (x + y; // syntax error 5 | -------------------------------------------------------------------------------- /01-syntax-error/syntax-error.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 8, 6 | "minor" : 0, 7 | "revision" : 3, 8 | "architecture" : "x64", 9 | "modernui" : 1 10 | } 11 | , 12 | "classnamespace" : "box", 13 | "rect" : [ 100.0, 100.0, 911.0, 630.0 ], 14 | "bglocked" : 0, 15 | "openinpresentation" : 0, 16 | "default_fontsize" : 12.0, 17 | "default_fontface" : 0, 18 | "default_fontname" : "Arial", 19 | "gridonopen" : 1, 20 | "gridsize" : [ 15.0, 15.0 ], 21 | "gridsnaponopen" : 1, 22 | "objectsnaponopen" : 1, 23 | "statusbarvisible" : 2, 24 | "toolbarvisible" : 1, 25 | "lefttoolbarpinned" : 0, 26 | "toptoolbarpinned" : 0, 27 | "righttoolbarpinned" : 0, 28 | "bottomtoolbarpinned" : 0, 29 | "toolbars_unpinned_last_save" : 0, 30 | "tallnewobj" : 0, 31 | "boxanimatetime" : 200, 32 | "enablehscroll" : 1, 33 | "enablevscroll" : 1, 34 | "devicewidth" : 0.0, 35 | "description" : "", 36 | "digest" : "", 37 | "tags" : "", 38 | "style" : "", 39 | "subpatcher_template" : "", 40 | "boxes" : [ { 41 | "box" : { 42 | "bubble" : 1, 43 | "id" : "obj-4", 44 | "linecount" : 3, 45 | "maxclass" : "comment", 46 | "numinlets" : 1, 47 | "numoutlets" : 0, 48 | "patching_rect" : [ 631.5, 386.5, 218.0, 51.0 ], 49 | "presentation_linecount" : 3, 50 | "text" : "2. This will show you the line in the source file where the script encountered an error." 51 | } 52 | 53 | } 54 | , { 55 | "box" : { 56 | "bubble" : 1, 57 | "id" : "obj-3", 58 | "linecount" : 7, 59 | "maxclass" : "comment", 60 | "numinlets" : 1, 61 | "numoutlets" : 0, 62 | "patching_rect" : [ 631.5, 446.5, 217.0, 104.0 ], 63 | "presentation_linecount" : 30, 64 | "text" : "3. You should see here a \"SyntaxError: Unexpected token ;\", followed by a stack trace. In this case, all of the frames are in library code, but the stack trace can be useful for diagnosing errors that you encounter in your own code." 65 | } 66 | 67 | } 68 | , { 69 | "box" : { 70 | "bubble" : 1, 71 | "id" : "obj-10", 72 | "linecount" : 2, 73 | "maxclass" : "comment", 74 | "numinlets" : 1, 75 | "numoutlets" : 0, 76 | "patching_rect" : [ 122.5, 132.5, 77.0, 37.0 ], 77 | "text" : "1. Start the script" 78 | } 79 | 80 | } 81 | , { 82 | "box" : { 83 | "id" : "obj-6", 84 | "maxclass" : "message", 85 | "numinlets" : 2, 86 | "numoutlets" : 1, 87 | "outlettype" : [ "" ], 88 | "patching_rect" : [ 46.0, 140.0, 64.0, 22.0 ], 89 | "text" : "script start" 90 | } 91 | 92 | } 93 | , { 94 | "box" : { 95 | "fontname" : "Lato Regular", 96 | "fontsize" : 13.0, 97 | "id" : "obj-2", 98 | "maxclass" : "comment", 99 | "numinlets" : 1, 100 | "numoutlets" : 0, 101 | "patching_rect" : [ 10.0, 79.0, 880.0, 22.0 ], 102 | "text" : "This node.script object tries to run a script with a syntax error. When there is a mistake in the code, you can use the node.debug tool to see what's wrong." 103 | } 104 | 105 | } 106 | , { 107 | "box" : { 108 | "fontname" : "Lato Regular", 109 | "fontsize" : 48.0, 110 | "id" : "obj-63", 111 | "maxclass" : "comment", 112 | "numinlets" : 1, 113 | "numoutlets" : 0, 114 | "patching_rect" : [ 10.0, 10.0, 366.0, 64.0 ], 115 | "text" : "01 - Syntax Error" 116 | } 117 | 118 | } 119 | , { 120 | "box" : { 121 | "bgmode" : 0, 122 | "border" : 0, 123 | "clickthrough" : 0, 124 | "enablehscroll" : 0, 125 | "enablevscroll" : 0, 126 | "id" : "obj-5", 127 | "lockeddragscroll" : 0, 128 | "maxclass" : "bpatcher", 129 | "name" : "n4m.monitor.maxpat", 130 | "numinlets" : 1, 131 | "numoutlets" : 1, 132 | "offset" : [ 0.0, 0.0 ], 133 | "outlettype" : [ "bang" ], 134 | "patching_rect" : [ 46.0, 266.0, 567.0, 336.0 ], 135 | "viewvisibility" : 1 136 | } 137 | 138 | } 139 | , { 140 | "box" : { 141 | "id" : "obj-1", 142 | "maxclass" : "newobj", 143 | "numinlets" : 1, 144 | "numoutlets" : 2, 145 | "outlettype" : [ "", "" ], 146 | "patching_rect" : [ 46.0, 200.0, 146.0, 22.0 ], 147 | "saved_object_attributes" : { 148 | "autostart" : 0, 149 | "defer" : 0, 150 | "node_bin_path" : "", 151 | "npm_bin_path" : "", 152 | "watch" : 0 153 | } 154 | , 155 | "text" : "node.script syntax-error.js" 156 | } 157 | 158 | } 159 | ], 160 | "lines" : [ { 161 | "patchline" : { 162 | "destination" : [ "obj-5", 0 ], 163 | "source" : [ "obj-1", 1 ] 164 | } 165 | 166 | } 167 | , { 168 | "patchline" : { 169 | "destination" : [ "obj-1", 0 ], 170 | "source" : [ "obj-6", 0 ] 171 | } 172 | 173 | } 174 | ], 175 | "dependency_cache" : [ { 176 | "name" : "syntax-error.js", 177 | "bootpath" : "~/git/n4m-core-examples/01-syntax-error", 178 | "patcherrelativepath" : ".", 179 | "type" : "TEXT", 180 | "implicit" : 1 181 | } 182 | , { 183 | "name" : "n4m.monitor.maxpat", 184 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 185 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 186 | "type" : "JSON", 187 | "implicit" : 1 188 | } 189 | , { 190 | "name" : "resize_n4m_monitor_patcher.js", 191 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 192 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 193 | "type" : "TEXT", 194 | "implicit" : 1 195 | } 196 | , { 197 | "name" : "fit_jweb_to_bounds.js", 198 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 199 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 200 | "type" : "TEXT", 201 | "implicit" : 1 202 | } 203 | ], 204 | "autosave" : 0, 205 | "styles" : [ { 206 | "name" : "light", 207 | "default" : { 208 | "fontsize" : [ 32.0 ], 209 | "textcolor_inverse" : [ 0.0, 0.0, 0.0, 1.0 ], 210 | "bgfillcolor" : { 211 | "type" : "color", 212 | "color1" : [ 1.0, 1.0, 1.0, 1.0 ], 213 | "color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 214 | "color" : [ 0.65098, 0.666667, 0.662745, 1.0 ], 215 | "angle" : 270.0, 216 | "proportion" : 0.39, 217 | "autogradient" : 0.0 218 | } 219 | 220 | } 221 | , 222 | "parentstyle" : "", 223 | "multi" : 0 224 | } 225 | ] 226 | } 227 | 228 | } 229 | -------------------------------------------------------------------------------- /02-message-handlers/README.md: -------------------------------------------------------------------------------- 1 | # Message Handlers 2 | 3 | This example demonstrates how to add handlers to a `[node.script]` object, so that it can respond to messages from Max. 4 | -------------------------------------------------------------------------------- /02-message-handlers/message-handlers.js: -------------------------------------------------------------------------------- 1 | // Include the Max API library 2 | let maxApi = require("max-api"); 3 | 4 | // addHandler takes two arguments. The first is a selector. The node.script 5 | // object will call this function whenever it gets a message whose first 6 | // element is the symbol "double". The second argument to addHandler is a 7 | // function that will receive the rest of the message sent to node.script. 8 | // Here, the function is declared using "big arrow" syntax for declaring 9 | // an anonymous function. See: 10 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions 11 | maxApi.addHandler("double", (x) => { 12 | maxApi.outlet(2 * x); 13 | }); 14 | 15 | // In order to accept a variable number of arguments, you can use the spread 16 | // operator. This handler will accept messages like [sum 41], [sum 1 2 3] or 17 | // even [sum 4 5 6 7 8 9 2 4 3 36]. It will return the sum of the remaining 18 | // elements of the Max list. 19 | maxApi.addHandler("sum", (...elements) => { 20 | // elements will be an array of the remaining elements of the list. 21 | let total = 0; 22 | for (let i = 0; i < elements.length; i++) { 23 | total = total + elements[i]; 24 | } 25 | maxApi.outlet(total); 26 | }); 27 | -------------------------------------------------------------------------------- /02-message-handlers/message-handlers.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 8, 6 | "minor" : 0, 7 | "revision" : 3, 8 | "architecture" : "x64", 9 | "modernui" : 1 10 | } 11 | , 12 | "classnamespace" : "box", 13 | "rect" : [ 100.0, 100.0, 656.0, 630.0 ], 14 | "bglocked" : 0, 15 | "openinpresentation" : 0, 16 | "default_fontsize" : 12.0, 17 | "default_fontface" : 0, 18 | "default_fontname" : "Arial", 19 | "gridonopen" : 1, 20 | "gridsize" : [ 15.0, 15.0 ], 21 | "gridsnaponopen" : 1, 22 | "objectsnaponopen" : 1, 23 | "statusbarvisible" : 2, 24 | "toolbarvisible" : 1, 25 | "lefttoolbarpinned" : 0, 26 | "toptoolbarpinned" : 0, 27 | "righttoolbarpinned" : 0, 28 | "bottomtoolbarpinned" : 0, 29 | "toolbars_unpinned_last_save" : 0, 30 | "tallnewobj" : 0, 31 | "boxanimatetime" : 200, 32 | "enablehscroll" : 1, 33 | "enablevscroll" : 1, 34 | "devicewidth" : 0.0, 35 | "description" : "", 36 | "digest" : "", 37 | "tags" : "", 38 | "style" : "", 39 | "subpatcher_template" : "", 40 | "boxes" : [ { 41 | "box" : { 42 | "id" : "obj-14", 43 | "maxclass" : "number", 44 | "numinlets" : 1, 45 | "numoutlets" : 2, 46 | "outlettype" : [ "", "bang" ], 47 | "parameter_enable" : 0, 48 | "patching_rect" : [ 46.0, 331.0, 50.0, 22.0 ] 49 | } 50 | 51 | } 52 | , { 53 | "box" : { 54 | "id" : "obj-12", 55 | "maxclass" : "message", 56 | "numinlets" : 2, 57 | "numoutlets" : 1, 58 | "outlettype" : [ "" ], 59 | "patching_rect" : [ 279.5, 202.0, 101.0, 22.0 ], 60 | "presentation_linecount" : 3, 61 | "text" : "sum 1 2 3 4 5 6 6" 62 | } 63 | 64 | } 65 | , { 66 | "box" : { 67 | "id" : "obj-9", 68 | "maxclass" : "message", 69 | "numinlets" : 2, 70 | "numoutlets" : 1, 71 | "outlettype" : [ "" ], 72 | "patching_rect" : [ 218.5, 202.0, 48.0, 22.0 ], 73 | "text" : "sum 41" 74 | } 75 | 76 | } 77 | , { 78 | "box" : { 79 | "id" : "obj-7", 80 | "maxclass" : "message", 81 | "numinlets" : 2, 82 | "numoutlets" : 1, 83 | "outlettype" : [ "" ], 84 | "patching_rect" : [ 149.0, 202.0, 55.0, 22.0 ], 85 | "text" : "double 9" 86 | } 87 | 88 | } 89 | , { 90 | "box" : { 91 | "id" : "obj-4", 92 | "maxclass" : "message", 93 | "numinlets" : 2, 94 | "numoutlets" : 1, 95 | "outlettype" : [ "" ], 96 | "patching_rect" : [ 81.0, 202.0, 55.0, 22.0 ], 97 | "text" : "double 4" 98 | } 99 | 100 | } 101 | , { 102 | "box" : { 103 | "bubble" : 1, 104 | "id" : "obj-11", 105 | "linecount" : 2, 106 | "maxclass" : "comment", 107 | "numinlets" : 1, 108 | "numoutlets" : 0, 109 | "patching_rect" : [ 404.5, 194.5, 160.0, 37.0 ], 110 | "text" : "2. Try sending these messages to node.script" 111 | } 112 | 113 | } 114 | , { 115 | "box" : { 116 | "bubble" : 1, 117 | "id" : "obj-10", 118 | "linecount" : 2, 119 | "maxclass" : "comment", 120 | "numinlets" : 1, 121 | "numoutlets" : 0, 122 | "patching_rect" : [ 123.5, 136.5, 191.0, 37.0 ], 123 | "text" : "1. You must start the script before it will accept messages" 124 | } 125 | 126 | } 127 | , { 128 | "box" : { 129 | "id" : "obj-6", 130 | "maxclass" : "message", 131 | "numinlets" : 2, 132 | "numoutlets" : 1, 133 | "outlettype" : [ "" ], 134 | "patching_rect" : [ 46.0, 144.0, 64.0, 22.0 ], 135 | "text" : "script start" 136 | } 137 | 138 | } 139 | , { 140 | "box" : { 141 | "fontname" : "Lato Regular", 142 | "fontsize" : 13.0, 143 | "id" : "obj-2", 144 | "maxclass" : "comment", 145 | "numinlets" : 1, 146 | "numoutlets" : 0, 147 | "patching_rect" : [ 10.0, 79.0, 578.0, 22.0 ], 148 | "text" : "Use the addHandlers function in the max-api package to define entry points into Node from Max." 149 | } 150 | 151 | } 152 | , { 153 | "box" : { 154 | "fontname" : "Lato Regular", 155 | "fontsize" : 48.0, 156 | "id" : "obj-63", 157 | "maxclass" : "comment", 158 | "numinlets" : 1, 159 | "numoutlets" : 0, 160 | "patching_rect" : [ 10.0, 10.0, 492.0, 64.0 ], 161 | "text" : "02 - Message Handlers" 162 | } 163 | 164 | } 165 | , { 166 | "box" : { 167 | "bubble" : 1, 168 | "id" : "obj-39", 169 | "linecount" : 4, 170 | "maxclass" : "comment", 171 | "numinlets" : 1, 172 | "numoutlets" : 0, 173 | "patching_rect" : [ 247.5, 248.5, 150.0, 64.0 ], 174 | "text" : "3. Double-click to view message-handlers.js and to see how handlers are defined." 175 | } 176 | 177 | } 178 | , { 179 | "box" : { 180 | "bgmode" : 0, 181 | "border" : 0, 182 | "clickthrough" : 0, 183 | "enablehscroll" : 0, 184 | "enablevscroll" : 0, 185 | "id" : "obj-5", 186 | "lockeddragscroll" : 0, 187 | "maxclass" : "bpatcher", 188 | "name" : "n4m.monitor.maxpat", 189 | "numinlets" : 1, 190 | "numoutlets" : 1, 191 | "offset" : [ 0.0, 0.0 ], 192 | "outlettype" : [ "bang" ], 193 | "patching_rect" : [ 218.5, 382.0, 400.0, 220.0 ], 194 | "viewvisibility" : 1 195 | } 196 | 197 | } 198 | , { 199 | "box" : { 200 | "id" : "obj-1", 201 | "maxclass" : "newobj", 202 | "numinlets" : 1, 203 | "numoutlets" : 2, 204 | "outlettype" : [ "", "" ], 205 | "patching_rect" : [ 46.0, 269.5, 181.0, 22.0 ], 206 | "saved_object_attributes" : { 207 | "autostart" : 0, 208 | "defer" : 0, 209 | "node_bin_path" : "", 210 | "npm_bin_path" : "", 211 | "watch" : 0 212 | } 213 | , 214 | "text" : "node.script message-handlers.js" 215 | } 216 | 217 | } 218 | ], 219 | "lines" : [ { 220 | "patchline" : { 221 | "destination" : [ "obj-14", 0 ], 222 | "source" : [ "obj-1", 0 ] 223 | } 224 | 225 | } 226 | , { 227 | "patchline" : { 228 | "destination" : [ "obj-5", 0 ], 229 | "source" : [ "obj-1", 1 ] 230 | } 231 | 232 | } 233 | , { 234 | "patchline" : { 235 | "destination" : [ "obj-1", 0 ], 236 | "source" : [ "obj-12", 0 ] 237 | } 238 | 239 | } 240 | , { 241 | "patchline" : { 242 | "destination" : [ "obj-1", 0 ], 243 | "source" : [ "obj-4", 0 ] 244 | } 245 | 246 | } 247 | , { 248 | "patchline" : { 249 | "destination" : [ "obj-1", 0 ], 250 | "source" : [ "obj-6", 0 ] 251 | } 252 | 253 | } 254 | , { 255 | "patchline" : { 256 | "destination" : [ "obj-1", 0 ], 257 | "source" : [ "obj-7", 0 ] 258 | } 259 | 260 | } 261 | , { 262 | "patchline" : { 263 | "destination" : [ "obj-1", 0 ], 264 | "source" : [ "obj-9", 0 ] 265 | } 266 | 267 | } 268 | ], 269 | "dependency_cache" : [ { 270 | "name" : "message-handlers.js", 271 | "bootpath" : "~/git/n4m-core-examples/02-message-handlers", 272 | "patcherrelativepath" : ".", 273 | "type" : "TEXT", 274 | "implicit" : 1 275 | } 276 | , { 277 | "name" : "n4m.monitor.maxpat", 278 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 279 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 280 | "type" : "JSON", 281 | "implicit" : 1 282 | } 283 | , { 284 | "name" : "resize_n4m_monitor_patcher.js", 285 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 286 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 287 | "type" : "TEXT", 288 | "implicit" : 1 289 | } 290 | , { 291 | "name" : "fit_jweb_to_bounds.js", 292 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 293 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 294 | "type" : "TEXT", 295 | "implicit" : 1 296 | } 297 | ], 298 | "autosave" : 0, 299 | "styles" : [ { 300 | "name" : "light", 301 | "default" : { 302 | "fontsize" : [ 32.0 ], 303 | "textcolor_inverse" : [ 0.0, 0.0, 0.0, 1.0 ], 304 | "bgfillcolor" : { 305 | "type" : "color", 306 | "color1" : [ 1.0, 1.0, 1.0, 1.0 ], 307 | "color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 308 | "color" : [ 0.65098, 0.666667, 0.662745, 1.0 ], 309 | "angle" : 270.0, 310 | "proportion" : 0.39, 311 | "autogradient" : 0.0 312 | } 313 | 314 | } 315 | , 316 | "parentstyle" : "", 317 | "multi" : 0 318 | } 319 | ] 320 | } 321 | 322 | } 323 | -------------------------------------------------------------------------------- /03-message-types/README.md: -------------------------------------------------------------------------------- 1 | # Message Handlers 2 | 3 | This example demonstrates how to use the built-in MESSAGE_TYPES for attaching handlers to a `[node.script]` object. 4 | -------------------------------------------------------------------------------- /03-message-types/message-types.js: -------------------------------------------------------------------------------- 1 | // Include the Max API library 2 | let maxApi = require("max-api"); 3 | 4 | // Convenience access to MESSAGE_TYPES 5 | const MESSAGE_TYPES = maxApi.MESSAGE_TYPES; 6 | 7 | // MESSAGE_TYPES supports 4 built-in types: 8 | // ALL for handling all messages to node.script 9 | // BANG for handling all bang messages to node.script 10 | // NUMBER for handling number input 11 | // LIST for handling list input 12 | // DICT for handling dict input 13 | 14 | maxApi.addHandler(MESSAGE_TYPES.BANG, async () => { 15 | await maxApi.outlet("handler", "received: bang"); 16 | }); 17 | 18 | maxApi.addHandler(MESSAGE_TYPES.NUMBER, async (num) => { 19 | await maxApi.outlet("handler", `received number: ${num}`); 20 | }); 21 | 22 | maxApi.addHandler(MESSAGE_TYPES.LIST, async (...args) => { 23 | await maxApi.outlet("handler", `received list: ${args.join(", ")}`); 24 | }); 25 | 26 | maxApi.addHandler(MESSAGE_TYPES.DICT, async (dict) => { 27 | await maxApi.outlet("handler", `received dict: ${JSON.stringify(dict)}`); 28 | }); 29 | 30 | // We are using the ALL type to implement a logger that catches all input 31 | // the first argument indicates whether the message has been processed by any handler before 32 | // the second argument indicates the type or selector of the message 33 | maxApi.addHandler(MESSAGE_TYPES.ALL, async (handled, selector, ...msg) => { 34 | await maxApi.outlet("log", ...msg); 35 | }); 36 | -------------------------------------------------------------------------------- /03-message-types/message-types.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 8, 6 | "minor" : 0, 7 | "revision" : 2, 8 | "architecture" : "x64", 9 | "modernui" : 1 10 | } 11 | , 12 | "classnamespace" : "box", 13 | "rect" : [ 100.0, 100.0, 677.0, 630.0 ], 14 | "bglocked" : 0, 15 | "openinpresentation" : 0, 16 | "default_fontsize" : 12.0, 17 | "default_fontface" : 0, 18 | "default_fontname" : "Arial", 19 | "gridonopen" : 1, 20 | "gridsize" : [ 15.0, 15.0 ], 21 | "gridsnaponopen" : 1, 22 | "objectsnaponopen" : 1, 23 | "statusbarvisible" : 2, 24 | "toolbarvisible" : 1, 25 | "lefttoolbarpinned" : 0, 26 | "toptoolbarpinned" : 0, 27 | "righttoolbarpinned" : 0, 28 | "bottomtoolbarpinned" : 0, 29 | "toolbars_unpinned_last_save" : 0, 30 | "tallnewobj" : 0, 31 | "boxanimatetime" : 200, 32 | "enablehscroll" : 1, 33 | "enablevscroll" : 1, 34 | "devicewidth" : 0.0, 35 | "description" : "", 36 | "digest" : "", 37 | "tags" : "", 38 | "style" : "", 39 | "subpatcher_template" : "", 40 | "boxes" : [ { 41 | "box" : { 42 | "id" : "obj-24", 43 | "maxclass" : "newobj", 44 | "numinlets" : 1, 45 | "numoutlets" : 1, 46 | "outlettype" : [ "" ], 47 | "patching_rect" : [ 46.0, 353.0, 72.0, 22.0 ], 48 | "text" : "prepend set" 49 | } 50 | 51 | } 52 | , { 53 | "box" : { 54 | "id" : "obj-23", 55 | "maxclass" : "comment", 56 | "numinlets" : 1, 57 | "numoutlets" : 0, 58 | "patching_rect" : [ 46.0, 398.0, 150.0, 20.0 ], 59 | "text" : "received: bang" 60 | } 61 | 62 | } 63 | , { 64 | "box" : { 65 | "id" : "obj-19", 66 | "maxclass" : "button", 67 | "numinlets" : 1, 68 | "numoutlets" : 1, 69 | "outlettype" : [ "bang" ], 70 | "parameter_enable" : 0, 71 | "patching_rect" : [ 265.0, 163.0, 24.0, 24.0 ] 72 | } 73 | 74 | } 75 | , { 76 | "box" : { 77 | "data" : { 78 | "type" : "dict" 79 | } 80 | , 81 | "id" : "obj-17", 82 | "maxclass" : "newobj", 83 | "numinlets" : 2, 84 | "numoutlets" : 4, 85 | "outlettype" : [ "dictionary", "", "", "" ], 86 | "patching_rect" : [ 265.0, 202.0, 89.0, 22.0 ], 87 | "saved_object_attributes" : { 88 | "embed" : 1, 89 | "parameter_enable" : 0, 90 | "parameter_mappable" : 0 91 | } 92 | , 93 | "text" : "dict @embed 1" 94 | } 95 | 96 | } 97 | , { 98 | "box" : { 99 | "id" : "obj-16", 100 | "maxclass" : "message", 101 | "numinlets" : 2, 102 | "numoutlets" : 1, 103 | "outlettype" : [ "" ], 104 | "patching_rect" : [ 68.0, 142.0, 63.0, 22.0 ], 105 | "text" : "script stop" 106 | } 107 | 108 | } 109 | , { 110 | "box" : { 111 | "id" : "obj-15", 112 | "maxclass" : "number", 113 | "numinlets" : 1, 114 | "numoutlets" : 2, 115 | "outlettype" : [ "", "bang" ], 116 | "parameter_enable" : 0, 117 | "patching_rect" : [ 129.0, 202.0, 50.0, 22.0 ] 118 | } 119 | 120 | } 121 | , { 122 | "box" : { 123 | "id" : "obj-13", 124 | "maxclass" : "newobj", 125 | "numinlets" : 1, 126 | "numoutlets" : 0, 127 | "patching_rect" : [ 129.0, 353.0, 91.0, 22.0 ], 128 | "text" : "print @popup 1" 129 | } 130 | 131 | } 132 | , { 133 | "box" : { 134 | "id" : "obj-8", 135 | "maxclass" : "newobj", 136 | "numinlets" : 3, 137 | "numoutlets" : 3, 138 | "outlettype" : [ "", "", "" ], 139 | "patching_rect" : [ 46.0, 312.0, 185.0, 22.0 ], 140 | "text" : "route handler log" 141 | } 142 | 143 | } 144 | , { 145 | "box" : { 146 | "id" : "obj-4", 147 | "maxclass" : "button", 148 | "numinlets" : 1, 149 | "numoutlets" : 1, 150 | "outlettype" : [ "bang" ], 151 | "parameter_enable" : 0, 152 | "patching_rect" : [ 81.0, 202.0, 24.0, 24.0 ] 153 | } 154 | 155 | } 156 | , { 157 | "box" : { 158 | "id" : "obj-9", 159 | "maxclass" : "message", 160 | "numinlets" : 2, 161 | "numoutlets" : 1, 162 | "outlettype" : [ "" ], 163 | "patching_rect" : [ 195.0, 202.0, 45.0, 22.0 ], 164 | "text" : "1 2 3 4" 165 | } 166 | 167 | } 168 | , { 169 | "box" : { 170 | "bubble" : 1, 171 | "id" : "obj-11", 172 | "linecount" : 2, 173 | "maxclass" : "comment", 174 | "numinlets" : 1, 175 | "numoutlets" : 0, 176 | "patching_rect" : [ 385.5, 194.5, 189.0, 37.0 ], 177 | "text" : "2. Try sending these messages to node.script" 178 | } 179 | 180 | } 181 | , { 182 | "box" : { 183 | "bubble" : 1, 184 | "id" : "obj-10", 185 | "linecount" : 2, 186 | "maxclass" : "comment", 187 | "numinlets" : 1, 188 | "numoutlets" : 0, 189 | "patching_rect" : [ 126.5, 108.5, 191.0, 37.0 ], 190 | "text" : "1. You must start the script before it will accept messages" 191 | } 192 | 193 | } 194 | , { 195 | "box" : { 196 | "id" : "obj-6", 197 | "maxclass" : "message", 198 | "numinlets" : 2, 199 | "numoutlets" : 1, 200 | "outlettype" : [ "" ], 201 | "patching_rect" : [ 49.0, 116.0, 64.0, 22.0 ], 202 | "text" : "script start" 203 | } 204 | 205 | } 206 | , { 207 | "box" : { 208 | "fontname" : "Lato Regular", 209 | "fontsize" : 13.0, 210 | "id" : "obj-2", 211 | "maxclass" : "comment", 212 | "numinlets" : 1, 213 | "numoutlets" : 0, 214 | "patching_rect" : [ 10.0, 79.0, 578.0, 22.0 ], 215 | "text" : "Use MESSAGE_TYPES in the max-api package to add handlers for typical Max types." 216 | } 217 | 218 | } 219 | , { 220 | "box" : { 221 | "fontname" : "Lato Regular", 222 | "fontsize" : 48.0, 223 | "id" : "obj-63", 224 | "maxclass" : "comment", 225 | "numinlets" : 1, 226 | "numoutlets" : 0, 227 | "patching_rect" : [ 10.0, 10.0, 492.0, 64.0 ], 228 | "text" : "03 - Message Types" 229 | } 230 | 231 | } 232 | , { 233 | "box" : { 234 | "bubble" : 1, 235 | "id" : "obj-39", 236 | "linecount" : 5, 237 | "maxclass" : "comment", 238 | "numinlets" : 1, 239 | "numoutlets" : 0, 240 | "patching_rect" : [ 252.0, 241.5, 150.0, 78.0 ], 241 | "text" : "3. Double-click to view message-types.js and to see how to use built-in messages types" 242 | } 243 | 244 | } 245 | , { 246 | "box" : { 247 | "bgmode" : 0, 248 | "border" : 0, 249 | "clickthrough" : 0, 250 | "enablehscroll" : 0, 251 | "enablevscroll" : 0, 252 | "id" : "obj-5", 253 | "lockeddragscroll" : 0, 254 | "maxclass" : "bpatcher", 255 | "name" : "n4m.monitor.maxpat", 256 | "numinlets" : 1, 257 | "numoutlets" : 1, 258 | "offset" : [ 0.0, 0.0 ], 259 | "outlettype" : [ "bang" ], 260 | "patching_rect" : [ 259.5, 332.0, 400.0, 220.0 ], 261 | "viewvisibility" : 1 262 | } 263 | 264 | } 265 | , { 266 | "box" : { 267 | "id" : "obj-1", 268 | "maxclass" : "newobj", 269 | "numinlets" : 1, 270 | "numoutlets" : 2, 271 | "outlettype" : [ "", "" ], 272 | "patching_rect" : [ 46.0, 269.5, 164.0, 22.0 ], 273 | "saved_object_attributes" : { 274 | "autostart" : 0, 275 | "defer" : 0, 276 | "node_bin_path" : "", 277 | "npm_bin_path" : "", 278 | "watch" : 0 279 | } 280 | , 281 | "text" : "node.script message-types.js" 282 | } 283 | 284 | } 285 | ], 286 | "lines" : [ { 287 | "patchline" : { 288 | "destination" : [ "obj-5", 0 ], 289 | "source" : [ "obj-1", 1 ] 290 | } 291 | 292 | } 293 | , { 294 | "patchline" : { 295 | "destination" : [ "obj-8", 0 ], 296 | "source" : [ "obj-1", 0 ] 297 | } 298 | 299 | } 300 | , { 301 | "patchline" : { 302 | "destination" : [ "obj-1", 0 ], 303 | "source" : [ "obj-15", 0 ] 304 | } 305 | 306 | } 307 | , { 308 | "patchline" : { 309 | "destination" : [ "obj-1", 0 ], 310 | "source" : [ "obj-16", 0 ] 311 | } 312 | 313 | } 314 | , { 315 | "patchline" : { 316 | "destination" : [ "obj-1", 0 ], 317 | "source" : [ "obj-17", 0 ] 318 | } 319 | 320 | } 321 | , { 322 | "patchline" : { 323 | "destination" : [ "obj-17", 0 ], 324 | "source" : [ "obj-19", 0 ] 325 | } 326 | 327 | } 328 | , { 329 | "patchline" : { 330 | "destination" : [ "obj-23", 0 ], 331 | "source" : [ "obj-24", 0 ] 332 | } 333 | 334 | } 335 | , { 336 | "patchline" : { 337 | "destination" : [ "obj-1", 0 ], 338 | "source" : [ "obj-4", 0 ] 339 | } 340 | 341 | } 342 | , { 343 | "patchline" : { 344 | "destination" : [ "obj-1", 0 ], 345 | "source" : [ "obj-6", 0 ] 346 | } 347 | 348 | } 349 | , { 350 | "patchline" : { 351 | "destination" : [ "obj-13", 0 ], 352 | "source" : [ "obj-8", 1 ] 353 | } 354 | 355 | } 356 | , { 357 | "patchline" : { 358 | "destination" : [ "obj-24", 0 ], 359 | "source" : [ "obj-8", 0 ] 360 | } 361 | 362 | } 363 | , { 364 | "patchline" : { 365 | "destination" : [ "obj-1", 0 ], 366 | "source" : [ "obj-9", 0 ] 367 | } 368 | 369 | } 370 | ], 371 | "dependency_cache" : [ { 372 | "name" : "message-types.js", 373 | "bootpath" : "~/c74/n4m-core-examples/03-message-types", 374 | "patcherrelativepath" : ".", 375 | "type" : "TEXT", 376 | "implicit" : 1 377 | } 378 | , { 379 | "name" : "n4m.monitor.maxpat", 380 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 381 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 382 | "type" : "JSON", 383 | "implicit" : 1 384 | } 385 | , { 386 | "name" : "resize_n4m_monitor_patcher.js", 387 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 388 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 389 | "type" : "TEXT", 390 | "implicit" : 1 391 | } 392 | , { 393 | "name" : "fit_jweb_to_bounds.js", 394 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 395 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 396 | "type" : "TEXT", 397 | "implicit" : 1 398 | } 399 | ], 400 | "autosave" : 0, 401 | "styles" : [ { 402 | "name" : "light", 403 | "default" : { 404 | "textcolor_inverse" : [ 0.0, 0.0, 0.0, 1.0 ], 405 | "fontsize" : [ 32.0 ], 406 | "bgfillcolor" : { 407 | "type" : "color", 408 | "color1" : [ 1.0, 1.0, 1.0, 1.0 ], 409 | "color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 410 | "color" : [ 0.65098, 0.666667, 0.662745, 1.0 ], 411 | "angle" : 270.0, 412 | "proportion" : 0.39, 413 | "autogradient" : 0.0 414 | } 415 | 416 | } 417 | , 418 | "parentstyle" : "", 419 | "multi" : 0 420 | } 421 | ] 422 | } 423 | 424 | } 425 | -------------------------------------------------------------------------------- /04-outlet-methods/README.md: -------------------------------------------------------------------------------- 1 | # Outlet Methods 2 | 3 | The maxApi.outlet method can do a lot of useful things. This example demonstrates some of them. 4 | -------------------------------------------------------------------------------- /04-outlet-methods/outlet-methods.js: -------------------------------------------------------------------------------- 1 | // Include the Max API library 2 | let maxApi = require("max-api"); 3 | 4 | maxApi.addHandler("example1", () => { 5 | // When sending a result back from a handler, using maxApi.outlet, it's 6 | // common to include a selector as the first argument. This makes it 7 | // easier to route the message in Max. 8 | maxApi.outlet("example1", "result", 42); 9 | }); 10 | 11 | maxApi.addHandler("example2", () => { 12 | // maxApi.outlet can take any number of arguments. Each will be added 13 | // to a Max list and then sent out from node.script. If you want to 14 | // send an array back to Max, use the spread operator to "unpack" 15 | // the array across the arguments to maxApi.outlet. 16 | const returnArray = [4, 5, 6, "seven"]; 17 | maxApi.outlet("example2", ...returnArray); 18 | }); 19 | 20 | maxApi.addHandler("example3", () => { 21 | // If one of the arguments to maxApi.outlet is a JavaScript object, it 22 | // will be converted automatically into a Max dictionary. Note that this 23 | // will change the length of the list in Max, since a single dictionary 24 | // is represented by two symbols in a Max list: the symbol "dictionary", 25 | // followed by the unique name of the dictionary. 26 | maxApi.outlet("example3", { 27 | red: "red", 28 | green: "green", 29 | blue: 42 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /04-outlet-methods/outlet-methods.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 8, 6 | "minor" : 0, 7 | "revision" : 3, 8 | "architecture" : "x64", 9 | "modernui" : 1 10 | } 11 | , 12 | "classnamespace" : "box", 13 | "rect" : [ 100.0, 100.0, 970.0, 616.0 ], 14 | "bglocked" : 0, 15 | "openinpresentation" : 0, 16 | "default_fontsize" : 12.0, 17 | "default_fontface" : 0, 18 | "default_fontname" : "Arial", 19 | "gridonopen" : 1, 20 | "gridsize" : [ 15.0, 15.0 ], 21 | "gridsnaponopen" : 1, 22 | "objectsnaponopen" : 1, 23 | "statusbarvisible" : 2, 24 | "toolbarvisible" : 1, 25 | "lefttoolbarpinned" : 0, 26 | "toptoolbarpinned" : 0, 27 | "righttoolbarpinned" : 0, 28 | "bottomtoolbarpinned" : 0, 29 | "toolbars_unpinned_last_save" : 0, 30 | "tallnewobj" : 0, 31 | "boxanimatetime" : 200, 32 | "enablehscroll" : 1, 33 | "enablevscroll" : 1, 34 | "devicewidth" : 0.0, 35 | "description" : "", 36 | "digest" : "", 37 | "tags" : "", 38 | "style" : "", 39 | "subpatcher_template" : "", 40 | "boxes" : [ { 41 | "box" : { 42 | "id" : "obj-22", 43 | "maxclass" : "newobj", 44 | "numinlets" : 1, 45 | "numoutlets" : 1, 46 | "outlettype" : [ "" ], 47 | "patching_rect" : [ 276.666656494140625, 425.0, 72.0, 22.0 ], 48 | "text" : "prepend set" 49 | } 50 | 51 | } 52 | , { 53 | "box" : { 54 | "id" : "obj-23", 55 | "ignoreclick" : 1, 56 | "linecount" : 2, 57 | "maxclass" : "textedit", 58 | "numinlets" : 1, 59 | "numoutlets" : 4, 60 | "outlettype" : [ "", "int", "", "" ], 61 | "parameter_enable" : 0, 62 | "patching_rect" : [ 276.666656494140625, 464.0, 100.0, 50.0 ], 63 | "presentation_linecount" : 2, 64 | "text" : "dictionary u191008654" 65 | } 66 | 67 | } 68 | , { 69 | "box" : { 70 | "id" : "obj-21", 71 | "maxclass" : "newobj", 72 | "numinlets" : 1, 73 | "numoutlets" : 1, 74 | "outlettype" : [ "" ], 75 | "patching_rect" : [ 81.0, 383.0, 63.0, 22.0 ], 76 | "text" : "loadmess " 77 | } 78 | 79 | } 80 | , { 81 | "box" : { 82 | "id" : "obj-19", 83 | "maxclass" : "newobj", 84 | "numinlets" : 1, 85 | "numoutlets" : 1, 86 | "outlettype" : [ "" ], 87 | "patching_rect" : [ 46.0, 425.0, 72.0, 22.0 ], 88 | "text" : "prepend set" 89 | } 90 | 91 | } 92 | , { 93 | "box" : { 94 | "id" : "obj-20", 95 | "ignoreclick" : 1, 96 | "maxclass" : "textedit", 97 | "numinlets" : 1, 98 | "numoutlets" : 4, 99 | "outlettype" : [ "", "int", "", "" ], 100 | "parameter_enable" : 0, 101 | "patching_rect" : [ 46.0, 464.0, 100.0, 50.0 ], 102 | "text" : "result 42" 103 | } 104 | 105 | } 106 | , { 107 | "box" : { 108 | "id" : "obj-18", 109 | "maxclass" : "newobj", 110 | "numinlets" : 1, 111 | "numoutlets" : 1, 112 | "outlettype" : [ "" ], 113 | "patching_rect" : [ 161.333328247070312, 425.0, 72.0, 22.0 ], 114 | "text" : "prepend set" 115 | } 116 | 117 | } 118 | , { 119 | "box" : { 120 | "id" : "obj-17", 121 | "ignoreclick" : 1, 122 | "maxclass" : "textedit", 123 | "numinlets" : 1, 124 | "numoutlets" : 4, 125 | "outlettype" : [ "", "int", "", "" ], 126 | "parameter_enable" : 0, 127 | "patching_rect" : [ 161.333328247070312, 464.0, 100.0, 50.0 ], 128 | "text" : "4 5 6 seven" 129 | } 130 | 131 | } 132 | , { 133 | "box" : { 134 | "id" : "obj-15", 135 | "maxclass" : "dict.view", 136 | "numinlets" : 1, 137 | "numoutlets" : 0, 138 | "patching_rect" : [ 402.0, 425.0, 100.0, 100.0 ] 139 | } 140 | 141 | } 142 | , { 143 | "box" : { 144 | "id" : "obj-3", 145 | "maxclass" : "newobj", 146 | "numinlets" : 4, 147 | "numoutlets" : 4, 148 | "outlettype" : [ "", "", "", "" ], 149 | "patching_rect" : [ 46.0, 342.5, 365.0, 22.0 ], 150 | "text" : "route example1 example2 example3" 151 | } 152 | 153 | } 154 | , { 155 | "box" : { 156 | "id" : "obj-9", 157 | "maxclass" : "message", 158 | "numinlets" : 2, 159 | "numoutlets" : 1, 160 | "outlettype" : [ "" ], 161 | "patching_rect" : [ 218.5, 202.0, 61.0, 22.0 ], 162 | "text" : "example3" 163 | } 164 | 165 | } 166 | , { 167 | "box" : { 168 | "id" : "obj-7", 169 | "maxclass" : "message", 170 | "numinlets" : 2, 171 | "numoutlets" : 1, 172 | "outlettype" : [ "" ], 173 | "patching_rect" : [ 149.0, 202.0, 61.0, 22.0 ], 174 | "text" : "example2" 175 | } 176 | 177 | } 178 | , { 179 | "box" : { 180 | "id" : "obj-4", 181 | "maxclass" : "message", 182 | "numinlets" : 2, 183 | "numoutlets" : 1, 184 | "outlettype" : [ "" ], 185 | "patching_rect" : [ 81.0, 202.0, 61.0, 22.0 ], 186 | "text" : "example1" 187 | } 188 | 189 | } 190 | , { 191 | "box" : { 192 | "bubble" : 1, 193 | "id" : "obj-11", 194 | "linecount" : 2, 195 | "maxclass" : "comment", 196 | "numinlets" : 1, 197 | "numoutlets" : 0, 198 | "patching_rect" : [ 299.5, 194.5, 160.0, 37.0 ], 199 | "text" : "2. Try sending these messages to node.script" 200 | } 201 | 202 | } 203 | , { 204 | "box" : { 205 | "bubble" : 1, 206 | "id" : "obj-10", 207 | "linecount" : 2, 208 | "maxclass" : "comment", 209 | "numinlets" : 1, 210 | "numoutlets" : 0, 211 | "patching_rect" : [ 120.5, 136.5, 191.0, 37.0 ], 212 | "text" : "1. You must start the script before it will accept messages" 213 | } 214 | 215 | } 216 | , { 217 | "box" : { 218 | "id" : "obj-6", 219 | "maxclass" : "message", 220 | "numinlets" : 2, 221 | "numoutlets" : 1, 222 | "outlettype" : [ "" ], 223 | "patching_rect" : [ 46.0, 144.0, 64.0, 22.0 ], 224 | "text" : "script start" 225 | } 226 | 227 | } 228 | , { 229 | "box" : { 230 | "fontname" : "Lato Regular", 231 | "fontsize" : 13.0, 232 | "id" : "obj-2", 233 | "maxclass" : "comment", 234 | "numinlets" : 1, 235 | "numoutlets" : 0, 236 | "patching_rect" : [ 10.0, 79.0, 578.0, 22.0 ], 237 | "text" : "The maxApi.outlet function can be used in a number of ways to make your life easier." 238 | } 239 | 240 | } 241 | , { 242 | "box" : { 243 | "fontname" : "Lato Regular", 244 | "fontsize" : 48.0, 245 | "id" : "obj-63", 246 | "maxclass" : "comment", 247 | "numinlets" : 1, 248 | "numoutlets" : 0, 249 | "patching_rect" : [ 10.0, 10.0, 492.0, 64.0 ], 250 | "text" : "04 - Outlet Methods" 251 | } 252 | 253 | } 254 | , { 255 | "box" : { 256 | "bubble" : 1, 257 | "id" : "obj-39", 258 | "linecount" : 4, 259 | "maxclass" : "comment", 260 | "numinlets" : 1, 261 | "numoutlets" : 0, 262 | "patching_rect" : [ 247.5, 248.5, 150.0, 64.0 ], 263 | "text" : "3. Double-click to view outlet-methods.js and to see how handlers are defined." 264 | } 265 | 266 | } 267 | , { 268 | "box" : { 269 | "bgmode" : 0, 270 | "border" : 0, 271 | "clickthrough" : 0, 272 | "enablehscroll" : 0, 273 | "enablevscroll" : 0, 274 | "id" : "obj-5", 275 | "lockeddragscroll" : 0, 276 | "maxclass" : "bpatcher", 277 | "name" : "n4m.monitor.maxpat", 278 | "numinlets" : 1, 279 | "numoutlets" : 1, 280 | "offset" : [ 0.0, 0.0 ], 281 | "outlettype" : [ "bang" ], 282 | "patching_rect" : [ 531.5, 374.0, 400.0, 220.0 ], 283 | "viewvisibility" : 1 284 | } 285 | 286 | } 287 | , { 288 | "box" : { 289 | "id" : "obj-1", 290 | "maxclass" : "newobj", 291 | "numinlets" : 1, 292 | "numoutlets" : 2, 293 | "outlettype" : [ "", "" ], 294 | "patching_rect" : [ 46.0, 269.5, 162.0, 22.0 ], 295 | "saved_object_attributes" : { 296 | "autostart" : 0, 297 | "defer" : 0, 298 | "node_bin_path" : "", 299 | "npm_bin_path" : "", 300 | "watch" : 0 301 | } 302 | , 303 | "text" : "node.script outlet-methods.js" 304 | } 305 | 306 | } 307 | ], 308 | "lines" : [ { 309 | "patchline" : { 310 | "destination" : [ "obj-3", 0 ], 311 | "source" : [ "obj-1", 0 ] 312 | } 313 | 314 | } 315 | , { 316 | "patchline" : { 317 | "destination" : [ "obj-5", 0 ], 318 | "midpoints" : [ 198.5, 325.25, 541.0, 325.25 ], 319 | "source" : [ "obj-1", 1 ] 320 | } 321 | 322 | } 323 | , { 324 | "patchline" : { 325 | "destination" : [ "obj-17", 0 ], 326 | "source" : [ "obj-18", 0 ] 327 | } 328 | 329 | } 330 | , { 331 | "patchline" : { 332 | "destination" : [ "obj-20", 0 ], 333 | "source" : [ "obj-19", 0 ] 334 | } 335 | 336 | } 337 | , { 338 | "patchline" : { 339 | "destination" : [ "obj-18", 0 ], 340 | "order" : 1, 341 | "source" : [ "obj-21", 0 ] 342 | } 343 | 344 | } 345 | , { 346 | "patchline" : { 347 | "destination" : [ "obj-19", 0 ], 348 | "order" : 2, 349 | "source" : [ "obj-21", 0 ] 350 | } 351 | 352 | } 353 | , { 354 | "patchline" : { 355 | "destination" : [ "obj-22", 0 ], 356 | "order" : 0, 357 | "source" : [ "obj-21", 0 ] 358 | } 359 | 360 | } 361 | , { 362 | "patchline" : { 363 | "destination" : [ "obj-23", 0 ], 364 | "source" : [ "obj-22", 0 ] 365 | } 366 | 367 | } 368 | , { 369 | "patchline" : { 370 | "destination" : [ "obj-15", 0 ], 371 | "order" : 0, 372 | "source" : [ "obj-3", 2 ] 373 | } 374 | 375 | } 376 | , { 377 | "patchline" : { 378 | "destination" : [ "obj-18", 0 ], 379 | "source" : [ "obj-3", 1 ] 380 | } 381 | 382 | } 383 | , { 384 | "patchline" : { 385 | "destination" : [ "obj-19", 0 ], 386 | "source" : [ "obj-3", 0 ] 387 | } 388 | 389 | } 390 | , { 391 | "patchline" : { 392 | "destination" : [ "obj-22", 0 ], 393 | "order" : 1, 394 | "source" : [ "obj-3", 2 ] 395 | } 396 | 397 | } 398 | , { 399 | "patchline" : { 400 | "destination" : [ "obj-1", 0 ], 401 | "source" : [ "obj-4", 0 ] 402 | } 403 | 404 | } 405 | , { 406 | "patchline" : { 407 | "destination" : [ "obj-1", 0 ], 408 | "source" : [ "obj-6", 0 ] 409 | } 410 | 411 | } 412 | , { 413 | "patchline" : { 414 | "destination" : [ "obj-1", 0 ], 415 | "source" : [ "obj-7", 0 ] 416 | } 417 | 418 | } 419 | , { 420 | "patchline" : { 421 | "destination" : [ "obj-1", 0 ], 422 | "source" : [ "obj-9", 0 ] 423 | } 424 | 425 | } 426 | ], 427 | "dependency_cache" : [ { 428 | "name" : "outlet-methods.js", 429 | "bootpath" : "~/git/n4m-core-examples/03-outlet-methods", 430 | "patcherrelativepath" : ".", 431 | "type" : "TEXT", 432 | "implicit" : 1 433 | } 434 | , { 435 | "name" : "n4m.monitor.maxpat", 436 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 437 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 438 | "type" : "JSON", 439 | "implicit" : 1 440 | } 441 | , { 442 | "name" : "resize_n4m_monitor_patcher.js", 443 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 444 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 445 | "type" : "TEXT", 446 | "implicit" : 1 447 | } 448 | , { 449 | "name" : "fit_jweb_to_bounds.js", 450 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 451 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 452 | "type" : "TEXT", 453 | "implicit" : 1 454 | } 455 | ], 456 | "autosave" : 0, 457 | "styles" : [ { 458 | "name" : "light", 459 | "default" : { 460 | "fontsize" : [ 32.0 ], 461 | "textcolor_inverse" : [ 0.0, 0.0, 0.0, 1.0 ], 462 | "bgfillcolor" : { 463 | "type" : "color", 464 | "color1" : [ 1.0, 1.0, 1.0, 1.0 ], 465 | "color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 466 | "color" : [ 0.65098, 0.666667, 0.662745, 1.0 ], 467 | "angle" : 270.0, 468 | "proportion" : 0.39, 469 | "autogradient" : 0.0 470 | } 471 | 472 | } 473 | , 474 | "parentstyle" : "", 475 | "multi" : 0 476 | } 477 | ] 478 | } 479 | 480 | } 481 | -------------------------------------------------------------------------------- /05-dynamic-message-handlers/README.md: -------------------------------------------------------------------------------- 1 | # Adding and removing Message Handlers dynamically 2 | 3 | We have learned a simple way to attach handlers using `addHandler` in [02-message-handlers](../02-message-handlers). This shows how you can bulk add handlers with a single function call of `maxAPI.addHandlers`. Also we will cover how to register and deregister handlers dynamically. 4 | -------------------------------------------------------------------------------- /05-dynamic-message-handlers/dynamic-message-handlers.js: -------------------------------------------------------------------------------- 1 | const maxApi = require("max-api"); 2 | 3 | // A simple logger function to show us when an input message was received 4 | // We will also indicate whether a message has been handled or not. 5 | const logMessage = async (handled, selector, ...msg) => { 6 | await maxApi.outlet("log", `received ${handled ? "handled" : "unhandled" } message: ${msg && msg.length ? msg : selector}`); 7 | }; 8 | 9 | // Simple number duplicator 10 | const doubleNumber = async (num) => { 11 | await maxApi.outlet("double", num * 2); 12 | }; 13 | 14 | const tripleNumber = async (num) => { 15 | await maxApi.outlet("triple", num * 3); 16 | }; 17 | 18 | // Instead of calling addHandler we can also leverage addHandlers and register 19 | // a whole set of message handlers with a single statement. 20 | maxApi.addHandlers({ 21 | 22 | 23 | // You can use a computed property key to access f.e. a MESSAGE_TYPE 24 | // Learn more: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names 25 | [maxApi.MESSAGE_TYPES.ALL]: logMessage, 26 | 27 | // Dynamically attach a second handler for number input 28 | 29 | "enable_double": () => { 30 | maxApi.addHandler(maxApi.MESSAGE_TYPES.NUMBER, doubleNumber); 31 | }, 32 | 33 | "disable_double": () => { 34 | maxApi.removeHandler(maxApi.MESSAGE_TYPES.NUMBER, doubleNumber); 35 | }, 36 | 37 | "enable_triple": () => { 38 | maxApi.addHandler(maxApi.MESSAGE_TYPES.NUMBER, tripleNumber); 39 | }, 40 | 41 | // Dynamically detach the second number input handler 42 | "disable_triple": () => { 43 | maxApi.removeHandler(maxApi.MESSAGE_TYPES.NUMBER, tripleNumber); 44 | }, 45 | 46 | // Use removeHandlers to remove... 47 | // all handlers for a specific message type or all registered handlers... 48 | "remove_number_handlers": (msg) => { 49 | maxApi.removeHandlers(maxApi.MESSAGE_TYPES.NUMBER); 50 | }, 51 | 52 | // ...or all registered handlers alltogether 53 | "remove_all_handlers": () => { 54 | maxApi.removeHandlers(); 55 | } 56 | }); 57 | -------------------------------------------------------------------------------- /05-dynamic-message-handlers/dynamic-message-handlers.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 8, 6 | "minor" : 0, 7 | "revision" : 2, 8 | "architecture" : "x64", 9 | "modernui" : 1 10 | } 11 | , 12 | "classnamespace" : "box", 13 | "rect" : [ 100.0, 100.0, 970.0, 616.0 ], 14 | "bglocked" : 0, 15 | "openinpresentation" : 0, 16 | "default_fontsize" : 12.0, 17 | "default_fontface" : 0, 18 | "default_fontname" : "Arial", 19 | "gridonopen" : 1, 20 | "gridsize" : [ 15.0, 15.0 ], 21 | "gridsnaponopen" : 1, 22 | "objectsnaponopen" : 1, 23 | "statusbarvisible" : 2, 24 | "toolbarvisible" : 1, 25 | "lefttoolbarpinned" : 0, 26 | "toptoolbarpinned" : 0, 27 | "righttoolbarpinned" : 0, 28 | "bottomtoolbarpinned" : 0, 29 | "toolbars_unpinned_last_save" : 0, 30 | "tallnewobj" : 0, 31 | "boxanimatetime" : 200, 32 | "enablehscroll" : 1, 33 | "enablevscroll" : 1, 34 | "devicewidth" : 0.0, 35 | "description" : "", 36 | "digest" : "", 37 | "tags" : "", 38 | "style" : "", 39 | "subpatcher_template" : "", 40 | "boxes" : [ { 41 | "box" : { 42 | "bubble" : 1, 43 | "id" : "obj-35", 44 | "maxclass" : "comment", 45 | "numinlets" : 1, 46 | "numoutlets" : 0, 47 | "patching_rect" : [ 279.0, 347.0, 354.0, 24.0 ], 48 | "text" : "3d. Disable all handlers including the logger" 49 | } 50 | 51 | } 52 | , { 53 | "box" : { 54 | "id" : "obj-34", 55 | "maxclass" : "message", 56 | "numinlets" : 2, 57 | "numoutlets" : 1, 58 | "outlettype" : [ "" ], 59 | "patching_rect" : [ 89.0, 347.0, 120.0, 22.0 ], 60 | "text" : "remove_all_handlers" 61 | } 62 | 63 | } 64 | , { 65 | "box" : { 66 | "bubble" : 1, 67 | "id" : "obj-31", 68 | "maxclass" : "comment", 69 | "numinlets" : 1, 70 | "numoutlets" : 0, 71 | "patching_rect" : [ 279.0, 308.0, 354.0, 24.0 ], 72 | "text" : "3c. Disable both Number input handlers" 73 | } 74 | 75 | } 76 | , { 77 | "box" : { 78 | "id" : "obj-33", 79 | "maxclass" : "message", 80 | "numinlets" : 2, 81 | "numoutlets" : 1, 82 | "outlettype" : [ "" ], 83 | "patching_rect" : [ 89.0, 308.0, 183.0, 22.0 ], 84 | "text" : "remove_number_handlers" 85 | } 86 | 87 | } 88 | , { 89 | "box" : { 90 | "bubble" : 1, 91 | "id" : "obj-30", 92 | "maxclass" : "comment", 93 | "numinlets" : 1, 94 | "numoutlets" : 0, 95 | "patching_rect" : [ 279.0, 273.0, 354.0, 24.0 ], 96 | "text" : "3b. Enable/Disable outputting the triple of the input value" 97 | } 98 | 99 | } 100 | , { 101 | "box" : { 102 | "bubble" : 1, 103 | "id" : "obj-29", 104 | "maxclass" : "comment", 105 | "numinlets" : 1, 106 | "numoutlets" : 0, 107 | "patching_rect" : [ 279.0, 235.0, 354.0, 24.0 ], 108 | "text" : "3a. Enable/Disable outputting the double of the input value" 109 | } 110 | 111 | } 112 | , { 113 | "box" : { 114 | "id" : "obj-28", 115 | "maxclass" : "message", 116 | "numinlets" : 2, 117 | "numoutlets" : 1, 118 | "outlettype" : [ "" ], 119 | "patching_rect" : [ 183.0, 273.0, 89.0, 22.0 ], 120 | "text" : "disable_triple" 121 | } 122 | 123 | } 124 | , { 125 | "box" : { 126 | "id" : "obj-26", 127 | "maxclass" : "message", 128 | "numinlets" : 2, 129 | "numoutlets" : 1, 130 | "outlettype" : [ "" ], 131 | "patching_rect" : [ 89.0, 273.0, 87.0, 22.0 ], 132 | "text" : "enable_triple" 133 | } 134 | 135 | } 136 | , { 137 | "box" : { 138 | "id" : "obj-24", 139 | "maxclass" : "message", 140 | "numinlets" : 2, 141 | "numoutlets" : 1, 142 | "outlettype" : [ "" ], 143 | "patching_rect" : [ 183.0, 235.0, 89.0, 22.0 ], 144 | "text" : "disable_double" 145 | } 146 | 147 | } 148 | , { 149 | "box" : { 150 | "id" : "obj-22", 151 | "maxclass" : "message", 152 | "numinlets" : 2, 153 | "numoutlets" : 1, 154 | "outlettype" : [ "" ], 155 | "patching_rect" : [ 89.0, 235.0, 87.0, 22.0 ], 156 | "text" : "enable_double" 157 | } 158 | 159 | } 160 | , { 161 | "box" : { 162 | "id" : "obj-20", 163 | "maxclass" : "comment", 164 | "numinlets" : 1, 165 | "numoutlets" : 0, 166 | "patching_rect" : [ 284.0, 578.0, 73.0, 20.0 ], 167 | "text" : "logger" 168 | } 169 | 170 | } 171 | , { 172 | "box" : { 173 | "id" : "obj-19", 174 | "maxclass" : "newobj", 175 | "numinlets" : 1, 176 | "numoutlets" : 0, 177 | "patching_rect" : [ 284.0, 549.0, 91.0, 22.0 ], 178 | "text" : "print @popup 1" 179 | } 180 | 181 | } 182 | , { 183 | "box" : { 184 | "id" : "obj-17", 185 | "maxclass" : "comment", 186 | "numinlets" : 1, 187 | "numoutlets" : 0, 188 | "patching_rect" : [ 40.0, 578.0, 73.0, 20.0 ], 189 | "text" : "value * 2" 190 | } 191 | 192 | } 193 | , { 194 | "box" : { 195 | "id" : "obj-18", 196 | "maxclass" : "number", 197 | "numinlets" : 1, 198 | "numoutlets" : 2, 199 | "outlettype" : [ "", "bang" ], 200 | "parameter_enable" : 0, 201 | "patching_rect" : [ 162.0, 549.0, 73.0, 22.0 ] 202 | } 203 | 204 | } 205 | , { 206 | "box" : { 207 | "id" : "obj-16", 208 | "maxclass" : "comment", 209 | "numinlets" : 1, 210 | "numoutlets" : 0, 211 | "patching_rect" : [ 162.0, 578.0, 73.0, 20.0 ], 212 | "text" : "value * 3" 213 | } 214 | 215 | } 216 | , { 217 | "box" : { 218 | "id" : "obj-13", 219 | "maxclass" : "number", 220 | "numinlets" : 1, 221 | "numoutlets" : 2, 222 | "outlettype" : [ "", "bang" ], 223 | "parameter_enable" : 0, 224 | "patching_rect" : [ 40.0, 549.0, 73.0, 22.0 ] 225 | } 226 | 227 | } 228 | , { 229 | "box" : { 230 | "id" : "obj-8", 231 | "maxclass" : "number", 232 | "numinlets" : 1, 233 | "numoutlets" : 2, 234 | "outlettype" : [ "", "bang" ], 235 | "parameter_enable" : 0, 236 | "patching_rect" : [ 89.0, 183.0, 50.0, 22.0 ] 237 | } 238 | 239 | } 240 | , { 241 | "box" : { 242 | "id" : "obj-3", 243 | "maxclass" : "newobj", 244 | "numinlets" : 4, 245 | "numoutlets" : 4, 246 | "outlettype" : [ "", "", "", "" ], 247 | "patching_rect" : [ 40.0, 466.5, 385.0, 22.0 ], 248 | "text" : "route double triple log" 249 | } 250 | 251 | } 252 | , { 253 | "box" : { 254 | "bubble" : 1, 255 | "id" : "obj-11", 256 | "linecount" : 2, 257 | "maxclass" : "comment", 258 | "numinlets" : 1, 259 | "numoutlets" : 0, 260 | "patching_rect" : [ 143.75, 175.5, 213.0, 37.0 ], 261 | "text" : "2. Send a number to node.script to trigger processing" 262 | } 263 | 264 | } 265 | , { 266 | "box" : { 267 | "bubble" : 1, 268 | "id" : "obj-10", 269 | "linecount" : 2, 270 | "maxclass" : "comment", 271 | "numinlets" : 1, 272 | "numoutlets" : 0, 273 | "patching_rect" : [ 113.5, 121.5, 191.0, 37.0 ], 274 | "text" : "1. You must start the script before it will accept messages" 275 | } 276 | 277 | } 278 | , { 279 | "box" : { 280 | "id" : "obj-6", 281 | "maxclass" : "message", 282 | "numinlets" : 2, 283 | "numoutlets" : 1, 284 | "outlettype" : [ "" ], 285 | "patching_rect" : [ 40.0, 129.0, 64.0, 22.0 ], 286 | "text" : "script start" 287 | } 288 | 289 | } 290 | , { 291 | "box" : { 292 | "fontname" : "Lato Regular", 293 | "fontsize" : 13.0, 294 | "id" : "obj-2", 295 | "linecount" : 2, 296 | "maxclass" : "comment", 297 | "numinlets" : 1, 298 | "numoutlets" : 0, 299 | "patching_rect" : [ 10.0, 79.0, 916.0, 38.0 ], 300 | "text" : "The .addHandler / .addHandlers and .removeHandler / .removeHandlers MaxAPI endpoints can be used to dynamicall attach and detach functions to handle input from your Max Patch within [node.script]" 301 | } 302 | 303 | } 304 | , { 305 | "box" : { 306 | "fontname" : "Lato Regular", 307 | "fontsize" : 48.0, 308 | "id" : "obj-63", 309 | "maxclass" : "comment", 310 | "numinlets" : 1, 311 | "numoutlets" : 0, 312 | "patching_rect" : [ 10.0, 10.0, 916.0, 64.0 ], 313 | "text" : "05 - Dynamic usage of Message Handlers" 314 | } 315 | 316 | } 317 | , { 318 | "box" : { 319 | "bubble" : 1, 320 | "id" : "obj-39", 321 | "linecount" : 4, 322 | "maxclass" : "comment", 323 | "numinlets" : 1, 324 | "numoutlets" : 0, 325 | "patching_rect" : [ 279.0, 387.5, 223.0, 64.0 ], 326 | "text" : "4. Double-click to view message-handlers-advanced.js.js and to see how handlers are dynamically attached and detached" 327 | } 328 | 329 | } 330 | , { 331 | "box" : { 332 | "bgmode" : 0, 333 | "border" : 0, 334 | "clickthrough" : 0, 335 | "enablehscroll" : 0, 336 | "enablevscroll" : 0, 337 | "id" : "obj-5", 338 | "lockeddragscroll" : 0, 339 | "maxclass" : "bpatcher", 340 | "name" : "n4m.monitor.maxpat", 341 | "numinlets" : 1, 342 | "numoutlets" : 1, 343 | "offset" : [ 0.0, 0.0 ], 344 | "outlettype" : [ "bang" ], 345 | "patching_rect" : [ 514.5, 391.0, 400.0, 220.0 ], 346 | "viewvisibility" : 1 347 | } 348 | 349 | } 350 | , { 351 | "box" : { 352 | "id" : "obj-1", 353 | "maxclass" : "newobj", 354 | "numinlets" : 1, 355 | "numoutlets" : 2, 356 | "outlettype" : [ "", "" ], 357 | "patching_rect" : [ 40.0, 408.5, 230.0, 22.0 ], 358 | "saved_object_attributes" : { 359 | "autostart" : 0, 360 | "defer" : 0, 361 | "node_bin_path" : "", 362 | "npm_bin_path" : "", 363 | "watch" : 0 364 | } 365 | , 366 | "text" : "node.script dynamic-message-handlers.js" 367 | } 368 | 369 | } 370 | ], 371 | "lines" : [ { 372 | "patchline" : { 373 | "destination" : [ "obj-3", 0 ], 374 | "source" : [ "obj-1", 0 ] 375 | } 376 | 377 | } 378 | , { 379 | "patchline" : { 380 | "destination" : [ "obj-5", 0 ], 381 | "midpoints" : [ 260.5, 431.0, 276.0, 431.0, 276.0, 461.0, 510.0, 461.0, 510.0, 386.0, 524.0, 386.0 ], 382 | "source" : [ "obj-1", 1 ] 383 | } 384 | 385 | } 386 | , { 387 | "patchline" : { 388 | "destination" : [ "obj-1", 0 ], 389 | "midpoints" : [ 98.5, 267.0, 49.5, 267.0 ], 390 | "source" : [ "obj-22", 0 ] 391 | } 392 | 393 | } 394 | , { 395 | "patchline" : { 396 | "destination" : [ "obj-1", 0 ], 397 | "midpoints" : [ 192.5, 268.0, 49.5, 268.0 ], 398 | "source" : [ "obj-24", 0 ] 399 | } 400 | 401 | } 402 | , { 403 | "patchline" : { 404 | "destination" : [ "obj-1", 0 ], 405 | "midpoints" : [ 98.5, 303.0, 49.5, 303.0 ], 406 | "source" : [ "obj-26", 0 ] 407 | } 408 | 409 | } 410 | , { 411 | "patchline" : { 412 | "destination" : [ "obj-1", 0 ], 413 | "midpoints" : [ 192.5, 303.0, 49.5, 303.0 ], 414 | "source" : [ "obj-28", 0 ] 415 | } 416 | 417 | } 418 | , { 419 | "patchline" : { 420 | "destination" : [ "obj-13", 0 ], 421 | "source" : [ "obj-3", 0 ] 422 | } 423 | 424 | } 425 | , { 426 | "patchline" : { 427 | "destination" : [ "obj-18", 0 ], 428 | "source" : [ "obj-3", 1 ] 429 | } 430 | 431 | } 432 | , { 433 | "patchline" : { 434 | "destination" : [ "obj-19", 0 ], 435 | "source" : [ "obj-3", 2 ] 436 | } 437 | 438 | } 439 | , { 440 | "patchline" : { 441 | "destination" : [ "obj-1", 0 ], 442 | "midpoints" : [ 98.5, 332.0, 49.5, 332.0 ], 443 | "source" : [ "obj-33", 0 ] 444 | } 445 | 446 | } 447 | , { 448 | "patchline" : { 449 | "destination" : [ "obj-1", 0 ], 450 | "midpoints" : [ 98.5, 395.0, 49.5, 395.0 ], 451 | "source" : [ "obj-34", 0 ] 452 | } 453 | 454 | } 455 | , { 456 | "patchline" : { 457 | "destination" : [ "obj-1", 0 ], 458 | "source" : [ "obj-6", 0 ] 459 | } 460 | 461 | } 462 | , { 463 | "patchline" : { 464 | "destination" : [ "obj-1", 0 ], 465 | "midpoints" : [ 98.5, 221.0, 49.5, 221.0 ], 466 | "source" : [ "obj-8", 0 ] 467 | } 468 | 469 | } 470 | ], 471 | "dependency_cache" : [ { 472 | "name" : "dynamic-message-handlers.js", 473 | "bootpath" : "~/c74/n4m-core-examples/04-message-handlers-advanced", 474 | "patcherrelativepath" : ".", 475 | "type" : "TEXT", 476 | "implicit" : 1 477 | } 478 | , { 479 | "name" : "n4m.monitor.maxpat", 480 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 481 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 482 | "type" : "JSON", 483 | "implicit" : 1 484 | } 485 | , { 486 | "name" : "resize_n4m_monitor_patcher.js", 487 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 488 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 489 | "type" : "TEXT", 490 | "implicit" : 1 491 | } 492 | , { 493 | "name" : "fit_jweb_to_bounds.js", 494 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 495 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 496 | "type" : "TEXT", 497 | "implicit" : 1 498 | } 499 | ], 500 | "autosave" : 0, 501 | "styles" : [ { 502 | "name" : "light", 503 | "default" : { 504 | "textcolor_inverse" : [ 0.0, 0.0, 0.0, 1.0 ], 505 | "fontsize" : [ 32.0 ], 506 | "bgfillcolor" : { 507 | "type" : "color", 508 | "color1" : [ 1.0, 1.0, 1.0, 1.0 ], 509 | "color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 510 | "color" : [ 0.65098, 0.666667, 0.662745, 1.0 ], 511 | "angle" : 270.0, 512 | "proportion" : 0.39, 513 | "autogradient" : 0.0 514 | } 515 | 516 | } 517 | , 518 | "parentstyle" : "", 519 | "multi" : 0 520 | } 521 | ] 522 | } 523 | 524 | } 525 | -------------------------------------------------------------------------------- /06-using-dicts/README.md: -------------------------------------------------------------------------------- 1 | # Using dicts 2 | 3 | This example shows how to interact with `dicts` in Node For Max. You can receive a `dict` via the inlet of `[node.script]` as shown in [03-message-types](../03-message-types) or send a dict to Max using the `outlet` function of the API as shown in [04-outlet-methods](../04-outlet-methods). Apart from that the API offers three additional methods: 4 | 5 | * `getDict` to request the content of a dict from Max 6 | * `setDict` to set or overwrite the content of a dict in Max 7 | * `updateDict` to partially update the content of a dict in Max given a `path` and `value` 8 | -------------------------------------------------------------------------------- /06-using-dicts/using-dicts.js: -------------------------------------------------------------------------------- 1 | const maxApi = require("max-api"); 2 | 3 | const DICT_ID = "n4m.dict"; 4 | 5 | // Used for storing the initial value 6 | let initialDict = {}; 7 | 8 | // Getting and setting dicts is an asynchronous process and the API function 9 | // calls all return a Promise. We use the async/await syntax here in order 10 | // to handle the async behaviour gracefully. 11 | // 12 | // Want to learn more about Promised and async/await: 13 | // * Web Fundamentals intro to Promises: https://developers.google.com/web/fundamentals/primers/promises 14 | // * Promises Deep Dive on MDN: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Promises 15 | // * Web Fundamentals on using async/await and their benefits: https://developers.google.com/web/fundamentals/primers/async-functions 16 | // * Async Functions on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function 17 | 18 | maxApi.addHandlers({ 19 | set: async (path, value) => { 20 | const dict = await maxApi.updateDict(DICT_ID, path, value); 21 | await maxApi.outlet(dict); 22 | }, 23 | reset: async () => { 24 | const dict = await maxApi.setDict(DICT_ID, initialDict); 25 | await maxApi.outlet(dict); 26 | }, 27 | show: async () => { 28 | const dict = await maxApi.getDict(DICT_ID); 29 | await maxApi.outlet(dict); 30 | } 31 | }); 32 | 33 | // We use this to store the initial value of the dict on process start 34 | // so that the call to "reset" and reset it accordingly 35 | const main = async () => { initialDict = await maxApi.getDict(DICT_ID); }; 36 | main(); 37 | 38 | 39 | -------------------------------------------------------------------------------- /06-using-dicts/using-dicts.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 8, 6 | "minor" : 0, 7 | "revision" : 2, 8 | "architecture" : "x64", 9 | "modernui" : 1 10 | } 11 | , 12 | "classnamespace" : "box", 13 | "rect" : [ 100.0, 100.0, 831.0, 639.0 ], 14 | "bglocked" : 0, 15 | "openinpresentation" : 0, 16 | "default_fontsize" : 12.0, 17 | "default_fontface" : 0, 18 | "default_fontname" : "Arial", 19 | "gridonopen" : 1, 20 | "gridsize" : [ 15.0, 15.0 ], 21 | "gridsnaponopen" : 1, 22 | "objectsnaponopen" : 1, 23 | "statusbarvisible" : 2, 24 | "toolbarvisible" : 1, 25 | "lefttoolbarpinned" : 0, 26 | "toptoolbarpinned" : 0, 27 | "righttoolbarpinned" : 0, 28 | "bottomtoolbarpinned" : 0, 29 | "toolbars_unpinned_last_save" : 0, 30 | "tallnewobj" : 0, 31 | "boxanimatetime" : 200, 32 | "enablehscroll" : 1, 33 | "enablevscroll" : 1, 34 | "devicewidth" : 0.0, 35 | "description" : "", 36 | "digest" : "", 37 | "tags" : "", 38 | "style" : "", 39 | "subpatcher_template" : "", 40 | "boxes" : [ { 41 | "box" : { 42 | "bubble" : 1, 43 | "id" : "obj-58", 44 | "maxclass" : "comment", 45 | "numinlets" : 1, 46 | "numoutlets" : 0, 47 | "patching_rect" : [ 248.5, 286.5, 334.0, 24.0 ], 48 | "text" : "3b. use this numberbox to set the value within the dict" 49 | } 50 | 51 | } 52 | , { 53 | "box" : { 54 | "bubble" : 1, 55 | "id" : "obj-55", 56 | "linecount" : 2, 57 | "maxclass" : "comment", 58 | "numinlets" : 1, 59 | "numoutlets" : 0, 60 | "patching_rect" : [ 203.5, 177.5, 200.0, 37.0 ], 61 | "presentation_linecount" : 2, 62 | "text" : "2. Use this to show to the content of the dict using getDict" 63 | } 64 | 65 | } 66 | , { 67 | "box" : { 68 | "id" : "obj-52", 69 | "maxclass" : "newobj", 70 | "numinlets" : 1, 71 | "numoutlets" : 1, 72 | "outlettype" : [ "" ], 73 | "patching_rect" : [ 90.0, 343.5, 72.0, 22.0 ], 74 | "text" : "prepend set" 75 | } 76 | 77 | } 78 | , { 79 | "box" : { 80 | "id" : "obj-51", 81 | "maxclass" : "number", 82 | "numinlets" : 1, 83 | "numoutlets" : 2, 84 | "outlettype" : [ "", "bang" ], 85 | "parameter_enable" : 0, 86 | "patching_rect" : [ 195.5, 286.5, 50.0, 22.0 ] 87 | } 88 | 89 | } 90 | , { 91 | "box" : { 92 | "bubble" : 1, 93 | "id" : "obj-49", 94 | "linecount" : 2, 95 | "maxclass" : "comment", 96 | "numinlets" : 1, 97 | "numoutlets" : 0, 98 | "patching_rect" : [ 248.5, 228.5, 334.0, 37.0 ], 99 | "presentation_linecount" : 3, 100 | "text" : "3a. use this menu to select the \"path\" to the value you'd like to change within the dict" 101 | } 102 | 103 | } 104 | , { 105 | "box" : { 106 | "id" : "obj-48", 107 | "maxclass" : "newobj", 108 | "numinlets" : 1, 109 | "numoutlets" : 1, 110 | "outlettype" : [ "" ], 111 | "patching_rect" : [ 90.0, 275.0, 72.0, 22.0 ], 112 | "text" : "prepend set" 113 | } 114 | 115 | } 116 | , { 117 | "box" : { 118 | "id" : "obj-45", 119 | "maxclass" : "newobj", 120 | "numinlets" : 1, 121 | "numoutlets" : 1, 122 | "outlettype" : [ "" ], 123 | "patching_rect" : [ 90.0, 313.0, 53.0, 22.0 ], 124 | "text" : "prepend" 125 | } 126 | 127 | } 128 | , { 129 | "box" : { 130 | "id" : "obj-36", 131 | "items" : [ "a", ",", "b", ",", "c", ",", "nested.value", ",", "nested.arrayofvalues[0]", ",", "nested.arrayofvalues[1]", ",", "nested.arrayofvalues[2]", ",", "nested.arrayofvalues[3]", ",", "even.more.nested.value" ], 132 | "maxclass" : "umenu", 133 | "numinlets" : 1, 134 | "numoutlets" : 3, 135 | "outlettype" : [ "int", "", "" ], 136 | "parameter_enable" : 0, 137 | "patching_rect" : [ 90.0, 236.0, 156.0, 22.0 ] 138 | } 139 | 140 | } 141 | , { 142 | "box" : { 143 | "id" : "obj-22", 144 | "maxclass" : "message", 145 | "numinlets" : 2, 146 | "numoutlets" : 1, 147 | "outlettype" : [ "" ], 148 | "patching_rect" : [ 62.0, 185.0, 133.0, 22.0 ], 149 | "text" : "show" 150 | } 151 | 152 | } 153 | , { 154 | "box" : { 155 | "id" : "obj-20", 156 | "maxclass" : "message", 157 | "numinlets" : 2, 158 | "numoutlets" : 1, 159 | "outlettype" : [ "" ], 160 | "patching_rect" : [ 248.5, 350.0, 133.0, 22.0 ], 161 | "text" : "reset" 162 | } 163 | 164 | } 165 | , { 166 | "box" : { 167 | "id" : "obj-18", 168 | "maxclass" : "dict.view", 169 | "numinlets" : 1, 170 | "numoutlets" : 0, 171 | "patching_rect" : [ 40.0, 428.0, 191.0, 201.0 ] 172 | } 173 | 174 | } 175 | , { 176 | "box" : { 177 | "bubble" : 1, 178 | "bubbleside" : 2, 179 | "id" : "obj-9", 180 | "linecount" : 2, 181 | "maxclass" : "comment", 182 | "numinlets" : 1, 183 | "numoutlets" : 0, 184 | "patching_rect" : [ 588.0, 114.0, 223.0, 52.0 ], 185 | "presentation_linecount" : 2, 186 | "text" : "you can double-click the [dict] object to view the contents of the dict", 187 | "textjustification" : 1 188 | } 189 | 190 | } 191 | , { 192 | "box" : { 193 | "data" : { 194 | "a" : 0, 195 | "b" : 0, 196 | "c" : 0, 197 | "nested" : { 198 | "arrayofvalues" : [ 0, 0, 0, 0 ], 199 | "value" : 0 200 | } 201 | , 202 | "even" : { 203 | "more" : { 204 | "nested" : { 205 | "value" : 0 206 | } 207 | 208 | } 209 | 210 | } 211 | 212 | } 213 | , 214 | "id" : "obj-4", 215 | "maxclass" : "newobj", 216 | "numinlets" : 2, 217 | "numoutlets" : 4, 218 | "outlettype" : [ "dictionary", "", "", "" ], 219 | "patching_rect" : [ 636.0, 168.0, 138.0, 22.0 ], 220 | "saved_object_attributes" : { 221 | "embed" : 1, 222 | "parameter_enable" : 0, 223 | "parameter_mappable" : 0 224 | } 225 | , 226 | "text" : "dict n4m.dict @embed 1" 227 | } 228 | 229 | } 230 | , { 231 | "box" : { 232 | "bubble" : 1, 233 | "id" : "obj-10", 234 | "linecount" : 2, 235 | "maxclass" : "comment", 236 | "numinlets" : 1, 237 | "numoutlets" : 0, 238 | "patching_rect" : [ 113.5, 121.5, 191.0, 37.0 ], 239 | "text" : "1. You must start the script before it will accept messages" 240 | } 241 | 242 | } 243 | , { 244 | "box" : { 245 | "id" : "obj-6", 246 | "maxclass" : "message", 247 | "numinlets" : 2, 248 | "numoutlets" : 1, 249 | "outlettype" : [ "" ], 250 | "patching_rect" : [ 40.0, 129.0, 64.0, 22.0 ], 251 | "text" : "script start" 252 | } 253 | 254 | } 255 | , { 256 | "box" : { 257 | "fontname" : "Lato Regular", 258 | "fontsize" : 13.0, 259 | "id" : "obj-2", 260 | "maxclass" : "comment", 261 | "numinlets" : 1, 262 | "numoutlets" : 0, 263 | "patching_rect" : [ 10.0, 79.0, 811.0, 22.0 ], 264 | "text" : "Shows how to use .getDict, .setDict and .updateDict in order to interact with dicts in Max from within Node For Max" 265 | } 266 | 267 | } 268 | , { 269 | "box" : { 270 | "fontname" : "Lato Regular", 271 | "fontsize" : 48.0, 272 | "id" : "obj-63", 273 | "maxclass" : "comment", 274 | "numinlets" : 1, 275 | "numoutlets" : 0, 276 | "patching_rect" : [ 10.0, 10.0, 811.0, 64.0 ], 277 | "text" : "06 - Using Dicts" 278 | } 279 | 280 | } 281 | , { 282 | "box" : { 283 | "bubble" : 1, 284 | "id" : "obj-39", 285 | "maxclass" : "comment", 286 | "numinlets" : 1, 287 | "numoutlets" : 0, 288 | "patching_rect" : [ 383.5, 350.0, 257.0, 24.0 ], 289 | "text" : "4. Reset the dictionary to its initial content" 290 | } 291 | 292 | } 293 | , { 294 | "box" : { 295 | "bgmode" : 0, 296 | "border" : 0, 297 | "clickthrough" : 0, 298 | "enablehscroll" : 0, 299 | "enablevscroll" : 0, 300 | "id" : "obj-5", 301 | "lockeddragscroll" : 0, 302 | "maxclass" : "bpatcher", 303 | "name" : "n4m.monitor.maxpat", 304 | "numinlets" : 1, 305 | "numoutlets" : 1, 306 | "offset" : [ 0.0, 0.0 ], 307 | "outlettype" : [ "bang" ], 308 | "patching_rect" : [ 235.5, 409.0, 400.0, 220.0 ], 309 | "viewvisibility" : 1 310 | } 311 | 312 | } 313 | , { 314 | "box" : { 315 | "id" : "obj-1", 316 | "maxclass" : "newobj", 317 | "numinlets" : 1, 318 | "numoutlets" : 2, 319 | "outlettype" : [ "", "" ], 320 | "patching_rect" : [ 40.0, 388.5, 140.0, 22.0 ], 321 | "saved_object_attributes" : { 322 | "autostart" : 0, 323 | "defer" : 0, 324 | "node_bin_path" : "", 325 | "npm_bin_path" : "", 326 | "watch" : 0 327 | } 328 | , 329 | "text" : "node.script using-dicts.js" 330 | } 331 | 332 | } 333 | ], 334 | "lines" : [ { 335 | "patchline" : { 336 | "destination" : [ "obj-18", 0 ], 337 | "source" : [ "obj-1", 0 ] 338 | } 339 | 340 | } 341 | , { 342 | "patchline" : { 343 | "destination" : [ "obj-5", 0 ], 344 | "midpoints" : [ 170.5, 421.0, 221.0, 421.0, 221.0, 395.0, 245.0, 395.0 ], 345 | "source" : [ "obj-1", 1 ] 346 | } 347 | 348 | } 349 | , { 350 | "patchline" : { 351 | "destination" : [ "obj-1", 0 ], 352 | "source" : [ "obj-20", 0 ] 353 | } 354 | 355 | } 356 | , { 357 | "patchline" : { 358 | "destination" : [ "obj-1", 0 ], 359 | "midpoints" : [ 71.5, 222.0, 49.5, 222.0 ], 360 | "source" : [ "obj-22", 0 ] 361 | } 362 | 363 | } 364 | , { 365 | "patchline" : { 366 | "destination" : [ "obj-48", 0 ], 367 | "source" : [ "obj-36", 1 ] 368 | } 369 | 370 | } 371 | , { 372 | "patchline" : { 373 | "destination" : [ "obj-52", 0 ], 374 | "source" : [ "obj-45", 0 ] 375 | } 376 | 377 | } 378 | , { 379 | "patchline" : { 380 | "destination" : [ "obj-45", 0 ], 381 | "source" : [ "obj-48", 0 ] 382 | } 383 | 384 | } 385 | , { 386 | "patchline" : { 387 | "destination" : [ "obj-45", 0 ], 388 | "source" : [ "obj-51", 0 ] 389 | } 390 | 391 | } 392 | , { 393 | "patchline" : { 394 | "destination" : [ "obj-1", 0 ], 395 | "midpoints" : [ 99.5, 373.0, 49.5, 373.0 ], 396 | "source" : [ "obj-52", 0 ] 397 | } 398 | 399 | } 400 | , { 401 | "patchline" : { 402 | "destination" : [ "obj-1", 0 ], 403 | "source" : [ "obj-6", 0 ] 404 | } 405 | 406 | } 407 | ], 408 | "dependency_cache" : [ { 409 | "name" : "using-dicts.js", 410 | "bootpath" : "~/c74/n4m-core-examples/06-using-dicts", 411 | "patcherrelativepath" : ".", 412 | "type" : "TEXT", 413 | "implicit" : 1 414 | } 415 | , { 416 | "name" : "n4m.monitor.maxpat", 417 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 418 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 419 | "type" : "JSON", 420 | "implicit" : 1 421 | } 422 | , { 423 | "name" : "resize_n4m_monitor_patcher.js", 424 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 425 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 426 | "type" : "TEXT", 427 | "implicit" : 1 428 | } 429 | , { 430 | "name" : "fit_jweb_to_bounds.js", 431 | "bootpath" : "~/Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 432 | "patcherrelativepath" : "../../../Documents/Max 8/Packages/Node For Max/patchers/debug-monitor", 433 | "type" : "TEXT", 434 | "implicit" : 1 435 | } 436 | ], 437 | "autosave" : 0, 438 | "styles" : [ { 439 | "name" : "light", 440 | "default" : { 441 | "textcolor_inverse" : [ 0.0, 0.0, 0.0, 1.0 ], 442 | "fontsize" : [ 32.0 ], 443 | "bgfillcolor" : { 444 | "type" : "color", 445 | "color1" : [ 1.0, 1.0, 1.0, 1.0 ], 446 | "color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 447 | "color" : [ 0.65098, 0.666667, 0.662745, 1.0 ], 448 | "angle" : 270.0, 449 | "proportion" : 0.39, 450 | "autogradient" : 0.0 451 | } 452 | 453 | } 454 | , 455 | "parentstyle" : "", 456 | "multi" : 0 457 | } 458 | ] 459 | } 460 | 461 | } 462 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 26 | * Trolling, insulting/derogatory comments, and personal or political attacks 27 | * Public or private harassment 28 | * Publishing others' private information, such as a physical or electronic 29 | address, without explicit permission 30 | * Other conduct which could reasonably be considered inappropriate in a 31 | professional setting 32 | 33 | ## Our Responsibilities 34 | 35 | Project maintainers are responsible for clarifying the standards of acceptable 36 | behavior and are expected to take appropriate and fair corrective action in 37 | response to any instances of unacceptable behavior. 38 | 39 | Project maintainers have the right and responsibility to remove, edit, or 40 | reject comments, commits, code, wiki edits, issues, and other contributions 41 | that are not aligned to this Code of Conduct, or to ban temporarily or 42 | permanently any contributor for other behaviors that they deem inappropriate, 43 | threatening, offensive, or harmful. 44 | 45 | ## Scope 46 | 47 | This Code of Conduct applies both within project spaces and in public spaces 48 | when an individual is representing the project or its community. Examples of 49 | representing a project or community include using an official project e-mail 50 | address, posting via an official social media account, or acting as an appointed 51 | representative at an online or offline event. Representation of a project may be 52 | further defined and clarified by project maintainers. 53 | 54 | ## Enforcement 55 | 56 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 57 | reported by contacting Cycling '74 support via [http://cycling74.com](http://cycling74.com/contact-support/) .All 58 | complaints will be reviewed and investigated and will result in a response that 59 | is deemed necessary and appropriate to the circumstances. The project team is 60 | obligated to maintain confidentiality with regard to the reporter of an incident. 61 | Further details of specific enforcement policies may be posted separately. 62 | 63 | Project maintainers who do not follow or enforce the Code of Conduct in good 64 | faith may face temporary or permanent repercussions as determined by other 65 | members of the project's leadership. 66 | 67 | ## Attribution 68 | 69 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 70 | available at [http://contributor-covenant.org/version/1/4][version] 71 | 72 | [homepage]: http://contributor-covenant.org 73 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | The Node for Max Core Examples repository is an open source project, and contributions and help from the community is strongly encouraged and important to improve the software. Contributions are therefore always welcome, no matter how large or small. Here are some things we'd like you to keep in mind in order to help with keeping the process smooth and organized. Please also read our [Code of Conduct](CODE_OF_CONDUCT.md). 4 | 5 | ## Bug Reports / Example Suggestions 6 | 7 | If you've come across a bug in one of the examples, would like to suggest a new example, suggest an enhancement to a current example, or just ask a question, please use the GitHub Issues section for [n4m-core-examples][issues]. In order to make things easier for the maintainers and others the following would be helpful: 8 | 9 | * **Use the search.** It's possible that someone already filed the issue or asked the question you have in mind, so please try to avoid duplicates. 10 | * **Share Info** Please try to share as much helpful info as possible. 11 | * **Distinct test case** Please try to provide detailed info about your bug, example suggestion, feature request, or question. In the case of a bug please try to share clear reproducible steps or ideally even an isolated, reproducible test case. 12 | 13 | ## Contributing Changes / Pull Requests 14 | 15 | We are happy to accept your contributions in the form of pull requests from the GitHub Community. Please make sure your contributions are well-formatted, pass the tests (use `npm run test`) and make use of commonly understood commit messages. 16 | 17 | ## Quick Code Style Guide 18 | 19 | * Use tab characters for spacing 20 | * No trailing whitespace and also blank lines should have no whitespace 21 | * Make use of strict equals === unless type coercion is intended 22 | * Follow conventions already established in project's source code 23 | * Validate changes with eslint and build/test the project to make sure you didn't break anything 24 | 25 | This project also uses eslint. So please feel free to use `npm run lint` to check the formatting or `npm run fix` to have eslint auto format where it can. 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018, Cycling'74 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included 11 | in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Node For Max 3 |

4 | 5 | # Node For Max Core Examples 6 | [![Build Status](https://travis-ci.org/Cycling74/n4m-core-examples.svg?branch=master)](https://travis-ci.org/Cycling74/n4m-core-examples) 7 | 8 | This repository contains the code examples for the Node For Max package, maintained by [@Cycling74](https://github.com/Cycling74). It's main purpose is to show basic techniques when using `Node For Max` and teach how to use the API. 9 | 10 | ## Getting Started with Node For Max 11 | 12 | Hello Maxers! If you're looking for resources to learn more about Node For Max, you're in the right place. 13 | 14 | ### API Reference 15 | 16 | You can find the full API Reference [here](https://docs.cycling74.com/nodeformax/api/index.html). 17 | 18 | ### Core Examples 19 | 20 | If you're completely new to Node For Max, we recommend starting here, with the core examples. These are small and show you how to do basic things you'll probably want to do again and again. Each folder is a self-contained example, containing at a minimum a Max patch and a JavaScript file. Cycling '74 will continue adding more examples, so keep checking back! 21 | 22 | ### Bigger Examples, made by Cycling '74. 23 | 24 | [n4m-examples](https://github.com/cycling74/n4m-examples) is a collection of real-live examples created and maintained by Cycling '74. These are usually larger in size than the core examples. Cycling '74 will continue to add more, so keep checking back! 25 | 26 | ### Recipes 27 | 28 | * Socket Drawings - a recipe that demonstrates how to create a web socket server and have users interact with your Max patch from the Internet. [Recipe](https://cycling74.com/tutorials/node-recipe-00-socket-drawings) | [GitHub](https://github.com/pixlpa/socket-drawings) 29 | 30 | ### Community Examples 31 | 32 | We would also like to share and feature all of your work! Go to the [Node For Max Community Examples](https://github.com/Cycling74/n4m-community) repository to see the work of other Node For Max users and add your own. 33 | 34 | ## Contributing 35 | 36 | The main purpose of this repository is to show basic concepts when using `Node For Max`. We are grateful to the community for contributing bufixes and improvements. 37 | 38 | ### Contributing Guide 39 | 40 | You might find an error in an example, or have a request for an example you would like to see. You can report this by [submitting an issue](https://github.com/Cycling74/n4m-core-examples/issues/new) to this repository. Note that you will need to have a GitHub account to submit an issue. See the full [Contributing Guide](./CONTRIBUTING.md) for more details on how to participate in this project. 41 | 42 | ### Code of Conduct 43 | 44 | We have adopted a Code of Conduct that we expect every participant to adhere to. You can find the full text [here](./CODE_OF_CONDUCT.md). 45 | 46 | ## License 47 | 48 | [MIT](./LICENSE) 49 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "n4m-core-examples", 3 | "version": "0.0.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.0.0", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", 10 | "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.0.0" 14 | } 15 | }, 16 | "@babel/highlight": { 17 | "version": "7.0.0", 18 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", 19 | "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", 20 | "dev": true, 21 | "requires": { 22 | "chalk": "^2.0.0", 23 | "esutils": "^2.0.2", 24 | "js-tokens": "^4.0.0" 25 | } 26 | }, 27 | "acorn": { 28 | "version": "6.0.5", 29 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.5.tgz", 30 | "integrity": "sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg==", 31 | "dev": true 32 | }, 33 | "acorn-jsx": { 34 | "version": "5.0.1", 35 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", 36 | "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", 37 | "dev": true 38 | }, 39 | "ajv": { 40 | "version": "6.7.0", 41 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", 42 | "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", 43 | "dev": true, 44 | "requires": { 45 | "fast-deep-equal": "^2.0.1", 46 | "fast-json-stable-stringify": "^2.0.0", 47 | "json-schema-traverse": "^0.4.1", 48 | "uri-js": "^4.2.2" 49 | } 50 | }, 51 | "ansi-escapes": { 52 | "version": "3.1.0", 53 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", 54 | "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", 55 | "dev": true 56 | }, 57 | "ansi-regex": { 58 | "version": "3.0.0", 59 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 60 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 61 | "dev": true 62 | }, 63 | "ansi-styles": { 64 | "version": "3.2.1", 65 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 66 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 67 | "dev": true, 68 | "requires": { 69 | "color-convert": "^1.9.0" 70 | } 71 | }, 72 | "argparse": { 73 | "version": "1.0.10", 74 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 75 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 76 | "dev": true, 77 | "requires": { 78 | "sprintf-js": "~1.0.2" 79 | } 80 | }, 81 | "astral-regex": { 82 | "version": "1.0.0", 83 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 84 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 85 | "dev": true 86 | }, 87 | "balanced-match": { 88 | "version": "1.0.0", 89 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 90 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 91 | "dev": true 92 | }, 93 | "brace-expansion": { 94 | "version": "1.1.11", 95 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 96 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 97 | "dev": true, 98 | "requires": { 99 | "balanced-match": "^1.0.0", 100 | "concat-map": "0.0.1" 101 | } 102 | }, 103 | "callsites": { 104 | "version": "3.0.0", 105 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz", 106 | "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==", 107 | "dev": true 108 | }, 109 | "chalk": { 110 | "version": "2.4.2", 111 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 112 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 113 | "dev": true, 114 | "requires": { 115 | "ansi-styles": "^3.2.1", 116 | "escape-string-regexp": "^1.0.5", 117 | "supports-color": "^5.3.0" 118 | } 119 | }, 120 | "chardet": { 121 | "version": "0.7.0", 122 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", 123 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", 124 | "dev": true 125 | }, 126 | "circular-json": { 127 | "version": "0.3.3", 128 | "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", 129 | "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", 130 | "dev": true 131 | }, 132 | "cli-cursor": { 133 | "version": "2.1.0", 134 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 135 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 136 | "dev": true, 137 | "requires": { 138 | "restore-cursor": "^2.0.0" 139 | } 140 | }, 141 | "cli-width": { 142 | "version": "2.2.0", 143 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 144 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", 145 | "dev": true 146 | }, 147 | "color-convert": { 148 | "version": "1.9.3", 149 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 150 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 151 | "dev": true, 152 | "requires": { 153 | "color-name": "1.1.3" 154 | } 155 | }, 156 | "color-name": { 157 | "version": "1.1.3", 158 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 159 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 160 | "dev": true 161 | }, 162 | "concat-map": { 163 | "version": "0.0.1", 164 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 165 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 166 | "dev": true 167 | }, 168 | "cross-spawn": { 169 | "version": "6.0.5", 170 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 171 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 172 | "dev": true, 173 | "requires": { 174 | "nice-try": "^1.0.4", 175 | "path-key": "^2.0.1", 176 | "semver": "^5.5.0", 177 | "shebang-command": "^1.2.0", 178 | "which": "^1.2.9" 179 | } 180 | }, 181 | "debug": { 182 | "version": "4.1.1", 183 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 184 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 185 | "dev": true, 186 | "requires": { 187 | "ms": "^2.1.1" 188 | } 189 | }, 190 | "deep-is": { 191 | "version": "0.1.3", 192 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 193 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 194 | "dev": true 195 | }, 196 | "doctrine": { 197 | "version": "2.1.0", 198 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", 199 | "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", 200 | "dev": true, 201 | "requires": { 202 | "esutils": "^2.0.2" 203 | } 204 | }, 205 | "escape-string-regexp": { 206 | "version": "1.0.5", 207 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 208 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 209 | "dev": true 210 | }, 211 | "eslint": { 212 | "version": "5.12.0", 213 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.12.0.tgz", 214 | "integrity": "sha512-LntwyPxtOHrsJdcSwyQKVtHofPHdv+4+mFwEe91r2V13vqpM8yLr7b1sW+Oo/yheOPkWYsYlYJCkzlFAt8KV7g==", 215 | "dev": true, 216 | "requires": { 217 | "@babel/code-frame": "^7.0.0", 218 | "ajv": "^6.5.3", 219 | "chalk": "^2.1.0", 220 | "cross-spawn": "^6.0.5", 221 | "debug": "^4.0.1", 222 | "doctrine": "^2.1.0", 223 | "eslint-scope": "^4.0.0", 224 | "eslint-utils": "^1.3.1", 225 | "eslint-visitor-keys": "^1.0.0", 226 | "espree": "^5.0.0", 227 | "esquery": "^1.0.1", 228 | "esutils": "^2.0.2", 229 | "file-entry-cache": "^2.0.0", 230 | "functional-red-black-tree": "^1.0.1", 231 | "glob": "^7.1.2", 232 | "globals": "^11.7.0", 233 | "ignore": "^4.0.6", 234 | "import-fresh": "^3.0.0", 235 | "imurmurhash": "^0.1.4", 236 | "inquirer": "^6.1.0", 237 | "js-yaml": "^3.12.0", 238 | "json-stable-stringify-without-jsonify": "^1.0.1", 239 | "levn": "^0.3.0", 240 | "lodash": "^4.17.5", 241 | "minimatch": "^3.0.4", 242 | "mkdirp": "^0.5.1", 243 | "natural-compare": "^1.4.0", 244 | "optionator": "^0.8.2", 245 | "path-is-inside": "^1.0.2", 246 | "pluralize": "^7.0.0", 247 | "progress": "^2.0.0", 248 | "regexpp": "^2.0.1", 249 | "semver": "^5.5.1", 250 | "strip-ansi": "^4.0.0", 251 | "strip-json-comments": "^2.0.1", 252 | "table": "^5.0.2", 253 | "text-table": "^0.2.0" 254 | } 255 | }, 256 | "eslint-config-c74": { 257 | "version": "1.0.0", 258 | "resolved": "https://registry.npmjs.org/eslint-config-c74/-/eslint-config-c74-1.0.0.tgz", 259 | "integrity": "sha512-u7W3FVTggmsNnxeemqIv/Zd/2FzLr7RCBxTj6YRujMtbVtSfis6RmCL08B9MawILYtPJo0Zgm+WSsZ3F2zCopg==", 260 | "dev": true 261 | }, 262 | "eslint-scope": { 263 | "version": "4.0.0", 264 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", 265 | "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", 266 | "dev": true, 267 | "requires": { 268 | "esrecurse": "^4.1.0", 269 | "estraverse": "^4.1.1" 270 | } 271 | }, 272 | "eslint-utils": { 273 | "version": "1.3.1", 274 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", 275 | "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", 276 | "dev": true 277 | }, 278 | "eslint-visitor-keys": { 279 | "version": "1.0.0", 280 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", 281 | "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", 282 | "dev": true 283 | }, 284 | "espree": { 285 | "version": "5.0.0", 286 | "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.0.tgz", 287 | "integrity": "sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA==", 288 | "dev": true, 289 | "requires": { 290 | "acorn": "^6.0.2", 291 | "acorn-jsx": "^5.0.0", 292 | "eslint-visitor-keys": "^1.0.0" 293 | } 294 | }, 295 | "esprima": { 296 | "version": "4.0.1", 297 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 298 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 299 | "dev": true 300 | }, 301 | "esquery": { 302 | "version": "1.0.1", 303 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", 304 | "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", 305 | "dev": true, 306 | "requires": { 307 | "estraverse": "^4.0.0" 308 | } 309 | }, 310 | "esrecurse": { 311 | "version": "4.2.1", 312 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 313 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 314 | "dev": true, 315 | "requires": { 316 | "estraverse": "^4.1.0" 317 | } 318 | }, 319 | "estraverse": { 320 | "version": "4.2.0", 321 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", 322 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", 323 | "dev": true 324 | }, 325 | "esutils": { 326 | "version": "2.0.2", 327 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 328 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 329 | "dev": true 330 | }, 331 | "external-editor": { 332 | "version": "3.0.3", 333 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", 334 | "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", 335 | "dev": true, 336 | "requires": { 337 | "chardet": "^0.7.0", 338 | "iconv-lite": "^0.4.24", 339 | "tmp": "^0.0.33" 340 | } 341 | }, 342 | "fast-deep-equal": { 343 | "version": "2.0.1", 344 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", 345 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", 346 | "dev": true 347 | }, 348 | "fast-json-stable-stringify": { 349 | "version": "2.0.0", 350 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 351 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", 352 | "dev": true 353 | }, 354 | "fast-levenshtein": { 355 | "version": "2.0.6", 356 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 357 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 358 | "dev": true 359 | }, 360 | "figures": { 361 | "version": "2.0.0", 362 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 363 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 364 | "dev": true, 365 | "requires": { 366 | "escape-string-regexp": "^1.0.5" 367 | } 368 | }, 369 | "file-entry-cache": { 370 | "version": "2.0.0", 371 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", 372 | "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", 373 | "dev": true, 374 | "requires": { 375 | "flat-cache": "^1.2.1", 376 | "object-assign": "^4.0.1" 377 | } 378 | }, 379 | "flat-cache": { 380 | "version": "1.3.4", 381 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", 382 | "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", 383 | "dev": true, 384 | "requires": { 385 | "circular-json": "^0.3.1", 386 | "graceful-fs": "^4.1.2", 387 | "rimraf": "~2.6.2", 388 | "write": "^0.2.1" 389 | } 390 | }, 391 | "fs.realpath": { 392 | "version": "1.0.0", 393 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 394 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 395 | "dev": true 396 | }, 397 | "functional-red-black-tree": { 398 | "version": "1.0.1", 399 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 400 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 401 | "dev": true 402 | }, 403 | "glob": { 404 | "version": "7.1.3", 405 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", 406 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", 407 | "dev": true, 408 | "requires": { 409 | "fs.realpath": "^1.0.0", 410 | "inflight": "^1.0.4", 411 | "inherits": "2", 412 | "minimatch": "^3.0.4", 413 | "once": "^1.3.0", 414 | "path-is-absolute": "^1.0.0" 415 | } 416 | }, 417 | "globals": { 418 | "version": "11.10.0", 419 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz", 420 | "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==", 421 | "dev": true 422 | }, 423 | "graceful-fs": { 424 | "version": "4.1.15", 425 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", 426 | "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", 427 | "dev": true 428 | }, 429 | "has-flag": { 430 | "version": "3.0.0", 431 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 432 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 433 | "dev": true 434 | }, 435 | "iconv-lite": { 436 | "version": "0.4.24", 437 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 438 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 439 | "dev": true, 440 | "requires": { 441 | "safer-buffer": ">= 2.1.2 < 3" 442 | } 443 | }, 444 | "ignore": { 445 | "version": "4.0.6", 446 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 447 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 448 | "dev": true 449 | }, 450 | "import-fresh": { 451 | "version": "3.0.0", 452 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", 453 | "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", 454 | "dev": true, 455 | "requires": { 456 | "parent-module": "^1.0.0", 457 | "resolve-from": "^4.0.0" 458 | } 459 | }, 460 | "imurmurhash": { 461 | "version": "0.1.4", 462 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 463 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 464 | "dev": true 465 | }, 466 | "inflight": { 467 | "version": "1.0.6", 468 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 469 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 470 | "dev": true, 471 | "requires": { 472 | "once": "^1.3.0", 473 | "wrappy": "1" 474 | } 475 | }, 476 | "inherits": { 477 | "version": "2.0.3", 478 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 479 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 480 | "dev": true 481 | }, 482 | "inquirer": { 483 | "version": "6.2.1", 484 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.1.tgz", 485 | "integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==", 486 | "dev": true, 487 | "requires": { 488 | "ansi-escapes": "^3.0.0", 489 | "chalk": "^2.0.0", 490 | "cli-cursor": "^2.1.0", 491 | "cli-width": "^2.0.0", 492 | "external-editor": "^3.0.0", 493 | "figures": "^2.0.0", 494 | "lodash": "^4.17.10", 495 | "mute-stream": "0.0.7", 496 | "run-async": "^2.2.0", 497 | "rxjs": "^6.1.0", 498 | "string-width": "^2.1.0", 499 | "strip-ansi": "^5.0.0", 500 | "through": "^2.3.6" 501 | }, 502 | "dependencies": { 503 | "ansi-regex": { 504 | "version": "4.0.0", 505 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", 506 | "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", 507 | "dev": true 508 | }, 509 | "strip-ansi": { 510 | "version": "5.0.0", 511 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", 512 | "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", 513 | "dev": true, 514 | "requires": { 515 | "ansi-regex": "^4.0.0" 516 | } 517 | } 518 | } 519 | }, 520 | "is-fullwidth-code-point": { 521 | "version": "2.0.0", 522 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 523 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 524 | "dev": true 525 | }, 526 | "is-promise": { 527 | "version": "2.1.0", 528 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 529 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", 530 | "dev": true 531 | }, 532 | "isexe": { 533 | "version": "2.0.0", 534 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 535 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 536 | "dev": true 537 | }, 538 | "js-tokens": { 539 | "version": "4.0.0", 540 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 541 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 542 | "dev": true 543 | }, 544 | "js-yaml": { 545 | "version": "3.12.1", 546 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", 547 | "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", 548 | "dev": true, 549 | "requires": { 550 | "argparse": "^1.0.7", 551 | "esprima": "^4.0.0" 552 | } 553 | }, 554 | "json-schema-traverse": { 555 | "version": "0.4.1", 556 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 557 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 558 | "dev": true 559 | }, 560 | "json-stable-stringify-without-jsonify": { 561 | "version": "1.0.1", 562 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 563 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 564 | "dev": true 565 | }, 566 | "levn": { 567 | "version": "0.3.0", 568 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 569 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 570 | "dev": true, 571 | "requires": { 572 | "prelude-ls": "~1.1.2", 573 | "type-check": "~0.3.2" 574 | } 575 | }, 576 | "lodash": { 577 | "version": "4.17.11", 578 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", 579 | "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", 580 | "dev": true 581 | }, 582 | "mimic-fn": { 583 | "version": "1.2.0", 584 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 585 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", 586 | "dev": true 587 | }, 588 | "minimatch": { 589 | "version": "3.0.4", 590 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 591 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 592 | "dev": true, 593 | "requires": { 594 | "brace-expansion": "^1.1.7" 595 | } 596 | }, 597 | "minimist": { 598 | "version": "0.0.8", 599 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 600 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 601 | "dev": true 602 | }, 603 | "mkdirp": { 604 | "version": "0.5.1", 605 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 606 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 607 | "dev": true, 608 | "requires": { 609 | "minimist": "0.0.8" 610 | } 611 | }, 612 | "ms": { 613 | "version": "2.1.1", 614 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 615 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", 616 | "dev": true 617 | }, 618 | "mute-stream": { 619 | "version": "0.0.7", 620 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 621 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", 622 | "dev": true 623 | }, 624 | "natural-compare": { 625 | "version": "1.4.0", 626 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 627 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 628 | "dev": true 629 | }, 630 | "nice-try": { 631 | "version": "1.0.5", 632 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 633 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 634 | "dev": true 635 | }, 636 | "object-assign": { 637 | "version": "4.1.1", 638 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 639 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 640 | "dev": true 641 | }, 642 | "once": { 643 | "version": "1.4.0", 644 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 645 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 646 | "dev": true, 647 | "requires": { 648 | "wrappy": "1" 649 | } 650 | }, 651 | "onetime": { 652 | "version": "2.0.1", 653 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 654 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 655 | "dev": true, 656 | "requires": { 657 | "mimic-fn": "^1.0.0" 658 | } 659 | }, 660 | "optionator": { 661 | "version": "0.8.2", 662 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 663 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 664 | "dev": true, 665 | "requires": { 666 | "deep-is": "~0.1.3", 667 | "fast-levenshtein": "~2.0.4", 668 | "levn": "~0.3.0", 669 | "prelude-ls": "~1.1.2", 670 | "type-check": "~0.3.2", 671 | "wordwrap": "~1.0.0" 672 | } 673 | }, 674 | "os-tmpdir": { 675 | "version": "1.0.2", 676 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 677 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 678 | "dev": true 679 | }, 680 | "parent-module": { 681 | "version": "1.0.0", 682 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.0.tgz", 683 | "integrity": "sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA==", 684 | "dev": true, 685 | "requires": { 686 | "callsites": "^3.0.0" 687 | } 688 | }, 689 | "path-is-absolute": { 690 | "version": "1.0.1", 691 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 692 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 693 | "dev": true 694 | }, 695 | "path-is-inside": { 696 | "version": "1.0.2", 697 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 698 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", 699 | "dev": true 700 | }, 701 | "path-key": { 702 | "version": "2.0.1", 703 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 704 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", 705 | "dev": true 706 | }, 707 | "pluralize": { 708 | "version": "7.0.0", 709 | "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", 710 | "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", 711 | "dev": true 712 | }, 713 | "prelude-ls": { 714 | "version": "1.1.2", 715 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 716 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 717 | "dev": true 718 | }, 719 | "progress": { 720 | "version": "2.0.3", 721 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 722 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 723 | "dev": true 724 | }, 725 | "punycode": { 726 | "version": "2.1.1", 727 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 728 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 729 | "dev": true 730 | }, 731 | "regexpp": { 732 | "version": "2.0.1", 733 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", 734 | "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", 735 | "dev": true 736 | }, 737 | "resolve-from": { 738 | "version": "4.0.0", 739 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 740 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 741 | "dev": true 742 | }, 743 | "restore-cursor": { 744 | "version": "2.0.0", 745 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 746 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 747 | "dev": true, 748 | "requires": { 749 | "onetime": "^2.0.0", 750 | "signal-exit": "^3.0.2" 751 | } 752 | }, 753 | "rimraf": { 754 | "version": "2.6.3", 755 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 756 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 757 | "dev": true, 758 | "requires": { 759 | "glob": "^7.1.3" 760 | } 761 | }, 762 | "run-async": { 763 | "version": "2.3.0", 764 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 765 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 766 | "dev": true, 767 | "requires": { 768 | "is-promise": "^2.1.0" 769 | } 770 | }, 771 | "rxjs": { 772 | "version": "6.3.3", 773 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", 774 | "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", 775 | "dev": true, 776 | "requires": { 777 | "tslib": "^1.9.0" 778 | } 779 | }, 780 | "safer-buffer": { 781 | "version": "2.1.2", 782 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 783 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 784 | "dev": true 785 | }, 786 | "semver": { 787 | "version": "5.6.0", 788 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", 789 | "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", 790 | "dev": true 791 | }, 792 | "shebang-command": { 793 | "version": "1.2.0", 794 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 795 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 796 | "dev": true, 797 | "requires": { 798 | "shebang-regex": "^1.0.0" 799 | } 800 | }, 801 | "shebang-regex": { 802 | "version": "1.0.0", 803 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 804 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 805 | "dev": true 806 | }, 807 | "signal-exit": { 808 | "version": "3.0.2", 809 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 810 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 811 | "dev": true 812 | }, 813 | "slice-ansi": { 814 | "version": "2.0.0", 815 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.0.0.tgz", 816 | "integrity": "sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ==", 817 | "dev": true, 818 | "requires": { 819 | "ansi-styles": "^3.2.0", 820 | "astral-regex": "^1.0.0", 821 | "is-fullwidth-code-point": "^2.0.0" 822 | } 823 | }, 824 | "sprintf-js": { 825 | "version": "1.0.3", 826 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 827 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 828 | "dev": true 829 | }, 830 | "string-width": { 831 | "version": "2.1.1", 832 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 833 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 834 | "dev": true, 835 | "requires": { 836 | "is-fullwidth-code-point": "^2.0.0", 837 | "strip-ansi": "^4.0.0" 838 | } 839 | }, 840 | "strip-ansi": { 841 | "version": "4.0.0", 842 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 843 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 844 | "dev": true, 845 | "requires": { 846 | "ansi-regex": "^3.0.0" 847 | } 848 | }, 849 | "strip-json-comments": { 850 | "version": "2.0.1", 851 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 852 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 853 | "dev": true 854 | }, 855 | "supports-color": { 856 | "version": "5.5.0", 857 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 858 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 859 | "dev": true, 860 | "requires": { 861 | "has-flag": "^3.0.0" 862 | } 863 | }, 864 | "table": { 865 | "version": "5.2.1", 866 | "resolved": "https://registry.npmjs.org/table/-/table-5.2.1.tgz", 867 | "integrity": "sha512-qmhNs2GEHNqY5fd2Mo+8N1r2sw/rvTAAvBZTaTx+Y7PHLypqyrxr1MdIu0pLw6Xvl/Gi4ONu/sdceP8vvUjkyA==", 868 | "dev": true, 869 | "requires": { 870 | "ajv": "^6.6.1", 871 | "lodash": "^4.17.11", 872 | "slice-ansi": "2.0.0", 873 | "string-width": "^2.1.1" 874 | } 875 | }, 876 | "text-table": { 877 | "version": "0.2.0", 878 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 879 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 880 | "dev": true 881 | }, 882 | "through": { 883 | "version": "2.3.8", 884 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 885 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 886 | "dev": true 887 | }, 888 | "tmp": { 889 | "version": "0.0.33", 890 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 891 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 892 | "dev": true, 893 | "requires": { 894 | "os-tmpdir": "~1.0.2" 895 | } 896 | }, 897 | "tslib": { 898 | "version": "1.9.3", 899 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", 900 | "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", 901 | "dev": true 902 | }, 903 | "type-check": { 904 | "version": "0.3.2", 905 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 906 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 907 | "dev": true, 908 | "requires": { 909 | "prelude-ls": "~1.1.2" 910 | } 911 | }, 912 | "uri-js": { 913 | "version": "4.2.2", 914 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 915 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 916 | "dev": true, 917 | "requires": { 918 | "punycode": "^2.1.0" 919 | } 920 | }, 921 | "which": { 922 | "version": "1.3.1", 923 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 924 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 925 | "dev": true, 926 | "requires": { 927 | "isexe": "^2.0.0" 928 | } 929 | }, 930 | "wordwrap": { 931 | "version": "1.0.0", 932 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 933 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", 934 | "dev": true 935 | }, 936 | "wrappy": { 937 | "version": "1.0.2", 938 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 939 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 940 | "dev": true 941 | }, 942 | "write": { 943 | "version": "0.2.1", 944 | "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", 945 | "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", 946 | "dev": true, 947 | "requires": { 948 | "mkdirp": "^0.5.1" 949 | } 950 | } 951 | } 952 | } 953 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "n4m-core-examples", 3 | "version": "0.0.1", 4 | "description": "A collection of core examples for Node for Max", 5 | "scripts": { 6 | "lint": "eslint .", 7 | "lint-fix": "eslint . --fix", 8 | "test": "npm run lint" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/Cycling74/n4m-core-examples.git" 13 | }, 14 | "keywords": [ 15 | "node for max", 16 | "creative coding", 17 | "max/msp" 18 | ], 19 | "author": "Cassie Tarakajian ", 20 | "contributors": [ 21 | "Sam Tarakajian " 23 | ], 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/Cycling74/n4m-core-examples/issues" 27 | }, 28 | "homepage": "https://github.com/Cycling74/n4m-core-examples#readme", 29 | "devDependencies": { 30 | "eslint": "^5.12.0", 31 | "eslint-config-c74": "^1.0.0" 32 | } 33 | } 34 | --------------------------------------------------------------------------------