1var DEFAULTS = {
2  '*': {
3    colors: {
4      opacity: true // rgba / hsla
5    },
6    properties: {
7      backgroundClipMerging: true, // background-clip to shorthand
8      backgroundOriginMerging: true, // background-origin to shorthand
9      backgroundSizeMerging: true, // background-size to shorthand
10      colors: true, // any kind of color transformations, like `#ff00ff` to `#f0f` or `#fff` into `red`
11      ieBangHack: false, // !ie suffix hacks on IE<8
12      ieFilters: false, // whether to preserve `filter` and `-ms-filter` properties
13      iePrefixHack: false, // underscore / asterisk prefix hacks on IE
14      ieSuffixHack: false, // \9 suffix hacks on IE6-9
15      merging: true, // merging properties into one
16      shorterLengthUnits: false, // optimize pixel units into `pt`, `pc` or `in` units
17      spaceAfterClosingBrace: true, // 'url() no-repeat' to 'url()no-repeat'
18      urlQuotes: false, // whether to wrap content of `url()` into quotes or not
19      zeroUnits: true // 0[unit] -> 0
20    },
21    selectors: {
22      adjacentSpace: false, // div+ nav Android stock browser hack
23      ie7Hack: false, // *+html hack
24      mergeablePseudoClasses: [
25        ':active',
26        ':after',
27        ':before',
28        ':empty',
29        ':checked',
30        ':disabled',
31        ':empty',
32        ':enabled',
33        ':first-child',
34        ':first-letter',
35        ':first-line',
36        ':first-of-type',
37        ':focus',
38        ':hover',
39        ':lang',
40        ':last-child',
41        ':last-of-type',
42        ':link',
43        ':not',
44        ':nth-child',
45        ':nth-last-child',
46        ':nth-last-of-type',
47        ':nth-of-type',
48        ':only-child',
49        ':only-of-type',
50        ':root',
51        ':target',
52        ':visited'
53      ], // selectors with these pseudo-classes can be merged as these are universally supported
54      mergeablePseudoElements: [
55        '::after',
56        '::before',
57        '::first-letter',
58        '::first-line'
59      ], // selectors with these pseudo-elements can be merged as these are universally supported
60      mergeLimit: 8191, // number of rules that can be safely merged together
61      multiplePseudoMerging: true
62    },
63    units: {
64      ch: true,
65      in: true,
66      pc: true,
67      pt: true,
68      rem: true,
69      vh: true,
70      vm: true, // vm is vmin on IE9+ see https://developer.mozilla.org/en-US/docs/Web/CSS/length
71      vmax: true,
72      vmin: true,
73      vw: true
74    }
75  }
76};
77
78DEFAULTS.ie11 = DEFAULTS['*'];
79
80DEFAULTS.ie10 = DEFAULTS['*'];
81
82DEFAULTS.ie9 = merge(DEFAULTS['*'], {
83  properties: {
84    ieFilters: true,
85    ieSuffixHack: true
86  }
87});
88
89DEFAULTS.ie8 = merge(DEFAULTS.ie9, {
90  colors: {
91    opacity: false
92  },
93  properties: {
94    backgroundClipMerging: false,
95    backgroundOriginMerging: false,
96    backgroundSizeMerging: false,
97    iePrefixHack: true,
98    merging: false
99  },
100  selectors: {
101    mergeablePseudoClasses: [
102      ':after',
103      ':before',
104      ':first-child',
105      ':first-letter',
106      ':focus',
107      ':hover',
108      ':visited'
109    ],
110    mergeablePseudoElements: []
111  },
112  units: {
113    ch: false,
114    rem: false,
115    vh: false,
116    vm: false,
117    vmax: false,
118    vmin: false,
119    vw: false
120  }
121});
122
123DEFAULTS.ie7 = merge(DEFAULTS.ie8, {
124  properties: {
125    ieBangHack: true
126  },
127  selectors: {
128    ie7Hack: true,
129    mergeablePseudoClasses: [
130      ':first-child',
131      ':first-letter',
132      ':hover',
133      ':visited'
134    ]
135  },
136});
137
138function compatibilityFrom(source) {
139  return merge(DEFAULTS['*'], calculateSource(source));
140}
141
142function merge(source, target) {
143  for (var key in source) {
144    if (Object.prototype.hasOwnProperty.call(source, key)) {
145      var value = source[key];
146
147      if (Object.prototype.hasOwnProperty.call(target, key) && typeof value === 'object' && !Array.isArray(value)) {
148        target[key] = merge(value, target[key] || {});
149      } else {
150        target[key] = key in target ? target[key] : value;
151      }
152    }
153  }
154
155  return target;
156}
157
158function calculateSource(source) {
159  if (typeof source == 'object')
160    return source;
161
162  if (!/[,\+\-]/.test(source))
163    return DEFAULTS[source] || DEFAULTS['*'];
164
165  var parts = source.split(',');
166  var template = parts[0] in DEFAULTS ?
167    DEFAULTS[parts.shift()] :
168    DEFAULTS['*'];
169
170  source = {};
171
172  parts.forEach(function (part) {
173    var isAdd = part[0] == '+';
174    var key = part.substring(1).split('.');
175    var group = key[0];
176    var option = key[1];
177
178    source[group] = source[group] || {};
179    source[group][option] = isAdd;
180  });
181
182  return merge(template, source);
183}
184
185module.exports = compatibilityFrom;
186