js-beautify 1.7.4 → 1.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,4 +1,15 @@
1
1
  # Changelog
2
+ ## v1.7.5
3
+
4
+ ### Description
5
+
6
+
7
+ ### Closed Issues
8
+ * Strict mode: js_source_text is not defined [CSS] ([#1286](https://github.com/beautify-web/js-beautify/issues/1286))
9
+ * Made brace_style option more inclusive ([#1277](https://github.com/beautify-web/js-beautify/pull/1277))
10
+ * White space before"!important" tag missing in CSS beautify ([#1273](https://github.com/beautify-web/js-beautify/issues/1273))
11
+
12
+
2
13
  ## v1.7.4
3
14
 
4
15
  ### Description
@@ -32,6 +43,7 @@ Lessons learned:
32
43
 
33
44
 
34
45
  ### Closed Issues
46
+ * undindent-chained-methods option. Resolves #482 ([#1240](https://github.com/beautify-web/js-beautify/pull/1240))
35
47
  * Add test and tools folder to npmignore ([#1239](https://github.com/beautify-web/js-beautify/issues/1239))
36
48
  * incorrect new-line insertion after "yield" ([#1206](https://github.com/beautify-web/js-beautify/issues/1206))
37
49
  * Do not modify built-in objects ([#1205](https://github.com/beautify-web/js-beautify/issues/1205))
package/CONTRIBUTING.md CHANGED
@@ -2,59 +2,59 @@
2
2
 
3
3
 
4
4
  ## Report Issues and Request Changes
5
- If you find a bug, please report it, including environment and examples of current behavior and what you believe to be the correct behavior. The clearer your description and information, the more likely it is someone will be able to make progress on it. The default issue template will help guide you through this.
5
+ If you find a bug, please report it, including environment and examples of current behavior and what you believe to be the correct behavior. The clearer your description and information, the more likely it is someone will be able to make progress on it. The default issue template will help guide you through this.
6
6
 
7
- ## How to Make Changes (Implement Fixes and New Features)
7
+ ## How to Make Changes (Implement Fixes and New Features)
8
8
  Fixes and enhancements are totally welcome. We prefer if you file an issue before filing a PR, as this gives us chance to discuss design details, but fee free to dive right in.
9
9
 
10
10
  ### 1. Build and Test Locally
11
- While developing, you may build and test locally in JavaScript or Python implementation. The HTML beautifier is only implemented in JavaScript.
11
+ While developing, you may build and test locally in JavaScript or Python implementation. The HTML beautifier is only implemented in JavaScript.
12
12
 
13
- * Familiarize yourself with the folder structure and code style before you dive in.
14
- * Make changes to the implemnation of your choice
15
- * Add tests to `/test/data/*/test.js`.
16
- * Run `./build jstest` or `./build pytest` to run style checks, and to generate and run tests.
13
+ * Familiarize yourself with the folder structure and code style before you dive in.
14
+ * Make changes to the implementation of your choice
15
+ * Add tests to `/test/data/*/test.js`.
16
+ * Run `./build jstest` or `./build pytest` to run style checks, and to generate and run tests.
17
17
  * Include all changed files in your commit - The generated test files are checked in along with changes to the test data files.
18
18
 
19
19
  ### 2. Ensure Feature Parity
20
- You must port changes to the other implementation. **This is required**. Every time we make an exception to this requirement the project becomes harder to maintain. If you find yourself making changes and find you cannot port them to the other implementation due to implmentations being out of sync, you will begin to understand why this is required. We made this a requirement several years ago and there are still a open issues for changes that people at the time promised to port "in the next week or two". The entire HTML beautifier is an example of this. :(
20
+ You must port changes to the other implementation. **This is required**. Every time we make an exception to this requirement the project becomes harder to maintain. If you find yourself making changes and find you cannot port them to the other implementation due to implementations being out of sync, you will begin to understand why this is required. We made this a requirement several years ago and there are still a open issues for changes that people at the time promised to port "in the next week or two". The entire HTML beautifier is an example of this. :(
21
21
 
22
22
  The implementations are already very similar and neither Python nor JavaScript are that hard to understand. Take the plunge, it is easier than you think. If you get stuck, move on to filing a Pull Request and we can discuss how to move forward.
23
23
 
24
- * Run `./build` (with no parameters) to run style checks, and to generate and run tests on both implementations.
24
+ * Run `./build` (with no parameters) to run style checks, and to generate and run tests on both implementations.
25
25
  * Include all changed files in your commit - The generated test files are checked in along with changes to the test data files.
26
26
 
27
27
  ### 3. Update Documentation and Tools
28
28
  Update documentation as needed. This such as the README.md, internal command-line help, and file comments.
29
- Also, check your change needs any tooling updates. For example, the CDN urls required added scripting to update automatically for new releases.
29
+ Also, check your change needs any tooling updates. For example, the CDN URLs required added scripting to update automatically for new releases.
30
30
 
31
- ### 4. Submit a Pull Request
31
+ ### 4. Submit a Pull Request
32
32
 
33
33
  * Run `./build full` locally after commit but before creation of Pull Request. You may start a Pull Request if this does not succeed, but the PR will not be accepted without additional changes.
34
- * Include description of changes. Include examples of input and expected output if possible.
35
- * Pull requests must pass build checks on all platforms before being accepted. We use travis-ci and appveyor to run tests on Linux and Windows, across multiple versions of Node.js and Python.
34
+ * Include description of changes. Include examples of input and expected output if possible.
35
+ * Pull requests must pass build checks on all platforms before being accepted. We use Travis CI and AppVeyor to run tests on Linux and Windows, across multiple versions of Node.js and Python.
36
36
 
37
37
  # Folders
38
38
 
39
39
  ## Root
40
- Some files related to specific implementations or platforms are found in the root folder, but most are cross-project tools and configuration.
40
+ Some files related to specific implementations or platforms are found in the root folder, but most are cross-project tools and configuration.
41
41
 
42
- ## js
43
- Files related to the JavaScript implmentations of the beautifiers.
42
+ ## `js`
43
+ Files related to the JavaScript implementations of the beautifiers.
44
44
 
45
- ## python
46
- Files related to the Python implmentations of the beautifiers.
45
+ ## `python`
46
+ Files related to the Python implementations of the beautifiers.
47
47
 
48
48
 
49
- ## web
50
- Files related to http://jsbeautifier.org/.
49
+ ## `web`
50
+ Files related to http://jsbeautifier.org/.
51
51
 
52
- ## test
53
- Test data files and support files used to generate implmentation-specific test files from them.
52
+ ## `test`
53
+ Test data files and support files used to generate implementation-specific test files from them.
54
54
 
55
55
 
56
56
  # Branches
57
- We use the `master` branch as the primrary development branch.
57
+ We use the `master` branch as the primary development branch.
58
58
 
59
59
  ## Releases
60
60
  Each platform has a branch that tracks to the latest release of that platform.
@@ -64,7 +64,7 @@ Each platform has a branch that tracks to the latest release of that platform.
64
64
  * `gh-pages`
65
65
 
66
66
  ## Functional Parity
67
- Keeping the platforms in some semblance of functional parity is one of the key features of this project. As such, there branches for the last time synchronization occured and when it stablized.
67
+ Keeping the platforms in some semblance of functional parity is one of the key features of this project. As such, there branches for the last time synchronization occurred and when it stabilized.
68
68
 
69
69
  * `sync`
70
70
  * `sync-stable`
@@ -91,21 +91,20 @@ it on this separate branch to keep it from hurting the other children.
91
91
  # Publishing a Release
92
92
  Each platform has it's own release process.
93
93
 
94
- NOTE: Before you do any of these make sure the latest changes have passed the travis-ci build!
94
+ NOTE: Before you do any of these make sure the latest changes have passed the Travis CI build!
95
95
 
96
96
  ## Web
97
97
  Merge changes from `master` to `gh-pages` branch. This is very low cost and can be done whenever is convenient.
98
98
 
99
99
  ## Python
100
- NOTE: For now, we'd like to keep python and node version numbers synchronized,
101
- so if you publish a python release, you should publish a node release as well.
100
+ NOTE: For now, we'd like to keep Python and Node version numbers synchronized,
101
+ so if you publish a Python release, you should publish a Node release as well.
102
102
 
103
103
  To perform these steps you will need:
104
- 1. A pypi user account from https://pypi.python.org/pypi?%3Aaction=register_form .
105
- 2. Permissions to the jsbeautifier package. File an issue here on github and the appropriate person will help you.
106
-
107
- We basically follow the simplest release path found at http://docs.python.org/2/distutils/packageindex.html . :
104
+ 1. A PyPI user account from https://pypi.python.org/pypi?%3Aaction=register_form.
105
+ 2. Permissions to the jsbeautifier package. File an issue here on GitHub and the appropriate person will help you.
108
106
 
107
+ We basically follow the simplest release path found at http://docs.python.org/2/distutils/packageindex.html:
109
108
  ```bash
110
109
  git clean -xfd
111
110
  # replace 0.0.1 with the actual version number you want to use
@@ -119,15 +118,15 @@ git push
119
118
  ```
120
119
 
121
120
  ## Node
122
- NOTE: For now, we'd like to keep python and node version numbers synchronized,
123
- so if you plan to publish a node release, you should publish a python release *first*,
121
+ NOTE: For now, we'd like to keep Python and Node version numbers synchronized,
122
+ so if you plan to publish a Node release, you should publish a Python release *first*,
124
123
  then perform the steps below.
125
124
 
126
125
  To perform these steps you will need:
127
- 1. An npmjs.org user account from https://npmjs.org/signup .
128
- 2. Permissions to the js-beautify module on npmjs.org. File an issue here on github and the appropriate person will help you.
126
+ 1. An npmjs.org user account from https://npmjs.org/signup.
127
+ 2. Permissions to the js-beautify module on npmjs.org. File an issue here on GitHub and the appropriate person will help you.
129
128
 
130
- Npm makes this process even simpler than python's and creates a tag for the release as well.
129
+ Npm makes this process even simpler than Python's and creates a tag for the release as well.
131
130
 
132
131
  ```bash
133
132
  git clean -xfd
package/README.md CHANGED
@@ -8,6 +8,7 @@
8
8
  [![Download stats](https://img.shields.io/npm/dm/js-beautify.svg)](https://www.npmjs.com/package/js-beautify)
9
9
 
10
10
  [![Join the chat at https://gitter.im/beautify-web/js-beautify](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/beautify-web/js-beautify?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
11
+ [![Twitter Follow](https://img.shields.io/twitter/follow/js_beautifier.svg?style=social&label=Follow)](https://twitter.com/intent/user?screen_name=js_beautifier)
11
12
 
12
13
  [![NPM stats](https://nodei.co/npm/js-beautify.svg?downloadRank=true&downloads=true)](https://www.npmjs.org/package/js-beautify)
13
14
 
@@ -24,17 +25,17 @@ JS Beautifier is hosted on two CDN services: [cdnjs](https://cdnjs.com/libraries
24
25
 
25
26
  To pull from one of these services include one set of the script tags below in your document:
26
27
  ```html
27
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.4/beautify.js"></script>
28
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.4/beautify-css.js"></script>
29
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.4/beautify-html.js"></script>
28
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.5/beautify.js"></script>
29
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.5/beautify-css.js"></script>
30
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.5/beautify-html.js"></script>
30
31
 
31
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.4/beautify.min.js"></script>
32
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.4/beautify-css.min.js"></script>
33
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.4/beautify-html.min.js"></script>
32
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.5/beautify.min.js"></script>
33
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.5/beautify-css.min.js"></script>
34
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.5/beautify-html.min.js"></script>
34
35
 
35
- <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.7.4/js/lib/beautify.js"></script>
36
- <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.7.4/js/lib/beautify-css.js"></script>
37
- <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.7.4/js/lib/beautify-html.js"></script>
36
+ <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.7.5/js/lib/beautify.js"></script>
37
+ <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.7.5/js/lib/beautify-css.js"></script>
38
+ <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.7.5/js/lib/beautify-html.js"></script>
38
39
  ```
39
40
  Disclaimer: These are free services, so there are [no uptime or support guarantees](https://github.com/rgrove/rawgit/wiki/Frequently-Asked-Questions#i-need-guaranteed-100-uptime-should-i-use-cdnrawgitcom).
40
41
 
@@ -321,4 +322,4 @@ Thanks also to Jason Diamond, Patrick Hof, Nochum Sossonko, Andreas Schneider, D
321
322
  Vasilevsky, Vital Batmanov, Ron Baldwin, Gabriel Harrison, Chris J. Shull,
322
323
  Mathias Bynens, Vittorio Gambaletta and others.
323
324
 
324
- (README.md: js-beautify@1.7.4)
325
+ (README.md: js-beautify@1.7.5)
@@ -335,7 +335,7 @@ function Beautifier(source_text, options) {
335
335
  preindent_index += 1;
336
336
  }
337
337
  baseIndentString = source_text.substring(0, preindent_index);
338
- js_source_text = source_text.substring(preindent_index);
338
+ source_text = source_text.substring(preindent_index);
339
339
  }
340
340
 
341
341
 
@@ -584,7 +584,9 @@ function Beautifier(source_text, options) {
584
584
  if (whiteRe.test(ch)) {
585
585
  ch = '';
586
586
  }
587
-
587
+ } else if (ch === '!') { // !important
588
+ print_string(' ');
589
+ print_string(ch);
588
590
  } else {
589
591
  preserveSingleSpace(isAfterSpace);
590
592
  print_string(ch);
@@ -425,15 +425,22 @@ function Beautifier(js_source_text, options) {
425
425
  options.brace_style = "collapse,preserve-inline";
426
426
  } else if (options.braces_on_own_line !== undefined) { //graceful handling of deprecated option
427
427
  options.brace_style = options.braces_on_own_line ? "expand" : "collapse";
428
- } else if (!options.brace_style) //Nothing exists to set it
429
- {
428
+ } else if (!options.brace_style) { //Nothing exists to set it
430
429
  options.brace_style = "collapse";
431
430
  }
432
431
 
433
-
432
+ //preserve-inline in delimited string will trigger brace_preserve_inline, everything
433
+ //else is considered a brace_style and the last one only will have an effect
434
434
  var brace_style_split = options.brace_style.split(/[^a-zA-Z0-9_\-]+/);
435
- opt.brace_style = brace_style_split[0];
436
- opt.brace_preserve_inline = brace_style_split[1] ? brace_style_split[1] : false;
435
+ opt.brace_preserve_inline = false; //Defaults in case one or other was not specified in meta-option
436
+ opt.brace_style = "collapse";
437
+ for (var bs = 0; bs < brace_style_split.length; bs++) {
438
+ if (brace_style_split[bs] === "preserve-inline") {
439
+ opt.brace_preserve_inline = true;
440
+ } else {
441
+ opt.brace_style = brace_style_split[bs];
442
+ }
443
+ }
437
444
 
438
445
  opt.indent_size = options.indent_size ? parseInt(options.indent_size, 10) : 4;
439
446
  opt.indent_char = options.indent_char ? options.indent_char : ' ';
package/js/lib/cli.js CHANGED
@@ -41,20 +41,23 @@ var fs = require('fs'),
41
41
  beautify = require('../index'),
42
42
  mkdirp = require('mkdirp'),
43
43
  nopt = require('nopt');
44
+ nopt.invalidHandler = function(key, val, types) {
45
+ throw new Error(key + " was invalid with value \"" + val + "\"");
46
+ }
44
47
  nopt.typeDefs.brace_style = {
45
48
  type: "brace_style",
46
49
  validate: function(data, key, val) {
47
50
  data[key] = val;
48
51
  // TODO: expand-strict is obsolete, now identical to expand. Remove in future version
49
52
  // TODO: collapse-preserve-inline is obselete, now identical to collapse,preserve-inline = true. Remove in future version
50
- var validVals = ["collapse", "collapse-preserve-inline", "expand", "end-expand", "expand-strict", "none"];
51
- var valSplit = val.split(/[^a-zA-Z0-9_\-]+/);
52
- for (var i = 0; i < validVals.length; i++) {
53
- if (validVals[i] === val || validVals[i] === valSplit[0] && valSplit[1] === "preserve-inline") {
54
- return true;
53
+ var validVals = ["collapse", "collapse-preserve-inline", "expand", "end-expand", "expand-strict", "none", "preserve-inline"];
54
+ var valSplit = val.split(/[^a-zA-Z0-9_\-]+/); //Split will always return at least one parameter
55
+ for (var i = 0; i < valSplit.length; i++) {
56
+ if (validVals.indexOf(valSplit[i]) === -1) {
57
+ return false;
55
58
  }
56
59
  }
57
- return false;
60
+ return true;
58
61
  }
59
62
  };
60
63
  var path = require('path'),
@@ -235,7 +238,16 @@ function set_file_editorconfig_opts(file, config) {
235
238
 
236
239
  // var cli = require('js-beautify/cli'); cli.interpret();
237
240
  var interpret = exports.interpret = function(argv, slice) {
238
- var parsed = nopt(knownOpts, shortHands, argv, slice);
241
+ var parsed;
242
+ try {
243
+ parsed = nopt(knownOpts, shortHands, argv, slice);
244
+ } catch (ex) {
245
+ usage(ex);
246
+ // console.error(ex);
247
+ // console.error('Run `' + getScriptName() + ' -h` for help.');
248
+ process.exit(1);
249
+ }
250
+
239
251
 
240
252
  if (parsed.version) {
241
253
  console.log(require('../../package.json').version);
@@ -196,7 +196,7 @@ function Beautifier(source_text, options) {
196
196
  preindent_index += 1;
197
197
  }
198
198
  baseIndentString = source_text.substring(0, preindent_index);
199
- js_source_text = source_text.substring(preindent_index);
199
+ source_text = source_text.substring(preindent_index);
200
200
  }
201
201
 
202
202
 
@@ -445,7 +445,9 @@ function Beautifier(source_text, options) {
445
445
  if (whiteRe.test(ch)) {
446
446
  ch = '';
447
447
  }
448
-
448
+ } else if (ch === '!') { // !important
449
+ print_string(' ');
450
+ print_string(ch);
449
451
  } else {
450
452
  preserveSingleSpace(isAfterSpace);
451
453
  print_string(ch);
@@ -193,15 +193,22 @@ function Beautifier(js_source_text, options) {
193
193
  options.brace_style = "collapse,preserve-inline";
194
194
  } else if (options.braces_on_own_line !== undefined) { //graceful handling of deprecated option
195
195
  options.brace_style = options.braces_on_own_line ? "expand" : "collapse";
196
- } else if (!options.brace_style) //Nothing exists to set it
197
- {
196
+ } else if (!options.brace_style) { //Nothing exists to set it
198
197
  options.brace_style = "collapse";
199
198
  }
200
199
 
201
-
200
+ //preserve-inline in delimited string will trigger brace_preserve_inline, everything
201
+ //else is considered a brace_style and the last one only will have an effect
202
202
  var brace_style_split = options.brace_style.split(/[^a-zA-Z0-9_\-]+/);
203
- opt.brace_style = brace_style_split[0];
204
- opt.brace_preserve_inline = brace_style_split[1] ? brace_style_split[1] : false;
203
+ opt.brace_preserve_inline = false; //Defaults in case one or other was not specified in meta-option
204
+ opt.brace_style = "collapse";
205
+ for (var bs = 0; bs < brace_style_split.length; bs++) {
206
+ if (brace_style_split[bs] === "preserve-inline") {
207
+ opt.brace_preserve_inline = true;
208
+ } else {
209
+ opt.brace_style = brace_style_split[bs];
210
+ }
211
+ }
205
212
 
206
213
  opt.indent_size = options.indent_size ? parseInt(options.indent_size, 10) : 4;
207
214
  opt.indent_char = options.indent_char ? options.indent_char : ' ';
@@ -569,6 +569,10 @@ function run_css_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_bea
569
569
  '.div {}\n' +
570
570
  '\n' +
571
571
  '.span {}');
572
+ t(
573
+ 'html {}\n' +
574
+ '\n' +
575
+ '/*this is a comment*/');
572
576
  t(
573
577
  '.div {\n' +
574
578
  '\ta: 1;\n' +
@@ -1251,6 +1255,31 @@ function run_css_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_bea
1251
1255
  '}');
1252
1256
 
1253
1257
 
1258
+ //============================================================
1259
+ // Important
1260
+ reset_options();
1261
+ t(
1262
+ 'a {\n' +
1263
+ '\tcolor: blue !important;\n' +
1264
+ '}',
1265
+ // -- output --
1266
+ 'a {\n' +
1267
+ '\tcolor: blue !important;\n' +
1268
+ '}');
1269
+ t(
1270
+ 'a {\n' +
1271
+ '\tcolor: blue!important;\n' +
1272
+ '}',
1273
+ // -- output --
1274
+ 'a {\n' +
1275
+ '\tcolor: blue !important;\n' +
1276
+ '}');
1277
+ t(
1278
+ 'a {\n' +
1279
+ '\tcolor: blue !important;\n' +
1280
+ '}');
1281
+
1282
+
1254
1283
  //============================================================
1255
1284
  //
1256
1285
  reset_options();
@@ -55,7 +55,6 @@ test_cli_common()
55
55
  echo "[$CLI_SCRIPT_NAME $MISSING_FILE] Stdout should have no text."
56
56
  exit 1
57
57
  fi
58
-
59
58
  }
60
59
 
61
60
  setup_temp()
@@ -341,6 +340,20 @@ test_cli_js_beautify()
341
340
  cleanup 1
342
341
  }
343
342
 
343
+ #meta-parameter brace_style
344
+ $CLI_SCRIPT -b 'invalid' $TEST_TEMP/example1-default.js > /dev/null && {
345
+ echo "[$CLI_SCRIPT_NAME -b 'invalid' $TEST_TEMP/example1-default.js] Return code for invalid brace_style meta-parameter should be error."
346
+ cleanup 1
347
+ }
348
+ $CLI_SCRIPT -b 'expand,preserve-inline,invalid' $TEST_TEMP/example1-default.js > /dev/null && {
349
+ echo "[$CLI_SCRIPT_NAME -b 'expand,preserve-inline,invalid' $TEST_TEMP/example1-default.js] Return code for invalid brace_style meta-parameter should be error."
350
+ cleanup 1
351
+ }
352
+ $CLI_SCRIPT -b 'preserve-inline' $TEST_TEMP/example1-default.js > /dev/null || {
353
+ echo "[$CLI_SCRIPT_NAME -b 'preserve-inline' $TEST_TEMP/example1-default.js] Return code for only one part of valid brace_style meta-parameter should be success (uses default where it can)."
354
+ cleanup 1
355
+ }
356
+
344
357
  cleanup
345
358
  }
346
359
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-beautify",
3
- "version": "1.7.4",
3
+ "version": "1.7.5",
4
4
  "description": "jsbeautifier.org for node",
5
5
  "main": "js/index.js",
6
6
  "bin": {