| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 | var Stream = require("stream")var writeMethods = ["write", "end", "destroy"]var readMethods = ["resume", "pause"]var readEvents = ["data", "close"]var slice = Array.prototype.slicemodule.exports = duplexfunction forEach (arr, fn) {    if (arr.forEach) {        return arr.forEach(fn)    }    for (var i = 0; i < arr.length; i++) {        fn(arr[i], i)    }}function duplex(writer, reader) {    var stream = new Stream()    var ended = false    forEach(writeMethods, proxyWriter)    forEach(readMethods, proxyReader)    forEach(readEvents, proxyStream)    reader.on("end", handleEnd)    writer.on("drain", function() {      stream.emit("drain")    })    writer.on("error", reemit)    reader.on("error", reemit)    stream.writable = writer.writable    stream.readable = reader.readable    return stream    function proxyWriter(methodName) {        stream[methodName] = method        function method() {            return writer[methodName].apply(writer, arguments)        }    }    function proxyReader(methodName) {        stream[methodName] = method        function method() {            stream.emit(methodName)            var func = reader[methodName]            if (func) {                return func.apply(reader, arguments)            }            reader.emit(methodName)        }    }    function proxyStream(methodName) {        reader.on(methodName, reemit)        function reemit() {            var args = slice.call(arguments)            args.unshift(methodName)            stream.emit.apply(stream, args)        }    }    function handleEnd() {        if (ended) {            return        }        ended = true        var args = slice.call(arguments)        args.unshift("end")        stream.emit.apply(stream, args)    }    function reemit(err) {        stream.emit("error", err)    }}
 |