조인천

ver3

Showing 121 changed files with 5023 additions and 4 deletions
1 var request = require('request'); 1 var request = require('request');
2 2
3 var optionParams = { 3 var optionParams = {
4 - q:"kakao", 4 + q:"저라뎃",
5 part:"snippet", 5 part:"snippet",
6 key:"AIzaSyCgGa6aM7taXs4bajtYukbc_EQAKTLVTNc", 6 key:"AIzaSyCgGa6aM7taXs4bajtYukbc_EQAKTLVTNc",
7 - maxResult2:5 7 + type:"video",
8 + maxResult2:5,
9 + regionCode:"KR",
10 + videoDuration:"short"
8 }; 11 };
12 +optionParams.q = encodeURI(optionParams.q);
13 +
9 var url = "https://www.googleapis.com/youtube/v3/search?"; 14 var url = "https://www.googleapis.com/youtube/v3/search?";
10 for (var option in optionParams) 15 for (var option in optionParams)
11 { 16 {
...@@ -14,6 +19,33 @@ for (var option in optionParams) ...@@ -14,6 +19,33 @@ for (var option in optionParams)
14 19
15 url = url.substr(0,url.length-1); 20 url = url.substr(0,url.length-1);
16 21
22 +var VideoIds = new Array();
23 +var idx = 0;
17 request(url, function(err,res,body){ 24 request(url, function(err,res,body){
18 - console.log(body)
19 -});
...\ No newline at end of file ...\ No newline at end of file
25 + //console.log(body)
26 + var data = JSON.parse(body).items;
27 +
28 + for(var content in data)
29 + {
30 + VideoIds[idx]=(data[content].id.videoId);
31 + idx++;
32 + }
33 + console.log(VideoIds.length);
34 + console.log(VideoIds[0]);
35 + console.log(typeof(VideoIds[1]));
36 +
37 + //다운로드 부분
38 + var fs = require('fs');
39 + var youtubedl = require('youtube-dl');
40 + var video = youtubedl('http://www.youtube.com/watch?v='.concat(VideoIds[1]));
41 +
42 + video.on('info',function(info)
43 + {
44 + console.log('Download started');
45 + console.log('filename : '+ info.filename);
46 + console.log('size : '+info.size);
47 + });
48 +
49 + video.pipe(fs.createWriteStream('justlikethat.mp4'));
50 +});
51 +
......
This file is too large to display.
This file is too large to display.
This file is too large to display.
This file is too large to display.
1 +#!/bin/sh
2 +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3 +
4 +case `uname` in
5 + *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
6 +esac
7 +
8 +if [ -x "$basedir/node" ]; then
9 + "$basedir/node" "$basedir/../mkdirp/bin/cmd.js" "$@"
10 + ret=$?
11 +else
12 + node "$basedir/../mkdirp/bin/cmd.js" "$@"
13 + ret=$?
14 +fi
15 +exit $ret
1 +@IF EXIST "%~dp0\node.exe" (
2 + "%~dp0\node.exe" "%~dp0\..\mkdirp\bin\cmd.js" %*
3 +) ELSE (
4 + @SETLOCAL
5 + @SET PATHEXT=%PATHEXT:;.JS;=;%
6 + node "%~dp0\..\mkdirp\bin\cmd.js" %*
7 +)
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
1 +Copyright (C) 2011 by Roly Fentanes
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
8 +furnished to do so, subject to the following conditions:
9 +
10 +The above copyright notice and this permission notice shall be included in
11 +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.
1 +# youtube-dl
2 +
3 +[![Build Status](https://travis-ci.org/przemyslawpluta/node-youtube-dl.svg?branch=master)](https://travis-ci.org/przemyslawpluta/node-youtube-dl) [![npm version](https://badge.fury.io/js/youtube-dl.svg)](https://badge.fury.io/js/youtube-dl)
4 +
5 +Download videos from youtube in node.js using [youtube-dl](http://rg3.github.com/youtube-dl/).
6 +
7 +If you're only interested in downloading only from youtube, you should consider using [pure Javascript youtube downloading module](https://github.com/fent/node-ytdl).
8 +
9 +## Installation
10 +
11 +With [npm](https://www.npmjs.com/) do:
12 +
13 +``` sh
14 +npm install @microlink/youtube-dl
15 +```
16 +
17 +## Usage
18 +
19 +### Downloading videos
20 +
21 +``` js
22 +var fs = require('fs');
23 +var youtubedl = require('youtube-dl');
24 +var video = youtubedl('http://www.youtube.com/watch?v=90AiXO1pAiA',
25 + // Optional arguments passed to youtube-dl.
26 + ['--format=18'],
27 + // Additional options can be given for calling `child_process.execFile()`.
28 + { cwd: __dirname });
29 +
30 +// Will be called when the download starts.
31 +video.on('info', function(info) {
32 + console.log('Download started');
33 + console.log('filename: ' + info._filename);
34 + console.log('size: ' + info.size);
35 +});
36 +
37 +video.pipe(fs.createWriteStream('myvideo.mp4'));
38 +```
39 +
40 +It will produce an output that looks like the following when ran.
41 +
42 +```bash
43 +Got video info
44 +saving to T-ara - Number Nine - MV - 티아라-Seku9G1kT0c.mp4
45 +100.00%
46 +```
47 +
48 +### Resuming partially downloaded videos
49 +
50 +``` js
51 +var youtubedl = require('./');
52 +var fs = require('fs');
53 +var output = 'myvideo.mp4';
54 +
55 +var downloaded = 0;
56 +if (fs.existsSync(output)) {
57 + downloaded = fs.statSync(output).size;
58 +}
59 +
60 +var video = youtubedl('https://www.youtube.com/watch?v=179MiZSibco',
61 +
62 + // Optional arguments passed to youtube-dl.
63 + ['--format=18'],
64 +
65 + // start will be sent as a range header
66 + { start: downloaded, cwd: __dirname });
67 +
68 +// Will be called when the download starts.
69 +video.on('info', function(info) {
70 + console.log('Download started');
71 + console.log('filename: ' + info._filename);
72 +
73 + // info.size will be the amount to download, add
74 + var total = info.size + downloaded;
75 + console.log('size: ' + total);
76 +
77 + if (downloaded > 0) {
78 + // size will be the amount already downloaded
79 + console.log('resuming from: ' + downloaded);
80 +
81 + // display the remaining bytes to download
82 + console.log('remaining bytes: ' + info.size);
83 + }
84 +});
85 +
86 +video.pipe(fs.createWriteStream('myvideo.mp4', { flags: 'a' }));
87 +
88 +// Will be called if download was already completed and there is nothing more to download.
89 +video.on('complete', function complete(info) {
90 + 'use strict';
91 + console.log('filename: ' + info._filename + ' already downloaded.');
92 +});
93 +
94 +video.on('end', function() {
95 + console.log('finished downloading!');
96 +});
97 +```
98 +
99 +It will produce an output that looks like the following when ran.
100 +
101 +**Output:**
102 +
103 +``` sh
104 +[~/nodejs/node-youtube-dl/example]$ node resume.js
105 +Download started
106 +filename: 1 1 1-179MiZSibco.mp4
107 +size: 5109213
108 +^C
109 +```
110 +
111 +``` sh
112 +[~/nodejs/node-youtube-dl/example]$ node resume.js
113 +Download started
114 +filename: 1 1 1-179MiZSibco.mp4
115 +size: 5109213
116 +resuming from: 917504
117 +remaining bytes: 4191709
118 +finished downloading
119 +```
120 +
121 +### Getting video information
122 +
123 +``` js
124 +var youtubedl = require('youtube-dl');
125 +var url = 'http://www.youtube.com/watch?v=WKsjaOqDXgg';
126 +// Optional arguments passed to youtube-dl.
127 +var options = ['--username=user', '--password=hunter2'];
128 +youtubedl.getInfo(url, options, function(err, info) {
129 + if (err) throw err;
130 +
131 + console.log('id:', info.id);
132 + console.log('title:', info.title);
133 + console.log('url:', info.url);
134 + console.log('thumbnail:', info.thumbnail);
135 + console.log('description:', info.description);
136 + console.log('filename:', info._filename);
137 + console.log('format id:', info.format_id);
138 +});
139 +```
140 +
141 +Running that will produce something like
142 +
143 +``` sh
144 +id: WKsjaOqDXgg
145 +title: Ace Rimmer to the Rescue
146 +url: http://r5---sn-p5qlsn7e.c.youtube.com/videoplayback?ms=au&ip=160.79.125.18&cp=U0hWTFVQVl9FTENONl9NSlpDOjgtU1VsODlkVmRH&id=58ab2368ea835e08&source=youtube&expire=1377558202&factor=1.25&key=yt1&ipbits=8&mt=1377534150&itag=34&sver=3&upn=-rGWz2vYpN4&fexp=912306%2C927900%2C919395%2C926518%2C936203%2C913819%2C929117%2C929121%2C929906%2C929907%2C929922%2C929127%2C929129%2C929131%2C929930%2C925726%2C925720%2C925722%2C925718%2C929917%2C906945%2C929919%2C929933%2C912521%2C932306%2C913428%2C904830%2C919373%2C930803%2C908536%2C904122%2C938701%2C936308%2C909549%2C900816%2C912711%2C904494%2C904497%2C900375%2C906001&sparams=algorithm%2Cburst%2Ccp%2Cfactor%2Cid%2Cip%2Cipbits%2Citag%2Csource%2Cupn%2Cexpire&mv=m&burst=40&algorithm=throttle-factor&signature=ABD3A847684AD9B39331E567568D3FA0DCFA4776.7895521E130A042FB3625A17242CE3C02A4460B7&ratebypass=yes
147 +thumbnail: https://i1.ytimg.com/vi/WKsjaOqDXgg/hqdefault.jpg
148 +description: An old Red Dwarf eposide where Ace Rimmer saves the Princess Bonjella.
149 +filename: Ace Rimmer to the Rescue-WKsjaOqDXgg.flv
150 +format id: 34
151 +```
152 +
153 +You can use an array of urls to produce an array of response objects with matching array index (e.g. the 1st response object will match the first url etc...)
154 +
155 +``` js
156 +var youtubedl = require('youtube-dl');
157 +var url1 = 'http://www.youtube.com/watch?v=WKsjaOqDXgg';
158 +var url2 = 'https://vimeo.com/6586873';
159 +youtubedl.getInfo([url1, url2], function(err, info) {
160 + if (err) throw err;
161 +
162 + console.log('title for the url1:', info[0].title);
163 + console.log('title for the url2:', info[1].title);
164 +});
165 +```
166 +
167 +### Downloading subtitles
168 +
169 +``` js
170 +var youtubedl = require('youtube-dl');
171 +var url = 'https://youtu.be/PizwcirYuGY';
172 +
173 +var options = {
174 + // Write automatic subtitle file (youtube only)
175 + auto: false,
176 + // Downloads all the available subtitles.
177 + all: false,
178 + // Subtitle format. YouTube generated subtitles
179 + // are available ttml or vtt.
180 + format: 'ttml',
181 + // Languages of subtitles to download, separated by commas.
182 + lang: 'en',
183 + // The directory to save the downloaded files in.
184 + cwd: __dirname,
185 +};
186 +youtubedl.getSubs(url, options, function(err, files) {
187 + if (err) throw err;
188 +
189 + console.log('subtitle files downloaded:', files);
190 +});
191 +```
192 +
193 +### Downloading thumbnails
194 +
195 +``` js
196 +var youtubedl = require('youtube-dl');
197 +var url = 'https://youtu.be/PizwcirYuGY';
198 +
199 +var options = {
200 + // Downloads available thumbnail.
201 + all: false,
202 + // The directory to save the downloaded files in.
203 + cwd: __dirname,
204 +};
205 +youtubedl.getThumbs(url, options, function(err, files) {
206 + if (err) throw err;
207 + console.log('thumbnail file downloaded:', files);
208 +});
209 +```
210 +
211 +For more usage info on youtube-dl and the arguments you can pass to it, do `youtube-dl -h` or go to the [youtube-dl documentation][].
212 +
213 +### Downloading playlists
214 +
215 +``` js
216 +
217 +var path = require('path');
218 +var fs = require('fs');
219 +var ytdl = require('youtube-dl');
220 +
221 +function playlist(url) {
222 +
223 + 'use strict';
224 + var video = ytdl(url);
225 +
226 + video.on('error', function error(err) {
227 + console.log('error 2:', err);
228 + });
229 +
230 + var size = 0;
231 + video.on('info', function(info) {
232 + size = info.size;
233 + var output = path.join(__dirname + '/', size + '.mp4');
234 + video.pipe(fs.createWriteStream(output));
235 + });
236 +
237 + var pos = 0;
238 + video.on('data', function data(chunk) {
239 + pos += chunk.length;
240 + // `size` should not be 0 here.
241 + if (size) {
242 + var percent = (pos / size * 100).toFixed(2);
243 + process.stdout.cursorTo(0);
244 + process.stdout.clearLine(1);
245 + process.stdout.write(percent + '%');
246 + }
247 + });
248 +
249 + video.on('next', playlist);
250 +
251 +}
252 +
253 +playlist('https://www.youtube.com/playlist?list=PLEFA9E9D96CB7F807');
254 +
255 +```
256 +
257 +### Getting the list of extractors
258 +
259 +``` js
260 +var youtubedl = require('youtube-dl');
261 +youtubedl.getExtractors(true, function(err, list) {
262 + console.log('Found ' + list.length + ' extractors');
263 + for (var i = 0; i < list.length; i++) {
264 + console.log(list[i]);
265 + }
266 +});
267 +```
268 +
269 +Will print something like
270 +
271 +``` sh
272 +Found 521 extractors
273 +1up.com
274 +220.ro
275 +24video
276 +3sat
277 +```
278 +
279 +### Call the `youtube-dl` binary directly
280 +
281 +This module doesn't have `youtube-dl` download the video. Instead, it uses the `url` key from the `--dump-json` CLI option to create a node stream. That way, it can be used like any other node stream.
282 +
283 +If that, or none of the above support your use case, you can use `ytdl.exec()` to call `youtube-dl` however you like.
284 +
285 +``` js
286 +ytdl.exec(url, ['-x', '--audio-format', 'mp3'], {}, function(err, output) {
287 + if (err) throw err;
288 + console.log(output.join('\n'));
289 +});
290 +```
291 +
292 +### Update
293 +
294 +Since the youtube-dl binary is updated regularly, you can run `npm run update` to check for and download any updates for it. You can also require `../lib/downloader` in your app if you'd like to place `youtube-dl` binary in a specific directory and control when it gets updates.
295 +
296 +``` js
297 +var downloader = require('../lib/downloader');
298 +
299 +downloader('path/to-binary', function error(err, done) {
300 + 'use strict';
301 + if (err) { return console.log(err.stack); }
302 + console.log(done);
303 +});
304 +```
305 +
306 +### Tests
307 +
308 +Tests are written with [vows](http://vowsjs.org/)
309 +
310 +``` sh
311 +npm test
312 +```
313 +
314 +## License
315 +
316 +MIT
317 +
318 +[youtube-dl]: http://rg3.github.com/youtube-dl/
319 +[youtube-dl documentation]: http://rg3.github.com/youtube-dl/documentation.html
1 +{"version":"2019.05.20","path":null,"exec":"youtube-dl.exe"}
...\ No newline at end of file ...\ No newline at end of file
1 +'use strict'
2 +
3 +const request = require('request')
4 +const mkdirp = require('mkdirp')
5 +const path = require('path')
6 +const fs = require('fs')
7 +
8 +const [, , ...flags] = process.argv
9 +
10 +const isWin = flags.includes('--platform=windows') || require('./util').isWin
11 +
12 +// First, look for the download link.
13 +let dir, filePath
14 +const defaultBin = path.join(__dirname, '..', 'bin')
15 +const defaultPath = path.join(defaultBin, 'details')
16 +const url = 'https://yt-dl.org/downloads/latest/youtube-dl'
17 +
18 +function download (url, callback) {
19 + let status
20 +
21 + // download the correct version of the binary based on the platform
22 + url = exec(url)
23 +
24 + request.get(url, { followRedirect: false }, function (err, res) {
25 + if (err) return callback(err)
26 +
27 + if (res.statusCode !== 302) {
28 + return callback(
29 + new Error(
30 + 'Did not get redirect for the latest version link. Status: ' +
31 + res.statusCode
32 + )
33 + )
34 + }
35 +
36 + const url = res.headers.location
37 + const downloadFile = request.get(url)
38 + const newVersion = /yt-dl\.org\/downloads\/(\d{4}\.\d\d\.\d\d(\.\d)?)\/youtube-dl/.exec(
39 + url
40 + )[1]
41 +
42 + downloadFile.on('response', function response (res) {
43 + if (res.statusCode !== 200) {
44 + status = new Error('Response Error: ' + res.statusCode)
45 + return
46 + }
47 + downloadFile.pipe(fs.createWriteStream(filePath, { mode: 493 }))
48 + })
49 +
50 + downloadFile.on('error', function error (err) {
51 + callback(err)
52 + })
53 +
54 + downloadFile.on('end', function end () {
55 + callback(status, newVersion)
56 + })
57 + })
58 +}
59 +
60 +const exec = path => (isWin ? path + '.exe' : path)
61 +
62 +function createBase (binDir) {
63 + dir = binDir || defaultBin
64 + mkdirp.sync(dir)
65 + if (binDir) mkdirp.sync(defaultBin)
66 + filePath = path.join(dir, exec('youtube-dl'))
67 +}
68 +
69 +function downloader (binDir, callback) {
70 + if (typeof binDir === 'function') {
71 + callback = binDir
72 + binDir = null
73 + }
74 +
75 + createBase(binDir)
76 +
77 + download(url, function error (err, newVersion) {
78 + if (err) return callback(err)
79 + fs.writeFileSync(
80 + defaultPath,
81 + JSON.stringify({
82 + version: newVersion,
83 + path: binDir ? filePath : binDir,
84 + exec: exec('youtube-dl')
85 + }),
86 + 'utf8'
87 + )
88 + return callback(null, 'Downloaded youtube-dl ' + newVersion)
89 + })
90 +}
91 +
92 +module.exports = downloader
1 +// Arguments we dont want users to use with youtube-dl
2 +// because they will break the module.
3 +const badArgs = [
4 + '-h',
5 + '--help',
6 + '-v',
7 + '--version',
8 + '-U',
9 + '--update',
10 + '-q',
11 + '--quiet',
12 + '-s',
13 + '--simulate',
14 + '-g',
15 + '--get-url',
16 + '-e',
17 + '--get-title',
18 + '--get-id',
19 + '--get-thumbnail',
20 + '--get-description',
21 + '--get-duration',
22 + '--get-filename',
23 + '--get-format',
24 + '-j',
25 + '--dump-json',
26 + '--newline',
27 + '--no-progress',
28 + '--console-title',
29 + '-v',
30 + '--verbose',
31 + '--dump-intermediate-pages',
32 + '--write-pages',
33 + '--print-traffic'
34 +]
35 +
36 +/**
37 + * Helps parse options used in youtube-dl command.
38 + *
39 + * @param {Array.<String>}
40 + * @return {Array.<String>}
41 + */
42 +exports.parseOpts = function (args) {
43 + var pos
44 + for (var i = 0, len = badArgs.length; i < len; i++) {
45 + if ((pos = args.indexOf(badArgs[i])) !== -1) {
46 + args.splice(pos, 1)
47 + }
48 + }
49 + return args
50 +}
51 +
52 +/**
53 + * Converts seconds to format hh:mm:ss
54 + *
55 + * @param {Number} seconds
56 + * @return {String}
57 + */
58 +exports.formatDuration = function (seconds) {
59 + var parts = []
60 + parts.push(seconds % 60)
61 + var minutes = Math.floor(seconds / 60)
62 + if (minutes > 0) {
63 + parts.push(minutes % 60)
64 + var hours = Math.floor(minutes / 60)
65 + if (hours > 0) {
66 + parts.push(hours)
67 + }
68 + }
69 + return parts.reverse().join(':')
70 +}
71 +
72 +/**
73 + * Checks wether str is a string or not
74 + *
75 + * @param {String} str
76 + * @return {Boolean}
77 + */
78 +exports.isString = str => typeof str === 'string'
79 +
80 +/**
81 + * Checks arr contains value
82 + *
83 + * @param {Array} arr
84 + * @param {string|number} arr
85 + * @return {Boolean}
86 + */
87 +exports.has = (arr, value) => arr && arr.indexOf(value) > -1
88 +
89 +exports.isYouTubeRegex = /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\//
90 +
91 +exports.isWin =
92 + process.platform === 'win32' || process.env.NODE_PLATFORM === 'windows'
1 +'use strict'
2 +
3 +const execFile = require('child_process').execFile
4 +const streamify = require('streamify')
5 +const request = require('request')
6 +const hms = require('hh-mm-ss')
7 +const path = require('path')
8 +const http = require('http')
9 +const url = require('url')
10 +const fs = require('fs')
11 +
12 +const {
13 + isYouTubeRegex,
14 + isWin,
15 + formatDuration,
16 + has,
17 + isString
18 +} = require('./util')
19 +
20 +const detailsPath = path.join(__dirname, '..', 'bin/details')
21 +
22 +const TEN_MEGABYTES = 1000 * 1000 * 10
23 +
24 +const execFileOpts = { maxBuffer: TEN_MEGABYTES }
25 +
26 +let ytdlBinary = (() => {
27 + if (fs.existsSync(detailsPath)) {
28 + const details = JSON.parse(fs.readFileSync(detailsPath))
29 + return details.path
30 + ? details.path
31 + : path.resolve(__dirname, '..', 'bin', details.exec)
32 + }
33 +
34 + if (!fs.existsSync(ytdlBinary)) {
35 + console.error(
36 + 'ERROR: unable to locate youtube-dl details in ' +
37 + path.dirname(ytdlBinary)
38 + )
39 + process.exit(1)
40 + }
41 +})()
42 +
43 +function youtubeDl (args, options, cb) {
44 + execFile(ytdlBinary, args, { ...execFileOpts, ...options }, function done (
45 + err,
46 + stdout,
47 + stderr
48 + ) {
49 + if (err) return cb(err)
50 + return cb(null, stdout.trim().split(/\r?\n/))
51 + })
52 +}
53 +
54 +/**
55 + * Processes data
56 + *
57 + * @param {Object} data
58 + * @param {Object} options
59 + * @param {Object} stream
60 + */
61 +
62 +function processData (data, options, stream) {
63 + const item = !data.length ? data : data.shift()
64 +
65 + // fix for pause/resume downloads
66 + const headers = Object.assign(
67 + { Host: url.parse(item.url).hostname },
68 + data.http_headers
69 + )
70 +
71 + if (options && options.start > 0 && options.end > 0) {
72 + headers.Range = 'bytes=' + options.start + '-' + options.end
73 + }
74 +
75 + const req = request({ url: item.url, headers: headers, ecdhCurve: 'auto' })
76 +
77 + req.on('response', function response (res) {
78 + const size = parseInt(res.headers['content-length'], 10)
79 + if (size) item.size = size
80 +
81 + if (options && options.start > 0 && res.statusCode === 416) {
82 + // the file that is being resumed is complete.
83 + return stream.emit('complete', item)
84 + }
85 +
86 + if (res.statusCode !== 200 && res.statusCode !== 206) {
87 + return stream.emit('error', new Error('status code ' + res.statusCode))
88 + }
89 +
90 + stream.emit('info', item)
91 +
92 + stream.on('end', function end () {
93 + if (data.length) stream.emit('next', data)
94 + })
95 + })
96 +
97 + return stream.resolve(req)
98 +}
99 +
100 +/**
101 + * Downloads a video.
102 + *
103 + * @param {String} videoUrl
104 + * @param {!Array.<String>} args
105 + * @param {!Object} options
106 + */
107 +const ytdl = (module.exports = function (videoUrl, args, options) {
108 + const stream = streamify({
109 + superCtor: http.ClientResponse,
110 + readable: true,
111 + writable: false
112 + })
113 +
114 + if (!isString(videoUrl)) {
115 + processData(videoUrl, options, stream)
116 + return stream
117 + }
118 +
119 + ytdl.getInfo(videoUrl, args, options, function getInfo (err, data) {
120 + return err ? stream.emit('error', err) : processData(data, options, stream)
121 + })
122 +
123 + return stream
124 +})
125 +
126 +/**
127 + * Calls youtube-dl with some arguments and the `cb`
128 + * gets called with the output.
129 + *
130 + * @param {String|Array.<String>}
131 + * @param {Array.<String>} args
132 + * @param {Array.<String>} args2
133 + * @param {Object} options
134 + * @param {Function(!Error, String)} cb
135 + */
136 +function call (urls, args1, args2, options = {}, cb) {
137 + let args = args1
138 + if (args2) args = args.concat(args2)
139 +
140 + // check if encoding is already set
141 + if (isWin && !args.includes('--encoding')) {
142 + args.push('--encoding')
143 + args.push('utf8')
144 + }
145 +
146 + if (urls !== null) {
147 + if (isString(urls)) urls = [urls]
148 +
149 + for (let i = 0; i < urls.length; i++) {
150 + const video = urls[i]
151 + if (isYouTubeRegex.test(video)) {
152 + // Get possible IDs.
153 + const details = url.parse(video, true)
154 + let id = details.query.v || ''
155 + if (id) {
156 + args.push('http://www.youtube.com/watch?v=' + id)
157 + } else {
158 + // Get possible IDs for youtu.be from urladdr.
159 + id = details.pathname.slice(1).replace(/^v\//, '')
160 + if (id) {
161 + args.push(video)
162 + args.unshift('-i')
163 + }
164 + }
165 + } else {
166 + if (i === 0) args.push('--')
167 + args.push(video)
168 + }
169 + }
170 + }
171 +
172 + return youtubeDl(args, options, cb)
173 +}
174 +
175 +/**
176 + * Calls youtube-dl with some arguments and the `cb`
177 + * gets called with the output.
178 + *
179 + * @param {String} url
180 + * @param {Array.<String>} args
181 + * @param {Object} options
182 + * @param {Function(!Error, String)} cb
183 + */
184 +ytdl.exec = function exec (url, args, options, cb) {
185 + return call(url, [], args, options, cb)
186 +}
187 +
188 +/**
189 + * @param {Object} data
190 + * @returns {Object}
191 + */
192 +function parseInfo (data) {
193 + // youtube-dl might return just an url as a string when using the "-g" or "--get-url" flag
194 + if (isString(data) && data.startsWith('http')) {
195 + data = JSON.stringify({ url: data })
196 + }
197 +
198 + const info = JSON.parse(data)
199 +
200 + info._duration_raw = info.duration
201 + info._duration_hms = info.duration
202 + ? hms.fromS(info.duration, 'hh:mm:ss')
203 + : info.duration
204 + info.duration = info.duration ? formatDuration(info.duration) : info.duration
205 +
206 + return info
207 +}
208 +
209 +/**
210 + * Set path from youtube-dl.
211 + *
212 + * @param {String} path
213 + */
214 +ytdl.setYtdlBinary = function setYtdlBinary (path) {
215 + ytdlBinary = path
216 +}
217 +
218 +/**
219 + * Get path from youtube-dl.
220 + *
221 + * @param {String} path
222 + */
223 +ytdl.getYtdlBinary = function getYtdlBinary () {
224 + return ytdlBinary
225 +}
226 +
227 +/**
228 + * Gets info from a video.
229 + *
230 + * @param {String} url
231 + * @param {Array.<String>} args
232 + * @param {Object} options
233 + * @param {Function(!Error, Object)} cb
234 + */
235 +ytdl.getInfo = function getInfo (url, args, options, cb) {
236 + if (typeof options === 'function') {
237 + cb = options
238 + options = {}
239 + } else if (typeof args === 'function') {
240 + cb = args
241 + options = {}
242 + args = []
243 + }
244 + const defaultArgs = ['--dump-json']
245 + if (
246 + !args ||
247 + (!has(args, '-f') &&
248 + !has(args, '--format') &&
249 + args.every(function (a) {
250 + return a.indexOf('--format=') !== 0
251 + }))
252 + ) {
253 + defaultArgs.push('-f')
254 + defaultArgs.push('best')
255 + }
256 +
257 + call(url, defaultArgs, args, options, function done (err, data) {
258 + if (err) return cb(err)
259 + let info
260 +
261 + // If using the "-g" or "--get-url" flag youtube-dl will return just a string (the URL to the video) which messes up the parsing
262 + // This fixes this behaviour
263 + if (has(args, '-g') || has(args, '--get-url')) {
264 + if (Array.isArray(data) && data.length >= 2) data.splice(0, 1)
265 + }
266 +
267 + try {
268 + info = data.map(parseInfo)
269 + } catch (err) {
270 + return cb(err)
271 + }
272 +
273 + return cb(null, info.length === 1 ? info[0] : info)
274 + })
275 +}
276 +
277 +/**
278 + * @param {String} url
279 + * @param {Object} options
280 + * {Boolean} auto
281 + * {Boolean} all
282 + * {String} lang
283 + * {String} format
284 + * {String} cwd
285 + * @param {Function(!Error, Object)} cb
286 + */
287 +ytdl.getSubs = function getSubs (url, options, cb) {
288 + if (typeof options === 'function') {
289 + cb = options
290 + options = {}
291 + }
292 +
293 + const args = ['--skip-download']
294 + args.push('--write' + (options.auto ? '-auto' : '') + '-sub')
295 + if (options.all) args.push('--all-subs')
296 + if (options.lang) args.push('--sub-lang=' + options.lang)
297 + if (options.format) args.push('--sub-format=' + options.format)
298 + if (!options.warrning) args.push('--no-warnings')
299 +
300 + call(url, args, [], { cwd: options.cwd }, function (err, data) {
301 + if (err) return cb(err)
302 +
303 + const files = []
304 +
305 + for (let i = 0, len = data.length; i < len; i++) {
306 + const line = data[i]
307 + if (line.indexOf('[info] Writing video subtitles to: ') === 0) {
308 + files.push(line.slice(35))
309 + }
310 + }
311 +
312 + return cb(null, files)
313 + })
314 +}
315 +
316 +/**
317 + * @param {String} url
318 + * @param {Object} options
319 + * {Boolean} all
320 + * {String} cwd
321 + * @param {Function(!Error, Object)} cb
322 + */
323 +ytdl.getThumbs = function getThumbs (url, options, cb) {
324 + if (typeof options === 'function') {
325 + cb = options
326 + options = {}
327 + }
328 +
329 + const args = ['--skip-download']
330 +
331 + if (options.all) args.push('--write-all-thumbnails')
332 + else args.push('--write-thumbnail')
333 +
334 + if (!options.warrning) args.push('--no-warnings')
335 +
336 + call(url, args, [], { cwd: options.cwd }, function (err, data) {
337 + if (err) return cb(err)
338 +
339 + const files = []
340 +
341 + for (let i = 0, len = data.length; i < len; i++) {
342 + const line = data[i]
343 + const info = 'Writing thumbnail to: '
344 + if (has(line, info)) {
345 + files.push(line.slice(line.indexOf(info) + info.length))
346 + }
347 + }
348 +
349 + return cb(null, files)
350 + })
351 +}
352 +
353 +/**
354 + * @param {!Boolean} descriptions
355 + * @param {!Object} options
356 + * @param {Function(!Error, Object)} cb
357 + */
358 +ytdl.getExtractors = function getExtractors (descriptions, options, cb) {
359 + if (typeof options === 'function') {
360 + cb = options
361 + options = {}
362 + } else if (typeof descriptions === 'function') {
363 + cb = descriptions
364 + options = {}
365 + descriptions = false
366 + }
367 +
368 + const args = descriptions
369 + ? ['--extractor-descriptions']
370 + : ['--list-extractors']
371 +
372 + return call(null, args, null, options, cb)
373 +}
1 +{
2 + "_from": "@microlink/youtube-dl",
3 + "_id": "@microlink/youtube-dl@2.0.0",
4 + "_inBundle": false,
5 + "_integrity": "sha512-B2DqRrDHFMu1MsBTq6ZAKR4BtKgvOK91Ci9EQiMVbSGC1/3UIPxpIYP4Py4kzcS94B++zVSMirhnCgX//5Qs4w==",
6 + "_location": "/@microlink/youtube-dl",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "tag",
10 + "registry": true,
11 + "raw": "@microlink/youtube-dl",
12 + "name": "@microlink/youtube-dl",
13 + "escapedName": "@microlink%2fyoutube-dl",
14 + "scope": "@microlink",
15 + "rawSpec": "",
16 + "saveSpec": null,
17 + "fetchSpec": "latest"
18 + },
19 + "_requiredBy": [
20 + "#USER",
21 + "/"
22 + ],
23 + "_resolved": "https://registry.npmjs.org/@microlink/youtube-dl/-/youtube-dl-2.0.0.tgz",
24 + "_shasum": "0120c67949185228afe4d771cfd80719b278cd73",
25 + "_spec": "@microlink/youtube-dl",
26 + "_where": "C:\\Users\\user\\Desktop\\오소git\\오소플젝\\Youtube_MPL",
27 + "author": {
28 + "name": "Roly Fentanes",
29 + "url": "https://github.com/fent"
30 + },
31 + "bugs": {
32 + "url": "https://github.com/przemyslawpluta/node-youtube-dl/issues"
33 + },
34 + "bundleDependencies": false,
35 + "commitlint": {
36 + "extends": [
37 + "@commitlint/config-conventional"
38 + ]
39 + },
40 + "contributors": [
41 + {
42 + "name": "Roly Fentanes",
43 + "email": "roly426@gmail.com"
44 + },
45 + {
46 + "name": "przemyslawpluta",
47 + "email": "przemekpluta@hotmail.com"
48 + },
49 + {
50 + "name": "Kiko Beats",
51 + "email": "josefrancisco.verdu@gmail.com"
52 + },
53 + {
54 + "name": "Jay Salvat",
55 + "email": "jay@jaysalvat.com"
56 + },
57 + {
58 + "name": "Benjamin C",
59 + "email": "benjamin@coriou.net"
60 + },
61 + {
62 + "name": "Gregoire Guémas",
63 + "email": "gregoire.guemas@navispeed.eu"
64 + },
65 + {
66 + "name": "Jaime Marquínez Ferrándiz",
67 + "email": "jaime.marquinez.ferrandiz@gmail.com"
68 + },
69 + {
70 + "name": "Jay Baker",
71 + "email": "logikal@gmail.com"
72 + },
73 + {
74 + "name": "Jack Li",
75 + "email": "jack.lee2980@gmail.com"
76 + },
77 + {
78 + "name": "optikfluffel",
79 + "email": "optik@fluffel.io"
80 + },
81 + {
82 + "name": "Calvin",
83 + "email": "calvin@sealtelecom.com.br"
84 + },
85 + {
86 + "name": "Jeremy Louie",
87 + "email": "jeremy@jeremylouie.com"
88 + },
89 + {
90 + "name": "Sergey M․",
91 + "email": "dstftw@gmail.com"
92 + },
93 + {
94 + "name": "t3rr0r",
95 + "email": "mail@t3rr0r.com"
96 + },
97 + {
98 + "name": "EragonJ",
99 + "email": "eragonj@eragonj.me"
100 + },
101 + {
102 + "name": "tifroz",
103 + "email": "hhardel@gmail.com"
104 + },
105 + {
106 + "name": "walheresq",
107 + "email": "walheresq@hotmail.com"
108 + },
109 + {
110 + "name": "Alireza Mirian",
111 + "email": "alireza.mirian@gmail.com"
112 + },
113 + {
114 + "name": "▟ ▖▟ ▖",
115 + "email": "dodo.the.last@gmail.com"
116 + },
117 + {
118 + "name": "Davide Pastore",
119 + "email": "pasdavide@gmail.com"
120 + },
121 + {
122 + "name": "Farrin Reid",
123 + "email": "blakmatrix@gmail.com"
124 + },
125 + {
126 + "name": "Jason Penny",
127 + "email": "jason@jooraccess.com"
128 + },
129 + {
130 + "name": "Juan C. Olivares",
131 + "email": "cristobal@cxsoftware.com"
132 + },
133 + {
134 + "name": "Lopez Hugo",
135 + "email": "hugo.lpz@gmail.com"
136 + },
137 + {
138 + "name": "Meral",
139 + "email": "meral.harbes@gmail.com"
140 + },
141 + {
142 + "name": "Michael Nguyen",
143 + "email": "tehtotalpwnage@gmail.com"
144 + },
145 + {
146 + "name": "Nicolas Gotchac",
147 + "email": "ngotchac@gmail.com"
148 + },
149 + {
150 + "name": "Parikshit Hooda",
151 + "email": "phooda804@live.com"
152 + },
153 + {
154 + "name": "Pietro",
155 + "email": "pietro.passarelli@gmail.com"
156 + },
157 + {
158 + "name": "Sagi Nadir",
159 + "email": "saginadir@gmail.com"
160 + },
161 + {
162 + "name": "bartronicus",
163 + "email": "matthewdavidbarton@gmail.com"
164 + },
165 + {
166 + "name": "btmdave",
167 + "email": "dave@bluetopmedia.com"
168 + },
169 + {
170 + "name": "coderaiser",
171 + "email": "mnemonic.enemy@gmail.com"
172 + }
173 + ],
174 + "dependencies": {
175 + "hh-mm-ss": "~1.2.0",
176 + "mkdirp": "~0.5.1",
177 + "request": "~2.88.0",
178 + "streamify": "~0.2.9"
179 + },
180 + "deprecated": false,
181 + "description": "youtube-dl driver for node",
182 + "devDependencies": {
183 + "@commitlint/cli": "latest",
184 + "@commitlint/config-conventional": "latest",
185 + "finepack": "latest",
186 + "git-authors-cli": "latest",
187 + "husky": "latest",
188 + "lint-staged": "latest",
189 + "prettier-standard": "latest",
190 + "standard": "latest",
191 + "standard-markdown": "latest",
192 + "standard-version": "latest",
193 + "vows": "latest"
194 + },
195 + "engines": {
196 + "node": ">= 8"
197 + },
198 + "files": [
199 + "lib",
200 + "scripts"
201 + ],
202 + "homepage": "https://github.com/przemyslawpluta/node-youtube-dl#readme",
203 + "husky": {
204 + "hooks": {
205 + "commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
206 + "pre-commit": "lint-staged"
207 + }
208 + },
209 + "keywords": [
210 + "download",
211 + "video",
212 + "youtube"
213 + ],
214 + "license": "MIT",
215 + "lint-staged": {
216 + "linters": {
217 + "package.json": [
218 + "finepack",
219 + "git add"
220 + ],
221 + "*.js": [
222 + "prettier-standard",
223 + "git add"
224 + ],
225 + "*.md": [
226 + "standard-markdown",
227 + "git add"
228 + ]
229 + }
230 + },
231 + "main": "./lib/youtube-dl.js",
232 + "name": "@microlink/youtube-dl",
233 + "repository": {
234 + "type": "git",
235 + "url": "git://github.com/przemyslawpluta/node-youtube-dl.git"
236 + },
237 + "scripts": {
238 + "lint": "standard-markdown README.md && standard",
239 + "postinstall": "node ./scripts/download.js",
240 + "release": "bumped release",
241 + "test": "vows ./test/*.js --spec",
242 + "update": "node ./scripts/download.js"
243 + },
244 + "version": "2.0.0"
245 +}
1 +var downloader = require('../lib/downloader')
2 +
3 +downloader(function error (err, done) {
4 + if (err) return console.log(err.stack)
5 + console.log(done)
6 +})
1 +Hashish
2 +=======
3 +
4 +Hashish is a node.js library for manipulating hash data structures.
5 +It is distilled from the finest that ruby, perl, and haskell have to offer by
6 +way of hash/map interfaces.
7 +
8 +Hashish provides a chaining interface, where you can do:
9 +
10 + var Hash = require('hashish');
11 +
12 + Hash({ a : 1, b : 2, c : 3, d : 4 })
13 + .map(function (x) { return x * 10 })
14 + .filter(function (x) { return x < 30 })
15 + .forEach(function (x, key) {
16 + console.log(key + ' => ' + x);
17 + })
18 + ;
19 +
20 +Output:
21 +
22 + a => 10
23 + b => 20
24 +
25 +Some functions and attributes in the chaining interface are terminal, like
26 +`.items` or `.detect()`. They return values of their own instead of the chain
27 +context.
28 +
29 +Each function in the chainable interface is also attached to `Hash` in chainless
30 +form:
31 +
32 + var Hash = require('hashish');
33 + var obj = { a : 1, b : 2, c : 3, d : 4 };
34 +
35 + var mapped = Hash.map(obj, function (x) {
36 + return x * 10
37 + });
38 +
39 + console.dir(mapped);
40 +
41 +Output:
42 +
43 + { a: 10, b: 20, c: 30, d: 40 }
44 +
45 +In either case, the 'this' context of the function calls is the same object that
46 +the chained functions return, so you can make nested chains.
47 +
48 +Methods
49 +=======
50 +
51 +forEach(cb)
52 +-----------
53 +
54 +For each key/value in the hash, calls `cb(value, key)`.
55 +
56 +map(cb)
57 +-------
58 +
59 +For each key/value in the hash, calls `cb(value, key)`.
60 +The return value of `cb` is the new value at `key` in the resulting hash.
61 +
62 +filter(cb)
63 +----------
64 +
65 +For each key/value in the hash, calls `cb(value, key)`.
66 +The resulting hash omits key/value pairs where `cb` returned a falsy value.
67 +
68 +detect(cb)
69 +----------
70 +
71 +Returns the first value in the hash for which `cb(value, key)` is non-falsy.
72 +Order of hashes is not well-defined so watch out for that.
73 +
74 +reduce(cb)
75 +----------
76 +
77 +Returns the accumulated value of a left-fold over the key/value pairs.
78 +
79 +some(cb)
80 +--------
81 +
82 +Returns a boolean: whether or not `cb(value, key)` ever returned a non-falsy
83 +value.
84 +
85 +update(obj1, [obj2, obj3, ...])
86 +-----------
87 +
88 +Mutate the context hash, merging the key/value pairs from the passed objects
89 +and overwriting keys from the context hash if the current `obj` has keys of
90 +the same name. Falsy arguments are silently ignored.
91 +
92 +updateAll([ obj1, obj2, ... ])
93 +------------------------------
94 +
95 +Like multi-argument `update()` but operate on an array directly.
96 +
97 +merge(obj1, [obj2, obj3, ...])
98 +----------
99 +
100 +Merge the key/value pairs from the passed objects into the resultant hash
101 +without modifying the context hash. Falsy arguments are silently ignored.
102 +
103 +mergeAll([ obj1, obj2, ... ])
104 +------------------------------
105 +
106 +Like multi-argument `merge()` but operate on an array directly.
107 +
108 +has(key)
109 +--------
110 +
111 +Return whether the hash has a key, `key`.
112 +
113 +valuesAt(keys)
114 +--------------
115 +
116 +Return an Array with the values at the keys from `keys`.
117 +
118 +tap(cb)
119 +-------
120 +
121 +Call `cb` with the present raw hash.
122 +This function is chainable.
123 +
124 +extract(keys)
125 +-------------
126 +
127 +Filter by including only those keys in `keys` in the resulting hash.
128 +
129 +exclude(keys)
130 +-------------
131 +
132 +Filter by excluding those keys in `keys` in the resulting hash.
133 +
134 +Attributes
135 +==========
136 +
137 +These are attributes in the chaining interface and functions in the `Hash.xxx`
138 +interface.
139 +
140 +keys
141 +----
142 +
143 +Return all the enumerable attribute keys in the hash.
144 +
145 +values
146 +------
147 +
148 +Return all the enumerable attribute values in the hash.
149 +
150 +compact
151 +-------
152 +
153 +Filter out values which are `=== undefined`.
154 +
155 +clone
156 +-----
157 +
158 +Make a deep copy of the hash.
159 +
160 +copy
161 +----
162 +
163 +Make a shallow copy of the hash.
164 +
165 +length
166 +------
167 +
168 +Return the number of key/value pairs in the hash.
169 +Note: use `Hash.size()` for non-chain mode.
170 +
171 +size
172 +----
173 +
174 +Alias for `length` since `Hash.length` is masked by `Function.prototype`.
175 +
176 +See Also
177 +========
178 +
179 +See also [creationix's pattern/hash](http://github.com/creationix/pattern),
180 +which does a similar thing except with hash inputs and array outputs.
181 +
182 +Installation
183 +============
184 +
185 +To install with [npm](http://github.com/isaacs/npm):
186 +
187 + npm install hashish
188 +
189 +To run the tests with [expresso](http://github.com/visionmedia/expresso):
190 +
191 + expresso
1 +var Hash = require('hashish');
2 +
3 +Hash({ a : 1, b : 2, c : 3, d : 4 })
4 + .map(function (x) { return x * 10 })
5 + .filter(function (x) { return x < 30 })
6 + .forEach(function (x, key) {
7 + console.log(key + ' => ' + x);
8 + })
9 +;
1 +var Hash = require('hashish');
2 +var obj = { a : 1, b : 2, c : 3, d : 4 };
3 +
4 +var mapped = Hash.map(obj, function (x) {
5 + return x * 10
6 +});
7 +console.dir(mapped);
1 +module.exports = Hash;
2 +var Traverse = require('traverse');
3 +
4 +function Hash (hash, xs) {
5 + if (Array.isArray(hash) && Array.isArray(xs)) {
6 + var to = Math.min(hash.length, xs.length);
7 + var acc = {};
8 + for (var i = 0; i < to; i++) {
9 + acc[hash[i]] = xs[i];
10 + }
11 + return Hash(acc);
12 + }
13 +
14 + if (hash === undefined) return Hash({});
15 +
16 + var self = {
17 + map : function (f) {
18 + var acc = { __proto__ : hash.__proto__ };
19 + Object.keys(hash).forEach(function (key) {
20 + acc[key] = f.call(self, hash[key], key);
21 + });
22 + return Hash(acc);
23 + },
24 + forEach : function (f) {
25 + Object.keys(hash).forEach(function (key) {
26 + f.call(self, hash[key], key);
27 + });
28 + return self;
29 + },
30 + filter : function (f) {
31 + var acc = { __proto__ : hash.__proto__ };
32 + Object.keys(hash).forEach(function (key) {
33 + if (f.call(self, hash[key], key)) {
34 + acc[key] = hash[key];
35 + }
36 + });
37 + return Hash(acc);
38 + },
39 + detect : function (f) {
40 + for (var key in hash) {
41 + if (f.call(self, hash[key], key)) {
42 + return hash[key];
43 + }
44 + }
45 + return undefined;
46 + },
47 + reduce : function (f, acc) {
48 + var keys = Object.keys(hash);
49 + if (acc === undefined) acc = keys.shift();
50 + keys.forEach(function (key) {
51 + acc = f.call(self, acc, hash[key], key);
52 + });
53 + return acc;
54 + },
55 + some : function (f) {
56 + for (var key in hash) {
57 + if (f.call(self, hash[key], key)) return true;
58 + }
59 + return false;
60 + },
61 + update : function (obj) {
62 + if (arguments.length > 1) {
63 + self.updateAll([].slice.call(arguments));
64 + }
65 + else {
66 + Object.keys(obj).forEach(function (key) {
67 + hash[key] = obj[key];
68 + });
69 + }
70 + return self;
71 + },
72 + updateAll : function (xs) {
73 + xs.filter(Boolean).forEach(function (x) {
74 + self.update(x);
75 + });
76 + return self;
77 + },
78 + merge : function (obj) {
79 + if (arguments.length > 1) {
80 + return self.copy.updateAll([].slice.call(arguments));
81 + }
82 + else {
83 + return self.copy.update(obj);
84 + }
85 + },
86 + mergeAll : function (xs) {
87 + return self.copy.updateAll(xs);
88 + },
89 + has : function (key) { // only operates on enumerables
90 + return Array.isArray(key)
91 + ? key.every(function (k) { return self.has(k) })
92 + : self.keys.indexOf(key.toString()) >= 0;
93 + },
94 + valuesAt : function (keys) {
95 + return Array.isArray(keys)
96 + ? keys.map(function (key) { return hash[key] })
97 + : hash[keys]
98 + ;
99 + },
100 + tap : function (f) {
101 + f.call(self, hash);
102 + return self;
103 + },
104 + extract : function (keys) {
105 + var acc = {};
106 + keys.forEach(function (key) {
107 + acc[key] = hash[key];
108 + });
109 + return Hash(acc);
110 + },
111 + exclude : function (keys) {
112 + return self.filter(function (_, key) {
113 + return keys.indexOf(key) < 0
114 + });
115 + },
116 + end : hash,
117 + items : hash
118 + };
119 +
120 + var props = {
121 + keys : function () { return Object.keys(hash) },
122 + values : function () {
123 + return Object.keys(hash).map(function (key) { return hash[key] });
124 + },
125 + compact : function () {
126 + return self.filter(function (x) { return x !== undefined });
127 + },
128 + clone : function () { return Hash(Hash.clone(hash)) },
129 + copy : function () { return Hash(Hash.copy(hash)) },
130 + length : function () { return Object.keys(hash).length },
131 + size : function () { return self.length }
132 + };
133 +
134 + if (Object.defineProperty) {
135 + // es5-shim has an Object.defineProperty but it throws for getters
136 + try {
137 + for (var key in props) {
138 + Object.defineProperty(self, key, { get : props[key] });
139 + }
140 + }
141 + catch (err) {
142 + for (var key in props) {
143 + if (key !== 'clone' && key !== 'copy' && key !== 'compact') {
144 + // ^ those keys use Hash() so can't call them without
145 + // a stack overflow
146 + self[key] = props[key]();
147 + }
148 + }
149 + }
150 + }
151 + else if (self.__defineGetter__) {
152 + for (var key in props) {
153 + self.__defineGetter__(key, props[key]);
154 + }
155 + }
156 + else {
157 + // non-lazy version for browsers that suck >_<
158 + for (var key in props) {
159 + self[key] = props[key]();
160 + }
161 + }
162 +
163 + return self;
164 +};
165 +
166 +// deep copy
167 +Hash.clone = function (ref) {
168 + return Traverse.clone(ref);
169 +};
170 +
171 +// shallow copy
172 +Hash.copy = function (ref) {
173 + var hash = { __proto__ : ref.__proto__ };
174 + Object.keys(ref).forEach(function (key) {
175 + hash[key] = ref[key];
176 + });
177 + return hash;
178 +};
179 +
180 +Hash.map = function (ref, f) {
181 + return Hash(ref).map(f).items;
182 +};
183 +
184 +Hash.forEach = function (ref, f) {
185 + Hash(ref).forEach(f);
186 +};
187 +
188 +Hash.filter = function (ref, f) {
189 + return Hash(ref).filter(f).items;
190 +};
191 +
192 +Hash.detect = function (ref, f) {
193 + return Hash(ref).detect(f);
194 +};
195 +
196 +Hash.reduce = function (ref, f, acc) {
197 + return Hash(ref).reduce(f, acc);
198 +};
199 +
200 +Hash.some = function (ref, f) {
201 + return Hash(ref).some(f);
202 +};
203 +
204 +Hash.update = function (a /*, b, c, ... */) {
205 + var args = Array.prototype.slice.call(arguments, 1);
206 + var hash = Hash(a);
207 + return hash.update.apply(hash, args).items;
208 +};
209 +
210 +Hash.merge = function (a /*, b, c, ... */) {
211 + var args = Array.prototype.slice.call(arguments, 1);
212 + var hash = Hash(a);
213 + return hash.merge.apply(hash, args).items;
214 +};
215 +
216 +Hash.has = function (ref, key) {
217 + return Hash(ref).has(key);
218 +};
219 +
220 +Hash.valuesAt = function (ref, keys) {
221 + return Hash(ref).valuesAt(keys);
222 +};
223 +
224 +Hash.tap = function (ref, f) {
225 + return Hash(ref).tap(f).items;
226 +};
227 +
228 +Hash.extract = function (ref, keys) {
229 + return Hash(ref).extract(keys).items;
230 +};
231 +
232 +Hash.exclude = function (ref, keys) {
233 + return Hash(ref).exclude(keys).items;
234 +};
235 +
236 +Hash.concat = function (xs) {
237 + var hash = Hash({});
238 + xs.forEach(function (x) { hash.update(x) });
239 + return hash.items;
240 +};
241 +
242 +Hash.zip = function (xs, ys) {
243 + return Hash(xs, ys).items;
244 +};
245 +
246 +// .length is already defined for function prototypes
247 +Hash.size = function (ref) {
248 + return Hash(ref).size;
249 +};
250 +
251 +Hash.compact = function (ref) {
252 + return Hash(ref).compact.items;
253 +};
1 +{
2 + "_from": "hashish@~0.0.4",
3 + "_id": "hashish@0.0.4",
4 + "_inBundle": false,
5 + "_integrity": "sha1-bWC8b/r3Ebav1g5CbQd5iAFOZVQ=",
6 + "_location": "/hashish",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "hashish@~0.0.4",
12 + "name": "hashish",
13 + "escapedName": "hashish",
14 + "rawSpec": "~0.0.4",
15 + "saveSpec": null,
16 + "fetchSpec": "~0.0.4"
17 + },
18 + "_requiredBy": [
19 + "/streamify"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/hashish/-/hashish-0.0.4.tgz",
22 + "_shasum": "6d60bc6ffaf711b6afd60e426d077988014e6554",
23 + "_spec": "hashish@~0.0.4",
24 + "_where": "C:\\Users\\user\\Desktop\\오소git\\오소플젝\\Youtube_MPL\\node_modules\\streamify",
25 + "author": {
26 + "name": "James Halliday",
27 + "email": "mail@substack.net",
28 + "url": "http://substack.net"
29 + },
30 + "bugs": {
31 + "url": "https://github.com/substack/node-hashish/issues"
32 + },
33 + "bundleDependencies": false,
34 + "dependencies": {
35 + "traverse": ">=0.2.4"
36 + },
37 + "deprecated": false,
38 + "description": "Hash data structure manipulation functions",
39 + "devDependencies": {
40 + "expresso": ">=0.6.0"
41 + },
42 + "engine": [
43 + "node >=0.2.0"
44 + ],
45 + "engines": {
46 + "node": "*"
47 + },
48 + "homepage": "https://github.com/substack/node-hashish#readme",
49 + "keywords": [
50 + "hash",
51 + "object",
52 + "convenience",
53 + "manipulation",
54 + "data structure"
55 + ],
56 + "license": "MIT/X11",
57 + "main": "./index.js",
58 + "name": "hashish",
59 + "repository": {
60 + "type": "git",
61 + "url": "git+ssh://git@github.com/substack/node-hashish.git"
62 + },
63 + "scripts": {
64 + "test": "expresso"
65 + },
66 + "version": "0.0.4"
67 +}
1 +var Hash = require('hashish');
2 +var assert = require('assert');
3 +
4 +exports.map = function () {
5 + var ref = { a : 1, b : 2 };
6 + var items = Hash(ref).map(function (v) { return v + 1 }).items;
7 + var hash = Hash.map(ref, function (v) { return v + 1 });
8 + assert.deepEqual(ref, { a : 1, b : 2 });
9 + assert.deepEqual(items, { a : 2, b : 3 });
10 + assert.deepEqual(hash, { a : 2, b : 3 });
11 +};
12 +
13 +exports['cloned map'] = function () {
14 + var ref = { foo : [1,2], bar : [4,5] };
15 + var hash = Hash(ref).clone.map(
16 + function (v) { v.unshift(v[0] - 1); return v }
17 + ).items;
18 + assert.deepEqual(ref.foo, [1,2]);
19 + assert.deepEqual(ref.bar, [4,5]);
20 + assert.deepEqual(hash.foo, [0,1,2]);
21 + assert.deepEqual(hash.bar, [3,4,5]);
22 +};
23 +
24 +exports.forEach = function () {
25 + var ref = { a : 5, b : 2, c : 7, 1337 : 'leet' };
26 + var xs = [];
27 + Hash(ref).forEach(function (x, i) {
28 + xs.push([ i, x ]);
29 + });
30 +
31 + assert.eql(
32 + xs.map(function (x) { return x[0] }).sort(),
33 + [ '1337', 'a', 'b', 'c' ]
34 + );
35 +
36 + assert.eql(
37 + xs.map(function (x) { return x[1] }).sort(),
38 + [ 2, 5, 7, 'leet' ]
39 + );
40 +
41 + var ys = [];
42 + Hash.forEach(ref, function (x, i) {
43 + ys.push([ i, x ]);
44 + });
45 +
46 + assert.eql(xs.sort(), ys.sort());
47 +};
48 +
49 +exports.filter_items = function () {
50 + var ref = { a : 5, b : 2, c : 7, 1337 : 'leet' };
51 + var items = Hash(ref).filter(function (v, k) {
52 + return v > 5 || k > 5
53 + }).items;
54 + var hash = Hash.filter(ref, function (v, k) { return v > 5 || k > 5 });
55 + assert.deepEqual(items, { 1337 : 'leet', c : 7 });
56 + assert.deepEqual(hash, { 1337 : 'leet', c : 7 });
57 + assert.deepEqual(ref, { a : 5, b : 2, c : 7, 1337 : 'leet' });
58 + assert.equal(Hash(ref).length, 4);
59 +};
60 +
61 +exports.detect = function () {
62 + var h = { a : 5, b : 6, c : 7, d : 8 };
63 + var hh = Hash(h);
64 + var gt6hh = hh.detect(function (x) { return x > 6 });
65 + assert.ok(gt6hh == 7 || gt6hh == 8);
66 + var gt6h = Hash.detect(h, function (x) { return x > 6 });
67 + assert.ok(gt6h == 7 || gt6h == 8);
68 + assert.equal(hh.detect(function (x) { return x > 100 }), undefined);
69 +};
70 +
71 +exports.reduce = function () {
72 + var ref = { foo : [1,2], bar : [4,5] };
73 +
74 + var sum1 = Hash(ref).reduce(function (acc, v) {
75 + return acc + v.length
76 + }, 0);
77 + assert.equal(sum1, 4);
78 +
79 + var sum2 = Hash.reduce(ref, function (acc, v) {
80 + return acc + v.length
81 + }, 0);
82 + assert.equal(sum2, 4);
83 +};
84 +
85 +exports.some = function () {
86 + var h = { a : 5, b : 6, c : 7, d : 8 };
87 + var hh = Hash(h);
88 + assert.ok(Hash.some(h, function (x) { return x > 7 }));
89 + assert.ok(Hash.some(h, function (x) { return x < 6 }));
90 + assert.ok(!Hash.some(h, function (x) { return x > 10 }));
91 + assert.ok(!Hash.some(h, function (x) { return x < 0 }));
92 +
93 + assert.ok(hh.some(function (x) { return x > 7 }));
94 + assert.ok(hh.some(function (x) { return x < 6 }));
95 + assert.ok(!hh.some(function (x) { return x > 10 }));
96 + assert.ok(!hh.some(function (x) { return x < 0 }));
97 +};
98 +
99 +exports.update = function () {
100 + var ref = { a : 1, b : 2 };
101 + var items = Hash(ref).clone.update({ c : 3, a : 0 }).items;
102 + assert.deepEqual(ref, { a : 1, b : 2 });
103 + assert.deepEqual(items, { a : 0, b : 2, c : 3 });
104 +
105 + var hash = Hash.update(ref, { c : 3, a : 0 });
106 + assert.deepEqual(ref, hash);
107 + assert.deepEqual(hash, { a : 0, b : 2, c : 3 });
108 +
109 + var ref2 = {a: 1};
110 + var hash2 = Hash.update(ref2, { b: 2, c: 3 }, undefined, { d: 4 });
111 + assert.deepEqual(ref2, { a: 1, b: 2, c: 3, d: 4 });
112 +};
113 +
114 +exports.merge = function () {
115 + var ref = { a : 1, b : 2 };
116 + var items = Hash(ref).merge({ b : 3, c : 3.14 }).items;
117 + var hash = Hash.merge(ref, { b : 3, c : 3.14 });
118 +
119 + assert.deepEqual(ref, { a : 1, b : 2 });
120 + assert.deepEqual(items, { a : 1, b : 3, c : 3.14 });
121 + assert.deepEqual(hash, { a : 1, b : 3, c : 3.14 });
122 +
123 + var ref2 = { a : 1 };
124 + var hash2 = Hash.merge(ref, { b: 2, c: 3 }, undefined, { d: 4 });
125 + assert.deepEqual(hash2, { a: 1, b: 2, c: 3, d: 4 });
126 +};
127 +
128 +exports.has = function () {
129 + var h = { a : 4, b : 5 };
130 + var hh = Hash(h);
131 +
132 + assert.ok(hh.has('a'));
133 + assert.equal(hh.has('c'), false);
134 + assert.ok(hh.has(['a','b']));
135 + assert.equal(hh.has(['a','b','c']), false);
136 +
137 + assert.ok(Hash.has(h, 'a'));
138 + assert.equal(Hash.has(h, 'c'), false);
139 + assert.ok(Hash.has(h, ['a','b']));
140 + assert.equal(Hash.has(h, ['a','b','c']), false);
141 +};
142 +
143 +exports.valuesAt = function () {
144 + var h = { a : 4, b : 5, c : 6 };
145 + assert.equal(Hash(h).valuesAt('a'), 4);
146 + assert.equal(Hash(h).valuesAt(['a'])[0], 4);
147 + assert.deepEqual(Hash(h).valuesAt(['a','b']), [4,5]);
148 + assert.equal(Hash.valuesAt(h, 'a'), 4);
149 + assert.deepEqual(Hash.valuesAt(h, ['a']), [4]);
150 + assert.deepEqual(Hash.valuesAt(h, ['a','b']), [4,5]);
151 +};
152 +
153 +exports.tap = function () {
154 + var h = { a : 4, b : 5, c : 6 };
155 + var hh = Hash(h);
156 + hh.tap(function (x) {
157 + assert.ok(this === hh)
158 + assert.eql(x, h);
159 + });
160 +
161 + Hash.tap(h, function (x) {
162 + assert.eql(
163 + Object.keys(this).sort(),
164 + Object.keys(hh).sort()
165 + );
166 + assert.eql(x, h);
167 + });
168 +};
169 +
170 +exports.extract = function () {
171 + var hash = Hash({ a : 1, b : 2, c : 3 }).clone;
172 + var extracted = hash.extract(['a','b']);
173 + assert.equal(extracted.length, 2);
174 + assert.deepEqual(extracted.items, { a : 1, b : 2 });
175 +};
176 +
177 +exports.exclude = function () {
178 + var hash = Hash({ a : 1, b : 2, c : 3 }).clone;
179 + var extracted = hash.exclude(['a','b']);
180 + assert.equal(extracted.length, 1);
181 + assert.deepEqual(extracted.items, { c : 3 });
182 +};
183 +
184 +exports.concat = function () {
185 + var ref1 = { a : 1, b : 2 };
186 + var ref2 = { foo : 100, bar : 200 };
187 + var ref3 = { b : 3, c : 4, bar : 300 };
188 +
189 + assert.deepEqual(
190 + Hash.concat([ ref1, ref2 ]),
191 + { a : 1, b : 2, foo : 100, bar : 200 }
192 + );
193 +
194 + assert.deepEqual(
195 + Hash.concat([ ref1, ref2, ref3 ]),
196 + { a : 1, b : 3, c : 4, foo : 100, bar : 300 }
197 + );
198 +};
199 +
200 +exports.zip = function () {
201 + var xs = ['a','b','c'];
202 + var ys = [1,2,3,4];
203 + var h = Hash(xs,ys);
204 + assert.equal(h.length, 3);
205 + assert.deepEqual(h.items, { a : 1, b : 2, c : 3 });
206 +
207 + var zipped = Hash.zip(xs,ys);
208 + assert.deepEqual(zipped, { a : 1, b : 2, c : 3 });
209 +};
210 +
211 +exports.length = function () {
212 + assert.equal(Hash({ a : 1, b : [2,3], c : 4 }).length, 3);
213 + assert.equal(Hash({ a : 1, b : [2,3], c : 4 }).size, 3);
214 + assert.equal(Hash.size({ a : 1, b : [2,3], c : 4 }), 3);
215 +};
216 +
217 +exports.compact = function () {
218 + var hash = {
219 + a : 1,
220 + b : undefined,
221 + c : false,
222 + d : 4,
223 + e : [ undefined, 4 ],
224 + f : null
225 + };
226 + var compacted = Hash(hash).compact;
227 + assert.deepEqual(
228 + {
229 + a : 1,
230 + b : undefined,
231 + c : false,
232 + d : 4,
233 + e : [ undefined, 4 ],
234 + f : null
235 + },
236 + hash, 'compact modified the hash'
237 + );
238 + assert.deepEqual(
239 + compacted.items,
240 + {
241 + a : 1,
242 + c : false,
243 + d : 4,
244 + e : [ undefined, 4 ],
245 + f : null
246 + }
247 + );
248 + var h = Hash.compact(hash);
249 + assert.deepEqual(h, compacted.items);
250 +};
1 +var Hash = require('hashish');
2 +var assert = require('assert');
3 +var vm = require('vm');
4 +var fs = require('fs');
5 +
6 +var src = fs.readFileSync(__dirname + '/../index.js', 'utf8');
7 +
8 +exports.defineGetter = function () {
9 + var context = {
10 + module : { exports : {} },
11 + Object : {
12 + keys : Object.keys,
13 + defineProperty : undefined,
14 + },
15 + require : require,
16 + };
17 + context.exports = context.module.exports;
18 +
19 + vm.runInNewContext('(function () {' + src + '})()', context);
20 + var Hash_ = context.module.exports;
21 +
22 + var times = 0;
23 + Hash_.__proto__.__proto__.__defineGetter__ = function () {
24 + times ++;
25 + return Object.__defineGetter__.apply(this, arguments);
26 + };
27 +
28 + assert.equal(vm.runInNewContext('Object.defineProperty', context), null);
29 +
30 + assert.deepEqual(
31 + Hash_({ a : 1, b : 2, c : 3 }).values,
32 + [ 1, 2, 3 ]
33 + );
34 +
35 + assert.ok(times > 5);
36 +};
37 +
38 +exports.defineProperty = function () {
39 + var times = 0;
40 + var context = {
41 + module : { exports : {} },
42 + Object : {
43 + keys : Object.keys,
44 + defineProperty : function (prop) {
45 + times ++;
46 + if (prop.get) throw new TypeError('engine does not support')
47 + assert.fail('should have asserted by now');
48 + },
49 + },
50 + require : require
51 + };
52 + context.exports = context.module.exports;
53 +
54 + vm.runInNewContext('(function () {' + src + '})()', context);
55 + var Hash_ = context.module.exports;
56 +
57 + Hash_.__proto__.__proto__.__defineGetter__ = function () {
58 + assert.fail('getter called when a perfectly good'
59 + + ' defineProperty was available'
60 + );
61 + };
62 +
63 + assert.deepEqual(
64 + Hash_({ a : 1, b : 2, c : 3 }).values,
65 + [ 1, 2, 3 ]
66 + );
67 +
68 + assert.equal(times, 1);
69 +};
1 +language: node_js
2 +node_js:
3 + - 'node'
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Adam Gotlib
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy of
6 +this software and associated documentation files (the "Software"), to deal in
7 +the Software without restriction, including without limitation the rights to
8 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 +the Software, and to permit persons to whom the Software is furnished to do so,
10 +subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in all
13 +copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 +# hh-mm-ss: time formatting utility
2 +[![Build Status](https://travis-ci.org/Goldob/hh-mm-ss.svg?branch=master)](https://travis-ci.org/Goldob/hh-mm-ss)
3 +[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
4 +
5 +
6 +:watch: Convert seconds or miliseconds to `hh:mm:ss` format and vice versa.
7 +
8 +```js
9 +var TimeFormat = require('hh-mm-ss')
10 +
11 +TimeFormat.toS('137:00:00') // 493200
12 +TimeFormat.toS('02:00') // 120
13 +TimeFormat.toS('02:00', 'hh:mm') // 7200
14 +
15 +TimeFormat.fromS(194) // '03:14'
16 +TimeFormat.fromS(150, 'hh:mm:ss') // '00:02:30'
17 +TimeFormat.fromS(8100, 'hh:mm') // '02:15'
18 +
19 +TimeFormat.fromMs(12345) // '00:12.345'
20 +```
21 +
22 +## Usage
23 +
24 +### `toMs(time, format)`
25 +
26 +Convert given `hh:mm:ss` formatted string to miliseconds
27 +
28 +#### Parameters
29 +- `time` String representation
30 +- `format` _(optional)_ Default input format. If present, it will be used to resolve amiguities during interpretation. If not specified, `mm:ss` is implied. See section below for supported format list
31 +
32 +### `toS(time, format)`
33 +
34 +Convert given `hh:mm:ss` formatted string to seconds
35 +
36 +#### Parameters
37 +- `time` String representation
38 +- `format` _(optional)_ Default input format. If present, it will be used to resolve amiguities during interpretation. If not specified, `mm:ss` is implied. See section below for supported format list
39 +
40 +### `fromMs(ms, format)`
41 +
42 +Generate formatted string from time in miliseconds
43 +
44 +#### Parameters
45 +- `ms` Time in miliseconds
46 +- `format` _(optional)_ Default output format. If not specified, `mm:ss` is implied. See section below for supported format list.
47 +
48 +### `fromS(s, format)`
49 +
50 +Generate formatted string from time in seconds
51 +
52 +#### Parameters
53 +- `s` Time in seconds
54 +- `format` _(optional)_ Default output format. If not specified, `mm:ss` is implied. See section below for supported format list
55 +
56 +### Supported time formats
57 +The following formats are supported: `mm:ss`, `hh:mm`, `hh:mm:ss`, `mm:ss.sss`, `hh:mm:ss.sss`.
58 +
59 +- `hh` - hours
60 +- `mm` - minutes
61 +- `ss` - second
62 +- `sss` - miliseconds
63 +
64 +Specified format constitutes a baseline for corresponding functions, but will be appropriately extended as needed. For example, `fromMs(9000, 'mm:ss')` will return `01:30`, yet `fromMs(9500, 'mm:ss')` will return `01:30.500` to account for the miliseconds part.
65 +
66 +## Install
67 +
68 +`npm install hh-mm-ss --save`
69 +
70 +## License
71 +
72 +MIT
1 +'use strict'
2 +
3 +module.exports = {
4 + fromMs,
5 + fromS,
6 + toMs,
7 + toS
8 +}
9 +
10 +const zeroFill = require('zero-fill')
11 +
12 +// Time units with their corresponding values in miliseconds
13 +const HOUR = 3600000
14 +const MINUTE = 60000
15 +const SECOND = 1000
16 +
17 +const TIME_FORMAT_ERRMSG = 'Time format error'
18 +
19 +// =============================================================================
20 +// Export functions
21 +// =============================================================================
22 +
23 +function fromMs (ms, format = 'mm:ss') {
24 + if (typeof ms !== 'number' || Number.isNaN(ms)) {
25 + throw new Error('NaN error')
26 + }
27 +
28 + let absMs = Math.abs(ms)
29 +
30 + let negative = (ms < 0)
31 + let hours = Math.floor(absMs / HOUR)
32 + let minutes = Math.floor(absMs % HOUR / MINUTE)
33 + let seconds = Math.floor(absMs % MINUTE / SECOND)
34 + let miliseconds = Math.floor(absMs % SECOND)
35 +
36 + return formatTime({
37 + negative, hours, minutes, seconds, miliseconds
38 + }, format)
39 +}
40 +
41 +function fromS (s, format = 'mm:ss') {
42 + if (typeof s !== 'number' || Number.isNaN(s)) {
43 + throw new Error('NaN error')
44 + }
45 +
46 + let ms = s * SECOND
47 +
48 + return fromMs(ms, format)
49 +}
50 +
51 +function toMs (time, format = 'mm:ss') {
52 + let re
53 +
54 + if (['mm:ss', 'mm:ss.sss', 'hh:mm:ss', 'hh:mm:ss.sss'].includes(format)) {
55 + re = /^(-)?(?:(\d\d+):)?(\d\d):(\d\d)(\.\d+)?$/
56 + } else if (format === 'hh:mm') {
57 + re = /^(-)?(\d\d):(\d\d)(?::(\d\d)(?:(\.\d+))?)?$/
58 + } else {
59 + throw new Error(TIME_FORMAT_ERRMSG)
60 + }
61 +
62 + let result = re.exec(time)
63 + if (!result) throw new Error()
64 +
65 + let negative = result[1] === '-'
66 + let hours = result[2] | 0
67 + let minutes = result[3] | 0
68 + let seconds = result[4] | 0
69 + let miliseconds = Math.floor(1000 * result[5] | 0)
70 +
71 + if (minutes > 60 || seconds > 60) {
72 + throw new Error()
73 + }
74 +
75 + return (negative ? -1 : 1) * (
76 + hours * HOUR + minutes * MINUTE + seconds * SECOND + miliseconds
77 + )
78 +}
79 +
80 +function toS (time, format = 'mm:ss') {
81 + let ms = toMs(time, format)
82 + return Math.floor(ms / SECOND)
83 +}
84 +
85 +// =============================================================================
86 +// Utility functions
87 +// =============================================================================
88 +
89 +function formatTime (time, format) {
90 + let showMs
91 + let showSc
92 + let showHr
93 +
94 + switch (format.toLowerCase()) {
95 + case 'hh:mm:ss.sss':
96 + showMs = true
97 + showSc = true
98 + showHr = true
99 + break
100 + case 'hh:mm:ss':
101 + showMs = !(!time.miliseconds)
102 + showSc = true
103 + showHr = true
104 + break
105 + case 'hh:mm':
106 + showMs = !(!time.miliseconds)
107 + showSc = showMs || !(!time.seconds)
108 + showHr = true
109 + break
110 + case 'mm:ss':
111 + showMs = !(!time.miliseconds)
112 + showSc = true
113 + showHr = !(!time.hours)
114 + break
115 + case 'mm:ss.sss':
116 + showMs = true
117 + showSc = true
118 + showHr = !(!time.hours)
119 + break
120 + default:
121 + throw new Error(TIME_FORMAT_ERRMSG)
122 + }
123 +
124 + let hh = zeroFill(2, time.hours)
125 + let mm = zeroFill(2, time.minutes)
126 + let ss = zeroFill(2, time.seconds)
127 + let sss = zeroFill(3, time.miliseconds)
128 +
129 + return (time.negative ? '-' : '') + (showHr ? (
130 + showMs ? `${hh}:${mm}:${ss}.${sss}` : showSc ? `${hh}:${mm}:${ss}` : `${hh}:${mm}`
131 + ) : (
132 + showMs ? `${mm}:${ss}.${sss}` : `${mm}:${ss}`
133 + ))
134 +}
1 +{
2 + "_from": "hh-mm-ss@~1.2.0",
3 + "_id": "hh-mm-ss@1.2.0",
4 + "_inBundle": false,
5 + "_integrity": "sha512-f4I9Hz1dLpX/3mrEs7yq30+FiuO3tt5NWAqAGeBTaoeoBfB8vhcQ3BphuDc5DjZb/K809agqrAaFlP0jhEU/8w==",
6 + "_location": "/hh-mm-ss",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "hh-mm-ss@~1.2.0",
12 + "name": "hh-mm-ss",
13 + "escapedName": "hh-mm-ss",
14 + "rawSpec": "~1.2.0",
15 + "saveSpec": null,
16 + "fetchSpec": "~1.2.0"
17 + },
18 + "_requiredBy": [
19 + "/youtube-dl"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/hh-mm-ss/-/hh-mm-ss-1.2.0.tgz",
22 + "_shasum": "6d0f0b8280824a634cb1d1f20e0bc7bc8b689948",
23 + "_spec": "hh-mm-ss@~1.2.0",
24 + "_where": "C:\\Users\\user\\Desktop\\오소git\\오소플젝\\Youtube_MPL\\node_modules\\youtube-dl",
25 + "author": {
26 + "name": "Adam Gotlib"
27 + },
28 + "bugs": {
29 + "url": "https://github.com/Goldob/hh-mm-ss/issues"
30 + },
31 + "bundleDependencies": false,
32 + "dependencies": {
33 + "zero-fill": "^2.2.3"
34 + },
35 + "deprecated": false,
36 + "description": "Simple hh:mm:ss time formatting utility",
37 + "devDependencies": {
38 + "standard": "^7.1.2",
39 + "tape": "^4.6.0"
40 + },
41 + "homepage": "https://github.com/Goldob/hh-mm-ss#readme",
42 + "keywords": [
43 + "time format",
44 + "hours",
45 + "minutes",
46 + "seconds",
47 + "miliseconds",
48 + "hh:mm:ss"
49 + ],
50 + "license": "MIT",
51 + "main": "index.js",
52 + "name": "hh-mm-ss",
53 + "repository": {
54 + "type": "git",
55 + "url": "git+https://github.com/Goldob/hh-mm-ss.git"
56 + },
57 + "scripts": {
58 + "test": "standard & node test"
59 + },
60 + "version": "1.2.0"
61 +}
1 +'use-strict'
2 +
3 +const test = require('tape')
4 +const {fromMs, fromS, toMs, toS} = require('../')
5 +
6 +// =============================================================================
7 +// Test cases
8 +// =============================================================================
9 +
10 +test('fromMs() test', (t) => {
11 + // Basic functionality
12 + t.equal(fromMs(75000), '01:15')
13 + t.equal(fromMs(442800000), '123:00:00')
14 + t.equal(fromMs(90576), '01:30.576')
15 + t.equal(fromMs(-157250), '-02:37.250')
16 +
17 + // Output formatting
18 + t.equal(fromMs(38000, 'mm:ss.sss'), '00:38.000')
19 + t.equal(fromMs(0, 'hh:mm:ss'), '00:00:00')
20 + t.equal(fromMs(3600000, 'mm:ss'), '01:00:00')
21 + t.equal(fromMs(4500000, 'hh:mm'), '01:15')
22 + t.equal(fromMs(-9900000, 'hh:mm'), '-02:45')
23 +
24 + // Input validation
25 + t.throws(() => fromMs(null))
26 + t.throws(() => fromMs('text'))
27 + t.throws(() => fromMs(0, 'mm:hh:ss'))
28 +
29 + t.end()
30 +})
31 +
32 +test('fromS() test', (t) => {
33 + // Basic functionality
34 + t.equal(fromS(75), '01:15')
35 + t.equal(fromS(442800), '123:00:00')
36 + t.equal(fromS(-442800), '-123:00:00')
37 +
38 + // Output formatting
39 + t.equal(fromS(38, 'mm:ss.sss'), '00:38.000')
40 + t.equal(fromS(0, 'hh:mm:ss'), '00:00:00')
41 + t.equal(fromS(3600, 'mm:ss'), '01:00:00')
42 + t.equal(fromS(4500, 'hh:mm'), '01:15')
43 + t.equal(fromS(-9900, 'hh:mm'), '-02:45')
44 +
45 + // Input validation
46 + t.throws(() => fromS(null))
47 + t.throws(() => fromS('text'))
48 + t.throws(() => fromS(0, 'mm:hh:ss'))
49 +
50 + t.end()
51 +})
52 +
53 +test('toMs() test', (t) => {
54 + // Basic functionality
55 + t.equal(toMs('01:05:17'), 3917000)
56 + t.equal(toMs('137:00:00.0'), 493200000)
57 + t.equal(toMs('00:10.230'), 10230)
58 + t.equal(toMs('00:00:07.10845'), 7108)
59 + t.equal(toMs('-02:07:12'), -7632000)
60 + t.equal(toMs('02:00'), 120000)
61 + t.equal(toMs('02:00', 'hh:mm'), 7200000)
62 + t.equal(toMs('-04:35', 'hh:mm'), -16500000)
63 + t.equal(toMs('00:00:07.10845', 'hh:mm'), 7108)
64 +
65 + // Input validation
66 + t.throws(() => toMs('13:05:02:11'))
67 + t.throws(() => toMs('153'))
68 + t.throws(() => toMs(null))
69 + t.throws(() => toMs('00:62'))
70 + t.throws(() => toS('01:30', 'mm:hh:ss'))
71 +
72 + t.end()
73 +})
74 +
75 +test('toS() test', (t) => {
76 + // Basic functionality
77 + t.equal(toS('01:05:17'), 3917)
78 + t.equal(toS('137:00:00.0'), 493200)
79 + t.equal(toS('00:10.230'), 10)
80 + t.equal(toS('00:00:07.10845'), 7)
81 + t.equal(toS('-02:07:12'), -7632)
82 + t.equal(toS('02:00'), 120)
83 + t.equal(toS('02:00', 'hh:mm'), 7200)
84 + t.equal(toS('-04:35', 'hh:mm'), -16500)
85 + t.equal(toS('00:00:07.10845', 'hh:mm'), 7)
86 +
87 + // Input validation
88 + t.throws(() => toS('13:05:02:11'))
89 + t.throws(() => toS('153'))
90 + t.throws(() => toS(null))
91 + t.throws(() => toS('00:62'))
92 + t.throws(() => toS('01:30', 'mm:hh:ss'))
93 +
94 + t.end()
95 +})
96 +
97 +test('symmetrical conversion test', (t) => {
98 + /*
99 + * fromMs() and toMs() for all formats
100 + */
101 +
102 + // 90000ms = 1m 30s
103 + t.equal(toMs(fromMs(90000, 'mm:ss'), 'mm:ss'), 90000)
104 + t.equal(toMs(fromMs(90000, 'mm:ss.sss'), 'mm:ss.sss'), 90000)
105 + t.equal(toMs(fromMs(90000, 'hh:mm'), 'hh:mm'), 90000)
106 + t.equal(toMs(fromMs(90000, 'hh:mm:ss'), 'hh:mm:ss'), 90000)
107 + t.equal(toMs(fromMs(90000, 'hh:mm:ss.sss'), 'hh:mm:ss.sss'), 90000)
108 +
109 + // 7517245ms = 2h 5m 17.245s
110 + t.equal(toMs(fromMs(7517245, 'mm:ss'), 'mm:ss'), 7517245)
111 + t.equal(toMs(fromMs(7517245, 'mm:ss.sss'), 'mm:ss.sss'), 7517245)
112 + t.equal(toMs(fromMs(7517245, 'hh:mm'), 'hh:mm'), 7517245)
113 + t.equal(toMs(fromMs(7517245, 'hh:mm:ss'), 'hh:mm:ss'), 7517245)
114 + t.equal(toMs(fromMs(7517245, 'hh:mm:ss.sss'), 'hh:mm:ss.sss'), 7517245)
115 +
116 + // -10800000ms = -3h
117 + t.equal(toMs(fromMs(-10800000, 'mm:ss'), 'mm:ss'), -10800000)
118 + t.equal(toMs(fromMs(-10800000, 'mm:ss.sss'), 'mm:ss.sss'), -10800000)
119 + t.equal(toMs(fromMs(-10800000, 'hh:mm'), 'hh:mm'), -10800000)
120 + t.equal(toMs(fromMs(-10800000, 'hh:mm:ss'), 'hh:mm:ss'), -10800000)
121 + t.equal(toMs(fromMs(-10800000, 'hh:mm:ss.sss'), 'hh:mm:ss.sss'), -10800000)
122 +
123 + /*
124 + * fromS() and toMs() for all formats
125 + */
126 +
127 + // 930s = 15m 30s
128 + t.equal(toS(fromS(930, 'mm:ss'), 'mm:ss'), 930)
129 + t.equal(toS(fromS(930, 'mm:ss.sss'), 'mm:ss.sss'), 930)
130 + t.equal(toS(fromS(930, 'hh:mm'), 'hh:mm'), 930)
131 + t.equal(toS(fromS(930, 'hh:mm:ss'), 'hh:mm:ss'), 930)
132 + t.equal(toS(fromS(930, 'hh:mm:ss.sss'), 'hh:mm:ss.sss'), 930)
133 +
134 + // 4850s = 1h 20m 50s
135 + t.equal(toS(fromS(4850, 'mm:ss'), 'mm:ss'), 4850)
136 + t.equal(toS(fromS(4850, 'mm:ss.sss'), 'mm:ss.sss'), 4850)
137 + t.equal(toS(fromS(4850, 'hh:mm'), 'hh:mm'), 4850)
138 + t.equal(toS(fromS(4850, 'hh:mm:ss'), 'hh:mm:ss'), 4850)
139 + t.equal(toS(fromS(4850, 'hh:mm:ss.sss'), 'hh:mm:ss.sss'), 4850)
140 +
141 + // -300s = -5m
142 + t.equal(toS(fromS(-300, 'mm:ss'), 'mm:ss'), -300)
143 + t.equal(toS(fromS(-300, 'mm:ss.sss'), 'mm:ss.sss'), -300)
144 + t.equal(toS(fromS(-300, 'hh:mm'), 'hh:mm'), -300)
145 + t.equal(toS(fromS(-300, 'hh:mm:ss'), 'hh:mm:ss'), -300)
146 + t.equal(toS(fromS(-300, 'hh:mm:ss.sss'), 'hh:mm:ss.sss'), -300)
147 +
148 + t.end()
149 +})
1 +language: node_js
2 +node_js:
3 + - "0.8"
4 + - "0.10"
1 +This software is released under the MIT license:
2 +
3 +Permission is hereby granted, free of charge, to any person obtaining a copy of
4 +this software and associated documentation files (the "Software"), to deal in
5 +the Software without restriction, including without limitation the rights to
6 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 +the Software, and to permit persons to whom the Software is furnished to do so,
8 +subject to the following conditions:
9 +
10 +The above copyright notice and this permission notice shall be included in all
11 +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, FITNESS
15 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 +var argv = require('../')(process.argv.slice(2));
2 +console.dir(argv);
1 +module.exports = function (args, opts) {
2 + if (!opts) opts = {};
3 +
4 + var flags = { bools : {}, strings : {} };
5 +
6 + [].concat(opts['boolean']).filter(Boolean).forEach(function (key) {
7 + flags.bools[key] = true;
8 + });
9 +
10 + [].concat(opts.string).filter(Boolean).forEach(function (key) {
11 + flags.strings[key] = true;
12 + });
13 +
14 + var aliases = {};
15 + Object.keys(opts.alias || {}).forEach(function (key) {
16 + aliases[key] = [].concat(opts.alias[key]);
17 + aliases[key].forEach(function (x) {
18 + aliases[x] = [key].concat(aliases[key].filter(function (y) {
19 + return x !== y;
20 + }));
21 + });
22 + });
23 +
24 + var defaults = opts['default'] || {};
25 +
26 + var argv = { _ : [] };
27 + Object.keys(flags.bools).forEach(function (key) {
28 + setArg(key, defaults[key] === undefined ? false : defaults[key]);
29 + });
30 +
31 + var notFlags = [];
32 +
33 + if (args.indexOf('--') !== -1) {
34 + notFlags = args.slice(args.indexOf('--')+1);
35 + args = args.slice(0, args.indexOf('--'));
36 + }
37 +
38 + function setArg (key, val) {
39 + var value = !flags.strings[key] && isNumber(val)
40 + ? Number(val) : val
41 + ;
42 + setKey(argv, key.split('.'), value);
43 +
44 + (aliases[key] || []).forEach(function (x) {
45 + setKey(argv, x.split('.'), value);
46 + });
47 + }
48 +
49 + for (var i = 0; i < args.length; i++) {
50 + var arg = args[i];
51 +
52 + if (/^--.+=/.test(arg)) {
53 + // Using [\s\S] instead of . because js doesn't support the
54 + // 'dotall' regex modifier. See:
55 + // http://stackoverflow.com/a/1068308/13216
56 + var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
57 + setArg(m[1], m[2]);
58 + }
59 + else if (/^--no-.+/.test(arg)) {
60 + var key = arg.match(/^--no-(.+)/)[1];
61 + setArg(key, false);
62 + }
63 + else if (/^--.+/.test(arg)) {
64 + var key = arg.match(/^--(.+)/)[1];
65 + var next = args[i + 1];
66 + if (next !== undefined && !/^-/.test(next)
67 + && !flags.bools[key]
68 + && (aliases[key] ? !flags.bools[aliases[key]] : true)) {
69 + setArg(key, next);
70 + i++;
71 + }
72 + else if (/^(true|false)$/.test(next)) {
73 + setArg(key, next === 'true');
74 + i++;
75 + }
76 + else {
77 + setArg(key, flags.strings[key] ? '' : true);
78 + }
79 + }
80 + else if (/^-[^-]+/.test(arg)) {
81 + var letters = arg.slice(1,-1).split('');
82 +
83 + var broken = false;
84 + for (var j = 0; j < letters.length; j++) {
85 + var next = arg.slice(j+2);
86 +
87 + if (next === '-') {
88 + setArg(letters[j], next)
89 + continue;
90 + }
91 +
92 + if (/[A-Za-z]/.test(letters[j])
93 + && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
94 + setArg(letters[j], next);
95 + broken = true;
96 + break;
97 + }
98 +
99 + if (letters[j+1] && letters[j+1].match(/\W/)) {
100 + setArg(letters[j], arg.slice(j+2));
101 + broken = true;
102 + break;
103 + }
104 + else {
105 + setArg(letters[j], flags.strings[letters[j]] ? '' : true);
106 + }
107 + }
108 +
109 + var key = arg.slice(-1)[0];
110 + if (!broken && key !== '-') {
111 + if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1])
112 + && !flags.bools[key]
113 + && (aliases[key] ? !flags.bools[aliases[key]] : true)) {
114 + setArg(key, args[i+1]);
115 + i++;
116 + }
117 + else if (args[i+1] && /true|false/.test(args[i+1])) {
118 + setArg(key, args[i+1] === 'true');
119 + i++;
120 + }
121 + else {
122 + setArg(key, flags.strings[key] ? '' : true);
123 + }
124 + }
125 + }
126 + else {
127 + argv._.push(
128 + flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)
129 + );
130 + }
131 + }
132 +
133 + Object.keys(defaults).forEach(function (key) {
134 + if (!hasKey(argv, key.split('.'))) {
135 + setKey(argv, key.split('.'), defaults[key]);
136 +
137 + (aliases[key] || []).forEach(function (x) {
138 + setKey(argv, x.split('.'), defaults[key]);
139 + });
140 + }
141 + });
142 +
143 + notFlags.forEach(function(key) {
144 + argv._.push(key);
145 + });
146 +
147 + return argv;
148 +};
149 +
150 +function hasKey (obj, keys) {
151 + var o = obj;
152 + keys.slice(0,-1).forEach(function (key) {
153 + o = (o[key] || {});
154 + });
155 +
156 + var key = keys[keys.length - 1];
157 + return key in o;
158 +}
159 +
160 +function setKey (obj, keys, value) {
161 + var o = obj;
162 + keys.slice(0,-1).forEach(function (key) {
163 + if (o[key] === undefined) o[key] = {};
164 + o = o[key];
165 + });
166 +
167 + var key = keys[keys.length - 1];
168 + if (o[key] === undefined || typeof o[key] === 'boolean') {
169 + o[key] = value;
170 + }
171 + else if (Array.isArray(o[key])) {
172 + o[key].push(value);
173 + }
174 + else {
175 + o[key] = [ o[key], value ];
176 + }
177 +}
178 +
179 +function isNumber (x) {
180 + if (typeof x === 'number') return true;
181 + if (/^0x[0-9a-f]+$/i.test(x)) return true;
182 + return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
183 +}
184 +
185 +function longest (xs) {
186 + return Math.max.apply(null, xs.map(function (x) { return x.length }));
187 +}
1 +{
2 + "_from": "minimist@0.0.8",
3 + "_id": "minimist@0.0.8",
4 + "_inBundle": false,
5 + "_integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
6 + "_location": "/minimist",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "version",
10 + "registry": true,
11 + "raw": "minimist@0.0.8",
12 + "name": "minimist",
13 + "escapedName": "minimist",
14 + "rawSpec": "0.0.8",
15 + "saveSpec": null,
16 + "fetchSpec": "0.0.8"
17 + },
18 + "_requiredBy": [
19 + "/mkdirp"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
22 + "_shasum": "857fcabfc3397d2625b8228262e86aa7a011b05d",
23 + "_spec": "minimist@0.0.8",
24 + "_where": "C:\\Users\\user\\Desktop\\오소git\\오소플젝\\Youtube_MPL\\node_modules\\mkdirp",
25 + "author": {
26 + "name": "James Halliday",
27 + "email": "mail@substack.net",
28 + "url": "http://substack.net"
29 + },
30 + "bugs": {
31 + "url": "https://github.com/substack/minimist/issues"
32 + },
33 + "bundleDependencies": false,
34 + "deprecated": false,
35 + "description": "parse argument options",
36 + "devDependencies": {
37 + "tap": "~0.4.0",
38 + "tape": "~1.0.4"
39 + },
40 + "homepage": "https://github.com/substack/minimist",
41 + "keywords": [
42 + "argv",
43 + "getopt",
44 + "parser",
45 + "optimist"
46 + ],
47 + "license": "MIT",
48 + "main": "index.js",
49 + "name": "minimist",
50 + "repository": {
51 + "type": "git",
52 + "url": "git://github.com/substack/minimist.git"
53 + },
54 + "scripts": {
55 + "test": "tap test/*.js"
56 + },
57 + "testling": {
58 + "files": "test/*.js",
59 + "browsers": [
60 + "ie/6..latest",
61 + "ff/5",
62 + "firefox/latest",
63 + "chrome/10",
64 + "chrome/latest",
65 + "safari/5.1",
66 + "safari/latest",
67 + "opera/12"
68 + ]
69 + },
70 + "version": "0.0.8"
71 +}
1 +# minimist
2 +
3 +parse argument options
4 +
5 +This module is the guts of optimist's argument parser without all the
6 +fanciful decoration.
7 +
8 +[![browser support](https://ci.testling.com/substack/minimist.png)](http://ci.testling.com/substack/minimist)
9 +
10 +[![build status](https://secure.travis-ci.org/substack/minimist.png)](http://travis-ci.org/substack/minimist)
11 +
12 +# example
13 +
14 +``` js
15 +var argv = require('minimist')(process.argv.slice(2));
16 +console.dir(argv);
17 +```
18 +
19 +```
20 +$ node example/parse.js -a beep -b boop
21 +{ _: [], a: 'beep', b: 'boop' }
22 +```
23 +
24 +```
25 +$ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
26 +{ _: [ 'foo', 'bar', 'baz' ],
27 + x: 3,
28 + y: 4,
29 + n: 5,
30 + a: true,
31 + b: true,
32 + c: true,
33 + beep: 'boop' }
34 +```
35 +
36 +# methods
37 +
38 +``` js
39 +var parseArgs = require('minimist')
40 +```
41 +
42 +## var argv = parseArgs(args, opts={})
43 +
44 +Return an argument object `argv` populated with the array arguments from `args`.
45 +
46 +`argv._` contains all the arguments that didn't have an option associated with
47 +them.
48 +
49 +Numeric-looking arguments will be returned as numbers unless `opts.string` or
50 +`opts.boolean` is set for that argument name.
51 +
52 +Any arguments after `'--'` will not be parsed and will end up in `argv._`.
53 +
54 +options can be:
55 +
56 +* `opts.string` - a string or array of strings argument names to always treat as
57 +strings
58 +* `opts.boolean` - a string or array of strings to always treat as booleans
59 +* `opts.alias` - an object mapping string names to strings or arrays of string
60 +argument names to use as aliases
61 +* `opts.default` - an object mapping string argument names to default values
62 +
63 +# install
64 +
65 +With [npm](https://npmjs.org) do:
66 +
67 +```
68 +npm install minimist
69 +```
70 +
71 +# license
72 +
73 +MIT
1 +var parse = require('../');
2 +var test = require('tape');
3 +
4 +test('-', function (t) {
5 + t.plan(5);
6 + t.deepEqual(parse([ '-n', '-' ]), { n: '-', _: [] });
7 + t.deepEqual(parse([ '-' ]), { _: [ '-' ] });
8 + t.deepEqual(parse([ '-f-' ]), { f: '-', _: [] });
9 + t.deepEqual(
10 + parse([ '-b', '-' ], { boolean: 'b' }),
11 + { b: true, _: [ '-' ] }
12 + );
13 + t.deepEqual(
14 + parse([ '-s', '-' ], { string: 's' }),
15 + { s: '-', _: [] }
16 + );
17 +});
18 +
19 +test('-a -- b', function (t) {
20 + t.plan(3);
21 + t.deepEqual(parse([ '-a', '--', 'b' ]), { a: true, _: [ 'b' ] });
22 + t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] });
23 + t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] });
24 +});
1 +var test = require('tape');
2 +var parse = require('../');
3 +
4 +test('boolean default true', function (t) {
5 + var argv = parse([], {
6 + boolean: 'sometrue',
7 + default: { sometrue: true }
8 + });
9 + t.equal(argv.sometrue, true);
10 + t.end();
11 +});
12 +
13 +test('boolean default false', function (t) {
14 + var argv = parse([], {
15 + boolean: 'somefalse',
16 + default: { somefalse: false }
17 + });
18 + t.equal(argv.somefalse, false);
19 + t.end();
20 +});
1 +var parse = require('../');
2 +var test = require('tape');
3 +
4 +test('dotted alias', function (t) {
5 + var argv = parse(['--a.b', '22'], {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}});
6 + t.equal(argv.a.b, 22);
7 + t.equal(argv.aa.bb, 22);
8 + t.end();
9 +});
10 +
11 +test('dotted default', function (t) {
12 + var argv = parse('', {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}});
13 + t.equal(argv.a.b, 11);
14 + t.equal(argv.aa.bb, 11);
15 + t.end();
16 +});
1 +var test = require('tape');
2 +var parse = require('../');
3 +
4 +test('long opts', function (t) {
5 + t.deepEqual(
6 + parse([ '--bool' ]),
7 + { bool : true, _ : [] },
8 + 'long boolean'
9 + );
10 + t.deepEqual(
11 + parse([ '--pow', 'xixxle' ]),
12 + { pow : 'xixxle', _ : [] },
13 + 'long capture sp'
14 + );
15 + t.deepEqual(
16 + parse([ '--pow=xixxle' ]),
17 + { pow : 'xixxle', _ : [] },
18 + 'long capture eq'
19 + );
20 + t.deepEqual(
21 + parse([ '--host', 'localhost', '--port', '555' ]),
22 + { host : 'localhost', port : 555, _ : [] },
23 + 'long captures sp'
24 + );
25 + t.deepEqual(
26 + parse([ '--host=localhost', '--port=555' ]),
27 + { host : 'localhost', port : 555, _ : [] },
28 + 'long captures eq'
29 + );
30 + t.end();
31 +});
1 +var parse = require('../');
2 +var test = require('tape');
3 +
4 +test('parse args', function (t) {
5 + t.deepEqual(
6 + parse([ '--no-moo' ]),
7 + { moo : false, _ : [] },
8 + 'no'
9 + );
10 + t.deepEqual(
11 + parse([ '-v', 'a', '-v', 'b', '-v', 'c' ]),
12 + { v : ['a','b','c'], _ : [] },
13 + 'multi'
14 + );
15 + t.end();
16 +});
17 +
18 +test('comprehensive', function (t) {
19 + t.deepEqual(
20 + parse([
21 + '--name=meowmers', 'bare', '-cats', 'woo',
22 + '-h', 'awesome', '--multi=quux',
23 + '--key', 'value',
24 + '-b', '--bool', '--no-meep', '--multi=baz',
25 + '--', '--not-a-flag', 'eek'
26 + ]),
27 + {
28 + c : true,
29 + a : true,
30 + t : true,
31 + s : 'woo',
32 + h : 'awesome',
33 + b : true,
34 + bool : true,
35 + key : 'value',
36 + multi : [ 'quux', 'baz' ],
37 + meep : false,
38 + name : 'meowmers',
39 + _ : [ 'bare', '--not-a-flag', 'eek' ]
40 + }
41 + );
42 + t.end();
43 +});
44 +
45 +test('nums', function (t) {
46 + var argv = parse([
47 + '-x', '1234',
48 + '-y', '5.67',
49 + '-z', '1e7',
50 + '-w', '10f',
51 + '--hex', '0xdeadbeef',
52 + '789'
53 + ]);
54 + t.deepEqual(argv, {
55 + x : 1234,
56 + y : 5.67,
57 + z : 1e7,
58 + w : '10f',
59 + hex : 0xdeadbeef,
60 + _ : [ 789 ]
61 + });
62 + t.deepEqual(typeof argv.x, 'number');
63 + t.deepEqual(typeof argv.y, 'number');
64 + t.deepEqual(typeof argv.z, 'number');
65 + t.deepEqual(typeof argv.w, 'string');
66 + t.deepEqual(typeof argv.hex, 'number');
67 + t.deepEqual(typeof argv._[0], 'number');
68 + t.end();
69 +});
70 +
71 +test('flag boolean', function (t) {
72 + var argv = parse([ '-t', 'moo' ], { boolean: 't' });
73 + t.deepEqual(argv, { t : true, _ : [ 'moo' ] });
74 + t.deepEqual(typeof argv.t, 'boolean');
75 + t.end();
76 +});
77 +
78 +test('flag boolean value', function (t) {
79 + var argv = parse(['--verbose', 'false', 'moo', '-t', 'true'], {
80 + boolean: [ 't', 'verbose' ],
81 + default: { verbose: true }
82 + });
83 +
84 + t.deepEqual(argv, {
85 + verbose: false,
86 + t: true,
87 + _: ['moo']
88 + });
89 +
90 + t.deepEqual(typeof argv.verbose, 'boolean');
91 + t.deepEqual(typeof argv.t, 'boolean');
92 + t.end();
93 +});
94 +
95 +test('flag boolean default false', function (t) {
96 + var argv = parse(['moo'], {
97 + boolean: ['t', 'verbose'],
98 + default: { verbose: false, t: false }
99 + });
100 +
101 + t.deepEqual(argv, {
102 + verbose: false,
103 + t: false,
104 + _: ['moo']
105 + });
106 +
107 + t.deepEqual(typeof argv.verbose, 'boolean');
108 + t.deepEqual(typeof argv.t, 'boolean');
109 + t.end();
110 +
111 +});
112 +
113 +test('boolean groups', function (t) {
114 + var argv = parse([ '-x', '-z', 'one', 'two', 'three' ], {
115 + boolean: ['x','y','z']
116 + });
117 +
118 + t.deepEqual(argv, {
119 + x : true,
120 + y : false,
121 + z : true,
122 + _ : [ 'one', 'two', 'three' ]
123 + });
124 +
125 + t.deepEqual(typeof argv.x, 'boolean');
126 + t.deepEqual(typeof argv.y, 'boolean');
127 + t.deepEqual(typeof argv.z, 'boolean');
128 + t.end();
129 +});
130 +
131 +test('newlines in params' , function (t) {
132 + var args = parse([ '-s', "X\nX" ])
133 + t.deepEqual(args, { _ : [], s : "X\nX" });
134 +
135 + // reproduce in bash:
136 + // VALUE="new
137 + // line"
138 + // node program.js --s="$VALUE"
139 + args = parse([ "--s=X\nX" ])
140 + t.deepEqual(args, { _ : [], s : "X\nX" });
141 + t.end();
142 +});
143 +
144 +test('strings' , function (t) {
145 + var s = parse([ '-s', '0001234' ], { string: 's' }).s;
146 + t.equal(s, '0001234');
147 + t.equal(typeof s, 'string');
148 +
149 + var x = parse([ '-x', '56' ], { string: 'x' }).x;
150 + t.equal(x, '56');
151 + t.equal(typeof x, 'string');
152 + t.end();
153 +});
154 +
155 +test('stringArgs', function (t) {
156 + var s = parse([ ' ', ' ' ], { string: '_' })._;
157 + t.same(s.length, 2);
158 + t.same(typeof s[0], 'string');
159 + t.same(s[0], ' ');
160 + t.same(typeof s[1], 'string');
161 + t.same(s[1], ' ');
162 + t.end();
163 +});
164 +
165 +test('empty strings', function(t) {
166 + var s = parse([ '-s' ], { string: 's' }).s;
167 + t.equal(s, '');
168 + t.equal(typeof s, 'string');
169 +
170 + var str = parse([ '--str' ], { string: 'str' }).str;
171 + t.equal(str, '');
172 + t.equal(typeof str, 'string');
173 +
174 + var letters = parse([ '-art' ], {
175 + string: [ 'a', 't' ]
176 + });
177 +
178 + t.equal(letters.a, '');
179 + t.equal(letters.r, true);
180 + t.equal(letters.t, '');
181 +
182 + t.end();
183 +});
184 +
185 +
186 +test('slashBreak', function (t) {
187 + t.same(
188 + parse([ '-I/foo/bar/baz' ]),
189 + { I : '/foo/bar/baz', _ : [] }
190 + );
191 + t.same(
192 + parse([ '-xyz/foo/bar/baz' ]),
193 + { x : true, y : true, z : '/foo/bar/baz', _ : [] }
194 + );
195 + t.end();
196 +});
197 +
198 +test('alias', function (t) {
199 + var argv = parse([ '-f', '11', '--zoom', '55' ], {
200 + alias: { z: 'zoom' }
201 + });
202 + t.equal(argv.zoom, 55);
203 + t.equal(argv.z, argv.zoom);
204 + t.equal(argv.f, 11);
205 + t.end();
206 +});
207 +
208 +test('multiAlias', function (t) {
209 + var argv = parse([ '-f', '11', '--zoom', '55' ], {
210 + alias: { z: [ 'zm', 'zoom' ] }
211 + });
212 + t.equal(argv.zoom, 55);
213 + t.equal(argv.z, argv.zoom);
214 + t.equal(argv.z, argv.zm);
215 + t.equal(argv.f, 11);
216 + t.end();
217 +});
218 +
219 +test('nested dotted objects', function (t) {
220 + var argv = parse([
221 + '--foo.bar', '3', '--foo.baz', '4',
222 + '--foo.quux.quibble', '5', '--foo.quux.o_O',
223 + '--beep.boop'
224 + ]);
225 +
226 + t.same(argv.foo, {
227 + bar : 3,
228 + baz : 4,
229 + quux : {
230 + quibble : 5,
231 + o_O : true
232 + }
233 + });
234 + t.same(argv.beep, { boop : true });
235 + t.end();
236 +});
237 +
238 +test('boolean and alias with chainable api', function (t) {
239 + var aliased = [ '-h', 'derp' ];
240 + var regular = [ '--herp', 'derp' ];
241 + var opts = {
242 + herp: { alias: 'h', boolean: true }
243 + };
244 + var aliasedArgv = parse(aliased, {
245 + boolean: 'herp',
246 + alias: { h: 'herp' }
247 + });
248 + var propertyArgv = parse(regular, {
249 + boolean: 'herp',
250 + alias: { h: 'herp' }
251 + });
252 + var expected = {
253 + herp: true,
254 + h: true,
255 + '_': [ 'derp' ]
256 + };
257 +
258 + t.same(aliasedArgv, expected);
259 + t.same(propertyArgv, expected);
260 + t.end();
261 +});
262 +
263 +test('boolean and alias with options hash', function (t) {
264 + var aliased = [ '-h', 'derp' ];
265 + var regular = [ '--herp', 'derp' ];
266 + var opts = {
267 + alias: { 'h': 'herp' },
268 + boolean: 'herp'
269 + };
270 + var aliasedArgv = parse(aliased, opts);
271 + var propertyArgv = parse(regular, opts);
272 + var expected = {
273 + herp: true,
274 + h: true,
275 + '_': [ 'derp' ]
276 + };
277 + t.same(aliasedArgv, expected);
278 + t.same(propertyArgv, expected);
279 + t.end();
280 +});
281 +
282 +test('boolean and alias using explicit true', function (t) {
283 + var aliased = [ '-h', 'true' ];
284 + var regular = [ '--herp', 'true' ];
285 + var opts = {
286 + alias: { h: 'herp' },
287 + boolean: 'h'
288 + };
289 + var aliasedArgv = parse(aliased, opts);
290 + var propertyArgv = parse(regular, opts);
291 + var expected = {
292 + herp: true,
293 + h: true,
294 + '_': [ ]
295 + };
296 +
297 + t.same(aliasedArgv, expected);
298 + t.same(propertyArgv, expected);
299 + t.end();
300 +});
301 +
302 +// regression, see https://github.com/substack/node-optimist/issues/71
303 +test('boolean and --x=true', function(t) {
304 + var parsed = parse(['--boool', '--other=true'], {
305 + boolean: 'boool'
306 + });
307 +
308 + t.same(parsed.boool, true);
309 + t.same(parsed.other, 'true');
310 +
311 + parsed = parse(['--boool', '--other=false'], {
312 + boolean: 'boool'
313 + });
314 +
315 + t.same(parsed.boool, true);
316 + t.same(parsed.other, 'false');
317 + t.end();
318 +});
1 +var parse = require('../');
2 +var test = require('tape');
3 +
4 +test('parse with modifier functions' , function (t) {
5 + t.plan(1);
6 +
7 + var argv = parse([ '-b', '123' ], { boolean: 'b' });
8 + t.deepEqual(argv, { b: true, _: ['123'] });
9 +});
1 +var parse = require('../');
2 +var test = require('tape');
3 +
4 +test('numeric short args', function (t) {
5 + t.plan(2);
6 + t.deepEqual(parse([ '-n123' ]), { n: 123, _: [] });
7 + t.deepEqual(
8 + parse([ '-123', '456' ]),
9 + { 1: true, 2: true, 3: 456, _: [] }
10 + );
11 +});
12 +
13 +test('short', function (t) {
14 + t.deepEqual(
15 + parse([ '-b' ]),
16 + { b : true, _ : [] },
17 + 'short boolean'
18 + );
19 + t.deepEqual(
20 + parse([ 'foo', 'bar', 'baz' ]),
21 + { _ : [ 'foo', 'bar', 'baz' ] },
22 + 'bare'
23 + );
24 + t.deepEqual(
25 + parse([ '-cats' ]),
26 + { c : true, a : true, t : true, s : true, _ : [] },
27 + 'group'
28 + );
29 + t.deepEqual(
30 + parse([ '-cats', 'meow' ]),
31 + { c : true, a : true, t : true, s : 'meow', _ : [] },
32 + 'short group next'
33 + );
34 + t.deepEqual(
35 + parse([ '-h', 'localhost' ]),
36 + { h : 'localhost', _ : [] },
37 + 'short capture'
38 + );
39 + t.deepEqual(
40 + parse([ '-h', 'localhost', '-p', '555' ]),
41 + { h : 'localhost', p : 555, _ : [] },
42 + 'short captures'
43 + );
44 + t.end();
45 +});
46 +
47 +test('mixed short bool and capture', function (t) {
48 + t.same(
49 + parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]),
50 + {
51 + f : true, p : 555, h : 'localhost',
52 + _ : [ 'script.js' ]
53 + }
54 + );
55 + t.end();
56 +});
57 +
58 +test('short and long', function (t) {
59 + t.deepEqual(
60 + parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]),
61 + {
62 + f : true, p : 555, h : 'localhost',
63 + _ : [ 'script.js' ]
64 + }
65 + );
66 + t.end();
67 +});
1 +var parse = require('../');
2 +var test = require('tape');
3 +
4 +test('whitespace should be whitespace' , function (t) {
5 + t.plan(1);
6 + var x = parse([ '-x', '\t' ]).x;
7 + t.equal(x, '\t');
8 +});
1 +language: node_js
2 +node_js:
3 + - "0.8"
4 + - "0.10"
5 + - "0.12"
6 + - "iojs"
7 +before_install:
8 + - npm install -g npm@~1.4.6
1 +Copyright 2010 James Halliday (mail@substack.net)
2 +
3 +This project is free software released under the MIT/X11 license:
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +#!/usr/bin/env node
2 +
3 +var mkdirp = require('../');
4 +var minimist = require('minimist');
5 +var fs = require('fs');
6 +
7 +var argv = minimist(process.argv.slice(2), {
8 + alias: { m: 'mode', h: 'help' },
9 + string: [ 'mode' ]
10 +});
11 +if (argv.help) {
12 + fs.createReadStream(__dirname + '/usage.txt').pipe(process.stdout);
13 + return;
14 +}
15 +
16 +var paths = argv._.slice();
17 +var mode = argv.mode ? parseInt(argv.mode, 8) : undefined;
18 +
19 +(function next () {
20 + if (paths.length === 0) return;
21 + var p = paths.shift();
22 +
23 + if (mode === undefined) mkdirp(p, cb)
24 + else mkdirp(p, mode, cb)
25 +
26 + function cb (err) {
27 + if (err) {
28 + console.error(err.message);
29 + process.exit(1);
30 + }
31 + else next();
32 + }
33 +})();
1 +usage: mkdirp [DIR1,DIR2..] {OPTIONS}
2 +
3 + Create each supplied directory including any necessary parent directories that
4 + don't yet exist.
5 +
6 + If the directory already exists, do nothing.
7 +
8 +OPTIONS are:
9 +
10 + -m, --mode If a directory needs to be created, set the mode as an octal
11 + permission string.
12 +
1 +var mkdirp = require('mkdirp');
2 +
3 +mkdirp('/tmp/foo/bar/baz', function (err) {
4 + if (err) console.error(err)
5 + else console.log('pow!')
6 +});
1 +var path = require('path');
2 +var fs = require('fs');
3 +var _0777 = parseInt('0777', 8);
4 +
5 +module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
6 +
7 +function mkdirP (p, opts, f, made) {
8 + if (typeof opts === 'function') {
9 + f = opts;
10 + opts = {};
11 + }
12 + else if (!opts || typeof opts !== 'object') {
13 + opts = { mode: opts };
14 + }
15 +
16 + var mode = opts.mode;
17 + var xfs = opts.fs || fs;
18 +
19 + if (mode === undefined) {
20 + mode = _0777 & (~process.umask());
21 + }
22 + if (!made) made = null;
23 +
24 + var cb = f || function () {};
25 + p = path.resolve(p);
26 +
27 + xfs.mkdir(p, mode, function (er) {
28 + if (!er) {
29 + made = made || p;
30 + return cb(null, made);
31 + }
32 + switch (er.code) {
33 + case 'ENOENT':
34 + mkdirP(path.dirname(p), opts, function (er, made) {
35 + if (er) cb(er, made);
36 + else mkdirP(p, opts, cb, made);
37 + });
38 + break;
39 +
40 + // In the case of any other error, just see if there's a dir
41 + // there already. If so, then hooray! If not, then something
42 + // is borked.
43 + default:
44 + xfs.stat(p, function (er2, stat) {
45 + // if the stat fails, then that's super weird.
46 + // let the original error be the failure reason.
47 + if (er2 || !stat.isDirectory()) cb(er, made)
48 + else cb(null, made);
49 + });
50 + break;
51 + }
52 + });
53 +}
54 +
55 +mkdirP.sync = function sync (p, opts, made) {
56 + if (!opts || typeof opts !== 'object') {
57 + opts = { mode: opts };
58 + }
59 +
60 + var mode = opts.mode;
61 + var xfs = opts.fs || fs;
62 +
63 + if (mode === undefined) {
64 + mode = _0777 & (~process.umask());
65 + }
66 + if (!made) made = null;
67 +
68 + p = path.resolve(p);
69 +
70 + try {
71 + xfs.mkdirSync(p, mode);
72 + made = made || p;
73 + }
74 + catch (err0) {
75 + switch (err0.code) {
76 + case 'ENOENT' :
77 + made = sync(path.dirname(p), opts, made);
78 + sync(p, opts, made);
79 + break;
80 +
81 + // In the case of any other error, just see if there's a dir
82 + // there already. If so, then hooray! If not, then something
83 + // is borked.
84 + default:
85 + var stat;
86 + try {
87 + stat = xfs.statSync(p);
88 + }
89 + catch (err1) {
90 + throw err0;
91 + }
92 + if (!stat.isDirectory()) throw err0;
93 + break;
94 + }
95 + }
96 +
97 + return made;
98 +};
1 +{
2 + "_from": "mkdirp@~0.5.1",
3 + "_id": "mkdirp@0.5.1",
4 + "_inBundle": false,
5 + "_integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
6 + "_location": "/mkdirp",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "mkdirp@~0.5.1",
12 + "name": "mkdirp",
13 + "escapedName": "mkdirp",
14 + "rawSpec": "~0.5.1",
15 + "saveSpec": null,
16 + "fetchSpec": "~0.5.1"
17 + },
18 + "_requiredBy": [
19 + "/youtube-dl"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
22 + "_shasum": "30057438eac6cf7f8c4767f38648d6697d75c903",
23 + "_spec": "mkdirp@~0.5.1",
24 + "_where": "C:\\Users\\user\\Desktop\\오소git\\오소플젝\\Youtube_MPL\\node_modules\\youtube-dl",
25 + "author": {
26 + "name": "James Halliday",
27 + "email": "mail@substack.net",
28 + "url": "http://substack.net"
29 + },
30 + "bin": {
31 + "mkdirp": "bin/cmd.js"
32 + },
33 + "bugs": {
34 + "url": "https://github.com/substack/node-mkdirp/issues"
35 + },
36 + "bundleDependencies": false,
37 + "dependencies": {
38 + "minimist": "0.0.8"
39 + },
40 + "deprecated": false,
41 + "description": "Recursively mkdir, like `mkdir -p`",
42 + "devDependencies": {
43 + "mock-fs": "2 >=2.7.0",
44 + "tap": "1"
45 + },
46 + "homepage": "https://github.com/substack/node-mkdirp#readme",
47 + "keywords": [
48 + "mkdir",
49 + "directory"
50 + ],
51 + "license": "MIT",
52 + "main": "index.js",
53 + "name": "mkdirp",
54 + "repository": {
55 + "type": "git",
56 + "url": "git+https://github.com/substack/node-mkdirp.git"
57 + },
58 + "scripts": {
59 + "test": "tap test/*.js"
60 + },
61 + "version": "0.5.1"
62 +}
1 +# mkdirp
2 +
3 +Like `mkdir -p`, but in node.js!
4 +
5 +[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp)
6 +
7 +# example
8 +
9 +## pow.js
10 +
11 +```js
12 +var mkdirp = require('mkdirp');
13 +
14 +mkdirp('/tmp/foo/bar/baz', function (err) {
15 + if (err) console.error(err)
16 + else console.log('pow!')
17 +});
18 +```
19 +
20 +Output
21 +
22 +```
23 +pow!
24 +```
25 +
26 +And now /tmp/foo/bar/baz exists, huzzah!
27 +
28 +# methods
29 +
30 +```js
31 +var mkdirp = require('mkdirp');
32 +```
33 +
34 +## mkdirp(dir, opts, cb)
35 +
36 +Create a new directory and any necessary subdirectories at `dir` with octal
37 +permission string `opts.mode`. If `opts` is a non-object, it will be treated as
38 +the `opts.mode`.
39 +
40 +If `opts.mode` isn't specified, it defaults to `0777 & (~process.umask())`.
41 +
42 +`cb(err, made)` fires with the error or the first directory `made`
43 +that had to be created, if any.
44 +
45 +You can optionally pass in an alternate `fs` implementation by passing in
46 +`opts.fs`. Your implementation should have `opts.fs.mkdir(path, mode, cb)` and
47 +`opts.fs.stat(path, cb)`.
48 +
49 +## mkdirp.sync(dir, opts)
50 +
51 +Synchronously create a new directory and any necessary subdirectories at `dir`
52 +with octal permission string `opts.mode`. If `opts` is a non-object, it will be
53 +treated as the `opts.mode`.
54 +
55 +If `opts.mode` isn't specified, it defaults to `0777 & (~process.umask())`.
56 +
57 +Returns the first directory that had to be created, if any.
58 +
59 +You can optionally pass in an alternate `fs` implementation by passing in
60 +`opts.fs`. Your implementation should have `opts.fs.mkdirSync(path, mode)` and
61 +`opts.fs.statSync(path)`.
62 +
63 +# usage
64 +
65 +This package also ships with a `mkdirp` command.
66 +
67 +```
68 +usage: mkdirp [DIR1,DIR2..] {OPTIONS}
69 +
70 + Create each supplied directory including any necessary parent directories that
71 + don't yet exist.
72 +
73 + If the directory already exists, do nothing.
74 +
75 +OPTIONS are:
76 +
77 + -m, --mode If a directory needs to be created, set the mode as an octal
78 + permission string.
79 +
80 +```
81 +
82 +# install
83 +
84 +With [npm](http://npmjs.org) do:
85 +
86 +```
87 +npm install mkdirp
88 +```
89 +
90 +to get the library, or
91 +
92 +```
93 +npm install -g mkdirp
94 +```
95 +
96 +to get the command.
97 +
98 +# license
99 +
100 +MIT
1 +var mkdirp = require('../').mkdirp;
2 +var path = require('path');
3 +var fs = require('fs');
4 +var test = require('tap').test;
5 +var _0777 = parseInt('0777', 8);
6 +var _0755 = parseInt('0755', 8);
7 +var _0744 = parseInt('0744', 8);
8 +
9 +var ps = [ '', 'tmp' ];
10 +
11 +for (var i = 0; i < 25; i++) {
12 + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
13 + ps.push(dir);
14 +}
15 +
16 +var file = ps.join('/');
17 +
18 +test('chmod-pre', function (t) {
19 + var mode = _0744
20 + mkdirp(file, mode, function (er) {
21 + t.ifError(er, 'should not error');
22 + fs.stat(file, function (er, stat) {
23 + t.ifError(er, 'should exist');
24 + t.ok(stat && stat.isDirectory(), 'should be directory');
25 + t.equal(stat && stat.mode & _0777, mode, 'should be 0744');
26 + t.end();
27 + });
28 + });
29 +});
30 +
31 +test('chmod', function (t) {
32 + var mode = _0755
33 + mkdirp(file, mode, function (er) {
34 + t.ifError(er, 'should not error');
35 + fs.stat(file, function (er, stat) {
36 + t.ifError(er, 'should exist');
37 + t.ok(stat && stat.isDirectory(), 'should be directory');
38 + t.end();
39 + });
40 + });
41 +});
1 +var mkdirp = require('../').mkdirp;
2 +var path = require('path');
3 +var fs = require('fs');
4 +var test = require('tap').test;
5 +var _0755 = parseInt('0755', 8);
6 +
7 +var ps = [ '', 'tmp' ];
8 +
9 +for (var i = 0; i < 25; i++) {
10 + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
11 + ps.push(dir);
12 +}
13 +
14 +var file = ps.join('/');
15 +
16 +// a file in the way
17 +var itw = ps.slice(0, 3).join('/');
18 +
19 +
20 +test('clobber-pre', function (t) {
21 + console.error("about to write to "+itw)
22 + fs.writeFileSync(itw, 'I AM IN THE WAY, THE TRUTH, AND THE LIGHT.');
23 +
24 + fs.stat(itw, function (er, stat) {
25 + t.ifError(er)
26 + t.ok(stat && stat.isFile(), 'should be file')
27 + t.end()
28 + })
29 +})
30 +
31 +test('clobber', function (t) {
32 + t.plan(2);
33 + mkdirp(file, _0755, function (err) {
34 + t.ok(err);
35 + t.equal(err.code, 'ENOTDIR');
36 + t.end();
37 + });
38 +});
1 +var mkdirp = require('../');
2 +var path = require('path');
3 +var fs = require('fs');
4 +var exists = fs.exists || path.exists;
5 +var test = require('tap').test;
6 +var _0777 = parseInt('0777', 8);
7 +var _0755 = parseInt('0755', 8);
8 +
9 +test('woo', function (t) {
10 + t.plan(5);
11 + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
12 + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
13 + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
14 +
15 + var file = '/tmp/' + [x,y,z].join('/');
16 +
17 + mkdirp(file, _0755, function (err) {
18 + t.ifError(err);
19 + exists(file, function (ex) {
20 + t.ok(ex, 'file created');
21 + fs.stat(file, function (err, stat) {
22 + t.ifError(err);
23 + t.equal(stat.mode & _0777, _0755);
24 + t.ok(stat.isDirectory(), 'target not a directory');
25 + })
26 + })
27 + });
28 +});
1 +var mkdirp = require('../');
2 +var path = require('path');
3 +var test = require('tap').test;
4 +var mockfs = require('mock-fs');
5 +var _0777 = parseInt('0777', 8);
6 +var _0755 = parseInt('0755', 8);
7 +
8 +test('opts.fs', function (t) {
9 + t.plan(5);
10 +
11 + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
12 + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
13 + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
14 +
15 + var file = '/beep/boop/' + [x,y,z].join('/');
16 + var xfs = mockfs.fs();
17 +
18 + mkdirp(file, { fs: xfs, mode: _0755 }, function (err) {
19 + t.ifError(err);
20 + xfs.exists(file, function (ex) {
21 + t.ok(ex, 'created file');
22 + xfs.stat(file, function (err, stat) {
23 + t.ifError(err);
24 + t.equal(stat.mode & _0777, _0755);
25 + t.ok(stat.isDirectory(), 'target not a directory');
26 + });
27 + });
28 + });
29 +});
1 +var mkdirp = require('../');
2 +var path = require('path');
3 +var test = require('tap').test;
4 +var mockfs = require('mock-fs');
5 +var _0777 = parseInt('0777', 8);
6 +var _0755 = parseInt('0755', 8);
7 +
8 +test('opts.fs sync', function (t) {
9 + t.plan(4);
10 +
11 + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
12 + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
13 + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
14 +
15 + var file = '/beep/boop/' + [x,y,z].join('/');
16 + var xfs = mockfs.fs();
17 +
18 + mkdirp.sync(file, { fs: xfs, mode: _0755 });
19 + xfs.exists(file, function (ex) {
20 + t.ok(ex, 'created file');
21 + xfs.stat(file, function (err, stat) {
22 + t.ifError(err);
23 + t.equal(stat.mode & _0777, _0755);
24 + t.ok(stat.isDirectory(), 'target not a directory');
25 + });
26 + });
27 +});
1 +var mkdirp = require('../');
2 +var path = require('path');
3 +var fs = require('fs');
4 +var exists = fs.exists || path.exists;
5 +var test = require('tap').test;
6 +var _0777 = parseInt('0777', 8);
7 +var _0755 = parseInt('0755', 8);
8 +
9 +test('async perm', function (t) {
10 + t.plan(5);
11 + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16);
12 +
13 + mkdirp(file, _0755, function (err) {
14 + t.ifError(err);
15 + exists(file, function (ex) {
16 + t.ok(ex, 'file created');
17 + fs.stat(file, function (err, stat) {
18 + t.ifError(err);
19 + t.equal(stat.mode & _0777, _0755);
20 + t.ok(stat.isDirectory(), 'target not a directory');
21 + })
22 + })
23 + });
24 +});
25 +
26 +test('async root perm', function (t) {
27 + mkdirp('/tmp', _0755, function (err) {
28 + if (err) t.fail(err);
29 + t.end();
30 + });
31 + t.end();
32 +});
1 +var mkdirp = require('../');
2 +var path = require('path');
3 +var fs = require('fs');
4 +var exists = fs.exists || path.exists;
5 +var test = require('tap').test;
6 +var _0777 = parseInt('0777', 8);
7 +var _0755 = parseInt('0755', 8);
8 +
9 +test('sync perm', function (t) {
10 + t.plan(4);
11 + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16) + '.json';
12 +
13 + mkdirp.sync(file, _0755);
14 + exists(file, function (ex) {
15 + t.ok(ex, 'file created');
16 + fs.stat(file, function (err, stat) {
17 + t.ifError(err);
18 + t.equal(stat.mode & _0777, _0755);
19 + t.ok(stat.isDirectory(), 'target not a directory');
20 + });
21 + });
22 +});
23 +
24 +test('sync root perm', function (t) {
25 + t.plan(3);
26 +
27 + var file = '/tmp';
28 + mkdirp.sync(file, _0755);
29 + exists(file, function (ex) {
30 + t.ok(ex, 'file created');
31 + fs.stat(file, function (err, stat) {
32 + t.ifError(err);
33 + t.ok(stat.isDirectory(), 'target not a directory');
34 + })
35 + });
36 +});
1 +var mkdirp = require('../').mkdirp;
2 +var path = require('path');
3 +var fs = require('fs');
4 +var exists = fs.exists || path.exists;
5 +var test = require('tap').test;
6 +var _0777 = parseInt('0777', 8);
7 +var _0755 = parseInt('0755', 8);
8 +
9 +test('race', function (t) {
10 + t.plan(10);
11 + var ps = [ '', 'tmp' ];
12 +
13 + for (var i = 0; i < 25; i++) {
14 + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
15 + ps.push(dir);
16 + }
17 + var file = ps.join('/');
18 +
19 + var res = 2;
20 + mk(file);
21 +
22 + mk(file);
23 +
24 + function mk (file, cb) {
25 + mkdirp(file, _0755, function (err) {
26 + t.ifError(err);
27 + exists(file, function (ex) {
28 + t.ok(ex, 'file created');
29 + fs.stat(file, function (err, stat) {
30 + t.ifError(err);
31 + t.equal(stat.mode & _0777, _0755);
32 + t.ok(stat.isDirectory(), 'target not a directory');
33 + });
34 + })
35 + });
36 + }
37 +});
1 +var mkdirp = require('../');
2 +var path = require('path');
3 +var fs = require('fs');
4 +var exists = fs.exists || path.exists;
5 +var test = require('tap').test;
6 +var _0777 = parseInt('0777', 8);
7 +var _0755 = parseInt('0755', 8);
8 +
9 +test('rel', function (t) {
10 + t.plan(5);
11 + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
12 + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
13 + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
14 +
15 + var cwd = process.cwd();
16 + process.chdir('/tmp');
17 +
18 + var file = [x,y,z].join('/');
19 +
20 + mkdirp(file, _0755, function (err) {
21 + t.ifError(err);
22 + exists(file, function (ex) {
23 + t.ok(ex, 'file created');
24 + fs.stat(file, function (err, stat) {
25 + t.ifError(err);
26 + process.chdir(cwd);
27 + t.equal(stat.mode & _0777, _0755);
28 + t.ok(stat.isDirectory(), 'target not a directory');
29 + })
30 + })
31 + });
32 +});
1 +var mkdirp = require('../');
2 +var path = require('path');
3 +var fs = require('fs');
4 +var test = require('tap').test;
5 +
6 +test('return value', function (t) {
7 + t.plan(4);
8 + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
9 + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
10 + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
11 +
12 + var file = '/tmp/' + [x,y,z].join('/');
13 +
14 + // should return the first dir created.
15 + // By this point, it would be profoundly surprising if /tmp didn't
16 + // already exist, since every other test makes things in there.
17 + mkdirp(file, function (err, made) {
18 + t.ifError(err);
19 + t.equal(made, '/tmp/' + x);
20 + mkdirp(file, function (err, made) {
21 + t.ifError(err);
22 + t.equal(made, null);
23 + });
24 + });
25 +});
1 +var mkdirp = require('../');
2 +var path = require('path');
3 +var fs = require('fs');
4 +var test = require('tap').test;
5 +
6 +test('return value', function (t) {
7 + t.plan(2);
8 + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
9 + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
10 + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
11 +
12 + var file = '/tmp/' + [x,y,z].join('/');
13 +
14 + // should return the first dir created.
15 + // By this point, it would be profoundly surprising if /tmp didn't
16 + // already exist, since every other test makes things in there.
17 + // Note that this will throw on failure, which will fail the test.
18 + var made = mkdirp.sync(file);
19 + t.equal(made, '/tmp/' + x);
20 +
21 + // making the same file again should have no effect.
22 + made = mkdirp.sync(file);
23 + t.equal(made, null);
24 +});
1 +var mkdirp = require('../');
2 +var path = require('path');
3 +var fs = require('fs');
4 +var test = require('tap').test;
5 +var _0755 = parseInt('0755', 8);
6 +
7 +test('root', function (t) {
8 + // '/' on unix, 'c:/' on windows.
9 + var file = path.resolve('/');
10 +
11 + mkdirp(file, _0755, function (err) {
12 + if (err) throw err
13 + fs.stat(file, function (er, stat) {
14 + if (er) throw er
15 + t.ok(stat.isDirectory(), 'target is a directory');
16 + t.end();
17 + })
18 + });
19 +});
1 +var mkdirp = require('../');
2 +var path = require('path');
3 +var fs = require('fs');
4 +var exists = fs.exists || path.exists;
5 +var test = require('tap').test;
6 +var _0777 = parseInt('0777', 8);
7 +var _0755 = parseInt('0755', 8);
8 +
9 +test('sync', function (t) {
10 + t.plan(4);
11 + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
12 + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
13 + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
14 +
15 + var file = '/tmp/' + [x,y,z].join('/');
16 +
17 + try {
18 + mkdirp.sync(file, _0755);
19 + } catch (err) {
20 + t.fail(err);
21 + return t.end();
22 + }
23 +
24 + exists(file, function (ex) {
25 + t.ok(ex, 'file created');
26 + fs.stat(file, function (err, stat) {
27 + t.ifError(err);
28 + t.equal(stat.mode & _0777, _0755);
29 + t.ok(stat.isDirectory(), 'target not a directory');
30 + });
31 + });
32 +});
1 +var mkdirp = require('../');
2 +var path = require('path');
3 +var fs = require('fs');
4 +var exists = fs.exists || path.exists;
5 +var test = require('tap').test;
6 +var _0777 = parseInt('0777', 8);
7 +var _0755 = parseInt('0755', 8);
8 +
9 +test('implicit mode from umask', function (t) {
10 + t.plan(5);
11 + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
12 + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
13 + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
14 +
15 + var file = '/tmp/' + [x,y,z].join('/');
16 +
17 + mkdirp(file, function (err) {
18 + t.ifError(err);
19 + exists(file, function (ex) {
20 + t.ok(ex, 'file created');
21 + fs.stat(file, function (err, stat) {
22 + t.ifError(err);
23 + t.equal(stat.mode & _0777, _0777 & (~process.umask()));
24 + t.ok(stat.isDirectory(), 'target not a directory');
25 + });
26 + })
27 + });
28 +});
1 +var mkdirp = require('../');
2 +var path = require('path');
3 +var fs = require('fs');
4 +var exists = fs.exists || path.exists;
5 +var test = require('tap').test;
6 +var _0777 = parseInt('0777', 8);
7 +var _0755 = parseInt('0755', 8);
8 +
9 +test('umask sync modes', function (t) {
10 + t.plan(4);
11 + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
12 + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
13 + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
14 +
15 + var file = '/tmp/' + [x,y,z].join('/');
16 +
17 + try {
18 + mkdirp.sync(file);
19 + } catch (err) {
20 + t.fail(err);
21 + return t.end();
22 + }
23 +
24 + exists(file, function (ex) {
25 + t.ok(ex, 'file created');
26 + fs.stat(file, function (err, stat) {
27 + t.ifError(err);
28 + t.equal(stat.mode & _0777, (_0777 & (~process.umask())));
29 + t.ok(stat.isDirectory(), 'target not a directory');
30 + });
31 + });
32 +});
1 +Copyright (C) 2012 by Roly Fentanes
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
8 +furnished to do so, subject to the following conditions:
9 +
10 +The above copyright notice and this permission notice shall be included in
11 +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.
1 +# node-streamify
2 +
3 +Streamify helps you easily provide a streaming interface for your code.
4 +
5 +[![Build Status](https://secure.travis-ci.org/fent/node-streamify.svg)](http://travis-ci.org/fent/node-streamify)
6 +[![Dependency Status](https://david-dm.org/fent/node-streamify.svg)](https://david-dm.org/fent/node-streamify)
7 +[![codecov](https://codecov.io/gh/fent/node-streamify/branch/master/graph/badge.svg)](https://codecov.io/gh/fent/node-streamify)
8 +
9 +# Usage
10 +
11 +```js
12 +var streamify = require('streamify');
13 +var request = require('request');
14 +
15 +exports.doSomething = function doSomething() {
16 + var stream = streamify();
17 +
18 + request(url1, function(err, res, body) {
19 + // do something with `body`
20 +
21 + // once the actual stream you want to return is ready,
22 + // call `stream.resolve()`
23 + stream.resolve(request(url2));
24 + });
25 +
26 + // your function can return back a stream!!
27 + return stream;
28 +}
29 +
30 +// because `doSomething()` returns a stream, it can be piped
31 +exports.doSomething().pipe(anotherStream);
32 +```
33 +
34 +
35 +# API
36 +### streamify([options])
37 +
38 +Returns an instance of a stream. `options` can be
39 +
40 +* `superCtor` - The object from which it inherits. Defaults to `require('stream').Stream`. Sometimes you may want to use this if your stream might be checked with the `instanceof` operator against objects such as `http.ServerResponse`.
41 +* `readable` - Defaults to `true`.
42 +* `writable` - Defaults to `true`.
43 +
44 +### Stream#resolve(stream)
45 +
46 +Must be called only once when the actual stream you are proxying to becomes available after an asynchronous operation.
47 +
48 +### Stream#unresolve()
49 +
50 +Can be used to unbind a a resolved stream to later call `resolve()` again.
51 +
52 +### Stream#addSource(stream)
53 +
54 +Add a source readable stream.
55 +
56 +### Stream#removeSource()
57 +
58 +Remove previously added source stream.
59 +
60 +### Stream#addDest(stream)
61 +
62 +Add a destination writable stream.
63 +
64 +### Stream#removeDest()
65 +
66 +Remove a previously added destination stream.
67 +
68 +
69 +# Install
70 +
71 + npm install streamify
72 +
73 +
74 +# Tests
75 +Tests are written with [mocha](https://mochajs.org)
76 +
77 +```bash
78 +npm test
79 +```
80 +
81 +# License
82 +MIT
1 +var Readable = require('stream').Readable;
2 +var Writable = require('stream').Writable;
3 +var Duplex = require('stream').Duplex;
4 +var hashish = require('hashish');
5 +
6 +
7 +/**
8 + * Proxy some events from underlying readable and writable streams.
9 + */
10 +var SOURCE_EVENTS = ['error', 'close'];
11 +var DEST_EVENTS = ['drain', 'close'];
12 +
13 +
14 +/**
15 + * Creates property to use with `Object.create()`
16 + *
17 + * @param {Object} value
18 + * @return {Object}
19 + */
20 +function prop(value) {
21 + return {
22 + writable: true,
23 + enumerable: true,
24 + configurable: true,
25 + value: value
26 + };
27 +}
28 +
29 +
30 +/**
31 + * @constructor
32 + * @param {Object} options
33 + * {Object} superCtor
34 + * {Boolean} readable
35 + * {Boolean} writable
36 + * @return {Duplex}
37 + */
38 +var Streamify = module.exports = function Streamify(options) {
39 + options = options || {};
40 + options.readable = typeof options.readable !== 'undefined' ?
41 + options.readable : true;
42 + options.writable = typeof options.writable !== 'undefined' ?
43 + options.writable : true;
44 +
45 + var superCtor = getConstructor(options);
46 +
47 + // Add `Streamify.prototype` methods.
48 + var properties = hashish.map(Streamify.prototype, prop);
49 +
50 + var o = Object.create(superCtor.prototype, properties);
51 + superCtor.call(o);
52 + o.readable = options.readable;
53 + o.writable = options.writable;
54 + o.__options = options;
55 + o._onevent = function onevent() {
56 + };
57 + o._destWritten = [];
58 +
59 + if (options.writable) {
60 + o.once('finish', function() {
61 + if (o._dest) {
62 + o._dest.stream.end();
63 + }
64 + });
65 + }
66 + return o;
67 +};
68 +
69 +
70 +/**
71 + * Required implementation by streaming API.
72 + *
73 + * @param {Number} size
74 + */
75 +Streamify.prototype._read = function(size) {
76 + if (this._source) {
77 + var self = this;
78 + var onreadable = this._source.onreadable = function onreadable() {
79 + if (!self._source) { return; }
80 + var data = self._source.stream.read(size);
81 + if (data) {
82 + self.push(data);
83 + } else {
84 + self._source.stream.once('readable', onreadable);
85 + }
86 + };
87 + onreadable();
88 +
89 + } else {
90 + this._sourceRead = size;
91 + }
92 +};
93 +
94 +
95 +/**
96 + * Required implementation by streaming API.
97 + *
98 + * @param {Buffer|String} chunk
99 + * @param {!String} encoding
100 + * @param {Function(!Error)} callback
101 + */
102 +Streamify.prototype._write = function(chunk, encoding, callback) {
103 + if (this._dest) {
104 + this._dest.stream.write(chunk, encoding, callback);
105 + } else {
106 + this._destWritten.push(arguments);
107 + }
108 +};
109 +
110 +
111 +/**
112 + * Add a stream to be the readable stream source.
113 + *
114 + * @param {Readable|Stream} stream
115 + */
116 +Streamify.prototype.addSource = function(stream) {
117 + if (this._source) {
118 + throw Error('A source stream has already been added.');
119 + }
120 + stream = getReadable(stream);
121 +
122 + this._source = { stream: stream, listeners: {}, onend: onend };
123 + var self = this;
124 +
125 + SOURCE_EVENTS.forEach(function(event) {
126 + var onevent = self._source.listeners[event] = function onevent() {
127 + var args = Array.prototype.slice.call(arguments);
128 + self.emit.apply(self, [event].concat(args));
129 + };
130 + stream.on(event, onevent);
131 + });
132 +
133 + // Listen for `end` event to signal for end of data.
134 + function onend() {
135 + self.push(null);
136 + }
137 + stream.on('end', onend);
138 +
139 + // Check if `Readable#_read()` has already been called.
140 + this._read(this._sourceRead);
141 +};
142 +
143 +
144 +/**
145 + * Remove a stream from being the source.
146 + */
147 +Streamify.prototype.removeSource = function() {
148 + if (!this._source) {
149 + throw Error('A source stream has not been added.');
150 + }
151 +
152 + var source = this._source;
153 + SOURCE_EVENTS.forEach(function(event) {
154 + source.stream.removeListener(event, source.listeners[event]);
155 + });
156 + source.stream.removeListener('readable', source.onreadable);
157 + source.stream.removeListener('end', source.onend);
158 +
159 + delete this._source;
160 +};
161 +
162 +
163 +/**
164 + * Add a stream to be the writable stream destination.
165 + *
166 + * @param {Writable|Stream} stream
167 + */
168 +Streamify.prototype.addDest = function(stream) {
169 + if (this._dest) {
170 + throw Error('A destination stream has already been added.');
171 + }
172 +
173 + this._dest = { stream: stream, listeners: {} };
174 + var self = this;
175 +
176 + DEST_EVENTS.forEach(function(event) {
177 + var onevent = self._dest.listeners[event] = function onevent() {
178 + var args = Array.prototype.slice.call(arguments);
179 + self.emit.apply(self, [event].concat(args));
180 + };
181 + stream.on(event, onevent);
182 + });
183 +
184 + if (this._destWritten.length) {
185 + this._destWritten.forEach(function(args) {
186 + stream.write.apply(stream, args);
187 + });
188 + }
189 +};
190 +
191 +
192 +/**
193 + * Remove a stream from being the destination.
194 + */
195 +Streamify.prototype.removeDest = function() {
196 + if (!this._dest) {
197 + throw Error('A destination stream has not been added.');
198 + }
199 +
200 + var dest = this._dest;
201 + DEST_EVENTS.forEach(function(event) {
202 + dest.stream.removeListener(event, dest.listeners[event]);
203 + });
204 +
205 + delete this._dest;
206 + this._destWritten = [];
207 +};
208 +
209 +
210 +/**
211 + * Begins fueling data from actual stream into Streamify instance.
212 + *
213 + * @param {Readable|Writable|Duplex|Stream} stream
214 + */
215 +Streamify.prototype.resolve = function(stream) {
216 + if (this.__options.readable && stream.readable) {
217 + this.addSource(stream);
218 + }
219 +
220 + if (this.__options.writable && stream.writable) {
221 + this.addDest(stream);
222 + }
223 +};
224 +
225 +
226 +/**
227 + * Removes a stream from this, possibly because another is replacing it.
228 + */
229 +Streamify.prototype.unresolve = function() {
230 + if (this._source) {
231 + this.removeSource();
232 + }
233 +
234 + if (this._dest) {
235 + this.removeDest();
236 + }
237 +};
238 +
239 +
240 +/**
241 + * Returns a readable new stream API stream if the stream is using the
242 + * old API. Otherwise it returns the same stream.
243 + *
244 + * @param {Readable|Stream} stream
245 + * @return {Readable}
246 + */
247 +function getReadable(stream) {
248 + if (isOldStyleStream(stream)) {
249 + var readable = new Readable();
250 + readable.wrap(stream);
251 + return readable;
252 + } else {
253 + return stream;
254 + }
255 +}
256 +
257 +
258 +/**
259 + * Returns true if a stream is an old style API stream.
260 + *
261 + * @param {Readable|Stream} stream
262 + * @return {Boolean}
263 + */
264 +function isOldStyleStream(stream) {
265 + return typeof stream.read !== 'function' ||
266 + typeof stream._read !== 'function' ||
267 + typeof stream.push !== 'function' ||
268 + typeof stream.unshift !== 'function' ||
269 + typeof stream.wrap !== 'function';
270 +}
271 +
272 +
273 +function getConstructor (options) {
274 + var superCtor = Duplex;
275 + if (options.readable && !options.writable) {
276 + superCtor = Readable;
277 + }
278 +
279 + if (options.writable && !options.readable) {
280 + superCtor = Writable;
281 + }
282 +
283 + return superCtor;
284 +}
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "_from": "streamify@~0.2.9",
3 + "_id": "streamify@0.2.9",
4 + "_inBundle": false,
5 + "_integrity": "sha512-8pUxeLEef9UO1FxtTt5iikAiyzGI4SZRnGuJ3sz8axZ5Xk+/7ezEV5kuJQsMEFxw7AKYw3xp0Ow+20mmSaJbQQ==",
6 + "_location": "/streamify",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "streamify@~0.2.9",
12 + "name": "streamify",
13 + "escapedName": "streamify",
14 + "rawSpec": "~0.2.9",
15 + "saveSpec": null,
16 + "fetchSpec": "~0.2.9"
17 + },
18 + "_requiredBy": [
19 + "/youtube-dl"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/streamify/-/streamify-0.2.9.tgz",
22 + "_shasum": "8938b14db491e2b6be4f8d99cc4133c9f0384f0b",
23 + "_spec": "streamify@~0.2.9",
24 + "_where": "C:\\Users\\user\\Desktop\\오소git\\오소플젝\\Youtube_MPL\\node_modules\\youtube-dl",
25 + "author": {
26 + "name": "Roly Fentanes",
27 + "url": "https://github.com/fent"
28 + },
29 + "bugs": {
30 + "url": "https://github.com/fent/node-streamify/issues"
31 + },
32 + "bundleDependencies": false,
33 + "dependencies": {
34 + "hashish": "~0.0.4"
35 + },
36 + "deprecated": false,
37 + "description": "Streamify helps you easily provide a streaming interface for code.",
38 + "devDependencies": {
39 + "istanbul": "*",
40 + "mocha": "*",
41 + "stream-equal": "~1.0.0"
42 + },
43 + "directories": {
44 + "lib": "./lib"
45 + },
46 + "engines": {
47 + "node": ">=0.12"
48 + },
49 + "files": [
50 + "lib"
51 + ],
52 + "homepage": "https://github.com/fent/node-streamify#readme",
53 + "keywords": [
54 + "stream",
55 + "input",
56 + "output",
57 + "api"
58 + ],
59 + "license": "MIT",
60 + "main": "./lib/index.js",
61 + "name": "streamify",
62 + "repository": {
63 + "type": "git",
64 + "url": "git://github.com/fent/node-streamify.git"
65 + },
66 + "scripts": {
67 + "test": "istanbul cover node_modules/.bin/_mocha -- test/*-test.js"
68 + },
69 + "version": "0.2.9"
70 +}
1 +language: node_js
2 +node_js:
3 + - 0.6
1 +Copyright 2010 James Halliday (mail@substack.net)
2 +
3 +This project is free software released under the MIT/X11 license:
4 +http://www.opensource.org/licenses/mit-license.php
5 +
6 +Copyright 2010 James Halliday (mail@substack.net)
7 +
8 +Permission is hereby granted, free of charge, to any person obtaining a copy
9 +of this software and associated documentation files (the "Software"), to deal
10 +in the Software without restriction, including without limitation the rights
11 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 +copies of the Software, and to permit persons to whom the Software is
13 +furnished to do so, subject to the following conditions:
14 +
15 +The above copyright notice and this permission notice shall be included in
16 +all copies or substantial portions of the Software.
17 +
18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 +THE SOFTWARE.
1 +var traverse = require('traverse');
2 +
3 +var id = 54;
4 +var callbacks = {};
5 +var obj = { moo : function () {}, foo : [2,3,4, function () {}] };
6 +
7 +var scrubbed = traverse(obj).map(function (x) {
8 + if (typeof x === 'function') {
9 + callbacks[id] = { id : id, f : x, path : this.path };
10 + this.update('[Function]');
11 + id++;
12 + }
13 +});
14 +
15 +console.dir(scrubbed);
16 +console.dir(callbacks);
1 +var traverse = require('traverse');
2 +
3 +var obj = {
4 + a : [1,2,3],
5 + b : 4,
6 + c : [5,6],
7 + d : { e : [7,8], f : 9 },
8 +};
9 +
10 +var leaves = traverse(obj).reduce(function (acc, x) {
11 + if (this.isLeaf) acc.push(x);
12 + return acc;
13 +}, []);
14 +
15 +console.dir(leaves);
1 +var traverse = require('traverse');
2 +var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];
3 +
4 +traverse(obj).forEach(function (x) {
5 + if (x < 0) this.update(x + 128);
6 +});
7 +
8 +console.dir(obj);
1 +// scrub out circular references
2 +var traverse = require('traverse');
3 +
4 +var obj = { a : 1, b : 2, c : [ 3, 4 ] };
5 +obj.c.push(obj);
6 +
7 +var scrubbed = traverse(obj).map(function (x) {
8 + if (this.circular) this.remove()
9 +});
10 +console.dir(scrubbed);
1 +#!/usr/bin/env node
2 +var traverse = require('traverse');
3 +
4 +var obj = [ 'five', 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];
5 +
6 +var s = '';
7 +traverse(obj).forEach(function to_s (node) {
8 + if (Array.isArray(node)) {
9 + this.before(function () { s += '[' });
10 + this.post(function (child) {
11 + if (!child.isLast) s += ',';
12 + });
13 + this.after(function () { s += ']' });
14 + }
15 + else if (typeof node == 'object') {
16 + this.before(function () { s += '{' });
17 + this.pre(function (x, key) {
18 + to_s(key);
19 + s += ':';
20 + });
21 + this.post(function (child) {
22 + if (!child.isLast) s += ',';
23 + });
24 + this.after(function () { s += '}' });
25 + }
26 + else if (typeof node == 'string') {
27 + s += '"' + node.toString().replace(/"/g, '\\"') + '"';
28 + }
29 + else if (typeof node == 'function') {
30 + s += 'null';
31 + }
32 + else {
33 + s += node.toString();
34 + }
35 +});
36 +
37 +console.log('JSON.stringify: ' + JSON.stringify(obj));
38 +console.log('this stringify: ' + s);
1 +var traverse = module.exports = function (obj) {
2 + return new Traverse(obj);
3 +};
4 +
5 +function Traverse (obj) {
6 + this.value = obj;
7 +}
8 +
9 +Traverse.prototype.get = function (ps) {
10 + var node = this.value;
11 + for (var i = 0; i < ps.length; i ++) {
12 + var key = ps[i];
13 + if (!node || !hasOwnProperty.call(node, key)) {
14 + node = undefined;
15 + break;
16 + }
17 + node = node[key];
18 + }
19 + return node;
20 +};
21 +
22 +Traverse.prototype.has = function (ps) {
23 + var node = this.value;
24 + for (var i = 0; i < ps.length; i ++) {
25 + var key = ps[i];
26 + if (!node || !hasOwnProperty.call(node, key)) {
27 + return false;
28 + }
29 + node = node[key];
30 + }
31 + return true;
32 +};
33 +
34 +Traverse.prototype.set = function (ps, value) {
35 + var node = this.value;
36 + for (var i = 0; i < ps.length - 1; i ++) {
37 + var key = ps[i];
38 + if (!hasOwnProperty.call(node, key)) node[key] = {};
39 + node = node[key];
40 + }
41 + node[ps[i]] = value;
42 + return value;
43 +};
44 +
45 +Traverse.prototype.map = function (cb) {
46 + return walk(this.value, cb, true);
47 +};
48 +
49 +Traverse.prototype.forEach = function (cb) {
50 + this.value = walk(this.value, cb, false);
51 + return this.value;
52 +};
53 +
54 +Traverse.prototype.reduce = function (cb, init) {
55 + var skip = arguments.length === 1;
56 + var acc = skip ? this.value : init;
57 + this.forEach(function (x) {
58 + if (!this.isRoot || !skip) {
59 + acc = cb.call(this, acc, x);
60 + }
61 + });
62 + return acc;
63 +};
64 +
65 +Traverse.prototype.paths = function () {
66 + var acc = [];
67 + this.forEach(function (x) {
68 + acc.push(this.path);
69 + });
70 + return acc;
71 +};
72 +
73 +Traverse.prototype.nodes = function () {
74 + var acc = [];
75 + this.forEach(function (x) {
76 + acc.push(this.node);
77 + });
78 + return acc;
79 +};
80 +
81 +Traverse.prototype.clone = function () {
82 + var parents = [], nodes = [];
83 +
84 + return (function clone (src) {
85 + for (var i = 0; i < parents.length; i++) {
86 + if (parents[i] === src) {
87 + return nodes[i];
88 + }
89 + }
90 +
91 + if (typeof src === 'object' && src !== null) {
92 + var dst = copy(src);
93 +
94 + parents.push(src);
95 + nodes.push(dst);
96 +
97 + forEach(objectKeys(src), function (key) {
98 + dst[key] = clone(src[key]);
99 + });
100 +
101 + parents.pop();
102 + nodes.pop();
103 + return dst;
104 + }
105 + else {
106 + return src;
107 + }
108 + })(this.value);
109 +};
110 +
111 +function walk (root, cb, immutable) {
112 + var path = [];
113 + var parents = [];
114 + var alive = true;
115 +
116 + return (function walker (node_) {
117 + var node = immutable ? copy(node_) : node_;
118 + var modifiers = {};
119 +
120 + var keepGoing = true;
121 +
122 + var state = {
123 + node : node,
124 + node_ : node_,
125 + path : [].concat(path),
126 + parent : parents[parents.length - 1],
127 + parents : parents,
128 + key : path.slice(-1)[0],
129 + isRoot : path.length === 0,
130 + level : path.length,
131 + circular : null,
132 + update : function (x, stopHere) {
133 + if (!state.isRoot) {
134 + state.parent.node[state.key] = x;
135 + }
136 + state.node = x;
137 + if (stopHere) keepGoing = false;
138 + },
139 + 'delete' : function (stopHere) {
140 + delete state.parent.node[state.key];
141 + if (stopHere) keepGoing = false;
142 + },
143 + remove : function (stopHere) {
144 + if (isArray(state.parent.node)) {
145 + state.parent.node.splice(state.key, 1);
146 + }
147 + else {
148 + delete state.parent.node[state.key];
149 + }
150 + if (stopHere) keepGoing = false;
151 + },
152 + keys : null,
153 + before : function (f) { modifiers.before = f },
154 + after : function (f) { modifiers.after = f },
155 + pre : function (f) { modifiers.pre = f },
156 + post : function (f) { modifiers.post = f },
157 + stop : function () { alive = false },
158 + block : function () { keepGoing = false }
159 + };
160 +
161 + if (!alive) return state;
162 +
163 + function updateState() {
164 + if (typeof state.node === 'object' && state.node !== null) {
165 + if (!state.keys || state.node_ !== state.node) {
166 + state.keys = objectKeys(state.node)
167 + }
168 +
169 + state.isLeaf = state.keys.length == 0;
170 +
171 + for (var i = 0; i < parents.length; i++) {
172 + if (parents[i].node_ === node_) {
173 + state.circular = parents[i];
174 + break;
175 + }
176 + }
177 + }
178 + else {
179 + state.isLeaf = true;
180 + state.keys = null;
181 + }
182 +
183 + state.notLeaf = !state.isLeaf;
184 + state.notRoot = !state.isRoot;
185 + }
186 +
187 + updateState();
188 +
189 + // use return values to update if defined
190 + var ret = cb.call(state, state.node);
191 + if (ret !== undefined && state.update) state.update(ret);
192 +
193 + if (modifiers.before) modifiers.before.call(state, state.node);
194 +
195 + if (!keepGoing) return state;
196 +
197 + if (typeof state.node == 'object'
198 + && state.node !== null && !state.circular) {
199 + parents.push(state);
200 +
201 + updateState();
202 +
203 + forEach(state.keys, function (key, i) {
204 + path.push(key);
205 +
206 + if (modifiers.pre) modifiers.pre.call(state, state.node[key], key);
207 +
208 + var child = walker(state.node[key]);
209 + if (immutable && hasOwnProperty.call(state.node, key)) {
210 + state.node[key] = child.node;
211 + }
212 +
213 + child.isLast = i == state.keys.length - 1;
214 + child.isFirst = i == 0;
215 +
216 + if (modifiers.post) modifiers.post.call(state, child);
217 +
218 + path.pop();
219 + });
220 + parents.pop();
221 + }
222 +
223 + if (modifiers.after) modifiers.after.call(state, state.node);
224 +
225 + return state;
226 + })(root).node;
227 +}
228 +
229 +function copy (src) {
230 + if (typeof src === 'object' && src !== null) {
231 + var dst;
232 +
233 + if (isArray(src)) {
234 + dst = [];
235 + }
236 + else if (isDate(src)) {
237 + dst = new Date(src.getTime ? src.getTime() : src);
238 + }
239 + else if (isRegExp(src)) {
240 + dst = new RegExp(src);
241 + }
242 + else if (isError(src)) {
243 + dst = { message: src.message };
244 + }
245 + else if (isBoolean(src)) {
246 + dst = new Boolean(src);
247 + }
248 + else if (isNumber(src)) {
249 + dst = new Number(src);
250 + }
251 + else if (isString(src)) {
252 + dst = new String(src);
253 + }
254 + else if (Object.create && Object.getPrototypeOf) {
255 + dst = Object.create(Object.getPrototypeOf(src));
256 + }
257 + else if (src.constructor === Object) {
258 + dst = {};
259 + }
260 + else {
261 + var proto =
262 + (src.constructor && src.constructor.prototype)
263 + || src.__proto__
264 + || {}
265 + ;
266 + var T = function () {};
267 + T.prototype = proto;
268 + dst = new T;
269 + }
270 +
271 + forEach(objectKeys(src), function (key) {
272 + dst[key] = src[key];
273 + });
274 + return dst;
275 + }
276 + else return src;
277 +}
278 +
279 +var objectKeys = Object.keys || function keys (obj) {
280 + var res = [];
281 + for (var key in obj) res.push(key)
282 + return res;
283 +};
284 +
285 +function toS (obj) { return Object.prototype.toString.call(obj) }
286 +function isDate (obj) { return toS(obj) === '[object Date]' }
287 +function isRegExp (obj) { return toS(obj) === '[object RegExp]' }
288 +function isError (obj) { return toS(obj) === '[object Error]' }
289 +function isBoolean (obj) { return toS(obj) === '[object Boolean]' }
290 +function isNumber (obj) { return toS(obj) === '[object Number]' }
291 +function isString (obj) { return toS(obj) === '[object String]' }
292 +
293 +var isArray = Array.isArray || function isArray (xs) {
294 + return Object.prototype.toString.call(xs) === '[object Array]';
295 +};
296 +
297 +var forEach = function (xs, fn) {
298 + if (xs.forEach) return xs.forEach(fn)
299 + else for (var i = 0; i < xs.length; i++) {
300 + fn(xs[i], i, xs);
301 + }
302 +};
303 +
304 +forEach(objectKeys(Traverse.prototype), function (key) {
305 + traverse[key] = function (obj) {
306 + var args = [].slice.call(arguments, 1);
307 + var t = new Traverse(obj);
308 + return t[key].apply(t, args);
309 + };
310 +});
311 +
312 +var hasOwnProperty = Object.hasOwnProperty || function (obj, key) {
313 + return key in obj;
314 +};
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
No preview for this file type
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.