|  | 'use strict'; | 
|  |  | 
|  | /** | 
|  | * @param typeMap [Object] Map of MIME type -> Array[extensions] | 
|  | * @param ... | 
|  | */ | 
|  | function Mime() { | 
|  | this._types = Object.create(null); | 
|  | this._extensions = Object.create(null); | 
|  |  | 
|  | for (var i = 0; i < arguments.length; i++) { | 
|  | this.define(arguments[i]); | 
|  | } | 
|  |  | 
|  | this.define = this.define.bind(this); | 
|  | this.getType = this.getType.bind(this); | 
|  | this.getExtension = this.getExtension.bind(this); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Define mimetype -> extension mappings.  Each key is a mime-type that maps | 
|  | * to an array of extensions associated with the type.  The first extension is | 
|  | * used as the default extension for the type. | 
|  | * | 
|  | * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']}); | 
|  | * | 
|  | * If a type declares an extension that has already been defined, an error will | 
|  | * be thrown.  To suppress this error and force the extension to be associated | 
|  | * with the new type, pass `force`=true.  Alternatively, you may prefix the | 
|  | * extension with "*" to map the type to extension, without mapping the | 
|  | * extension to the type. | 
|  | * | 
|  | * e.g. mime.define({'audio/wav', ['wav']}, {'audio/x-wav', ['*wav']}); | 
|  | * | 
|  | * | 
|  | * @param map (Object) type definitions | 
|  | * @param force (Boolean) if true, force overriding of existing definitions | 
|  | */ | 
|  | Mime.prototype.define = function(typeMap, force) { | 
|  | for (var type in typeMap) { | 
|  | var extensions = typeMap[type].map(function(t) {return t.toLowerCase()}); | 
|  | type = type.toLowerCase(); | 
|  |  | 
|  | for (var i = 0; i < extensions.length; i++) { | 
|  | var ext = extensions[i]; | 
|  |  | 
|  | // '*' prefix = not the preferred type for this extension.  So fixup the | 
|  | // extension, and skip it. | 
|  | if (ext[0] == '*') { | 
|  | continue; | 
|  | } | 
|  |  | 
|  | if (!force && (ext in this._types)) { | 
|  | throw new Error( | 
|  | 'Attempt to change mapping for "' + ext + | 
|  | '" extension from "' + this._types[ext] + '" to "' + type + | 
|  | '". Pass `force=true` to allow this, otherwise remove "' + ext + | 
|  | '" from the list of extensions for "' + type + '".' | 
|  | ); | 
|  | } | 
|  |  | 
|  | this._types[ext] = type; | 
|  | } | 
|  |  | 
|  | // Use first extension as default | 
|  | if (force || !this._extensions[type]) { | 
|  | var ext = extensions[0]; | 
|  | this._extensions[type] = (ext[0] != '*') ? ext : ext.substr(1) | 
|  | } | 
|  | } | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * Lookup a mime type based on extension | 
|  | */ | 
|  | Mime.prototype.getType = function(path) { | 
|  | path = String(path); | 
|  | var last = path.replace(/^.*[/\\]/, '').toLowerCase(); | 
|  | var ext = last.replace(/^.*\./, '').toLowerCase(); | 
|  |  | 
|  | var hasPath = last.length < path.length; | 
|  | var hasDot = ext.length < last.length - 1; | 
|  |  | 
|  | return (hasDot || !hasPath) && this._types[ext] || null; | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * Return file extension associated with a mime type | 
|  | */ | 
|  | Mime.prototype.getExtension = function(type) { | 
|  | type = /^\s*([^;\s]*)/.test(type) && RegExp.$1; | 
|  | return type && this._extensions[type.toLowerCase()] || null; | 
|  | }; | 
|  |  | 
|  | module.exports = Mime; |