Name: js-handler/node_modules/restify/node_modules/negotiator/lib/language.js 
1:
module.exports = preferredLanguages;
2:
preferredLanguages.preferredLanguages = preferredLanguages;
3:
 
4:
function parseAcceptLanguage(accept) {
5:
  return accept.split(',').map(function(e) {
6:
    return parseLanguage(e.trim());
7:
  }).filter(function(e) {
8:
    return e && e.q > 0;
9:
  });
10:
}
11:
 
12:
function parseLanguage(s) {
13:
  var match = s.match(/^\s*(\S+?)(?:-(\S+?))?\s*(?:;(.*))?$/);
14:
  if (!match) return null;
15:
 
16:
  var prefix = match[1],
17:
      suffix = match[2],
18:
      full = prefix;
19:
 
20:
  if (suffix) full += "-" + suffix;
21:
 
22:
  var q = 1;
23:
  if (match[3]) {
24:
    var params = match[3].split(';')
25:
    for (var i = 0; i < params.length; i ++) {
26:
      var p = params[i].split('=');
27:
      if (p[0] === 'q') q = parseFloat(p[1]);
28:
    }
29:
  }
30:
 
31:
  return {
32:
    prefix: prefix,
33:
    suffix: suffix,
34:
    q: q,
35:
    full: full
36:
  };
37:
}
38:
 
39:
function getLanguagePriority(language, accepted) {
40:
  var match = getClosestMatch(language, accepted);
41:
  return match ? match.q : 0;
42:
}
43:
 
44:
function getClosestMatch(language, accepted) {
45:
  var parsed = parseLanguage(language);
46:
 
47:
  var matches = accepted.filter(function(a) {
48:
    return a.full === parsed.full;
49:
  });
50:
  if (matches.length) return matches[0];
51:
 
52:
  matches = accepted.filter(function(a) {
53:
    return a.prefix === parsed.prefix && !a.suffix;
54:
  });
55:
  if (matches.length) return matches[0];
56:
 
57:
  matches = accepted.filter(function(a) {
58:
    return a.prefix === parsed.prefix;
59:
  });
60:
  if (matches.length) return matches[0];
61:
 
62:
  matches = accepted.filter(function(a) {
63:
    return a.prefix === '*';
64:
  });
65:
  return matches[0];
66:
}
67:
 
68:
function preferredLanguages(accept, provided) {
69:
  accept = parseAcceptLanguage(accept || '');
70:
  if (provided) {
71:
 
72:
    var ret = provided.map(function(type) {
73:
      return [type, getLanguagePriority(type, accept)];
74:
    }).filter(function(pair) {
75:
      return pair[1] > 0;
76:
    }).sort(function(a, b) {
77:
      // revsort
78:
      return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1;
79:
    }).map(function(pair) {
80:
      return pair[0];
81:
    });
82:
    return ret;
83:
 
84:
  } else {
85:
    return accept.map(function(type) {
86:
      return type.full;
87:
    });
88:
  }
89:
}