| 1 | var SPACE = /\s/ |
| 2 | |
| 3 | function endsWithOperator(block) { |
| 4 | // Scan the suffix once rather than backtracking over long whitespace runs. |
| 5 | var end = block.length |
| 6 | while (end > 0 && SPACE.test(block[end - 1])) end-- |
| 7 | |
| 8 | if (block[end - 1] === ',') { |
| 9 | return block.slice(0, end - 1).trim().length > 0 |
| 10 | } |
| 11 | |
| 12 | var tail = block.slice(Math.max(0, end - 3), end).toLowerCase() |
| 13 | var size = 0 |
| 14 | if (tail === 'and') { |
| 15 | size = 3 |
| 16 | } else if (tail.slice(-2) === 'or') { |
| 17 | size = 2 |
| 18 | } |
| 19 | if (size === 0 || end <= size || !SPACE.test(block[end - size - 1])) { |
| 20 | return false |
| 21 | } |
| 22 | return block.slice(0, end - size).trim().length > 0 |
| 23 | } |
| 24 | |
| 25 | function flatten(array) { |
| 26 | if (!Array.isArray(array)) return [array] |