| 'use strict' |
| |
| // A derivative work based on: |
| // <https://github.com/browserify/path-browserify>. |
| // Which is licensed: |
| // |
| // MIT License |
| // |
| // Copyright (c) 2013 James Halliday |
| // |
| // Permission is hereby granted, free of charge, to any person obtaining a copy of |
| // this software and associated documentation files (the "Software"), to deal in |
| // the Software without restriction, including without limitation the rights to |
| // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
| // the Software, and to permit persons to whom the Software is furnished to do so, |
| // subject to the following conditions: |
| // |
| // The above copyright notice and this permission notice shall be included in all |
| // copies or substantial portions of the Software. |
| // |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
| // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
| // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
| // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| // A derivative work based on: |
| // |
| // Parts of that are extracted from Node’s internal `path` module: |
| // <https://github.com/nodejs/node/blob/master/lib/path.js>. |
| // Which is licensed: |
| // |
| // Copyright Joyent, Inc. and other Node contributors. |
| // |
| // Permission is hereby granted, free of charge, to any person obtaining a |
| // copy of this software and associated documentation files (the |
| // "Software"), to deal in the Software without restriction, including |
| // without limitation the rights to use, copy, modify, merge, publish, |
| // distribute, sublicense, and/or sell copies of the Software, and to permit |
| // persons to whom the Software is furnished to do so, subject to the |
| // following conditions: |
| // |
| // The above copyright notice and this permission notice shall be included |
| // in all copies or substantial portions of the Software. |
| // |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN |
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
| // USE OR OTHER DEALINGS IN THE SOFTWARE. |
| |
| exports.basename = basename |
| exports.dirname = dirname |
| exports.extname = extname |
| exports.join = join |
| exports.sep = '/' |
| |
| function basename(path, ext) { |
| var start = 0 |
| var end = -1 |
| var index |
| var firstNonSlashEnd |
| var seenNonSlash |
| var extIndex |
| |
| if (ext !== undefined && typeof ext !== 'string') { |
| throw new TypeError('"ext" argument must be a string') |
| } |
| |
| assertPath(path) |
| index = path.length |
| |
| if (ext === undefined || !ext.length || ext.length > path.length) { |
| while (index--) { |
| if (path.charCodeAt(index) === 47 /* `/` */) { |
| // If we reached a path separator that was not part of a set of path |
| // separators at the end of the string, stop now. |
| if (seenNonSlash) { |
| start = index + 1 |
| break |
| } |
| } else if (end < 0) { |
| // We saw the first non-path separator, mark this as the end of our |
| // path component. |
| seenNonSlash = true |
| end = index + 1 |
| } |
| } |
| |
| return end < 0 ? '' : path.slice(start, end) |
| } |
| |
| if (ext === path) { |
| return '' |
| } |
| |
| firstNonSlashEnd = -1 |
| extIndex = ext.length - 1 |
| |
| while (index--) { |
| if (path.charCodeAt(index) === 47 /* `/` */) { |
| // If we reached a path separator that was not part of a set of path |
| // separators at the end of the string, stop now. |
| if (seenNonSlash) { |
| start = index + 1 |
| break |
| } |
| } else { |
| if (firstNonSlashEnd < 0) { |
| // We saw the first non-path separator, remember this index in case |
| // we need it if the extension ends up not matching. |
| seenNonSlash = true |
| firstNonSlashEnd = index + 1 |
| } |
| |
| if (extIndex > -1) { |
| // Try to match the explicit extension. |
| if (path.charCodeAt(index) === ext.charCodeAt(extIndex--)) { |
| if (extIndex < 0) { |
| // We matched the extension, so mark this as the end of our path |
| // component |
| end = index |
| } |
| } else { |
| // Extension does not match, so our result is the entire path |
| // component |
| extIndex = -1 |
| end = firstNonSlashEnd |
| } |
| } |
| } |
| } |
| |
| if (start === end) { |
| end = firstNonSlashEnd |
| } else if (end < 0) { |
| end = path.length |
| } |
| |
| return path.slice(start, end) |
| } |
| |
| function dirname(path) { |
| var end |
| var unmatchedSlash |
| var index |
| |
| assertPath(path) |
| |
| if (!path.length) { |
| return '.' |
| } |
| |
| end = -1 |
| index = path.length |
| |
| // Prefix `--` is important to not run on `0`. |
| while (--index) { |
| if (path.charCodeAt(index) === 47 /* `/` */) { |
| if (unmatchedSlash) { |
| end = index |
| break |
| } |
| } else if (!unmatchedSlash) { |
| // We saw the first non-path separator |
| unmatchedSlash = true |
| } |
| } |
| |
| return end < 0 |
| ? path.charCodeAt(0) === 47 /* `/` */ |
| ? '/' |
| : '.' |
| : end === 1 && path.charCodeAt(0) === 47 /* `/` */ |
| ? '//' |
| : path.slice(0, end) |
| } |
| |
| function extname(path) { |
| var startDot = -1 |
| var startPart = 0 |
| var end = -1 |
| // Track the state of characters (if any) we see before our first dot and |
| // after any path separator we find. |
| var preDotState = 0 |
| var unmatchedSlash |
| var code |
| var index |
| |
| assertPath(path) |
| |
| index = path.length |
| |
| while (index--) { |
| code = path.charCodeAt(index) |
| |
| if (code === 47 /* `/` */) { |
| // If we reached a path separator that was not part of a set of path |
| // separators at the end of the string, stop now. |
| if (unmatchedSlash) { |
| startPart = index + 1 |
| break |
| } |
| |
| continue |
| } |
| |
| if (end < 0) { |
| // We saw the first non-path separator, mark this as the end of our |
| // extension. |
| unmatchedSlash = true |
| end = index + 1 |
| } |
| |
| if (code === 46 /* `.` */) { |
| // If this is our first dot, mark it as the start of our extension. |
| if (startDot < 0) { |
| startDot = index |
| } else if (preDotState !== 1) { |
| preDotState = 1 |
| } |
| } else if (startDot > -1) { |
| // We saw a non-dot and non-path separator before our dot, so we should |
| // have a good chance at having a non-empty extension. |
| preDotState = -1 |
| } |
| } |
| |
| if ( |
| startDot < 0 || |
| end < 0 || |
| // We saw a non-dot character immediately before the dot. |
| preDotState === 0 || |
| // The (right-most) trimmed path component is exactly `..`. |
| (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) |
| ) { |
| return '' |
| } |
| |
| return path.slice(startDot, end) |
| } |
| |
| function join() { |
| var index = -1 |
| var joined |
| |
| while (++index < arguments.length) { |
| assertPath(arguments[index]) |
| |
| if (arguments[index]) { |
| joined = |
| joined === undefined |
| ? arguments[index] |
| : joined + '/' + arguments[index] |
| } |
| } |
| |
| return joined === undefined ? '.' : normalize(joined) |
| } |
| |
| // Note: `normalize` is not exposed as `path.normalize`, so some code is |
| // manually removed from it. |
| function normalize(path) { |
| var absolute |
| var value |
| |
| assertPath(path) |
| |
| absolute = path.charCodeAt(0) === 47 /* `/` */ |
| |
| // Normalize the path according to POSIX rules. |
| value = normalizeString(path, !absolute) |
| |
| if (!value.length && !absolute) { |
| value = '.' |
| } |
| |
| if (value.length && path.charCodeAt(path.length - 1) === 47 /* / */) { |
| value += '/' |
| } |
| |
| return absolute ? '/' + value : value |
| } |
| |
| // Resolve `.` and `..` elements in a path with directory names. |
| function normalizeString(path, allowAboveRoot) { |
| var result = '' |
| var lastSegmentLength = 0 |
| var lastSlash = -1 |
| var dots = 0 |
| var index = -1 |
| var code |
| var lastSlashIndex |
| |
| while (++index <= path.length) { |
| if (index < path.length) { |
| code = path.charCodeAt(index) |
| } else if (code === 47 /* `/` */) { |
| break |
| } else { |
| code = 47 /* `/` */ |
| } |
| |
| if (code === 47 /* `/` */) { |
| if (lastSlash === index - 1 || dots === 1) { |
| // Empty. |
| } else if (lastSlash !== index - 1 && dots === 2) { |
| if ( |
| result.length < 2 || |
| lastSegmentLength !== 2 || |
| result.charCodeAt(result.length - 1) !== 46 /* `.` */ || |
| result.charCodeAt(result.length - 2) !== 46 /* `.` */ |
| ) { |
| if (result.length > 2) { |
| lastSlashIndex = result.lastIndexOf('/') |
| |
| /* istanbul ignore else - No clue how to cover it. */ |
| if (lastSlashIndex !== result.length - 1) { |
| if (lastSlashIndex < 0) { |
| result = '' |
| lastSegmentLength = 0 |
| } else { |
| result = result.slice(0, lastSlashIndex) |
| lastSegmentLength = result.length - 1 - result.lastIndexOf('/') |
| } |
| |
| lastSlash = index |
| dots = 0 |
| continue |
| } |
| } else if (result.length) { |
| result = '' |
| lastSegmentLength = 0 |
| lastSlash = index |
| dots = 0 |
| continue |
| } |
| } |
| |
| if (allowAboveRoot) { |
| result = result.length ? result + '/..' : '..' |
| lastSegmentLength = 2 |
| } |
| } else { |
| if (result.length) { |
| result += '/' + path.slice(lastSlash + 1, index) |
| } else { |
| result = path.slice(lastSlash + 1, index) |
| } |
| |
| lastSegmentLength = index - lastSlash - 1 |
| } |
| |
| lastSlash = index |
| dots = 0 |
| } else if (code === 46 /* `.` */ && dots > -1) { |
| dots++ |
| } else { |
| dots = -1 |
| } |
| } |
| |
| return result |
| } |
| |
| function assertPath(path) { |
| if (typeof path !== 'string') { |
| throw new TypeError( |
| 'Path must be a string. Received ' + JSON.stringify(path) |
| ) |
| } |
| } |