lib/util.js
function findPositions(data, items) {
    var depth = 0;
    var rootId = -1;
    var result = [];
    var currentItem = {};

    var accumulator = '';
    for (var ci = 0; ci < data.length; ci++) {
        accumulator += data[ci];

        var matchedItem = false;
        for (var x = 0; x < items.length; x++) {
            var item = items[x];

            if (depth > 0 && endsWith(accumulator, item.end)) {
                depth--;
                if (depth === 0 && rootId === x) {
                    currentItem.end = ci - item.end.length + 1;
                    rootId = -1;
                    accumulator = '';
                    result.push(currentItem);
                    currentItem = {};
                }
            } else if (endsWith(accumulator, item.start)) {
                depth++;
                if (depth === 1 && rootId === -1) {
                    currentItem = {
                        startChar: item.start,
                        endChar: item.end,
                        start: ci
                    };
                    rootId = x;
                    accumulator = '';
                }
            }
        }
    }
    return result;
}
function findPositions(data, items) {
    var depth = 0;
    var rootId = -1;
    var result = [];
    var currentItem = {};

    var accumulator = '';
    for (var ci = 0; ci < data.length; ci++) {
        accumulator += data[ci];

        var matchedItem = false;
        for (var x = 0; x < items.length; x++) {
            var item = items[x];

            if (depth > 0 && endsWith(accumulator, item.end)) {
                depth--;
                if (depth === 0 && rootId === x) {
                    currentItem.end = ci - item.end.length + 1;
                    rootId = -1;
                    accumulator = '';
                    result.push(currentItem);
                    currentItem = {};
                }
            } else if (endsWith(accumulator, item.start)) {
                depth++;
                if (depth === 1 && rootId === -1) {
                    currentItem = {
                        startChar: item.start,
                        endChar: item.end,
                        start: ci
                    };
                    rootId = x;
                    accumulator = '';
                }
            }
        }
    }
    return result;
}
Finds the start/end position of each item

@param {String} data The string to search
@param {Array<{start: String, end: String}>} items The array of items to find
@returns {Array<{startChar: String, endChar: String, start: Number, end: Number}>} The found items and locations