/* onigenc_strlen
347446
public int strLength(byte[]bytes, int p, int end) {
        int n = 0;
        int q = p;
        while (q < end) {
            q += length(bytes, q, end);
            n++;
        }
        return n;
    }
359892
function _substr($binary_string, $start, $length) {
        if (function_exists('mb_substr')) {
            return mb_substr($binary_string, $start, $length, '8bit');
        }
        return substr($binary_string, $start, $length);
    }
116556
public function mbStrLen($string, $encoding = null)
    {
        // Meh, the original mb_strlen interprets a null here as an empty string.
        if ($encoding === null) {
            return mb_strlen($string);
        }
        return mb_strlen($string, $encoding);
    }
1207615
function strcpy(dest, src, offset) {
  var origDestLen = dest.length;
  var start = dest.slice(0, offset);
  var end = dest.slice(offset + src.length);
  return (start + src + end).substr(0, origDestLen);
}
919776
static function Part($string, $start, $length = null)
    {
        self::InitEncoding();
        if ($length !== null)
            return mb_substr($string, $start, $length);

        return mb_substr($string, $start);
    }
1038627
public static function strlen($string, $charset = self::UTF8)
	{
		switch (strtolower($charset))
		{
			case self::GBK:
				$count = self::strlenForGbk($string);
				break;
			case self::UTF8:
				$count = self::strlenForUtf8($string);
				break;
			default:
				$count = strlen($string);
		}
		return $count;
	}
1147725
function _gpfArrayFromString(array, string) {
        var length = string.length, index = 0;
        for (; index < length; ++index) {
            array.push(string.charAt(index));
        }
    }
680854
public static function strlen($str) {
    if (is_array($str))
      return false;

    if (function_exists('mb_strlen'))
      return mb_strlen($str, 'UTF-8');

    return strlen($str);
  }
1090178
@Override
	public void writeString(String str) throws IOException {
		byte[] bytes = Utf8.getBytesFor(str);
		writeBytes(bytes, 0, bytes.length);
	}
1165821
function utf8_strtrunc($str, $len) {
		$i = $len - 1;
		if (ord($str{$i}) & 0x80) { // part of a multibyte sequence
			for (; $i > 0 && !(ord($str{$i}) & 0x40); $i--) {
				// find the first byte
				;
			}
			if ($i <= 0) {
				return '';
			} // sanity check
			for ($bc = 0, $mbs = ord($str{$i}); $mbs & 0x80; $mbs = $mbs << 1) {
				// calculate number of bytes
				$bc++;
			}
			if ($bc + $i > $len) {
				return substr($str, 0, $i);
			}
			// fallthru: multibyte char fits into length
		}
		return substr($str, 0, $len);
	}
498083
static function repeat($str, $n) {
        $nstr = '';

        for ($i = 0; $i < $n; $i++) {
            $nstr .= $str;
        }

        return $nstr;
    }
859099
function checkString(i) {
  if (i >= tokensLength) {
    return 0;
  }

  if (tokens[i].type === TokenType.StringSQ ||
      tokens[i].type === TokenType.StringDQ) {
    return 1;
  }

  return 0;
}
1185660
function _unoctify($str)
    {
        $result = "";
        $i = 0;
        while ($i < strlen($str)) {
            $char = $str[$i];
            if ($char == "\\") {
                // Look to see if the next char is a backslash and
                // append it.
                if ($str[$i + 1] != "\\") {
                    $octal_digits = substr($str, $i + 1, 3);
                    $dec = octdec($octal_digits);
                    $char = chr($dec);
                    $i += 4;
                } else {
                    $char = "\\";
                    $i += 2;
                }
            } else {
                $i += 1;
            }

            $result .= $char;
        }

        return $result;
    }
1217130
function (str, callback) {
            var root, start, end, zone, line, lines, buff = [], c, error = null;

            i = j = current = furthest = 0;
            input = str.replace(/\r\n/g, '\n');

            // Remove potential UTF Byte Order Mark
            input = input.replace(/^\uFEFF/, '');

            // Split the input into chunks.
            chunks = (function (chunks) {
                var j = 0,
                    skip = /(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,
                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
                    string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,
                    level = 0,
                    match,
                    chunk = chunks[0],
                    inParam;

                for (var i = 0, c, cc; i < input.length;) {
                    skip.lastIndex = i;
                    if (match = skip.exec(input)) {
                        if (match.index === i) {
                            i += match[0].length;
                            chunk.push(match[0]);
                        }
                    }
                    c = input.charAt(i);
                    comment.lastIndex = string.lastIndex = i;

                    if (match = string.exec(input)) {
                        if (match.index === i) {
                            i += match[0].length;
                            chunk.push(match[0]);
                            continue;
                        }
                    }

                    if (!inParam && c === '/') {
                        cc = input.charAt(i + 1);
                        if (cc === '/' || cc === '*') {
                            if (match = comment.exec(input)) {
                                if (match.index === i) {
                                    i += match[0].length;
                                    chunk.push(match[0]);
                                    continue;
                                }
                            }
                        }
                    }
                    
                    switch (c) {
                        case '{': if (! inParam) { level ++;        chunk.push(c);                           break }
                        case '}': if (! inParam) { level --;        chunk.push(c); chunks[++j] = chunk = []; break }
                        case '(': if (! inParam) { inParam = true;  chunk.push(c);                           break }
                        case ')': if (  inParam) { inParam = false; chunk.push(c);                           break }
                        default:                                    chunk.push(c);
                    }
                    
                    i++;
                }
                if (level != 0) {
                    error = new(LessError)({
                        index: i-1,
                        type: 'Parse',
                        message: (level > 0) ? "missing closing `}`" : "missing opening `{`",
                        filename: env.filename
                    }, env);
                }

                return chunks.map(function (c) { return c.join('') });;
            })([[]]);

            if (error) {
                return callback(error, env);
            }

            // Start with the primary rule.
            // The whole syntax tree is held under a Ruleset node,
            // with the `root` property set to true, so no `{}` are
            // output. The callback is called when the input is parsed.
            try {
                root = new(tree.Ruleset)([], $(this.parsers.primary));
                root.root = true;
            } catch (e) {
                return callback(new(LessError)(e, env));
            }

            root.toCSS = (function (evaluate) {
                var line, lines, column;

                return function (options, variables) {
                    var frames = [], importError;

                    options = options || {};
                    //
                    // Allows setting variables with a hash, so:
                    //
                    //   `{ color: new(tree.Color)('#f01') }` will become:
                    //
                    //   new(tree.Rule)('@color',
                    //     new(tree.Value)([
                    //       new(tree.Expression)([
                    //         new(tree.Color)('#f01')
                    //       ])
                    //     ])
                    //   )
                    //
                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
                        variables = Object.keys(variables).map(function (k) {
                            var value = variables[k];

                            if (! (value instanceof tree.Value)) {
                                if (! (value instanceof tree.Expression)) {
                                    value = new(tree.Expression)([value]);
                                }
                                value = new(tree.Value)([value]);
                            }
                            return new(tree.Rule)('@' + k, value, false, 0);
                        });
                        frames = [new(tree.Ruleset)(null, variables)];
                    }

                    try {
                        var css = evaluate.call(this, { frames: frames })
                                          .toCSS([], { compress: options.compress || false, dumpLineNumbers: env.dumpLineNumbers });
                    } catch (e) {
                        throw new(LessError)(e, env);
                    }

                    if ((importError = parser.imports.error)) { // Check if there was an error during importing
                        if (importError instanceof LessError) throw importError;
                        else                                  throw new(LessError)(importError, env);
                    }

                    if (options.yuicompress && less.mode === 'node') {
                        return require('ycssmin').cssmin(css);
                    } else if (options.compress) {
                        return css.replace(/(\s)+/g, "$1");
                    } else {
                        return css;
                    }
                };
            })(root.eval);

            // If `i` is smaller than the `input.length - 1`,
            // it means the parser wasn't able to parse the whole
            // string, so we've got a parsing error.
            //
            // We try to extract a \n delimited string,
            // showing the line where the parse error occured.
            // We split it up into two parts (the part which parsed,
            // and the part which didn't), so we can color them differently.
            if (i < input.length - 1) {
                i = furthest;
                lines = input.split('\n');
                line = (input.slice(0, i).match(/\n/g) || "").length + 1;

                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }

                error = {
                    type: "Parse",
                    message: "Syntax Error on line " + line,
                    index: i,
                    filename: env.filename,
                    line: line,
                    column: column,
                    extract: [
                        lines[line - 2],
                        lines[line - 1],
                        lines[line]
                    ]
                };
            }

            if (this.imports.queue.length > 0) {
                finish = function (e) {
                    e = error || e;
                    if (e) callback(e);
                    else callback(null, root);
                };
            } else {
                callback(error, root);
            }
        }
341737
function(string) {
            
            var i = 0;
            while(i < string.length)
            {
                if(     (// ASCII
                string[i] == 0x09 ||
                    string[i] == 0x0A ||
                    string[i] == 0x0D ||
                    (0x20 <= string[i] && string[i] <= 0x7E)
                    )
                    ) {
                    i += 1;
                    continue;
                }
                
                if(     (// non-overlong 2-byte
                (0xC2 <= string[i] && string[i] <= 0xDF) &&
                    (0x80 <= string[i+1] && string[i+1] <= 0xBF)
                    )
                    ) {
                    i += 2;
                    continue;
                }
                
                if(     (// excluding overlongs
                string[i] == 0xE0 &&
                    (0xA0 <= string[i + 1] && string[i + 1] <= 0xBF) &&
                    (0x80 <= string[i + 2] && string[i + 2] <= 0xBF)
                    ) ||
                    (// straight 3-byte
                ((0xE1 <= string[i] && string[i] <= 0xEC) ||
                    string[i] == 0xEE ||
                    string[i] == 0xEF) &&
                    (0x80 <= string[i + 1] && string[i+1] <= 0xBF) &&
                    (0x80 <= string[i+2] && string[i+2] <= 0xBF)
                    ) ||
                    (// excluding surrogates
                string[i] == 0xED &&
                    (0x80 <= string[i+1] && string[i+1] <= 0x9F) &&
                    (0x80 <= string[i+2] && string[i+2] <= 0xBF)
                    )
                    ) {
                    i += 3;
                    continue;
                }
                
                if(     (// planes 1-3
                string[i] == 0xF0 &&
                    (0x90 <= string[i + 1] && string[i + 1] <= 0xBF) &&
                    (0x80 <= string[i + 2] && string[i + 2] <= 0xBF) &&
                    (0x80 <= string[i + 3] && string[i + 3] <= 0xBF)
                    ) ||
                    (// planes 4-15
                (0xF1 <= string[i] && string[i] <= 0xF3) &&
                    (0x80 <= string[i + 1] && string[i + 1] <= 0xBF) &&
                    (0x80 <= string[i + 2] && string[i + 2] <= 0xBF) &&
                    (0x80 <= string[i + 3] && string[i + 3] <= 0xBF)
                    ) ||
                    (// plane 16
                string[i] == 0xF4 &&
                    (0x80 <= string[i + 1] && string[i + 1] <= 0x8F) &&
                    (0x80 <= string[i + 2] && string[i + 2] <= 0xBF) &&
                    (0x80 <= string[i + 3] && string[i + 3] <= 0xBF)
                    )
                    ) {
                    i += 4;
                    continue;
                }
                
                return false;
            }
            
            return true;
        }
361863
public static String readString(ByteBuffer buffer, int strLen) {
        StringBuilder sb = new StringBuilder(strLen);
        for (int i = 0; i < strLen; i++) {
            sb.append(buffer.getChar());
        }
        return sb.toString();
    }
1100703
public final int strLengthNull(byte[]bytes, int p, int end) {
        int n = 0;

        while (true) {
            if (bytes[p] == 0) {
                int len = minLength();

                if (len == 1) return n;
                int q = p + 1;

                while (len > 1) {
                    if (bytes[q] != 0) break;
                    q++;
                    len--;
                }
                if (len == 1) return n;
            }
            p += length(bytes, p, end);
            n++;
        }
    }