| var canReorder = require('./reorderable').canReorder; | 
| var extractProperties = require('./extract-properties'); | 
|   | 
| var optimizeProperties = require('./properties/optimize'); | 
|   | 
| var serializeRules = require('../../writer/one-time').rules; | 
|   | 
| var Token = require('../../tokenizer/token'); | 
|   | 
| function mergeNonAdjacentBySelector(tokens, context) { | 
|   var specificityCache = context.cache.specificity; | 
|   var allSelectors = {}; | 
|   var repeatedSelectors = []; | 
|   var i; | 
|   | 
|   for (i = tokens.length - 1; i >= 0; i--) { | 
|     if (tokens[i][0] != Token.RULE) | 
|       continue; | 
|     if (tokens[i][2].length === 0) | 
|       continue; | 
|   | 
|     var selector = serializeRules(tokens[i][1]); | 
|     allSelectors[selector] = [i].concat(allSelectors[selector] || []); | 
|   | 
|     if (allSelectors[selector].length == 2) | 
|       repeatedSelectors.push(selector); | 
|   } | 
|   | 
|   for (i = repeatedSelectors.length - 1; i >= 0; i--) { | 
|     var positions = allSelectors[repeatedSelectors[i]]; | 
|   | 
|     selectorIterator: | 
|     for (var j = positions.length - 1; j > 0; j--) { | 
|       var positionOne = positions[j - 1]; | 
|       var tokenOne = tokens[positionOne]; | 
|       var positionTwo = positions[j]; | 
|       var tokenTwo = tokens[positionTwo]; | 
|   | 
|       directionIterator: | 
|       for (var direction = 1; direction >= -1; direction -= 2) { | 
|         var topToBottom = direction == 1; | 
|         var from = topToBottom ? positionOne + 1 : positionTwo - 1; | 
|         var to = topToBottom ? positionTwo : positionOne; | 
|         var delta = topToBottom ? 1 : -1; | 
|         var moved = topToBottom ? tokenOne : tokenTwo; | 
|         var target = topToBottom ? tokenTwo : tokenOne; | 
|         var movedProperties = extractProperties(moved); | 
|   | 
|         while (from != to) { | 
|           var traversedProperties = extractProperties(tokens[from]); | 
|           from += delta; | 
|   | 
|           // traversed then moved as we move selectors towards the start | 
|           var reorderable = topToBottom ? | 
|             canReorder(movedProperties, traversedProperties, specificityCache) : | 
|             canReorder(traversedProperties, movedProperties, specificityCache); | 
|   | 
|           if (!reorderable && !topToBottom) | 
|             continue selectorIterator; | 
|           if (!reorderable && topToBottom) | 
|             continue directionIterator; | 
|         } | 
|   | 
|         if (topToBottom) { | 
|           Array.prototype.push.apply(moved[2], target[2]); | 
|           target[2] = moved[2]; | 
|         } else { | 
|           Array.prototype.push.apply(target[2], moved[2]); | 
|         } | 
|   | 
|         optimizeProperties(target[2], true, true, context); | 
|         moved[2] = []; | 
|       } | 
|     } | 
|   } | 
| } | 
|   | 
| module.exports = mergeNonAdjacentBySelector; |